@creative-dswork/dscode 0.2.5 → 0.2.6

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
@@ -9981,7 +9981,7 @@ ${lanes.join("\n")}
9981
9981
  return process.memoryUsage().heapUsed;
9982
9982
  },
9983
9983
  getFileSize(path) {
9984
- const stat4 = statSync5(path);
9984
+ const stat4 = statSync6(path);
9985
9985
  if (stat4 == null ? void 0 : stat4.isFile()) {
9986
9986
  return stat4.size;
9987
9987
  }
@@ -10025,7 +10025,7 @@ ${lanes.join("\n")}
10025
10025
  }
10026
10026
  };
10027
10027
  return nodeSystem;
10028
- function statSync5(path) {
10028
+ function statSync6(path) {
10029
10029
  try {
10030
10030
  return _fs.statSync(path, statSyncOptions);
10031
10031
  } catch {
@@ -10084,7 +10084,7 @@ ${lanes.join("\n")}
10084
10084
  activeSession.post("Profiler.stop", (err, { profile }) => {
10085
10085
  var _a;
10086
10086
  if (!err) {
10087
- if ((_a = statSync5(profilePath)) == null ? void 0 : _a.isDirectory()) {
10087
+ if ((_a = statSync6(profilePath)) == null ? void 0 : _a.isDirectory()) {
10088
10088
  profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
10089
10089
  }
10090
10090
  try {
@@ -10204,7 +10204,7 @@ ${lanes.join("\n")}
10204
10204
  let stat4;
10205
10205
  if (typeof dirent === "string" || dirent.isSymbolicLink()) {
10206
10206
  const name = combinePaths(path, entry);
10207
- stat4 = statSync5(name);
10207
+ stat4 = statSync6(name);
10208
10208
  if (!stat4) {
10209
10209
  continue;
10210
10210
  }
@@ -10228,7 +10228,7 @@ ${lanes.join("\n")}
10228
10228
  return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
10229
10229
  }
10230
10230
  function fileSystemEntryExists(path, entryKind) {
10231
- const stat4 = statSync5(path);
10231
+ const stat4 = statSync6(path);
10232
10232
  if (!stat4) {
10233
10233
  return false;
10234
10234
  }
@@ -10270,7 +10270,7 @@ ${lanes.join("\n")}
10270
10270
  }
10271
10271
  function getModifiedTime3(path) {
10272
10272
  var _a;
10273
- return (_a = statSync5(path)) == null ? void 0 : _a.mtime;
10273
+ return (_a = statSync6(path)) == null ? void 0 : _a.mtime;
10274
10274
  }
10275
10275
  function setModifiedTime(path, time) {
10276
10276
  try {
@@ -221308,7 +221308,7 @@ var DEFAULT_MAX_CHARS;
221308
221308
  var init_tool_result_formatter = __esm({
221309
221309
  "src/ui/shared/tool-result-formatter.ts"() {
221310
221310
  "use strict";
221311
- DEFAULT_MAX_CHARS = 600;
221311
+ DEFAULT_MAX_CHARS = 2e3;
221312
221312
  }
221313
221313
  });
221314
221314
 
@@ -221570,7 +221570,7 @@ __export(web_backend_exports, {
221570
221570
  WebUiBackend: () => WebUiBackend
221571
221571
  });
221572
221572
  import { createServer, request as httpRequest2 } from "node:http";
221573
- import { readFileSync as readFileSync21, existsSync as existsSync24 } from "node:fs";
221573
+ import { readFileSync as readFileSync21, existsSync as existsSync24, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, rmSync as rmSync3, readdirSync as readdirSync9, statSync as statSync5 } from "node:fs";
221574
221574
  import { join as join29, extname as extname2, resolve as resolve10 } from "node:path";
221575
221575
  import { fileURLToPath as fileURLToPath3 } from "node:url";
221576
221576
  function extractImagesFromToolResult(result) {
@@ -221630,6 +221630,15 @@ var init_web_backend = __esm({
221630
221630
  contextWindowThrottlePending = false;
221631
221631
  lastArtifactHtml = "";
221632
221632
  isAssistantTurn = false;
221633
+ cleanupUploadDir(sessionId) {
221634
+ const uploadDir = join29(this.config.projectPath, ".dscode", "uploads", sessionId);
221635
+ if (existsSync24(uploadDir)) {
221636
+ try {
221637
+ rmSync3(uploadDir, { recursive: true, force: true });
221638
+ } catch {
221639
+ }
221640
+ }
221641
+ }
221633
221642
  constructor(options) {
221634
221643
  this.port = options.port;
221635
221644
  this.harness = options.harness;
@@ -221803,22 +221812,6 @@ var init_web_backend = __esm({
221803
221812
  toolStart(name, args) {
221804
221813
  this.broadcast({ type: "tool_start", name, args });
221805
221814
  }
221806
- toolEnd(name, result, isError) {
221807
- const resultStr = typeof result === "string" ? result.slice(0, 5e3) : JSON.stringify(result).slice(0, 5e3);
221808
- const images = extractImagesFromToolResult(result);
221809
- if (this.currentAssistant) {
221810
- this.currentAssistant.tools = this.currentAssistant.tools.filter((t) => t.name !== name || t.result !== "");
221811
- this.currentAssistant.tools.push({
221812
- name,
221813
- args: "",
221814
- result: resultStr,
221815
- isError,
221816
- images
221817
- });
221818
- }
221819
- this.broadcast({ type: "tool_end", name, result: resultStr, isError, images });
221820
- this.broadcastContextWindow(false);
221821
- }
221822
221815
  finishAssistantMessage() {
221823
221816
  this.broadcastSessionTime();
221824
221817
  this.stopSessionTimeBroadcast();
@@ -222024,24 +222017,90 @@ var init_web_backend = __esm({
222024
222017
  for (const warn of resolved.warnings) {
222025
222018
  client.send({ type: "info", display: "toast", text: `@${warn.path ?? ""}: ${warn.type}${warn.detail ? ` \u2014 ${warn.detail}` : ""}` });
222026
222019
  }
222020
+ if (cmd.uploadedFiles && cmd.uploadedFiles.length > 0) {
222021
+ const sm = this.harness.sessionManager;
222022
+ const sessionId = sm.getCurrentSessionId?.() ?? "default";
222023
+ const ts = Date.now();
222024
+ const uploadDir = join29(this.config.projectPath, ".dscode", "uploads", sessionId);
222025
+ mkdirSync13(uploadDir, { recursive: true });
222026
+ const tempPaths = [];
222027
+ for (const uf of cmd.uploadedFiles) {
222028
+ const tempName = `${ts}-${uf.name}`;
222029
+ const tempPath = join29(uploadDir, tempName);
222030
+ writeFileSync14(tempPath, Buffer.from(uf.content, "base64"));
222031
+ tempPaths.push(tempPath);
222032
+ }
222033
+ if (tempPaths.length > 0) {
222034
+ const pathLines = tempPaths.map((p) => `- \`${p}\``).join("\n");
222035
+ text = text ? `${text}
222036
+
222037
+ \u{1F4C1} Attached files:
222038
+ ${pathLines}` : `\u{1F4C1} Attached files:
222039
+ ${pathLines}`;
222040
+ }
222041
+ }
222027
222042
  if (cmd.fileRefs && cmd.fileRefs.length > 0) {
222028
- const refsResolved = resolveFileRefs(this.config.projectPath, cmd.fileRefs, this.config.atFile ?? {});
222029
- if (!refsResolved.reject) {
222030
- if (refsResolved.text) {
222031
- text = text ? `${text}
222043
+ const imageRefs = cmd.fileRefs.filter((f) => isImagePath(f));
222044
+ const nonImageRefs = cmd.fileRefs.filter((f) => !isImagePath(f));
222045
+ if (nonImageRefs.length > 0) {
222046
+ const pathLines = nonImageRefs.map((f) => `- \`${f}\``).join("\n");
222047
+ text = text ? `${text}
222048
+
222049
+ \u{1F4C1} Attached files:
222050
+ ${pathLines}` : `\u{1F4C1} Attached files:
222051
+ ${pathLines}`;
222052
+ }
222053
+ if (imageRefs.length > 0) {
222054
+ const refsResolved = resolveFileRefs(this.config.projectPath, imageRefs, this.config.atFile ?? {});
222055
+ if (!refsResolved.reject) {
222056
+ if (refsResolved.text) {
222057
+ text = text ? `${text}
222032
222058
 
222033
222059
  ${refsResolved.text}` : refsResolved.text;
222060
+ }
222061
+ if (refsResolved.images.length > 0) {
222062
+ const refImages = refsResolved.images.map((img) => ({
222063
+ data: img.data,
222064
+ mimeType: img.mimeType
222065
+ }));
222066
+ images = [...images ?? [], ...refImages];
222067
+ }
222034
222068
  }
222035
- if (refsResolved.images.length > 0) {
222036
- const refImages = refsResolved.images.map((img) => ({
222037
- data: img.data,
222038
- mimeType: img.mimeType
222039
- }));
222040
- images = [...images ?? [], ...refImages];
222069
+ for (const warn of refsResolved.warnings) {
222070
+ client.send({ type: "info", display: "toast", text: `${warn.path ?? ""}: ${warn.type}${warn.detail ? ` \u2014 ${warn.detail}` : ""}` });
222041
222071
  }
222042
222072
  }
222043
- for (const warn of refsResolved.warnings) {
222044
- client.send({ type: "info", display: "toast", text: `${warn.path ?? ""}: ${warn.type}${warn.detail ? ` \u2014 ${warn.detail}` : ""}` });
222073
+ }
222074
+ if (cmd.fileRefs && cmd.fileRefs.length > 0) {
222075
+ const imageRefs = cmd.fileRefs.filter((f) => isImagePath(f));
222076
+ const nonImageRefs = cmd.fileRefs.filter((f) => !isImagePath(f));
222077
+ if (nonImageRefs.length > 0) {
222078
+ const pathLines = nonImageRefs.map((f) => `- \`${f}\``).join("\n");
222079
+ text = text ? `${text}
222080
+
222081
+ \u{1F4C1} Attached files:
222082
+ ${pathLines}` : `\u{1F4C1} Attached files:
222083
+ ${pathLines}`;
222084
+ }
222085
+ if (imageRefs.length > 0) {
222086
+ const refsResolved = resolveFileRefs(this.config.projectPath, imageRefs, this.config.atFile ?? {});
222087
+ if (!refsResolved.reject) {
222088
+ if (refsResolved.text) {
222089
+ text = text ? `${text}
222090
+
222091
+ ${refsResolved.text}` : refsResolved.text;
222092
+ }
222093
+ if (refsResolved.images.length > 0) {
222094
+ const refImages = refsResolved.images.map((img) => ({
222095
+ data: img.data,
222096
+ mimeType: img.mimeType
222097
+ }));
222098
+ images = [...images ?? [], ...refImages];
222099
+ }
222100
+ }
222101
+ for (const warn of refsResolved.warnings) {
222102
+ client.send({ type: "info", display: "toast", text: `${warn.path ?? ""}: ${warn.type}${warn.detail ? ` \u2014 ${warn.detail}` : ""}` });
222103
+ }
222045
222104
  }
222046
222105
  }
222047
222106
  client.send({ type: "user_message", text, images: images && images.length > 0 ? images : void 0 });
@@ -222054,6 +222113,7 @@ ${refsResolved.text}` : refsResolved.text;
222054
222113
  mimeType: img.mimeType
222055
222114
  }));
222056
222115
  this.pendingImages = [];
222116
+ this.harness.logger.info("tool", "web-backend", `promptWithImages: textLen=${text.length}, images=${imageContents.length}, img[0].dataLen=${imageContents[0]?.data?.length ?? 0}, mime=${imageContents[0]?.mimeType ?? "?"}`);
222057
222117
  await this.harness.promptWithImages(text, imageContents);
222058
222118
  } else {
222059
222119
  this.pendingImages = [];
@@ -222201,12 +222261,51 @@ ${refsResolved.text}` : refsResolved.text;
222201
222261
  await this.handleArtifact(client, cmd);
222202
222262
  break;
222203
222263
  }
222264
+ case "cache": {
222265
+ this.handleCache(client, cmd);
222266
+ break;
222267
+ }
222204
222268
  case "mcp": {
222205
222269
  this.handleMcp(client, cmd);
222206
222270
  break;
222207
222271
  }
222208
222272
  }
222209
222273
  }
222274
+ handleCache(client, cmd) {
222275
+ const uploadsDir = join29(this.config.projectPath, ".dscode", "uploads");
222276
+ if (cmd.action === "clear") {
222277
+ if (existsSync24(uploadsDir)) {
222278
+ try {
222279
+ rmSync3(uploadsDir, { recursive: true, force: true });
222280
+ } catch {
222281
+ }
222282
+ }
222283
+ client.send({ type: "cache_size", totalBytes: 0, fileCount: 0, sessionCount: 0 });
222284
+ return;
222285
+ }
222286
+ let totalBytes = 0;
222287
+ let fileCount = 0;
222288
+ let sessionCount = 0;
222289
+ if (existsSync24(uploadsDir)) {
222290
+ const sessionDirs = readdirSync9(uploadsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
222291
+ sessionCount = sessionDirs.length;
222292
+ for (const dir of sessionDirs) {
222293
+ const sessionPath = join29(uploadsDir, dir.name);
222294
+ const files = readdirSync9(sessionPath, { withFileTypes: true });
222295
+ for (const f of files) {
222296
+ if (f.isFile()) {
222297
+ try {
222298
+ const st = statSync5(join29(sessionPath, f.name));
222299
+ totalBytes += st.size;
222300
+ fileCount++;
222301
+ } catch {
222302
+ }
222303
+ }
222304
+ }
222305
+ }
222306
+ }
222307
+ client.send({ type: "cache_size", totalBytes, fileCount, sessionCount });
222308
+ }
222210
222309
  async handleSlashCommand(client, text) {
222211
222310
  try {
222212
222311
  const executed = executeSlashCommand(text, { harness: this.harness, ui: this });
@@ -222598,6 +222697,7 @@ ${matchList}` });
222598
222697
  if (wasCurrent) {
222599
222698
  client.send({ type: "clear_conversation" });
222600
222699
  }
222700
+ this.cleanupUploadDir(cmd.id);
222601
222701
  client.send({ type: "info", display: "toast", text: "Session deleted." });
222602
222702
  const sessions = sessionManager.listSessions();
222603
222703
  const currentId = sessionManager.getCurrentSessionId?.() ?? void 0;
@@ -230050,6 +230150,8 @@ var TuiApp = class {
230050
230150
  attachmentScrollOffset = 0;
230051
230151
  // Pre-drained images: captured in input listener before Editor's onChange("") clears them
230052
230152
  drainedSubmitImages = null;
230153
+ // Pre-drained files: captured in input listener before Editor's onChange("") clears them
230154
+ drainedSubmitFiles = null;
230053
230155
  lastPasteTime = 0;
230054
230156
  // ── Kitty protocol multi-chunk buffer ──
230055
230157
  // Kitty transmits large images in chunks. Accumulate base64 payloads here
@@ -230125,8 +230227,13 @@ var TuiApp = class {
230125
230227
  if (pasteResult) {
230126
230228
  return pasteResult;
230127
230229
  }
230128
- if ((matchesKey(data, Key.enter) || matchesKey(data, Key.return) || data === "\r" || data === "\n") && this.imagePasteHandler.imageCount > 0 && !this.processing) {
230129
- this.drainedSubmitImages = this.imagePasteHandler.drainImages();
230230
+ if ((matchesKey(data, Key.enter) || matchesKey(data, Key.return) || data === "\r" || data === "\n") && !this.processing) {
230231
+ if (this.imagePasteHandler.imageCount > 0) {
230232
+ this.drainedSubmitImages = this.imagePasteHandler.drainImages();
230233
+ }
230234
+ if (this.fileTracker.count > 0) {
230235
+ this.drainedSubmitFiles = this.fileTracker.drain();
230236
+ }
230130
230237
  }
230131
230238
  if (this.handleInput(data)) {
230132
230239
  return { consume: true };
@@ -230921,7 +231028,8 @@ ${hintLine}`);
230921
231028
  }
230922
231029
  const hasText = text.length > 0;
230923
231030
  const hasImages = Boolean(images?.length);
230924
- const fileRefs = this.fileTracker.drain();
231031
+ const fileRefs = this.drainedSubmitFiles ?? this.fileTracker.drain();
231032
+ this.drainedSubmitFiles = null;
230925
231033
  const hasFiles = fileRefs.length > 0;
230926
231034
  if (!hasText && !hasImages && !hasFiles) {
230927
231035
  const now = Date.now();
@@ -230935,7 +231043,7 @@ ${hintLine}`);
230935
231043
  });
230936
231044
  return;
230937
231045
  }
230938
- if (!hasText && !hasImages) {
231046
+ if (!hasText && !hasImages && !hasFiles) {
230939
231047
  const now = Date.now();
230940
231048
  if (now - this.lastPasteTime < 100) return;
230941
231049
  this.lastPasteTime = now;
@@ -231022,23 +231130,33 @@ ${hintLine}`);
231022
231130
  images = [...images ?? [], ...atImages];
231023
231131
  }
231024
231132
  if (hasFiles) {
231025
- const dedupedFileRefs = fileRefs.filter((f) => !atPathAbsPaths.has(f));
231026
- if (dedupedFileRefs.length > 0) {
231027
- const refsResolved = resolveFileRefs(this.deps.config.projectPath, dedupedFileRefs, this.deps.config.atFile ?? {});
231028
- if (refsResolved.warnings.length > 0) {
231029
- for (const warn of refsResolved.warnings) {
231030
- this.conversation.addInfo(c.yellow(`${warn.path ?? ""}: ${warn.type}${warn.detail ? ` \u2014 ${warn.detail}` : ""}`));
231031
- }
231032
- }
231133
+ const imageRefs = fileRefs.filter((f) => isImagePath(f));
231134
+ const nonImageRefs = fileRefs.filter((f) => !isImagePath(f));
231135
+ if (nonImageRefs.length > 0) {
231136
+ const pathLines = nonImageRefs.map((f) => `- \`${f}\``).join("\n");
231033
231137
  text = text ? `${text}
231034
- ${refsResolved.text}` : refsResolved.text;
231035
- if (refsResolved.images.length > 0) {
231036
- const refImages = refsResolved.images.map((img) => ({
231037
- type: "image",
231038
- data: img.data,
231039
- mimeType: img.mimeType
231040
- }));
231041
- images = [...images ?? [], ...refImages];
231138
+
231139
+ \u{1F4C1} Attached files:
231140
+ ${pathLines}` : `\u{1F4C1} Attached files:
231141
+ ${pathLines}`;
231142
+ }
231143
+ if (imageRefs.length > 0) {
231144
+ const dedupedImageRefs = imageRefs.filter((f) => !atPathAbsPaths.has(f));
231145
+ if (dedupedImageRefs.length > 0) {
231146
+ const refsResolved = resolveFileRefs(this.deps.config.projectPath, dedupedImageRefs, this.deps.config.atFile ?? {});
231147
+ if (refsResolved.warnings.length > 0) {
231148
+ for (const warn of refsResolved.warnings) {
231149
+ this.conversation.addInfo(c.yellow(`${warn.path ?? ""}: ${warn.type}${warn.detail ? ` \u2014 ${warn.detail}` : ""}`));
231150
+ }
231151
+ }
231152
+ if (refsResolved.images.length > 0) {
231153
+ const refImages = refsResolved.images.map((img) => ({
231154
+ type: "image",
231155
+ data: img.data,
231156
+ mimeType: img.mimeType
231157
+ }));
231158
+ images = [...images ?? [], ...refImages];
231159
+ }
231042
231160
  }
231043
231161
  }
231044
231162
  }
@@ -231264,6 +231382,8 @@ async function ocrImages(images, signal) {
231264
231382
  // src/drivers/vision/client.ts
231265
231383
  init_models();
231266
231384
  init_models();
231385
+ init_logger();
231386
+ var _clog = new Logger({ type: "harness", id: process.env.DSCODE_RUNTIME_ID ?? "vision-client" });
231267
231387
  function resolveVisionModel(visionConfig, fallbackApiKey, onWarning) {
231268
231388
  if (!visionConfig?.provider || !visionConfig?.model) return null;
231269
231389
  try {
@@ -231311,11 +231431,15 @@ async function describeImagesViaVisionModel(images, visionModel, apiKey, signal)
231311
231431
  if (err instanceof DOMException && err.name === "AbortError") {
231312
231432
  throw err;
231313
231433
  }
231434
+ const errMsg = err instanceof Error ? err.message : String(err);
231435
+ _clog.warn("tool", "vision-client", `describeImages FAILED: ${errMsg}. images=${images.length}, totalBase64=${images.reduce((s, i) => s + (i.data?.length ?? 0), 0)}, img[0].mime=${images[0]?.mimeType ?? "?"}`);
231314
231436
  throw err;
231315
231437
  }
231316
231438
  }
231317
231439
 
231318
231440
  // src/drivers/vision/pipeline.ts
231441
+ init_logger();
231442
+ var _plog = new Logger({ type: "harness", id: process.env.DSCODE_RUNTIME_ID ?? "pipeline" });
231319
231443
  var ImagePipeline = class {
231320
231444
  visionConfig;
231321
231445
  fallbackApiKey;
@@ -231344,12 +231468,15 @@ var ImagePipeline = class {
231344
231468
  onProgress?.({ phase: "compressing", cachedRefs: [] });
231345
231469
  const cachedRefs = await Promise.all(normalizedImages.map((img) => ImageCache.put(img)));
231346
231470
  onProgress?.({ phase: "compressing", cachedRefs });
231471
+ const compressedRaw = await Promise.all(cachedRefs.map((ref) => ImageCache.get(ref)));
231472
+ const compressedImages = compressedRaw.every((img) => img !== null) ? compressedRaw : normalizedImages;
231347
231473
  if (signal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
231348
231474
  const vision = resolveVisionModel(this.visionConfig, this.fallbackApiKey, this.onWarning);
231475
+ _plog.info("tool", "image-pipeline", `vision resolved: ${vision ? `${vision.model.provider}/${vision.model.id}` : "null \u2014 falling to OCR"}, images=${normalizedImages.length}, img[0].dataLen=${normalizedImages[0]?.data?.length ?? 0}, mime=${normalizedImages[0]?.mimeType ?? "?"}`);
231349
231476
  if (vision) {
231350
231477
  try {
231351
231478
  onProgress?.({ phase: "describing", cachedRefs });
231352
- const description = await describeImagesViaVisionModel(normalizedImages, vision.model, vision.apiKey, signal);
231479
+ const description = await describeImagesViaVisionModel(compressedImages, vision.model, vision.apiKey, signal);
231353
231480
  if (!description || description.trim().length === 0) {
231354
231481
  throw new Error("Vision model returned empty description");
231355
231482
  }
@@ -231366,13 +231493,16 @@ ${description}
231366
231493
  if (err instanceof DOMException && err.name === "AbortError") {
231367
231494
  throw err;
231368
231495
  }
231369
- this.onWarning(`Vision model failed: ${err instanceof Error ? err.message : String(err)}. Falling back to OCR.`);
231496
+ const errMsg = err instanceof Error ? err.message : String(err);
231497
+ _plog.warn("tool", "image-pipeline", `vision FAILED: ${errMsg}. img[0].dataLen=${normalizedImages[0]?.data?.length ?? 0}, mime=${normalizedImages[0]?.mimeType ?? "?"}, preview=${normalizedImages[0]?.data?.slice(0, 80) ?? "?"}`);
231498
+ this.onWarning(`Vision model failed: ${errMsg}. Falling back to OCR.`);
231370
231499
  }
231371
231500
  }
231501
+ _plog.info("tool", "image-pipeline", `entering OCR fallback, images=${normalizedImages.length}`);
231372
231502
  if (signal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
231373
231503
  try {
231374
231504
  onProgress?.({ phase: "ocr", cachedRefs });
231375
- const result = await ocrImages(normalizedImages, signal);
231505
+ const result = await ocrImages(compressedImages, signal);
231376
231506
  onProgress?.({ phase: "done", cachedRefs });
231377
231507
  if (result.hasText) {
231378
231508
  const ocrText = text ? `${text}
@@ -232185,12 +232315,12 @@ You have a \`skill\` tool available. When you decide to use a skill from the lis
232185
232315
  const hash = String(prompt.length);
232186
232316
  if (hash === this.debugPromptLastHash) return;
232187
232317
  this.debugPromptLastHash = hash;
232188
- const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync14 } = await import("node:fs");
232318
+ const { mkdirSync: mkdirSync14, writeFileSync: writeFileSync15 } = await import("node:fs");
232189
232319
  const { join: join31 } = await import("node:path");
232190
232320
  const dumpDir = join31(this.config.projectPath, "dump");
232191
- mkdirSync13(dumpDir, { recursive: true });
232321
+ mkdirSync14(dumpDir, { recursive: true });
232192
232322
  const filePath = join31(dumpDir, "system-prompt.md");
232193
- writeFileSync14(filePath, prompt, "utf8");
232323
+ writeFileSync15(filePath, prompt, "utf8");
232194
232324
  process.stderr.write("\n[dscode] --debug: system prompt dumped to " + filePath + " (" + prompt.length + " chars)\n\n");
232195
232325
  }
232196
232326
  makeSkillTool() {
@@ -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)}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.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}.user-msg{display:flex;flex-direction:column;align-items:flex-end;gap:6px;animation:fade-up .6s cubic-bezier(.16,1,.3,1) forwards}.user-msg .content{max-width:80%;font-size:15px;line-height:1.5;padding:10px 18px;background:var(--color-user-bubble);color:var(--color-user-bubble-text);border-radius:16px 16px 4px}.user-msg .meta{font-size:10px;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;font-weight:500}.assistant-msg{display:flex;flex-direction:column;gap:16px;animation:fade-up .6s cubic-bezier(.16,1,.3,1) forwards}.assistant-msg .meta{font-size:10px;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;font-weight:500}.thinking{font-size:13px;color:var(--color-text-muted);font-style:italic;line-height:1.55;padding-left:12px;border-left:2px solid var(--color-border);transition:border-color .3s}.thinking:hover{border-left-color:var(--color-accent)}.thinking .label .dot{width:5px;height:5px;border-radius:50%;background:var(--color-accent);opacity:.6}.thinking-body{max-height:500px;overflow:hidden;transition:max-height .3s ease,opacity .3s ease}.thinking.collapsed .thinking-body{max-height:0;opacity:0}.thinking.\!collapsed .thinking-body{max-height:0!important;opacity:0!important}.thinking .label{font-size:10px;font-style:normal;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-text-muted);margin-bottom:4px;display:flex;align-items:center;gap:6px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.tool-card{background:var(--color-surface);border:1px solid var(--color-border);border-radius:6px;overflow:hidden;transition:background .15s}.tool-card:hover{background:var(--color-surface-hover)}.tool-card.mcp{border-left:2px solid var(--color-accent)}.tool-card-header{display:flex;align-items:center;gap:10px;padding:8px 14px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.tool-card-header .status{font-size:11px;width:18px;height:18px;display:flex;align-items:center;justify-content:center;border-radius:4px;font-weight:700;flex-shrink:0}.tool-card-header .status.ok{background:var(--color-success);color:var(--color-success-text)}.tool-card-header .status.err{background:var(--color-error);color:var(--color-error-text)}.tool-card-header .name{font-family:Geist Mono,JetBrains Mono,monospace;font-size:11px;font-weight:600;color:var(--color-accent)}.exec-card{margin:8px 14px;padding:12px;border-radius:8px;border:1px solid var(--color-border);background:var(--color-surface);display:flex;flex-direction:column;gap:10px}.exec-card-top{display:flex;align-items:center;justify-content:space-between}.exec-card-label{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:600;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em}.exec-pulse-dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--color-accent);animation:exec-pulse 1.5s ease-in-out infinite}@keyframes exec-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.3;transform:scale(1.3)}}.exec-elapsed{font-family:Geist Mono,monospace;font-size:10px;color:var(--color-text-muted);flex-shrink:0}.exec-waiting-text{font-family:Geist Sans,sans-serif;font-size:12px;color:var(--color-text-muted);font-style:italic}.exec-progress-section{display:flex;flex-direction:column;gap:4px}.exec-progress-footer{display:flex;align-items:center;justify-content:space-between}.tool-card-header .args{font-size:11px;color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.tool-card-header .arrow{font-size:9px;color:var(--color-text-muted);transition:transform .3s;opacity:.4;flex-shrink:0}.tool-card.open .tool-card-header .arrow{transform:rotate(180deg)}.tool-card.\!open .tool-card-header .arrow{transform:rotate(180deg)!important}.tool-card-body{max-height:0;overflow:hidden;transition:max-height .3s ease}.tool-card.open .tool-card-body{max-height:500px}.tool-card.\!open .tool-card-body{max-height:500px!important}.tool-card-body-inner{padding:2px 14px 6px;margin-top:0;max-height:400px;background:var(--color-bg);overflow-y:auto}.mcp-badge{display:inline-block;font-family:Geist Mono,JetBrains Mono,monospace;font-size:8px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;padding:1px 5px;border-radius:3px;background:var(--color-accent-bg);color:var(--color-accent);flex-shrink:0}.mcp-rich-list{display:flex;flex-direction:column}.mcp-rich-item{padding:12px 14px;background:var(--color-bg);border-bottom:1px solid var(--color-border);transition:background .15s;font-family:Inter,system-ui,sans-serif}.mcp-rich-item:last-child{border-bottom:none}.mcp-rich-item:hover{background:var(--color-surface-hover)}.mcp-rich-item .r-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:6px}.mcp-rich-item .r-title{font-size:13px;font-weight:600;color:var(--color-text);line-height:1.4}.mcp-rich-item .r-score{flex-shrink:0;font-family:Geist Mono,JetBrains Mono,monospace;font-size:9px;font-weight:600;padding:2px 7px;border-radius:10px;background:var(--color-success);color:var(--color-success-text);white-space:nowrap;margin-top:2px}.mcp-rich-item .r-url{font-family:Geist Mono,JetBrains Mono,monospace;font-size:10px;color:var(--color-accent);opacity:.7;margin-bottom:6px;word-break:break-all}.mcp-rich-item .r-content{font-size:12px;color:var(--color-text-muted);line-height:1.55}.mcp-rich-item .r-content p+p{margin-top:4px}.mcp-rich-item .r-meta-row{display:flex;align-items:center;gap:12px;margin-top:8px;font-size:10px;color:var(--color-text-muted)}.mcp-raw-block{padding:2px 14px 6px;max-height:280px;overflow-y:auto;background:var(--color-bg)}.text-response{font-size:15px;line-height:1.7;color:var(--color-text);max-width:85%}.text-response p+p{margin-top:8px}.text-response code{font-family:Geist Mono,JetBrains Mono,monospace;font-size:12.5px;background:var(--color-accent-bg);color:var(--color-accent);padding:1px 5px;border-radius:3px}.text-response strong{font-weight:600}.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)}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.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-1{margin-top:.25rem;margin-bottom:.25rem}.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-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.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-48{max-height:12rem}.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-4{width:1rem}.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}.gap-4{gap:1rem}.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-0{border-width:0px}.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-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}.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}.ring{--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(3px + 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)}.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}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}: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-accent-bg: rgba(202, 138, 4, .12);--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-bg: rgba(212, 151, 8, .15);--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}.md-pre-base{border-radius:8px;background-color:var(--color-bg);border:1px solid var(--color-border);color:var(--color-text)}.tool-card-body-inner .md-pre-base{padding:6px 10px;margin:0;border:none;border-radius:4px}@media (max-width: 767px){.resize-handle{display:none}}.progress-container{padding:8px 14px;border-top:1px solid var(--color-border);display:flex;flex-direction:column;gap:4px;transition:opacity .6s ease}.progress-container.progress-fade-out{opacity:0;pointer-events:none}.progress-bar{height:4px;border-radius:2px;background:var(--color-surface-hover);overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent);border-radius:2px;transition:width .3s ease}.progress-fill.indeterminate{width:30%!important;animation:progress-indeterminate 1.5s ease-in-out infinite}.progress-text{font-family:Geist Mono,monospace;font-size:10px;color:var(--color-text-muted);text-align:right}.progress-message{font-family:Geist Sans,sans-serif;font-size:11px;color:var(--color-text-muted);line-height:1.4}.mini-progress-bar{display:inline-flex;align-items:center;gap:4px;margin:0 4px;flex-shrink:0}.mini-progress-bar-track{width:72px;height:2px;border-radius:1px;background:var(--color-border);overflow:hidden;position:relative;flex-shrink:0}.mini-progress-fill{position:absolute;left:0;top:0;height:100%;background:var(--color-accent);border-radius:1px;transition:width .3s ease}.mini-progress-fill.indeterminate{animation:progress-indeterminate 1.5s ease-in-out infinite}.mini-progress-text{font-family:Geist Mono,monospace;font-size:9px;color:var(--color-text-muted);flex-shrink:0}@keyframes progress-indeterminate{0%{left:0%;width:30%}50%{left:70%;width:30%}to{left:0%;width:30%}}.status.spinner{animation:spin 1.2s linear infinite;color:var(--color-accent)}@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}.view-fade-enter{animation:view-fade-in .3s ease-out forwards}@keyframes view-fade-in{0%{opacity:0}to{opacity:1}}@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))}}