cctally 1.44.1 → 1.44.2

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/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.44.2] - 2026-06-14
9
+
10
+ ### Fixed
11
+ - Conversation viewer: an `Edit`/`Write`/`MultiEdit` card whose input was truncated for transport now shows the document's **true** line count in its header (`wrote N lines` / `+A −D`) instead of the post-truncation count — previously a Write of a file larger than ~8 KB rendered e.g. `wrote 114 lines` (the clipped prefix) until you clicked "load full input", which then corrected it. The true `{add, del}` is now computed from the full input at ingest and stamped on truncated edit calls (matching the in-browser diff exactly: added rows = `|new lines| − LCS`, removed = `|old lines| − LCS`, with the unique LCS length), and the header prefers it only while the input is truncated-and-not-yet-loaded so a non-truncated card still mirrors its rendered diff. Already-cached conversations pick up the correct count after `cctally cache-sync --rebuild` (the cache is re-derivable); newly-recorded conversations are correct immediately (#198).
12
+ - **Internal (test infra, no user-facing change): the per-migration golden builders are now byte-idempotent, with a guard that enforces it.** The conversation cache goldens build `pre.sqlite` via `_apply_cache_schema`, which always emits the current full cache schema, so as later migrations added tables (`conversation_sessions` #013, `conversation_ai_titles` #012) or reshaped the FTS5 index (#010) the committed goldens silently fell behind — a full `bin/build-migrations-fixtures.py` regen rewrote ~24 fixtures at once that the maintainer then had to hand-revert (the broader cousin of #194, which fixed only the missing-marker case). Cache `001`'s wall-clock self-stamp (the #140 carve-out) is now overwritten with a pinned `applied_at_utc` in the builder (production handler untouched), removing the last source of regen non-determinism; all builder-produced goldens were refreshed to the current schema; and `tests/test_build_migrations_fixtures_stamps_markers.py` now rebuilds every per-migration golden (across both builder scripts) and asserts byte-equality with the committed fixture, so future schema drift fails loudly at the commit that introduces it instead of accumulating silently. Nothing to do on upgrade (#197).
13
+
8
14
  ## [1.44.1] - 2026-06-14
9
15
 
10
16
  ### Fixed
@@ -178,6 +178,12 @@ _INPUT_MAX_DEPTH = 12 # max nesting depth before subtree elision (Recursion
178
178
  _INPUT_KEY_CAP = 512 # max chars per dict key (else keys are stored verbatim, unbounded)
179
179
  _INPUT_ELISION = "…" # sentinel for elided leaves / subtrees
180
180
 
181
+ # #198: cap the O(n·m) LCS pass that stamps edit_stat from the FULL (unbounded)
182
+ # input. Realistic truncated edits have a few hundred lines per side (n·m ~ 1e4–1e5);
183
+ # this bound only excludes a pathological multi-thousand-line edit, in which case
184
+ # edit_stat is omitted and the client falls back to its bounded recompute.
185
+ _EDIT_STAT_LCS_CELL_BUDGET = 4_000_000
186
+
181
187
  # #177 S4: WebSearch link-list capture bounds + the media item types whose
182
188
  # placeholders the ordinal chokepoint (iter_media_items) addresses.
183
189
  _WEB_SEARCH_LINK_CAP = 50
@@ -470,6 +476,14 @@ def _blocks_and_text(content):
470
476
  "input": bounded, "input_truncated": input_trunc,
471
477
  "id": b.get("id"),
472
478
  "preview": tool_preview(b.get("name"), b.get("input"))}
479
+ # #198: stamp the true edit-family stat from the FULL input ONLY when
480
+ # the bounded copy was clipped — the one case where the client can't
481
+ # recount the header from `block["input"]`. Additive; omitted
482
+ # otherwise (non-truncated cards recount from their live jsdiff hunks).
483
+ if input_trunc:
484
+ edit_stat = _edit_stat_for(b.get("name"), b.get("input"))
485
+ if edit_stat is not None:
486
+ block["edit_stat"] = edit_stat
473
487
  inp = b.get("input")
474
488
  st = inp.get("subagent_type") if isinstance(inp, dict) else None
475
489
  if isinstance(st, str) and st: # #166: spawn kind (Agent/Task)
@@ -760,6 +774,117 @@ def _summarize(inp):
760
774
  return s[:200]
761
775
 
762
776
 
777
+ # ---------------------------------------------------------------------------
778
+ # #198: true edit-family stat, stamped at ingest from the FULL (un-bounded) input.
779
+ #
780
+ # DiffCard's header badge (`wrote N lines` for Write, `+A −D` for Edit/MultiEdit)
781
+ # was computed client-side from `call.input`, which `_bound_input` clips to
782
+ # _INPUT_LEAF_CAP per string leaf — so a large Write/Edit reported the post-clip
783
+ # count, not the document's true total. We stamp the true {add, del} here (where
784
+ # the full input is still in hand) on TRUNCATED edit-family calls only; the client
785
+ # prefers it for the header solely while truncated-and-not-yet-loaded, so a
786
+ # non-truncated card keeps header==body parity with its rendered jsdiff hunks.
787
+ #
788
+ # Parity with the client's jsdiff (dashboard/web/src/conversations/computeDiff.ts):
789
+ # jsdiff `diffLines` is Myers-minimal, so added rows = |new_lines| − LCS and
790
+ # removed = |old_lines| − LCS. The LCS *length* is unique, so a plain LCS pass
791
+ # reproduces jsdiff's counts WITHOUT replicating its alignment. Line tokens carry
792
+ # their trailing newline (jsdiff's tokenization), so a no-newline-at-eof line is a
793
+ # distinct token from its newline-terminated twin — matching the rendered diff.
794
+ # ---------------------------------------------------------------------------
795
+ def _line_count(s):
796
+ """Number of lines in `s`, matching computeDiff.ts::splitLines length (split on
797
+ '\\n', drop the phantom blank from a trailing newline). Drives Write's
798
+ `wrote N lines`, which the client builds from `computeWrite(content).length`."""
799
+ if not s:
800
+ return 0
801
+ parts = s.split("\n")
802
+ if parts and parts[-1] == "":
803
+ parts.pop()
804
+ return len(parts)
805
+
806
+
807
+ def _line_tokens(s):
808
+ """Tokenize `s` into jsdiff line tokens (each line keeps its trailing newline),
809
+ mirroring jsdiff's LineDiff.tokenize so the LCS below counts what `diffLines`
810
+ counts. `re.split(r"(\\n|\\r\\n)")` keeps separators; the trailing empty from a
811
+ final newline is dropped, then each separator is folded onto its line."""
812
+ if not s:
813
+ return []
814
+ parts = re.split(r"(\n|\r\n)", s)
815
+ if parts and parts[-1] == "":
816
+ parts.pop()
817
+ tokens = []
818
+ for i, p in enumerate(parts):
819
+ if i % 2: # captured separator → fold onto the preceding line
820
+ tokens[-1] += p
821
+ else:
822
+ tokens.append(p)
823
+ return tokens
824
+
825
+
826
+ def _lcs_len(a, b):
827
+ """Length of the longest common subsequence of token lists `a`, `b` (rolling
828
+ 1-D DP, O(len(a)·len(b)) time / O(min) space). The length is unique even when
829
+ the LCS itself is not, which is exactly why it reproduces jsdiff's add/del
830
+ counts."""
831
+ if not a or not b:
832
+ return 0
833
+ if len(b) > len(a):
834
+ a, b = b, a # keep the inner row short
835
+ prev = [0] * (len(b) + 1)
836
+ for x in a:
837
+ diag = 0 # prev[j-1] before this row overwrote it
838
+ for j in range(1, len(b) + 1):
839
+ cur = prev[j]
840
+ prev[j] = diag + 1 if x == b[j - 1] else (prev[j] if prev[j] >= prev[j - 1] else prev[j - 1])
841
+ diag = cur
842
+ return prev[len(b)]
843
+
844
+
845
+ def _diff_stat(old, new):
846
+ """{"add", "del"} for a single old→new line diff, or None when the LCS would
847
+ exceed the cell budget. Non-string sides coerce to '' (mirroring
848
+ computeMultiEdit's leaf coercion)."""
849
+ ot = _line_tokens(old if isinstance(old, str) else "")
850
+ nt = _line_tokens(new if isinstance(new, str) else "")
851
+ if len(ot) * len(nt) > _EDIT_STAT_LCS_CELL_BUDGET:
852
+ return None
853
+ lcs = _lcs_len(ot, nt)
854
+ return {"add": len(nt) - lcs, "del": len(ot) - lcs}
855
+
856
+
857
+ def _edit_stat_for(name, inp):
858
+ """True {"add", "del"} for an edit-family tool computed from its FULL input, or
859
+ None when not an edit-family tool / not computable / over the LCS budget. Write
860
+ is a pure line count (no prior content); Edit diffs old→new; MultiEdit sums per
861
+ edit. Mirrors computeWrite/computeDiff/computeMultiEdit COUNTS exactly."""
862
+ if not isinstance(inp, dict):
863
+ return None
864
+ nm = (name or "").lower()
865
+ if nm == "write":
866
+ content = inp.get("content")
867
+ if not isinstance(content, str):
868
+ return None
869
+ return {"add": _line_count(content), "del": 0}
870
+ if nm == "edit":
871
+ return _diff_stat(inp.get("old_string"), inp.get("new_string"))
872
+ if nm == "multiedit":
873
+ edits = inp.get("edits")
874
+ if not isinstance(edits, list):
875
+ return None
876
+ add = dele = 0
877
+ for e in edits:
878
+ e = e if isinstance(e, dict) else {}
879
+ st = _diff_stat(e.get("old_string"), e.get("new_string"))
880
+ if st is None:
881
+ return None # one over-budget edit → omit the whole stamp
882
+ add += st["add"]
883
+ dele += st["del"]
884
+ return {"add": add, "del": dele}
885
+ return None
886
+
887
+
763
888
  def _bound_input(inp):
764
889
  """Return (bounded_structured_input, truncated) for a tool_use input dict, or
765
890
  (None, False) for a non-dict (the same non-dict contract as _summarize /
@@ -56,8 +56,8 @@ Error generating stack: `+e.message+`
56
56
  `)&&(e=e.slice(0,-1)),t.endsWith(`
57
57
  `)&&(t=t.slice(0,-1))),super.equals(e,t,n)}};function SS(e,t,n){return xS.diff(e,t,n)}function CS(e,t){t.stripTrailingCr&&(e=e.replace(/\r\n/g,`
58
58
  `));let n=[],r=e.split(/(\n|\r\n)/);r[r.length-1]||r.pop();for(let e=0;e<r.length;e++){let i=r[e];e%2&&!t.newlineIsToken?n[n.length-1]+=i:n.push(i)}return n}function wS(e){return e==`.`||e==`!`||e==`?`}new class extends rS{tokenize(e){let t=[],n=0;for(let r=0;r<e.length;r++){if(r==e.length-1){t.push(e.slice(n));break}if(wS(e[r])&&e[r+1].match(/\s/)){for(t.push(e.slice(n,r+1)),r=n=r+1;e[r+1]?.match(/\s/);)r++;t.push(e.slice(n,r+1)),n=r+1}}return t}},new class extends rS{tokenize(e){return e.split(/([{}:;,]|\s+)/)}},new class extends rS{constructor(){super(...arguments),this.tokenize=CS}get useLongestToken(){return!0}castInput(e,t){let{undefinedReplacement:n,stringifyReplacer:r=(e,t)=>t===void 0?n:t}=t;return typeof e==`string`?e:JSON.stringify(TS(e,null,null,r),null,` `)}equals(e,t,n){return super.equals(e.replace(/,([\r\n])/g,`$1`),t.replace(/,([\r\n])/g,`$1`),n)}};function TS(e,t,n,r,i){t||=[],n||=[],r&&(e=r(i===void 0?``:i,e));let a;for(a=0;a<t.length;a+=1)if(t[a]===e)return n[a];let o;if(Object.prototype.toString.call(e)===`[object Array]`){for(t.push(e),o=Array(e.length),n.push(o),a=0;a<e.length;a+=1)o[a]=TS(e[a],t,n,r,String(a));return t.pop(),n.pop(),o}if(e&&e.toJSON&&(e=e.toJSON()),typeof e==`object`&&e){t.push(e),o={},n.push(o);let i=[],s;for(s in e)Object.prototype.hasOwnProperty.call(e,s)&&i.push(s);for(i.sort(),a=0;a<i.length;a+=1)s=i[a],o[s]=TS(e[s],t,n,r,s);t.pop(),n.pop()}else o=e;return o}new class extends rS{tokenize(e){return e.slice()}join(e){return e}removeEmpty(e){return e}};function ES(e){let t=e.split(`
59
- `);return t.length&&t[t.length-1]===``&&t.pop(),t}function DS(e,t){let n=[],r=1,i=1;for(let a of SS(e,t))for(let e of ES(a.value))a.added?n.push({type:`add`,oldNo:null,newNo:i++,text:e}):a.removed?n.push({type:`del`,oldNo:r++,newNo:null,text:e}):n.push({type:`context`,oldNo:r++,newNo:i++,text:e});return OS(n)}function OS(e){for(let t=0;t<e.length;){if(e[t].type!==`del`){t++;continue}let n=t;for(;n<e.length&&e[n].type===`del`;)n++;let r=n;for(;r<e.length&&e[r].type===`add`;)r++;let i=e.slice(t,n),a=e.slice(n,r),o=Math.min(i.length,a.length);for(let e=0;e<o;e++){let t=bS(i[e].text,a[e].text);i[e].segments=t.filter(e=>!e.added).map(e=>({text:e.value,emph:!!e.removed})),a[e].segments=t.filter(e=>!e.removed).map(e=>({text:e.value,emph:!!e.added}))}t=r}return e}function kS(e){return ES(e).map((e,t)=>({type:`add`,oldNo:null,newNo:t+1,text:e}))}function AS(e){return Array.isArray(e)?e.map(e=>DS(typeof e?.old_string==`string`?e.old_string:``,typeof e?.new_string==`string`?e.new_string:``)):[]}function jS(e){return e.input??{}}function MS(e){return typeof e.file_path==`string`?e.file_path:``}function NS(e){let t=e.lastIndexOf(`/`);return t<0?{dir:``,base:e}:{dir:e.slice(0,t+1),base:e.slice(t+1)}}function PS(e){let t=0,n=0;for(let r of e)for(let e of r)e.type===`add`?t++:e.type===`del`&&n++;return{add:t,del:n}}function FS(e,t){let n=(e.name??``).toLowerCase(),r=t??jS(e);return n===`write`?{hunks:[kS(typeof r.content==`string`?r.content:``)],kind:`write`}:n===`multiedit`?{hunks:AS(Array.isArray(r.edits)?r.edits:[]),kind:`multiedit`}:{hunks:[DS(typeof r.old_string==`string`?r.old_string:``,typeof r.new_string==`string`?r.new_string:``)],kind:`edit`}}function IS({row:e,lang:t}){let n=e.type===`add`?`+`:e.type===`del`?`−`:`\xA0`,r;return r=e.type===`context`?Sx(e.text,t):e.segments?e.segments.map((e,t)=>e.emph?(0,U.jsx)(`span`,{className:`conv-diff-word`,children:e.text},t):(0,U.jsx)(`span`,{children:e.text},t)):e.text,(0,U.jsxs)(`div`,{className:`conv-diff-row conv-diff-row--${e.type}`,children:[(0,U.jsx)(`span`,{className:`conv-diff-gutter`,"aria-hidden":`true`,children:e.oldNo??``}),(0,U.jsx)(`span`,{className:`conv-diff-gutter`,"aria-hidden":`true`,children:e.newNo??``}),(0,U.jsx)(`span`,{className:`conv-diff-sign`,"aria-hidden":`true`,children:n}),(0,U.jsx)(`span`,{className:`conv-diff-text`,children:r})]})}function LS({rows:e,lang:t}){return(0,U.jsx)(`div`,{className:`conv-diff-hunk`,children:e.map((e,n)=>(0,U.jsx)(IS,{row:e,lang:t},n))})}function RS({call:e}){let[t,n]=(0,_.useState)(null),r=jS(e),{dir:i,base:a}=NS(MS(r)),o=Fx(e),{hunks:s,kind:c}=(0,_.useMemo)(()=>FS(e,t),[e,t]),l=(0,_.useMemo)(()=>PS(s),[s]),u=r.replace_all===!0,d=c===`multiedit`?s.length:0,f=(0,_.useMemo)(()=>s.flatMap(e=>e.map(e=>(e.type===`add`?`+`:e.type===`del`?`-`:` `)+e.text)).join(`
60
- `),[s]);return(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--tool conv-diff-card`,open:!0,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(Yb,{}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:e.name??`Edit`}),(0,U.jsxs)(`span`,{className:`conv-diff-hdr`,children:[(0,U.jsx)(`span`,{className:`conv-diff-base`,children:a||`(file)`}),i&&(0,U.jsx)(`span`,{className:`conv-diff-dir`,children:i}),c===`write`?(0,U.jsxs)(`span`,{className:`conv-diff-stat conv-diff-stat--write`,children:[`wrote `,l.add,` lines`]}):(0,U.jsxs)(`span`,{className:`conv-diff-stat`,children:[(0,U.jsxs)(`span`,{className:`conv-diff-stat-add`,children:[`+`,l.add]}),` `,(0,U.jsxs)(`span`,{className:`conv-diff-stat-del`,children:[`−`,l.del]})]}),u&&(0,U.jsx)(`span`,{className:`conv-diff-tag`,children:`replace all`}),d>0&&(0,U.jsxs)(`span`,{className:`conv-diff-tag`,children:[d,` edit`,d===1?``:`s`]})]})]}),(0,U.jsxs)(`div`,{className:`conv-diff-body`,children:[(0,U.jsx)(`div`,{className:`conv-diff-copy`,children:(0,U.jsx)(yx,{text:f})}),s.map((e,t)=>(0,U.jsxs)(`div`,{children:[c===`multiedit`&&(0,U.jsxs)(`div`,{className:`conv-diff-divider`,children:[`edit `,t+1,` of `,s.length]}),(0,U.jsx)(LS,{rows:e,lang:o})]},t)),e.input_truncated&&(0,U.jsx)(nS,{toolUseId:e.tool_use_id??``,which:`input`,fullLength:null,label:`load full input`,onLoaded:e=>{e.which===`input`&&n(e.input)}}),e.result&&(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--result conv-diff-result`,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:`result`}),(0,U.jsx)(`span`,{className:`conv-chip-preview`,children:`cat -n snippet`})]}),(0,U.jsxs)(`div`,{className:`conv-chip-body conv-tool-io`,children:[(0,U.jsx)(yx,{text:e.result.text}),(0,U.jsx)(jx,{code:e.result.text,lang:o})]})]})]})]})}var zS={30:`ansi-blk`,31:`ansi-red`,32:`ansi-grn`,33:`ansi-yel`,34:`ansi-blu`,35:`ansi-mag`,36:`ansi-cyn`,37:`ansi-wht`,90:`ansi-dim`,91:`ansi-red`,92:`ansi-grn`,93:`ansi-yel`,94:`ansi-blu`,95:`ansi-mag`,96:`ansi-cyn`,97:`ansi-wht`},BS=/\x1b\[([0-9;]*)m/g,VS=/\x1b\[[0-9;]*[A-Za-z]/g,HS=/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?/g,US=/\x1b/g;function WS(e){let t=[],n=0,r=null,i;for(BS.lastIndex=0;(i=BS.exec(e))!==null;){i.index>n&&t.push({text:e.slice(n,i.index),cls:r});let a=i[1].split(`;`).filter(Boolean).map(Number);(a.length===0||a.includes(0))&&(r=null);for(let e of a)zS[e]&&(r=zS[e]);n=BS.lastIndex}return n<e.length&&t.push({text:e.slice(n),cls:r}),t.map(e=>({...e,text:e.text.replace(VS,``).replace(HS,``).replace(US,``)})).filter(e=>e.text.length>0)}function GS({text:e}){return(0,U.jsx)(U.Fragment,{children:WS(e).map((e,t)=>e.cls?(0,U.jsx)(`span`,{className:e.cls,children:e.text},t):(0,U.jsx)(`span`,{children:e.text},t))})}function KS(e){let t=e.input?.command;return typeof t==`string`?t:``}function qS(e){let t=e.input?.description,n=typeof t==`string`?t.trim():``;return n.length>0?n:void 0}function JS(e,t){return typeof t==`string`&&t.length>0&&e.endsWith(t)?{stdout:e.slice(0,e.length-t.length),stderr:t}:{stdout:e,stderr:null}}function YS({call:e}){let[t,n]=(0,_.useState)(null),r=KS(e),i=e.result,a=i?.is_error===!0,o=e.interrupted===!0,s=t?.text??i?.text??``,{stdout:c,stderr:l}=t==null?JS(s,e.stderr):JS(s,t.stderr),u=a?(0,U.jsx)(`span`,{className:`conv-term-badge conv-term-badge--err`,children:`● error`}):o?(0,U.jsx)(`span`,{className:`conv-term-badge conv-term-badge--int`,children:`■ interrupted`}):null;return(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--tool conv-term`,open:!0,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(Xb,{}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:`Bash`}),(0,U.jsx)(`span`,{className:`conv-chip-preview`,children:qS(e)??e.preview}),u]}),(0,U.jsxs)(`div`,{className:`conv-term-body`,children:[(0,U.jsx)(`div`,{className:`conv-term-copy`,children:(0,U.jsx)(yx,{text:r})}),(0,U.jsxs)(`pre`,{className:`conv-term-cmd conv-code--hl`,children:[(0,U.jsxs)(`span`,{className:`conv-term-prompt`,"aria-hidden":`true`,children:[`$`,` `]}),Sx(r,`bash`)]}),i&&(0,U.jsxs)(U.Fragment,{children:[(c.length>0||!o&&l==null)&&(0,U.jsx)(`pre`,{className:`conv-term-out`,children:(0,U.jsx)(GS,{text:c})}),l!=null&&(0,U.jsx)(`pre`,{className:`conv-term-stderr`,children:(0,U.jsx)(GS,{text:l})}),i.truncated&&t==null&&(0,U.jsx)(nS,{toolUseId:e.tool_use_id??``,which:`result`,fullLength:i.full_length??null,label:`load full output`,onLoaded:e=>{e.which===`result`&&n({text:e.text,stderr:e.stderr})}})]})]})]})}function XS(e){let t=Math.floor(e*3/4);return t>=1024*1024?`~${(t/(1024*1024)).toFixed(1)} MB`:t>=1024?`~${Math.round(t/1024)} KB`:`~${t} B`}function ZS({media:e,toolUseId:t,uuid:n,context:r}){let i=$x(),[a,o]=(0,_.useState)(!1),s=t?`tool_use_id=${encodeURIComponent(t)}`:n?`uuid=${encodeURIComponent(n)}`:null;if(!(i!=null&&s!=null&&Number.isInteger(e.index)&&e.index>=0)||a)return(0,U.jsxs)(`span`,{className:`conv-chip conv-chip--media`,children:[e.kind===`image`?(0,U.jsx)(tx,{}):(0,U.jsx)(nx,{}),` `,e.media_type??e.kind,` · `,e.bytes,` B`,a&&(0,U.jsx)(`span`,{className:`conv-media-gone`,children:` · source no longer available`})]});let c=`/api/conversation/${encodeURIComponent(i)}/media?${s}&index=${e.index}`;return e.kind===`document`?(0,U.jsxs)(`span`,{className:`conv-chip conv-chip--media`,children:[(0,U.jsx)(nx,{}),` `,e.media_type??`document`,` · `,XS(e.bytes),` ·`,` `,(0,U.jsx)(`a`,{href:c,target:`_blank`,rel:`noopener noreferrer`,children:`open ↗`})]}):(0,U.jsxs)(`figure`,{className:`conv-media-figure`,children:[(0,U.jsx)(`img`,{src:c,loading:`lazy`,decoding:`async`,alt:`${r} image ${e.index+1} (${e.media_type??`image`})`,onError:()=>o(!0)}),(0,U.jsxs)(`figcaption`,{className:`conv-media-caption`,children:[(0,U.jsx)(`span`,{children:e.media_type??`image`}),(0,U.jsx)(`span`,{children:XS(e.bytes)}),(0,U.jsx)(`a`,{href:c,target:`_blank`,rel:`noopener noreferrer`,children:`open full size ↗`})]})]})}function QS(e){try{return new URL(e).hostname}catch{return``}}function $S(e){return/^https?:\/\//i.test(e)}function eC(e){let t=e.input?.url;return typeof t==`string`?t:``}function tC(e){let t=e.input?.prompt;return typeof t==`string`?t:``}function nC(e){return e.split(`
59
+ `);return t.length&&t[t.length-1]===``&&t.pop(),t}function DS(e,t){let n=[],r=1,i=1;for(let a of SS(e,t))for(let e of ES(a.value))a.added?n.push({type:`add`,oldNo:null,newNo:i++,text:e}):a.removed?n.push({type:`del`,oldNo:r++,newNo:null,text:e}):n.push({type:`context`,oldNo:r++,newNo:i++,text:e});return OS(n)}function OS(e){for(let t=0;t<e.length;){if(e[t].type!==`del`){t++;continue}let n=t;for(;n<e.length&&e[n].type===`del`;)n++;let r=n;for(;r<e.length&&e[r].type===`add`;)r++;let i=e.slice(t,n),a=e.slice(n,r),o=Math.min(i.length,a.length);for(let e=0;e<o;e++){let t=bS(i[e].text,a[e].text);i[e].segments=t.filter(e=>!e.added).map(e=>({text:e.value,emph:!!e.removed})),a[e].segments=t.filter(e=>!e.removed).map(e=>({text:e.value,emph:!!e.added}))}t=r}return e}function kS(e){return ES(e).map((e,t)=>({type:`add`,oldNo:null,newNo:t+1,text:e}))}function AS(e){return Array.isArray(e)?e.map(e=>DS(typeof e?.old_string==`string`?e.old_string:``,typeof e?.new_string==`string`?e.new_string:``)):[]}function jS(e){return e.input??{}}function MS(e){return typeof e.file_path==`string`?e.file_path:``}function NS(e){let t=e.lastIndexOf(`/`);return t<0?{dir:``,base:e}:{dir:e.slice(0,t+1),base:e.slice(t+1)}}function PS(e){let t=0,n=0;for(let r of e)for(let e of r)e.type===`add`?t++:e.type===`del`&&n++;return{add:t,del:n}}function FS(e,t){let n=(e.name??``).toLowerCase(),r=t??jS(e);return n===`write`?{hunks:[kS(typeof r.content==`string`?r.content:``)],kind:`write`}:n===`multiedit`?{hunks:AS(Array.isArray(r.edits)?r.edits:[]),kind:`multiedit`}:{hunks:[DS(typeof r.old_string==`string`?r.old_string:``,typeof r.new_string==`string`?r.new_string:``)],kind:`edit`}}function IS({row:e,lang:t}){let n=e.type===`add`?`+`:e.type===`del`?`−`:`\xA0`,r;return r=e.type===`context`?Sx(e.text,t):e.segments?e.segments.map((e,t)=>e.emph?(0,U.jsx)(`span`,{className:`conv-diff-word`,children:e.text},t):(0,U.jsx)(`span`,{children:e.text},t)):e.text,(0,U.jsxs)(`div`,{className:`conv-diff-row conv-diff-row--${e.type}`,children:[(0,U.jsx)(`span`,{className:`conv-diff-gutter`,"aria-hidden":`true`,children:e.oldNo??``}),(0,U.jsx)(`span`,{className:`conv-diff-gutter`,"aria-hidden":`true`,children:e.newNo??``}),(0,U.jsx)(`span`,{className:`conv-diff-sign`,"aria-hidden":`true`,children:n}),(0,U.jsx)(`span`,{className:`conv-diff-text`,children:r})]})}function LS({rows:e,lang:t}){return(0,U.jsx)(`div`,{className:`conv-diff-hunk`,children:e.map((e,n)=>(0,U.jsx)(IS,{row:e,lang:t},n))})}function RS({call:e}){let[t,n]=(0,_.useState)(null),r=jS(e),{dir:i,base:a}=NS(MS(r)),o=Fx(e),{hunks:s,kind:c}=(0,_.useMemo)(()=>FS(e,t),[e,t]),l=(0,_.useMemo)(()=>PS(s),[s]),u=e.edit_stat&&typeof e.edit_stat.add==`number`&&typeof e.edit_stat.del==`number`?e.edit_stat:null,d=e.input_truncated&&!t&&u?u:l,f=r.replace_all===!0,p=c===`multiedit`?s.length:0,m=(0,_.useMemo)(()=>s.flatMap(e=>e.map(e=>(e.type===`add`?`+`:e.type===`del`?`-`:` `)+e.text)).join(`
60
+ `),[s]);return(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--tool conv-diff-card`,open:!0,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(Yb,{}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:e.name??`Edit`}),(0,U.jsxs)(`span`,{className:`conv-diff-hdr`,children:[(0,U.jsx)(`span`,{className:`conv-diff-base`,children:a||`(file)`}),i&&(0,U.jsx)(`span`,{className:`conv-diff-dir`,children:i}),c===`write`?(0,U.jsxs)(`span`,{className:`conv-diff-stat conv-diff-stat--write`,children:[`wrote `,d.add,` lines`]}):(0,U.jsxs)(`span`,{className:`conv-diff-stat`,children:[(0,U.jsxs)(`span`,{className:`conv-diff-stat-add`,children:[`+`,d.add]}),` `,(0,U.jsxs)(`span`,{className:`conv-diff-stat-del`,children:[`−`,d.del]})]}),f&&(0,U.jsx)(`span`,{className:`conv-diff-tag`,children:`replace all`}),p>0&&(0,U.jsxs)(`span`,{className:`conv-diff-tag`,children:[p,` edit`,p===1?``:`s`]})]})]}),(0,U.jsxs)(`div`,{className:`conv-diff-body`,children:[(0,U.jsx)(`div`,{className:`conv-diff-copy`,children:(0,U.jsx)(yx,{text:m})}),s.map((e,t)=>(0,U.jsxs)(`div`,{children:[c===`multiedit`&&(0,U.jsxs)(`div`,{className:`conv-diff-divider`,children:[`edit `,t+1,` of `,s.length]}),(0,U.jsx)(LS,{rows:e,lang:o})]},t)),e.input_truncated&&(0,U.jsx)(nS,{toolUseId:e.tool_use_id??``,which:`input`,fullLength:null,label:`load full input`,onLoaded:e=>{e.which===`input`&&n(e.input)}}),e.result&&(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--result conv-diff-result`,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:`result`}),(0,U.jsx)(`span`,{className:`conv-chip-preview`,children:`cat -n snippet`})]}),(0,U.jsxs)(`div`,{className:`conv-chip-body conv-tool-io`,children:[(0,U.jsx)(yx,{text:e.result.text}),(0,U.jsx)(jx,{code:e.result.text,lang:o})]})]})]})]})}var zS={30:`ansi-blk`,31:`ansi-red`,32:`ansi-grn`,33:`ansi-yel`,34:`ansi-blu`,35:`ansi-mag`,36:`ansi-cyn`,37:`ansi-wht`,90:`ansi-dim`,91:`ansi-red`,92:`ansi-grn`,93:`ansi-yel`,94:`ansi-blu`,95:`ansi-mag`,96:`ansi-cyn`,97:`ansi-wht`},BS=/\x1b\[([0-9;]*)m/g,VS=/\x1b\[[0-9;]*[A-Za-z]/g,HS=/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?/g,US=/\x1b/g;function WS(e){let t=[],n=0,r=null,i;for(BS.lastIndex=0;(i=BS.exec(e))!==null;){i.index>n&&t.push({text:e.slice(n,i.index),cls:r});let a=i[1].split(`;`).filter(Boolean).map(Number);(a.length===0||a.includes(0))&&(r=null);for(let e of a)zS[e]&&(r=zS[e]);n=BS.lastIndex}return n<e.length&&t.push({text:e.slice(n),cls:r}),t.map(e=>({...e,text:e.text.replace(VS,``).replace(HS,``).replace(US,``)})).filter(e=>e.text.length>0)}function GS({text:e}){return(0,U.jsx)(U.Fragment,{children:WS(e).map((e,t)=>e.cls?(0,U.jsx)(`span`,{className:e.cls,children:e.text},t):(0,U.jsx)(`span`,{children:e.text},t))})}function KS(e){let t=e.input?.command;return typeof t==`string`?t:``}function qS(e){let t=e.input?.description,n=typeof t==`string`?t.trim():``;return n.length>0?n:void 0}function JS(e,t){return typeof t==`string`&&t.length>0&&e.endsWith(t)?{stdout:e.slice(0,e.length-t.length),stderr:t}:{stdout:e,stderr:null}}function YS({call:e}){let[t,n]=(0,_.useState)(null),r=KS(e),i=e.result,a=i?.is_error===!0,o=e.interrupted===!0,s=t?.text??i?.text??``,{stdout:c,stderr:l}=t==null?JS(s,e.stderr):JS(s,t.stderr),u=a?(0,U.jsx)(`span`,{className:`conv-term-badge conv-term-badge--err`,children:`● error`}):o?(0,U.jsx)(`span`,{className:`conv-term-badge conv-term-badge--int`,children:`■ interrupted`}):null;return(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--tool conv-term`,open:!0,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(Xb,{}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:`Bash`}),(0,U.jsx)(`span`,{className:`conv-chip-preview`,children:qS(e)??e.preview}),u]}),(0,U.jsxs)(`div`,{className:`conv-term-body`,children:[(0,U.jsx)(`div`,{className:`conv-term-copy`,children:(0,U.jsx)(yx,{text:r})}),(0,U.jsxs)(`pre`,{className:`conv-term-cmd conv-code--hl`,children:[(0,U.jsxs)(`span`,{className:`conv-term-prompt`,"aria-hidden":`true`,children:[`$`,` `]}),Sx(r,`bash`)]}),i&&(0,U.jsxs)(U.Fragment,{children:[(c.length>0||!o&&l==null)&&(0,U.jsx)(`pre`,{className:`conv-term-out`,children:(0,U.jsx)(GS,{text:c})}),l!=null&&(0,U.jsx)(`pre`,{className:`conv-term-stderr`,children:(0,U.jsx)(GS,{text:l})}),i.truncated&&t==null&&(0,U.jsx)(nS,{toolUseId:e.tool_use_id??``,which:`result`,fullLength:i.full_length??null,label:`load full output`,onLoaded:e=>{e.which===`result`&&n({text:e.text,stderr:e.stderr})}})]})]})]})}function XS(e){let t=Math.floor(e*3/4);return t>=1024*1024?`~${(t/(1024*1024)).toFixed(1)} MB`:t>=1024?`~${Math.round(t/1024)} KB`:`~${t} B`}function ZS({media:e,toolUseId:t,uuid:n,context:r}){let i=$x(),[a,o]=(0,_.useState)(!1),s=t?`tool_use_id=${encodeURIComponent(t)}`:n?`uuid=${encodeURIComponent(n)}`:null;if(!(i!=null&&s!=null&&Number.isInteger(e.index)&&e.index>=0)||a)return(0,U.jsxs)(`span`,{className:`conv-chip conv-chip--media`,children:[e.kind===`image`?(0,U.jsx)(tx,{}):(0,U.jsx)(nx,{}),` `,e.media_type??e.kind,` · `,e.bytes,` B`,a&&(0,U.jsx)(`span`,{className:`conv-media-gone`,children:` · source no longer available`})]});let c=`/api/conversation/${encodeURIComponent(i)}/media?${s}&index=${e.index}`;return e.kind===`document`?(0,U.jsxs)(`span`,{className:`conv-chip conv-chip--media`,children:[(0,U.jsx)(nx,{}),` `,e.media_type??`document`,` · `,XS(e.bytes),` ·`,` `,(0,U.jsx)(`a`,{href:c,target:`_blank`,rel:`noopener noreferrer`,children:`open ↗`})]}):(0,U.jsxs)(`figure`,{className:`conv-media-figure`,children:[(0,U.jsx)(`img`,{src:c,loading:`lazy`,decoding:`async`,alt:`${r} image ${e.index+1} (${e.media_type??`image`})`,onError:()=>o(!0)}),(0,U.jsxs)(`figcaption`,{className:`conv-media-caption`,children:[(0,U.jsx)(`span`,{children:e.media_type??`image`}),(0,U.jsx)(`span`,{children:XS(e.bytes)}),(0,U.jsx)(`a`,{href:c,target:`_blank`,rel:`noopener noreferrer`,children:`open full size ↗`})]})]})}function QS(e){try{return new URL(e).hostname}catch{return``}}function $S(e){return/^https?:\/\//i.test(e)}function eC(e){let t=e.input?.url;return typeof t==`string`?t:``}function tC(e){let t=e.input?.prompt;return typeof t==`string`?t:``}function nC(e){return e.split(`
61
61
  `).length>24||e.length>1400}function rC({call:e}){let t=eC(e),n=tC(e),r=QS(t),[i,a]=(0,_.useState)(!1),[o,s]=(0,_.useState)(null),c=o??e.result?.text??``,l=nC(c)&&!i,u=e.web_fetch,d=u!=null&&u.code>=200&&u.code<400;return(0,U.jsxs)(`details`,{className:`conv-chip conv-web`,open:!0,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(Zb,{}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:`WebFetch`}),r&&(0,U.jsx)(`span`,{className:`conv-web-domain`,children:r}),u!=null&&(0,U.jsxs)(`span`,{className:`conv-web-status ${d?`conv-web-status--ok`:`conv-web-status--err`}`,children:[u.code,u.code_text?` ${u.code_text}`:``]}),e.result?.is_error&&(0,U.jsx)(`span`,{className:`conv-chip-status`,children:` · error`})]}),(0,U.jsxs)(`div`,{className:`conv-web-body`,children:[(0,U.jsxs)(`div`,{className:`conv-web-field`,children:[(0,U.jsx)(`span`,{className:`conv-web-key`,children:`url`}),$S(t)?(0,U.jsx)(`a`,{href:t,target:`_blank`,rel:`noopener noreferrer`,children:t}):(0,U.jsx)(`span`,{children:t})]}),n&&(0,U.jsxs)(`div`,{className:`conv-web-field`,children:[(0,U.jsx)(`span`,{className:`conv-web-key`,children:`prompt`}),(0,U.jsx)(`span`,{children:n})]}),c?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`div`,{className:`conv-web-copy`,children:(0,U.jsx)(yx,{text:c})}),(0,U.jsx)(`div`,{className:`conv-web-md`+(l?` conv-web-md--clamp`:``),children:(0,U.jsx)(kx,{children:c})}),l&&(0,U.jsx)(`div`,{className:`conv-web-more`,children:(0,U.jsx)(`button`,{type:`button`,onClick:()=>a(!0),children:`Show full summary ↓`})})]}):e.result==null&&(0,U.jsx)(`div`,{className:`conv-tool-io-label conv-tool-io-label--none`,children:`no result`}),e.result?.media?.map(t=>(0,U.jsx)(ZS,{media:t,toolUseId:e.tool_use_id,context:`WebFetch`},t.index)),e.result?.truncated&&o==null&&e.tool_use_id&&(0,U.jsx)(nS,{toolUseId:e.tool_use_id,which:`result`,fullLength:e.result.full_length??null,label:`load full summary`,onLoaded:e=>{e.which===`result`&&s(e.text)}})]})]})}var iC=10;function aC(e){let t=e.input?.query;return typeof t==`string`?t:``}function oC({call:e}){let t=aC(e),n=e.web_search?.links,[r,i]=(0,_.useState)(!1),a=n!=null&&n.length>0,o=a&&!r?n.slice(0,iC):n??[];return(0,U.jsxs)(`details`,{className:`conv-chip conv-web`,open:!0,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),(0,U.jsx)(gx,{}),(0,U.jsx)(`span`,{className:`conv-chip-name`,children:`WebSearch`}),(0,U.jsxs)(`span`,{className:`conv-web-domain`,children:[`“`,t,`”`]}),n!=null&&(0,U.jsxs)(`span`,{className:`conv-web-status conv-web-status--ok`,children:[n.length,e.web_search?.links_truncated?`+`:``,` results`]}),e.result?.is_error&&(0,U.jsx)(`span`,{className:`conv-chip-status`,children:` · error`})]}),(0,U.jsx)(`div`,{className:`conv-web-body`,children:a?(0,U.jsxs)(U.Fragment,{children:[o.map((e,t)=>(0,U.jsxs)(`div`,{className:`conv-web-link`,children:[$S(e.url)?(0,U.jsx)(`a`,{href:e.url,target:`_blank`,rel:`noopener noreferrer`,children:e.title}):(0,U.jsx)(`span`,{children:e.title}),(0,U.jsx)(`span`,{className:`conv-web-link-domain`,children:QS(e.url)||e.url})]},t)),!r&&n.length>iC&&(0,U.jsx)(`div`,{className:`conv-web-more`,children:(0,U.jsxs)(`button`,{type:`button`,onClick:()=>i(!0),children:[`+ `,n.length-iC,` more results`]})})]}):e.result?.text?(0,U.jsxs)(`div`,{className:`conv-tool-io`,children:[(0,U.jsx)(yx,{text:e.result.text}),(0,U.jsx)(`pre`,{className:`conv-code conv-code--result`,children:e.result.text})]}):(0,U.jsx)(`div`,{className:`conv-tool-io-label conv-tool-io-label--none`,children:`no result`})})]})}function sC(e){let t=e.input?.plan;return typeof t==`string`&&t.length>0?t:null}function cC(e){let t=e.input;return!!t&&typeof t.old_string==`string`&&typeof t.new_string==`string`}function lC(e){let t=e.input?.edits;return Array.isArray(t)&&t.length>0}function uC(e){return typeof e.input?.content==`string`}function dC(e){return typeof e.input?.command==`string`}function fC(e){return typeof e.input?.url==`string`}function pC(e){return typeof e.input?.query==`string`}function mC(e){switch((e.name??``).toLowerCase()){case`askuserquestion`:return(0,U.jsx)(Vx,{call:e});case`todowrite`:return(0,U.jsx)(Gx,{call:e});case`exitplanmode`:return sC(e)==null?null:(0,U.jsx)(Yx,{call:e});case`edit`:return cC(e)?(0,U.jsx)(RS,{call:e}):null;case`multiedit`:return lC(e)?(0,U.jsx)(RS,{call:e}):null;case`write`:return uC(e)?(0,U.jsx)(RS,{call:e}):null;case`bash`:return dC(e)?(0,U.jsx)(YS,{call:e}):null;case`webfetch`:return fC(e)?(0,U.jsx)(rC,{call:e}):null;case`websearch`:return pC(e)?(0,U.jsx)(oC,{call:e}):null;default:return null}}function hC({call:e}){return(0,U.jsx)(Ux,{todos:e.task_snapshot??[],label:`Tasks`})}function gC({name:e}){let t=Vb(e);return t?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`span`,{className:`conv-chip-name`,title:e??void 0,children:t.action}),(0,U.jsx)(`span`,{className:`conv-chip-server`,children:t.serverLabel})]}):(0,U.jsx)(`span`,{className:`conv-chip-name`,children:e??`tool`})}var _C=new Set([`TaskCreate`,`TaskUpdate`,`TaskList`]);function vC(e){let t=e[0];return t!=null&&t.name!=null&&_C.has(t.name)&&Array.isArray(t.task_snapshot)}function yC({blocks:e,anchorUuid:t}){let n=eS()===`chat`,r=[],i=0,a=[],o=()=>{a.length&&(r.push((0,U.jsx)(kx,{children:a.join(`
62
62
 
63
63
  `)},`t${r.length}`)),a=[])};for(;i<e.length;){let s=e[i];if(s.kind===`text`){a.push(s.text),i++;continue}if(o(),s.kind===`tool_call`){let t=[];for(;i<e.length&&e[i].kind===`tool_call`;)t.push(e[i]),i++;n||r.push((0,U.jsx)(bC,{calls:t},`r${r.length}`));continue}if(n&&(s.kind===`tool_use`||s.kind===`tool_result`)){i++;continue}r.push((0,U.jsx)(wC,{block:s,anchorUuid:t},`c${r.length}`)),i++}return o(),r.length===0?null:(0,U.jsx)(`div`,{className:`conv-blocks`,children:r})}function bC({calls:e}){return vC(e)?(0,U.jsx)(`div`,{className:`conv-toolrun`,children:(0,U.jsx)(hC,{call:e[0]})}):(0,U.jsxs)(`div`,{className:`conv-toolrun`,children:[e.length>=2&&(0,U.jsxs)(`div`,{className:`conv-toolrun-head`,children:[`tool run · `,e.length,` actions`]}),e.map((e,t)=>(0,U.jsx)(SC,{call:e},t))]})}function xC({result:e,name:t,preview:n}){let r=t===`Read`&&!e.is_error?Px(`Read`,n):``;return r?(0,U.jsx)(jx,{code:e.text,lang:r}):(0,U.jsx)(`pre`,{className:`conv-code conv-code--result`,children:e.text})}function SC({call:e}){if(e.skill_body!=null)return(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--tool conv-chip--skill`,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),vx(e.name),` `,(0,U.jsx)(gC,{name:e.name}),(0,U.jsx)(`span`,{className:`conv-chip-preview`,children:e.preview})]}),(0,U.jsxs)(`div`,{className:`conv-chip-body`,children:[(0,U.jsx)(yx,{text:e.skill_body}),(0,U.jsx)(kx,{children:e.skill_body})]})]});let t=mC(e);if(t)return t;let n=e.result?.is_error?` · error`:e.result?.truncated?` · truncated`:``;return(0,U.jsxs)(`details`,{className:`conv-chip conv-chip--tool`,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{className:`conv-chev`,"aria-hidden":`true`}),vx(e.name),` `,(0,U.jsx)(gC,{name:e.name}),(0,U.jsx)(`span`,{className:`conv-chip-preview`,children:e.preview}),n&&(0,U.jsx)(`span`,{className:`conv-chip-status`,children:n})]}),(0,U.jsxs)(`div`,{className:`conv-chip-body conv-chip-body--io`,children:[(0,U.jsxs)(`div`,{className:`conv-tool-io`,children:[(0,U.jsx)(`div`,{className:`conv-tool-io-label`,children:`request`}),(0,U.jsx)(yx,{text:e.input_summary}),(0,U.jsx)(`pre`,{className:`conv-code conv-code--hl`,children:Sx(e.input_summary,`json`)})]}),e.result?(0,U.jsxs)(`div`,{className:`conv-tool-io`,children:[(0,U.jsxs)(`div`,{className:`conv-tool-io-label`,children:[`result`,e.result.is_error?` · error`:` · ok`,e.result.truncated?` · truncated`:``]}),(0,U.jsx)(yx,{text:e.result.text}),(0,U.jsx)(xC,{result:e.result,name:e.name,preview:e.preview}),e.result.media?.map(t=>(0,U.jsx)(ZS,{media:t,toolUseId:e.tool_use_id,context:e.name??`tool`},t.index))]}):(0,U.jsx)(`div`,{className:`conv-tool-io`,children:(0,U.jsx)(`div`,{className:`conv-tool-io-label conv-tool-io-label--none`,children:`no result`})})]})]})}function CC(e){let t=e.split(`
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
6
  <title>cctally dashboard</title>
7
- <script type="module" crossorigin src="/static/assets/index-C_xsUDIl.js"></script>
7
+ <script type="module" crossorigin src="/static/assets/index-L_FSvwQH.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/static/assets/index-Drpkfv6k.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cctally",
3
- "version": "1.44.1",
3
+ "version": "1.44.2",
4
4
  "description": "Claude Code usage tracker and local dashboard for Pro/Max subscription limits - weekly cost-per-percent trend, quota forecasts, threshold alerts. ccusage-compatible.",
5
5
  "homepage": "https://github.com/omrikais/cctally",
6
6
  "repository": {