@creative-dswork/dscode 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dscode.mjs CHANGED
@@ -220426,6 +220426,83 @@ var init_at_file_resolver = __esm({
220426
220426
  }
220427
220427
  });
220428
220428
 
220429
+ // src/ui/shared/tool-result-formatter.ts
220430
+ function extractWriteSummary(text) {
220431
+ const lines = text.split("\n");
220432
+ const meaningful = [];
220433
+ for (const line of lines) {
220434
+ if (meaningful.length >= 2) break;
220435
+ const trimmed = line.trim();
220436
+ if (trimmed.length > 0) {
220437
+ meaningful.push(trimmed);
220438
+ }
220439
+ }
220440
+ if (meaningful.length === 0) return text.slice(0, DEFAULT_MAX_CHARS);
220441
+ const summary = meaningful.join("\n");
220442
+ const remainingLines = lines.length - 2;
220443
+ if (remainingLines > 0) {
220444
+ return `${summary}
220445
+ \u2026 (${remainingLines} more lines \u2014 anchor preview hidden)`;
220446
+ }
220447
+ return summary;
220448
+ }
220449
+ function isJSON(text) {
220450
+ const trimmed = text.trim();
220451
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return false;
220452
+ try {
220453
+ JSON.parse(trimmed);
220454
+ return true;
220455
+ } catch {
220456
+ return false;
220457
+ }
220458
+ }
220459
+ function prettyPrintJSON(text) {
220460
+ return JSON.stringify(JSON.parse(text.trim()), null, 2);
220461
+ }
220462
+ function formatCodeBlock(text, lang) {
220463
+ const fence = lang ? "```" + lang : "```";
220464
+ return `${fence}
220465
+ ${text}
220466
+ \`\`\``;
220467
+ }
220468
+ function truncate(text) {
220469
+ if (text.length <= DEFAULT_MAX_CHARS) return text;
220470
+ return text.slice(0, DEFAULT_MAX_CHARS) + `
220471
+ \u2026 (${text.length - DEFAULT_MAX_CHARS} more chars)`;
220472
+ }
220473
+ function formatToolResultForUI(toolName, rawText) {
220474
+ if (!rawText) return "";
220475
+ switch (toolName) {
220476
+ case "write_file":
220477
+ case "overwrite_file":
220478
+ return extractWriteSummary(rawText);
220479
+ case "bash":
220480
+ return formatCodeBlock(truncate(rawText), "sh");
220481
+ case "grep":
220482
+ case "glob": {
220483
+ if (isJSON(rawText)) {
220484
+ return formatCodeBlock(truncate(prettyPrintJSON(rawText)), "json");
220485
+ }
220486
+ return formatCodeBlock(truncate(rawText));
220487
+ }
220488
+ case "read_file":
220489
+ return formatCodeBlock(truncate(rawText));
220490
+ default: {
220491
+ if (isJSON(rawText)) {
220492
+ return formatCodeBlock(truncate(prettyPrintJSON(rawText)), "json");
220493
+ }
220494
+ return truncate(rawText);
220495
+ }
220496
+ }
220497
+ }
220498
+ var DEFAULT_MAX_CHARS;
220499
+ var init_tool_result_formatter = __esm({
220500
+ "src/ui/shared/tool-result-formatter.ts"() {
220501
+ "use strict";
220502
+ DEFAULT_MAX_CHARS = 600;
220503
+ }
220504
+ });
220505
+
220429
220506
  // src/session/display.ts
220430
220507
  function extractText(content) {
220431
220508
  if (typeof content === "string") return content;
@@ -220449,9 +220526,10 @@ function extractThinkingFromContent(blocks) {
220449
220526
  }
220450
220527
  return parts.length > 0 ? parts.join("\n\n") : void 0;
220451
220528
  }
220452
- function extractToolResultText(blocks) {
220529
+ function extractToolResultText(blocks, toolName) {
220453
220530
  if (!Array.isArray(blocks)) return "";
220454
- return blocks.filter((b) => b && b.type === "text").map((b) => b.text).join("\n");
220531
+ const raw = blocks.filter((b) => b && b.type === "text").map((b) => b.text).join("\n");
220532
+ return formatToolResultForUI(toolName, raw);
220455
220533
  }
220456
220534
  function rebuildDisplayMessages(messages, visionMessages) {
220457
220535
  const visionMap = /* @__PURE__ */ new Map();
@@ -220494,14 +220572,17 @@ function rebuildDisplayMessages(messages, visionMessages) {
220494
220572
  const toolCallId = m.toolCallId;
220495
220573
  if (toolCallId && lastAssistantToolIds.has(toolCallId)) {
220496
220574
  const toolIdx = lastAssistantToolIds.get(toolCallId);
220497
- const resultText = extractToolResultText(m.content);
220575
+ const assistantMsg = messages[lastAssistantIdx];
220576
+ const parsedTools = assistantMsg.__parsedTools;
220577
+ const toolName = parsedTools?.[toolIdx]?.name ?? "unknown";
220578
+ const resultText = extractToolResultText(m.content, toolName);
220498
220579
  const isError = !!m.isError;
220499
220580
  let results = pendingResults.get(lastAssistantIdx);
220500
220581
  if (!results) {
220501
220582
  results = /* @__PURE__ */ new Map();
220502
220583
  pendingResults.set(lastAssistantIdx, results);
220503
220584
  }
220504
- results.set(toolCallId, { result: resultText, isError });
220585
+ results.set(toolCallId, { result: resultText, isError, toolName });
220505
220586
  } else {
220506
220587
  output.add(i);
220507
220588
  }
@@ -220577,6 +220658,7 @@ var init_display = __esm({
220577
220658
  "src/session/display.ts"() {
220578
220659
  "use strict";
220579
220660
  init_image_cache();
220661
+ init_tool_result_formatter();
220580
220662
  }
220581
220663
  });
220582
220664
 
@@ -220707,6 +220789,7 @@ var init_web_backend = __esm({
220707
220789
  init_mcp_browser();
220708
220790
  init_at_file_resolver();
220709
220791
  init_display();
220792
+ init_tool_result_formatter();
220710
220793
  init_ws_server();
220711
220794
  WebUiBackend = class {
220712
220795
  port;
@@ -220730,6 +220813,10 @@ var init_web_backend = __esm({
220730
220813
  pendingImages = [];
220731
220814
  // Message accumulation for the current assistant turn
220732
220815
  currentAssistant = null;
220816
+ // Context window broadcast throttling
220817
+ contextWindowThrottleTimer = null;
220818
+ contextWindowThrottlePending = false;
220819
+ isAssistantTurn = false;
220733
220820
  constructor(options) {
220734
220821
  this.port = options.port;
220735
220822
  this.harness = options.harness;
@@ -220758,23 +220845,29 @@ var init_web_backend = __esm({
220758
220845
  this.broadcast({ type: "tool_start", name: e.name, args: e.args });
220759
220846
  });
220760
220847
  h.events.on("tool:end", (e) => {
220761
- const rs = typeof e.result === "string" ? e.result.slice(0, 5e3) : JSON.stringify(e.result).slice(0, 5e3);
220848
+ const rawResult = typeof e.result === "string" ? e.result : JSON.stringify(e.result);
220849
+ const rs = formatToolResultForUI(e.name, rawResult);
220762
220850
  const imgs = extractImagesFromToolResult(e.result);
220763
220851
  if (this.currentAssistant) {
220764
220852
  this.currentAssistant.tools = this.currentAssistant.tools.filter((t) => t.name !== e.name || t.result !== "");
220765
220853
  this.currentAssistant.tools.push({ name: e.name, args: "", result: rs, isError: e.isError, images: imgs });
220766
220854
  }
220767
220855
  this.broadcast({ type: "tool_end", name: e.name, result: rs, isError: e.isError, images: imgs });
220856
+ this.broadcastContextWindow(false);
220768
220857
  });
220769
220858
  h.events.on("turn:streaming:start", () => {
220770
220859
  this.currentAssistant = { thinking: "", text: "", tools: [] };
220771
220860
  this.broadcast({ type: "assistant_start" });
220772
220861
  this.startSessionTimeBroadcast();
220862
+ this.isAssistantTurn = true;
220773
220863
  });
220774
220864
  h.events.on("turn:end", () => {
220775
220865
  this.broadcastSessionTime();
220866
+ const toolsForBroadcast = this.currentAssistant?.tools ?? [];
220776
220867
  this.currentAssistant = null;
220777
220868
  this.broadcast({ type: "assistant_end" });
220869
+ this.isAssistantTurn = false;
220870
+ this.broadcastContextWindow(true, toolsForBroadcast);
220778
220871
  this.pushSessionListToAll();
220779
220872
  });
220780
220873
  h.events.on("turn:abort", () => {
@@ -220810,6 +220903,7 @@ var init_web_backend = __esm({
220810
220903
  this.currentAssistant = null;
220811
220904
  this.pendingImages = [];
220812
220905
  this.broadcast({ type: "clear_conversation" });
220906
+ this.broadcastContextWindow(true);
220813
220907
  });
220814
220908
  h.events.on("config:change", (e) => {
220815
220909
  this.broadcast({ type: "config", data: e.data });
@@ -220827,6 +220921,9 @@ var init_web_backend = __esm({
220827
220921
  h.events.on("session:created", () => {
220828
220922
  this.pushSessionListToAll();
220829
220923
  });
220924
+ h.events.on("session:deleted", () => {
220925
+ this.pushSessionListToAll();
220926
+ });
220830
220927
  }
220831
220928
  setAppHostManager(manager) {
220832
220929
  this.appHostManager = manager;
@@ -220903,12 +221000,15 @@ var init_web_backend = __esm({
220903
221000
  });
220904
221001
  }
220905
221002
  this.broadcast({ type: "tool_end", name, result: resultStr, isError, images });
221003
+ this.broadcastContextWindow(false);
220906
221004
  }
220907
221005
  finishAssistantMessage() {
220908
221006
  this.broadcastSessionTime();
220909
221007
  this.stopSessionTimeBroadcast();
221008
+ const toolsForBroadcast2 = this.currentAssistant?.tools ?? [];
220910
221009
  this.currentAssistant = null;
220911
221010
  this.broadcast({ type: "assistant_end" });
221011
+ this.broadcastContextWindow(true, toolsForBroadcast2);
220912
221012
  const sm2 = this.harness.sessionManager;
220913
221013
  if (sm2) {
220914
221014
  const sessions2 = sm2.listSessions();
@@ -221013,9 +221113,11 @@ var init_web_backend = __esm({
221013
221113
  focusEditor() {
221014
221114
  }
221015
221115
  clearConversationView() {
221116
+ const toolsForBroadcast3 = this.currentAssistant?.tools ?? [];
221016
221117
  this.currentAssistant = null;
221017
221118
  this.pendingImages = [];
221018
221119
  this.broadcast({ type: "clear_conversation" });
221120
+ this.broadcastContextWindow(true, toolsForBroadcast3);
221019
221121
  }
221020
221122
  // ── UiBackend Processing ──
221021
221123
  setProcessing(processing) {
@@ -221060,6 +221162,7 @@ var init_web_backend = __esm({
221060
221162
  config: configData,
221061
221163
  messages
221062
221164
  });
221165
+ this.broadcastContextWindow(true);
221063
221166
  if (this.mcpManager) {
221064
221167
  this.pushMcpState();
221065
221168
  }
@@ -221601,6 +221704,7 @@ ${matchList}` });
221601
221704
  config: this.buildConfigData(),
221602
221705
  messages
221603
221706
  });
221707
+ this.broadcastContextWindow(true);
221604
221708
  this.pushSessionList(client);
221605
221709
  break;
221606
221710
  }
@@ -221609,15 +221713,21 @@ ${matchList}` });
221609
221713
  client.send({ type: "error", text: "Session ID required." });
221610
221714
  return;
221611
221715
  }
221716
+ const wasCurrent = sessionManager.getCurrentSessionId?.() === cmd.id;
221612
221717
  const result = sessionManager.deleteSession(cmd.id);
221613
221718
  if (!result.success) {
221614
221719
  client.send({ type: "error", text: `Failed to delete session: ${result.error}` });
221615
221720
  return;
221616
221721
  }
221722
+ if (wasCurrent) {
221723
+ client.send({ type: "clear_conversation" });
221724
+ }
221617
221725
  client.send({ type: "info", display: "toast", text: "Session deleted." });
221618
221726
  const sessions = sessionManager.listSessions();
221727
+ const currentId = sessionManager.getCurrentSessionId?.() ?? void 0;
221619
221728
  client.send({
221620
221729
  type: "sessions",
221730
+ currentSessionId: currentId,
221621
221731
  data: sessions.slice(0, 50).map((s) => ({
221622
221732
  id: s.id,
221623
221733
  title: s.title,
@@ -221716,6 +221826,44 @@ ${matchList}` });
221716
221826
  const vms = this.harness.sessionManager?.visionMessages ?? [];
221717
221827
  return rebuildDisplayMessages(messages, vms);
221718
221828
  }
221829
+ getSkillToolNames() {
221830
+ const names = /* @__PURE__ */ new Set();
221831
+ const sm = this.harness.skillManager;
221832
+ if (sm) {
221833
+ for (const name of sm.listAllSkillNames()) {
221834
+ names.add(name);
221835
+ }
221836
+ }
221837
+ return names;
221838
+ }
221839
+ broadcastContextWindow(bypassThrottle, toolsOverride) {
221840
+ const cm = this.harness.contextManager;
221841
+ const cw = cm.getContextWindow();
221842
+ if (cw <= 0) return;
221843
+ if (!bypassThrottle) {
221844
+ if (this.contextWindowThrottleTimer) {
221845
+ this.contextWindowThrottlePending = true;
221846
+ return;
221847
+ }
221848
+ this.contextWindowThrottleTimer = setTimeout(() => {
221849
+ this.contextWindowThrottleTimer = null;
221850
+ if (this.contextWindowThrottlePending) {
221851
+ this.contextWindowThrottlePending = false;
221852
+ this.broadcastContextWindow(true, toolsOverride);
221853
+ }
221854
+ }, 500);
221855
+ }
221856
+ const messages = this.harness.agent.state.messages;
221857
+ const tools = toolsOverride ?? this.currentAssistant?.tools ?? [];
221858
+ const breakdown = cm.getCategoryBreakdown(messages, tools, this.getSkillToolNames());
221859
+ this.broadcast({
221860
+ type: "context_window",
221861
+ total: breakdown.total,
221862
+ used: breakdown.used,
221863
+ free: breakdown.free,
221864
+ categories: breakdown.categories
221865
+ });
221866
+ }
221719
221867
  broadcast(event) {
221720
221868
  this.wsServer.broadcast(event);
221721
221869
  }
@@ -222253,6 +222401,7 @@ var SessionManager = class {
222253
222401
  deleteSession(id) {
222254
222402
  try {
222255
222403
  this.store.delete(id);
222404
+ if (id === this.current?.id) this.current = null;
222256
222405
  this.events?.emit({ type: "session:deleted", id });
222257
222406
  return { success: true };
222258
222407
  } catch (err) {
@@ -222402,6 +222551,99 @@ var ContextManager = class {
222402
222551
  const reservedTools = 3e3;
222403
222552
  return this.contextWindow - this.maxTokens - reservedSystem - reservedTools;
222404
222553
  }
222554
+ getContextWindow() {
222555
+ return this.contextWindow;
222556
+ }
222557
+ classifyToolCategory(toolName, skillNames) {
222558
+ if (toolName.startsWith("mcp__")) return "mcp";
222559
+ if (skillNames?.has(toolName)) return "skill";
222560
+ if (toolName === "read_file" || toolName === "list_files" || toolName === "grep" || toolName === "glob" || toolName === "write_file" || toolName === "overwrite_file")
222561
+ return "readwrite";
222562
+ if (toolName === "edit" || toolName === "edit_undo") return "edit";
222563
+ if (toolName === "bash") return "shell";
222564
+ return "other";
222565
+ }
222566
+ getCategoryBreakdown(messages, tools, skillNames) {
222567
+ const categories = {
222568
+ system: 0,
222569
+ rules: 0,
222570
+ user: 0,
222571
+ thinking: 0,
222572
+ readwrite: 0,
222573
+ edit: 0,
222574
+ shell: 0,
222575
+ skill: 0,
222576
+ mcp: 0,
222577
+ other: 0
222578
+ };
222579
+ let systemMsgIndex = 0;
222580
+ for (const msg of messages) {
222581
+ const m = msg;
222582
+ const role = m?.role;
222583
+ const content = m?.content;
222584
+ if (role === "system") {
222585
+ systemMsgIndex++;
222586
+ const target = systemMsgIndex === 1 ? "system" : "rules";
222587
+ if (typeof content === "string") {
222588
+ categories[target] += estimateTokens(content);
222589
+ categories[target] += 4;
222590
+ } else if (Array.isArray(content)) {
222591
+ for (const block of content) {
222592
+ if (block?.type === "text" && typeof block.text === "string") {
222593
+ categories[target] += estimateTokens(block.text);
222594
+ }
222595
+ }
222596
+ categories[target] += 4;
222597
+ }
222598
+ } else if (role === "user") {
222599
+ if (typeof content === "string") {
222600
+ categories.user += estimateTokens(content);
222601
+ } else if (Array.isArray(content)) {
222602
+ for (const block of content) {
222603
+ if (block?.type === "text" && typeof block.text === "string") {
222604
+ categories.user += estimateTokens(block.text);
222605
+ }
222606
+ }
222607
+ }
222608
+ categories.user += 4;
222609
+ } else if (role === "assistant") {
222610
+ if (typeof content === "string") {
222611
+ categories.thinking += estimateTokens(content);
222612
+ } else if (Array.isArray(content)) {
222613
+ for (const block of content) {
222614
+ if (block?.type === "text" && typeof block.text === "string") {
222615
+ categories.thinking += estimateTokens(block.text);
222616
+ } else if (block?.type === "thinking" && typeof block.thinking === "string") {
222617
+ categories.thinking += estimateTokens(block.thinking);
222618
+ }
222619
+ }
222620
+ }
222621
+ categories.thinking += 4;
222622
+ } else if (role === "toolResult") {
222623
+ const toolName = m?.toolName ?? "";
222624
+ const cat = this.classifyToolCategory(toolName, skillNames);
222625
+ if (Array.isArray(content)) {
222626
+ for (const block of content) {
222627
+ if (block?.type === "text" && typeof block.text === "string") {
222628
+ categories[cat] += estimateTokens(block.text);
222629
+ }
222630
+ }
222631
+ } else if (typeof content === "string") {
222632
+ categories[cat] += estimateTokens(content);
222633
+ }
222634
+ categories[cat] += 20;
222635
+ }
222636
+ }
222637
+ for (const tool of tools) {
222638
+ const cat = this.classifyToolCategory(tool.name, skillNames);
222639
+ const resultTokens = typeof tool.result === "string" ? estimateTokens(tool.result) : 0;
222640
+ categories[cat] += resultTokens + 20;
222641
+ }
222642
+ const used = Object.values(categories).reduce((a, b) => a + b, 0);
222643
+ const total = this.contextWindow;
222644
+ const free = Math.max(0, total - used);
222645
+ return { total, used, free, categories };
222646
+ }
222405
222647
  getEstimatedTokens(messages) {
222406
222648
  return estimateMessagesTokens(messages);
222407
222649
  }
@@ -0,0 +1 @@
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Geist Sans,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:Geist Mono,JetBrains Mono,Fira Code,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}*{scrollbar-width:thin;scrollbar-color:var(--color-border) transparent;transition:background-color .3s ease,border-color .3s ease,color .3s ease}*::-webkit-scrollbar{width:6px}*::-webkit-scrollbar-track{background:transparent}*::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:3px}body{font-family:Geist Sans,system-ui,sans-serif;background-color:var(--color-bg);color:var(--color-text)}.btn{padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem;font-weight:500;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.btn:focus{outline:2px solid transparent;outline-offset:2px}.btn:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-offset-width: 1px}.btn:disabled{cursor:not-allowed;opacity:.5}.btn{border-radius:6px;border:1px solid transparent}.btn-primary{padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem;font-weight:500;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.btn-primary:focus{outline:2px solid transparent;outline-offset:2px}.btn-primary:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-offset-width: 1px}.btn-primary:disabled{cursor:not-allowed;opacity:.5}.btn-primary{border-radius:6px;border:1px solid transparent;background-color:var(--color-accent);color:#fff;border-color:var(--color-accent)}.btn-primary:hover{background-color:var(--color-accent-hover);border-color:var(--color-accent-hover)}.btn-secondary{padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem;font-weight:500;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.btn-secondary:focus{outline:2px solid transparent;outline-offset:2px}.btn-secondary:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-offset-width: 1px}.btn-secondary:disabled{cursor:not-allowed;opacity:.5}.btn-secondary{border-radius:6px;border:1px solid transparent;background-color:var(--color-surface);color:var(--color-text);border-color:var(--color-border)}.btn-secondary:hover{background-color:var(--color-surface-hover)}.btn-danger{padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem;font-weight:500;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.btn-danger:focus{outline:2px solid transparent;outline-offset:2px}.btn-danger:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-offset-width: 1px}.btn-danger:disabled{cursor:not-allowed;opacity:.5}.btn-danger{border-radius:6px;border:1px solid transparent;background-color:var(--color-error);color:var(--color-error-text);border-color:var(--color-error-text)}.btn-danger:hover{filter:brightness(.95)}.input{width:100%;padding:.625rem 1rem;font-size:.875rem;line-height:1.25rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.input::-moz-placeholder{color:var(--color-text-muted)}.input::placeholder{color:var(--color-text-muted)}.input:focus{outline:2px solid transparent;outline-offset:2px}.input{border-radius:12px;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text)}.input:focus{border-color:var(--color-accent)}.card{border-radius:8px;border:1px solid var(--color-border);background-color:var(--color-surface);padding:1rem}.resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;z-index:10;transition:background-color .15s ease}.resize-handle:hover{background-color:var(--color-border)}.resize-handle:active{background-color:var(--color-accent)}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.-right-1\.5{right:-.375rem}.-top-1\.5{top:-.375rem}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.left-4{left:1rem}.right-4{right:1rem}.top-4{top:1rem}.top-full{top:100%}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-screen{height:100vh}.max-h-24{max-height:6rem}.max-h-32{max-height:8rem}.max-h-40{max-height:10rem}.max-h-48{max-height:12rem}.max-h-60{max-height:15rem}.max-h-\[200px\]{max-height:200px}.max-h-\[300px\]{max-height:300px}.max-h-\[400px\]{max-height:400px}.max-h-\[70vh\]{max-height:70vh}.min-h-0{min-height:0px}.min-h-\[40px\]{min-height:40px}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-5{width:1.25rem}.w-72{width:18rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-full{min-width:100%}.max-w-4xl{max-width:56rem}.max-w-\[200px\]{max-width:200px}.max-w-\[300px\]{max-width:300px}.max-w-\[85\%\]{max-width:85%}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-bounce{animation:bounce 1s infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-btn{border-radius:6px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-sm{border-radius:.125rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.bg-black\/30{background-color:#0000004d}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pl-3{padding-left:.75rem}.pt-16{padding-top:4rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:Geist Mono,JetBrains Mono,Fira Code,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.capitalize{text-transform:capitalize}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.underline{text-decoration-line:underline}.\!opacity-0{opacity:0!important}.opacity-0{opacity:0}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[filter\]{transition-property:filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}:root{--color-bg: #f8f7f5;--color-surface: #f3f2ef;--color-surface-hover: #ebe9e5;--color-border: #e6e4e0;--color-text: #2d2a26;--color-text-muted: #8a8580;--color-accent: #ca8a04;--color-accent-hover: #a07004;--color-success: #edf4ed;--color-success-text: #347539;--color-error: #fdebec;--color-error-text: #9f2f2d;--color-warning: #fbf3db;--color-warning-text: #956400;--color-user-bubble: #ca8a04;--color-user-bubble-text: #ffffff;--cw-system: #8a8580;--cw-rules: #a0908b;--cw-user: #ca8a04;--cw-thinking: #a78bfa;--cw-readwrite: #eab308;--cw-edit: #3b82f6;--cw-shell: #ef4444;--cw-skill: #059669;--cw-mcp: #8b5cf6;--cw-other: #6b7280}.dark{--color-bg: #1e1c19;--color-surface: #282622;--color-surface-hover: #322e2a;--color-border: #3a3732;--color-text: #e8e4dd;--color-text-muted: #8a8580;--cw-system: #8a8580;--cw-rules: #b0a09b;--cw-user: #d49708;--cw-thinking: #7c6bb0;--cw-readwrite: #ca8a04;--cw-edit: #60a5fa;--cw-shell: #f87171;--cw-skill: #10b981;--cw-mcp: #a78bfa;--cw-other: #9ca3af;--color-accent: #d49708;--color-accent-hover: #e5a50a;--color-success: #1a2e1a;--color-success-text: #5ca860;--color-error: #3a1a1a;--color-error-text: #e05553;--color-warning: #3a2e10;--color-warning-text: #d4a017;--color-user-bubble: #d49708;--color-user-bubble-text: #1e1c19}@media (max-width: 767px){.resize-handle{display:none}}@keyframes fade-up{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes slide-in{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}@keyframes spin{to{transform:rotate(360deg)}}.animate-fade-up{animation:fade-up .6s cubic-bezier(.16,1,.3,1) forwards}.animate-slide-in{animation:slide-in .3s ease-out forwards}@media (prefers-reduced-motion: reduce){.animate-fade-up,.animate-slide-in{animation:none}*{transition:none!important}}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-90:hover{opacity:.9}.hover\:brightness-95:hover{--tw-brightness: brightness(.95);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.group:hover .group-hover\:opacity-100{opacity:1}@media (min-width: 640px){.sm\:inline{display:inline}}@media (min-width: 768px){.md\:static{position:static}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:max-w-\[75\%\]{max-width:75%}.md\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}}