tuneloop 0.1.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/LICENSE +21 -0
- package/README.md +256 -0
- package/dist/chunk-RB45XK57.js +6941 -0
- package/dist/chunk-RB45XK57.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +154 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/app.js +4937 -0
- package/dist/client/app.js.map +1 -0
- package/dist/client/favicon.svg +7 -0
- package/dist/client/index.html +74 -0
- package/dist/client/styles.css +698 -0
- package/dist/index.d.ts +1623 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/client/core.ts","../../src/server/client/router-url.ts","../../src/server/client/sessions.ts","../../src/server/client/artifacts.ts","../../src/server/client/notice.ts","../../src/server/client/home.ts","../../src/server/client/askbanner.ts","../../src/server/client/charts.ts","../../src/server/client/facets.ts","../../src/server/client/metrics/successRate.ts","../../src/server/client/featTreemap.ts","../../src/server/client/metrics/costArtifact.ts","../../src/server/client/metrics/totalSpend.ts","../../src/server/client/metrics/sessionsMetric.ts","../../src/server/client/metrics/ops.ts","../../src/server/client/kpis.ts","../../src/server/client/router.ts","../../src/server/client/main.ts"],"sourcesContent":["// Shared state singleton + the small primitives every module leans on: DOM\n// lookup, escaping, formatting, fetch helpers, and the KPI delta badge. Kept in\n// the same vanilla style as the rest of the client so the extraction stays a\n// structural move, not a rewrite.\n\n// The client is a small SPA with a single shared mutable state object. API\n// payloads stay `any` (the server owns those shapes); the control state that the\n// UI reassigns is typed so the wider value ranges (e.g. days: number | 'all')\n// are explicit and property typos are caught.\nexport interface SessionFilters {\n facets: Record<string, string>\n q: string\n artifact: string\n artifactKind: string\n outcomes: string[]\n // Resolved window for the request (ISO); '' when the window is 'all'.\n from: string\n to: string\n}\n\n// Sessions-list time window. `preset` drives from/to; 'custom' reads the date\n// inputs; 'all' means no bound. Independent of the dashboard KPI window.\nexport interface SessTime {\n preset: 7 | 14 | 30 | 90 | 'all' | 'custom'\n from: string // ISO date (yyyy-mm-dd) for custom range\n to: string\n}\n\nexport interface ClientState {\n // The top-level tab the app is showing. Mirrored into the URL hash by the\n // router; setView() keeps it in step with the DOM.\n view: 'highlights' | 'dashboard' | 'artifacts' | 'sessions'\n // The session whose detail drawer is open (null = drawer closed). Mirrored into\n // the URL as `?session=<id>` so a session is shareable / reload-survivable.\n open: string | null\n artKind: string\n overview: any\n home: any // Explore (question-led) stats; null until fetched\n asked: any // the question the user clicked through from, for the grounding banner (null = none)\n filters: Partial<SessionFilters> // starts {}, filled in by applyFilters()\n facets: any[]\n dist: Record<string, any[]>\n measures: any[]\n metric: string | null // which headline KPI's detail view is open (null = overview)\n outcomeTypes: any[]\n days: number | 'all' // top-level KPI window (drives the whole headline row + cost-artifact curves)\n sr: { outcomes: string[]; bucket: string; by: string; filters: Record<string, string[]> } // success-rate detail controls\n // cost-per-artifact detail controls. `kind` follows defaultKind until the user\n // toggles it (userPicked), after which it sticks and the headline tile mirrors\n // it. `bucket` is the curve granularity: '' = auto-derived from the window;\n // a manual pick overrides until the window changes.\n // `kind` (feature|pr) scopes the whole section; `complexity` scopes the cost-by-artifact view.\n ca: { kind: string; defaultKind: string; userPicked: boolean; bucket: string; complexity: string }\n spend: { bucket: string; by: string; filters: Record<string, string[]> } // total-spend detail controls\n sm: { bucket: string; by: string; filters: Record<string, string[]> } // sessions detail controls\n // operational detail: one shared bucket, a per-graph \"break down by\" choice\n // ('' | 'name' | 'error_category'), and row-level scopes for the error-rate\n // chart (tool names + error categories — ops-specific, not the shared facets).\n ops: { bucket: string; tab: string; by: Record<string, string>; filters: { toolNames: string[]; errorCategories: string[] } }\n ac: { items: any[]; sel: number } // artifact-search typeahead state\n sessTime: SessTime // sessions-list time window (default 30d)\n // Artifacts tab list controls (PRs/Features table): free-text search + the PR\n // table's column sort. Mirrored into the URL so a filtered/sorted table is a\n // shareable, reload-survivable link. Reset when switching kind (feature ↔ pr).\n art: { q: string; sort: string; dir: string }\n}\n\nexport var state: ClientState = {\n view: 'dashboard', open: null,\n artKind: 'feature', overview: null, home: null, asked: null, filters: {}, facets: [], dist: {}, measures: [],\n metric: null,\n outcomeTypes: [],\n days: 7,\n // bucket '' = auto-derive from the window (bucketForWindow); a manual pick\n // overrides until the window changes. Uniform across every expansion.\n sr: { outcomes: ['session_success'], bucket: '', by: '', filters: {} },\n ca: { kind: 'feature', defaultKind: 'feature', userPicked: false, bucket: '', complexity: '' },\n spend: { bucket: '', by: '', filters: {} },\n sm: { bucket: '', by: '', filters: {} },\n ops: { bucket: '', tab: 'tools', by: { tool_calls: 'name', error_rate: 'name', skill_usage: 'name' }, filters: { toolNames: [], errorCategories: [] } },\n ac: { items: [], sel: -1 },\n sessTime: { preset: 30, from: '', to: '' },\n art: { q: '', sort: 'created', dir: 'desc' }\n};\n\n// The success-rate detail controls persist across reloads: the user's \"what\n// counts as success\" (and the breakdown) becomes their default until they change\n// it again. Stored client-side, so the windowed KPI passes the same outcomes to\n// the server to stay consistent (see loadKpis). Bucket is intentionally NOT\n// persisted — it auto-derives from the window.\nvar SR_PREFS_KEY = 'tuneloop.sr';\nfunction loadSrPrefs() {\n try {\n var saved = JSON.parse(localStorage.getItem(SR_PREFS_KEY) || 'null');\n if (!saved || typeof saved !== 'object') return;\n if (Array.isArray(saved.outcomes)) state.sr.outcomes = saved.outcomes.filter(function (x) { return typeof x === 'string'; });\n if (typeof saved.by === 'string') state.sr.by = saved.by;\n } catch (e) { /* malformed or unavailable storage → keep defaults */ }\n}\nexport function saveSrPrefs() {\n try { localStorage.setItem(SR_PREFS_KEY, JSON.stringify({ outcomes: state.sr.outcomes, by: state.sr.by })); } catch (e) { /* ignore */ }\n}\nloadSrPrefs();\n\nexport function $(s) { return document.querySelector(s); }\nexport function esc(s) {\n return String(s == null ? '' : s).replace(/[&<>\"]/g, function (c) {\n return { '&': '&', '<': '<', '>': '>', '\"': '"' }[c];\n });\n}\n// Minimal, safe Markdown → HTML for assistant message text. Escape-first by\n// construction: fenced/inline code is pulled out to placeholders, everything\n// else is HTML-escaped (so no raw HTML from the transcript is ever rendered),\n// then a small set of block/inline rules are applied. Covers the common cases\n// (headings, lists, blockquotes, bold/italic, inline + fenced code, links);\n// imperfect on exotic nesting, which is fine for a transcript viewer.\nexport function renderMd(src) {\n var text = String(src == null ? '' : src);\n var codes = [], inls = [];\n // Private-use sentinel delimiting code placeholders. Never appears in real\n // text, survives esc(), and is stripped by restore(). (A literal char, not a\n // NUL byte, so the file stays text and diffs render.)\n var Z = String.fromCharCode(0xe000);\n // Fenced code blocks first, so their contents are never treated as markdown.\n text = text.replace(/```[ \\t]*[\\w+-]*\\n?([\\s\\S]*?)```/g, function (_m, code) {\n codes.push('<pre class=\"md-code\"><code>' + esc(code.replace(/\\n+$/, '')) + '</code></pre>');\n return Z + 'C' + (codes.length - 1) + Z;\n });\n // Inline code next (single line), so emphasis rules don't touch it.\n text = text.replace(/`([^`\\n]+)`/g, function (_m, code) {\n inls.push('<code>' + esc(code) + '</code>');\n return Z + 'I' + (inls.length - 1) + Z;\n });\n\n var inline = function (s) {\n s = esc(s);\n s = s.replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>');\n s = s.replace(/__([^_]+)__/g, '<strong>$1</strong>');\n s = s.replace(/(^|[^*])\\*([^*\\s][^*]*?)\\*/g, '$1<em>$2</em>');\n s = s.replace(/(^|[^_\\w])_([^_\\s][^_]*?)_/g, '$1<em>$2</em>');\n s = s.replace(/~~([^~]+)~~/g, '<del>$1</del>');\n // [text](url) — only http/https/relative/anchor hrefs (esc turned & into &).\n s = s.replace(/\\[([^\\]]+)\\]\\(((?:https?:\\/\\/|\\/|#)[^\\s)]+)\\)/g, function (_m, label, href) {\n return '<a href=\"' + href + '\" target=\"_blank\" rel=\"noopener noreferrer\">' + label + '</a>';\n });\n return s;\n };\n var restore = function (s) {\n return s\n .replace(new RegExp(Z + 'C(\\\\d+)' + Z, 'g'), function (_m, i) { return codes[Number(i)]; })\n .replace(new RegExp(Z + 'I(\\\\d+)' + Z, 'g'), function (_m, i) { return inls[Number(i)]; });\n };\n\n var lines = text.split('\\n');\n var out = [], i = 0;\n var flushPara = function (buf) { if (buf.length) out.push('<p>' + buf.map(inline).join('<br>') + '</p>'); };\n while (i < lines.length) {\n var line = lines[i];\n var cb = line.trim().match(new RegExp('^' + Z + 'C(\\\\d+)' + Z + '$'));\n if (cb) { out.push(codes[Number(cb[1])]); i++; continue; }\n if (!line.trim()) { i++; continue; }\n var h = line.match(/^(#{1,6})\\s+(.*)$/);\n if (h) { var lvl = h[1].length; out.push('<div class=\"md-h md-h' + lvl + '\">' + inline(h[2]) + '</div>'); i++; continue; }\n if (/^\\s*>\\s?/.test(line)) {\n var q = [];\n while (i < lines.length && /^\\s*>\\s?/.test(lines[i])) { q.push(lines[i].replace(/^\\s*>\\s?/, '')); i++; }\n out.push('<blockquote>' + q.map(inline).join('<br>') + '</blockquote>');\n continue;\n }\n if (/^\\s*[-*+]\\s+/.test(line)) {\n var ul = [];\n while (i < lines.length && /^\\s*[-*+]\\s+/.test(lines[i])) { ul.push('<li>' + inline(lines[i].replace(/^\\s*[-*+]\\s+/, '')) + '</li>'); i++; }\n out.push('<ul>' + ul.join('') + '</ul>');\n continue;\n }\n if (/^\\s*\\d+\\.\\s+/.test(line)) {\n var ol = [];\n while (i < lines.length && /^\\s*\\d+\\.\\s+/.test(lines[i])) { ol.push('<li>' + inline(lines[i].replace(/^\\s*\\d+\\.\\s+/, '')) + '</li>'); i++; }\n out.push('<ol>' + ol.join('') + '</ol>');\n continue;\n }\n var para = [];\n while (i < lines.length && lines[i].trim() && !new RegExp('^' + Z + 'C\\\\d+' + Z + '$').test(lines[i].trim()) &&\n !/^(#{1,6})\\s+/.test(lines[i]) && !/^\\s*>\\s?/.test(lines[i]) &&\n !/^\\s*[-*+]\\s+/.test(lines[i]) && !/^\\s*\\d+\\.\\s+/.test(lines[i])) { para.push(lines[i]); i++; }\n flushPara(para);\n }\n return restore(out.join(''));\n}\n\nexport function usd(n) { return '$' + (Number(n) || 0).toFixed(2); }\nexport function num(n) { return (Number(n) || 0).toLocaleString('en-US'); }\nexport function get(url) { return fetch(url).then(function (r) { return r.json(); }); }\nexport function post(url, body) {\n return fetch(url, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }).then(function (r) { return r.json(); });\n}\nexport function dayOf(s) { return s ? String(s).slice(0, 10) : ''; }\n// Collapse a home dir to `~/` so screenshots (and any shared UI) don't leak the username.\nexport function tildeHome(p) { return (p || '').replace(/^(\\/Users\\/[^/]+|\\/home\\/[^/]+|\\/root)\\//, '~/'); }\n\nexport function badge(v) {\n var c = v === 'success' ? 'b-success' : v === 'partial' ? 'b-partial' : v === 'failure' ? 'b-failure' : v ? 'b-unknown' : 'b-null';\n return '<span class=\"badge ' + c + '\">' + esc(v || '—') + '</span>';\n}\n\nexport function grainOfSrc(src) { return src === 'usage' ? 'usage' : src === 'tool-call' ? 'tool_call' : src === 'block' ? 'block' : 'session'; }\n\nexport function fmtVal(v, format) {\n if (v == null) return '—';\n if (format === 'usd') return usd(v);\n if (format === 'pct') return Math.round(v * 100) + '%';\n return num(Math.round(v));\n}\n\n// Format a composite breakdown key (a \", \"-joined value set) for display: a\n// multi-value set is truncated to the first few members + \"+N\", with the full\n// set kept for the title/tooltip. Single values and the synthetic \"(none)\"\n// placeholder pass through unchanged. The top-K rollup key \"Other\" is relabeled\n// to \"... other values\" so it can't be mistaken for a real value named \"other\"\n// (the legend's \"Show all\" link expands it). Shared by the outcome and\n// session-count breakdown charts.\nexport function comboLabel(key) {\n if (key === '(none)') return { text: key, full: key };\n if (key === 'Other') return { text: '... other values', full: '... other values' };\n var parts = String(key).split(', ');\n if (parts.length <= 1) return { text: key, full: key };\n var MAX = 3, shown = parts.slice(0, MAX).join(', ');\n if (parts.length > MAX) shown += ' +' + (parts.length - MAX);\n return { text: shown, full: parts.join(', ') };\n}\n\nexport var SR_PALETTE = ['#0f7a55', '#b8860b', '#b4452f', '#3b6ea5', '#7d5ba6', '#1b8a8a', '#a65c2e', '#6b8e23'];\n\n// Complexity bucket → display label. One source of truth shared by the Cost-by-\n// Artifact filter buttons and the headline KPI subtext, so they always agree.\nexport var CX_LABELS: Record<string, string> = {\n trivial: 'Trivial', small: 'Simple', medium: 'Moderate', large: 'Complex', xl: 'Highly Complex', none: 'Not tagged',\n};\n// Comma-joined bucket keys → \"Trivial, Simple\" (preserving selection order).\nexport function cxLabelList(keys: string) {\n return (keys || '').split(',').filter(Boolean).map(function (k) { return CX_LABELS[k] || k; }).join(', ');\n}\n// A single artifact's complexity → its bucket label. Features carry an ordinal\n// (1–5, user-tagged); PRs carry a diff-size churn (line count) bucketed by the\n// same ranges as the Cost-by-Artifact filter. Null/untagged → '' (no label).\nvar CX_ORDINAL = ['', 'trivial', 'small', 'medium', 'large', 'xl'];\nexport function complexityLabel(kind: string, complexity: number | null | undefined) {\n if (complexity == null) return '';\n if (kind === 'feature') return CX_LABELS[CX_ORDINAL[complexity]] || '';\n var n = Number(complexity);\n var key = n <= 10 ? 'trivial' : n <= 100 ? 'small' : n <= 500 ? 'medium' : n <= 1500 ? 'large' : 'xl';\n return CX_LABELS[key];\n}\n\n// Canonical outcome display order: concrete shipped artifacts first, softening\n// down to the LLM-judged catch-all. Shared by the success-rate \"Count as success\"\n// picker and the sessions Outcomes column so they read consistently. Types not\n// listed sort to the end (preserving their relative order).\nexport var OUTCOME_ORDER = ['pr_merged', 'pr_created', 'pr_contributed', 'pr_approved', 'pr_changes_requested', 'pr_reviewed', 'commit_pushed', 'file_written', 'session_success'];\nexport function outcomeRank(type) { var i = OUTCOME_ORDER.indexOf(type); return i < 0 ? OUTCOME_ORDER.length : i; }\n\n// Friendly display for an outcome type in selection UIs (success-rate picker,\n// the sessions Outcome filter, active chips). The LLM-judged signal keeps its\n// snake_case token (consistent with git-derived outcomes like pr_merged) and\n// adds a \"(LLM Judged)\" cue; every other type shows its raw token unchanged.\nexport function outcomeLabel(type) {\n return type === 'session_success' ? 'session_success (LLM Judged)' : type;\n}\n\n// A delta badge comparing this window's value to the prior window's. mode:\n// 'points' for rates (absolute percentage-point change), 'rel' for everything\n// else (relative % change). good = which direction is favorable ('up'|'down'):\n// the change is green when favorable, red when not. good=null marks a neutral\n// metric (spend/sessions) with no better/worse direction — its change shows in\n// the brand green (the accent) rather than greyed out, to match the other tiles.\nexport function kpiDelta(cur, prev, mode, good) {\n if (cur == null || prev == null) return '';\n var diff;\n var text;\n if (mode === 'points') {\n diff = (cur - prev) * 100;\n if (Math.abs(diff) < 0.05) return '<span class=\"delta flat\">±0pp</span>';\n text = (diff > 0 ? '+' : '') + diff.toFixed(1) + 'pp';\n } else {\n if (!prev) return ''; // no baseline to divide by\n diff = ((cur - prev) / Math.abs(prev)) * 100;\n if (Math.abs(diff) < 0.5) return '<span class=\"delta flat\">±0%</span>';\n text = (diff > 0 ? '+' : '') + Math.round(diff) + '%';\n }\n var dir = diff > 0 ? 'up' : 'down';\n var cls = good == null ? 'good' : (dir === good ? 'good' : 'bad');\n var arrow = diff > 0 ? '▲' : '▼';\n return '<span class=\"delta ' + cls + '\">' + arrow + ' ' + esc(text) + '</span>';\n}\n\n// ---- window + bucket helpers (shared by every KPI expansion) ----------------\n\n// An appropriate curve granularity for the selected window: fine buckets for\n// short spans, coarse for long ones, so charts stay readable.\nexport function bucketForWindow(days) {\n if (days === 'all') return 'month';\n if (days <= 31) return 'day';\n if (days <= 180) return 'week';\n return 'month';\n}\n\n// The effective bucket for an expansion: the user's manual pick ('' = none), or\n// the window-derived default. Manual picks are cleared on window change.\nexport function autoBucket(b) { return b || bucketForWindow(state.days); }\n\n// Query fragment ('&from=…&to=…') pinning an expansion's data to the selected\n// window; '' for the all-time window. Appended to an already-non-empty query.\nexport function windowQs() {\n if (state.days === 'all') return '';\n var span = state.days * 86400000, now = Date.now();\n return '&from=' + encodeURIComponent(new Date(now - span).toISOString()) +\n '&to=' + encodeURIComponent(new Date(now).toISOString());\n}\n","// Pure URL <-> Route serialization for the hash router. No DOM / state imports,\n// so it's unit-testable under Node and reusable by router.ts. The grammar:\n//\n// #/highlights the landing digest (empty hash also lands here)\n// #/dashboard/<metric> e.g. #/dashboard/cost_artifact\n// #/artifacts/<kind>[?q=&sort=&dir=]\n// #/sessions[?win=&q=&outcomes=&artifact=&artifactKind=&f.<facet>=…]\n// ...any of the above + ?session=<id> (the open detail drawer, orthogonal)\n//\n// The path picks the screen; the query string carries that screen's filtered-list\n// state, so a filtered list (and a future graph drill-down into one) is a plain\n// URL. Facet filters are namespaced `f.<key>` so a dynamic facet name can't\n// collide with a reserved param. Unknown views/metrics/kinds fall back to\n// defaults rather than erroring, so a stale or hand-mangled hash always resolves.\n\nexport interface Route {\n view: 'highlights' | 'dashboard' | 'artifacts' | 'sessions'\n metric: string // dashboard sub-selection (which KPI is expanded)\n artKind: string // artifacts sub-selection (feature | pr)\n session: string | null // open drawer target, or null (mirror of query.session)\n query: Record<string, string> // full decoded query string (filtered-list state)\n}\n\n/** The path-level slice of client state that maps to the URL path. */\nexport interface NavState {\n view: 'highlights' | 'dashboard' | 'artifacts' | 'sessions'\n metric: string | null\n artKind: string\n}\n\n// 'highlights' is routable (so the landing tab is shareable / reload-survivable),\n// but it is NOT the parse fallback — an empty or unknown hash still resolves to\n// 'dashboard' (see parseHash). main.ts decides to LAND on highlights when the hash\n// is empty; an explicit deep link to any other view wins.\nexport const VIEWS = ['highlights', 'dashboard', 'artifacts', 'sessions']\nexport const METRICS = ['success_rate', 'cost_artifact', 'total_spend', 'sessions', 'ops']\nexport const ART_KINDS = ['feature', 'pr']\nexport const DEFAULT_METRIC = 'success_rate'\nexport const DEFAULT_ARTKIND = 'feature'\n\n/** Decode a `a=1&b=2` query string into a map (tolerant of junk / bad encoding). */\nexport function parseQuery(str: string): Record<string, string> {\n const out: Record<string, string> = {}\n ;(str || '').split('&').forEach((kv) => {\n if (!kv) return\n const eq = kv.indexOf('=')\n const k = eq < 0 ? kv : kv.slice(0, eq)\n const v = eq < 0 ? '' : kv.slice(eq + 1)\n if (!k) return\n try {\n out[decodeURIComponent(k)] = decodeURIComponent(v)\n } catch {\n /* drop a malformed pair rather than throw */\n }\n })\n return out\n}\n\n/** Encode a map into a stable (key-sorted) query string; empty values dropped. */\nexport function serializeQuery(query: Record<string, string>): string {\n return Object.keys(query)\n .filter((k) => query[k] != null && query[k] !== '')\n .sort()\n .map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(query[k]))\n .join('&')\n}\n\n/** Parse a location.hash string into a fully-defaulted Route (never throws). */\nexport function parseHash(hash: string): Route {\n // '#/dashboard/cost_artifact?session=abc' → path 'dashboard/cost_artifact', query 'session=abc'\n const raw = (hash || '').replace(/^#\\/?/, '')\n const qIdx = raw.indexOf('?')\n const path = qIdx >= 0 ? raw.slice(0, qIdx) : raw\n const query = parseQuery(qIdx >= 0 ? raw.slice(qIdx + 1) : '')\n const parts = path.split('/').filter(Boolean)\n\n const view = (VIEWS.indexOf(parts[0]) >= 0 ? parts[0] : 'dashboard') as Route['view']\n const metric = view === 'dashboard' && METRICS.indexOf(parts[1]) >= 0 ? parts[1] : DEFAULT_METRIC\n const artKind = view === 'artifacts' && ART_KINDS.indexOf(parts[1]) >= 0 ? parts[1] : DEFAULT_ARTKIND\n\n return { view, metric, artKind, session: query.session || null, query }\n}\n\n/** Serialize a path slice + a query map into a canonical hash string. */\nexport function serializeRoute(nav: NavState, query: Record<string, string>): string {\n const base =\n nav.view === 'highlights'\n ? '#/highlights'\n : nav.view === 'artifacts'\n ? '#/artifacts/' + (nav.artKind || DEFAULT_ARTKIND)\n : nav.view === 'sessions'\n ? '#/sessions'\n : '#/dashboard/' + (nav.metric || DEFAULT_METRIC)\n const qs = serializeQuery(query)\n return qs ? base + '?' + qs : base\n}\n","// Sessions tab: the filter bar (facet selects + artifact-search typeahead +\n// free-text), the session table, the detail drawer, and view switching. The\n// typeahead helpers (ac*) are module-private; filterByArtifact/setView are\n// shared so the artifacts tab and drawer can jump into a filtered session list.\nimport { state, $, esc, renderMd, usd, num, dayOf, badge, get, post, outcomeRank, outcomeLabel } from './core'\nimport { syncHash } from './router'\n\n// Close the transcript outline dropdown on an outside click — it's a custom\n// dropdown with no native blur. One module-level listener (added once) that\n// queries the live elements, so it works across drawer re-opens without leaking\n// per-open handlers. mousedown (not click) so opening the dropdown via its own\n// button doesn't immediately re-close it on the same interaction.\ndocument.addEventListener('mousedown', function (e) {\n var panel = document.getElementById('tx-outline');\n if (!panel || !panel.classList.contains('on')) return;\n var btn = document.querySelector('#drawerBody .tx-ol-btn');\n var target = e.target as Node;\n if (panel.contains(target) || (btn && btn.contains(target))) return;\n panel.classList.remove('on');\n if (btn) btn.classList.remove('on');\n});\n\n// Close the outcome multi-select popover on an outside click (same pattern as\n// the transcript outline above): one module-level listener over live elements.\ndocument.addEventListener('mousedown', function (e) {\n var menu = document.getElementById('f-outcome-menu');\n if (!menu || !menu.classList.contains('on')) return;\n var wrap = document.getElementById('f-outcome-wrap');\n if (wrap && wrap.contains(e.target as Node)) return;\n menu.classList.remove('on');\n});\n\nvar TIME_PRESETS = [\n { d: 7, l: '7d' }, { d: 14, l: '14d' }, { d: 30, l: '30d' }, { d: 90, l: '90d' }, { d: 'all', l: 'All' }, { d: 'custom', l: 'Custom' }\n];\n\n// Filter facets shown inline (in this order); every other filter-role facet —\n// plus the artifact search — collapses behind \"More filters\" to keep the bar\n// compact. Adding a facet to a processor still surfaces it (under \"More\").\nvar PRIMARY_FACETS = ['use_case', 'repo'];\n\nexport function buildFilters() {\n // Compact toolbar. The generic facet loop still drives everything (so a new\n // processor facet surfaces automatically) — PRIMARY_FACETS render inline,\n // the rest collapse behind \"More filters\" with the artifact search.\n function sel(f) {\n var d = state.dist[f.key] || [];\n var opts = '<option value=\"\">' + esc(f.label || f.key) + ': all</option>';\n d.forEach(function (r) { if (r.value == null) return; opts += '<option value=\"' + esc(r.value) + '\">' + esc(r.value) + '</option>'; });\n return '<select class=\"facet-filter\" data-key=\"' + esc(f.key) + '\">' + opts + '</select>';\n }\n function usable(f) { return (f.roles || []).indexOf('filter') >= 0 && (state.dist[f.key] || []).length > 0; }\n\n var primary = '';\n PRIMARY_FACETS.forEach(function (k) {\n var f = state.facets.filter(function (x) { return x.key === k; })[0];\n if (f && usable(f)) primary += sel(f);\n });\n var more = '';\n state.facets.forEach(function (f) {\n if (!usable(f) || PRIMARY_FACETS.indexOf(f.key) >= 0) return;\n more += sel(f);\n });\n\n var segBtns = TIME_PRESETS.map(function (p) {\n return '<button type=\"button\" data-d=\"' + p.d + '\"' +\n (String(p.d) === String(state.sessTime.preset) ? ' class=\"on\"' : '') + '>' + p.l + '</button>';\n }).join('');\n\n $('#filters').innerHTML =\n '<div class=\"flt-row\">' +\n '<span class=\"flt-grp\"><span class=\"flt-lbl\">Time</span>' +\n '<div class=\"seg flt-seg\" id=\"f-time\">' + segBtns + '</div>' +\n '<span class=\"flt-dates\" id=\"f-dates\"' + (state.sessTime.preset === 'custom' ? '' : ' hidden') + '>' +\n '<input type=\"date\" id=\"f-from\" value=\"' + esc(state.sessTime.from) + '\" />' +\n '<span class=\"flt-dash\">→</span>' +\n '<input type=\"date\" id=\"f-to\" value=\"' + esc(state.sessTime.to) + '\" />' +\n '</span>' +\n '</span>' +\n '<input id=\"f-q\" class=\"flt-search\" placeholder=\"search title / intent\" />' +\n '</div>' +\n '<div class=\"flt-row flt-row-facets\">' + primary +\n '<span class=\"flt-pop\" id=\"f-outcome-wrap\">' +\n '<button type=\"button\" class=\"flt-pop-btn\" id=\"f-outcome-btn\">Outcomes' +\n '<span class=\"flt-pop-cnt\" id=\"f-outcome-cnt\"></span><span class=\"flt-pop-car\">▾</span></button>' +\n '<div class=\"flt-menu\" id=\"f-outcome-menu\"></div>' +\n '</span>' +\n '<span class=\"ac\" id=\"f-artifact-ac\">' +\n '<input id=\"f-artifact\" placeholder=\"file path / PR # / feature\" autocomplete=\"off\" />' +\n '<div class=\"ac-menu\" id=\"f-artifact-menu\"></div>' +\n '</span>' +\n (more ? '<button type=\"button\" class=\"flt-pop-btn flt-more-btn\" id=\"f-more-btn\">More filters<span class=\"flt-pop-cnt\" id=\"f-more-cnt\"></span><span class=\"flt-pop-car\">▾</span></button>' : '') +\n '</div>' +\n (more ? '<div class=\"flt-row flt-more\" id=\"f-more\" hidden>' + more + '</div>' : '') +\n '<div class=\"flt-active\" id=\"filter-active\"></div>';\n\n // Reflect current filter state into the freshly-built controls, so a restored or\n // URL-driven filter shows in the bar (not just in the request). Time + dates are\n // already rendered from state.sessTime above; do the rest here.\n var ff = state.filters || {};\n var ffacets = ff.facets || {};\n Array.prototype.forEach.call(document.querySelectorAll('.facet-filter'), function (s) {\n var v = ffacets[s.getAttribute('data-key')];\n if (v != null) s.value = v; // a value absent from the options list leaves it at \"all\"\n });\n if ($('#f-q')) $('#f-q').value = ff.q || '';\n var afEl0 = $('#f-artifact');\n if (afEl0) { afEl0.value = ff.artifact || ''; afEl0.dataset.kind = ff.artifactKind || ''; }\n updateOutcomeCount((ff.outcomes || []).length);\n\n Array.prototype.forEach.call(document.querySelectorAll('.facet-filter'), function (s) { s.onchange = applyFilters; });\n\n // Time segmented control (presets + custom range).\n Array.prototype.forEach.call(document.querySelectorAll('#f-time button'), function (b) {\n b.onclick = function () {\n var d = b.getAttribute('data-d');\n setTimePreset(d === 'all' || d === 'custom' ? d : parseInt(d, 10));\n };\n });\n $('#f-from').onchange = function () { state.sessTime.from = this.value; applyFilters(); };\n $('#f-to').onchange = function () { state.sessTime.to = this.value; applyFilters(); };\n\n // Outcome multi-select popover (built lazily; outcome types load async).\n $('#f-outcome-btn').onclick = function () { buildOutcomeMenu(); $('#f-outcome-menu').classList.toggle('on'); };\n\n // More-filters disclosure.\n var moreBtn = $('#f-more-btn');\n if (moreBtn) moreBtn.onclick = function () { var m = $('#f-more'); var open = m.hidden; m.hidden = !open; this.classList.toggle('on', open); };\n\n var t;\n $('#f-q').oninput = function () { clearTimeout(t); t = setTimeout(applyFilters, 250); };\n // Artifact search: typeahead suggestions + (debounced) live substring filter.\n // Typing manually clears the picked kind, so the search spans all kinds.\n var t2;\n $('#f-artifact').oninput = function () { this.dataset.kind = ''; clearTimeout(t2); t2 = setTimeout(function () { acFetch(); applyFilters(); }, 200); };\n $('#f-artifact').onkeydown = acKeydown;\n $('#f-artifact').onblur = function () { setTimeout(acClose, 150); }; // delay so a click registers\n\n // Apply current defaults (30d window) and render the active-chip row.\n applyFilters();\n}\n\n// Badge on the \"More filters\" button = how many collapsed filters are active.\nfunction updateMoreCount() {\n var el = $('#f-more-cnt');\n if (!el) return;\n var f = state.filters || {};\n var n = 0;\n Object.keys(f.facets || {}).forEach(function (k) { if (PRIMARY_FACETS.indexOf(k) < 0) n++; });\n el.textContent = n ? String(n) : '';\n}\n\n// Clear every sessions filter, including the time window (→ all-time), and reload.\n// buildFilters() rebuilds the bar empty, then applyFilters() reloads + empties the\n// chip row (so the \"Clear all\" button itself disappears — nothing left to clear).\nexport function clearAllFilters() {\n state.sessTime = { preset: 'all', from: '', to: '' };\n // buildFilters() now reflects state.filters into the controls, so clearing the\n // bar means clearing the state too (not just rebuilding empty DOM).\n state.filters = { facets: {}, q: '', artifact: '', artifactKind: '', outcomes: [], from: '', to: '' };\n buildFilters();\n}\n\n// ---- URL <-> sessions-filter bridge (used by the router) ---------------------\n\n// The current sessions filter as URL query params: window (win / from+to), free\n// text (q), artifact (+kind), outcomes (csv), and each facet as `f.<key>`.\n// Defaults (the 30-day window) are omitted so an unfiltered list stays `#/sessions`.\nexport function getSessionParams(): Record<string, string> {\n var q: Record<string, string> = {};\n var st = state.sessTime;\n if (st.preset === 'custom') { if (st.from) q.from = st.from; if (st.to) q.to = st.to; }\n else if (st.preset === 'all') q.win = 'all';\n else if (st.preset !== 30) q.win = String(st.preset); // 30d is the default\n var f = state.filters || {};\n if (f.q) q.q = f.q;\n if (f.artifact) { q.artifact = f.artifact; if (f.artifactKind) q.artifactKind = f.artifactKind; }\n if (f.outcomes && f.outcomes.length) q.outcomes = f.outcomes.join(',');\n var facets = f.facets || {};\n Object.keys(facets).forEach(function (k) { if (facets[k]) q['f.' + k] = facets[k]; });\n return q;\n}\n\n// Restore the sessions filter from URL query params, then rebuild the bar (which\n// reflects the state into the controls and reloads the list). Inverse of\n// getSessionParams; unknown/absent params fall back to defaults.\nexport function applySessionParams(query: Record<string, string>) {\n state.view = 'sessions';\n if (query.from || query.to) state.sessTime = { preset: 'custom', from: query.from || '', to: query.to || '' };\n else if (query.win === 'all') state.sessTime = { preset: 'all', from: '', to: '' };\n else if (query.win === '7' || query.win === '14' || query.win === '90') state.sessTime = { preset: parseInt(query.win, 10) as 7 | 14 | 90, from: '', to: '' };\n else state.sessTime = { preset: 30, from: '', to: '' }; // default (win=30 or absent)\n var facets: Record<string, string> = {};\n Object.keys(query).forEach(function (k) { if (k.indexOf('f.') === 0 && query[k]) facets[k.slice(2)] = query[k]; });\n state.filters = {\n facets: facets,\n q: query.q || '',\n artifact: query.artifact || '',\n artifactKind: query.artifactKind || '',\n outcomes: query.outcomes ? query.outcomes.split(',').filter(Boolean) : [],\n from: '', to: '', // resolved by applyFilters() → sessWindow()\n };\n buildFilters(); // renders the bar from state.* and calls applyFilters() → loadSessions\n}\n\n// Resolve the sessions-list window to ISO {from,to} for the request. Empty\n// bounds mean \"open\" (the 'all' preset, or a half-filled custom range).\nfunction sessWindow() {\n var st = state.sessTime;\n if (st.preset === 'all') return { from: '', to: '' };\n if (st.preset === 'custom') {\n return {\n from: st.from ? new Date(st.from + 'T00:00:00').toISOString() : '',\n to: st.to ? new Date(st.to + 'T23:59:59.999').toISOString() : '',\n };\n }\n var span = st.preset * 86400000, now = Date.now();\n return { from: new Date(now - span).toISOString(), to: new Date(now).toISOString() };\n}\n\n// Apply a time preset: update state + the segmented control + date visibility,\n// then refresh. Shared by the seg buttons and the active-chip \"clear\".\nfunction setTimePreset(preset) {\n state.sessTime.preset = preset;\n Array.prototype.forEach.call(document.querySelectorAll('#f-time button'), function (b) {\n b.classList.toggle('on', b.getAttribute('data-d') === String(preset));\n });\n var dates = $('#f-dates');\n if (dates) dates.hidden = preset !== 'custom';\n applyFilters();\n}\n\nfunction selectedOutcomes() {\n var out = [];\n Array.prototype.forEach.call(document.querySelectorAll('#f-outcome-menu input:checked'), function (cb) { out.push(cb.value); });\n return out;\n}\n\n// Populate the outcome checklist on first open (state.outcomeTypes loads async,\n// so build lazily and only mark built once it actually has items).\nfunction buildOutcomeMenu() {\n var menu = $('#f-outcome-menu');\n if (!menu || menu.getAttribute('data-built')) return;\n var types = state.outcomeTypes || [];\n if (!types.length) { menu.innerHTML = '<div class=\"flt-menu-empty\">No outcomes recorded yet.</div>'; return; }\n menu.innerHTML = types.map(function (t) {\n return '<label class=\"flt-menu-item\"><input type=\"checkbox\" value=\"' + esc(t.type) + '\" />' +\n '<span class=\"flt-menu-tx\">' + esc(outcomeLabel(t.type)) + '</span>' +\n '<span class=\"flt-menu-n\">' + num(t.sessions || 0) + '</span></label>';\n }).join('');\n menu.setAttribute('data-built', '1');\n Array.prototype.forEach.call(menu.querySelectorAll('input'), function (cb) { cb.onchange = applyFilters; });\n // Reflect the current (possibly URL-restored) selection now that the boxes exist.\n var selO = (state.filters && state.filters.outcomes) || [];\n Array.prototype.forEach.call(menu.querySelectorAll('input'), function (cb) { cb.checked = selO.indexOf(cb.value) >= 0; });\n}\n\nfunction updateOutcomeCount(n) {\n var el = $('#f-outcome-cnt');\n if (el) el.textContent = n ? String(n) : '';\n var btn = $('#f-outcome-btn');\n if (btn) btn.classList.toggle('on', n > 0);\n}\n\n// One active-filter chip with a per-filter clear (×).\nfunction chipHtml(cat, key, label, val) {\n return '<span class=\"flt-chip\"><span class=\"flt-chip-k\">' + esc(label) + '</span>' +\n '<span class=\"flt-chip-v\">' + esc(val) + '</span>' +\n '<button class=\"flt-chip-x\" type=\"button\" data-c=\"' + esc(cat) + '\" data-k=\"' + esc(key) + '\" aria-label=\"Remove filter\">×</button></span>';\n}\n\n// Clear one filter (from its chip ×) and re-apply.\nfunction clearChip(cat, key) {\n if (cat === 'time') { setTimePreset('all'); return; }\n if (cat === 'facet') {\n var sel = document.querySelector('.facet-filter[data-key=\"' + key + '\"]') as any;\n if (sel) sel.value = '';\n } else if (cat === 'outcome') {\n Array.prototype.forEach.call(document.querySelectorAll('#f-outcome-menu input'), function (cb) { if (cb.value === key) cb.checked = false; });\n } else if (cat === 'artifact') {\n var af = $('#f-artifact') as any; if (af) { af.value = ''; af.dataset.kind = ''; }\n } else if (cat === 'q') {\n var q = $('#f-q') as any; if (q) q.value = '';\n }\n applyFilters();\n}\n\n// The \"Active\" row: one chip per applied filter; chips double as per-filter clears.\nfunction renderActiveChips() {\n var host = $('#filter-active');\n if (!host) return;\n var f = state.filters || {};\n var labels = {};\n (state.facets || []).forEach(function (x) { labels[x.key] = x.label || x.key; });\n // Note: the time window is conveyed by the segmented control, so it isn't\n // repeated as a chip — only narrowing filters appear here.\n var chips = [];\n Object.keys(f.facets || {}).forEach(function (k) { chips.push(chipHtml('facet', k, labels[k] || k, f.facets[k])); });\n (f.outcomes || []).forEach(function (o) { chips.push(chipHtml('outcome', o, 'Outcome', outcomeLabel(o))); });\n if (f.artifact) chips.push(chipHtml('artifact', '', 'Artifact', f.artifact));\n if (f.q) chips.push(chipHtml('q', '', 'Search', f.q));\n\n if (!chips.length) { host.innerHTML = ''; return; }\n host.innerHTML = '<span class=\"flt-active-lbl\">Active</span>' + chips.join('') +\n '<button class=\"flt-clear-all\" type=\"button\">Clear all</button>';\n Array.prototype.forEach.call(host.querySelectorAll('.flt-chip-x'), function (b) {\n b.onclick = function () { clearChip(b.getAttribute('data-c'), b.getAttribute('data-k')); };\n });\n var ca = host.querySelector('.flt-clear-all') as any;\n if (ca) ca.onclick = clearAllFilters;\n}\n\n// ---- artifact-search typeahead (session-list filter) -----------------------\n\nfunction acFetch() {\n var inp = $('#f-artifact');\n if (!inp) return;\n var q = inp.value.trim();\n var kind = inp.dataset.kind || '';\n if (q.length < 1) { acClose(); return; }\n get('/api/artifact-suggest?q=' + encodeURIComponent(q) + (kind ? '&kind=' + encodeURIComponent(kind) : '')).then(function (items) {\n state.ac = { items: items || [], sel: -1 };\n acRender();\n });\n}\n\nfunction acItemHtml(it, idx, sel) {\n var label;\n if (it.kind === 'file') {\n var parts = String(it.value).split('/');\n var base = parts.pop();\n var dir = parts.length ? '…/' + parts.slice(-2).join('/') : '';\n label = esc(base) + (dir ? ' <span class=\"ac-dir\">' + esc(dir) + '</span>' : '');\n } else {\n label = esc(it.label);\n }\n return '<div class=\"ac-item' + (sel ? ' sel' : '') + '\" data-i=\"' + idx + '\">' +\n '<span class=\"ac-kind\">' + esc(it.kind) + '</span><span class=\"ac-label\">' + label + '</span></div>';\n}\n\nfunction acRender() {\n var menu = $('#f-artifact-menu');\n if (!menu) return;\n var items = state.ac.items || [];\n if (!items.length) { acClose(); return; }\n menu.innerHTML = items.map(function (it, i) { return acItemHtml(it, i, i === state.ac.sel); }).join('');\n menu.classList.add('on');\n Array.prototype.forEach.call(menu.children, function (el) {\n // mousedown (not click) + preventDefault so the input's blur doesn't fire first\n el.onmousedown = function (e) { e.preventDefault(); acPick(parseInt(el.getAttribute('data-i'), 10)); };\n });\n}\n\nfunction acPick(i) {\n var it = (state.ac.items || [])[i];\n if (!it) return;\n var af = $('#f-artifact');\n af.value = it.value;\n af.dataset.kind = it.kind || ''; // narrow the filter to the picked kind\n acClose();\n applyFilters();\n}\n\nfunction acClose() {\n state.ac = { items: [], sel: -1 };\n var m = $('#f-artifact-menu');\n if (m) m.classList.remove('on');\n}\n\nfunction acKeydown(e) {\n var menu = $('#f-artifact-menu');\n if (!menu || !menu.classList.contains('on')) return;\n var items = state.ac.items || [];\n if (e.key === 'ArrowDown') { e.preventDefault(); state.ac.sel = Math.min(items.length - 1, state.ac.sel + 1); acRender(); }\n else if (e.key === 'ArrowUp') { e.preventDefault(); state.ac.sel = Math.max(0, state.ac.sel - 1); acRender(); }\n else if (e.key === 'Enter') { if (state.ac.sel >= 0) { e.preventDefault(); acPick(state.ac.sel); } }\n else if (e.key === 'Escape') { acClose(); }\n}\n\nexport function applyFilters() {\n var facets = {};\n Array.prototype.forEach.call(document.querySelectorAll('.facet-filter'), function (s) {\n if (s.value) facets[s.getAttribute('data-key')] = s.value;\n });\n var af = $('#f-artifact');\n var win = sessWindow();\n // The outcome popover is built lazily on first open, so before that the DOM has\n // no checkboxes to read — fall back to the state (which a URL restore populated)\n // rather than wiping it. Once built, the DOM is the source of truth.\n var menu = $('#f-outcome-menu');\n var outcomes = menu && menu.getAttribute('data-built') ? selectedOutcomes() : ((state.filters && state.filters.outcomes) || []);\n updateOutcomeCount(outcomes.length);\n state.filters = {\n facets: facets,\n q: $('#f-q') ? $('#f-q').value : '',\n artifact: af ? af.value : '',\n artifactKind: af && af.dataset.kind ? af.dataset.kind : '',\n outcomes: outcomes,\n from: win.from,\n to: win.to\n };\n updateMoreCount();\n renderActiveChips();\n loadSessions();\n syncHash({ replace: true }); // mirror the filter into the URL, in place (no history spam)\n}\n\nexport function renderSessions(rows) {\n if (!rows || !rows.length) { $('#sessions').innerHTML = '<div class=\"empty\">No sessions match.</div>'; return; }\n var head = '<tr><th>Session</th><th>Date</th><th>Cost</th><th>Outcomes</th><th>Complexity</th><th>Work type</th></tr>';\n var body = rows.map(function (r) {\n // Outcomes in the canonical order (pr_merged first … session_success last).\n var outs = (r.outcomes || []).slice().sort(function (a, b) { return outcomeRank(a) - outcomeRank(b); });\n return '<tr class=\"srow\" data-id=\"' + esc(r.id) + '\">' +\n '<td><span class=\"s-title\" title=\"' + esc(r.title) + '\">' + esc(r.title) + '</span></td>' +\n '<td class=\"num nowrap\">' + esc(dayOf(r.startedAt)) + '</td>' +\n '<td class=\"num nowrap\">' + usd(r.costUsd) + '</td>' +\n '<td class=\"cell-tags\">' + tagCell(outs) + '</td>' +\n '<td>' + esc(r.complexity || '—') + '</td>' +\n '<td class=\"cell-tags\">' + tagCell(r.useCase) + '</td></tr>';\n }).join('');\n $('#sessions').innerHTML = '<table>' + head + body + '</table>';\n Array.prototype.forEach.call(document.querySelectorAll('.srow'), function (tr) {\n tr.onclick = function () {\n var f = state.filters || {};\n // Carry the active artifact filter (from \"See sessions\") into the drawer so\n // the transcript opens focused on that feature / PR.\n openDetail(tr.getAttribute('data-id'), f.artifact ? { kind: f.artifactKind, val: f.artifact } : null);\n };\n });\n // \"+N\" reveals the rest of a capped tag cell in place (without opening the row).\n Array.prototype.forEach.call(document.querySelectorAll('#sessions .tag-more'), function (b) {\n b.onclick = function (e) {\n e.stopPropagation();\n var rest = b.previousElementSibling;\n if (rest) rest.classList.add('on');\n b.style.display = 'none';\n };\n });\n}\n\n// A table cell of tags, capped at 2 with a \"+N\" that reveals the rest in place,\n// keeping rows to a single line by default.\nfunction tagCell(items) {\n items = items || [];\n if (!items.length) return '—';\n function t(x) { return '<span class=\"tag\">' + esc(x) + '</span>'; }\n var head = items.slice(0, 2).map(t).join('');\n if (items.length <= 2) return head;\n return head + '<span class=\"tag-rest\">' + items.slice(2).map(t).join('') + '</span>' +\n '<button class=\"tag-more\" type=\"button\">+' + (items.length - 2) + '</button>';\n}\n\n// Render a list of chips with a default cap; the overflow is rendered up front\n// but hidden behind a \"show all N\" toggle that expands in place (no re-fetch),\n// keeping long file/feature lists from bloating the summary.\nfunction chipList(items, cap, render) {\n if (!items.length) return '';\n var head = items.slice(0, cap).map(render).join('');\n if (items.length <= cap) return head;\n var rest = '<span class=\"chip-rest\">' + items.slice(cap).map(render).join('') + '</span>';\n var more = '<button class=\"chip-more\" type=\"button\" data-n=\"' + items.length + '\">show all ' + items.length + ' ›</button>';\n return head + rest + more;\n}\n\n// One-line, whitespace-collapsed preview for the transcript outline entries.\nfunction clipLine(s, n) {\n var t = String(s || '').replace(/\\s+/g, ' ').trim();\n return t.length > n ? t.slice(0, n) + '…' : t;\n}\n\n// Restart a CSS flash animation on an element (remove → reflow → re-add) so a\n// repeated jump to the same anchor re-triggers the highlight.\nfunction flashEl(el) {\n if (!el) return;\n el.classList.remove('flash');\n void el.offsetWidth;\n el.classList.add('flash');\n}\n\n// Flash when the element ARRIVES in view (center reaches the viewport's central\n// band), not after the smooth-scroll's easing tail. Falls back to scroll-stopped /\n// a frame cap so it always fires.\nfunction flashOnSettle(el) {\n if (!el) return;\n var last = null, stable = 0, frames = 0;\n function tick() {\n frames++;\n var r = el.getBoundingClientRect();\n var vh = window.innerHeight || document.documentElement.clientHeight || 800;\n var center = r.top + r.height / 2;\n var inView = center > vh * 0.25 && center < vh * 0.75;\n if (last !== null && Math.abs(r.top - last) < 0.5) stable++; else stable = 0;\n last = r.top;\n if (inView || stable >= 2 || frames > 90) { flashEl(el); return; }\n requestAnimationFrame(tick);\n }\n requestAnimationFrame(tick);\n}\n\n// ---- Files-changed view -----------------------------------------------------\n\n// Minimal line-level diff (LCS backtrace) → rows tagged ' ' (context), '-', '+'.\n// Hunks are small (capped server-side), so O(n·m) is fine.\nfunction diffLines(a, b) {\n var A = a ? a.split('\\n') : [], B = b ? b.split('\\n') : [];\n var n = A.length, m = B.length, i, j;\n var dp = [];\n for (i = 0; i <= n; i++) dp.push(new Array(m + 1).fill(0));\n for (i = n - 1; i >= 0; i--)\n for (j = m - 1; j >= 0; j--)\n dp[i][j] = A[i] === B[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);\n var rows = []; i = 0; j = 0;\n while (i < n && j < m) {\n if (A[i] === B[j]) { rows.push({ t: ' ', s: A[i] }); i++; j++; }\n else if (dp[i + 1][j] >= dp[i][j + 1]) { rows.push({ t: '-', s: A[i] }); i++; }\n else { rows.push({ t: '+', s: B[j] }); j++; }\n }\n while (i < n) { rows.push({ t: '-', s: A[i] }); i++; }\n while (j < m) { rows.push({ t: '+', s: B[j] }); j++; }\n return rows;\n}\n\nvar DIFF_ROW_CAP = 60;\n\n// Apply an Edit (old→new, first occurrence) to running content, so a later Write\n// to the same file can be diffed against its actual prior state.\nfunction applyEdit(s, oldStr, newStr) {\n if (!oldStr) return s;\n var i = s.indexOf(oldStr);\n return i < 0 ? s : s.slice(0, i) + newStr + s.slice(i + oldStr.length);\n}\n\n// Diff rows for one edit given the file's running content `prev`. A Write is\n// diffed against the previous content (so repeated rewrites show their DELTA,\n// not the whole file each time); an Edit is its own old→new hunk(s). Returns the\n// rows and the updated running content.\nfunction editRows(e, prev) {\n if (e.op === 'write') {\n var content = (e.hunks[0] && e.hunks[0].ins) || '';\n return { rows: diffLines(prev, content), next: content };\n }\n var rows = [], next = prev;\n (e.hunks || []).forEach(function (h, hi) {\n if (hi) rows.push({ t: '~', s: '' }); // separator between MultiEdit hunks\n rows = rows.concat(diffLines(h.del, h.ins));\n if (next) next = applyEdit(next, h.del, h.ins);\n });\n return { rows: rows, next: next };\n}\n\nfunction rowHtml(r) {\n if (r.t === '~') return '<div class=\"dl sep\">⋯</div>';\n var cls = r.t === '+' ? 'add' : r.t === '-' ? 'del' : 'ctx';\n var gut = r.t === '+' ? '+' : r.t === '-' ? '−' : ' ';\n return '<div class=\"dl ' + cls + '\"><span class=\"dg\">' + gut + '</span><span class=\"dt\">' + esc(r.s) + '</span></div>';\n}\n\n// Show just the tail of a long absolute path (last 2 dirs + filename), bolding\n// the basename; the full path stays available on hover (title).\nfunction shortPathHtml(p) {\n var parts = String(p || '').split('/').filter(Boolean);\n var base = parts.length ? parts.pop() : String(p || '');\n var dirs = parts.slice(-2);\n var prefix = (parts.length > dirs.length ? '…/' : '') + (dirs.length ? dirs.join('/') + '/' : '');\n return (prefix ? '<span class=\"fc-dir\">' + esc(prefix) + '</span>' : '') +\n '<span class=\"fc-base\">' + esc(base) + '</span>';\n}\n\n// Compute each edit's diff rows ONCE, in chronological order, maintaining a\n// per-file running content so consecutive Writes diff against the prior state.\n// Also attach the agent's nearest narration (its \"why\" at the edit's altitude).\nfunction prepEdits(edits, transcript) {\n var prevByFile = {};\n edits.forEach(function (e) {\n e._first = !prevByFile[e.path];\n var r = editRows(e, prevByFile[e.path] || '');\n e._rows = r.rows;\n prevByFile[e.path] = r.next;\n e._add = 0; e._del = 0;\n e._rows.forEach(function (x) { if (x.t === '+') e._add++; else if (x.t === '-') e._del++; });\n e._narr = narrationFor(e, transcript);\n });\n}\n\n// Nearest assistant text turn AT or before the edit's turn, but not before the\n// prompting user turn — the agent's local rationale for this specific change.\nfunction narrationFor(e, transcript) {\n var lo = e.userTurn >= 0 ? e.userTurn + 1 : 0;\n for (var k = Math.min(e.turn, transcript.length - 1); k >= lo; k--) {\n var t = transcript[k];\n if (t && t.role === 'assistant' && t.text) return t.text;\n }\n return '';\n}\n\n// Stable grouping that preserves first-seen order of keys.\nfunction groupBy(items, keyFn) {\n var order = [], map = {};\n items.forEach(function (it) {\n var k = keyFn(it);\n if (!(k in map)) { map[k] = []; order.push(k); }\n map[k].push(it);\n });\n return order.map(function (k) { return { key: k, items: map[k] }; });\n}\n\nfunction sumAddDel(edits) {\n var add = 0, del = 0;\n edits.forEach(function (e) { add += e._add; del += e._del; });\n return { add: add, del: del };\n}\n\n// One edit's diff block. showNarr gates the agent narration caption (deduped\n// against the previous edit by the caller). The jump-to-intent lives on the\n// enclosing prompt/note header, not per edit.\nfunction editHtml(e, showNarr) {\n var rows = e._rows || [];\n var head = rows.slice(0, DIFF_ROW_CAP).map(rowHtml).join('');\n var rest = rows.length > DIFF_ROW_CAP\n ? '<div class=\"dl-rest\">' + rows.slice(DIFF_ROW_CAP).map(rowHtml).join('') + '</div>' +\n '<button class=\"fc-rows-more\" type=\"button\">+ ' + (rows.length - DIFF_ROW_CAP) + ' more lines</button>'\n : '';\n var verb = e.op === 'write' ? (e._first ? 'Created' : 'Rewrote') : e.op === 'multiedit' ? 'Edited · ' + e.hunks.length + ' hunks' : 'Edited';\n var stat = ' (+' + e._add + (e._del ? ' −' + e._del : '') + ')';\n var narr = showNarr && e._narr ? '<div class=\"fc-narr\" title=\"' + esc(clipLine(e._narr, 600)) + '\">▸ ' + esc(clipLine(e._narr, 240)) + '</div>' : '';\n var diff = rows.length ? '<div class=\"fc-diff\">' + head + rest + '</div>'\n : '<div class=\"fc-noop\">no textual change (or beyond the captured window)</div>';\n return '<div class=\"fc-edit\">' + narr +\n '<div class=\"fc-edit-h\"><span class=\"fc-op\">' + esc(verb) + stat + '</span></div>' + diff + '</div>';\n}\n\n// A collapsible (collapsed by default) per-file card: header with path + stats,\n// body supplied by the caller (plain diffs under a note, or prompt-grouped in the\n// by-file view).\nfunction fileCardHtml(path, edits, bodyHtml) {\n var c = sumAddDel(edits);\n return '<div class=\"fc-file collapsed\" data-path=\"' + esc(path) + '\"><button class=\"fc-head\" type=\"button\">' +\n '<span class=\"fc-caret\">▾</span><span class=\"fc-path\" title=\"' + esc(path) + '\">' + shortPathHtml(path) + '</span>' +\n '<span class=\"fc-stat\"><span class=\"fc-add\">+' + c.add + '</span> <span class=\"fc-del\">−' + c.del + '</span> · ' +\n edits.length + ' edit' + (edits.length > 1 ? 's' : '') + '</span></button>' +\n '<div class=\"fc-body\">' + bodyHtml + '</div></div>';\n}\n\n// User-message header (truncated preview + expand, reusing the .msg show-more).\nfunction msgPreviewHtml(msg) {\n var t = String(msg || '');\n if (!t) return '<span class=\"fc-pseg-empty\">(work before the first prompt)</span>';\n if (t.length <= 200) return esc(t);\n return '<span class=\"msg\"><span class=\"msg-prev\">' + esc(t.slice(0, 200)) + ' …</span>' +\n '<span class=\"msg-full\">' + esc(t) + '</span></span><button class=\"msg-more\" type=\"button\">Show more ↓</button>';\n}\n\n// Within a file, group edits by the prompt that drove them and head each run with\n// the user message (+ → transcript); note captions add finer per-edit context.\nfunction promptSegmentsHtml(edits, transcript) {\n return groupBy(edits, function (e) { return String(e.userTurn); }).map(function (g) {\n var ut = parseInt(g.key, 10);\n var msg = ut >= 0 && transcript[ut] ? transcript[ut].text : '';\n var jump = ut >= 0 ? '<button class=\"fc-jump\" type=\"button\" data-u=\"' + ut + '\" title=\"Open this prompt in the transcript\">→ transcript</button>' : '';\n var lastNarr = '';\n var body = g.items.map(function (e) {\n var show = e._narr && e._narr !== lastNarr;\n if (e._narr) lastNarr = e._narr;\n return editHtml(e, show);\n }).join('');\n return '<div class=\"fc-pseg\"><div class=\"fc-pseg-h\"><div class=\"fc-pseg-msg\">' + msgPreviewHtml(msg) + '</div>' + jump + '</div>' + body + '</div>';\n }).join('');\n}\n\nfunction filesHtml(edits, transcript) {\n if (!edits || !edits.length) return '<div class=\"empty\">No file changes in this session.</div>';\n return groupBy(edits, function (e) { return e.path; })\n .map(function (g) { return fileCardHtml(g.key, g.items, promptSegmentsHtml(g.items, transcript)); }).join('');\n}\n\nvar _activeTab = 'transcript';\nvar _activeSessionId: string | null = null;\n\nexport function openDetail(id, focus?: any) {\n // Reflect the open session in the URL immediately (a shareable, Back-closable\n // entry) — before the async fetch. A stale/deleted id reverts below.\n state.open = id;\n syncHash();\n get('/api/session?id=' + encodeURIComponent(id)).then(function (d) {\n if (!d || d.error) {\n if (state.open === id) { state.open = null; syncHash({ replace: true }); }\n return;\n }\n var s = d.session, a = d.annotations || {};\n\n // Sticky-header pieces (title+close, tab subnav, transcript nav) are assembled\n // into one .drawer-head at the end, so they pin together as you scroll.\n var headTop = '<div class=\"drawer-head-top\"><h2>' + esc(s.title || '(untitled)') + '</h2>' +\n '<button class=\"x\" type=\"button\" id=\"drawerCloseBtn\">close</button></div>';\n var fileCount = (d.artifacts || []).filter(function (x) { return x.kind === 'file'; }).length;\n var tabs = '<div class=\"drawer-tabs\">' +\n '<button class=\"dtab on\" type=\"button\" data-dtab=\"transcript\">Transcript</button>' +\n (fileCount ? '<button class=\"dtab\" type=\"button\" data-dtab=\"files\">Files (' + fileCount + ')</button>' : '') +\n '<button class=\"dtab\" type=\"button\" data-dtab=\"summary\">Summary</button>' +\n '</div>';\n\n // ---- Summary pane: vitals, registry-driven dimensions, intent, artifacts --\n // `when` and `cost` are intrinsic (a timestamp and a measure), not facets, so\n // they stay fixed; every categorical dimension below comes from the facet\n // registry (roles include 'detail'), so a new processor facet shows up here\n // with no edits. enum values render as badges; everything else as text.\n var sum = '<div class=\"kv\">';\n sum += '<span class=\"k\">when</span><span class=\"num\">' + esc(dayOf(s.startedAt)) + '</span>';\n sum += '<span class=\"k\">cost</span><span class=\"num\">' + usd(s.costUsd) + '</span>';\n (d.facets || []).forEach(function (f) {\n var vals = Array.isArray(f.value) ? f.value : (f.value == null || f.value === '' ? [] : [f.value]);\n var disp = !vals.length ? '—'\n : f.type === 'enum' ? vals.map(function (v) { return badge(v); }).join(' ')\n : vals.map(esc).join(', ');\n sum += '<span class=\"k\">' + esc(f.label) + '</span><span>' + disp + '</span>';\n });\n sum += '</div>';\n if (a.intent_summary) sum += '<div class=\"sect-h\">Intent</div><div>' + esc(a.intent_summary) + '</div>';\n var decisions = Array.isArray(a.decisions) ? a.decisions : [];\n if (decisions.length) {\n sum += '<div class=\"sect-h\">Key decisions (' + decisions.length + ')</div>';\n sum += '<ul class=\"decisions\">' +\n decisions.map(function (d) { return '<li>' + esc(d) + '</li>'; }).join('') +\n '</ul>';\n }\n\n var arts = d.artifacts || [];\n var sessionId = s.id;\n var feats = arts.filter(function (x) { return x.kind === 'feature'; });\n sum += '<div class=\"sect-h\">Features (' + feats.length + ') <button class=\"link-add-btn\" type=\"button\" data-link-kind=\"feature\" data-session-id=\"' + esc(sessionId) + '\" title=\"Link feature\">+</button></div>';\n if (feats.length) {\n sum += chipList(feats, 6, function (f) {\n var xBtn = '<button class=\"link-remove-btn\" type=\"button\" data-artifact-id=\"' + esc(f.id) + '\" data-session-id=\"' + esc(sessionId) + '\" title=\"Unlink\">×</button>';\n return '<span class=\"tag click\" data-art=\"' + esc(f.title) + '\" data-kind=\"feature\">' +\n esc(f.title) + (f.source === 'derived' ? ' (proposed)' : '') + xBtn + '</span>';\n });\n }\n sum += '<div class=\"link-add-area\" data-link-kind=\"feature\" data-session-id=\"' + esc(sessionId) + '\"></div>';\n var prs = arts.filter(function (x) { return x.kind === 'pr'; });\n sum += '<div class=\"sect-h\">Pull requests (' + prs.length + ') <button class=\"link-add-btn\" type=\"button\" data-link-kind=\"pr\" data-session-id=\"' + esc(sessionId) + '\" title=\"Link PR\">+</button></div>';\n if (prs.length) {\n sum += chipList(prs, 8, function (p) {\n var xBtn = p.source === 'user' ? '<button class=\"link-remove-btn\" type=\"button\" data-artifact-id=\"' + esc(p.id) + '\" data-session-id=\"' + esc(sessionId) + '\" title=\"Unlink\">×</button>' : '';\n var label = (p.repo ? esc(p.repo) + ' ' : '') + '#' + esc(p.ident) + (p.status ? ' (' + esc(p.status) + ')' : '');\n // Content-match attribution as a subtle inline suffix (share of the PR authored by the agent).\n var ai = p.confidence != null ? '<span class=\"ai-note\" title=\"Share of this PR authored in this session\"> · ' + Math.round(p.confidence * 100) + '% AI</span>' : '';\n return '<span class=\"tag click\" data-art=\"' + esc(p.externalId || p.ident) + '\" data-kind=\"pr\">' + label + ai + xBtn + '</span>';\n });\n }\n sum += '<div class=\"link-add-area\" data-link-kind=\"pr\" data-session-id=\"' + esc(sessionId) + '\"></div>';\n var files = arts.filter(function (x) { return x.kind === 'file'; });\n if (files.length) {\n sum += '<div class=\"sect-h\">Files touched (' + files.length + ')</div>';\n sum += chipList(files, 10, function (f) {\n return '<span class=\"tag click\" data-art=\"' + esc(f.ident) + '\" data-kind=\"file\">' + esc(f.ident) + '</span>';\n });\n }\n var outs = d.outcomes || [];\n if (outs.length) {\n sum += '<div class=\"sect-h\">Outcomes</div>';\n sum += chipList(outs, 10, function (o) { return '<span class=\"tag\">' + esc(o.type) + '</span>'; });\n }\n if (fileCount) sum += '<div class=\"see-tx-wrap\"><button class=\"see-tx\" type=\"button\" data-tab=\"files\">See files changed →</button></div>';\n\n // ---- Transcript pane: the main thread + one tab per subagent. ----------\n // Claude Code writes each subagent (Task/Agent spawn) to its own sidechain\n // transcript; turns carry an `agentId` so we split them out of the main\n // thread into per-subagent scopes. The main thread's spawning call links to\n // its subagent's scope; the subagent links back to the call.\n // Within a scope, Claude Code emits each tool call as its OWN tool-only\n // assistant message, so \"a long series of tool calls\" is a RUN of consecutive\n // such turns — we keep text turns separate but coalesce each tool-only run\n // into one collapsible block (first few chips + \"+N more\").\n var TX = d.transcript || { turns: [], subagents: [], blocks: [] };\n var allTurns = TX.turns || [];\n var subMeta = {}; // agentId -> {agentType, description, toolUseId}\n (TX.subagents || []).forEach(function (sa) { subMeta[sa.agentId] = sa; });\n\n // ---- Block filter: focus the transcript on one PR / feature / use-case. ----\n // Each main-thread turn carries its block (server) and blocks carry labels.\n // A \"View by\" dimension is offered only when it has ≥2 distinct values;\n // picking a value hides the rest behind a named \"··· N turns ···\" gap.\n var TXB = TX.blocks || [];\n function blkVal(bi, dim) {\n var b = TXB[bi]; if (!b) return null;\n return dim === 'pr' ? (b.pr ? b.pr.ident : null) : dim === 'feature' ? (b.feature ? b.feature.id : null) : (b.useCase || null);\n }\n function blkLabel(bi, dim) {\n var b = TXB[bi]; if (!b) return null;\n return dim === 'pr' ? (b.pr ? '#' + b.pr.ident : null) : dim === 'feature' ? (b.feature ? (b.feature.title || 'feature') : null) : (b.useCase || null);\n }\n // Per-block size (any main turn, incl. each tool call) → the proportional\n // segment bar showing where in the session each value's stretches fall.\n var sizePerBlock = {}, totalSize = 0;\n allTurns.forEach(function (t) {\n if (t.sidechain || t.blockIdx == null) return;\n sizePerBlock[t.blockIdx] = (sizePerBlock[t.blockIdx] || 0) + 1; totalSize++;\n });\n // A mini sparkline of the whole session with this value's blocks lit — position\n // + fragmentation at a glance (the count already gives magnitude).\n function segBar(dim, key) {\n if (!TXB.length || !totalSize) return '';\n var W = 46, H = 8, x = 0, rects = '';\n TXB.forEach(function (b) {\n var w = (sizePerBlock[b.idx] || 0) / totalSize * W;\n if (w <= 0) return;\n var lit = blkVal(b.idx, dim) === key;\n rects += '<rect class=\"' + (lit ? 'lit' : 'trk') + '\" x=\"' + x.toFixed(1) + '\" y=\"0\" width=\"' + Math.max(0.7, w).toFixed(1) + '\" height=\"' + H + '\" rx=\"1\"></rect>';\n x += w;\n });\n return '<svg class=\"tx-fbar\" viewBox=\"0 0 ' + W + ' ' + H + '\" width=\"' + W + '\" height=\"' + H + '\" preserveAspectRatio=\"none\">' + rects + '</svg>';\n }\n var DIM_DEFS = [{ dim: 'pr', label: 'PRs' }, { dim: 'feature', label: 'Features' }, { dim: 'use_case', label: 'Work type' }];\n var dimsAvail = DIM_DEFS.map(function (def) {\n var byKey = {}, vals = [];\n TXB.forEach(function (b) {\n var k = blkVal(b.idx, def.dim);\n if (k == null || byKey[k]) return;\n byKey[k] = 1; vals.push({ key: k, label: blkLabel(b.idx, def.dim) });\n });\n return { dim: def.dim, label: def.label, values: vals };\n }).filter(function (d) { return d.values.length >= 2; });\n var fDim = dimsAvail.length ? dimsAvail[0].dim : null;\n var fVal = null; // null = All\n // Match a summary artifact chip (or an arrival focus) to a View-by dimension\n // VALUE — feature by title, PR by number. Null when that dimension isn't\n // filterable (≤1 value) or there's no match.\n function resolveDimValue(kind, val) {\n if ((kind !== 'feature' && kind !== 'pr') || val == null) return null;\n var fd = dimsAvail.filter(function (d) { return d.dim === kind; })[0];\n if (!fd) return null;\n var fv0 = String(val), digs = (fv0.match(/(\\d+)\\s*$/) || [])[1];\n var hit = fd.values.filter(function (v) {\n return v.key === fv0 || v.label === fv0 || '#' + v.key === fv0 || (kind === 'pr' && digs && v.key === digs);\n })[0];\n return hit ? hit.key : null;\n }\n // Focus the transcript on a dimension value (a summary chip → the transcript).\n // When the value isn't filterable (only one of its kind), just open the\n // transcript unfiltered — a single feature/PR ≈ the whole session.\n function focusDim(dim, key) {\n if (activeScope !== 'main') switchScope('main');\n if (key != null && dimsAvail.filter(function (d) { return d.dim === dim; })[0]) { fDim = dim; fVal = key; }\n else fVal = null;\n renderFilterBar();\n showTab('transcript');\n applyTxFilter(true);\n }\n // Arrived via an artifact drill (\"See sessions\") → pre-select that value.\n if (focus && focus.val) {\n var fk = resolveDimValue(focus.kind, focus.val);\n if (fk != null) { fDim = focus.kind; fVal = fk; }\n }\n function filterBarHtml() {\n if (!dimsAvail.length) return '';\n var dd = dimsAvail.filter(function (d) { return d.dim === fDim; })[0] || dimsAvail[0];\n var sw = dimsAvail.length > 1\n ? '<select class=\"tx-fdim\">' + dimsAvail.map(function (d) { return '<option value=\"' + d.dim + '\"' + (d.dim === fDim ? ' selected' : '') + '>' + esc(d.label) + '</option>'; }).join('') + '</select>'\n : '<span class=\"tx-fdim-lbl\">' + esc(dd.label) + '</span>';\n var chips = '<button class=\"tx-fchip' + (fVal == null ? ' on' : '') + '\" type=\"button\" data-v=\"\">All</button>' +\n dd.values.map(function (v) {\n return '<button class=\"tx-fchip' + (fVal === v.key ? ' on' : '') + '\" type=\"button\" data-v=\"' + esc(v.key) + '\">' +\n esc(v.label) + segBar(dd.dim, v.key) + '</button>';\n }).join('');\n return '<span class=\"tx-grp-lbl\">View by</span>' + sw + '<span class=\"tx-fchips\">' + chips + '</span>';\n }\n\n var TOOLCAP = 4;\n var errSeq = 0; // running id per failed tool call → error-panel anchor (unique across scopes)\n var errSink = null; // the scope currently rendering: its error-id list (errPanelHtml pushes here)\n var CMD_COLLAPSE_LINES = 2; // commands > this many lines get a collapse toggle\n\n function toolBlockHtml(tl) {\n var agent = tl.agentId && subMeta[tl.agentId];\n var go = agent ? '<span class=\"tool-chip-go\">view →</span>' : '';\n var attr = agent ? ' data-agent=\"' + esc(tl.agentId) + '\"' : '';\n var errBadge = tl.ok ? '' : '<span class=\"tool-badge err\">error</span>';\n // Command/input — sits inline next to the tool name; collapsible if >2 lines\n var cmd = '';\n if (tl.command) {\n var lines = tl.command.split('\\n');\n if (lines.length > CMD_COLLAPSE_LINES) {\n var preview = lines.slice(0, CMD_COLLAPSE_LINES).join('\\n');\n cmd = '<div class=\"tool-block-cmd collapsible\">' +\n '<pre class=\"tool-cmd-pre\">' + esc(preview) + '</pre>' +\n '<pre class=\"tool-cmd-full\">' + esc(tl.command) + '</pre>' +\n '<button class=\"tool-cmd-toggle\" type=\"button\">' +\n '<span class=\"tool-cmd-arrow\" style=\"transform:rotate(90deg)\">▶</span> expand</button></div>';\n } else {\n cmd = '<div class=\"tool-block-cmd\"><pre class=\"tool-cmd-pre\">' + esc(tl.command) + '</pre></div>';\n }\n }\n // Body: tool-specific output, collapsed by default behind an inline toggle\n var body = '';\n var toggle = '';\n if (tl.hunks && tl.hunks.length) {\n // Edit/Write: render as inline diff (same style as Files tab)\n var diffRows = [];\n tl.hunks.forEach(function (h, hi) {\n if (hi) diffRows.push({ t: '~', s: '' });\n diffRows = diffRows.concat(diffLines(h.del, h.ins));\n });\n var diffHead = diffRows.slice(0, DIFF_ROW_CAP).map(rowHtml).join('');\n var diffRest = diffRows.length > DIFF_ROW_CAP\n ? '<div class=\"dl-rest\">' + diffRows.slice(DIFF_ROW_CAP).map(rowHtml).join('') + '</div>' +\n '<button class=\"fc-rows-more\" type=\"button\">+ ' + (diffRows.length - DIFF_ROW_CAP) + ' more lines</button>'\n : '';\n body = '<div class=\"tool-block-body\"><div class=\"fc-diff\">' + diffHead + diffRest + '</div></div>';\n toggle = '<button class=\"tool-out-toggle\" type=\"button\">diff</button>';\n } else if (tl.output && tl.ok) {\n // Generic tool output. Failed calls already surface their result in the error\n // panel below, so an output toggle here would just duplicate it — skip it.\n body = '<div class=\"tool-block-body\"><pre class=\"tool-output-pre\">' + esc(tl.output) + '</pre></div>';\n toggle = '<button class=\"tool-out-toggle\" type=\"button\">output</button>';\n }\n // Single inline row: name · command · (output toggle / agent link) — replaces\n // the old dedicated header row to keep each tool call compact.\n var row = '<div class=\"tool-block-row\"' + attr + '>' +\n '<span class=\"tool-block-name\">' + esc(tl.name) + '</span>' +\n errBadge + cmd + go + toggle + '</div>';\n // Error panel for failed calls (stepper jump target)\n var errPanel = '';\n if (!tl.ok && tl.error) {\n errSeq++; // count total errors (errCount)\n var anchor = tl.idx != null ? tl.idx : 's' + errSeq; // stable per-call anchor for deep-links\n if (errSink) errSink.push(anchor);\n errPanel = '<div class=\"tx-error\" id=\"txerr-' + anchor + '\">' +\n '<div class=\"tx-error-h\">⚠ ' + esc(tl.name) + '</div>' +\n '<div class=\"tx-error-b\">' + esc(tl.error) + '</div></div>';\n }\n return '<div class=\"tool-block' + (tl.ok ? '' : ' err') + (agent ? ' agent' : '') + '\">' +\n row + body + errPanel + '</div>';\n }\n\n function toolsHtml(tools) {\n var head = tools.slice(0, TOOLCAP).map(toolBlockHtml).join('');\n var restArr = tools.slice(TOOLCAP);\n var rest = restArr.length\n ? '<div class=\"tool-rest\">' + restArr.map(toolBlockHtml).join('') + '</div>' +\n '<button class=\"tool-more\" type=\"button\" data-n=\"' + restArr.length + '\">+ ' + restArr.length +\n ' more tool call' + (restArr.length > 1 ? 's' : '') + '</button>'\n : '';\n return '<div class=\"tools\">' + head + rest + '</div>';\n }\n // A prominent, clickable banner standing in for a subagent-spawning call, so\n // the link into the subagent's scope is easy to find (and a stable anchor for\n // the subagent's \"back\" link).\n function spawnBlockHtml(sp, blk) {\n var m = subMeta[sp.agentId] || {};\n var lbl = (m.agentType || 'subagent') + (m.description ? ' · ' + m.description : '');\n var ba = blk != null ? ' data-blk=\"' + blk + '\"' : '';\n return '<button class=\"tx-spawn\" type=\"button\" id=\"txspawn-' + esc(sp.agentId) + '\" data-agent=\"' + esc(sp.agentId) + '\"' + ba + '>' +\n '<span class=\"tx-spawn-ico\">🤖</span><span class=\"tx-spawn-lbl\">Spawned subagent · ' + esc(lbl) + '</span>' +\n '<span class=\"tx-spawn-go\">view transcript →</span></button>';\n }\n // Message text, collapsed to a preview with a Show more/less toggle when long\n // (assistant/user text is capped at 20k server-side; this keeps walls of text\n // from dominating the scroll while still letting you read the whole thing).\n var MSG_PREVIEW = 1200;\n // `md` renders the text as Markdown (assistant/subagent responses); user\n // prompts stay plain-escaped so their literal formatting is preserved.\n function textBlock(text, md?) {\n var t = String(text || '');\n if (!t) return '';\n var render = md ? renderMd : esc;\n var cls = 'text' + (md ? ' md' : '');\n if (t.length <= 2000) return '<div class=\"' + cls + '\">' + render(t) + '</div>';\n return '<div class=\"' + cls + ' msg\"><span class=\"msg-prev\">' + render(t.slice(0, MSG_PREVIEW)) + ' …</span>' +\n '<span class=\"msg-full\">' + render(t) + '</span></div>' +\n '<button class=\"msg-more\" type=\"button\">Show more ↓</button>';\n }\n\n // Partition turns into scopes (main thread first, then each subagent in\n // first-seen order), keeping every turn's GLOBAL index for its txt-<i> anchor\n // (the Files view links there, so indices must stay stable across scopes).\n var scopeOrder = ['main'];\n var scopeItems = { main: [] };\n var scopeOfTurn = {}; // global turn index -> scope key\n allTurns.forEach(function (t, i) {\n var key = t.agentId || 'main';\n if (!(key in scopeItems)) { scopeItems[key] = []; scopeOrder.push(key); }\n scopeItems[key].push({ gi: i, t: t });\n scopeOfTurn[i] = key;\n });\n\n // Render one scope's turns to HTML, collecting its user turns (for the nav)\n // and pushing its error-panel ids into the scope's errIds via errSink.\n function renderScopeBlocks(items, isSub) {\n var blocks = [];\n var run = null; // tools from consecutive tool-only turns (within one block)\n var runBlk = null; // block idx of the current run (runs don't cross blocks, so a filter hides cleanly)\n var userTurns = []; // {i (global), text} powering the outline + scroll-spy\n function flushRun() {\n if (run && run.length) {\n var a = runBlk != null ? ' data-blk=\"' + runBlk + '\"' : '';\n blocks.push('<div class=\"turn asst toolrun\"' + a + '><div class=\"role\">Tool calls · ' + run.length + '</div>' +\n toolsHtml(run) + '</div>');\n }\n run = null; runBlk = null;\n }\n items.forEach(function (it) {\n var i = it.gi, t = it.t, tools = t.tools || [];\n var blk = t.blockIdx;\n var ba = blk != null ? ' data-blk=\"' + blk + '\"' : '';\n if (t.role === 'user') {\n flushRun();\n userTurns.push({ i: i, text: t.text });\n blocks.push('<div class=\"turn user\" id=\"txt-' + i + '\"' + ba + '><div class=\"role\">' + (isSub ? 'Prompt' : 'You') +\n '<span class=\"tnum\">#' + userTurns.length + '</span></div>' + textBlock(t.text) + '</div>');\n } else if (t.text) {\n flushRun();\n blocks.push('<div class=\"turn asst\" id=\"txt-' + i + '\"' + ba + '><div class=\"role\">' + (isSub ? 'Subagent' : 'Assistant') +\n '</div>' + textBlock(t.text, true) + (tools.length ? toolsHtml(tools) : '') + '</div>');\n } else if (tools.length) {\n // Surface spawning calls as their own banner; fold the rest into the run.\n // Flush when the block changes so a run stays within one block.\n var spawns = tools.filter(function (x) { return x.agentId && subMeta[x.agentId]; });\n if (spawns.length) {\n flushRun();\n spawns.forEach(function (sp) { blocks.push(spawnBlockHtml(sp, blk)); });\n var keep = tools.filter(function (x) { return !(x.agentId && subMeta[x.agentId]); });\n if (keep.length) { if (run && blk !== runBlk) flushRun(); runBlk = blk; run = (run || []).concat(keep); }\n } else {\n if (run && blk !== runBlk) flushRun();\n runBlk = blk; run = (run || []).concat(tools);\n }\n }\n });\n flushRun();\n return { blocksHtml: blocks.join(''), userTurns: userTurns };\n }\n\n var scopes = scopeOrder.map(function (key) {\n var errIds = [];\n errSink = errIds;\n var r = renderScopeBlocks(scopeItems[key], key !== 'main');\n var m = key === 'main' ? {} : (subMeta[key] || {});\n return {\n key: key, agentType: m.agentType, description: m.description, toolUseId: m.toolUseId,\n blocksHtml: r.blocksHtml, userTurns: r.userTurns, errIds: errIds\n };\n });\n errSink = null;\n var scopeByKey: any = {};\n scopes.forEach(function (sc) { scopeByKey[sc.key] = sc; });\n var hasSub = scopeOrder.length > 1;\n var errCount = errSeq; // total tool errors across all scopes\n\n // The scope's active state is reassigned by switchScope; the nav reads these.\n var activeScope = 'main';\n var userTurns = scopeByKey.main.userTurns;\n var errIds = scopeByKey.main.errIds;\n\n function scopeBtnHtml(sc, extra) {\n var lbl, ico = '', title = '';\n if (sc.key === 'main') lbl = 'Main thread';\n else {\n ico = '🤖 ';\n lbl = (sc.agentType || 'subagent') + (sc.description ? ' · ' + clipLine(sc.description, 36) : '');\n title = (sc.agentType || 'subagent') + (sc.description ? ': ' + sc.description : '');\n }\n var err = sc.errIds.length ? '<span class=\"tx-scope-err\">⚠' + sc.errIds.length + '</span>' : '';\n return '<button class=\"tx-scope-btn' + (sc.key === 'main' ? ' on' : '') + (extra ? ' tx-scope-extra' : '') +\n '\" type=\"button\" data-scope=\"' + esc(sc.key) + '\" title=\"' + esc(title) + '\">' + ico + esc(lbl) + err + '</button>';\n }\n // Collapse a long scope list to one line: show the first few, tuck the rest\n // behind a toggle. Main thread always leads, so the visible count stays small.\n var SCOPE_SHOWN = 3;\n var scopeExtra = scopes.length - SCOPE_SHOWN;\n var moreBtn = scopeExtra > 0\n ? '<button class=\"tx-scope-more\" type=\"button\" data-more=\"+' + scopeExtra + ' more\">+' + scopeExtra + ' more</button>'\n : '';\n var scopeBar = hasSub\n ? '<div class=\"tx-scopes' + (scopeExtra > 0 ? ' collapsed' : '') + '\">' +\n scopes.map(function (sc, i) { return scopeBtnHtml(sc, i >= SCOPE_SHOWN); }).join('') + moreBtn + '</div>'\n : '';\n\n function outlineListHtml(uts) {\n return uts.length\n ? uts.map(function (u, k) {\n return '<button class=\"tx-ol-item\" type=\"button\" data-k=\"' + k + '\" data-goto=\"txt-' + u.i + '\"' +\n ' data-s=\"' + esc(clipLine(u.text, 300).toLowerCase()) + '\">' +\n '<span class=\"tx-ol-n\">' + (k + 1) + '</span><span class=\"tx-ol-tx\">' + esc(clipLine(u.text, 90)) + '</span></button>';\n }).join('')\n : '<div class=\"empty\">No turns.</div>';\n }\n // Long turn lists get a filter box so you don't have to scroll to scan them.\n var OUTLINE_SEARCH_MIN = 10;\n function outlineHtml(uts) {\n var search = uts.length > OUTLINE_SEARCH_MIN\n ? '<div class=\"tx-ol-search\"><input class=\"tx-ol-search-input\" type=\"text\" placeholder=\"Filter turns…\" /></div>'\n : '';\n return search + '<div class=\"tx-ol-list\">' + outlineListHtml(uts) + '</div>';\n }\n // Show only the outline items whose text contains the query; note when none do.\n function filterOutline(q) {\n var list = $('#drawerBody .tx-ol-list'); if (!list) return;\n q = (q || '').trim().toLowerCase();\n var any = false;\n Array.prototype.forEach.call(list.querySelectorAll('.tx-ol-item'), function (it) {\n var hit = !q || (it.getAttribute('data-s') || '').indexOf(q) >= 0;\n it.classList.toggle('tx-ol-hide', !hit);\n if (hit) any = true;\n });\n var none = list.querySelector('.tx-ol-none') as HTMLElement;\n if (!any && q) {\n if (!none) { none = document.createElement('div'); none.className = 'empty tx-ol-none'; none.textContent = 'No matching turns.'; list.appendChild(none); }\n none.style.display = '';\n } else if (none) none.style.display = 'none';\n }\n var nav = '<div class=\"tx-nav\">' +\n '<div class=\"tx-filter-wrap\"></div>' +\n '<div class=\"tx-nav-row\">' +\n '<div class=\"tx-grp\">' +\n '<span class=\"tx-grp-lbl\">Turn</span>' +\n '<button class=\"btn tx-turn-prev\" type=\"button\" title=\"Previous turn\">‹</button>' +\n '<span class=\"tx-pos\"><b class=\"tx-turn-pos\">' + (userTurns.length ? 1 : 0) + '</b>/<span class=\"tx-turn-total\">' + userTurns.length + '</span></span>' +\n '<button class=\"btn tx-turn-next\" type=\"button\" title=\"Next turn\">›</button>' +\n '<div class=\"tx-ol-wrap\"><button class=\"tx-ol-btn\" type=\"button\" title=\"Jump to a turn\">▾</button>' +\n '<div class=\"tx-outline\" id=\"tx-outline\">' + outlineHtml(userTurns) + '</div></div>' +\n '</div>' +\n '<div class=\"tx-grp tx-search\">' +\n '<input class=\"tx-search-input\" type=\"text\" placeholder=\"Search — press Enter\" />' +\n '<div class=\"tx-search-results\">' +\n '<button class=\"btn tx-search-prev\" type=\"button\" title=\"Previous match\">‹</button>' +\n '<span class=\"tx-pos\"><b class=\"tx-search-pos\">0</b>/<span class=\"tx-search-total\">0</span></span>' +\n '<button class=\"btn tx-search-next\" type=\"button\" title=\"Next match\">›</button>' +\n '<button class=\"btn tx-search-x\" type=\"button\" title=\"Clear\">×</button>' +\n '</div>' +\n '</div>' +\n (errCount\n ? '<div class=\"tx-grp tx-errs\"><span class=\"tx-grp-lbl\">⚠ Errors</span>' +\n '<button class=\"btn tx-err-prev\" type=\"button\">‹</button>' +\n '<span class=\"tx-pos\"><b class=\"tx-err-pos\">—</b>/<span class=\"tx-err-total\">' + errIds.length + '</span></span>' +\n '<button class=\"btn tx-err-next\" type=\"button\">›</button></div>'\n : '<span class=\"tx-grp none\">no tool errors</span>') +\n '</div>' +\n '<div class=\"tx-now\" id=\"tx-now\"></div>' +\n '</div>';\n\n // Subagent scopes get a header (type/description + a link back to the call).\n function subPaneHeader(sc) {\n if (sc.key === 'main') return '';\n var back = sc.toolUseId\n ? '<button class=\"tx-sub-back\" type=\"button\" data-agent=\"' + esc(sc.key) + '\">↩ back to spawning call</button>'\n : '';\n return '<div class=\"tx-sub-head\"><span class=\"tx-spawn-ico\">🤖</span> <b>' + esc(sc.agentType || 'subagent') + '</b>' +\n (sc.description ? ' <span class=\"tx-sub-desc\">' + esc(sc.description) + '</span>' : '') + back + '</div>';\n }\n var panesHtml = scopes.map(function (sc) {\n return '<div class=\"tx-scope-pane' + (sc.key === 'main' ? ' on' : '') + '\" data-scope=\"' + esc(sc.key) + '\">' +\n subPaneHeader(sc) + (sc.blocksHtml || '<div class=\"empty\">No turns.</div>') + '</div>';\n }).join('');\n\n var hasTx = allTurns.length > 0;\n var txBody = hasTx ? panesHtml : '<div class=\"empty\">No transcript stored.</div>';\n // One sticky header (title + tabs + scope bar + transcript nav) over the panes.\n $('#drawerBody').innerHTML =\n '<div class=\"drawer-head\">' + headTop + tabs + (hasTx ? scopeBar : '') + (hasTx ? nav : '') + '</div>' +\n '<div class=\"dpane\" id=\"dpane-summary\">' + sum + '</div>' +\n (fileCount ? '<div class=\"dpane\" id=\"dpane-files\"><div class=\"empty\">Loading file changes…</div></div>' : '') +\n '<div class=\"dpane on\" id=\"dpane-transcript\">' + txBody + '</div>';\n\n // Keep --head-h (used for sticky-aware scroll-margin) in step with the header,\n // whose height changes when the transcript nav shows/hides between tabs.\n function syncHeadH() {\n var h = $('#drawerBody .drawer-head');\n if (h) $('#drawer').style.setProperty('--head-h', h.offsetHeight + 'px');\n }\n // Error bodies are scrollable; the failure usually sits at the end, so park\n // each at its bottom. Run once the pane is visible (hidden → scrollHeight 0).\n function scrollErrPanels() {\n Array.prototype.forEach.call(document.querySelectorAll('#dpane-transcript .tx-error-b'), function (el) {\n el.scrollTop = el.scrollHeight;\n });\n }\n\n // Tab switching — shared by the top tabs and the summary \"See transcript\".\n // The transcript nav lives in the shared header but only shows on that tab;\n // the Files diffs are fetched lazily the first time that tab is opened.\n var filesLoaded = false, filesRendered = false, pendingFile = null;\n function expandFile(path) {\n var pane = $('#dpane-files'); if (!pane) return;\n var card = null;\n Array.prototype.forEach.call(pane.querySelectorAll('.fc-file'), function (c) { if (c.getAttribute('data-path') === path) card = c; });\n if (card) { card.classList.remove('collapsed'); card.scrollIntoView({ block: 'start' }); flashEl(card); }\n }\n // A summary file chip → the Files tab with that file expanded (after lazy load).\n function openFile(path) {\n pendingFile = path;\n showTab('files');\n if (filesRendered) { expandFile(path); pendingFile = null; }\n }\n function showTab(name) {\n _activeTab = name;\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .dtab'), function (x) {\n x.classList.toggle('on', x.getAttribute('data-dtab') === name);\n });\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .dpane'), function (p) {\n p.classList.toggle('on', p.id === 'dpane-' + name);\n });\n var navEl = $('#drawerBody .tx-nav');\n if (navEl) navEl.classList.toggle('on', name === 'transcript');\n var sbEl = $('#drawerBody .tx-scopes');\n if (sbEl) sbEl.classList.toggle('on', name === 'transcript');\n $('#drawer').scrollTop = 0;\n syncHeadH();\n if (name === 'files' && !filesLoaded) { filesLoaded = true; loadFiles(); }\n if (name === 'transcript') requestAnimationFrame(function () { spy(); scrollErrPanels(); });\n }\n function loadFiles() {\n get('/api/session-files?id=' + encodeURIComponent(id)).then(function (res) {\n var edits = (res && res.edits) || [];\n var txTurns = (d.transcript && d.transcript.turns) || [];\n prepEdits(edits, txTurns);\n var pane = $('#dpane-files');\n if (!pane) return;\n pane.innerHTML =\n '<div class=\"fc-hint\">Grouped by file · click a file to see its diff, where edits are headed by the prompt that drove them (▸ is the agent’s note) · → opens the transcript.</div>' +\n filesHtml(edits, txTurns);\n Array.prototype.forEach.call(pane.querySelectorAll('.fc-head'), function (b) {\n b.onclick = function () { b.parentNode.classList.toggle('collapsed'); };\n });\n Array.prototype.forEach.call(pane.querySelectorAll('.fc-rows-more'), function (b) {\n b.onclick = function () { b.previousElementSibling.classList.add('on'); b.style.display = 'none'; };\n });\n Array.prototype.forEach.call(pane.querySelectorAll('.fc-jump'), function (b) {\n b.onclick = function () { jumpToIntent(parseInt(b.getAttribute('data-u'), 10), -1); };\n });\n Array.prototype.forEach.call(pane.querySelectorAll('.msg-more'), function (b) {\n b.onclick = function () { var on = b.previousElementSibling.classList.toggle('on'); b.textContent = on ? 'Show less ↑' : 'Show more ↓'; };\n });\n filesRendered = true;\n if (pendingFile) { expandFile(pendingFile); pendingFile = null; }\n });\n }\n // From a file edit, jump to the user message that prompted it (the intent),\n // falling back to the edit's own turn. Switch to the scope that owns the\n // target turn first (a subagent's edit lives in its tab); the spy re-syncs.\n function jumpToIntent(u, t) {\n showTab('transcript');\n var gi = u >= 0 ? u : (t >= 0 ? t : -1);\n if (gi < 0) return;\n switchScope(scopeOfTurn[gi] || 'main');\n requestAnimationFrame(function () {\n var el = document.getElementById('txt-' + gi);\n if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); flashEl(el); }\n });\n }\n var closeBtn = $('#drawerCloseBtn');\n if (closeBtn) closeBtn.onclick = closeDrawer;\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .dtab'), function (b) {\n b.onclick = function () { showTab(b.getAttribute('data-dtab')); };\n });\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .see-tx'), function (b) {\n b.onclick = function () { showTab(b.getAttribute('data-tab')); };\n });\n\n // Truncation toggles: summary chip lists (files/features) + per-turn tool runs.\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .chip-more'), function (b) {\n b.onclick = function () {\n var open = b.previousElementSibling.classList.toggle('on');\n b.textContent = open ? 'show fewer ‹' : 'show all ' + b.getAttribute('data-n') + ' ›';\n };\n });\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tool-more'), function (b) {\n b.onclick = function () {\n var open = b.previousElementSibling.classList.toggle('on');\n var n = b.getAttribute('data-n');\n b.textContent = open ? '– show fewer' : '+ ' + n + ' more tool call' + (n > 1 ? 's' : '');\n };\n });\n // Expand/collapse a tool's command section (>2 lines collapsed by default).\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tool-cmd-toggle'), function (b) {\n b.onclick = function (e) {\n e.stopPropagation();\n var wrap = b.closest('.tool-block-cmd');\n var on = wrap.classList.toggle('on');\n b.innerHTML = on\n ? '<span class=\"tool-cmd-arrow\" style=\"transform:rotate(-90deg)\">▶</span> collapse'\n : '<span class=\"tool-cmd-arrow\" style=\"transform:rotate(90deg)\">▶</span> expand';\n refreshSearch();\n };\n });\n // Expand overflow diff rows in tool blocks.\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tool-block-body .fc-rows-more'), function (b) {\n b.onclick = function () { b.previousElementSibling.classList.add('on'); b.style.display = 'none'; };\n });\n // Toggle a tool call's output/diff body (collapsed by default).\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tool-out-toggle'), function (b) {\n b.onclick = function (e) {\n e.stopPropagation();\n var body = b.closest('.tool-block').querySelector('.tool-block-body');\n if (body) b.classList.toggle('on', body.classList.toggle('on'));\n };\n });\n // Expand a long message's preview to its full text.\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .msg-more'), function (b) {\n b.onclick = function () {\n var on = b.previousElementSibling.classList.toggle('on');\n b.textContent = on ? 'Show less ↑' : 'Show more ↓';\n refreshSearch();\n };\n });\n\n // Artifact chips pivot to a filtered session list.\n var sumChips = document.querySelectorAll('#drawerBody .tag.click');\n // A feature/PR chip is clickable only when there are ≥2 of THAT kind in the\n // summary (focus the transcript on it); a lone one has nothing to filter, so\n // disable it. Gate on what's actually shown — the transcript's block-level\n // feature dim can be sparser than the session's linked features.\n var kindCount = {};\n Array.prototype.forEach.call(sumChips, function (el) { var k = el.getAttribute('data-kind'); kindCount[k] = (kindCount[k] || 0) + 1; });\n Array.prototype.forEach.call(sumChips, function (el) {\n var kind = el.getAttribute('data-kind'), art = el.getAttribute('data-art');\n if (kind === 'feature' || kind === 'pr') {\n if ((kindCount[kind] || 0) >= 2) el.onclick = function () { focusDim(kind, resolveDimValue(kind, art)); };\n else el.classList.remove('click');\n } else if (kind === 'file') {\n el.onclick = function () { openFile(art); };\n } else {\n el.onclick = function () { filterByArtifact(art, kind); };\n }\n });\n\n // ----- Link-add buttons: \"+\" opens inline typeahead to link artifacts ------\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .link-add-btn'), function (btn) {\n btn.onclick = function () {\n var kind = btn.getAttribute('data-link-kind');\n var sid = btn.getAttribute('data-session-id');\n var area = document.querySelector('#drawerBody .link-add-area[data-link-kind=\"' + kind + '\"][data-session-id=\"' + sid + '\"]') as HTMLElement;\n if (!area) return;\n if (area.classList.contains('on')) { area.classList.remove('on'); area.innerHTML = ''; return; }\n area.classList.add('on');\n area.innerHTML =\n '<div class=\"link-ac\">' +\n '<input class=\"link-ac-input\" placeholder=\"' + (kind === 'feature' ? 'Search features or type a name to create…' : kind === 'pr' ? 'Paste URL or type owner/repo#123…' : 'Search…') + '\" />' +\n '<div class=\"link-ac-menu\"></div>' +\n '</div>';\n var inp = area.querySelector('.link-ac-input') as HTMLInputElement;\n var menu = area.querySelector('.link-ac-menu') as HTMLElement;\n var debounce: any = null;\n inp.focus();\n inp.oninput = function () {\n var err = area.querySelector('.link-ac-error');\n if (err) err.remove();\n clearTimeout(debounce);\n debounce = setTimeout(function () { linkAcFetch(inp, menu, sid, kind); }, 200);\n };\n inp.onkeydown = function (e) {\n if (e.key === 'Escape') { area.classList.remove('on'); area.innerHTML = ''; }\n if (e.key === 'Enter') { linkAcSelect(inp, menu, sid, kind, -1); }\n };\n };\n });\n\n // ----- Link-remove buttons: \"✕\" on feature chips rejects the link ----------\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .link-remove-btn'), function (btn) {\n btn.onclick = function (e) {\n e.stopPropagation();\n var sid = btn.getAttribute('data-session-id');\n var aid = btn.getAttribute('data-artifact-id');\n if (!sid || !aid) return;\n if (!confirm('Unlink this artifact from the session?')) return;\n post('/api/session-links/remove', { sessionId: sid, artifactId: aid }).then(function (res) {\n if (res && res.ok) openDetail(sid);\n }).catch(function () {});\n };\n });\n\n // ----- Transcript navigation: turn stepper + scroll-spy + error stepper ----\n var curTurn = 0;\n // A programmatic jump sets the indicator explicitly AND triggers a smooth\n // scroll, whose scroll events would otherwise make spy() recompute a stale\n // mid-animation value and clobber it. Mute spy for the scroll's duration.\n var spyMuted = false, muteTimer = 0;\n function muteSpy() {\n spyMuted = true;\n clearTimeout(muteTimer);\n muteTimer = setTimeout(function () { spyMuted = false; }, 700);\n }\n function updateIndicator(k) {\n if (!userTurns.length) return;\n curTurn = k;\n var pos = $('#drawerBody .tx-turn-pos'); if (pos) pos.textContent = String(k + 1);\n var now = $('#tx-now'); if (now) now.textContent = '#' + (k + 1) + ' · ' + clipLine(userTurns[k].text, 130);\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tx-ol-item'), function (it) {\n it.classList.toggle('cur', it.getAttribute('data-k') === String(k));\n });\n }\n function jumpToTurn(k) {\n if (!userTurns.length) return;\n k = Math.max(0, Math.min(userTurns.length - 1, k));\n updateIndicator(k);\n muteSpy();\n var el = document.getElementById('txt-' + userTurns[k].i);\n if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); flashEl(el); }\n }\n // Which user-turn section the scroll position is currently in (the last user\n // turn whose top has passed below the sticky header). The line sits BELOW a\n // jumped-to turn's resting top (scroll-margin ≈ head+10) so the jump target\n // counts as current; a bottom guard catches the last turn (can't reach top).\n function spy() {\n if (spyMuted) return;\n var pane = $('#dpane-transcript');\n if (!pane || !pane.classList.contains('on') || !userTurns.length) return;\n var headEl = $('#drawerBody .drawer-head');\n var line = (headEl ? headEl.getBoundingClientRect().bottom : 0) + 20;\n var cur = 0;\n for (var k = 0; k < userTurns.length; k++) {\n var el = document.getElementById('txt-' + userTurns[k].i);\n if (el && el.getBoundingClientRect().top <= line) cur = k; else break;\n }\n var dr = $('#drawer');\n if (dr && dr.scrollTop + dr.clientHeight >= dr.scrollHeight - 2) cur = userTurns.length - 1;\n if (cur !== curTurn) updateIndicator(cur);\n }\n var spyRAF = 0;\n $('#drawer').onscroll = function () {\n if (!spyRAF) spyRAF = requestAnimationFrame(function () { spyRAF = 0; spy(); });\n };\n var tp = $('#drawerBody .tx-turn-prev'), tn = $('#drawerBody .tx-turn-next');\n if (tp) tp.onclick = function () { jumpToTurn(curTurn - 1); };\n if (tn) tn.onclick = function () { jumpToTurn(curTurn + 1); };\n\n // Outline dropdown: open/close + jump to a specific turn (highlights current).\n var olBtn = $('#drawerBody .tx-ol-btn'), olPanel = $('#tx-outline');\n if (olBtn) olBtn.onclick = function () {\n var open = olPanel.classList.toggle('on'); olBtn.classList.toggle('on');\n if (open) { var si = $('#drawerBody .tx-ol-search-input'); if (si) si.focus(); }\n };\n // (Re)wire the outline items to jump within the active scope, plus the filter\n // box. Called on open and whenever the outline's contents are swapped.\n function wireOutline() {\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tx-ol-item'), function (it) {\n it.onclick = function () {\n if (olPanel) olPanel.classList.remove('on');\n if (olBtn) olBtn.classList.remove('on');\n jumpToTurn(parseInt(it.getAttribute('data-k'), 10));\n };\n });\n var si = $('#drawerBody .tx-ol-search-input');\n if (si) {\n si.oninput = function () { filterOutline(si.value); };\n // Enter jumps to the first match (and closes the dropdown via the click).\n si.onkeydown = function (e) {\n if (e.key === 'Enter') { var first = $('#drawerBody .tx-ol-item:not(.tx-ol-hide)'); if (first) first.click(); }\n };\n }\n }\n wireOutline();\n if (userTurns.length) updateIndicator(0);\n\n // Error stepper: ‹ / › cycle through the ACTIVE scope's error panels (errIds\n // are global panel ids, so the anchors resolve even with all scopes in the DOM).\n // Scroll to an error panel, FIRST revealing it: a call beyond the per-turn cap\n // sits in a collapsed \".tool-rest\" group (display:none), where scrollIntoView is\n // a no-op. Expand that group (and hide its \"+N more\" button), then scroll+flash.\n function revealErr(anchor) {\n var el = document.getElementById('txerr-' + anchor);\n if (!el) return;\n var rest = el.closest && el.closest('.tool-rest');\n if (rest && !rest.classList.contains('on')) {\n rest.classList.add('on');\n var mb = rest.nextElementSibling as any;\n if (mb && mb.classList.contains('tool-more')) mb.style.display = 'none';\n }\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n flashOnSettle(el);\n }\n var errIdx = -1;\n function gotoErr(next) {\n if (!errIds.length) return;\n errIdx = ((next % errIds.length) + errIds.length) % errIds.length;\n var pos = $('#drawerBody .tx-err-pos');\n if (pos) pos.textContent = String(errIdx + 1);\n revealErr(errIds[errIdx]);\n }\n var ep = $('#drawerBody .tx-err-prev'), en = $('#drawerBody .tx-err-next');\n if (ep) ep.onclick = function () { gotoErr(errIdx - 1); };\n if (en) en.onclick = function () { gotoErr(errIdx + 1); };\n\n // Search runs on explicit Enter, not per keystroke: a full-transcript DOM walk\n // that wraps a <mark> around every hit is far too expensive to run live on big\n // sessions (a short prefix like \"a\" would mutate thousands of nodes and hang\n // the page). First Enter searches the term; pressing Enter again with the same\n // term steps to the next match, Shift+Enter to the previous.\n var searchInput = $('#drawerBody .tx-search-input') as HTMLInputElement;\n if (searchInput) {\n searchInput.oninput = function () {\n // Only the cheap \"box emptied\" case acts live (clears highlights); a term\n // change waits for Enter rather than re-running the expensive pass.\n if (!searchInput.value.trim()) transcriptSearch('');\n };\n searchInput.onkeydown = function (e) {\n if (e.key === 'Enter') {\n e.preventDefault();\n var q = searchInput.value.trim();\n if (q !== lastSearched) transcriptSearch(q);\n else if (searchMatches.length) jumpToSearchMatch(searchIdx + (e.shiftKey ? -1 : 1));\n }\n if (e.key === 'Escape') { searchInput.value = ''; transcriptSearch(''); searchInput.blur(); }\n };\n }\n var spBtn = $('#drawerBody .tx-search-prev'), snBtn = $('#drawerBody .tx-search-next'), sxBtn = $('#drawerBody .tx-search-x');\n if (spBtn) spBtn.onclick = function () { jumpToSearchMatch(searchIdx - 1); };\n if (snBtn) snBtn.onclick = function () { jumpToSearchMatch(searchIdx + 1); };\n if (sxBtn) sxBtn.onclick = function () { if (searchInput) { searchInput.value = ''; } transcriptSearch(''); };\n\n // ----- Block filter: focus the main thread on one PR / feature / use-case --\n function mainPaneEl() { return document.querySelector('#drawerBody .tx-scope-pane[data-scope=\"main\"]'); }\n function renderFilterBar() {\n var c = $('#drawerBody .tx-filter-wrap'); if (!c) return;\n c.innerHTML = filterBarHtml();\n var sel = c.querySelector('.tx-fdim');\n if (sel) sel.onchange = function () { fDim = this.value; fVal = null; renderFilterBar(); applyTxFilter(true); refreshSearch(); };\n Array.prototype.forEach.call(c.querySelectorAll('.tx-fchip'), function (b) {\n b.onclick = function () { var v = b.getAttribute('data-v'); fVal = v === '' ? null : v; renderFilterBar(); applyTxFilter(true); refreshSearch(); };\n });\n }\n // `scroll` (a user chip/switcher click) lands at the top of the newly-focused\n // view — otherwise switching focus after scrolling leaves you mid-transcript.\n function applyTxFilter(scroll?: boolean) {\n var pane = mainPaneEl(); if (!pane) return;\n Array.prototype.forEach.call(pane.querySelectorAll('.tx-gap'), function (g) { if (g.parentNode) g.parentNode.removeChild(g); });\n var els = Array.prototype.filter.call(pane.children, function (el) { return el.hasAttribute('data-blk'); });\n if (fVal == null || fDim == null) {\n els.forEach(function (el) { el.classList.remove('tx-hidden'); });\n } else {\n var run = [];\n var flush = function () {\n if (!run.length) return;\n var labels = {};\n run.forEach(function (el) { var l = blkLabel(parseInt(el.getAttribute('data-blk'), 10), fDim); if (l) labels[l] = 1; });\n var ks = Object.keys(labels);\n var n = run.filter(function (el) { return el.classList.contains('turn'); }).length || run.length;\n var g = document.createElement('div'); g.className = 'tx-gap';\n g.textContent = '··· ' + n + ' turn' + (n > 1 ? 's' : '') + (ks.length === 1 ? ' on ' + ks[0] : ' elsewhere') + ' ···';\n pane.insertBefore(g, run[0]); run = [];\n };\n els.forEach(function (el) {\n if (blkVal(parseInt(el.getAttribute('data-blk'), 10), fDim) === fVal) { flush(); el.classList.remove('tx-hidden'); }\n else { el.classList.add('tx-hidden'); run.push(el); }\n });\n flush();\n }\n recountTurns();\n if (scroll) {\n var first = pane.querySelector('[data-blk]:not(.tx-hidden)');\n if (first) { muteSpy(); first.scrollIntoView({ block: 'start' }); flashEl(first); }\n }\n }\n // Re-point the turn AND error steppers + the outline at the currently-VISIBLE\n // main-thread content, so every nav control walks only what you can see.\n function recountTurns() {\n if (activeScope !== 'main') return;\n var full = scopeByKey.main.userTurns;\n var vis = full.filter(function (u) { var el = document.getElementById('txt-' + u.i); return el && !el.classList.contains('tx-hidden'); });\n userTurns = vis;\n var tt = $('#drawerBody .tx-turn-total'); if (tt) tt.textContent = String(vis.length);\n var ol = $('#tx-outline'); if (ol) ol.innerHTML = outlineHtml(vis);\n wireOutline();\n curTurn = 0;\n if (vis.length) updateIndicator(0);\n else { var pos = $('#drawerBody .tx-turn-pos'); if (pos) pos.textContent = '0'; var now = $('#tx-now'); if (now) now.textContent = ''; }\n // Error stepper: cycle only errors whose block is still visible (a panel\n // lives inside a turn/toolrun, so check that ancestor's tx-hidden).\n errIds = scopeByKey.main.errIds.filter(function (eid) {\n var el = document.getElementById('txerr-' + eid);\n return el && !el.closest('.tx-hidden');\n });\n errIdx = -1;\n var et = $('#drawerBody .tx-err-total'); if (et) et.textContent = String(errIds.length);\n var epos = $('#drawerBody .tx-err-pos'); if (epos) epos.textContent = '—';\n syncHeadH();\n }\n renderFilterBar();\n if (dimsAvail.length) applyTxFilter();\n\n // ----- Transcript search: highlight + step through matches in active scope ---\n var SEARCH_MIN = 2; // ignore terms shorter than this (kills 'a'/'e' noise)\n var SEARCH_CAP = 100; // stop wrapping after this many hits — a page-freeze\n // backstop; a common term shows \"100+\", a cue to refine.\n var searchMatches = [];\n var searchIdx = -1;\n var searchCapped = false;\n var lastSearched = null; // term of the last executed search (null = none yet)\n\n function updateSearchUI(pos, total) {\n var p = $('#drawerBody .tx-search-pos'); if (p) p.textContent = String(pos);\n var t = $('#drawerBody .tx-search-total'); if (t) t.textContent = total + (searchCapped ? '+' : '');\n }\n\n function clearHighlights() {\n var marks = document.querySelectorAll('#dpane-transcript .tx-hl');\n Array.prototype.forEach.call(marks, function (m) {\n var parent = m.parentNode;\n parent.replaceChild(document.createTextNode(m.textContent), m);\n parent.normalize();\n });\n searchMatches = [];\n searchIdx = -1;\n searchCapped = false;\n }\n\n function expandAncestors(el) {\n var body = el.closest('.tool-block-body');\n if (body && !body.classList.contains('on')) {\n body.classList.add('on');\n var tog = body.parentElement.querySelector('.tool-out-toggle');\n if (tog) tog.classList.add('on');\n }\n var msg = el.closest('.msg');\n if (msg && !msg.classList.contains('on')) msg.classList.add('on');\n var rest = el.closest('.tool-rest');\n if (rest && !rest.classList.contains('on')) rest.classList.add('on');\n var dlr = el.closest('.dl-rest');\n if (dlr && !dlr.classList.contains('on')) dlr.classList.add('on');\n var cmd = el.closest('.tool-block-cmd.collapsible');\n if (cmd && !cmd.classList.contains('on')) cmd.classList.add('on');\n }\n\n function jumpToSearchMatch(idx) {\n if (!searchMatches.length) return;\n if (searchIdx >= 0 && searchMatches[searchIdx]) searchMatches[searchIdx].classList.remove('active');\n searchIdx = ((idx % searchMatches.length) + searchMatches.length) % searchMatches.length;\n var mark = searchMatches[searchIdx];\n mark.classList.add('active');\n expandAncestors(mark);\n mark.scrollIntoView({ behavior: 'smooth', block: 'center' });\n updateSearchUI(searchIdx + 1, searchMatches.length);\n }\n\n function transcriptSearch(query) {\n clearHighlights();\n lastSearched = query;\n // Below the minimum, treat it as no active search: clear and collapse the\n // stepper rather than wrap thousands of noise hits.\n var sg = $('#drawerBody .tx-search');\n if (query.length < SEARCH_MIN) { if (sg) sg.classList.remove('on'); updateSearchUI(0, 0); return; }\n if (sg) sg.classList.add('on');\n var pane = document.querySelector('#dpane-transcript .tx-scope-pane.on');\n if (!pane) return;\n var lowerQ = query.toLowerCase();\n var qLen = query.length;\n var walker = document.createTreeWalker(pane, NodeFilter.SHOW_TEXT, {\n acceptNode: function (n) {\n var el = n.parentElement;\n if (!el) return NodeFilter.FILTER_ACCEPT;\n // Messages have .msg-prev (truncated) + .msg-full (complete). Always\n // search the full version so matches beyond the preview are found;\n // skip the preview to avoid duplicates. expandAncestors reveals .msg-full.\n if (el.closest('.tx-hidden')) return NodeFilter.FILTER_REJECT;\n if (el.closest('.msg-prev')) return NodeFilter.FILTER_REJECT;\n // Commands have .tool-cmd-pre (first 2 lines) + .tool-cmd-full (complete).\n // Same logic: search the full, skip the preview.\n if (el.closest('.tool-cmd-pre')) {\n var cmdWrap = el.closest('.tool-block-cmd.collapsible');\n if (cmdWrap && cmdWrap.querySelector('.tool-cmd-full')) return NodeFilter.FILTER_REJECT;\n }\n return NodeFilter.FILTER_ACCEPT;\n }\n });\n var textNodes = [];\n while (walker.nextNode()) textNodes.push(walker.currentNode);\n for (var ni = 0; ni < textNodes.length && searchMatches.length < SEARCH_CAP; ni++) {\n var node = textNodes[ni];\n var text = node.textContent;\n var lower = text.toLowerCase();\n var offsets = [];\n var idx = lower.indexOf(lowerQ);\n while (idx !== -1) { offsets.push(idx); idx = lower.indexOf(lowerQ, idx + qLen); }\n var nodeMarks = [];\n for (var k = offsets.length - 1; k >= 0; k--) {\n var range = document.createRange();\n range.setStart(node, offsets[k]);\n range.setEnd(node, offsets[k] + qLen);\n var mark = document.createElement('mark');\n mark.className = 'tx-hl';\n range.surroundContents(mark);\n nodeMarks.unshift(mark);\n }\n searchMatches = searchMatches.concat(nodeMarks);\n }\n searchCapped = searchMatches.length >= SEARCH_CAP;\n updateSearchUI(searchMatches.length ? 1 : 0, searchMatches.length);\n if (searchMatches.length) jumpToSearchMatch(0);\n }\n\n function refreshSearch() {\n var q = searchInput && searchInput.value.trim();\n if (q) transcriptSearch(q);\n }\n\n // ----- Subagent scopes: switch tab, link from spawn calls, link back -------\n // Point the nav (turn stepper, outline, error stepper, scroll-spy) at a scope\n // and show its pane. Indices are global, so the steppers/anchors carry over.\n function switchScope(key) {\n if (!scopeByKey[key]) key = 'main';\n if (key === activeScope) return;\n activeScope = key;\n userTurns = scopeByKey[key].userTurns;\n errIds = scopeByKey[key].errIds;\n errIdx = -1;\n curTurn = 0;\n if (searchInput) { searchInput.value = ''; }\n clearHighlights();\n updateSearchUI(0, 0);\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tx-scope-btn'), function (b) {\n b.classList.toggle('on', b.getAttribute('data-scope') === key);\n });\n // If the newly active scope is tucked away, reveal the collapsed list so its pill shows.\n var sb = $('#drawerBody .tx-scopes');\n var activeBtn = $('#drawerBody .tx-scope-btn.on');\n if (sb && sb.classList.contains('collapsed') && activeBtn && activeBtn.classList.contains('tx-scope-extra')) {\n sb.classList.remove('collapsed');\n var mb = $('#drawerBody .tx-scope-more'); if (mb) mb.textContent = 'show less';\n }\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tx-scope-pane'), function (p) {\n p.classList.toggle('on', p.getAttribute('data-scope') === key);\n });\n var tt = $('#drawerBody .tx-turn-total'); if (tt) tt.textContent = String(userTurns.length);\n var et = $('#drawerBody .tx-err-total'); if (et) et.textContent = String(errIds.length);\n var ep2 = $('#drawerBody .tx-err-pos'); if (ep2) ep2.textContent = '—';\n var ol = $('#tx-outline'); if (ol) ol.innerHTML = outlineHtml(userTurns);\n wireOutline();\n $('#drawer').scrollTop = 0;\n if (userTurns.length) { updateIndicator(0); }\n else {\n var pos = $('#drawerBody .tx-turn-pos'); if (pos) pos.textContent = '0';\n var now = $('#tx-now'); if (now) now.textContent = '';\n }\n // The block filter applies to the main thread only; re-apply it on return.\n var fw = $('#drawerBody .tx-filter-wrap'); if (fw) fw.style.display = key === 'main' ? '' : 'none';\n if (key === 'main' && dimsAvail.length) applyTxFilter();\n syncHeadH();\n }\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tx-scope-btn'), function (b) {\n b.onclick = function () { switchScope(b.getAttribute('data-scope')); };\n });\n // The \"+N more\" pill expands/collapses the overflow scopes.\n var scopeMoreEl = $('#drawerBody .tx-scope-more');\n if (scopeMoreEl) scopeMoreEl.onclick = function () {\n var sb = $('#drawerBody .tx-scopes');\n var collapsed = sb.classList.toggle('collapsed');\n scopeMoreEl.textContent = collapsed ? scopeMoreEl.getAttribute('data-more') : 'show less';\n syncHeadH();\n };\n // A spawning call (banner or chip) opens its subagent's scope.\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tx-spawn, #drawerBody .tool-block.agent .tool-block-row'), function (b) {\n b.onclick = function (e) { e.stopPropagation(); switchScope(b.getAttribute('data-agent')); };\n });\n // A subagent's \"back\" link returns to the main thread and flashes the call.\n Array.prototype.forEach.call(document.querySelectorAll('#drawerBody .tx-sub-back'), function (b) {\n b.onclick = function () {\n switchScope('main');\n requestAnimationFrame(function () {\n var el = document.getElementById('txspawn-' + b.getAttribute('data-agent'));\n if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); flashEl(el); }\n });\n };\n });\n\n // Land on Transcript by default; restore previous tab only when re-opening the same session.\n var restoreTab = (_activeSessionId === id ? _activeTab : null) || 'transcript';\n if (restoreTab === 'files' && !fileCount) restoreTab = 'transcript';\n if (restoreTab === 'transcript' && !hasTx) restoreTab = 'summary';\n _activeSessionId = id;\n showTab(restoreTab);\n $('#drawer').classList.add('on');\n $('#overlay').classList.add('on');\n\n // Reveal a failed tool call inside THIS drawer: switch to its scope if needed,\n // then revealErr. Published to activeReveal so the pager reuses it same-session.\n function revealErrorTarget(target) {\n var sc = 'main';\n scopeOrder.forEach(function (k) { if (scopeByKey[k].errIds.indexOf(target) >= 0) sc = k; });\n if (sc !== activeScope) switchScope(sc);\n requestAnimationFrame(function () { revealErr(target); });\n }\n activeReveal = revealErrorTarget;\n if (focus && focus.errTarget != null) revealErrorTarget(focus.errTarget);\n });\n}\n\nexport function filterByArtifact(text, kind, preset?) {\n closeDrawer();\n setView('sessions');\n var af = $('#f-artifact');\n if (af) { af.value = text || ''; af.dataset.kind = kind || ''; } // kind rides along on the input (no visible kind dropdown)\n // Drilling into one artifact defaults to its FULL history (all-time). A caller\n // can pin a window instead — e.g. a Highlights drill passes its window (14d) so\n // the session count the user lands on matches the headline. setTimePreset()\n // re-applies (the matching preset chip must exist, else it shows none selected).\n setTimePreset(preset == null ? 'all' : preset);\n}\n\n// Drill-in from the dashboard's \"Errors by category\" widget: jump to the Sessions\n// list filtered to one error category, over the SAME window the user clicked from\nexport function filterByErrorCategory(category) {\n setView('sessions');\n buildFilters();\n Array.prototype.forEach.call(document.querySelectorAll('.facet-filter[data-key=\"error_category\"]'), function (s) {\n s.value = category || '';\n });\n setTimePreset(state.days === 'all' ? 'all' : state.days);\n}\n\nexport function closeDrawer() {\n $('#drawer').classList.remove('on'); $('#overlay').classList.remove('on');\n activeReveal = null;\n errWalk = null; renderErrWalkBar(); // closing the drawer ends any error walk\n if (state.open) { state.open = null; syncHash({ replace: true }); } // drop ?session= without adding history\n}\n\n// The open drawer publishes its error-reveal fn here so the pager can reveal the\n// next error in place without re-opening the session. Null when no drawer is open.\nvar activeReveal: ((idx: number) => void) | null = null;\n\n// ---- Cross-session error walk -------------------------------------------------\n// \"Step through every occurrence of one error category.\" The dashboard widget\n// hands us the occurrence list; we open each occurrence's transcript at its exact\n// error block (txerr-<idx>) and show a floating pager that walks ACROSS sessions.\n// The pager lives outside #drawerBody so it survives the drawer re-rendering as we\n// move between sessions.\nvar errWalk = null; // { label, occ:[{sessionId,idx,name,title,...}], i, openId }\n\nexport function startErrorWalk(label, occ, i) {\n if (!occ || !occ.length) return;\n errWalk = { label: label, occ: occ, i: 0, openId: null };\n openWalkOcc(i || 0);\n}\n\nfunction openWalkOcc(i) {\n if (!errWalk) return;\n var n = errWalk.occ.length;\n errWalk.i = ((i % n) + n) % n; // wrap\n var o = errWalk.occ[errWalk.i];\n if (o.sessionId === errWalk.openId && activeReveal) {\n activeReveal(o.idx); // same session open → reveal in place\n } else {\n errWalk.openId = o.sessionId;\n openDetail(o.sessionId, { errTarget: o.idx });\n }\n renderErrWalkBar();\n}\n\nfunction renderErrWalkBar() {\n var bar = document.getElementById('errwalk');\n if (!errWalk) { if (bar) bar.parentNode.removeChild(bar); return; }\n if (!bar) { bar = document.createElement('div'); bar.id = 'errwalk'; document.body.appendChild(bar); }\n var o = errWalk.occ[errWalk.i];\n bar.innerHTML =\n '<span class=\"ew-cat\">⚠ ' + esc(errWalk.label) + '</span>' +\n '<button class=\"ew-btn\" id=\"ew-prev\" type=\"button\">‹</button>' +\n '<span class=\"ew-pos\">' + (errWalk.i + 1) + ' / ' + errWalk.occ.length + '</span>' +\n '<button class=\"ew-btn\" id=\"ew-next\" type=\"button\">›</button>' +\n '<span class=\"ew-cur\" title=\"' + esc(o.title || '') + '\">' + esc(o.name) + '</span>' +\n '<button class=\"ew-btn ew-x\" id=\"ew-close\" type=\"button\">✕</button>';\n $('#ew-prev').onclick = function () { openWalkOcc(errWalk.i - 1); };\n $('#ew-next').onclick = function () { openWalkOcc(errWalk.i + 1); };\n $('#ew-close').onclick = function () { errWalk = null; renderErrWalkBar(); };\n}\n\n// ---- Link-add typeahead helpers (session detail) ----------------------------\n\nfunction linkAcFetch(inp: HTMLInputElement, menu: HTMLElement, sessionId: string, kind: string) {\n var q = inp.value.trim();\n if (!q) { menu.innerHTML = ''; return; }\n var url = '/api/session-links/suggest?sessionId=' + encodeURIComponent(sessionId) +\n '&q=' + encodeURIComponent(q) +\n (kind ? '&kind=' + encodeURIComponent(kind) : '');\n get(url).then(function (items) {\n var html = '';\n (items || []).forEach(function (it, i) {\n html += '<div class=\"link-ac-item\" data-idx=\"' + i + '\" data-id=\"' + esc(it.id) + '\">' + esc(it.label) + '</div>';\n });\n if (kind === 'feature') {\n html += '<div class=\"link-ac-item link-ac-create\" data-idx=\"-1\">Create “' + esc(q) + '”</div>';\n }\n if (kind === 'pr' && (/^[^\\s#]+#\\d+$/.test(q) || /^(?:https?:\\/\\/)?github\\.com\\/[^/]+\\/[^/]+\\/pull\\/\\d+/.test(q))) {\n html += '<div class=\"link-ac-item link-ac-create\" data-idx=\"-2\">Link PR ' + esc(q) + '</div>';\n }\n menu.innerHTML = html;\n Array.prototype.forEach.call(menu.querySelectorAll('.link-ac-item'), function (el) {\n el.onclick = function () { linkAcSelect(inp, menu, sessionId, kind, parseInt(el.getAttribute('data-idx'))); };\n });\n });\n}\n\nfunction linkAcSelect(inp: HTMLInputElement, menu: HTMLElement, sessionId: string, kind: string, idx: number) {\n var q = inp.value.trim();\n if (!q) return;\n var item = idx >= 0 ? menu.querySelector('[data-idx=\"' + idx + '\"]') : null;\n var promise: Promise<any>;\n if (item && item.getAttribute('data-id')) {\n promise = post('/api/session-links/add', { sessionId: sessionId, artifactId: item.getAttribute('data-id') });\n } else if (kind === 'feature') {\n promise = post('/api/session-links/create-feature', { sessionId: sessionId, title: q });\n } else if (kind === 'pr') {\n var m = q.match(/^([^\\s#]+)#(\\d+)$/) || q.match(/^(?:https?:\\/\\/)?github\\.com\\/([^/]+\\/[^/]+)\\/pull\\/(\\d+)/);\n if (!m) return;\n promise = post('/api/session-links/add-pr', { sessionId: sessionId, repo: m[1], prNumber: m[2] });\n } else {\n return;\n }\n var area = document.querySelector('#drawerBody .link-add-area[data-link-kind=\"' + kind + '\"].on') as HTMLElement;\n if (area) {\n var existing = area.querySelector('.link-ac-error');\n if (existing) existing.remove();\n var spinner = document.createElement('div');\n spinner.className = 'link-ac-spinner';\n spinner.textContent = 'Validating…';\n area.querySelector('.link-ac').appendChild(spinner);\n }\n promise.then(function (res) {\n if (area) { var sp = area.querySelector('.link-ac-spinner'); if (sp) sp.remove(); }\n if (res && (res.ok || res.id)) {\n openDetail(sessionId);\n } else if (res && res.error) {\n if (area) {\n var err = area.querySelector('.link-ac-error');\n if (!err) { err = document.createElement('div'); err.className = 'link-ac-error'; area.querySelector('.link-ac').appendChild(err); }\n err.textContent = res.error;\n }\n }\n }).catch(function () {\n if (area) {\n var sp = area.querySelector('.link-ac-spinner'); if (sp) sp.remove();\n var err = area.querySelector('.link-ac-error');\n if (!err) { err = document.createElement('div'); err.className = 'link-ac-error'; area.querySelector('.link-ac').appendChild(err); }\n err.textContent = 'Request failed — check your connection';\n }\n });\n}\n\nexport function setView(name) {\n ['highlights', 'dashboard', 'artifacts', 'sessions'].forEach(function (v) {\n document.getElementById('view-' + v).classList.toggle('on', v === name);\n });\n Array.prototype.forEach.call(document.querySelectorAll('.tab'), function (b) {\n b.classList.toggle('on', b.getAttribute('data-view') === name);\n });\n state.view = name;\n syncHash(); // mirror the active tab into the URL (no-op while a route is applying)\n}\n\nexport function loadSessions() {\n var f = state.filters || {}, qs = [];\n var facets = f.facets || {};\n Object.keys(facets).forEach(function (k) {\n if (facets[k]) qs.push(encodeURIComponent(k) + '=' + encodeURIComponent(facets[k]));\n });\n if (f.q) qs.push('q=' + encodeURIComponent(f.q));\n if (f.artifact) qs.push('artifact=' + encodeURIComponent(f.artifact));\n if (f.artifactKind) qs.push('artifact_kind=' + encodeURIComponent(f.artifactKind));\n if (f.from) qs.push('from=' + encodeURIComponent(f.from));\n if (f.to) qs.push('to=' + encodeURIComponent(f.to));\n if (f.outcomes && f.outcomes.length) qs.push('outcome_types=' + encodeURIComponent(f.outcomes.join(',')));\n get('/api/sessions' + (qs.length ? '?' + qs.join('&') : '')).then(renderSessions);\n}\n","// Artifacts tab: the Features/PRs sub-nav, the PR table, and the feature manager\n// (hierarchical list with ship-toggle, nest-under, move-to-top, delete). Feature\n// mutations POST to /api/features* and reload.\nimport { state, $, esc, usd, dayOf, get, post, complexityLabel } from './core'\nvar CX_OPTS = [['', 'Not tagged'], ['1', 'Trivial'], ['2', 'Simple'], ['3', 'Moderate'], ['4', 'Complex'], ['5', 'Highly Complex']];\nimport { syncHash } from './router'\nimport { filterByArtifact, setView } from './sessions'\n\n// The complexity tag as a pill — reuses the grey b-null badge (same as the other\n// artifacts-view pills). Empty for untagged features / PRs with no recorded churn.\n// PRs get the raw line count as a tooltip since their bucket is derived from diff size.\nfunction complexityPill(kind, complexity) {\n var label = complexityLabel(kind, complexity);\n if (!label) return '';\n var title = kind === 'pr' ? ' title=\"' + esc(Number(complexity) + ' lines changed') + '\"' : '';\n return '<span class=\"badge b-null\"' + title + '>' + esc(label) + '</span>';\n}\n\nexport function renderArtKindSeg() {\n var opts = [['feature', 'Features'], ['pr', 'PRs']];\n $('#artKindSeg').innerHTML = opts.map(function (o) {\n return '<button class=\"' + (o[0] === state.artKind ? 'on' : '') + '\" data-k=\"' + o[0] + '\">' + o[1] + '</button>';\n }).join('');\n Array.prototype.forEach.call($('#artKindSeg').children, function (btn) {\n btn.onclick = function () { setArtKind(btn.getAttribute('data-k')); };\n });\n}\n\n// Switch the Artifacts sub-tab (Features | PRs) from the segment buttons, and\n// mirror it into the URL. Switching kind resets the table's search/sort (each kind\n// gets a fresh list). No-op when already on that kind.\nexport function setArtKind(kind) {\n state.view = 'artifacts';\n if (state.artKind === kind) { syncHash(); return; }\n state.artKind = kind;\n state.art = { q: '', sort: 'created', dir: 'desc' };\n renderArtKindSeg();\n loadArtifacts();\n syncHash();\n}\n\n// ---- URL <-> artifacts-list bridge (used by the router) ----------------------\n\n// The current artifacts-table state as URL query params: free-text search (q) and,\n// for the PR table, the column sort. Defaults (created/desc) are omitted.\nexport function getArtifactParams(): Record<string, string> {\n var q: Record<string, string> = {};\n if (state.art.q) q.q = state.art.q;\n if (state.artKind === 'pr') {\n if (state.art.sort && state.art.sort !== 'created') q.sort = state.art.sort;\n if (state.art.dir === 'asc') q.dir = 'asc';\n }\n return q;\n}\n\n// Restore the artifacts kind + table search/sort from the URL, then reload. Used\n// by the router on Back/Forward and deep links (inverse of getArtifactParams).\nexport function applyArtifactParams(kind, query) {\n state.view = 'artifacts';\n state.artKind = kind === 'pr' || kind === 'feature' ? kind : 'feature';\n state.art = {\n q: query.q || '',\n sort: query.sort || 'created',\n dir: query.dir === 'asc' ? 'asc' : 'desc',\n };\n renderArtKindSeg();\n loadArtifacts();\n}\n\nfunction renderArtifacts(rows, kind) {\n if (kind === 'feature') { renderFeatureManager(rows || []); return; }\n renderPrTab(rows || []);\n}\n\n// The PR sub-tab: a search box (by title or identifier) over a sortable table.\n// Rows are held in module state so search + column sort re-render only the table\n// body, leaving the (outside) search input focused.\nvar prRows = [];\n// Column sort lives in state.art (state.art.sort / .dir) so it round-trips through\n// the URL; the search box value lives in state.art.q.\n// [key, label, numeric?] — numeric columns right-align and default to descending.\nvar PR_COLS = [['pr', 'Pull request', 0], ['status', 'Status', 0], ['sessions', 'Sessions', 1],\n ['cost', 'Cost', 1], ['created', 'Created', 1], ['merged', 'Merged', 1]];\n\nfunction renderPrTab(rows) {\n prRows = rows;\n if (!rows.length) {\n $('#artifacts').innerHTML = '<div class=\"empty\">No PRs linked yet. A PR appears here once it\\'s linked to a session — from the transcript (gh pr create / merge) or by matching code you pushed yourself.</div>';\n return;\n }\n $('#artifacts').innerHTML =\n '<input id=\"pr-search\" class=\"feat-search\" type=\"search\" placeholder=\"Search PRs by title or #identifier…\" autocomplete=\"off\" />' +\n '<div id=\"pr-table-wrap\"></div>';\n var srch = $('#pr-search');\n srch.value = state.art.q || ''; // restore a URL-driven search\n srch.oninput = function () { state.art.q = srch.value; syncHash({ replace: true }); renderPrTable(); };\n renderPrTable();\n}\n\n// Sort key for a column; `created` falls back to merge time (mirrors the server COALESCE).\nfunction prVal(r, col) {\n if (col === 'pr') return Number(r.ident) || 0;\n if (col === 'status') return (r.status || '').toLowerCase();\n if (col === 'sessions') return r.sessions || 0;\n if (col === 'cost') return r.costUsd || 0;\n if (col === 'created') return r.createdAt || r.completedAt || '';\n if (col === 'merged') return r.completedAt || '';\n return '';\n}\n\nfunction renderPrTable() {\n var search = $('#pr-search');\n var q = (search && search.value || '').trim().toLowerCase();\n var rows = prRows.filter(function (r) {\n if (!q) return true;\n var hay = ((r.title || '') + ' #' + (r.ident || '') + ' ' + (r.repo || '') + ' ' + (r.externalId || '')).toLowerCase();\n return hay.indexOf(q) !== -1;\n });\n var dir = state.art.dir === 'asc' ? 1 : -1;\n rows.sort(function (a, b) {\n var x = prVal(a, state.art.sort), y = prVal(b, state.art.sort);\n return x < y ? -dir : x > y ? dir : 0;\n });\n\n var head = '<tr>' + PR_COLS.map(function (c) {\n var arrow = c[0] === state.art.sort ? (state.art.dir === 'asc' ? ' ▴' : ' ▾') : '';\n return '<th class=\"pr-th' + (c[2] ? ' num' : '') + '\" data-sort=\"' + c[0] + '\">' + c[1] + arrow + '</th>';\n }).join('') + '<th></th></tr>';\n var body = rows.map(function (r) {\n var key = r.externalId || r.ident;\n var idLabel = (r.repo ? esc(r.repo) + ' ' : '') + '#' + esc(r.ident);\n var idHtml = r.externalId\n ? '<a class=\"pr-link\" href=\"' + esc(r.externalId) + '\" target=\"_blank\" rel=\"noopener\">' + idLabel + '</a>'\n : idLabel;\n // Inline AI-attribution tag beside the PR id (alternative to the AI-written column).\n var aiTag = r.aiPct != null ? ' <span class=\"pr-ai-tag\" title=\"Share of this PR authored by the agent (best single session)\">' + Math.round(r.aiPct * 100) + '% AI</span>' : '';\n var titleHtml = r.title ? '<div class=\"pr-title\">' + esc(r.title) + '</div>' : '';\n return '<tr class=\"arow\" data-art=\"' + esc(key) + '\" data-kind=\"pr\">' +\n '<td>' + idHtml + ' ' + complexityPill('pr', r.complexity) + aiTag + titleHtml + '</td>' +\n '<td>' + (r.status ? esc(r.status) : '—') + '</td>' +\n '<td class=\"num\">' + r.sessions + '</td>' +\n '<td class=\"num\">' + usd(r.costUsd) + '</td>' +\n '<td class=\"num\">' + (esc(dayOf(r.createdAt)) || '—') + '</td>' +\n '<td class=\"num\">' + (esc(dayOf(r.completedAt)) || '—') + '</td>' +\n '<td><button class=\"btn sess-btn\" data-art=\"' + esc(key) + '\">Sessions →</button></td></tr>';\n }).join('');\n var note = rows.length ? '' : '<div class=\"empty\">No PRs match your search.</div>';\n $('#pr-table-wrap').innerHTML = '<table>' + head + body + '</table>' + note;\n\n Array.prototype.forEach.call(document.querySelectorAll('#pr-table-wrap .pr-th'), function (th) {\n th.onclick = function () {\n var col = th.getAttribute('data-sort');\n if (state.art.sort === col) state.art.dir = state.art.dir === 'asc' ? 'desc' : 'asc';\n else { state.art.sort = col; state.art.dir = (col === 'pr' || col === 'status') ? 'asc' : 'desc'; }\n syncHash({ replace: true });\n renderPrTable();\n };\n });\n Array.prototype.forEach.call(document.querySelectorAll('#pr-table-wrap .sess-btn'), function (btn) {\n btn.onclick = function () { filterByArtifact(btn.getAttribute('data-art'), 'pr'); };\n });\n}\n\nfunction renderFeatureManager(rows) {\n var html = '';\n if (!rows.length) {\n html += '<div class=\"empty\">No features yet. Add one below, or enrich sessions to propose features.</div>';\n } else {\n html += '<input id=\"feat-search\" class=\"feat-search\" type=\"search\" placeholder=\"Search features…\" autocomplete=\"off\" />';\n html += '<div class=\"feat-list\">' +\n '<div class=\"feat-head\"><span>Feature</span><span>Repos</span><span>Last session</span><span class=\"fh-num\">Sessions</span><span class=\"fh-num\">Cost</span><span></span></div>';\n flattenFeatures(rows).forEach(function (e) {\n var r = e.node, indent = e.depth * 22;\n var twig = e.depth ? '<span class=\"feat-twig\">↳</span> ' : '';\n var shipped = !!r.completedAt;\n // \"open\" badge omitted — the top-level \"Mark shipped\" button implies open status.\n var statusHtml = shipped\n ? '<span class=\"badge b-success\">shipped ' + esc(dayOf(r.completedAt)) + '</span>'\n : '';\n var proposed = r.source === 'derived' ? '<span class=\"tag\">proposed</span>' : '';\n var repos = (r.repos && r.repos.length) ? r.repos.join(', ') : '—';\n var last = r.lastSessionAt ? dayOf(r.lastSessionAt) : '—';\n // Secondary actions (nest-under · complexity · move-to-top · delete) collapse\n // into a per-row hamburger; only the indent shifts, so columns stay aligned.\n var nest = '<select class=\"feat-nest\" data-id=\"' + esc(r.id) + '\">' +\n nestUnderOptions(rows, r.id, descendantsOf(rows, r.id)) + '</select>';\n var cxVal = r.complexity ? String(r.complexity) : '';\n var cxSelect = '<select class=\"feat-cx\" data-id=\"' + esc(r.id) + '\">' +\n CX_OPTS.map(function (o) { return '<option value=\"' + o[0] + '\"' + (o[0] === cxVal ? ' selected' : '') + '>' + o[1] + '</option>'; }).join('') +\n '</select>';\n var toTop = r.parentId\n ? '<button class=\"menu-item\" data-act=\"totop\" data-id=\"' + esc(r.id) + '\">Move to top level</button>'\n : '';\n html += '<div class=\"feat-row\" data-name=\"' + esc((r.title || '').toLowerCase()) +\n '\" data-id=\"' + esc(r.id) + '\" data-parent=\"' + esc(r.parentId || '') + '\">' +\n '<div class=\"feat-name\" style=\"padding-left:' + indent + 'px\">' + twig +\n '<span class=\"nm\" title=\"' + esc(r.title || '') + '\">' +\n esc(r.title || '(untitled)') + '</span> ' + proposed + ' ' + statusHtml + ' ' + complexityPill('feature', r.complexity) + '</div>' +\n '<span class=\"feat-repos\" title=\"' + esc(repos) + '\">' + esc(repos) + '</span>' +\n '<span class=\"feat-last\" title=\"' + esc(r.lastSessionAt || '') + '\">' + esc(last) + '</span>' +\n '<span class=\"feat-num\">' + r.sessions + '</span>' +\n '<span class=\"feat-num\">' + usd(r.costUsd) + '</span>' +\n '<div class=\"feat-actions\">' +\n '<button class=\"btn ship-btn' + (shipped ? ' shipped' : '') + '\" data-act=\"toggle\" data-id=\"' + esc(r.id) + '\" data-completed=\"' + (shipped ? '1' : '0') + '\">' +\n (shipped ? 'Reopen' : 'Mark shipped') + '</button>' +\n '<button class=\"btn sess-btn\" data-art=\"' + esc(r.title || '') + '\" data-kind=\"feature\">Sessions →</button>' +\n '<div class=\"feat-menu-wrap\">' +\n '<button class=\"feat-menu-btn\" aria-label=\"More actions\">⋯</button>' +\n '<div class=\"feat-menu\">' +\n '<div class=\"menu-nest\"><label>Nest under</label>' + nest + '</div>' +\n '<div class=\"menu-nest\"><label>Complexity</label>' + cxSelect + '</div>' +\n toTop +\n '<div class=\"menu-sep\"></div>' +\n '<button class=\"menu-item danger\" data-act=\"delete\" data-id=\"' + esc(r.id) + '\" data-title=\"' + esc(r.title || '') + '\">Delete</button>' +\n '</div>' +\n '</div>' +\n '</div></div>';\n });\n html += '</div>';\n }\n // New-feature form lives at the bottom, collapsed behind an \"Add feature\" button\n // to keep the list uncluttered.\n html += '<div class=\"feat-add\">' +\n '<button class=\"btn\" id=\"nf-toggle\">+ Add feature</button>' +\n '<div class=\"feat-new\" id=\"nf-form\" hidden>' +\n '<input id=\"nf-title\" placeholder=\"New feature title\" />' +\n '<select id=\"nf-parent\">' + featureParentOptions(rows, '', '', null) + '</select>' +\n '<select id=\"nf-complexity\"><option value=\"\">Complexity (optional)</option>' +\n CX_OPTS.slice(1).map(function (o) { return '<option value=\"' + o[0] + '\">' + o[1] + '</option>'; }).join('') + '</select>' +\n '<button class=\"btn\" id=\"nf-add\">Add</button>' +\n '<button class=\"btn\" id=\"nf-cancel\">Cancel</button>' +\n '</div></div>';\n $('#artifacts').innerHTML = html;\n wireFeatureManager();\n}\n\n// Options for the per-row \"Nest under…\" action — candidate parents only (no\n// \"(top level)\" option; that is its own explicit button). Excludes self + any\n// descendants (would create a cycle).\nfunction nestUnderOptions(rows, id, excludeSet) {\n var opts = '<option value=\"\" disabled selected>Nest under…</option>';\n rows.forEach(function (r) {\n if (r.id === id) return;\n if (excludeSet && excludeSet[r.id]) return;\n opts += '<option value=\"' + esc(r.id) + '\">' + esc(r.title || r.id) + '</option>';\n });\n return opts;\n}\n\nfunction featureParentOptions(rows, selectedId, excludeId, excludeSet) {\n var opts = '<option value=\"\"' + (selectedId ? '' : ' selected') + '>(top level)</option>';\n rows.forEach(function (r) {\n if (r.id === excludeId) return;\n if (excludeSet && excludeSet[r.id]) return;\n opts += '<option value=\"' + esc(r.id) + '\"' + (r.id === selectedId ? ' selected' : '') + '>' + esc(r.title || r.id) + '</option>';\n });\n return opts;\n}\n\nfunction descendantsOf(rows, id) {\n var children = {};\n rows.forEach(function (r) { var p = r.parentId || ''; (children[p] = children[p] || []).push(r.id); });\n var out = {}, stack = (children[id] || []).slice();\n while (stack.length) { var x = stack.pop(); if (out[x]) continue; out[x] = true; (children[x] || []).forEach(function (c) { stack.push(c); }); }\n return out;\n}\n\nfunction flattenFeatures(rows) {\n // Most-recent-activity first: order roots and each sibling group by last session\n // time descending (undated sorts last). Hierarchy is preserved — a parent still\n // renders before its children; only the order among siblings changes.\n function recency(a, b) { return String(b.lastSessionAt || '').localeCompare(String(a.lastSessionAt || '')); }\n var byId = {}; rows.forEach(function (r) { byId[r.id] = r; });\n var children = {};\n rows.forEach(function (r) {\n var p = r.parentId && byId[r.parentId] ? r.parentId : '';\n (children[p] = children[p] || []).push(r);\n });\n Object.keys(children).forEach(function (k) { children[k].sort(recency); });\n var out = [], visited = {};\n (function walk(key, depth) {\n (children[key] || []).forEach(function (r) {\n if (visited[r.id]) return; visited[r.id] = true;\n out.push({ node: r, depth: depth });\n walk(r.id, depth + 1);\n });\n })('', 0);\n rows.slice().sort(recency).forEach(function (r) { if (!visited[r.id]) { visited[r.id] = true; out.push({ node: r, depth: 0 }); } });\n return out;\n}\n\nfunction wireFeatureManager() {\n function each(sel, fn) { Array.prototype.forEach.call(document.querySelectorAll(sel), fn); }\n\n // Add-feature: a collapsed button that expands into the full form on click.\n var nfToggle = $('#nf-toggle'), nfForm = $('#nf-form'), nfTitle = $('#nf-title');\n if (nfToggle) nfToggle.onclick = function () {\n nfForm.hidden = false; nfToggle.hidden = true;\n if (nfTitle) nfTitle.focus();\n };\n var nfCancel = $('#nf-cancel');\n if (nfCancel) nfCancel.onclick = function () {\n nfForm.hidden = true; nfToggle.hidden = false;\n if (nfTitle) nfTitle.value = '';\n };\n var add = $('#nf-add');\n if (add) add.onclick = function () {\n var title = nfTitle.value.trim();\n if (!title) return;\n var cx = $('#nf-complexity').value || undefined;\n post('/api/features', { title: title, parentId: $('#nf-parent').value || undefined, complexity: cx ? Number(cx) : undefined }).then(loadArtifacts);\n };\n if (nfTitle) nfTitle.onkeydown = function (ev) { if (ev.key === 'Enter' && add) add.onclick(); };\n\n // Hamburger menus: fixed-positioned (so the scroll container's overflow can't\n // clip them) and only one open at a time. Clicks inside a menu don't bubble to\n // the document closer, keeping the nest <select> usable.\n each('#artifacts .feat-menu-btn', function (btn) {\n btn.onclick = function (ev) {\n ev.stopPropagation();\n var menu = btn.parentNode.querySelector('.feat-menu');\n var wasOpen = menu.classList.contains('on');\n closeFeatMenus();\n if (wasOpen) return;\n menu.classList.add('on');\n var rect = btn.getBoundingClientRect();\n menu.style.top = (rect.bottom + 4) + 'px';\n menu.style.left = (rect.right - menu.offsetWidth) + 'px';\n };\n });\n each('#artifacts .feat-menu', function (m) { m.onclick = function (ev) { ev.stopPropagation(); }; });\n var list = $('#artifacts .feat-list');\n if (list) list.onscroll = closeFeatMenus; // fixed menus don't track the scrolled button\n\n each('#artifacts .sess-btn', function (b) {\n b.onclick = function () { filterByArtifact(b.getAttribute('data-art'), b.getAttribute('data-kind')); };\n });\n each('#artifacts [data-act=\"toggle\"]', function (b) {\n b.onclick = function () {\n post('/api/features/update', { id: b.getAttribute('data-id'), completed: b.getAttribute('data-completed') !== '1' }).then(loadArtifacts);\n };\n });\n each('#artifacts [data-act=\"delete\"]', function (b) {\n b.onclick = function () {\n if (!window.confirm('Delete feature \"' + (b.getAttribute('data-title') || '') + '\"? Any sub-features move up to its parent.')) return;\n post('/api/features/delete', { id: b.getAttribute('data-id') }).then(loadArtifacts);\n };\n });\n each('#artifacts .feat-nest', function (sel) {\n sel.onchange = function () {\n if (!sel.value) return;\n post('/api/features/update', { id: sel.getAttribute('data-id'), parentId: sel.value }).then(loadArtifacts);\n };\n });\n each('#artifacts .feat-cx', function (sel) {\n sel.onchange = function () {\n var val = sel.value ? Number(sel.value) : null;\n post('/api/features/update', { id: sel.getAttribute('data-id'), complexity: val }).then(loadArtifacts);\n };\n });\n each('#artifacts [data-act=\"totop\"]', function (b) {\n b.onclick = function () {\n post('/api/features/update', { id: b.getAttribute('data-id'), parentId: null }).then(loadArtifacts);\n };\n });\n\n // Local name filter. A match reveals its WHOLE subtree (so searching an epic\n // shows everything under it) plus its ancestors (so the match keeps its place\n // in the tree). Pure show/hide in place — no refetch, keeps input focus.\n function filterFeatRows(qRaw) {\n var q = (qRaw || '').trim().toLowerCase();\n var rows = Array.prototype.slice.call(document.querySelectorAll('#artifacts .feat-row'));\n if (!q) { rows.forEach(function (r) { r.style.display = ''; }); return; }\n var childrenOf = {}, parentOf = {};\n rows.forEach(function (r) {\n var id = r.getAttribute('data-id'), p = r.getAttribute('data-parent') || '';\n parentOf[id] = p;\n (childrenOf[p] = childrenOf[p] || []).push(id);\n });\n var visible = {};\n function revealSubtree(id) {\n if (visible[id]) return;\n visible[id] = true;\n (childrenOf[id] || []).forEach(revealSubtree);\n }\n function revealAncestors(id) {\n var p = parentOf[id];\n while (p) { visible[p] = true; p = parentOf[p]; }\n }\n rows.forEach(function (r) {\n if ((r.getAttribute('data-name') || '').indexOf(q) !== -1) {\n var id = r.getAttribute('data-id');\n revealSubtree(id);\n revealAncestors(id);\n }\n });\n rows.forEach(function (r) { r.style.display = visible[r.getAttribute('data-id')] ? '' : 'none'; });\n }\n var search = $('#feat-search');\n if (search) {\n search.value = state.art.q || ''; // restore a URL-driven search\n search.oninput = function () { state.art.q = search.value; syncHash({ replace: true }); filterFeatRows(search.value); };\n if (search.value) filterFeatRows(search.value);\n }\n\n // One-time global closers: outside click and Escape dismiss any open menu.\n // Idempotent across reloads — they query the live DOM each time.\n if (!featMenusWired) {\n featMenusWired = true;\n document.addEventListener('click', closeFeatMenus);\n document.addEventListener('keydown', function (ev) { if (ev.key === 'Escape') closeFeatMenus(); });\n }\n}\n\n// Module-level so the global listeners are attached only once. closeFeatMenus is\n// hoisted out of wireFeatureManager so those one-time listeners don't capture a\n// stale closure from the first render.\nvar featMenusWired = false;\nfunction closeFeatMenus() {\n Array.prototype.forEach.call(document.querySelectorAll('#artifacts .feat-menu.on'), function (m) { m.classList.remove('on'); });\n}\n\n// When a deep-link (Explore Q1) lands here, pre-fill that sub-tab's search so the\n// list narrows to the one artifact instead of dropping the user into a full list.\nvar pendingArtSearch = '';\nfunction applyArtSearch() {\n if (!pendingArtSearch) return;\n var input = document.getElementById(state.artKind === 'pr' ? 'pr-search' : 'feat-search') as any;\n if (input) { input.value = pendingArtSearch; if (input.oninput) input.oninput(); }\n pendingArtSearch = '';\n}\n\nexport function loadArtifacts() {\n get('/api/artifacts?kind=' + encodeURIComponent(state.artKind)).then(function (rows) {\n renderArtifacts(rows, state.artKind);\n applyArtSearch();\n });\n}\n\n// Open the Artifacts tab at a sub-kind (feature/pr) with its search pre-filled to\n// `query` — the list ends up narrowed to that artifact (showing its cost).\nexport function openArtifactSearch(kind, query) {\n setView('artifacts');\n state.artKind = kind;\n pendingArtSearch = query || '';\n renderArtKindSeg();\n loadArtifacts();\n}\n","// Store-state banners. A fresh store (nothing analyzed yet) and an un-enriched\n// store (sessions exist but LLM enrichment never ran) both deserve a nudge rather\n// than a wall of zeros / a misleading 0% outcome rate. One classifier off the\n// /api/overview summary drives every surface — the dashboard banner above the KPI\n// row and the Highlights tab — so the copy stays consistent.\nimport { state, $ } from './core'\n\nexport type StoreStatus = 'loading' | 'empty' | 'unenriched' | 'stale' | 'ok'\n\n// The store is \"stale\" (worth a re-analyze nudge) once this many days have passed\n// since the last `analyze` run — aligned with the dashboard's default 7-day window.\nvar STALE_DAYS = 7;\n\n// Whole days since the last `analyze` run, or null when unknown (older stores that\n// predate the recorded timestamp — don't nag those).\nexport function daysSinceAnalyze(): number | null {\n var o = state.overview;\n var ts = o && o.lastAnalyzedAt;\n if (!ts) return null;\n var t = Date.parse(ts);\n if (!t) return null;\n return Math.floor((Date.now() - t) / 86400000);\n}\n\n// Classify the store from the overview summary, most-urgent first. 'loading' until\n// /api/overview resolves; 'empty' = nothing analyzed; 'unenriched' = sessions exist\n// but LLM enrichment never ran; 'stale' = enriched/healthy but not analyzed in a\n// while; otherwise 'ok'. `enrichmentRan` is sourced from processor_runs (an\n// LLM-backed processor recorded a model) — a durable signal that doesn't depend on\n// which annotation dimensions the enricher emits, and that works for free local\n// providers too (where enrichment spend is $0). The precedence keeps at most one\n// nudge on screen at a time.\nexport function storeStatus(): StoreStatus {\n var o = state.overview;\n if (!o) return 'loading';\n if (!o.sessions) return 'empty';\n if (!o.enrichmentRan) return 'unenriched';\n var d = daysSinceAnalyze();\n if (d != null && d >= STALE_DAYS) return 'stale';\n return 'ok';\n}\n\n// Whether the active \"count as success\" definition is even computable — i.e. at\n// least one of the currently-selected success outcome types actually occurs in the\n// store. When none can, the Session Outcome Rate is a structural 0 (no possible\n// numerator), so the headline tile shows \"—\" rather than a misleadingly bad \"0%\".\n// This is stricter than \"any outcome exists\": an un-enriched store can have git\n// outcomes (pr_merged…) yet still can't satisfy the default `session_success`\n// definition, which only LLM enrichment produces. Returns false until the overview\n// lands, so \"—\" is the safe placeholder rather than a possibly-misleading 0%.\nexport function successDefinable(): boolean {\n var o = state.overview;\n if (!o) return false;\n var present: Record<string, boolean> = {};\n (o.outcomes || []).forEach(function (x) { present[x.type] = true; });\n // Empty selection → the server falls back to session_success (see Store.kpis).\n var sel = (state.sr && state.sr.outcomes && state.sr.outcomes.length) ? state.sr.outcomes : ['session_success'];\n return sel.some(function (t) { return present[t]; });\n}\n\nfunction notice(cls, head, body) {\n return '<div class=\"notice ' + cls + '\"><div class=\"notice-h\">' + head + '</div><div class=\"notice-b\">' + body + '</div></div>';\n}\n\n// Banner HTML for the current store state — '' when ok or still loading (so the\n// caller can drop it straight into a slot). Static, author-controlled markup; no\n// user data is interpolated, so no escaping is needed.\nexport function noticeHtml(): string {\n var st = storeStatus();\n if (st === 'empty') {\n // The dashboard is only reachable once a store exists, so landing here means\n // `analyze` ran but ingested nothing (no AI-coding history yet, or a wrong\n // directory / --source) — not that analyze was never run. Word it accordingly.\n return notice('first-run',\n 'No sessions found',\n '<code>tuneloop analyze</code> scanned your Claude Code, Codex, and opencode history but found nothing. ' +\n 'Point it at a directory — <code>tuneloop analyze <dir></code> — or check <code>--source</code>.');\n }\n if (st === 'unenriched') {\n return notice('enrich',\n 'LLM enrichment hasn’t run',\n 'Outcomes, complexity, work type, and the Session Outcome Rate all need it. Re-run analysis with a provider key — e.g. ' +\n '<code>export TUNELOOP_LLM_PROVIDER=openrouter</code> and <code>export OPENROUTER_API_KEY=…</code>, then <code>tuneloop analyze</code>.');\n }\n if (st === 'stale') {\n var d = daysSinceAnalyze();\n var ago = d != null ? d + ' day' + (d === 1 ? '' : 's') + ' ago' : 'a while ago';\n return notice('stale',\n 'Your dashboard may be out of date',\n 'Last analyzed ' + ago + '. Run <code>tuneloop analyze</code> to pull in sessions since then.');\n }\n return '';\n}\n\n// Mount the banner into every full-width tab slot (Dashboard / Sessions /\n// Artifacts); Highlights injects it inline in the digest instead. Called once the\n// overview lands — the slots are static, so a tab switch (a visibility toggle)\n// leaves them intact, no per-tab re-render needed.\nexport function renderNotices(): void {\n var html = noticeHtml();\n ['#dash-notice', '#sessions-notice', '#art-notice'].forEach(function (id) {\n var el = $(id);\n if (el) el.innerHTML = html;\n });\n}\n","// The Highlights digest — the Dashboard's default view. A few computed insights\n// about your recent AI work (over a fixed window, see HL_DAYS below),\n// each a sentence with the real numbers + a \"See the data →\" drill-in into the\n// surface behind it (with a grounding banner, see askbanner.ts). Rendered into\n// #metric-detail when state.metric === 'highlights' (the landing default).\nimport { state, $, esc, usd, num, get, tildeHome } from './core'\nimport { openMetric, renderWindow, loadKpis } from './kpis'\nimport { filterByArtifact, setView } from './sessions'\nimport { openArtifactSearch } from './artifacts'\nimport { renderAskBanner, clearAsked } from './askbanner'\nimport { storeStatus, noticeHtml } from './notice'\n\n// Highlights runs over a fixed window — wider than the Dashboard's 7d default so\n// short-lived signals still surface, but capped at 14 so the prior-period\n// comparison (this 14d vs the 14d before it = 28d back) stays inside Claude\n// Code's ~30-day session retention and still has data to compare against. 30d\n// would reach 60 days back and the comparison would be empty. Change it here and\n// the copy, the drill window, and the API call all follow.\nvar HL_DAYS = 14;\nvar HL_WIN = 'the last ' + HL_DAYS + ' days';\nvar HL_PREV = 'the previous ' + HL_DAYS + ' days';\n\nfunction base(p) { var a = String(p || '').split('/'); return a[a.length - 1] || p; }\nfunction pct(n) { return Math.round(n) + '%'; }\nfunction ratePct(r) { return Math.round((r || 0) * 100) + '%'; }\nfunction signed(n) { return (Number(n) >= 0 ? '+' : '') + n + '%'; }\nfunction stripTags(s) { return String(s || '').replace(/<[^>]+>/g, ''); }\n\n// The change clause for a relative trend (spend, sessions). A big INCREASE (≥2×)\n// switches from an unreadable percentage (\"+2169%\") to a multiple with the prior\n// value for context (\"≈23× the previous 14 days ($63.57)\"); everything else (and\n// any decrease, which is naturally bounded at −100%) stays a signed percentage.\n// `fmt` formats the prior absolute value (usd for spend, num for counts).\nfunction relChange(cur, prev, pctNum, fmt) {\n if (pctNum >= 100 && prev > 0) {\n var mult = cur / prev;\n var multStr = mult >= 10 ? String(Math.round(mult)) : String(Math.round(mult * 10) / 10);\n return '<b>≈' + multStr + '×</b> ' + HL_PREV + ' (' + esc(fmt(prev)) + ')';\n }\n return '<b>' + signed(pctNum) + '</b> vs ' + HL_PREV;\n}\n\n// A highlight that drills into the Dashboard pins its window to the Highlights\n// window first, so the chart matches the statement the user just clicked (the\n// Dashboard otherwise keeps whatever window it was last left on). This is why 14d\n// has to be a selectable Dashboard window — the drill lands the user on it.\nfunction dashHl() {\n state.days = HL_DAYS;\n setView('dashboard');\n renderWindow();\n loadKpis();\n}\n\n// Friendly noun for a walked facet, used in the orientation line + the tag labels.\nvar FACET_NOUN = { use_case: 'work type', repo: 'repo', model: 'model', harness: 'agent', complexity: 'complexity', autonomy: 'autonomy' };\n\n// Per-tag-key plain-language hover tooltip, surfaced via the tag's title=.\nvar TAG_INFO = {\n file: { tip: 'A file your AI changed.' },\n PR: { tip: 'A pull request your AI opened or merged.' },\n feature: { tip: 'A unit of work your sessions are linked to.' },\n repo: { tip: 'The repository the work was in.' },\n model: { tip: 'The LLM model used.' },\n agent: { tip: 'The agent/harness used (Claude Code, Codex…).' },\n complexity: { tip: 'How hard the task was (LLM-judged).' },\n autonomy: { tip: 'How much the AI worked unaided (LLM-judged).' },\n 'work type': { tip: 'The kind of work — implement, debug, research… (LLM-judged).' },\n};\n\n// A facet/artifact mention styled as a labeled tag — a small muted uppercase key\n// (\"PR\", \"FILE\", \"REPO\") then the value with a faint underline — so a bare value\n// isn't mistaken for prose. Numbers stay bold (<b>); the label + tooltip explain it.\nfunction tag(key, value) {\n var info = TAG_INFO[key] || { tip: '' };\n return '<span class=\"hl-tag\"' + (info.tip ? ' title=\"' + esc(info.tip) + '\"' : '') +\n '><span class=\"hl-tag-k\">' + esc(key) + '</span><span class=\"hl-tag-v\">' + esc(value) + '</span></span>';\n}\n\n// Map an insight payload -> { html sentence, destination label, grounding `about`,\n// the localStorage `section` its orientation is gated on, and run() = the drill-in }.\nfunction present(h) {\n switch (h.kind) {\n case 'biggest_shipped': {\n var t = h.artifactKind === 'pr'\n ? tag('PR', h.repo && h.ident ? h.repo + '#' + h.ident + ' (' + h.title + ')' : h.title)\n : tag('feature', h.title);\n return {\n html: 'Most AI spend on shipped work: ' + t + ' — <b>' + esc(usd(h.cost)) + '</b>.',\n to: h.artifactKind === 'pr' ? 'Artifacts · PRs' : 'Artifacts · Features', section: 'artifacts',\n about: 'The Artifacts view lists every PR and feature your AI touched, with its block-attributed cost.',\n run: function () { openArtifactSearch(h.artifactKind, h.title); },\n };\n }\n case 'trend': {\n if (h.metric === 'rate') {\n var moved = (h.pp || 0) >= 0 ? 'rose' : 'fell';\n return {\n html: 'Your success rate ' + moved + ' from <b>' + ratePct(h.prev) + '</b> to <b>' + ratePct(h.cur) + '</b> vs ' + HL_PREV + '.',\n to: 'Session Outcome Rate', section: 'success_rate',\n about: 'The outcome rate over time — the same signal as the headline tile, here over ' + HL_WIN + '.',\n run: function () { dashHl(); state.sr.by = ''; openMetric('success_rate', true); },\n };\n }\n if (h.metric === 'sessions') {\n return {\n html: 'You ran <b>' + num(h.cur) + ' sessions</b> — ' + relChange(h.cur, h.prev, h.pct, num) + '.',\n to: 'Sessions over time', section: 'sessions_metric',\n about: 'Session count over time — the same signal as the headline tile, here over ' + HL_WIN + '.',\n run: function () { dashHl(); state.sm.by = ''; state.sm.bucket = ''; openMetric('sessions', true); },\n };\n }\n return {\n html: 'You spent <b>' + esc(usd(h.cur)) + '</b> — ' + relChange(h.cur, h.prev, h.pct, usd) + '.',\n to: 'Total spend', section: 'total_spend',\n about: 'Spend over time — the same signal as the headline tile, here over ' + HL_WIN + '.',\n run: function () { dashHl(); state.spend.by = ''; openMetric('total_spend', true); },\n };\n }\n case 'stalled_spend': {\n var st = h.artifactKind === 'pr'\n ? tag('PR', h.repo && h.ident ? h.repo + '#' + h.ident + ' (' + h.title + ')' : h.title)\n : tag('feature', h.title);\n return {\n html: 'Most AI spend not yet shipped: ' + st + ' — <b>' + esc(usd(h.cost)) + '</b>.',\n to: h.artifactKind === 'pr' ? 'Artifacts · PRs' : 'Artifacts · Features', section: 'artifacts',\n about: 'The Artifacts view shows each PR and feature with its block-attributed cost and whether it has shipped yet.',\n run: function () { openArtifactSearch(h.artifactKind, h.title); },\n };\n }\n case 'converted_spend':\n return {\n html: '<b>' + pct(h.pct) + '</b> of your AI spend (<b>' + esc(usd(h.shipped)) + '</b> of ' + esc(usd(h.total)) + ') turned into shipped work.',\n to: 'Cost per shipped artifact', section: 'cost_artifact',\n about: 'The burn curve shades how much of each period’s spend converted into shipped work versus what’s still in flight.',\n run: function () { dashHl(); state.ca.kind = 'pr'; state.ca.userPicked = true; openMetric('cost_artifact', true); },\n };\n case 'active_file':\n return {\n html: 'You touched ' + tag('file', base(h.path)) + ' in <b>' + num(h.sessions) + ' sessions</b> — more than any other.',\n to: 'Sessions · Files', section: 'sessions',\n about: 'This is your session list filtered to one file; open a session’s Files tab to see exactly what changed.',\n run: function () { filterByArtifact(h.path, 'file', HL_DAYS); },\n };\n case 'spend_concentration':\n return {\n html: '<b>' + pct(h.pct) + '</b> of your spend went to ' + tag(FACET_NOUN[h.facet] || h.facet, h.value) + '.',\n to: 'Total spend', section: 'total_spend',\n about: 'Spend over time, split by ' + (FACET_NOUN[h.facet] || h.facet) + ' — change the breakdown or filter to dig in.',\n run: function () { dashHl(); state.spend.by = h.facet; openMetric('total_spend', true); },\n };\n case 'success_spread': {\n var k = FACET_NOUN[h.facet] || h.facet;\n return {\n html: 'Your success rate is <b>' + ratePct(h.best.rate) + '</b> for ' + tag(k, h.best.value) + ' (' + num(h.best.n) +\n ' sessions) but <b>' + ratePct(h.worst.rate) + '</b> for ' + tag(k, h.worst.value) + ' (' + num(h.worst.n) + ').',\n to: 'Session Outcome Rate', section: 'success_rate',\n about: 'The outcome rate broken down by ' + k + ', so you can see where your AI does well.',\n run: function () { dashHl(); state.sr.by = h.facet; openMetric('success_rate', true); },\n };\n }\n case 'autonomy_complex': {\n var d = h.delta;\n var deltaStr = (d != null && d !== 0) ? ' — <b>' + (d > 0 ? 'up ' + d : 'down ' + Math.abs(d)) + '%</b> vs the prior ' + HL_DAYS + ' days' : '';\n return {\n html: '<b>' + num(h.count) + ' of your sessions</b> ran autonomously on complex tasks' + deltaStr + '.',\n to: 'Sessions over time', section: 'sessions_metric',\n about: 'Session count over time, filtered to complex tasks and broken down by autonomy — how much your agent takes on unaided.',\n run: function () {\n dashHl();\n state.sm.by = 'autonomy';\n state.sm.bucket = 'week';\n state.sm.filters = { complexity: ['substantial', 'open-ended'] };\n openMetric('sessions', true);\n },\n };\n }\n default:\n return null;\n }\n}\n\n// The most recent /api/highlights payload, kept so the tab can repaint (e.g. to\n// add the store-state nudge) once the overview lands, without a refetch.\nvar lastHl: any = null;\n\n// Highlights is its own tab, fixed to HL_DAYS (no window selector).\nexport function renderHighlights() {\n get('/api/highlights?days=' + HL_DAYS).then(function (d) {\n lastHl = d;\n paintHighlights();\n });\n}\n\n// The store path shown in the \"deep dive\" prompt: the highlights payload's if\n// loaded, else the overview's, else the default.\nfunction askDbPath() {\n return tildeHome((lastHl && lastHl.dbPath) || (state.overview && state.overview.dbPath) || '~/.tuneloop/tuneloop.sqlite');\n}\n\n// The \"explore the raw store yourself\" prompt shared by the Highlights and\n// Dashboard tabs (query-skill pitch). One string so the copy never diverges.\nexport function deepDiveHtml() {\n return '<div class=\"home-ask\">Want to do a deep dive into the data? It all lives in a local SQLite store at ' +\n '<code>' + esc(askDbPath()) + '</code>. Install the query skill and your coding agent can explore it for you: ' +\n '<code>npx skills add tuneloop/tuneloop</code></div>';\n}\n\n// Mirror the prompt at the bottom of the Dashboard tab. Hidden on an empty store\n// (nothing to explore yet), matching how Highlights suppresses its own body.\nexport function paintDashAsk() {\n var el = $('#dash-ask');\n if (!el) return;\n el.innerHTML = storeStatus() === 'empty' ? '' : deepDiveHtml();\n}\n\n// Paint the digest from the last fetched payload. Separated from the fetch so the\n// overview load can trigger a repaint that folds in the store-state nudge (a fresh\n// store replaces the digest with a first-run prompt; an un-enriched one prepends\n// the enrichment nudge). No-op until the first fetch resolves.\nexport function paintHighlights() {\n if (!lastHl) return;\n var winLabel = HL_WIN;\n // Fresh store (nothing analyzed): the digest would just say \"nothing notable\",\n // which reads as recent inactivity rather than an empty store — show the\n // first-run nudge alone instead.\n if (storeStatus() === 'empty') { $('#highlights').innerHTML = noticeHtml(); return; }\n var items = (lastHl && lastHl.highlights) || [];\n var rows = items.map(function (h, i) {\n var p = present(h);\n if (!p) return '';\n return '<div class=\"hrow\">' +\n '<span class=\"hrow-q\">' + p.html + '</span>' +\n '<button type=\"button\" class=\"hrow-to\" data-i=\"' + i + '\">See the data <i>→</i></button></div>';\n }).join('');\n if (!rows) rows = '<div class=\"empty\">Nothing notable in ' + esc(winLabel) + ' yet — widen the window, or run more sessions.</div>';\n $('#highlights').innerHTML =\n '<div class=\"hl\">' +\n noticeHtml() + // enrichment nudge when un-enriched; '' once enrichment has run\n '<div class=\"hl-head\">Notable in ' + esc(winLabel) + '</div>' +\n '<div class=\"hlist\">' + rows + '</div>' +\n // Order mirrors the top tabs (Dashboard, Artifacts, Sessions).\n '<div class=\"see-tx-wrap\">' +\n '<button class=\"see-tx\" type=\"button\" data-view=\"dashboard\">Headline metrics →</button>' +\n '<button class=\"see-tx\" type=\"button\" data-view=\"artifacts\">Artifacts →</button>' +\n '<button class=\"see-tx\" type=\"button\" data-view=\"sessions\">Your sessions →</button>' +\n '</div>' +\n deepDiveHtml() + '</div>';\n Array.prototype.forEach.call(document.querySelectorAll('#highlights .see-tx[data-view]'), function (b) {\n b.onclick = function () { clearAsked(); setView(b.getAttribute('data-view')); window.scrollTo(0, 0); };\n });\n Array.prototype.forEach.call(document.querySelectorAll('#highlights .hrow-to'), function (el) {\n el.onclick = function () {\n var h = items[parseInt(el.getAttribute('data-i'), 10)];\n var p = present(h);\n if (!p) return;\n // Reuse the grounding banner: the insight IS the answer, so only the\n // orientation (`about`) shows — once per destination section.\n state.asked = { q: stripTags(p.html), answer: '', about: p.about, section: p.section };\n p.run();\n renderAskBanner(true); // renders the message in the slot above the chart + scrolls there\n };\n });\n}\n\n// Return to the Highlights tab (wired to the brand logo + the banner's back link).\nexport function goHighlights() {\n clearAsked();\n setView('highlights');\n renderHighlights();\n}\n","// The grounding message shown when the user drills in from a highlight's \"See the\n// data\". It renders INTO a slot directly above the destination chart/table (not at\n// the page top, where it went unread) and scrolls that slot into view, so the\n// orientation sits next to the thing it describes. Two parts: a slim breadcrumb\n// (the insight + a \"← Back to Highlights\" link) and a one-time-per-section\n// orientation (what you're looking at), dismissable and remembered in localStorage.\nimport { state, esc } from './core'\nimport { goHighlights } from './home'\n\n// Which view's slot a destination renders into (keyed by the insight's `section`).\nvar SECTION_SLOT = {\n success_rate: 'ask-dashboard',\n cost_artifact: 'ask-dashboard',\n total_spend: 'ask-dashboard',\n sessions_metric: 'ask-dashboard',\n artifacts: 'ask-artifacts',\n sessions: 'ask-sessions',\n};\nvar ALL_SLOTS = ['ask-dashboard', 'ask-artifacts', 'ask-sessions'];\n\nfunction seenKey(section) { return 'tuneloop.seen.' + section; }\nfunction seen(section) { try { return !!localStorage.getItem(seenKey(section)); } catch (e) { return false; } }\nfunction markSeen(section) { try { localStorage.setItem(seenKey(section), '1'); } catch (e) { /* private mode */ } }\n\n// `scroll` = bring the slot into view (true only on a fresh drill — not on a dismiss\n// re-render, which would yank the page).\nexport function renderAskBanner(scroll?) {\n ALL_SLOTS.forEach(function (id) { var s = document.getElementById(id); if (s) { s.className = 'ask-slot'; s.innerHTML = ''; } });\n var a = state.asked;\n if (!a) return;\n var slot = document.getElementById(SECTION_SLOT[a.section] || 'ask-dashboard');\n if (!slot) return;\n\n var showOrient = (a.answer || a.about) && !seen(a.section);\n var html =\n '<div class=\"ask-banner on\"><div class=\"ask-bc\"><span class=\"ask-q\">' + esc(a.q) + '</span>' +\n '<a class=\"ask-back\" id=\"ask-back\">← Back to Highlights</a></div>';\n if (showOrient) {\n html +=\n '<div class=\"ask-orient\">' +\n (a.answer ? '<span class=\"ask-ans\">' + esc(a.answer) + '</span> ' : '') +\n (a.about ? '<span class=\"ask-about\">' + esc(a.about) + '</span>' : '') +\n '<button class=\"ask-x\" id=\"ask-x\" title=\"Got it — don’t show this again\">✕</button></div>';\n }\n html += '</div>';\n slot.className = 'ask-slot on';\n slot.innerHTML = html;\n\n var back = slot.querySelector('.ask-back') as any; if (back) back.onclick = goHighlights;\n var x = slot.querySelector('.ask-x') as any; if (x) x.onclick = function () { markSeen(a.section); renderAskBanner(); };\n\n if (scroll) slot.scrollIntoView({ block: 'start' });\n}\n\n// Drop the grounding context (manual nav away from a highlight) and clear the slots.\nexport function clearAsked() {\n state.asked = null;\n renderAskBanner();\n}\n","// Hand-rolled HTML/SVG chart renderers. Every function is pure: it takes data\n// and returns a markup string, so callers just drop the result into innerHTML.\nimport { esc, usd, num, fmtVal } from './core'\n\n// An x-axis tick label that won't clip at the SVG edges. A centered label near\n// the left/right plot bound would spill past the viewBox and get cut off (e.g.\n// a final week label like \"2026-W25\" losing its number); flipping to start/end\n// anchoring at the bound keeps the whole label inside.\nfunction xTick(x, y, text, leftEdge, rightEdge) {\n var s = String(text);\n var half = s.length * 3; // ≈ half the rendered width at 10px\n var anchor = 'middle', tx = x;\n if (x - half < leftEdge) { anchor = 'start'; tx = leftEdge; }\n else if (x + half > rightEdge) { anchor = 'end'; tx = rightEdge; }\n return '<text x=\"' + tx.toFixed(1) + '\" y=\"' + y + '\" text-anchor=\"' + anchor + '\">' + esc(s) + '</text>';\n}\n\n// Round a rate (0–1) up to a tidy axis top whose quarters land on clean\n// percentages (e.g. 0.037 → 0.04, giving 1/2/3/4% gridlines). Capped at 100%.\nfunction niceCeilRate(v) {\n if (!(v > 0)) return 0.04; // no data / all-zero: a small honest 0–4% axis\n var quarter = v / 4;\n var pow = Math.pow(10, Math.floor(Math.log10(quarter)));\n var n = quarter / pow;\n var nice = n <= 1 ? 1 : n <= 2 ? 2 : n <= 5 ? 5 : 10;\n return Math.min(nice * pow * 4, 1);\n}\n\nexport function bars(rows, keyName) {\n if (!rows || !rows.length) return '<div class=\"empty\">No data yet.</div>';\n var max = 0;\n rows.forEach(function (r) { if (r.count > max) max = r.count; });\n return rows.map(function (r) {\n var pct = max ? Math.round((r.count / max) * 100) : 0;\n var label = r[keyName] == null ? '—' : r[keyName];\n return '<div class=\"bar-row\"><span class=\"name\" title=\"' + esc(label) + '\">' + esc(label) +\n '</span><span class=\"bar-track\"><span class=\"bar-fill\" style=\"width:' + pct + '%\"></span></span>' +\n '<span class=\"n\">' + r.count + '</span></div>';\n }).join('');\n}\n\n// Bars for a breakdown ({bucket,value}), value formatted per the measure.\n// Rates (pct) draw on a fixed 0-100% scale (the value is already a fraction);\n// magnitudes draw relative to the largest bucket (sum/share-of-total doesn't\n// generalize — multi-valued facets overlap, so buckets don't sum to a whole).\nexport function measureBars(rows, format) {\n if (!rows || !rows.length) return '<div class=\"empty\">No data.</div>';\n var absolute = format === 'pct';\n var max = 0;\n if (!absolute) rows.forEach(function (r) { var v = Math.abs(r.value || 0); if (v > max) max = v; });\n return rows.map(function (r) {\n var v = Math.abs(r.value || 0);\n var pct = absolute ? Math.min(100, Math.round(v * 100)) : (max ? Math.round((v / max) * 100) : 0);\n var label = r.bucket == null ? '—' : r.bucket;\n return '<div class=\"bar-row\"><span class=\"name\" title=\"' + esc(label) + '\">' + esc(label) +\n '</span><span class=\"bar-track\"><span class=\"bar-fill\" style=\"width:' + pct + '%\"></span></span>' +\n '<span class=\"n\">' + esc(fmtVal(r.value, format)) + '</span></div>';\n }).join('');\n}\n\n// A rotated y-axis caption in the left margin. Shared by the count charts.\nfunction yAxisLabel(text, padT, plotH) {\n if (!text) return '';\n var yc = padT + plotH / 2;\n return '<text x=\"11\" y=\"' + yc.toFixed(1) + '\" text-anchor=\"middle\" transform=\"rotate(-90 11 ' +\n yc.toFixed(1) + ')\">' + esc(text) + '</text>';\n}\n\n// Overall mode: one stacked bar per bucket — full height = sessions started\n// (denominator), filled portion = sessions with a selected outcome (numerator).\n// The rate reads off as the green fraction; the bar's height shows volume.\nexport function barChart(buckets, points, yLabel?) {\n if (!buckets || !buckets.length) return '<div class=\"empty\">No sessions in range.</div>';\n // fullAxis() fills every bucket in a windowed range even when nothing landed in\n // it, so a non-empty `buckets` doesn't imply data — guard on real points too, or\n // an empty window (e.g. no sessions in the last 7 days) draws a bare axis frame.\n if (!points || !points.some(function (p) { return p && p.denom > 0; })) return '<div class=\"empty\">No sessions in range.</div>';\n var W = 920, H = 240, padL = 48, padR = 12, padT = 16, padB = 28;\n var plotW = W - padL - padR, plotH = H - padT - padB, n = buckets.length;\n var byBucket = {};\n points.forEach(function (p) { byBucket[p.bucket] = p; });\n var maxD = 0;\n points.forEach(function (p) { if (p.denom > maxD) maxD = p.denom; });\n maxD = maxD || 1;\n var yOf = function (v) { return padT + (1 - v / maxD) * plotH; };\n var base = yOf(0), bw = plotW / n;\n var svg = '<svg viewBox=\"0 0 ' + W + ' ' + H + '\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">';\n [0, 0.5, 1].forEach(function (g) {\n var v = Math.round(maxD * g), y = yOf(v);\n svg += '<line x1=\"' + padL + '\" y1=\"' + y + '\" x2=\"' + (W - padR) + '\" y2=\"' + y + '\" stroke=\"#ece7dc\"/>';\n svg += '<text x=\"' + (padL - 6) + '\" y=\"' + (y + 3) + '\" text-anchor=\"end\">' + v + '</text>';\n });\n svg += yAxisLabel(yLabel, padT, plotH);\n var step = Math.ceil(n / 9);\n buckets.forEach(function (b, i) {\n var x = padL + i * bw + 2, w = Math.max(2, bw - 4), p = byBucket[b];\n if (p && p.denom > 0) {\n var totalTop = yOf(p.denom), succTop = yOf(p.num);\n svg += '<rect x=\"' + x + '\" y=\"' + totalTop + '\" width=\"' + w + '\" height=\"' + (base - totalTop) + '\" rx=\"2\" fill=\"#ece7dc\"/>';\n svg += '<rect x=\"' + x + '\" y=\"' + succTop + '\" width=\"' + w + '\" height=\"' + (base - succTop) + '\" rx=\"2\" fill=\"#0f7a55\"/>';\n var tip = b + ': ' + p.num + '/' + p.denom + ' with outcome (' + (p.rate != null ? Math.round(p.rate * 100) : 0) + '%)';\n svg += '<rect x=\"' + x + '\" y=\"' + totalTop + '\" width=\"' + w + '\" height=\"' + (base - totalTop) + '\" fill=\"transparent\"><title>' + esc(tip) + '</title></rect>';\n }\n if (i % step === 0) svg += xTick(padL + i * bw + bw / 2, H - padB + 14, b, padL, W - padR);\n });\n svg += '</svg>';\n return svg;\n}\n\n// Breakdown mode: grouped count bars — per bucket, one bar PER series (facet\n// value). Each bar is a single hue (the value's color) so color always means\n// \"which value\"; outcome status is a separate channel — the SOLID lower portion\n// produced a selected outcome, the FADED upper portion did not. The rate reads\n// off as the solid fraction; bar heights show per-value volume.\n// series = [{label,color,points:[{bucket,num,denom,rate}]}].\nexport function groupedBarChart(buckets, series, yLabel?) {\n if (!buckets || !buckets.length) return '<div class=\"empty\">No sessions in range.</div>';\n // See barChart: a windowed axis is always full, so check for real points.\n if (!series || !series.some(function (s) { return (s.points || []).some(function (p) { return p && p.denom > 0; }); })) return '<div class=\"empty\">No sessions in range.</div>';\n var W = 920, H = 240, padL = 48, padR = 12, padT = 16, padB = 28;\n var plotW = W - padL - padR, plotH = H - padT - padB, n = buckets.length;\n var idx = series.map(function (s) {\n var m = {};\n (s.points || []).forEach(function (p) { m[p.bucket] = p; });\n return m;\n });\n var maxD = 0;\n series.forEach(function (s) { (s.points || []).forEach(function (p) { if (p.denom > maxD) maxD = p.denom; }); });\n maxD = maxD || 1;\n var yOf = function (v) { return padT + (1 - v / maxD) * plotH; };\n var base = yOf(0), bw = plotW / n, k = series.length || 1;\n var gpad = Math.min(8, bw * 0.18), inner = bw - gpad, sw = Math.max(1.5, inner / k);\n var svg = '<svg viewBox=\"0 0 ' + W + ' ' + H + '\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">';\n [0, 0.5, 1].forEach(function (g) {\n var v = Math.round(maxD * g), y = yOf(v);\n svg += '<line x1=\"' + padL + '\" y1=\"' + y + '\" x2=\"' + (W - padR) + '\" y2=\"' + y + '\" stroke=\"#ece7dc\"/>';\n svg += '<text x=\"' + (padL - 6) + '\" y=\"' + (y + 3) + '\" text-anchor=\"end\">' + v + '</text>';\n });\n svg += yAxisLabel(yLabel, padT, plotH);\n var step = Math.ceil(n / 9);\n buckets.forEach(function (b, i) {\n var gx = padL + i * bw + gpad / 2;\n series.forEach(function (s, si) {\n var p = idx[si][b];\n if (!p || p.denom <= 0) return;\n var x = gx + si * sw, w = Math.max(1, sw - 0.6);\n var totalTop = yOf(p.denom), fillTop = yOf(p.num);\n // Faded full bar (total) + solid lower portion (with a selected outcome) —\n // both in the value's own hue, so color = value and shade = outcome status.\n svg += '<rect x=\"' + x.toFixed(1) + '\" y=\"' + totalTop.toFixed(1) + '\" width=\"' + w.toFixed(1) + '\" height=\"' + (base - totalTop).toFixed(1) + '\" rx=\"1\" fill=\"' + s.color + '\" fill-opacity=\"0.28\"/>';\n if (p.num > 0) svg += '<rect x=\"' + x.toFixed(1) + '\" y=\"' + fillTop.toFixed(1) + '\" width=\"' + w.toFixed(1) + '\" height=\"' + (base - fillTop).toFixed(1) + '\" rx=\"1\" fill=\"' + s.color + '\"/>';\n var tip = b + ' · ' + s.label + ': ' + p.num + '/' + p.denom + (p.rate != null ? ' (' + Math.round(p.rate * 100) + '%)' : '');\n svg += '<rect x=\"' + x.toFixed(1) + '\" y=\"' + totalTop.toFixed(1) + '\" width=\"' + w.toFixed(1) + '\" height=\"' + (base - totalTop).toFixed(1) + '\" fill=\"transparent\"><title>' + esc(tip) + '</title></rect>';\n });\n if (i % step === 0) svg += xTick(padL + i * bw + bw / 2, H - padB + 14, b, padL, W - padR);\n });\n svg += '</svg>';\n return svg;\n}\n\n// Multi-series line chart on a percent y-axis (0–100% by default, or scaled to\n// the data with opts.adaptive). buckets = x-axis labels;\n// lines = [{label,color,points:[{bucket,rate,num,denom}]}]. Each line aligns to\n// the global bucket axis; buckets a line has no data for become gaps. Sample\n// size per point lives in the hover tooltip (successes/total) — it can't share\n// this percent axis.\nexport function lineChart(buckets, lines, opts?, yLabel?) {\n if (!buckets || !buckets.length) return '<div class=\"empty\">No sessions in range.</div>';\n // See barChart: a windowed axis is always full, so check for real plottable points.\n if (!lines || !lines.some(function (l) { return (l.points || []).some(function (p) { return p && p.rate != null && p.denom > 0; }); })) return '<div class=\"empty\">No sessions in range.</div>';\n // A rotated y-axis caption needs a wider left margin so it clears the % ticks.\n var W = 920, H = 240, padL = yLabel ? 48 : 36, padR = 12, padT = 16, padB = 28;\n var plotW = W - padL - padR, plotH = H - padT - padB, n = buckets.length;\n // Y-axis top: full 100% by default (an honest absolute scale for the outcome rate);\n // opts.adaptive scales to the data so small rates (e.g. error rates of a few %)\n // fill the chart instead of hugging the bottom. The nice-rounded top keeps the\n // quartile gridlines on clean percentages.\n var maxRate = 1;\n if (opts && opts.adaptive) {\n var dmax = 0;\n lines.forEach(function (l) {\n (l.points || []).forEach(function (p) { if (p && p.rate != null && p.denom > 0 && p.rate > dmax) dmax = p.rate; });\n });\n maxRate = niceCeilRate(dmax);\n }\n var xOf = function (i) { return padL + (n === 1 ? plotW / 2 : (i / (n - 1)) * plotW); };\n var yOf = function (r) { return padT + (1 - r / maxRate) * plotH; };\n var svg = '<svg viewBox=\"0 0 ' + W + ' ' + H + '\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">';\n [0, 0.25, 0.5, 0.75, 1].forEach(function (g) {\n var val = g * maxRate, y = yOf(val), pct = val * 100;\n // One decimal on a small adaptive axis so the quarter ticks don't all round\n // to the same integer percent; whole numbers otherwise.\n var lbl = (maxRate < 0.04 ? pct.toFixed(1) : String(Math.round(pct))) + '%';\n svg += '<line x1=\"' + padL + '\" y1=\"' + y + '\" x2=\"' + (W - padR) + '\" y2=\"' + y + '\" stroke=\"#ece7dc\"/>';\n svg += '<text x=\"' + (padL - 6) + '\" y=\"' + (y + 3) + '\" text-anchor=\"end\">' + lbl + '</text>';\n });\n svg += yAxisLabel(yLabel, padT, plotH);\n var step = Math.ceil(n / 9);\n buckets.forEach(function (b, i) {\n if (i % step === 0) svg += xTick(xOf(i), H - padB + 14, b, padL, W - padR);\n });\n lines.forEach(function (l) {\n var byBucket = {};\n (l.points || []).forEach(function (p) { byBucket[p.bucket] = p; });\n var path = '', run = 0, dots = '';\n buckets.forEach(function (b, i) {\n var p = byBucket[b];\n if (p && p.rate != null && p.denom > 0) {\n var x = xOf(i), y = yOf(p.rate);\n path += (run ? 'L' : 'M') + x.toFixed(1) + ' ' + y.toFixed(1) + ' ';\n run++;\n var tip = b + ' · ' + l.label + ': ' + Math.round(p.rate * 100) + '% (' + p.num + '/' + p.denom + ')';\n dots += '<circle cx=\"' + x + '\" cy=\"' + y + '\" r=\"2.6\" fill=\"' + l.color + '\"><title>' + esc(tip) + '</title></circle>';\n } else {\n run = 0; // gap: next plotted point starts a fresh subpath\n }\n });\n if (path) svg += '<path d=\"' + path.trim() + '\" fill=\"none\" stroke=\"' + l.color + '\" stroke-width=\"2\"/>';\n svg += dots;\n });\n svg += '</svg>';\n return svg;\n}\n\n// Stacked bar per bucket: track = total, emerald = filled (filled ≤ total).\n// format controls the y-axis + hover (usd or int). For throughput, filled=total\n// so the bar is fully emerald.\nexport function stackChart(buckets, points, format, yLabel?) {\n if (!buckets || !buckets.length) return '<div class=\"empty\">No data in range.</div>';\n // See barChart: a windowed axis is always full, so check for real points.\n if (!points || !points.some(function (p) { return p && p.total > 0; })) return '<div class=\"empty\">No data in range.</div>';\n var W = 920, H = 200, padL = 48, padR = 12, padT = 16, padB = 28;\n var plotW = W - padL - padR, plotH = H - padT - padB, n = buckets.length;\n var byB = {};\n points.forEach(function (p) { byB[p.bucket] = p; });\n var maxV = 0;\n points.forEach(function (p) { if (p.total > maxV) maxV = p.total; });\n maxV = maxV || 1;\n var yOf = function (v) { return padT + (1 - v / maxV) * plotH; };\n var base = yOf(0), bw = plotW / n;\n var fmt = function (v) { return format === 'usd' ? usd(v) : num(Math.round(v)); };\n var svg = '<svg viewBox=\"0 0 ' + W + ' ' + H + '\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">';\n [0, 0.5, 1].forEach(function (g) {\n var v = maxV * g, y = yOf(v);\n svg += '<line x1=\"' + padL + '\" y1=\"' + y + '\" x2=\"' + (W - padR) + '\" y2=\"' + y + '\" stroke=\"#ece7dc\"/>';\n svg += '<text x=\"' + (padL - 6) + '\" y=\"' + (y + 3) + '\" text-anchor=\"end\">' + esc(fmt(v)) + '</text>';\n });\n svg += yAxisLabel(yLabel, padT, plotH);\n var step = Math.ceil(n / 9);\n buckets.forEach(function (b, i) {\n var x = padL + i * bw + 2, w = Math.max(2, bw - 4), p = byB[b];\n if (p && p.total > 0) {\n var top = yOf(p.total), ftop = yOf(Math.min(p.filled, p.total));\n svg += '<rect x=\"' + x + '\" y=\"' + top + '\" width=\"' + w + '\" height=\"' + (base - top) + '\" rx=\"2\" fill=\"#ece7dc\"/>';\n if (p.filled > 0) svg += '<rect x=\"' + x + '\" y=\"' + ftop + '\" width=\"' + w + '\" height=\"' + (base - ftop) + '\" rx=\"2\" fill=\"#0f7a55\"/>';\n var tip = format === 'usd'\n ? b + ': ' + usd(p.filled) + ' converted of ' + usd(p.total) + ' spent'\n : b + ': ' + num(p.total);\n svg += '<rect x=\"' + x + '\" y=\"' + top + '\" width=\"' + w + '\" height=\"' + (base - top) + '\" fill=\"transparent\"><title>' + esc(tip) + '</title></rect>';\n }\n if (i % step === 0) svg += xTick(padL + i * bw + bw / 2, H - padB + 14, b, padL, W - padR);\n });\n svg += '</svg>';\n return svg;\n}\n\n// Stacked component bars: per bucket, one segment per series, stacked to the\n// bucket's total. series=[{label,color,points:[{bucket,y}]}]; format ('usd'|'int').\n// For breakdowns whose components PARTITION the total (so segments sum honestly to\n// the bar height) — e.g. spend by model/repo/use_case. Each segment carries its own\n// hover tooltip. Series should be pre-sorted (biggest first → stacked at the bottom).\nexport function stackedBarChart(buckets, series, format, yLabel?) {\n if (!buckets || !buckets.length) return '<div class=\"empty\">No data in range.</div>';\n // See barChart: a windowed axis is always full, so check for real points.\n if (!series || !series.some(function (s) { return (s.points || []).some(function (p) { return (p.y || 0) > 0; }); })) return '<div class=\"empty\">No data in range.</div>';\n var W = 920, H = 240, padL = 48, padR = 12, padT = 16, padB = 28;\n var plotW = W - padL - padR, plotH = H - padT - padB, n = buckets.length;\n var idx = series.map(function (s) {\n var m = {};\n (s.points || []).forEach(function (p) { m[p.bucket] = p.y || 0; });\n return m;\n });\n var maxV = 0;\n buckets.forEach(function (b) {\n var t = 0;\n idx.forEach(function (m) { t += m[b] || 0; });\n if (t > maxV) maxV = t;\n });\n maxV = maxV || 1;\n var yOf = function (v) { return padT + (1 - v / maxV) * plotH; };\n var base = yOf(0), bw = plotW / n;\n var fmt = function (v) { return format === 'usd' ? usd(v) : num(Math.round(v)); };\n var svg = '<svg viewBox=\"0 0 ' + W + ' ' + H + '\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">';\n [0, 0.5, 1].forEach(function (g) {\n var v = maxV * g, y = yOf(v);\n svg += '<line x1=\"' + padL + '\" y1=\"' + y + '\" x2=\"' + (W - padR) + '\" y2=\"' + y + '\" stroke=\"#ece7dc\"/>';\n svg += '<text x=\"' + (padL - 6) + '\" y=\"' + (y + 3) + '\" text-anchor=\"end\">' + esc(fmt(v)) + '</text>';\n });\n svg += yAxisLabel(yLabel, padT, plotH);\n var step = Math.ceil(n / 9);\n buckets.forEach(function (b, i) {\n var x = padL + i * bw + 2, w = Math.max(2, bw - 4), acc = 0;\n series.forEach(function (s, si) {\n var v = idx[si][b] || 0;\n if (v > 0) {\n var yTop = yOf(acc + v), yBot = yOf(acc);\n svg += '<rect x=\"' + x + '\" y=\"' + yTop.toFixed(1) + '\" width=\"' + w + '\" height=\"' + (yBot - yTop).toFixed(1) +\n '\" fill=\"' + s.color + '\"><title>' + esc(b + ' · ' + s.label + ': ' + fmt(v)) + '</title></rect>';\n acc += v;\n }\n });\n if (i % step === 0) svg += xTick(padL + i * bw + bw / 2, H - padB + 14, b, padL, W - padR);\n });\n svg += '</svg>';\n return svg;\n}\n\n// Value-axis multi-line chart. lines[i].points = [{bucket, y}]; format ('usd'|'int')\n// drives the y-axis labels + hover. Missing buckets are 0-filled (a real zero, not\n// a gap), so lines connect through quiet periods. Used by spend and sessions.\nexport function valueLineChart(buckets, lines, format, yLabel?) {\n if (!buckets || !buckets.length) return '<div class=\"empty\">No data in range.</div>';\n // See barChart: a windowed axis is always full and this chart 0-fills gaps, so a\n // bare frame would otherwise draw as a flat zero line — guard on a non-zero point.\n if (!lines || !lines.some(function (l) { return (l.points || []).some(function (p) { return (p.y || 0) !== 0; }); })) return '<div class=\"empty\">No data in range.</div>';\n var W = 920, H = 240, padL = 48, padR = 12, padT = 16, padB = 28;\n var plotW = W - padL - padR, plotH = H - padT - padB, n = buckets.length;\n var xOf = function (i) { return padL + (n === 1 ? plotW / 2 : (i / (n - 1)) * plotW); };\n var maxV = 0;\n lines.forEach(function (l) { (l.points || []).forEach(function (p) { if (p.y > maxV) maxV = p.y; }); });\n maxV = maxV || 1;\n var yOf = function (v) { return padT + (1 - v / maxV) * plotH; };\n var fmt = function (v) { return format === 'usd' ? usd(v) : num(Math.round(v)); };\n var svg = '<svg viewBox=\"0 0 ' + W + ' ' + H + '\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\">';\n [0, 0.5, 1].forEach(function (g) {\n var v = maxV * g, y = yOf(v);\n svg += '<line x1=\"' + padL + '\" y1=\"' + y + '\" x2=\"' + (W - padR) + '\" y2=\"' + y + '\" stroke=\"#ece7dc\"/>';\n svg += '<text x=\"' + (padL - 6) + '\" y=\"' + (y + 3) + '\" text-anchor=\"end\">' + esc(fmt(v)) + '</text>';\n });\n svg += yAxisLabel(yLabel, padT, plotH);\n var step = Math.ceil(n / 9);\n buckets.forEach(function (b, i) {\n if (i % step === 0) svg += xTick(xOf(i), H - padB + 14, b, padL, W - padR);\n });\n lines.forEach(function (l) {\n var byB = {};\n (l.points || []).forEach(function (p) { byB[p.bucket] = p; });\n var path = '', dots = '';\n buckets.forEach(function (b, i) {\n var v = byB[b] ? byB[b].y : 0;\n var x = xOf(i), y = yOf(v);\n path += (i ? 'L' : 'M') + x.toFixed(1) + ' ' + y.toFixed(1) + ' ';\n var tip = b + ' · ' + l.label + ': ' + fmt(v);\n dots += '<circle cx=\"' + x + '\" cy=\"' + y + '\" r=\"2.4\" fill=\"' + l.color + '\"><title>' + esc(tip) + '</title></circle>';\n });\n svg += '<path d=\"' + path.trim() + '\" fill=\"none\" stroke=\"' + l.color + '\" stroke-width=\"2\"/>';\n svg += dots;\n });\n svg += '</svg>';\n return svg;\n}\n","// Facet registry loading + the distribution cards, plus the per-metric helpers\n// that decide which facets may split a given chart (grain guards live here so\n// the metric modules don't each re-derive them).\nimport { state, $, esc, get, grainOfSrc } from './core'\nimport { bars } from './charts'\n\n// Fetch the facet registry + a distribution for every chart/filter facet, so\n// dist cards and filters are driven by the registry, not a hardcoded list.\nexport function loadFacets() {\n return get('/api/facets').then(function (facets) {\n state.facets = facets || [];\n var need = {};\n state.facets.forEach(function (f) {\n var roles = f.roles || [];\n if (roles.indexOf('chart') >= 0 || roles.indexOf('filter') >= 0) need[f.key] = 1;\n });\n state.dist = {};\n return Promise.all(Object.keys(need).map(function (k) {\n return get('/api/distribution?facet=' + encodeURIComponent(k)).then(function (d) { state.dist[k] = d || []; });\n }));\n });\n}\n\nexport function renderDists(o) {\n var cards = [];\n state.facets.forEach(function (f) {\n if ((f.roles || []).indexOf('chart') < 0) return;\n var d = state.dist[f.key] || [];\n if (!d.length) return; // skip empty facets (e.g. repo before it resolves)\n cards.push('<div class=\"card\"><h3>' + esc(f.label || f.key) + '</h3>' + bars(d.slice(0, 15), 'value') + '</div>');\n });\n // Non-facet cards (events / tool calls) still come from the overview.\n if (o.outcomes && o.outcomes.length) cards.push('<div class=\"card\"><h3>Outcomes</h3>' + bars(o.outcomes, 'type') + '</div>');\n var tools = (o.topTools || []).map(function (t) { return { value: t.name, count: t.calls }; });\n if (tools.length) cards.push('<div class=\"card\"><h3>Top tools</h3>' + bars(tools, 'value') + '</div>');\n var box = $('#sm-dists'); // distribution cards live under the Sessions tile\n if (box) box.innerHTML = cards.join('');\n}\n\n// Facets that can split a session-grain rate/count into series — any facet\n// declared as a CHART dimension (we compile each value to a session predicate,\n// so counts explode safely). Shared by success-rate + sessions. A facet declares\n// its own eligibility via the `chart` role: error_category is `filter`-only, so a\n// session's MANY error categories never explode the per-session composite-set\n// label here — its clean view is the Ops \"Errors by category\" widget. Skill stays\n// (tool-call grain but a chart dimension), since sessions use few skills.\nexport function srBreakdownFacets() {\n return state.facets.filter(function (f) {\n return (f.roles || []).indexOf('chart') >= 0;\n });\n}\n\n// Cost is usage-grain, so only usage/session-grain facets split it honestly\n// (model, repo, use_case, complexity…); tool-call facets (skill) are excluded.\nexport function spendBreakdownFacets() {\n return state.facets.filter(function (f) {\n var r = f.roles || [];\n if (r.indexOf('chart') < 0 && r.indexOf('filter') < 0) return false;\n return grainOfSrc(f.source) !== 'tool_call';\n });\n}\n\n// --- Per-metric filter slicers (success-rate / total-spend / sessions) ---------\n// A filter is a session-level predicate (compiled server-side by facetPredicate),\n// so the filterable set is BROADER than a measure's *breakdown* set: it includes\n// tool-call facets like `skill` even for cost (you can filter spend to \"sessions\n// that used skill X\" though you can't honestly *split* usage-grain cost by skill).\n// We offer every filter-role facet with a non-empty distribution; chart-only\n// facets (free-text `topics`) are excluded — bad as a dropdown.\nexport function metricFilterFacets() {\n return state.facets.filter(function (f) {\n return (f.roles || []).indexOf('filter') >= 0 && (state.dist[f.key] || []).length > 0;\n });\n}\n\n// Inline filter group for the control row (sits between Bucket and Break-down,\n// mirroring \"apply filters, then group by\"). Each active clause renders as a\n// fixed field LABEL + the selected values as removable chips (OR within a field)\n// + a small \"+\" to add another value of that field. A trailing \"+ filter\"\n// <select> lists only fields not yet used (so each field is one clause → the\n// `current` {field: values[]} map stays 1:1) and, once a field is picked, reveals\n// a value <select> that commits the first value of a new clause.\n// `current` is the section's own {facetKey: value[]} map (per-section, not shared).\nexport function filterRowHtml(idp, current) {\n var label = {};\n state.facets.forEach(function (f) { label[f.key] = f.label || f.key; });\n var clauses = Object.keys(current).filter(function (k) { return (current[k] || []).length; }).map(function (k) {\n var sel = current[k];\n var chips = sel.map(function (v) {\n return '<span class=\"mfl-v\">' + esc(v) +\n '<button class=\"mfl-vx\" type=\"button\" data-key=\"' + esc(k) + '\" data-val=\"' + esc(v) + '\" title=\"Remove value\">×</button></span>';\n }).join('');\n // \"+ value\" select: values of this field not already selected.\n var rest = (state.dist[k] || []).filter(function (r) { return r.value != null && sel.indexOf(String(r.value)) < 0; });\n var addv = '';\n if (rest.length) {\n var o = '<option value=\"\">+</option>';\n rest.forEach(function (r) { o += '<option value=\"' + esc(r.value) + '\">' + esc(r.value) + '</option>'; });\n addv = '<select class=\"sr-by mfl-addv\" data-key=\"' + esc(k) + '\" title=\"Add value\">' + o + '</select>';\n }\n return '<span class=\"mfl-clause\"><span class=\"mfl-k\">' + esc(label[k] || k) + '</span>' + chips + addv + '</span>';\n }).join('');\n var avail = metricFilterFacets().filter(function (f) { return !(current[f.key] || []).length; });\n var addOpts = '<option value=\"\">+ filter</option>';\n avail.forEach(function (f) { addOpts += '<option value=\"' + esc(f.key) + '\">' + esc(f.label || f.key) + '</option>'; });\n var add = '<select class=\"sr-by mfl-field\" id=\"' + idp + '-fl-field\"' + (avail.length ? '' : ' disabled') + '>' + addOpts + '</select>' +\n '<select class=\"sr-by mfl-addval\" id=\"' + idp + '-fl-val\" hidden></select>';\n return '<span class=\"sr-lbl\" style=\"margin-left:18px\">Filter</span>' + clauses + add;\n}\n\n// Wire one section's filter group: per-value removes (✕) + per-field \"+ value\"\n// adds + the \"+ filter\" add widget (field → first value → commit). `rerender`\n// rebuilds the section's controls (refreshing chips + the unused field/value\n// lists); `onChange` reloads the chart. Removing a field's last value drops the\n// clause. Scoped to `box` so it can't collide with the Sessions-list handlers.\nexport function wireFacetFilters(idp, box, current, rerender, onChange) {\n if (box) {\n Array.prototype.forEach.call(box.querySelectorAll('.mfl-vx'), function (b) {\n b.onclick = function () {\n var k = this.getAttribute('data-key'), v = this.getAttribute('data-val');\n current[k] = (current[k] || []).filter(function (x) { return x !== v; });\n if (!current[k].length) delete current[k];\n rerender(); onChange();\n };\n });\n Array.prototype.forEach.call(box.querySelectorAll('.mfl-addv'), function (s) {\n s.onchange = function () {\n if (!this.value) return;\n var k = this.getAttribute('data-key');\n (current[k] = current[k] || []).push(this.value);\n rerender(); onChange();\n };\n });\n }\n var field = document.getElementById(idp + '-fl-field') as any;\n var val = document.getElementById(idp + '-fl-val') as any;\n if (field && val) {\n field.onchange = function () {\n if (!this.value) { val.hidden = true; return; }\n var o = '<option value=\"\">value…</option>';\n (state.dist[this.value] || []).forEach(function (r) {\n if (r.value == null) return;\n o += '<option value=\"' + esc(r.value) + '\">' + esc(r.value) + '</option>';\n });\n val.innerHTML = o; val.hidden = false; val.focus();\n };\n val.onchange = function () {\n if (!field.value || !this.value) return;\n current[field.value] = [this.value];\n rerender(); onChange();\n };\n }\n}\n\n// Serialize a section's filter map to query-string params (each leading '&'):\n// one repeated param per selected value (?model=a&model=b), matching the\n// array-collecting convention the three over-time endpoints use.\nexport function facetFilterQs(current) {\n var qs = '';\n Object.keys(current || {}).forEach(function (k) {\n (current[k] || []).forEach(function (v) {\n qs += '&' + encodeURIComponent(k) + '=' + encodeURIComponent(v);\n });\n });\n return qs;\n}\n","// Session Outcome Rate detail (headline metric #1): outcome-set picker, bucket\n// selector, and a session-count chart whose filled portion is the outcome rate —\n// a single stacked bar per bucket, or grouped bars (one per value) when broken\n// down. The headline % lives on the KPI tile; the expanded view shows the counts\n// behind it.\nimport { state, $, esc, usd, num, SR_PALETTE, get, saveSrPrefs, autoBucket, windowQs, outcomeRank, outcomeLabel, comboLabel } from '../core'\nimport { loadKpis } from '../kpis'\nimport { barChart, groupedBarChart } from '../charts'\nimport { srBreakdownFacets, filterRowHtml, wireFacetFilters, facetFilterQs } from '../facets'\n\n// In-memory legend show/hide for the breakdown chart, keyed by series label.\n// Reset on every new query (loadSuccessRate); preserved across legend clicks,\n// which only re-paint. Not persisted — composite labels are data-dependent.\nvar srHidden = {};\n\nexport function renderSuccessRate() {\n $('#metric-detail').innerHTML =\n '<div class=\"metric-head\">' +\n '<h2>Session Outcome Rate</h2>' +\n '</div>' +\n '<div class=\"panel\">' +\n '<div class=\"sr-controls\" id=\"sr-controls\"></div>' +\n '<div class=\"chart-title\">Count of Sessions with Outcomes</div>' +\n '<div id=\"sr-chart\"></div>' +\n '<div class=\"sr-legend\" id=\"sr-legend\"></div>' +\n '<div class=\"card-note\" id=\"sr-note\"></div>' +\n '</div>' +\n // Cost-vs-outcome table. Only meaningful as a cross-value comparison, so it's\n // shown only when a breakdown is active (renderRateChart toggles the panel).\n '<div class=\"panel\" id=\"sr-tbl-panel\" style=\"display:none\">' +\n '<div class=\"chart-title\" id=\"sr-tbl-title\">Outcome and Spend</div>' +\n '<div id=\"sr-tbl\"></div>' +\n '<div class=\"card-note\" id=\"sr-tbl-note\"></div>' +\n '</div>';\n renderSrControls();\n loadSuccessRate();\n}\n\nexport function renderSrControls() {\n var oc = (state.outcomeTypes || []).slice().sort(function (a, b) { return outcomeRank(a.type) - outcomeRank(b.type); });\n var checks = oc.map(function (o) {\n var on = state.sr.outcomes.indexOf(o.type) >= 0;\n var label = esc(outcomeLabel(o.type));\n return '<label class=\"sr-check\"><input type=\"checkbox\" class=\"sr-oc\" value=\"' + esc(o.type) + '\"' +\n (on ? ' checked' : '') + '/> ' + label + ' <span class=\"sr-cnt\">' + o.sessions + '</span></label>';\n }).join('');\n var activeBucket = autoBucket(state.sr.bucket);\n var bucketBtns = ['day', 'week', 'month'].map(function (b) {\n return '<button class=\"' + (b === activeBucket ? 'on' : '') + '\" data-b=\"' + b + '\">' + b + '</button>';\n }).join('');\n var byOpts = '<option value=\"\">none</option>';\n srBreakdownFacets().forEach(function (f) {\n byOpts += '<option value=\"' + esc(f.key) + '\"' + (f.key === state.sr.by ? ' selected' : '') + '>' +\n esc(f.label || f.key) + '</option>';\n });\n $('#sr-controls').innerHTML =\n '<div class=\"sr-ctrl-row\"><span class=\"sr-lbl\">Count as success</span>' +\n '<span class=\"sr-checks\">' + (checks || '<span class=\"empty\">No outcomes recorded yet — run analysis with a provider key to add LLM-judged outcomes.</span>') + '</span></div>' +\n '<div class=\"sr-ctrl-row\">' +\n '<span class=\"sr-by-ctrl\"><span class=\"sr-lbl\">Bucket</span><span class=\"seg\" id=\"sr-bucket\">' + bucketBtns + '</span></span>' +\n filterRowHtml('sr', state.sr.filters) +\n '<span class=\"sr-by-ctrl\" style=\"margin-left:18px\"><span class=\"sr-lbl\">Break down by</span>' +\n '<select class=\"sr-by\" id=\"sr-by\">' + byOpts + '</select></span></div>';\n wireFacetFilters('sr', $('#sr-controls'), state.sr.filters, renderSrControls, loadSuccessRate);\n Array.prototype.forEach.call(document.querySelectorAll('.sr-oc'), function (c) {\n c.onchange = function () {\n var set = [];\n Array.prototype.forEach.call(document.querySelectorAll('.sr-oc'), function (x) { if (x.checked) set.push(x.value); });\n state.sr.outcomes = set;\n saveSrPrefs();\n loadSuccessRate();\n loadKpis(); // the windowed KPI tile counts success the same way — keep it in sync\n };\n });\n Array.prototype.forEach.call($('#sr-bucket').children, function (btn) {\n btn.onclick = function () { state.sr.bucket = btn.getAttribute('data-b'); renderSrControls(); loadSuccessRate(); };\n });\n $('#sr-by').onchange = function () { state.sr.by = this.value; saveSrPrefs(); loadSuccessRate(); };\n}\n\nexport function loadSuccessRate(topK?) {\n var sr = state.sr;\n srHidden = {}; // a new query may have a different set of labels — start all-visible\n var qs = ['outcomes=' + encodeURIComponent((sr.outcomes || []).join(',')), 'bucket=' + encodeURIComponent(autoBucket(sr.bucket))];\n if (sr.by) qs.push('by=' + encodeURIComponent(sr.by));\n if (topK) qs.push('topK=' + topK);\n get('/api/success-rate?' + qs.join('&') + windowQs() + facetFilterQs(sr.filters)).then(function (d) {\n if (!d || d.error) { $('#sr-chart').innerHTML = '<div class=\"empty\">No data.</div>'; return; }\n renderRateChart(d);\n });\n}\n\n// Per-value outcome-and-cost table (cost-at-equal-rate comparison). One row per\n// series, greyed when hidden in the legend above. The four columns are honest\n// primitives — two counts (sessions, with-outcome) and total spend, plus the one\n// normalized cost cue ($/session = spend ÷ sessions). Cost-per-outcome is left\n// to the eye (total spend vs the adjacent with-outcome count), deliberately not\n// printed, so nothing competes with the cost-per-shipped-artifact KPI.\n// `rows` are series-shaped: {key,text,color,num,denom,spend}.\nfunction tableRow(s) {\n var perSess = s.denom ? esc(usd(s.spend / s.denom)) : '—';\n return '<tr' + (srHidden[s.key] ? ' class=\"off\"' : '') + '>' +\n '<td><span class=\"swatch\" style=\"background:' + s.color + '\"></span>' + esc(s.text) + '</td>' +\n '<td class=\"num\">' + num(s.denom) + '</td>' +\n '<td class=\"num\">' + num(s.num) + '</td>' +\n '<td class=\"num\">' + esc(usd(s.spend)) + '</td>' +\n '<td class=\"num\">' + perSess + '</td>' +\n '</tr>';\n}\nfunction paintTable(rows) {\n $('#sr-tbl').innerHTML =\n '<table class=\"sr-tbl\"><thead><tr>' +\n '<th>Value</th><th class=\"num\">Sessions</th><th class=\"num\">Sessions with outcome</th>' +\n '<th class=\"num\">Total spend</th><th class=\"num\">$ / session</th>' +\n '</tr></thead><tbody>' + rows.map(tableRow).join('') + '</tbody></table>';\n}\n\n// Draw (or re-draw) the breakdown chart + legend + table from srHidden. Hidden\n// series drop out of the chart (the y-axis rescales to what's left) and grey out\n// in the legend and table. Called on load and on every legend interaction.\n// `series` carries the full set (key/label/full/color/points/rate/num/denom/spend).\nfunction paintRate(d, series) {\n var visible = series.filter(function (s) { return !srHidden[s.key]; });\n $('#sr-chart').innerHTML = groupedBarChart(d.buckets || [], visible, 'Sessions');\n paintTable(series); // table keeps every row but greys the hidden ones\n var anyHidden = series.some(function (s) { return srHidden[s.key]; });\n var legend = series.map(function (l) {\n // Two-tone swatch mirrors the bar: solid (with outcome) over faded (none).\n var sw = 'linear-gradient(to top,' + l.color + ' 0 50%,' + l.color + '47 50% 100%)';\n var rate = l.rate != null ? Math.round(l.rate * 100) + '%' : 'n/a';\n return '<span class=\"leg' + (srHidden[l.key] ? ' off' : '') + '\" data-key=\"' + esc(l.key) +\n '\" title=\"' + esc(l.full + (l.rate != null ? ' · ' + rate : '')) + '\">' +\n '<span class=\"swatch\" style=\"background:' + sw + '\"></span>' + esc(l.text) +\n ' <span class=\"sr-cnt\">' + rate + '</span></span>';\n }).join('');\n // Master toggle (de-select all / restore) — only worth showing with many series.\n if (series.length > 5) {\n legend += ' <a class=\"leg-toggle-all\" data-act=\"' + (anyHidden ? 'show' : 'hide') + '\">' +\n (anyHidden ? 'Show all' : 'Hide all') + '</a>';\n }\n if (d.truncated) {\n legend += ' <a class=\"show-all-link\" data-total=\"' + d.truncated.total + '\">Show all ' +\n d.truncated.total + ' combinations</a>';\n }\n $('#sr-legend').innerHTML = legend;\n Array.prototype.forEach.call(document.querySelectorAll('#sr-legend .leg'), function (el) {\n el.onclick = function () {\n var k = this.getAttribute('data-key');\n if (srHidden[k]) delete srHidden[k]; else srHidden[k] = 1;\n paintRate(d, series);\n };\n });\n var allBtn = $('#sr-legend .leg-toggle-all');\n if (allBtn) allBtn.onclick = function () {\n if (this.getAttribute('data-act') === 'hide') series.forEach(function (s) { srHidden[s.key] = 1; });\n else srHidden = {};\n paintRate(d, series);\n };\n var srLink = $('#sr-legend .show-all-link');\n if (srLink) srLink.onclick = function () { loadSuccessRate(this.getAttribute('data-total')); };\n}\n\nexport function renderRateChart(d) {\n var ov = d.overall || { rate: null, num: 0, denom: 0 };\n // Both modes are count charts (Y-axis = sessions), with the outcome rate read\n // off as the colored fill — overall is one stacked bar per bucket; breakdown is\n // one bar per composite label per bucket (grouped). Keeps the volume cue.\n var note = '';\n if (d.series && d.series.length) {\n var series = d.series.map(function (s, i) {\n var lab = comboLabel(s.key);\n // groupedBarChart reads `label` (its bar tooltip) — give it the full set.\n // num/denom/spend ride along for the cost table ($/session = spend/denom).\n return { key: s.key, label: lab.full, text: lab.text, full: lab.full,\n color: SR_PALETTE[i % SR_PALETTE.length], points: s.points,\n rate: s.rate, num: s.num, denom: s.denom, spend: s.spend };\n });\n paintRate(d, series);\n $('#sr-tbl-panel').style.display = '';\n note = d.truncated\n ? 'Showing the top ' + d.truncated.shown + ' of ' + d.truncated.total +\n ' value combinations by session volume; the rest are grouped as “... other values”. '\n : '';\n note += 'Each session is grouped by the set of values it used, so the bars partition sessions (no double-counting). ' +\n 'The solid lower portion of each bar produced a selected outcome, the faded upper portion did not. ' +\n 'Click a legend item to show or hide it.';\n } else {\n $('#sr-chart').innerHTML = barChart(d.buckets || [], ov.points || [], 'Sessions');\n $('#sr-legend').innerHTML =\n '<span class=\"leg-overall\">Overall ' + (ov.rate != null ? Math.round(ov.rate * 100) + '%' : 'n/a') +\n ' · ' + num(ov.num) + ' of ' + num(ov.denom) + ' sessions with a selected outcome</span>';\n note = 'Bar height is sessions started in the bucket; the filled portion produced a selected outcome.';\n // No breakdown → nothing to compare; hide the per-value cost table.\n $('#sr-tbl-panel').style.display = 'none';\n }\n if ((d.outcomes || []).indexOf('pr_merged') >= 0) {\n note += ' Recent buckets may rise as PRs merge — those outcomes backfill after the session.';\n }\n $('#sr-note').innerHTML = esc(note);\n if (d.series && d.series.length) {\n // Default to the raw facet key (state.sr.by), upgraded to the friendly label\n // once facets are loaded — so an early render (facets still in flight) shows\n // \"…by model\", never \"…by value\".\n var byLabel = state.sr.by || 'value';\n srBreakdownFacets().forEach(function (f) { if (f.key === state.sr.by) byLabel = f.label || f.key; });\n $('#sr-tbl-title').textContent = 'Outcome and Spend by ' + byLabel;\n $('#sr-tbl-note').innerHTML = esc('One row per ' + byLabel + ', sorted by session volume. ' +\n '$ / session = total spend ÷ sessions. Rows hidden in the legend above are greyed.');\n }\n}\n","// Interactive, zoomable treemap for the feature-cost breakdown. Unlike the static\n// SVG charts in charts.ts, this one is DOM-based (absolutely-positioned divs) so it\n// can do drill-down with a breadcrumb, a cursor-following tooltip, hover/focus\n// states, and a live \"roll up below $X\" threshold. It's self-contained: it builds\n// its own scaffold inside the host element and wires its own events.\nimport { esc } from './core'\n\ninterface TNode {\n name: string\n total: number\n own?: number\n children: TNode[]\n color?: string\n fill?: string\n direct?: boolean\n isOther?: boolean\n __decorated?: boolean\n}\n\n// One hue per top-level feature family; descendants are lighter shades of it.\nvar PALETTE = ['#0f7a55', '#b8860b', '#b4452f', '#3b6ea5', '#7d5ba6', '#1b8a8a', '#a65c2e', '#6b8e23',\n '#9c4f6e', '#5b7d3f', '#c08a3e', '#6a5acd', '#cc7a52', '#4e8d6e'];\n\n// Lighten a hex color toward white by `amt` (0..1).\nfunction shade(hex: string, amt: number): string {\n var n = parseInt(hex.slice(1), 16);\n var r = n >> 16, g = (n >> 8) & 255, b = n & 255;\n r = Math.round(r + (255 - r) * amt);\n g = Math.round(g + (255 - g) * amt);\n b = Math.round(b + (255 - b) * amt);\n return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);\n}\n\nfunction fmt(v: number): string {\n return '$' + (Number(v) || 0).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n}\n\n// Build a tree from the flat API nodes ([{id,title,parentId,ownCost,subtreeCost}]),\n// children sorted biggest-subtree-first. A parentId that doesn't resolve to a known\n// feature is treated as a root (matches the server normalization).\nfunction buildTree(nodes: any[], rootName: string): TNode {\n var byId: Record<string, TNode> = {};\n nodes.forEach(function (n) {\n byId[n.id] = { name: n.title || '(untitled)', total: n.subtreeCost || 0, own: n.ownCost || 0, children: [] };\n });\n var roots: TNode[] = [];\n nodes.forEach(function (n) {\n var node = byId[n.id];\n if (n.parentId && byId[n.parentId]) byId[n.parentId].children.push(node);\n else roots.push(node);\n });\n (function sortRec(list: TNode[]) {\n list.sort(function (a, b) { return b.total - a.total; });\n list.forEach(function (c) { sortRec(c.children); });\n })(roots);\n return { name: rootName, total: roots.reduce(function (s, c) { return s + c.total; }, 0), children: roots };\n}\n\n// Color each family by its root hue (lighter by depth) and add an explicit\n// \"(direct work)\" own-cost leaf, so when you drill into a parent its children plus\n// its direct spend partition the area honestly. Runs once at build time.\nfunction decorate(node: TNode, base: string, depth: number): void {\n if (node.__decorated) return;\n node.__decorated = true;\n node.color = base;\n node.fill = shade(base, Math.min(0.55, depth * 0.16));\n if (node.children.length) {\n var childSum = node.children.reduce(function (s, c) { return s + c.total; }, 0);\n var own = node.own != null ? node.own : Math.max(0, node.total - childSum);\n if (own > 0.005) {\n node.children.unshift({ name: '(direct work)', total: own, children: [], direct: true });\n }\n node.children.forEach(function (c) { decorate(c, base, depth + 1); });\n }\n}\n\n// Squarified treemap (Bruls/Huizing/van Wijk): pack {node,value} into a rect with\n// near-square tiles, area ∝ value.\nfunction squarify(children: TNode[], x: number, y: number, w: number, h: number) {\n var out: Array<{ node: TNode; x: number; y: number; w: number; h: number }> = [];\n var items = children\n .map(function (c) { return { node: c, value: Math.max(c.total, 0), area: 0 }; })\n .filter(function (it) { return it.value > 0; })\n .sort(function (a, b) { return b.value - a.value; });\n var totalVal = items.reduce(function (s, it) { return s + it.value; }, 0);\n if (totalVal <= 0) return out;\n var scale = (w * h) / totalVal;\n items.forEach(function (it) { it.area = it.value * scale; });\n\n var rx = x, ry = y, rw = w, rh = h;\n var row: typeof items = [], i = 0;\n function worst(r: typeof items, side: number) {\n var sum = r.reduce(function (s, it) { return s + it.area; }, 0);\n var mx = Math.max.apply(null, r.map(function (it) { return it.area; }));\n var mn = Math.min.apply(null, r.map(function (it) { return it.area; }));\n var s2 = side * side;\n return Math.max((s2 * mx) / (sum * sum), (sum * sum) / (s2 * mn));\n }\n function layoutRow(r: typeof items, side: number, horizontal: boolean) {\n var sum = r.reduce(function (s, it) { return s + it.area; }, 0);\n var thick = sum / side;\n var pos = horizontal ? ry : rx;\n r.forEach(function (it) {\n var len = it.area / thick;\n if (horizontal) { out.push({ node: it.node, x: rx, y: pos, w: thick, h: len }); pos += len; }\n else { out.push({ node: it.node, x: pos, y: ry, w: len, h: thick }); pos += len; }\n });\n if (horizontal) { rx += thick; rw -= thick; } else { ry += thick; rh -= thick; }\n }\n while (i < items.length) {\n var horizontal = rw < rh; // lay the row along the shorter side\n var side = horizontal ? rh : rw;\n var next = items[i];\n if (row.length === 0 || worst(row.concat([next]), side) <= worst(row, side)) { row.push(next); i++; }\n else { layoutRow(row, side, horizontal); row = []; }\n }\n if (row.length) { var hz = rw < rh; layoutRow(row, hz ? rh : rw, hz); }\n return out;\n}\n\n// A drillable node = the synthetic \"Other\" bucket, or a real node with at least one\n// non-direct child (so a leaf, or a node whose only extra tile is its own work, is\n// terminal).\nfunction drillable(n: TNode): boolean {\n return !!n.isOther || (!n.direct && !!n.children && n.children.some(function (c) { return !c.direct; }));\n}\n\n// ---- lifecycle: one live instance + a shared tooltip, so resize/teardown is clean.\nvar active: { chartEl: HTMLElement; render: () => void } | null = null;\nvar tipEl: HTMLElement | null = null;\nvar resizeBound = false;\n\nfunction getTip(): HTMLElement {\n if (!tipEl) { tipEl = document.createElement('div'); tipEl.className = 'tm-tip'; document.body.appendChild(tipEl); }\n return tipEl;\n}\nfunction onResize() { if (active && active.chartEl.isConnected) active.render(); else active = null; }\n\n// Tear down the active treemap (called when switching to the icicle) so its resize\n// handler stops firing and the tooltip hides.\nexport function disposeFeatTreemap(): void {\n active = null;\n if (tipEl) tipEl.style.display = 'none';\n}\n\n// Mount the interactive treemap into `host`, driven by the flat cost nodes\n// ([{id,title,parentId,ownCost,subtreeCost}]). `rootName` labels the breadcrumb\n// root (e.g. \"All features\" / \"All PRs\"). Flat node sets (no parentId) render as a\n// plain treemap — no drill-down or \"(direct work)\" tiles, just the roll-up slider.\nexport function renderFeatTreemap(host: HTMLElement, nodes: any[], rootName: string): void {\n var root = buildTree(nodes, rootName || 'All features');\n root.children.forEach(function (c, i) { decorate(c, PALETTE[i % PALETTE.length], 0); });\n\n host.innerHTML =\n '<div class=\"tm\">' +\n '<div class=\"tm-bar\">' +\n '<div class=\"tm-crumb\"></div>' +\n '<label class=\"tm-thr\">Roll up below ' +\n '<input type=\"range\" min=\"0\" max=\"3\" step=\"0.05\" value=\"0.45\">' +\n '<span class=\"tm-thrval\"></span>' +\n '</label>' +\n '</div>' +\n '<div class=\"tm-chart\"></div>' +\n '</div>';\n var chartEl = host.querySelector('.tm-chart') as HTMLElement;\n var crumbEl = host.querySelector('.tm-crumb') as HTMLElement;\n var slider = host.querySelector('.tm-thr input') as HTMLInputElement;\n var thrVal = host.querySelector('.tm-thrval') as HTMLElement;\n\n var stack: TNode[] = [root];\n var threshold = 1; // dollars; below this, siblings collapse into \"Other\"\n\n function render() {\n var node = stack[stack.length - 1];\n // breadcrumb (every level but the last is a clickable ancestor)\n crumbEl.innerHTML = stack.map(function (n, i) {\n return i === stack.length - 1\n ? '<span>' + esc(n.name) + ' · ' + fmt(n.total) + '</span>'\n : '<a data-i=\"' + i + '\">' + esc(n.name) + '</a>';\n }).join('<span class=\"sep\">›</span>');\n Array.prototype.forEach.call(crumbEl.querySelectorAll('a'), function (a: HTMLElement) {\n a.onclick = function () { stack = stack.slice(0, Number(a.getAttribute('data-i')) + 1); render(); };\n });\n\n var W = chartEl.clientWidth, H = chartEl.clientHeight;\n chartEl.innerHTML = '';\n // The direct-work tile is always kept; only real sub-features roll up into \"Other\".\n var kids = (node.children || []).filter(function (c) { return c.total > 0; });\n var big: TNode[] = kids.filter(function (c) { return c.direct; });\n var small: TNode[] = [];\n kids.forEach(function (c) {\n if (c.direct) return;\n if (c.total >= threshold) big.push(c); else small.push(c);\n });\n if (small.length > 1) {\n big.push({\n name: 'Other (' + small.length + ')',\n total: small.reduce(function (s, c) { return s + c.total; }, 0),\n children: small, color: '#9a948a', fill: '#bdb6a8', isOther: true,\n });\n } else if (small.length === 1) big.push(small[0]);\n\n squarify(big, 0, 0, W, H).forEach(function (c) {\n var n = c.node;\n var el = document.createElement('div');\n var canDrill = drillable(n);\n el.className = 'tm-cell' + (n.direct ? ' direct' : '') + (canDrill ? ' haskids' : '') +\n (c.w < 46 || c.h < 26 ? ' tiny' : '');\n el.style.left = c.x + 'px'; el.style.top = c.y + 'px';\n el.style.width = c.w + 'px'; el.style.height = c.h + 'px';\n // backgroundColor (not the `background` shorthand) so the .direct CSS stripe\n // background-image isn't wiped out by the inline style.\n el.style.backgroundColor = n.fill || n.color || '#888';\n el.tabIndex = 0;\n el.innerHTML = '<span class=\"l\">' + esc(n.name) + '</span><span class=\"v\">' + fmt(n.total) + '</span>';\n el.onmousemove = function (e) { showTip(e, n, node.total); };\n el.onmouseleave = function () { getTip().style.display = 'none'; };\n el.onclick = function () { if (canDrill) { stack.push(n); getTip().style.display = 'none'; render(); } };\n el.onkeydown = function (e) { if (e.key === 'Enter' && canDrill) { stack.push(n); render(); } };\n chartEl.appendChild(el);\n });\n }\n\n function showTip(e: MouseEvent, n: TNode, parentTotal: number) {\n var tip = getTip();\n var pct = parentTotal ? (n.total / parentTotal * 100) : 0;\n var subs = (n.children || []).filter(function (c) { return !c.direct; }).length;\n tip.innerHTML = '<b>' + esc(n.name) + '</b><br>' + fmt(n.total) +\n ' <span class=\"pct\">(' + pct.toFixed(1) + '% of ' + esc(stack[stack.length - 1].name) + ')</span>' +\n (subs ? '<br>' + subs + ' sub-feature' + (subs > 1 ? 's' : '') + ' — click to open' : (n.direct ? '<br>spend on this feature itself' : ''));\n tip.style.display = 'block';\n tip.style.left = Math.min(e.clientX + 14, window.innerWidth - 290) + 'px';\n tip.style.top = (e.clientY + 14) + 'px';\n }\n\n slider.oninput = function () {\n // slider 0..3 → $0..$50 on a soft curve, so the low end (where the long tail\n // lives) gets fine control.\n threshold = Math.max(0.01, Math.pow(Number(slider.value) / 3, 2) * 50);\n thrVal.textContent = fmt(threshold);\n render();\n };\n threshold = Math.max(0.01, Math.pow(Number(slider.value) / 3, 2) * 50);\n thrVal.textContent = fmt(threshold);\n\n active = { chartEl: chartEl, render: render };\n if (!resizeBound) { window.addEventListener('resize', onResize); resizeBound = true; }\n render();\n}\n","// Cost per shipped artifact detail (headline metric #2). A top-level Feature/PR\n// toggle scopes the section, with a Complexity filter beside it; below them, three\n// stacked panels:\n// 1. Cost breakdown treemap — feature (hierarchical) or PR (flat) per the toggle.\n// 2. AI spend converted vs unconverted — burn for the toggled kind.\n// 3. Throughput — one graph: \"Features shipped\" or \"PRs merged\". For PRs it counts\n// every merged PR you contributed to (authored OR reviewed), matching the KPI.\n// The window comes from the top-level selector (state.days); the curve bucket is\n// derived from it (short windows get fine buckets) unless the user picks one.\nimport { state, $, esc, get, autoBucket, CX_LABELS, cxLabelList } from '../core'\nimport { loadKpis, paintKpis, setCaKpiOverride } from '../kpis'\nimport { stackChart } from '../charts'\nimport { renderFeatTreemap } from '../featTreemap'\n\nvar caReqId = 0;\nfunction caNoun() { return state.ca.kind === 'pr' ? 'PRs' : 'features'; }\nfunction caWinLabel() { return state.days === 'all' ? 'all time' : 'last ' + state.days + ' days'; }\nfunction caBucket() { return autoBucket(state.ca.bucket); }\n\nexport function renderCostArtifact() {\n var pr = state.ca.kind === 'pr';\n var shipNoun = pr ? 'PR' : 'feature';\n var shipVerb = pr ? 'merged' : 'shipped';\n var win = esc(caWinLabel());\n var tmTitle = pr ? 'PR cost breakdown' : 'Feature cost breakdown';\n var tmSub = esc(caWinLabel()) + (pr ? ' · total spend per merged PR' : ' · total spend per feature & sub-features');\n $('#metric-detail').innerHTML =\n '<div class=\"ca-controls\" id=\"ca-controls\"></div>' +\n // 1. Cost breakdown treemap (feature or PR, per the top-level toggle).\n '<div class=\"panel\">' +\n '<div class=\"panel-head\"><h2>' + tmTitle + ' <span class=\"metric-sub\">' + tmSub + '</span></h2></div>' +\n '<div id=\"ca-feat\"></div>' +\n '<div class=\"sr-legend\" id=\"ca-feat-legend\"></div>' +\n '</div>' +\n // 2. AI spend converted/unconverted (burn for the toggled kind). The Bucket\n // control lives here (top-right) since it only affects this and the\n // throughput chart below — not the all-time treemap above.\n '<div class=\"panel\">' +\n '<div class=\"panel-head\">' +\n '<h2>AI spend: converted vs unconverted <span class=\"metric-sub\">' + win + ' · dated at session start time</span></h2>' +\n '<span style=\"display:inline-flex;align-items:center;gap:8px\"><span class=\"sr-lbl\">Bucket</span><span class=\"seg\" id=\"ca-bucket\"></span></span>' +\n '</div>' +\n '<div id=\"ca-burn\"></div>' +\n '<div class=\"sr-legend\">' +\n '<span class=\"leg\"><span class=\"swatch\" style=\"background:#0f7a55\"></span>converted (linked to a ' + esc(shipVerb) + ' ' + esc(shipNoun) + ')</span>' +\n '<span class=\"leg\"><span class=\"swatch\" style=\"background:#ece7dc\"></span>unconverted — in-flight or never ' + esc(shipVerb) + '</span>' +\n '</div>' +\n '<div class=\"card-note\" id=\"ca-burn-note\"></div>' +\n '</div>' +\n // 3. Throughput — one graph: \"Features shipped\" or \"PRs merged\" (all PRs you\n // contributed to, authored or reviewed). No toggle.\n '<div class=\"panel\">' +\n '<div class=\"panel-head\"><h2 id=\"ca-flow-title\"></h2></div>' +\n '<div id=\"ca-flow-chart\"></div>' +\n (pr ? '<div class=\"card-note\">Includes every merged PR you contributed to — authored or reviewed.</div>' : '') +\n '</div>' +\n '<div class=\"card-note\" id=\"ca-note\"></div>';\n renderCaControls();\n loadTreemap();\n loadCostArtifact();\n}\n\nexport function renderCaControls() {\n var type = [['feature', 'Feature'], ['pr', 'PR']].map(function (o) {\n return '<button class=\"' + (o[0] === state.ca.kind ? 'on' : '') + '\" data-k=\"' + o[0] + '\">' + o[1] + '</button>';\n }).join('');\n var active = caBucket();\n var bk = ['day', 'week', 'month'].map(function (b) {\n return '<button class=\"' + (b === active ? 'on' : '') + '\" data-b=\"' + b + '\">' + b + '</button>';\n }).join('');\n var el = $('#ca-controls');\n if (!el) return;\n var L = CX_LABELS;\n // No window subtitle for features (the ordinal buckets have no line range).\n // Default is every bucket checked (empty state.ca.complexity ⇒ no filter ⇒ all\n // boxes on); a partial selection stores just the checked keys.\n var cxOpts = state.ca.kind === 'pr'\n ? [['trivial', L.trivial, '1–10 lines'], ['small', L.small, '11–100'], ['medium', L.medium, '101–500'], ['large', L.large, '501–1.5k'], ['xl', L.xl, '1.5k+']]\n : [['trivial', L.trivial, ''], ['small', L.small, ''], ['medium', L.medium, ''], ['large', L.large, ''], ['xl', L.xl, ''], ['none', L.none, '']];\n var cxSel = state.ca.complexity ? state.ca.complexity.split(',') : null; // null ⇒ all selected\n var cx = cxOpts.map(function (o) {\n var on = cxSel ? cxSel.indexOf(o[0]) !== -1 : true;\n return '<label class=\"sr-check\"><input type=\"checkbox\" class=\"ca-cx\" value=\"' + o[0] + '\"' + (on ? ' checked' : '') + '/> ' +\n esc(o[1]) + (o[2] ? ' <span class=\"sr-cnt\">' + esc(o[2]) + '</span>' : '') + '</label>';\n }).join('');\n // Artifact (the section-scoping toggle, prominent seg-primary) + Complexity both\n // scope the KPI tile and every chart below. Bucket renders into the AI-spend panel\n // header (#ca-bucket) since it only affects the time-series charts, not the treemap.\n el.innerHTML =\n '<div class=\"sr-ctrl-row\"><span class=\"sr-lbl\">Artifact</span><span class=\"seg seg-primary\" id=\"ca-type\">' + type + '</span>' +\n '<span class=\"sr-lbl\" style=\"margin-left:18px\">Complexity</span>' +\n '<span class=\"sr-checks\" id=\"ca-complexity\">' + cx + '</span></div>';\n Array.prototype.forEach.call($('#ca-type').children, function (btn) {\n btn.onclick = function () {\n state.ca.kind = btn.getAttribute('data-k');\n state.ca.userPicked = true; // stick to this choice; the headline tile mirrors it\n state.ca.complexity = '';\n renderCostArtifact();\n loadKpis();\n };\n });\n var bktEl = $('#ca-bucket');\n if (bktEl) {\n bktEl.innerHTML = bk;\n Array.prototype.forEach.call(bktEl.children, function (btn) {\n btn.onclick = function () { state.ca.bucket = btn.getAttribute('data-b'); renderCaControls(); loadCostArtifact(); };\n });\n }\n var cxEl = $('#ca-complexity');\n if (cxEl) Array.prototype.forEach.call(cxEl.querySelectorAll('.ca-cx'), function (cb) {\n cb.onchange = function () {\n var boxes = cxEl.querySelectorAll('.ca-cx');\n var set = [];\n Array.prototype.forEach.call(boxes, function (x) { if (x.checked) set.push(x.value); });\n if (!set.length) { cb.checked = true; return; } // keep at least one bucket selected\n // Every box checked ⇒ clear the filter (also re-includes untagged artifacts);\n // a partial selection stores just those buckets.\n state.ca.complexity = set.length === boxes.length ? '' : set.join(',');\n loadTreemap(); // treemap is complexity-scoped too (cache keyed by the filter)\n loadCostArtifact();\n };\n });\n}\n\n// Treemap nodes scope to the top-level window (artifacts completed in it) and the\n// complexity filter — both applied server-side — while each tile stays sized by the\n// artifact's all-time build cost, so the treemap decomposes the cost-per-artifact\n// KPI. Cached per (kind, complexity, window); a change to either invalidates both\n// kinds' caches (caTreeKey). Features come hierarchical from /api/feature-costs; PRs\n// are a flat set from /api/artifacts (each PR a tile sized by its all-time cost).\nvar caFeatNodes: any[] | null = null;\nvar caPrNodes: any[] | null = null;\nvar caTreeKey = '';\nvar caTreeReqId = 0;\n\nexport function loadTreemap() {\n var key = state.ca.complexity + '|' + state.days;\n if (caTreeKey !== key) { caFeatNodes = null; caPrNodes = null; caTreeKey = key; }\n var cx = state.ca.complexity ? '&complexity=' + encodeURIComponent(state.ca.complexity) : '';\n var days = '&days=' + encodeURIComponent(String(state.days));\n var myReq = ++caTreeReqId; // ignore an out-of-order response from a superseded filter/window\n if (state.ca.kind === 'pr') {\n if (caPrNodes) { renderTreemap(); return; }\n get('/api/artifacts?kind=pr&shipped=1' + days + cx).then(function (rows) {\n if (myReq !== caTreeReqId) return;\n caPrNodes = (Array.isArray(rows) ? rows : []).map(function (r) {\n return { id: r.id, title: r.title || r.ident || r.externalId || r.id, parentId: null, ownCost: r.costUsd || 0, subtreeCost: r.costUsd || 0 };\n });\n renderTreemap();\n });\n } else {\n if (caFeatNodes) { renderTreemap(); return; }\n get('/api/feature-costs?days=' + encodeURIComponent(String(state.days)) + cx).then(function (d) {\n if (myReq !== caTreeReqId) return;\n caFeatNodes = (d && d.nodes) || [];\n renderTreemap();\n });\n }\n}\n\nfunction renderTreemap() {\n var el = $('#ca-feat');\n if (!el) return;\n var pr = state.ca.kind === 'pr';\n var nodes = pr ? caPrNodes : caFeatNodes;\n var cxNote = state.ca.complexity ? ' <span class=\"metric-sub\">complexity: ' + esc(cxLabelList(state.ca.complexity)) + '</span>' : '';\n if (!nodes) { el.innerHTML = '<div class=\"empty\">Loading…</div>'; return; }\n if (!nodes.length) {\n var emptyMsg = state.ca.complexity\n ? 'No ' + (pr ? 'PRs' : 'features') + ' match this complexity filter — widen the Complexity selection above.'\n : state.days !== 'all'\n ? 'No ' + (pr ? 'PRs merged' : 'features shipped') + ' in this window — widen the window above.'\n : 'No ' + (pr ? 'merged PR' : 'shipped feature') + ' costs yet — ' +\n (pr ? 'merge a PR with linked sessions' : 'ship a feature with linked sessions in the Features tab') + '.';\n el.innerHTML = '<div class=\"empty\">' + emptyMsg + '</div>';\n var leg0 = $('#ca-feat-legend'); if (leg0) leg0.innerHTML = '';\n return;\n }\n renderFeatTreemap(el, nodes, pr ? 'All PRs' : 'All features');\n var leg = $('#ca-feat-legend');\n if (leg) {\n leg.innerHTML = (pr\n ? '<span class=\"leg\">Area ∝ cost · each tile is a merged PR. Use the slider to roll up the long tail into “Other”.</span>'\n : '<span class=\"leg\">Area ∝ subtree cost · Click a tile to drill in; use the slider to roll up the long tail.</span>') + cxNote;\n }\n}\n\n// Curves for the toggled kind (one response feeds both the burn panel and the\n// throughput panel: d.burn, d.throughput = \"shipped\", d.reviewed = PR-only).\nvar caCurves: any = null;\n\nexport function loadCostArtifact() {\n var qs = ['kind=' + encodeURIComponent(state.ca.kind), 'days=' + encodeURIComponent(String(state.days)), 'bucket=' + encodeURIComponent(caBucket())];\n if (state.ca.complexity) qs.push('complexity=' + encodeURIComponent(state.ca.complexity));\n var myReq = ++caReqId;\n caCurves = null;\n renderFlow(); // show a loading state in the throughput panel\n get('/api/cost-artifact?' + qs.join('&')).then(function (d) {\n if (myReq !== caReqId) return;\n if (!d || d.error) { var b = $('#ca-burn'); if (b) b.innerHTML = '<div class=\"empty\">No data.</div>'; return; }\n caCurves = d;\n renderBurn(d);\n renderFlow();\n });\n}\n\nfunction renderBurn(d) {\n // Mirror the complexity-filtered unit cost into the headline tile. The tile is\n // sourced from /api/kpis (unfiltered), so when a filter is active we hand it the\n // figure this endpoint already computed for the same kind/window/complexity.\n setCaKpiOverride(\n state.ca.complexity\n ? { kind: state.ca.kind, days: state.days, complexity: state.ca.complexity, kpi: d.kpi }\n : null,\n );\n paintKpis();\n var burnPts = (d.burn || []).map(function (r) { return { bucket: r.bucket, total: r.spend, filled: r.shippedSpend }; });\n var el = $('#ca-burn');\n if (el) el.innerHTML = stackChart(d.buckets || [], burnPts, 'usd');\n // The complexity filter narrows only the converted line — total AI spend can't be\n // attributed to an artifact, so it stays whole. Flag that so the \"unconverted\"\n // band isn't read as \"never shipped\" when it also holds other-complexity spend.\n var burnNote = $('#ca-burn-note');\n if (burnNote) burnNote.innerHTML = state.ca.complexity\n ? esc('With a complexity filter on, only the converted line is filtered: it counts spend linked to a ' +\n (state.ca.kind === 'pr' ? 'merged PR' : 'shipped feature') + ' of the selected complexity. Total spend is unchanged, ' +\n 'so spend on ' + (state.ca.kind === 'pr' ? 'PRs' : 'features') + ' of other complexity falls into the unconverted band.')\n : '';\n var note = 'Unit cost includes every session that contributed to these ' + caNoun() +\n ', even spend from before the window — so it will not equal spend within the window.';\n if (state.ca.kind === 'pr') {\n note += ' Every merged PR you contributed to counts — authored or reviewed via gh in a' +\n ' captured session; PRs merged outside a captured session aren\\'t counted (yet).';\n }\n var n = $('#ca-note');\n if (n) n.innerHTML = esc(note);\n}\n\nfunction renderFlow() {\n var el = $('#ca-flow-chart');\n if (!el) return;\n var pr = state.ca.kind === 'pr';\n var noun = pr ? 'PRs' : 'Features';\n var verb = pr ? 'merged' : 'shipped';\n var titleEl = $('#ca-flow-title');\n if (titleEl) {\n titleEl.innerHTML = noun + ' ' + verb +\n ' <span class=\"metric-sub\">' + esc(caWinLabel()) + ' · dated at ' + (pr ? 'merge' : 'completion') + ' time</span>';\n }\n var d = caCurves;\n if (!d) { el.innerHTML = '<div class=\"empty\">Loading…</div>'; return; }\n var pts = (d.throughput || []).map(function (r) { return { bucket: r.bucket, total: r.count, filled: r.count }; });\n if (pts.some(function (p) { return p.total > 0; })) {\n el.innerHTML = stackChart(d.buckets || [], pts, 'int');\n return;\n }\n var hint = pr ? 'author or review a PR that merges' : 'mark a feature shipped in the Features tab';\n el.innerHTML = '<div class=\"empty\">No ' + noun.toLowerCase() + ' ' + verb +\n ' in this window — ' + hint + ', or widen the window above.</div>';\n}\n","// Total spend detail (the burn / spend-breakdown view): spend over time, with\n// an optional split into one usage/session-grain cohort line per facet value.\nimport { state, $, esc, usd, SR_PALETTE, get, autoBucket, windowQs } from '../core'\nimport { valueLineChart, stackChart, stackedBarChart } from '../charts'\nimport { spendBreakdownFacets, filterRowHtml, wireFacetFilters, facetFilterQs } from '../facets'\n\nexport function renderTotalSpend() {\n $('#metric-detail').innerHTML =\n '<div class=\"metric-head\">' +\n '<h2>Total spend</h2>' +\n '</div>' +\n '<div class=\"panel\">' +\n '<div class=\"sr-controls\" id=\"sp-controls\"></div>' +\n '<div id=\"sp-chart\"></div>' +\n '<div class=\"sr-legend\" id=\"sp-legend\"></div>' +\n '<div class=\"card-note\" id=\"sp-note\"></div>' +\n '</div>';\n renderSpendControls();\n loadTotalSpend();\n}\n\nexport function renderSpendControls() {\n var sp = state.spend;\n var activeBucket = autoBucket(sp.bucket);\n var bucketBtns = ['day', 'week', 'month'].map(function (b) {\n return '<button class=\"' + (b === activeBucket ? 'on' : '') + '\" data-b=\"' + b + '\">' + b + '</button>';\n }).join('');\n var byOpts = '<option value=\"\">none</option>';\n spendBreakdownFacets().forEach(function (f) {\n byOpts += '<option value=\"' + esc(f.key) + '\"' + (f.key === sp.by ? ' selected' : '') + '>' + esc(f.label || f.key) + '</option>';\n });\n $('#sp-controls').innerHTML =\n '<div class=\"sr-ctrl-row\">' +\n '<span class=\"sr-by-ctrl\"><span class=\"sr-lbl\">Bucket</span><span class=\"seg\" id=\"sp-bucket\">' + bucketBtns + '</span></span>' +\n filterRowHtml('sp', state.spend.filters) +\n '<span class=\"sr-by-ctrl\" style=\"margin-left:18px\"><span class=\"sr-lbl\">Break down by</span>' +\n '<select class=\"sr-by\" id=\"sp-by\">' + byOpts + '</select></span></div>';\n wireFacetFilters('sp', $('#sp-controls'), state.spend.filters, renderSpendControls, loadTotalSpend);\n Array.prototype.forEach.call($('#sp-bucket').children, function (btn) {\n btn.onclick = function () { state.spend.bucket = btn.getAttribute('data-b'); renderSpendControls(); loadTotalSpend(); };\n });\n $('#sp-by').onchange = function () { state.spend.by = this.value; loadTotalSpend(); };\n}\n\nexport function loadTotalSpend(topK?) {\n var sp = state.spend;\n var qs = ['bucket=' + encodeURIComponent(autoBucket(sp.bucket))];\n if (sp.by) qs.push('by=' + encodeURIComponent(sp.by));\n if (topK) qs.push('topK=' + topK);\n get('/api/spend-over-time?' + qs.join('&') + windowQs() + facetFilterQs(sp.filters)).then(function (d) {\n if (!d || d.error) { $('#sp-chart').innerHTML = '<div class=\"empty\">' + esc(d && d.error ? d.error : 'No data.') + '</div>'; return; }\n renderSpend(d);\n });\n}\n\nexport function renderSpend(d) {\n var ov = d.overall || { total: 0, points: [] };\n if (d.series && d.series.length) {\n var series = d.series.map(function (s, i) {\n return {\n label: s.key, color: SR_PALETTE[i % SR_PALETTE.length], total: s.total,\n points: s.points.map(function (p) { return { bucket: p.bucket, y: p.spend }; })\n };\n });\n if (d.presenceInflated) {\n // Multi-valued facet: a session's spend counts under several values, so the\n // components over-sum the total — stacking would lie. Keep cohort lines.\n $('#sp-chart').innerHTML = valueLineChart(d.buckets || [], series, 'usd');\n $('#sp-legend').innerHTML = spendLegend(series);\n var noteL = (d.truncated ? 'Showing top ' + d.truncated.shown + ' of ' + d.truncated.total + ' by spend. ' : '') +\n 'Each line is one cohort. Sessions can carry several values here, so the lines sum to more than total spend.';\n $('#sp-note').innerHTML = esc(noteL);\n } else {\n // Components partition the bucket's spend → stack them. Add a muted \"other\"\n // segment for any top-K tail so the bars still reach the true total.\n var ovByB = {};\n (ov.points || []).forEach(function (p) { ovByB[p.bucket] = p.spend; });\n var shownByB = {};\n series.forEach(function (s) { s.points.forEach(function (p) { shownByB[p.bucket] = (shownByB[p.bucket] || 0) + p.y; }); });\n var otherPts = (d.buckets || []).map(function (b) { return { bucket: b, y: Math.max(0, (ovByB[b] || 0) - (shownByB[b] || 0)) }; });\n var otherTotal = otherPts.reduce(function (a, p) { return a + p.y; }, 0);\n var chart = series.slice();\n if (otherTotal > 0.005) chart.push({ label: 'other', color: '#cfc8b8', total: otherTotal, points: otherPts });\n $('#sp-chart').innerHTML = stackedBarChart(d.buckets || [], chart, 'usd');\n $('#sp-legend').innerHTML = spendLegend(chart);\n var noteB = (d.truncated ? 'Top ' + d.truncated.shown + ' of ' + d.truncated.total + '; the rest are grouped as “other”. ' : '') +\n 'Each bar splits the bucket’s spend into components — hover a segment for its value.';\n $('#sp-note').innerHTML = esc(noteB);\n }\n if (d.truncated) {\n $('#sp-legend').innerHTML += ' <a class=\"show-all-link\" data-total=\"' + d.truncated.total + '\">Show all ' + d.truncated.total + '</a>';\n var spLink = $('#sp-legend .show-all-link');\n if (spLink) spLink.onclick = function () { loadTotalSpend(this.getAttribute('data-total')); };\n }\n } else {\n var barPts = (ov.points || []).map(function (p) { return { bucket: p.bucket, total: p.spend, filled: p.spend }; });\n $('#sp-chart').innerHTML = stackChart(d.buckets || [], barPts, 'usd');\n $('#sp-legend').innerHTML = '<span class=\"leg-overall\">Total ' + esc(usd(ov.total)) + '</span>';\n $('#sp-note').innerHTML = esc('Spend per ' + autoBucket(state.spend.bucket) + ', dated at session start. Break down by a dimension to split it.');\n }\n}\n\nfunction spendLegend(series) {\n return series.map(function (l) {\n return '<span class=\"leg\"><span class=\"swatch\" style=\"background:' + l.color + '\"></span>' + esc(l.label) +\n ' <span class=\"sr-cnt\">' + usd(l.total) + '</span></span>';\n }).join('');\n}\n","// Sessions detail: session count over time, optionally split into one cohort\n// line per facet value.\nimport { state, $, esc, num, SR_PALETTE, get, autoBucket, windowQs, comboLabel } from '../core'\nimport { stackChart, stackedBarChart } from '../charts'\nimport { srBreakdownFacets, filterRowHtml, wireFacetFilters, facetFilterQs } from '../facets'\n\nexport function renderSessionsMetric() {\n $('#metric-detail').innerHTML =\n '<div class=\"metric-head\">' +\n '<h2>Sessions</h2>' +\n '</div>' +\n '<div class=\"panel\">' +\n '<div class=\"sr-controls\" id=\"sm-controls\"></div>' +\n '<div class=\"chart-title\">Session Count</div>' +\n '<div id=\"sm-chart\"></div>' +\n '<div class=\"sr-legend\" id=\"sm-legend\"></div>' +\n '<div class=\"card-note\" id=\"sm-note\"></div>' +\n '</div>';\n renderSmControls();\n loadSessionsOverTime();\n}\n\nexport function renderSmControls() {\n var sm = state.sm;\n var activeBucket = autoBucket(sm.bucket);\n var bucketBtns = ['day', 'week', 'month'].map(function (b) {\n return '<button class=\"' + (b === activeBucket ? 'on' : '') + '\" data-b=\"' + b + '\">' + b + '</button>';\n }).join('');\n var byOpts = '<option value=\"\">none</option>';\n srBreakdownFacets().forEach(function (f) { // any chart-dimension facet (counts explode safely)\n byOpts += '<option value=\"' + esc(f.key) + '\"' + (f.key === sm.by ? ' selected' : '') + '>' + esc(f.label || f.key) + '</option>';\n });\n $('#sm-controls').innerHTML =\n '<div class=\"sr-ctrl-row\">' +\n '<span class=\"sr-by-ctrl\"><span class=\"sr-lbl\">Bucket</span><span class=\"seg\" id=\"sm-bucket\">' + bucketBtns + '</span></span>' +\n filterRowHtml('sm', state.sm.filters) +\n '<span class=\"sr-by-ctrl\" style=\"margin-left:18px\"><span class=\"sr-lbl\">Break down by</span>' +\n '<select class=\"sr-by\" id=\"sm-by\">' + byOpts + '</select></span></div>';\n wireFacetFilters('sm', $('#sm-controls'), state.sm.filters, renderSmControls, loadSessionsOverTime);\n Array.prototype.forEach.call($('#sm-bucket').children, function (btn) {\n btn.onclick = function () { state.sm.bucket = btn.getAttribute('data-b'); renderSmControls(); loadSessionsOverTime(); };\n });\n $('#sm-by').onchange = function () { state.sm.by = this.value; loadSessionsOverTime(); };\n}\n\nexport function loadSessionsOverTime(topK?) {\n var sm = state.sm;\n var qs = ['bucket=' + encodeURIComponent(autoBucket(sm.bucket))];\n if (sm.by) qs.push('by=' + encodeURIComponent(sm.by));\n if (topK) qs.push('topK=' + topK);\n get('/api/sessions-over-time?' + qs.join('&') + windowQs() + facetFilterQs(sm.filters)).then(function (d) {\n if (!d || d.error) { $('#sm-chart').innerHTML = '<div class=\"empty\">No data.</div>'; return; }\n renderSm(d);\n });\n}\n\nexport function renderSm(d) {\n var ov = d.overall || { total: 0, points: [] };\n if (d.series && d.series.length) {\n // Composite labels partition the sessions, so the breakdown stacks honestly:\n // bar height = total session count, each segment = one value combination.\n // Series arrive biggest-first (Other last) → biggest stacked at the bottom.\n var series = d.series.map(function (s, i) {\n var lab = comboLabel(s.key);\n return {\n // stackedBarChart reads `label` for its bar tooltip — give it the full set.\n label: lab.full, text: lab.text, full: lab.full, total: s.total,\n color: SR_PALETTE[i % SR_PALETTE.length],\n points: s.points.map(function (p) { return { bucket: p.bucket, y: p.count }; })\n };\n });\n $('#sm-chart').innerHTML = stackedBarChart(d.buckets || [], series, 'int', 'Sessions');\n $('#sm-legend').innerHTML = series.map(function (l) {\n return '<span class=\"leg\" title=\"' + esc(l.full) + '\"><span class=\"swatch\" style=\"background:' + l.color + '\"></span>' +\n esc(l.text) + ' <span class=\"sr-cnt\">' + num(l.total) + '</span></span>';\n }).join('');\n var note = d.truncated\n ? 'Showing the top ' + d.truncated.shown + ' of ' + d.truncated.total +\n ' value combinations by session count; the rest are grouped as “... other values”. '\n : '';\n note += 'Each session is grouped by the set of values it used, so the segments partition the bar — its height is the total session count.';\n if (d.truncated) {\n $('#sm-legend').innerHTML += ' <a class=\"show-all-link\" data-total=\"' + d.truncated.total + '\">Show all ' + d.truncated.total + ' combinations</a>';\n var smLink = $('#sm-legend .show-all-link');\n if (smLink) smLink.onclick = function () { loadSessionsOverTime(this.getAttribute('data-total')); };\n }\n $('#sm-note').innerHTML = esc(note);\n } else {\n var barPts = (ov.points || []).map(function (p) { return { bucket: p.bucket, total: p.count, filled: p.count }; });\n $('#sm-chart').innerHTML = stackChart(d.buckets || [], barPts, 'int', 'Sessions');\n $('#sm-legend').innerHTML = '<span class=\"leg-overall\">Total ' + num(ov.total) + ' sessions</span>';\n $('#sm-note').innerHTML = esc('Sessions started per ' + autoBucket(state.sm.bucket) + '. Break down by a dimension to split it.');\n }\n}\n","// Operational metrics detail: three independent time-series graphs — tool-call\n// counts, tool error rate, and skill-usage counts — sharing one bucket control,\n// split across two tabs. The Tools tab shows error rate, the errors-by-category\n// breakdown, then tool-call counts; the Skills tab shows skill-usage counts.\n// Each graph can break down by tool/skill name; the error-rate graph can also\n// break down by error category and carries row-level filters (tool name / error\n// category) that scope the rate to those calls. Error rate reuses the percent\n// line chart; counts use int bars (overall) or int lines (breakdown).\nimport { state, $, esc, num, dayOf, SR_PALETTE, get, autoBucket, windowQs } from '../core'\nimport { lineChart, valueLineChart } from '../charts'\nimport { filterByErrorCategory, startErrorWalk } from '../sessions'\n\n// Per-view, in-memory line show/hide (keyed by tool/skill name), like the\n// outcome chart's legend. Reset on every load (new query); preserved across\n// legend clicks, which only re-paint. Each of the three graphs hides its own.\nvar opsHidden = { tool_calls: {}, error_rate: {}, skill_usage: {} };\n\nvar OPS_VIEWS = [\n { key: 'tool_calls', title: 'Tool Call Counts' },\n { key: 'error_rate', title: 'Tool error rate' },\n { key: 'skill_usage', title: 'Skill Usage Count' }\n];\n\nfunction opsByLabel(view) { return view === 'skill_usage' ? 'skill name' : 'tool name'; }\n\n// Y-axis caption per graph: a percent error axis, or a count axis named for what\n// it counts.\nfunction opsYLabel(view, fmt) {\n return fmt === 'pct' ? 'Error rate' : view === 'skill_usage' ? 'Skill invocations' : 'Tool calls';\n}\n\nfunction opsView(key) {\n for (var i = 0; i < OPS_VIEWS.length; i++) if (OPS_VIEWS[i].key === key) return OPS_VIEWS[i];\n return { key: key, title: key };\n}\n\n// Break-down options for a view: none / by name, plus by-error-category on the\n// error-rate chart (which decomposes the rate into per-category contribution lines).\nfunction opsByOptions(v) {\n var cur = state.ops.by[v.key] || '';\n var html = '<option value=\"\"' + (cur === '' ? ' selected' : '') + '>none</option>' +\n '<option value=\"name\"' + (cur === 'name' ? ' selected' : '') + '>' + esc(opsByLabel(v.key)) + '</option>';\n if (v.key === 'error_rate') {\n html += '<option value=\"error_category\"' + (cur === 'error_category' ? ' selected' : '') + '>error category</option>';\n }\n return html;\n}\n\n// One metric panel (chart + its own break-down control + legend/note). The\n// error-rate panel head reads left-to-right Title → Filter → Break-down on one\n// wrapping row (the row-level filter sits inline; break-down drops to the next\n// line as a whole once the filter clauses grow). Other panels keep the title-left\n// / break-down-right head.\nfunction opsPanel(v) {\n var byCtrl = '<span class=\"sr-by-ctrl\"><span class=\"sr-lbl\">Break down by</span>' +\n '<select class=\"sr-by\" id=\"ops-by-' + v.key + '\">' + opsByOptions(v) + '</select></span>';\n var head = v.key === 'error_rate'\n ? '<div class=\"panel-head ops-erhead\"><h2>' + esc(v.title) + '</h2>' +\n '<span class=\"ops-flt\" id=\"ops-flt-error_rate\"></span>' + byCtrl + '</div>'\n : '<div class=\"panel-head\"><h2>' + esc(v.title) + '</h2>' + byCtrl + '</div>';\n return '<div class=\"panel\">' + head +\n '<div id=\"ops-chart-' + v.key + '\"></div>' +\n '<div class=\"sr-legend\" id=\"ops-legend-' + v.key + '\"></div>' +\n '<div class=\"card-note\" id=\"ops-note-' + v.key + '\"></div>' +\n '</div>';\n}\n\nfunction opsErrcatPanel() {\n return '<div class=\"panel\"><div class=\"panel-head\"><h2>Errors by category</h2></div>' +\n '<div class=\"errcat\" id=\"ops-errcat\"></div>' +\n '<div class=\"card-note\" id=\"ops-errcat-note\"></div>' +\n '</div>';\n}\n\nexport function renderOps() {\n var tab = state.ops.tab || 'tools';\n // Tools tab: error rate + category breakdown first, then tool-call counts.\n var toolsPane = opsPanel(opsView('error_rate')) + opsErrcatPanel() + opsPanel(opsView('tool_calls'));\n // Skills tab: skill-usage counts.\n var skillsPane = opsPanel(opsView('skill_usage'));\n $('#metric-detail').innerHTML =\n '<div class=\"metric-head\"><h2>Operational Metrics</h2></div>' +\n '<div class=\"ops-controls\" id=\"ops-controls\"></div>' +\n '<div class=\"ops-tabpane\" id=\"ops-tab-tools\"' + (tab === 'tools' ? '' : ' hidden') + '>' + toolsPane + '</div>' +\n '<div class=\"ops-tabpane\" id=\"ops-tab-skills\"' + (tab === 'skills' ? '' : ' hidden') + '>' + skillsPane + '</div>';\n renderOpsControls();\n // All views live in the DOM regardless of active tab (cheap; tab switch just\n // toggles visibility), so wire + load every one up front.\n OPS_VIEWS.forEach(function (v) {\n var sel = $('#ops-by-' + v.key);\n if (sel) sel.onchange = function () { state.ops.by[v.key] = this.value; loadOps(v.key); };\n loadOps(v.key);\n });\n loadErrorCats();\n // The error-rate filter row needs the tool-name + category value lists; fetch\n // (cached) then render + wire it.\n ensureOpsFilterData().then(renderOpsFilter);\n}\n\n// Value sources for the error-rate filter, fetched once and cached.\nvar opsToolNames = null; // string[]\nvar opsFilterCats = null; // [{ key, label }]\nfunction ensureOpsFilterData() {\n var ps = [];\n if (opsToolNames == null) ps.push(get('/api/tool-names').then(function (d) { opsToolNames = d || []; }));\n if (opsFilterCats == null) ps.push(get('/api/error-categories').then(function (d) { opsFilterCats = d || []; }));\n return Promise.all(ps);\n}\n\n// The two row-level filter fields, each as {key, label, vals:[{value,label}]}.\nfunction opsFilterFields() {\n return [\n { key: 'toolNames', label: 'Tool name', vals: (opsToolNames || []).map(function (n) { return { value: n, label: n }; }) },\n { key: 'errorCategories', label: 'Error category', vals: (opsFilterCats || []).map(function (c) { return { value: c.key, label: c.label }; }) },\n ];\n}\n\n// Render + wire the error-rate filter row. Mirrors the shared metric-filter\n// look (chips + \"+ value\" + \"+ filter\") but stays ops-local: it reads its values\n// from opsToolNames / opsFilterCats and writes state.ops.filters, never the\n// global facets. Re-renders itself on change, then reloads just the error chart.\nfunction renderOpsFilter() {\n var box = $('#ops-flt-error_rate');\n if (!box) return;\n var f = state.ops.filters;\n var fields = opsFilterFields();\n var clauses = fields.filter(function (fld) { return (f[fld.key] || []).length; }).map(function (fld) {\n var sel = f[fld.key];\n var labelOf = {};\n fld.vals.forEach(function (v) { labelOf[v.value] = v.label; });\n var chips = sel.map(function (v) {\n return '<span class=\"mfl-v\">' + esc(labelOf[v] || v) +\n '<button class=\"mfl-vx\" type=\"button\" data-field=\"' + esc(fld.key) + '\" data-val=\"' + esc(v) + '\" title=\"Remove value\">×</button></span>';\n }).join('');\n var rest = fld.vals.filter(function (v) { return sel.indexOf(v.value) < 0; });\n var addv = '';\n if (rest.length) {\n var o = '<option value=\"\">+</option>';\n rest.forEach(function (v) { o += '<option value=\"' + esc(v.value) + '\">' + esc(v.label) + '</option>'; });\n addv = '<select class=\"sr-by mfl-addv\" data-field=\"' + esc(fld.key) + '\" title=\"Add value\">' + o + '</select>';\n }\n return '<span class=\"mfl-clause\"><span class=\"mfl-k\">' + esc(fld.label) + '</span>' + chips + addv + '</span>';\n }).join('');\n var avail = fields.filter(function (fld) { return !(f[fld.key] || []).length; });\n var addOpts = '<option value=\"\">+ filter</option>';\n avail.forEach(function (fld) { addOpts += '<option value=\"' + esc(fld.key) + '\">' + esc(fld.label) + '</option>'; });\n var add = '<select class=\"sr-by mfl-field\" id=\"ops-er-fl-field\"' + (avail.length ? '' : ' disabled') + '>' + addOpts + '</select>' +\n '<select class=\"sr-by mfl-addval\" id=\"ops-er-fl-val\" hidden></select>';\n box.innerHTML = '<span class=\"sr-lbl\">Filter</span>' + clauses + add;\n\n // Reload the chart on any change; also refresh the \"Errors by category\" widget\n // when the TOOL filter changed (it scopes that widget too — but the category\n // filter doesn't, so don't disturb an open accordion for it).\n var reload = function (changed) {\n renderOpsFilter();\n loadOps('error_rate');\n if (changed === 'toolNames') loadErrorCats();\n };\n Array.prototype.forEach.call(box.querySelectorAll('.mfl-vx'), function (b) {\n b.onclick = function () {\n var k = this.getAttribute('data-field'), v = this.getAttribute('data-val');\n f[k] = (f[k] || []).filter(function (x) { return x !== v; });\n reload(k);\n };\n });\n Array.prototype.forEach.call(box.querySelectorAll('.mfl-addv'), function (s) {\n s.onchange = function () {\n if (!this.value) return;\n var k = this.getAttribute('data-field');\n (f[k] = f[k] || []).push(this.value);\n reload(k);\n };\n });\n var field = $('#ops-er-fl-field'), val = $('#ops-er-fl-val');\n if (field && val) {\n var byKey = {};\n fields.forEach(function (fl) { byKey[fl.key] = fl.vals; });\n field.onchange = function () {\n if (!this.value) { val.hidden = true; return; }\n var o = '<option value=\"\">value…</option>';\n (byKey[this.value] || []).forEach(function (v) { o += '<option value=\"' + esc(v.value) + '\">' + esc(v.label) + '</option>'; });\n val.innerHTML = o; val.hidden = false; val.focus();\n };\n val.onchange = function () {\n if (!field.value || !this.value) return;\n f[field.value] = [this.value];\n reload(field.value);\n };\n }\n}\n\n// Cached taxonomy metadata (key -> {label, description}) for the category tooltips.\nvar errorCatTips = null;\n\n// Dedicated widget: error COUNT per category (a rate-by-category has no honest\n// denominator — categories exist only on failed rows), scoped to the window.\nexport function loadErrorCats() {\n var box = $('#ops-errcat');\n if (!box) return;\n // Mirror the chart's tool filter: the widget counts are scoped to it too.\n var noteEl = $('#ops-errcat-note');\n if (noteEl) {\n var tn = state.ops.filters.toolNames || [];\n noteEl.innerHTML = 'Count of failed tool calls per category (share of all errors)' +\n (tn.length ? ' for ' + esc(tn.join(', ')) : '') +\n ', over the selected window. Hover a category for what it means.';\n }\n var tipsP = errorCatTips\n ? Promise.resolve(errorCatTips)\n : get('/api/error-categories').then(function (cats) {\n errorCatTips = {};\n (cats || []).forEach(function (c) { errorCatTips[c.key] = c; });\n return errorCatTips;\n });\n Promise.all([tipsP, get('/api/breakdown?measure=error_count&by=error_category' + windowQs() + opsToolQs())]).then(function (r) {\n var tips = r[0] || {}, d = r[1] || {};\n if (d.error) { box.innerHTML = '<div class=\"empty\">Could not load error categories.</div>'; return; }\n var rows = d.rows || [];\n if (!rows.length) { box.innerHTML = '<div class=\"empty\">No tool-call errors.</div>'; return; }\n var total = d.total || 0;\n var max = rows[0].value || 1; // rows arrive sorted by value DESC\n box.innerHTML = rows.map(function (row) {\n var key = row.bucket == null ? 'other' : row.bucket;\n var meta = tips[key] || { label: key, description: '' };\n var pct = max ? Math.round((row.value / max) * 100) : 0;\n var share = total ? Math.round((row.value / total) * 100) : 0;\n // Each category is an accordion: the bar + a collapsible occurrence list.\n // data-total is the true count (occurrences are capped → drives \"+N more\").\n return '<div class=\"errcat-item\" data-cat=\"' + esc(key) + '\" data-total=\"' + (row.value || 0) + '\">' +\n '<div class=\"bar-row errcat-row\" data-cat=\"' + esc(key) + '\"><span class=\"name\" title=\"' + esc(meta.description) + '\">' + esc(meta.label) +\n '</span><span class=\"bar-track\"><span class=\"bar-fill\" style=\"width:' + pct + '%\"></span></span>' +\n '<span class=\"n\"><span class=\"cnt\">' + num(row.value) + '</span><span class=\"pct\">' + share + '%</span></span></div>' +\n '<div class=\"errcat-occ\" hidden></div></div>';\n }).join('');\n // Click a category → expand its actual failed tool calls (the occurrence list).\n Array.prototype.forEach.call(box.querySelectorAll('.errcat-row'), function (el) {\n el.onclick = function () { toggleOcc(el.parentNode, el.getAttribute('data-cat'), tips); };\n });\n }).catch(function () { box.innerHTML = '<div class=\"empty\">Could not load error categories.</div>'; });\n}\n\n// Accordion: expand one category's occurrence list (single-open). Lazy-loads the\n// failed tool calls on first open, then caches them on the panel.\nfunction toggleOcc(item, cat, tips) {\n var panel = item.querySelector('.errcat-occ');\n if (!panel) return;\n var wasOpen = !panel.hidden;\n Array.prototype.forEach.call(document.querySelectorAll('#ops-errcat .errcat-occ'), function (p) {\n p.hidden = true; p.parentNode.querySelector('.errcat-row').classList.remove('open');\n });\n if (wasOpen) return; // toggle closed\n panel.hidden = false;\n item.querySelector('.errcat-row').classList.add('open');\n if (panel.getAttribute('data-loaded')) return;\n panel.innerHTML = '<div class=\"occ-loading\">Loading…</div>';\n // True category total (the bar count); the occurrence list is capped, so renderOcc\n // shows a \"+N more\" note when total exceeds the fetched rows.\n var total = parseInt(item.getAttribute('data-total'), 10) || 0;\n get('/api/error-occurrences?category=' + encodeURIComponent(cat) + windowQs() + opsToolQs()).then(function (occ) {\n panel.setAttribute('data-loaded', '1');\n renderOcc(panel, cat, occ || [], tips, total);\n }).catch(function () {\n // Leave data-loaded unset so re-opening retries the fetch.\n panel.innerHTML = '<div class=\"occ-empty\">Could not load occurrences.</div>';\n });\n}\n\nfunction renderOcc(panel, cat, occ, tips, total) {\n if (!occ.length) { panel.innerHTML = '<div class=\"occ-empty\">No occurrences in this window.</div>'; return; }\n var label = (tips[cat] && tips[cat].label) || cat;\n var count = total || occ.length; // the bar count is the true total; occ is capped\n var moreN = Math.max(0, count - occ.length); // occurrences beyond the fetched cap\n var head = '<div class=\"occ-head\">' + count + ' occurrence' + (count > 1 ? 's' : '') +\n ' · <a class=\"occ-sessions\" href=\"#\">view sessions →</a></div>';\n var list = occ.map(function (o, i) {\n var cmd = o.command || o.targetPath || '';\n return '<div class=\"occ-row\" data-i=\"' + i + '\" title=\"click to open the transcript at this error\">' +\n '<span class=\"occ-tool\">' + esc(o.name) + '</span>' +\n '<span class=\"occ-cmd\" title=\"' + esc(cmd) + '\">' + esc(clip(cmd, 44)) + '</span>' +\n '<span class=\"occ-msg\" title=\"' + esc(o.message || '') + '\">' + esc(clip(o.message || '', 60)) + '</span>' +\n '<span class=\"occ-sess\">' + esc(clip(o.title || '(untitled)', 22)) + '</span>' +\n '<span class=\"occ-date\">' + esc(dayOf(o.startedAt || o.ts)) + '</span></div>';\n }).join('');\n var more = moreN ? '<div class=\"occ-more\">+ ' + moreN + ' more (showing ' + occ.length + ')</div>' : '';\n panel.innerHTML = head + '<div class=\"occ-list\">' + list + '</div>' + more;\n // Click an occurrence → open its transcript at that exact error + start the walk.\n Array.prototype.forEach.call(panel.querySelectorAll('.occ-row'), function (el) {\n el.onclick = function () { startErrorWalk(label, occ, parseInt(el.getAttribute('data-i'), 10)); };\n });\n var sl = panel.querySelector('.occ-sessions');\n if (sl) sl.onclick = function (e) { e.preventDefault(); filterByErrorCategory(cat); };\n}\n\nfunction clip(s, n) { s = String(s == null ? '' : s); return s.length > n ? s.slice(0, n - 1) + '…' : s; }\n\nexport function renderOpsControls() {\n var activeBucket = autoBucket(state.ops.bucket);\n var bucketBtns = ['day', 'week', 'month'].map(function (b) {\n return '<button class=\"' + (b === activeBucket ? 'on' : '') + '\" data-b=\"' + b + '\">' + b + '</button>';\n }).join('');\n var activeTab = state.ops.tab || 'tools';\n var tabBtns = [['tools', 'Tools'], ['skills', 'Skills']].map(function (t) {\n return '<button class=\"' + (t[0] === activeTab ? 'on' : '') + '\" data-t=\"' + t[0] + '\">' + t[1] + '</button>';\n }).join('');\n $('#ops-controls').innerHTML =\n '<div class=\"sr-ctrl-row\"><span class=\"sr-lbl\">Bucket</span><span class=\"seg\" id=\"ops-bucket\">' + bucketBtns + '</span>' +\n '<span class=\"sr-lbl\">View</span><span class=\"seg\" id=\"ops-tab\">' + tabBtns + '</span></div>';\n Array.prototype.forEach.call($('#ops-bucket').children, function (btn) {\n btn.onclick = function () {\n state.ops.bucket = btn.getAttribute('data-b');\n renderOpsControls();\n OPS_VIEWS.forEach(function (v) { loadOps(v.key); }); // bucket is shared — reload all three\n };\n });\n // Tab switch only toggles pane visibility — every chart is already loaded.\n Array.prototype.forEach.call($('#ops-tab').children, function (btn) {\n btn.onclick = function () {\n state.ops.tab = btn.getAttribute('data-t');\n var isTools = state.ops.tab === 'tools';\n var tools = $('#ops-tab-tools'); if (tools) tools.hidden = !isTools;\n var skills = $('#ops-tab-skills'); if (skills) skills.hidden = isTools;\n renderOpsControls(); // refresh the 'on' highlight\n };\n });\n}\n\n// Tool-name params alone (repeated per value). Shared by the error-rate chart and\n// the \"Errors by category\" widget/drilldown, which the tool filter also scopes.\nfunction opsToolQs() {\n var qs = '';\n (state.ops.filters.toolNames || []).forEach(function (v) { qs += '&tool_name=' + encodeURIComponent(v); });\n return qs;\n}\n\n// Full row-level filter params for the error-rate chart: tool names + the\n// error-category numerator scope. Empty for the other views.\nfunction opsFilterQs() {\n var qs = opsToolQs();\n (state.ops.filters.errorCategories || []).forEach(function (v) { qs += '&error_category=' + encodeURIComponent(v); });\n return qs;\n}\n\nexport function loadOps(view, topK?) {\n var by = state.ops.by[view];\n opsHidden[view] = {}; // a new query may have a different set of lines — start all-visible\n var qs = 'view=' + encodeURIComponent(view) + '&bucket=' + encodeURIComponent(autoBucket(state.ops.bucket)) +\n (by ? '&by=' + encodeURIComponent(by) : '') + windowQs();\n if (view === 'error_rate') qs += opsFilterQs();\n if (topK) qs += '&topK=' + topK;\n get('/api/ops-over-time?' + qs).then(function (d) {\n if (!d || d.error) { $('#ops-chart-' + view).innerHTML = '<div class=\"empty\">No data.</div>'; return; }\n renderOpsChart(view, d);\n });\n}\n\n// Draw (or re-draw) a breakdown graph + legend from opsHidden[view]. Hidden\n// lines drop out of the chart (the y-axis rescales to what's left) and grey out\n// in the legend. fmt selects the line renderer + legend value (pct rate vs int\n// count). Each `line` carries {key,label,color,points,total/rate}.\nfunction paintOps(view, d, lines, fmt) {\n var hidden = opsHidden[view];\n var visible = lines.filter(function (l) { return !hidden[l.key]; });\n var yLabel = opsYLabel(view, fmt);\n $('#ops-chart-' + view).innerHTML = fmt === 'pct'\n ? lineChart(d.buckets || [], visible, { adaptive: true }, yLabel)\n : valueLineChart(d.buckets || [], visible, 'int', yLabel);\n var anyHidden = lines.some(function (l) { return hidden[l.key]; });\n var legend = lines.map(function (l) {\n var val = fmt === 'pct'\n ? (l.rate != null ? ' <span class=\"sr-cnt\">' + Math.round(l.rate * 100) + '%</span>' : '')\n : ' <span class=\"sr-cnt\">' + num(l.total) + '</span>';\n return '<span class=\"leg' + (hidden[l.key] ? ' off' : '') + '\" data-key=\"' + esc(l.key) + '\" title=\"' + esc(l.label) + '\">' +\n '<span class=\"swatch\" style=\"background:' + l.color + '\"></span>' + esc(l.label) + val + '</span>';\n }).join('');\n // Master toggle (de-select all / restore) — only worth showing with many lines.\n if (lines.length > 5) {\n legend += ' <a class=\"leg-toggle-all\" data-act=\"' + (anyHidden ? 'show' : 'hide') + '\">' +\n (anyHidden ? 'Show all' : 'Hide all') + '</a>';\n }\n if (d.truncated) {\n legend += ' <a class=\"show-all-link\" data-view=\"' + view + '\" data-total=\"' + d.truncated.total + '\">Show all ' +\n d.truncated.total + '</a>';\n }\n $('#ops-legend-' + view).innerHTML = legend;\n Array.prototype.forEach.call(document.querySelectorAll('#ops-legend-' + view + ' .leg'), function (el) {\n el.onclick = function () {\n var k = this.getAttribute('data-key');\n if (hidden[k]) delete hidden[k]; else hidden[k] = 1;\n paintOps(view, d, lines, fmt);\n };\n });\n var allBtn = $('#ops-legend-' + view + ' .leg-toggle-all');\n if (allBtn) allBtn.onclick = function () {\n if (this.getAttribute('data-act') === 'hide') lines.forEach(function (l) { hidden[l.key] = 1; });\n else opsHidden[view] = {};\n paintOps(view, d, lines, fmt);\n };\n var showAll = $('#ops-legend-' + view + ' .show-all-link');\n if (showAll) showAll.onclick = function () { loadOps(this.getAttribute('data-view'), this.getAttribute('data-total')); };\n}\n\nexport function renderOpsChart(view, d) {\n var ov = d.overall || { total: null, points: [] };\n var note = '';\n var hasBreakdown = d.series && d.series.length;\n if (d.format === 'pct') {\n // Error rate → percent line chart (reusing the success-rate renderer).\n if (hasBreakdown) {\n var rlines = d.series.map(function (s, i) {\n return { key: s.key, label: s.label || s.key, color: SR_PALETTE[i % SR_PALETTE.length], rate: s.total,\n points: s.points.map(function (p) { return { bucket: p.bucket, rate: p.value, num: p.errors, denom: p.calls }; }) };\n });\n paintOps(view, d, rlines, 'pct'); // interactive legend (hide/show lines)\n } else {\n var oline = [{ label: 'error rate', color: SR_PALETTE[2],\n points: ov.points.map(function (p) { return { bucket: p.bucket, rate: p.value, num: p.errors, denom: p.calls }; }), rate: ov.total }];\n $('#ops-chart-' + view).innerHTML = lineChart(d.buckets || [], oline, { adaptive: true }, opsYLabel(view, 'pct'));\n $('#ops-legend-' + view).innerHTML = '<span class=\"leg\"><span class=\"swatch\" style=\"background:' + oline[0].color + '\"></span>error rate' +\n (oline[0].rate != null ? ' <span class=\"sr-cnt\">' + Math.round(oline[0].rate * 100) + '%</span>' : '') + '</span>';\n }\n note = d.by === 'error_category'\n ? 'Each line = a category\\'s errored calls ÷ all calls in the bucket; the lines sum to the overall error rate.'\n : 'Error rate = errored tool calls / all tool calls, dated at session start.';\n } else {\n // Counts → int bars (overall) / int lines (breakdown).\n if (hasBreakdown) {\n var clines = d.series.map(function (s, i) {\n return { key: s.key, label: s.label || s.key, color: SR_PALETTE[i % SR_PALETTE.length], total: s.total,\n points: s.points.map(function (p) { return { bucket: p.bucket, y: p.value }; }) };\n });\n paintOps(view, d, clines, 'int'); // interactive legend (hide/show lines)\n } else {\n // A single line (not bars), to match the error-rate overall and the\n // breakdown lines — count graphs stay lines throughout.\n var lbl = d.view === 'skill_usage' ? 'skill invocations' : 'tool calls';\n var cline = [{ label: lbl, color: SR_PALETTE[0],\n points: ov.points.map(function (p) { return { bucket: p.bucket, y: p.value }; }) }];\n $('#ops-chart-' + view).innerHTML = valueLineChart(d.buckets || [], cline, 'int', opsYLabel(view, 'int'));\n $('#ops-legend-' + view).innerHTML = '<span class=\"leg\"><span class=\"swatch\" style=\"background:' + SR_PALETTE[0] +\n '\"></span>' + esc(lbl) + ' <span class=\"sr-cnt\">' + num(ov.total) + '</span></span>';\n }\n note = (d.view === 'skill_usage' ? 'Skill invocations' : 'Tool calls') + ' per bucket, dated at session start.';\n }\n if (d.truncated) note = 'Showing top ' + d.truncated.shown + ' of ' + d.truncated.total +\n (d.by === 'error_category' ? ' by error volume. ' : ' by call volume. ') + note;\n $('#ops-note-' + view).innerHTML = esc(note);\n}\n","// The headline KPI tile row + the tile-as-nav behaviour: clicking a tile opens\n// that metric's full-width detail section, and exactly one section is always\n// expanded (default success_rate, set in main.ts).\nimport { state, $, esc, usd, num, get, fmtVal, kpiDelta, cxLabelList } from './core'\nimport { syncHash } from './router'\nimport { clearAsked } from './askbanner'\nimport { successDefinable } from './notice'\nimport { renderSuccessRate } from './metrics/successRate'\nimport { renderCostArtifact } from './metrics/costArtifact'\nimport { renderTotalSpend } from './metrics/totalSpend'\nimport { renderSessionsMetric } from './metrics/sessionsMetric'\nimport { renderOps } from './metrics/ops'\n\n// The top-level window selector + caption. Sets the window every headline tile\n// AND every expansion's charts are computed over. Lives where the caption used\n// to, so \"Last N days\" is now an adjustable control, not just a label.\nvar WINDOWS = [['7', '7d'], ['14', '14d'], ['30', '30d'], ['90', '90d'], ['all', 'All']];\nexport function renderWindow() {\n var cap = $('#kpi-caption');\n if (!cap) return;\n var btns = WINDOWS.map(function (o) {\n return '<button class=\"' + (String(state.days) === o[0] ? 'on' : '') + '\" data-d=\"' + o[0] + '\">' + o[1] + '</button>';\n }).join('');\n var caption = state.days === 'all'\n ? 'All time'\n : 'Last ' + state.days + ' days · ▲▼ vs. previous ' + state.days + ' days';\n cap.innerHTML = '<span class=\"win-seg seg\" id=\"win-seg\">' + btns + '</span>' +\n '<span class=\"win-cap\">' + caption + '</span>';\n Array.prototype.forEach.call($('#win-seg').children, function (btn) {\n btn.onclick = function () {\n var d = btn.getAttribute('data-d');\n state.days = d === 'all' ? 'all' : parseInt(d, 10);\n renderWindow();\n loadKpis();\n // Every expansion's charts track the same window. Re-default each curve\n // bucket for the new span (clear manual picks), then re-render whichever\n // detail is open so its charts + labels follow N.\n state.sr.bucket = ''; state.ca.bucket = ''; state.spend.bucket = ''; state.sm.bucket = ''; state.ops.bucket = '';\n renderOpenMetric();\n };\n });\n}\n\n// Re-render the currently expanded metric's detail (shared by openMetric and the\n// window selector). No-op when no detail is open.\nexport function renderOpenMetric() {\n var m = state.metric;\n if (m === 'success_rate') renderSuccessRate();\n else if (m === 'cost_artifact') renderCostArtifact();\n else if (m === 'total_spend') renderTotalSpend();\n else if (m === 'sessions') renderSessionsMetric();\n else if (m === 'ops') renderOps();\n}\n\n// The most recent /api/kpis payload, kept so the tile row can repaint without a\n// refetch when the overview lands (which decides whether any outcomes exist at\n// all — see paintKpis' Session Outcome Rate handling).\nvar lastKpis: any = null;\n\n// The complexity-filtered cost-per-artifact figure, published by the Cost-by-\n// Artifact detail (renderBurn) so the headline tile can mirror the active filter.\n// Tagged with its kind/window/complexity so a stale filter never paints.\nvar caKpiOverride: any = null;\nexport function setCaKpiOverride(o: any) { caKpiOverride = o; }\n\nexport function loadKpis() {\n // The headline success-rate tile counts success the same way the detail view\n // does (outcomes), and the whole row honors the top-level window (days).\n var outcomes = (state.sr.outcomes || []).join(',');\n var qs = 'outcomes=' + encodeURIComponent(outcomes) + '&days=' + encodeURIComponent(String(state.days));\n get('/api/kpis?' + qs).then(function (k) {\n lastKpis = k;\n paintKpis();\n });\n}\n\n// Render the headline tile row from the last fetched payload + current store\n// state. Separated from the fetch so an overview load can trigger a repaint (the\n// \"any outcomes recorded?\" check below depends on it).\nexport function paintKpis() {\n var k = lastKpis;\n if (!k || k.error) { $('#kpis').innerHTML = ''; return; }\n var cur = k.current || {}, prev = k.previous || {};\n var cpf = cur.costPerFeature || {}, ppf = prev.costPerFeature || {};\n var cpr = cur.costPerPr || {}, ppr = prev.costPerPr || {};\n var defaultKind = (cpf.count === 0 && (cpr.count || 0) > 0) ? 'pr' : 'feature';\n state.ca.defaultKind = defaultKind;\n // The tile mirrors the kind the user picked in the detail; until then, the\n // smart default. Keep state.ca.kind synced so the detail opens on it too.\n if (!state.ca.userPicked) state.ca.kind = defaultKind;\n var caData = state.ca.kind === 'pr'\n ? { cur: cpr, prev: ppr, label: 'per merged PR', noun: 'PR', nounPl: 'PRs', verb: 'merged' }\n : { cur: cpf, prev: ppf, label: 'per shipped feature', noun: 'feature', nounPl: 'features', verb: 'shipped' };\n // When a complexity filter is active, the tile mirrors the filtered figure the\n // Cost-by-Artifact endpoint computed — but only if the override still matches the\n // current kind/window/complexity (guards against a stale filter after a switch).\n var caCx = state.ca.complexity;\n var useCaFilter = !!caCx && caKpiOverride && caKpiOverride.kind === state.ca.kind &&\n caKpiOverride.days === state.days && caKpiOverride.complexity === caCx;\n if (useCaFilter) {\n caData.cur = caKpiOverride.kpi.current || {};\n caData.prev = caKpiOverride.kpi.previous || {};\n }\n var cnt = caData.cur.count || 0;\n var caSub = useCaFilter\n ? caData.label + ' · counting ' + cnt + ' ' + (cnt === 1 ? caData.noun : caData.nounPl) + ' of complexity: ' + cxLabelList(caCx)\n : caData.label + ' · ' + cnt + ' ' + (cnt === 1 ? caData.noun : caData.nounPl) + ' ' + caData.verb;\n // A \"0%\" outcome rate only means something once the selected success definition\n // can actually be satisfied; when none of its outcome types exist (e.g. the\n // default `session_success` before LLM enrichment has run), the rate is a\n // structural 0, so show \"—\" (and no delta) rather than a misleadingly bad number.\n // successDefinable reads the overview, so this corrects once that lands (see the\n // paintKpis callers in main.ts) and the enrichment nudge explains why.\n var srKnown = successDefinable();\n var tiles = [\n { label: 'Session Outcome Rate', value: srKnown ? fmtVal(cur.successRate, 'pct') : '—',\n delta: srKnown ? kpiDelta(cur.successRate, prev.successRate, 'points', 'up') : '',\n sub: srKnown ? 'of sessions in window' : 'no matching outcomes yet', metric: 'success_rate' },\n { label: 'Cost per shipped artifact', value: caData.cur.costPerUnit != null ? usd(caData.cur.costPerUnit) : '—',\n delta: kpiDelta(caData.cur.costPerUnit, caData.prev.costPerUnit, 'rel', 'down'), sub: caSub,\n metric: 'cost_artifact' },\n { label: 'Total spend', value: usd(cur.totalSpend),\n delta: kpiDelta(cur.totalSpend, prev.totalSpend, 'rel', null), sub: '', metric: 'total_spend' },\n { label: 'Sessions', value: num(cur.sessions),\n delta: kpiDelta(cur.sessions, prev.sessions, 'rel', null), sub: '', metric: 'sessions' },\n { label: 'Tool error rate', value: fmtVal(cur.errorRate, 'pct'),\n delta: kpiDelta(cur.errorRate, prev.errorRate, 'points', 'down'), sub: 'of tool calls', metric: 'ops' }\n ];\n $('#kpis').innerHTML = tiles.map(function (t) {\n // Tiles with a metric key are clickable nav into that metric's detail view.\n var cls = 'tile' + (t.metric ? ' clickable' : '') + (t.metric && t.metric === state.metric ? ' on' : '');\n var attr = t.metric ? ' data-metric=\"' + t.metric + '\"' : '';\n return '<div class=\"' + cls + '\"' + attr + '><div class=\"label\">' + esc(t.label) + '</div><div class=\"value\"><span class=\"num\">' +\n esc(t.value) + '</span>' + (t.delta || '') + '</div><div class=\"sub\">' + esc(t.sub) + '</div></div>';\n }).join('');\n Array.prototype.forEach.call(document.querySelectorAll('#kpis .tile[data-metric]'), function (el) {\n el.onclick = function () { clearAsked(); openMetric(el.getAttribute('data-metric')); };\n });\n}\n\n// Tiles act as nav: one section is always expanded; clicking a tile switches to it.\nexport function openMetric(m, force?) {\n if (state.metric === m && !force) return; // already expanded (unless forced)\n state.metric = m;\n state.view = 'dashboard';\n syncKpiActive();\n renderOpenMetric();\n syncHash(); // mirror the metric into the URL (no-op while a route is applying)\n}\n\nexport function syncKpiActive() {\n Array.prototype.forEach.call(document.querySelectorAll('#kpis .tile[data-metric]'), function (el) {\n el.classList.toggle('on', el.getAttribute('data-metric') === state.metric);\n });\n}\n","// Hash-based router. The URL hash mirrors the navigational slice of `state`: the\n// path is which screen (tab + dashboard metric / artifacts kind), and the query\n// string is that screen's filtered-list state (so a filtered list — and a future\n// graph drill-down into one — is a shareable, reload-survivable URL). Two\n// directions:\n//\n// state → URL syncHash(): a nav/filter handler mutates state, then asks the\n// router to write the hash. Uses history.pushState/replaceState,\n// which do NOT fire popstate/hashchange — so writing never loops.\n// URL → state applyFromUrl(): on Back/Forward (popstate), a manual hash edit\n// (hashchange), or first load, parse the hash and drive the same\n// nav/filter functions a click would.\n//\n// Hash routing (not History API) is deliberate: the dev server only serves\n// index.html for `/`, so clean paths like /sessions/abc would 404 on reload.\n// Everything after `#` is never sent to the server, so deep links just work.\n// The pure parse/serialize lives in router-url.ts (DOM-free, unit-tested).\nimport { state } from './core'\nimport { parseHash, serializeRoute } from './router-url'\nimport type { Route } from './router-url'\nimport { setView, openDetail, closeDrawer, getSessionParams, applySessionParams } from './sessions'\nimport { openMetric } from './kpis'\nimport { getArtifactParams, applyArtifactParams } from './artifacts'\n\nexport type { Route } from './router-url'\n\n// True while applyRoute()/withoutSync() drive the nav functions, so their\n// syncHash() calls no-op — otherwise replaying a Back navigation (or the initial\n// paint) would push a fresh history entry.\nvar applying = false\n\n/** The query map for the current screen: the active list's filter state, plus\n * the open drawer (orthogonal to the list). */\nfunction currentQuery(): Record<string, string> {\n var q: Record<string, string> = {}\n if (state.view === 'sessions') q = getSessionParams()\n else if (state.view === 'artifacts') q = getArtifactParams()\n if (state.open) q.session = state.open\n return q\n}\n\n/** Serialize the current state into its canonical hash string. */\nexport function buildHash(): string {\n return serializeRoute(state, currentQuery())\n}\n\n/**\n * Write the current state into the URL. No-ops while a route is being applied\n * (so Back/Forward never spawns new entries) and when the hash is unchanged.\n * Discrete navigations push (Back retraces them); `replace` is for in-place\n * tweaks that shouldn't add history (filter edits, closing a drawer, the initial\n * normalize).\n */\nexport function syncHash(opts?: { replace?: boolean }): void {\n if (applying) return\n var next = buildHash()\n if (next === window.location.hash) return\n if (opts && opts.replace) window.history.replaceState(null, '', next)\n else window.history.pushState(null, '', next)\n}\n\n/** Drive the nav functions to match a Route. Idempotent, so a double-fired\n * popstate+hashchange (Back/Forward fires both for hash entries) is harmless. */\nfunction applyRoute(r: Route): void {\n applying = true\n try {\n setView(r.view)\n if (r.view === 'dashboard') openMetric(r.metric)\n else if (r.view === 'artifacts') applyArtifactParams(r.artKind, r.query)\n else if (r.view === 'sessions') applySessionParams(r.query)\n if (r.session && r.session !== state.open) openDetail(r.session)\n else if (!r.session && state.open) closeDrawer()\n } finally {\n applying = false\n }\n}\n\nfunction applyFromUrl(): void {\n applyRoute(parseHash(window.location.hash))\n}\n\n/**\n * Run `fn` with hash-writing suppressed — for the initial paint, where main.ts\n * drives the nav functions itself and a single replaceState(buildHash()) at the\n * end normalizes the URL, so no per-call pushState mints a stray history entry.\n */\nexport function withoutSync(fn: () => void): void {\n applying = true\n try {\n fn()\n } finally {\n applying = false\n }\n}\n\n/**\n * Boot the router: attach the Back/Forward + manual-hash-edit listeners and\n * return the initial Route parsed from the URL. main.ts owns the first render\n * (it controls the async load order), wrapping it in withoutSync() and finishing\n * with replaceState(buildHash()) to normalize the URL.\n */\nexport function initRouter(): Route {\n window.addEventListener('popstate', applyFromUrl)\n window.addEventListener('hashchange', applyFromUrl)\n return parseHash(window.location.hash)\n}\n","// Dashboard entry point. Wires the static chrome (tabs, drawer), restores the\n// view/metric/open-session from the URL hash, then kicks off the async loads.\n// Lands on the Highlights tab by default (when the hash is empty); an explicit\n// deep link to any other view wins. Bundled by tsup into dist/client/app.js and\n// loaded by index.html.\nimport { state, $, esc, get, dayOf, tildeHome } from './core'\nimport { initRouter, withoutSync, buildHash } from './router'\nimport { loadFacets } from './facets'\nimport { loadKpis, paintKpis, renderWindow, renderOpenMetric } from './kpis'\nimport { renderSrControls, loadSuccessRate } from './metrics/successRate'\nimport { renderHighlights, paintHighlights, paintDashAsk, goHighlights } from './home'\nimport { renderNotices } from './notice'\nimport { clearAsked } from './askbanner'\nimport { buildFilters, closeDrawer, setView, openDetail, applySessionParams } from './sessions'\nimport { renderArtKindSeg, loadArtifacts } from './artifacts'\n\nfunction init() {\n // Attach Back/Forward + hash-edit listeners and read where the URL says to land.\n var route = initRouter();\n\n // The drawer's close button is rendered per-open inside the sticky header\n // (wired in openDetail); the overlay click still closes from anywhere.\n $('#overlay').onclick = closeDrawer;\n Array.prototype.forEach.call(document.querySelectorAll('.tab'), function (b) {\n // Manual tab nav drops any question-grounding banner.\n b.onclick = function () { clearAsked(); setView(b.getAttribute('data-view')); };\n });\n\n // Highlights is the landing tab: an empty/partial hash lands there, while a deep\n // link to any other view (e.g. a shared #/dashboard/ops or #/sessions?…) wins.\n var hash = window.location.hash;\n var landHighlights = !hash || hash === '#' || hash === '#/';\n\n // Initial paint driven by the URL. Wrapped in withoutSync so none of these nav\n // calls mint history entries; the single replaceState below normalizes the URL\n // (so an empty or partial hash becomes its canonical form).\n withoutSync(function () {\n state.artKind = route.artKind;\n state.metric = route.metric; // the KPI tile that's expanded (default success_rate)\n // Restore the artifacts table's search/sort only when we're landing there\n // (the query params are scoped to the active view).\n if (route.view === 'artifacts') {\n state.art = { q: route.query.q || '', sort: route.query.sort || 'created', dir: route.query.dir === 'asc' ? 'asc' : 'desc' };\n }\n renderArtKindSeg();\n renderOpenMetric(); // pre-render the chosen dashboard metric's detail\n renderHighlights(); // pre-render the Highlights tab so it's ready whether we land there or tab in later\n setView(landHighlights ? 'highlights' : route.view);\n if (route.session) openDetail(route.session); // deep-linked drawer\n });\n\n // The brand logo returns to Highlights from anywhere.\n var brand = document.querySelector('.brand') as HTMLElement | null;\n if (brand) { brand.style.cursor = 'pointer'; brand.onclick = goHighlights; }\n\n get('/api/overview').then(function (o) {\n state.overview = o;\n var range = o.firstAt && o.lastAt ? dayOf(o.firstAt) + ' → ' + dayOf(o.lastAt) : '';\n // Tilde the home dir so screenshots don't leak the username.\n var tilde = tildeHome;\n var dbPath = tilde(o.dbPath || '');\n // The header shows just the store location; the session range, last-analyzed\n // time, and per-directory scan history live in an info popover beside it.\n var roots = o.analyzedRoots || [];\n var info = '';\n if (range || o.lastAnalyzedAt || roots.length) {\n var head =\n (range ? '<div class=\"mi-head\">Sessions ' + esc(range) + '</div>' : '') +\n (o.lastAnalyzedAt ? '<div class=\"mi-head\">Last analyzed ' + esc(dayOf(o.lastAnalyzedAt)) + '</div>' : '');\n var rows = roots.length\n ? roots.map(function (r) {\n return '<div class=\"mi-row\"><span class=\"mi-path\">' + esc(tilde(r.path)) + '</span>' +\n '<span class=\"mi-when\">' + esc(r.lastAnalyzedAt ? dayOf(r.lastAnalyzedAt) : '—') + '</span></div>';\n }).join('')\n : '<div class=\"mi-empty\">No directory scan history yet — run <code>tuneloop analyze</code>.</div>';\n info = '<span class=\"meta-info-wrap\">' +\n '<button type=\"button\" class=\"meta-info-btn\" id=\"metaInfoBtn\" title=\"Store details\" aria-label=\"Store details\">ⓘ</button>' +\n '<div class=\"meta-info-pop\" id=\"metaInfoPop\">' + head +\n '<div class=\"mi-title\">Analyzed directories</div>' + rows + '</div></span>';\n }\n $('#meta').innerHTML =\n '<span class=\"meta-top\">' +\n (dbPath ? '<span class=\"meta-path\">' + esc(dbPath) + '</span>' : '') + info +\n '</span>';\n var miBtn = document.getElementById('metaInfoBtn');\n if (miBtn) {\n miBtn.onclick = function (e) {\n e.stopPropagation();\n var pop = document.getElementById('metaInfoPop');\n if (pop) pop.classList.toggle('on');\n };\n // Close on an outside click (same pattern as the outcome popover).\n document.addEventListener('mousedown', function (e) {\n var pop = document.getElementById('metaInfoPop');\n if (!pop || !pop.classList.contains('on')) return;\n var wrap = document.querySelector('.meta-info-wrap');\n if (wrap && wrap.contains(e.target as Node)) return;\n pop.classList.remove('on');\n });\n }\n // The overview is what classifies the store (empty / un-enriched / ok) and\n // whether any outcomes exist, so surface the nudges + correct the outcome-rate\n // tile now that it's known (these paint from cached payloads — no refetch).\n renderNotices();\n paintKpis();\n paintHighlights();\n paintDashAsk();\n loadFacets().then(function () {\n // Build the sessions filter bar. If we landed on the sessions view, restore\n // its filter from the URL (facets are needed to populate the selects, so this\n // waits for them); otherwise build the default bar.\n if (route.view === 'sessions') applySessionParams(route.query);\n else buildFilters();\n // Facets drive the breakdown dropdown AND the per-value table's facet-named\n // title/labels. Success-rate has dedicated facet-aware controls; every other\n // metric just re-renders now that facets are in (its first paint fired before\n // they arrived).\n if (state.metric === 'success_rate') { renderSrControls(); loadSuccessRate(); }\n else renderOpenMetric();\n });\n });\n renderWindow();\n loadKpis();\n // Sessions load via buildFilters() → applyFilters() once facets resolve, so the\n // list arrives already windowed to the default (30d) with its active chips.\n loadArtifacts();\n get('/api/outcome-types').then(function (t) {\n state.outcomeTypes = t || [];\n if (state.metric === 'success_rate') renderSrControls();\n });\n\n // Collapse the (possibly empty / partial) initial hash to its canonical form,\n // in place — no extra history entry beyond the page load itself.\n window.history.replaceState(null, '', buildHash());\n}\ninit();\n"],"mappings":"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","names":["i","base","base","d","userTurns","a","errIds","present","fmt","base","pct","fmt","base","side","horizontal","pct","active","fmt","pct"]}
|