farming-code 2.2.12 → 2.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +1 -1
  2. package/README.zh_cn.md +1 -1
  3. package/backend/agent-manager.js +4 -0
  4. package/backend/server.js +10 -0
  5. package/dist/assets/{App-DWsa7DXG.js → App-xASd_Y0F.js} +3 -3
  6. package/dist/assets/{index-CUFPJoa5.js → index-CYZKdoqi.js} +2 -2
  7. package/dist/crt-markdown-assets/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
  8. package/dist/crt-markdown-assets/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
  9. package/dist/crt-markdown-assets/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  10. package/dist/crt-markdown-assets/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  11. package/dist/crt-markdown-assets/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
  12. package/dist/crt-markdown-assets/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
  13. package/dist/crt-markdown-assets/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
  14. package/dist/crt-markdown-assets/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
  15. package/dist/crt-markdown-assets/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  16. package/dist/crt-markdown-assets/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  17. package/dist/crt-markdown-assets/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
  18. package/dist/crt-markdown-assets/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
  19. package/dist/crt-markdown-assets/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  20. package/dist/crt-markdown-assets/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
  21. package/dist/crt-markdown-assets/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
  22. package/dist/crt-markdown-assets/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
  23. package/dist/crt-markdown-assets/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
  24. package/dist/crt-markdown-assets/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  25. package/dist/crt-markdown-assets/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
  26. package/dist/crt-markdown-assets/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  27. package/dist/crt-markdown-assets/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
  28. package/dist/crt-markdown-assets/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
  29. package/dist/crt-markdown-assets/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  30. package/dist/crt-markdown-assets/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
  31. package/dist/crt-markdown-assets/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  32. package/dist/crt-markdown-assets/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
  33. package/dist/crt-markdown-assets/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
  34. package/dist/crt-markdown-assets/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
  35. package/dist/crt-markdown-assets/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  36. package/dist/crt-markdown-assets/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
  37. package/dist/crt-markdown-assets/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  38. package/dist/crt-markdown-assets/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
  39. package/dist/crt-markdown-assets/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
  40. package/dist/crt-markdown-assets/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  41. package/dist/crt-markdown-assets/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
  42. package/dist/crt-markdown-assets/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
  43. package/dist/crt-markdown-assets/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  44. package/dist/crt-markdown-assets/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
  45. package/dist/crt-markdown-assets/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
  46. package/dist/crt-markdown-assets/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
  47. package/dist/crt-markdown-assets/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
  48. package/dist/crt-markdown-assets/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  49. package/dist/crt-markdown-assets/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
  50. package/dist/crt-markdown-assets/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
  51. package/dist/crt-markdown-assets/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  52. package/dist/crt-markdown-assets/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
  53. package/dist/crt-markdown-assets/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  54. package/dist/crt-markdown-assets/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
  55. package/dist/crt-markdown-assets/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
  56. package/dist/crt-markdown-assets/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
  57. package/dist/crt-markdown-assets/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  58. package/dist/crt-markdown-assets/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
  59. package/dist/crt-markdown-assets/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
  60. package/dist/crt-markdown-assets/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  61. package/dist/crt-markdown-assets/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
  62. package/dist/crt-markdown-assets/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  63. package/dist/crt-markdown-assets/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
  64. package/dist/crt-markdown-assets/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
  65. package/dist/crt-markdown-assets/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
  66. package/dist/crt-markdown-assets/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  67. package/dist/crt-markdown-renderer.css +1 -0
  68. package/dist/crt-markdown-renderer.js +361 -0
  69. package/dist/crt-mermaid-renderer.js +3595 -0
  70. package/dist/index.html +1 -1
  71. package/frontend/skins/crt/app.js +53 -32
  72. package/frontend/skins/crt/index.html +47 -31
  73. package/frontend/skins/crt/styles/markdown.css +251 -0
  74. package/frontend/skins/crt/styles/monochrome-green.css +14 -3
  75. package/package.json +5 -2
package/dist/index.html CHANGED
@@ -15,7 +15,7 @@
15
15
  <link rel="apple-touch-icon" sizes="180x180" href="/farming/farming-2/app-icon-v2-180.png" />
16
16
  <link rel="manifest" href="/farming/farming-2/site.webmanifest" />
17
17
  <title>Farming 2</title>
18
- <script type="module" crossorigin src="/farming/assets/index-CUFPJoa5.js"></script>
18
+ <script type="module" crossorigin src="/farming/assets/index-CYZKdoqi.js"></script>
19
19
  <link rel="modulepreload" crossorigin href="/farming/assets/chunk-DECur_0Z.js">
20
20
  <link rel="modulepreload" crossorigin href="/farming/assets/preload-helper-mJowh_hw.js">
21
21
  <link rel="modulepreload" crossorigin href="/farming/assets/jsx-runtime-BthL93pI.js">
@@ -2209,9 +2209,10 @@ function normalizeSessionViewPayload(payload, fallbackAgent = null) {
2209
2209
  };
2210
2210
  }
2211
2211
 
2212
- function createCrtTerminalReplication(agentId) {
2212
+ function createCrtTerminalReplication(agentId, { initialFocusPending = false } = {}) {
2213
2213
  return {
2214
2214
  agentId,
2215
+ initialFocusPending,
2215
2216
  lastResizeCols: null,
2216
2217
  lastResizeRows: null,
2217
2218
  pendingFitResize: null,
@@ -2230,6 +2231,26 @@ function createCrtTerminalReplication(agentId) {
2230
2231
  };
2231
2232
  }
2232
2233
 
2234
+ function settleInitialCrtTerminalFocus(replication, terminalInstance = terminal) {
2235
+ if (!replication || replication.disposed || !replication.initialFocusPending) return false;
2236
+ replication.initialFocusPending = false;
2237
+
2238
+ const modal = document.getElementById('session-modal');
2239
+ if (!modal || !modal.classList.contains('active') || !terminalInstance) return false;
2240
+
2241
+ const activeElement = document.activeElement;
2242
+ if (activeElement?.matches?.('#terminal-output .xterm-helper-textarea')) return true;
2243
+ if (
2244
+ activeElement
2245
+ && modal.contains(activeElement)
2246
+ && activeElement.matches('button, input, textarea, select, [contenteditable="true"]')
2247
+ ) return false;
2248
+ if (hasAnySelection()) return false;
2249
+
2250
+ terminalInstance.focus?.();
2251
+ return document.activeElement?.matches?.('#terminal-output .xterm-helper-textarea') === true;
2252
+ }
2253
+
2233
2254
  function installCrtTerminalTestApi() {
2234
2255
  if (
2235
2256
  typeof window === 'undefined' ||
@@ -2251,6 +2272,7 @@ function installCrtTerminalTestApi() {
2251
2272
  writeInProgress: replication.writeInProgress,
2252
2273
  checkpointInFlight: replication.checkpointInFlight,
2253
2274
  checkpointInstallInProgress: replication.installInProgress,
2275
+ initialFocusPending: replication.initialFocusPending,
2254
2276
  pendingFitResize: replication.pendingFitResize,
2255
2277
  fitResizeTimerPending: replication.fitResizeTimer !== null
2256
2278
  };
@@ -2393,6 +2415,7 @@ function finishCrtTerminalReplay(replication = crtTerminalReplication) {
2393
2415
  if (!crtTerminalReplication || crtTerminalReplication !== replication || replication.disposed) return;
2394
2416
  document.getElementById('terminal-output')?.classList.remove('crt-terminal-checkpoint-installing');
2395
2417
  sendSessionResize(replication.agentId);
2418
+ settleInitialCrtTerminalFocus(replication);
2396
2419
  });
2397
2420
  }
2398
2421
 
@@ -6890,37 +6913,28 @@ function renderStructuredTranscript(transcript, force = false) {
6890
6913
  if (!force && updatedAt && updatedAt === structuredSessionRenderedAt) return;
6891
6914
  const nearBottom = container.scrollHeight - container.scrollTop - container.clientHeight < 80;
6892
6915
  if (!nearBottom && focusedAgentId) saveCrtStructuredReadingAnchor(focusedAgentId);
6893
- const transcriptNode = document.createElement('div');
6894
- transcriptNode.className = 'crt-structured-transcript';
6895
6916
  const turns = structuredTranscriptTurns(transcript);
6896
6917
 
6897
- if (!turns.length) {
6898
- const empty = document.createElement('div');
6899
- empty.className = 'crt-structured-empty';
6900
- empty.textContent = 'No conversation yet.';
6901
- transcriptNode.appendChild(empty);
6902
- } else {
6903
- turns.forEach((turn) => {
6904
- const section = document.createElement('section');
6905
- section.className = 'crt-structured-turn';
6906
- section.dataset.readingAnchorId = String(turn.id || `${turn.userMessage || ''}\n${turn.finalMessage || ''}`.slice(0, 160));
6907
- if (turn.userMessage) {
6908
- const user = document.createElement('p');
6909
- user.className = 'crt-structured-message user';
6910
- user.textContent = turn.userMessage;
6911
- section.appendChild(user);
6912
- }
6913
- if (turn.finalMessage) {
6914
- const assistant = document.createElement('p');
6915
- assistant.className = 'crt-structured-message assistant';
6916
- assistant.textContent = turn.finalMessage;
6917
- section.appendChild(assistant);
6918
- }
6919
- transcriptNode.appendChild(section);
6920
- });
6918
+ const markdownRenderer = typeof window !== 'undefined' ? window.FarmingCrtMarkdownRenderer : null;
6919
+ if (!markdownRenderer || typeof markdownRenderer.render !== 'function') {
6920
+ const errorNode = document.createElement('div');
6921
+ errorNode.className = 'crt-structured-error';
6922
+ errorNode.textContent = 'Markdown renderer unavailable. Rebuild Farming and reload CRT.';
6923
+ container.replaceChildren(errorNode);
6924
+ structuredSessionRenderedAt = updatedAt;
6925
+ return;
6926
+ }
6927
+ try {
6928
+ markdownRenderer.render(container, turns);
6929
+ } catch (error) {
6930
+ if (typeof markdownRenderer.unmount === 'function') markdownRenderer.unmount(container);
6931
+ const errorNode = document.createElement('div');
6932
+ errorNode.className = 'crt-structured-error';
6933
+ errorNode.textContent = error && error.message ? error.message : 'Failed to render Markdown transcript';
6934
+ container.replaceChildren(errorNode);
6935
+ structuredSessionRenderedAt = updatedAt;
6936
+ return;
6921
6937
  }
6922
-
6923
- container.replaceChildren(transcriptNode);
6924
6938
  structuredSessionRenderedAt = updatedAt;
6925
6939
  if (!focusedAgentId || !restoreCrtStructuredReadingAnchor(focusedAgentId)) {
6926
6940
  if (force || nearBottom) container.scrollTop = container.scrollHeight;
@@ -7203,7 +7217,12 @@ function teardownSessionSurface() {
7203
7217
  disposeCrtTerminalReplication();
7204
7218
  disposeTerminal();
7205
7219
  setStructuredComposerActive(false);
7206
- document.getElementById('terminal-output')?.classList.remove('crt-structured-session');
7220
+ const transcriptContainer = document.getElementById('terminal-output');
7221
+ const markdownRenderer = typeof window !== 'undefined' ? window.FarmingCrtMarkdownRenderer : null;
7222
+ if (transcriptContainer && markdownRenderer && typeof markdownRenderer.unmount === 'function') {
7223
+ markdownRenderer.unmount(transcriptContainer);
7224
+ }
7225
+ transcriptContainer?.classList.remove('crt-structured-session');
7207
7226
  if (SESSION_MODAL_BRIDGE && SESSION_MODAL_BRIDGE.resetTerminalShell) {
7208
7227
  SESSION_MODAL_BRIDGE.resetTerminalShell(document);
7209
7228
  return;
@@ -7305,7 +7324,9 @@ async function openSession(agentId) {
7305
7324
 
7306
7325
  disposeTerminal();
7307
7326
  disposeCrtTerminalReplication();
7308
- crtTerminalReplication = createCrtTerminalReplication(agentId);
7327
+ crtTerminalReplication = createCrtTerminalReplication(agentId, {
7328
+ initialFocusPending: interactiveTerminal,
7329
+ });
7309
7330
  let mountedTerminal = null;
7310
7331
  try {
7311
7332
  mountedTerminal = SESSION_MODAL_BRIDGE && SESSION_MODAL_BRIDGE.mountTerminal
@@ -7326,7 +7347,7 @@ async function openSession(agentId) {
7326
7347
  sendSessionResize(agentId);
7327
7348
  },
7328
7349
  hasSelection: hasAnySelection,
7329
- focusTerminal: focusSessionTerminal,
7350
+ focusTerminal: () => terminalBundle.terminal?.focus?.(),
7330
7351
  isSessionActive: () => runtime ? runtime.isCurrentSession(agentId, sessionToken) : focusedAgentId === agentId,
7331
7352
  afterFit: () => {
7332
7353
  if (runtime && !runtime.isCurrentSession(agentId, sessionToken)) return;
@@ -7,6 +7,8 @@
7
7
  <link rel="icon" type="image/svg+xml" href="assets/branding/farming-crt-icon.svg">
8
8
  <link rel="stylesheet" href="../vendor/xterm/xterm.css">
9
9
  <link rel="stylesheet" href="styles/effects.css">
10
+ <link rel="stylesheet" href="crt-markdown-renderer.css">
11
+ <link rel="stylesheet" href="styles/markdown.css">
10
12
  <style>
11
13
  * {
12
14
  margin: 0;
@@ -196,7 +198,7 @@
196
198
  justify-content: space-between;
197
199
  gap: 8px;
198
200
  min-height: 11px;
199
- font-size: 9px;
201
+ font-size: 10px;
200
202
  line-height: 1;
201
203
  letter-spacing: 0.12em;
202
204
  opacity: 0.62;
@@ -242,8 +244,8 @@
242
244
  gap: 6px;
243
245
  flex: 0 0 auto;
244
246
  min-width: 0;
245
- font-size: 11px;
246
- line-height: 1.28;
247
+ font-size: 12px;
248
+ line-height: 1.3;
247
249
  }
248
250
 
249
251
  .agent-chat-preview-line::before {
@@ -261,7 +263,7 @@
261
263
 
262
264
  .agent-chat-preview-role {
263
265
  padding-top: 1px;
264
- font-size: 9px;
266
+ font-size: 10px;
265
267
  letter-spacing: 0.08em;
266
268
  opacity: 0.56;
267
269
  }
@@ -293,7 +295,7 @@
293
295
 
294
296
  .agent-chat-preview-empty {
295
297
  padding: 7px 0 3px;
296
- font-size: 10px;
298
+ font-size: 11px;
297
299
  letter-spacing: 0.08em;
298
300
  opacity: 0.58;
299
301
  }
@@ -415,6 +417,8 @@
415
417
  flex-wrap: nowrap;
416
418
  flex-shrink: 0;
417
419
  min-width: 0;
420
+ font-size: 14px;
421
+ line-height: 18px;
418
422
  }
419
423
 
420
424
  .modal-header span {
@@ -440,18 +444,18 @@
440
444
 
441
445
  #farming-crt .session-header-actions > .kill-btn,
442
446
  #farming-crt .session-header-actions > .close-btn {
443
- height: 38px;
447
+ height: 34px;
444
448
  margin-left: 0;
445
- padding: 0 14px;
446
- font-size: 16px;
449
+ padding: 0 12px;
450
+ font-size: 14px;
447
451
  line-height: 1;
448
452
  }
449
453
 
450
454
  #farming-crt .crt-runtime-control {
451
455
  display: inline-flex;
452
456
  align-items: stretch;
453
- height: 38px;
454
- min-height: 38px;
457
+ height: 34px;
458
+ min-height: 34px;
455
459
  margin: 0;
456
460
  overflow: hidden;
457
461
  border: 1px solid var(--crt-phosphor, #00cc66);
@@ -461,7 +465,7 @@
461
465
  0 0 7px rgba(0, 255, 102, 0.24),
462
466
  inset 0 0 7px rgba(0, 255, 102, 0.08);
463
467
  font-family: var(--crt-font, 'Courier New', monospace);
464
- font-size: 16px;
468
+ font-size: 14px;
465
469
  line-height: 1;
466
470
  white-space: nowrap;
467
471
  text-shadow: none;
@@ -483,7 +487,7 @@
483
487
  }
484
488
 
485
489
  #farming-crt .crt-runtime-control button {
486
- width: 46px;
490
+ width: 42px;
487
491
  padding: 0;
488
492
  color: var(--crt-phosphor, #00cc66);
489
493
  background: #030806;
@@ -514,7 +518,7 @@
514
518
  }
515
519
 
516
520
  #farming-crt .crt-command-shortcut {
517
- padding: 0 15px;
521
+ padding: 0 12px;
518
522
  color: var(--crt-phosphor-bright, #55f59b);
519
523
  background: #030806;
520
524
  font-size: inherit;
@@ -624,11 +628,14 @@
624
628
  .terminal.crt-structured-session {
625
629
  display: block;
626
630
  overflow-y: auto;
627
- padding: 18px 22px;
631
+ padding: 14px 20px;
628
632
  scrollbar-gutter: stable;
629
633
  scrollbar-width: thin;
630
634
  scrollbar-color: rgba(12, 204, 104, 0.46) transparent;
631
635
  outline: none;
636
+ font-family: var(--crt-terminal-font);
637
+ font-size: var(--crt-chat-font-size);
638
+ line-height: var(--crt-chat-line-height);
632
639
  }
633
640
 
634
641
  .terminal.crt-structured-session::-webkit-scrollbar {
@@ -658,7 +665,7 @@
658
665
 
659
666
  .crt-structured-transcript {
660
667
  display: grid;
661
- gap: 18px;
668
+ gap: 14px;
662
669
  position: relative;
663
670
  z-index: 1;
664
671
  white-space: pre-wrap;
@@ -667,15 +674,17 @@
667
674
 
668
675
  .crt-structured-turn {
669
676
  display: grid;
670
- gap: 8px;
671
- padding-bottom: 18px;
677
+ gap: 6px;
678
+ padding-bottom: 14px;
672
679
  border-bottom: 1px solid rgba(0, 255, 0, 0.22);
673
680
  }
674
681
 
675
682
  .crt-structured-message {
676
683
  margin: 0;
677
684
  color: #00cc66;
678
- line-height: 1.55;
685
+ font-family: var(--crt-terminal-font);
686
+ font-size: var(--crt-chat-font-size);
687
+ line-height: var(--crt-chat-line-height);
679
688
  }
680
689
 
681
690
  .crt-structured-message.user {
@@ -686,7 +695,9 @@
686
695
  display: block;
687
696
  margin-bottom: 5px;
688
697
  color: #00ff00;
689
- font-size: 11px;
698
+ font-family: var(--crt-font);
699
+ font-size: var(--crt-meta-font-size);
700
+ line-height: 1;
690
701
  }
691
702
 
692
703
  .crt-structured-message.user::before { content: "[USER]"; }
@@ -704,12 +715,15 @@
704
715
  .crt-structured-composer {
705
716
  display: none;
706
717
  grid-template-columns: 1fr auto;
707
- gap: 10px;
718
+ gap: 8px;
708
719
  align-items: end;
709
720
  flex: 0 0 auto;
710
- padding: 10px;
721
+ padding: 8px 10px;
711
722
  border-top: 1px solid #00ff00;
712
723
  background: #07110b;
724
+ font-family: var(--crt-terminal-font);
725
+ font-size: var(--crt-chat-font-size);
726
+ line-height: var(--crt-chat-line-height);
713
727
  }
714
728
 
715
729
  .crt-structured-composer.active {
@@ -802,7 +816,7 @@
802
816
  display: block;
803
817
  margin: 3px 0 0;
804
818
  color: #7d9b86;
805
- font-size: 11px;
819
+ font-size: var(--crt-meta-font-size);
806
820
  }
807
821
 
808
822
  .crt-structured-menu-item small {
@@ -828,7 +842,7 @@
828
842
  align-items: center;
829
843
  gap: 8px;
830
844
  color: #72f7c1;
831
- font-size: 11px;
845
+ font-size: var(--crt-meta-font-size);
832
846
  }
833
847
 
834
848
  .crt-structured-attachment button {
@@ -852,8 +866,8 @@
852
866
  .crt-structured-composer textarea {
853
867
  width: 100%;
854
868
  min-width: 0;
855
- min-height: 48px;
856
- max-height: 168px;
869
+ min-height: 40px;
870
+ max-height: 140px;
857
871
  resize: none;
858
872
  padding: 0;
859
873
  border: 0;
@@ -861,7 +875,7 @@
861
875
  color: #72f7c1;
862
876
  background: transparent;
863
877
  font: inherit;
864
- line-height: 1.4;
878
+ line-height: var(--crt-chat-line-height);
865
879
  overflow-y: hidden;
866
880
  }
867
881
 
@@ -879,9 +893,9 @@
879
893
  }
880
894
 
881
895
  #farming-crt #crt-structured-send {
882
- min-width: 132px;
883
- min-height: 34px;
884
- margin: 0 0 7px;
896
+ min-width: 120px;
897
+ min-height: 32px;
898
+ margin: 0 0 5px;
885
899
  padding: 5px 12px;
886
900
  border: 1px solid #00ff00;
887
901
  border-radius: 0;
@@ -925,7 +939,8 @@
925
939
  .crt-structured-composer-status {
926
940
  grid-column: 1 / -1;
927
941
  color: #7d9b86;
928
- font-size: 11px;
942
+ font-size: var(--crt-meta-font-size);
943
+ line-height: 16px;
929
944
  }
930
945
 
931
946
  .crt-structured-composer-status::after {
@@ -952,7 +967,7 @@
952
967
  .crt-structured-composer-usage {
953
968
  margin-left: auto;
954
969
  color: #7d9b86;
955
- font-size: 11px;
970
+ font-size: var(--crt-meta-font-size);
956
971
  }
957
972
 
958
973
  .crt-structured-file-input {
@@ -1996,6 +2011,7 @@
1996
2011
  <script src="shared/session-bridge.js"></script>
1997
2012
  <script src="shared/session-modal-bridge.js"></script>
1998
2013
  <script type="module" src="shared/ghostty-loader.js"></script>
2014
+ <script src="crt-markdown-renderer.js"></script>
1999
2015
  <script src="effects.js"></script>
2000
2016
  <script src="app.js"></script>
2001
2017
  </body>
@@ -0,0 +1,251 @@
1
+ #farming-crt .crt-markdown {
2
+ min-width: 0;
3
+ color: inherit;
4
+ font-family: var(--crt-terminal-font);
5
+ font-size: var(--crt-chat-font-size);
6
+ line-height: var(--crt-chat-line-height);
7
+ white-space: normal;
8
+ overflow-wrap: anywhere;
9
+ }
10
+
11
+ #farming-crt .crt-markdown > :first-child {
12
+ margin-top: 0;
13
+ }
14
+
15
+ #farming-crt .crt-markdown > :last-child {
16
+ margin-bottom: 0;
17
+ }
18
+
19
+ #farming-crt .crt-markdown p,
20
+ #farming-crt .crt-markdown ul,
21
+ #farming-crt .crt-markdown ol,
22
+ #farming-crt .crt-markdown pre,
23
+ #farming-crt .crt-markdown blockquote,
24
+ #farming-crt .crt-markdown table,
25
+ #farming-crt .crt-markdown hr {
26
+ margin: 0 0 8px;
27
+ }
28
+
29
+ #farming-crt .crt-markdown h1,
30
+ #farming-crt .crt-markdown h2,
31
+ #farming-crt .crt-markdown h3,
32
+ #farming-crt .crt-markdown h4,
33
+ #farming-crt .crt-markdown h5,
34
+ #farming-crt .crt-markdown h6 {
35
+ margin: 14px 0 7px;
36
+ color: #55f59b;
37
+ font-family: inherit;
38
+ font-weight: 700;
39
+ line-height: 1.25;
40
+ }
41
+
42
+ #farming-crt .crt-markdown h1 {
43
+ font-size: 20px;
44
+ }
45
+
46
+ #farming-crt .crt-markdown h2 {
47
+ font-size: 18px;
48
+ }
49
+
50
+ #farming-crt .crt-markdown h3 {
51
+ font-size: 16px;
52
+ }
53
+
54
+ #farming-crt .crt-markdown h4,
55
+ #farming-crt .crt-markdown h5,
56
+ #farming-crt .crt-markdown h6 {
57
+ font-size: 14px;
58
+ }
59
+
60
+ #farming-crt .crt-markdown ul,
61
+ #farming-crt .crt-markdown ol {
62
+ padding-left: 1.55em;
63
+ }
64
+
65
+ #farming-crt .crt-markdown li + li {
66
+ margin-top: 3px;
67
+ }
68
+
69
+ #farming-crt .crt-markdown a {
70
+ color: #72d7ff;
71
+ text-decoration: underline;
72
+ text-underline-offset: 0.18em;
73
+ }
74
+
75
+ #farming-crt .crt-markdown blockquote {
76
+ padding-left: 0.9em;
77
+ border-left: 2px solid rgba(85, 245, 155, 0.55);
78
+ color: #9fcab2;
79
+ }
80
+
81
+ #farming-crt .crt-markdown :not(pre) > code {
82
+ padding: 0.08em 0.32em;
83
+ border: 1px solid rgba(85, 245, 155, 0.28);
84
+ background: rgba(0, 255, 102, 0.07);
85
+ color: #f0c36e;
86
+ font-family: inherit;
87
+ font-size: 0.92em;
88
+ line-height: inherit;
89
+ }
90
+
91
+ #farming-crt .crt-markdown pre {
92
+ max-width: 100%;
93
+ padding: 8px 10px;
94
+ overflow: auto;
95
+ border: 1px solid rgba(85, 245, 155, 0.3);
96
+ background: rgba(0, 12, 7, 0.72);
97
+ color: #b9e6cb;
98
+ white-space: pre;
99
+ font-size: 13px;
100
+ line-height: 19px;
101
+ text-shadow: none;
102
+ }
103
+
104
+ #farming-crt .crt-markdown pre code {
105
+ padding: 0;
106
+ border: 0;
107
+ background: transparent;
108
+ color: inherit;
109
+ font-family: inherit;
110
+ font-size: inherit;
111
+ line-height: inherit;
112
+ }
113
+
114
+ #farming-crt .crt-markdown table {
115
+ display: block;
116
+ max-width: 100%;
117
+ overflow: auto;
118
+ border-collapse: collapse;
119
+ white-space: normal;
120
+ font-size: 13px;
121
+ line-height: 18px;
122
+ }
123
+
124
+ #farming-crt .crt-markdown th,
125
+ #farming-crt .crt-markdown td {
126
+ padding: 4px 8px;
127
+ border: 1px solid rgba(85, 245, 155, 0.3);
128
+ text-align: left;
129
+ }
130
+
131
+ #farming-crt .crt-markdown th {
132
+ color: #55f59b;
133
+ }
134
+
135
+ #farming-crt .crt-markdown img {
136
+ max-width: 100%;
137
+ height: auto;
138
+ }
139
+
140
+ #farming-crt .crt-markdown hr {
141
+ border: 0;
142
+ border-top: 1px solid rgba(85, 245, 155, 0.35);
143
+ }
144
+
145
+ #farming-crt .crt-markdown .katex {
146
+ color: #b9e6cb;
147
+ text-shadow: none;
148
+ }
149
+
150
+ #farming-crt .crt-markdown .katex-display {
151
+ max-width: 100%;
152
+ margin: 0 0 0.9em;
153
+ padding: 0.25em 0;
154
+ overflow-x: auto;
155
+ overflow-y: hidden;
156
+ }
157
+
158
+ #farming-crt .crt-markdown-mermaid {
159
+ min-height: 72px;
160
+ margin: 0 0 0.9em;
161
+ padding: 12px 14px;
162
+ overflow: auto;
163
+ border: 1px solid rgba(85, 245, 155, 0.3);
164
+ background: rgba(0, 12, 7, 0.72);
165
+ text-shadow: none;
166
+ }
167
+
168
+ #farming-crt .crt-markdown-mermaid-loading {
169
+ color: #7d9b86;
170
+ }
171
+
172
+ #farming-crt .crt-markdown-mermaid-canvas {
173
+ min-width: max-content;
174
+ }
175
+
176
+ #farming-crt .crt-markdown-mermaid-canvas svg {
177
+ display: block;
178
+ max-width: 100%;
179
+ height: auto;
180
+ margin: 0 auto;
181
+ }
182
+
183
+ #farming-crt .crt-markdown-mermaid.error {
184
+ border-color: rgba(255, 107, 107, 0.55);
185
+ }
186
+
187
+ #farming-crt .crt-markdown-mermaid.error figcaption {
188
+ margin-bottom: 0.55em;
189
+ color: #ff6b6b;
190
+ }
191
+
192
+ #farming-crt .crt-markdown-mermaid-error {
193
+ color: #ffa198;
194
+ white-space: pre-wrap;
195
+ }
196
+
197
+ #farming-crt .crt-markdown-mermaid-fallback {
198
+ margin-bottom: 0;
199
+ }
200
+
201
+ #farming-crt .crt-markdown .hljs-comment,
202
+ #farming-crt .crt-markdown .hljs-quote {
203
+ color: #7d9b86;
204
+ }
205
+
206
+ #farming-crt .crt-markdown .hljs-keyword,
207
+ #farming-crt .crt-markdown .hljs-selector-tag,
208
+ #farming-crt .crt-markdown .hljs-literal,
209
+ #farming-crt .crt-markdown .hljs-section,
210
+ #farming-crt .crt-markdown .hljs-link {
211
+ color: #ff7b72;
212
+ }
213
+
214
+ #farming-crt .crt-markdown .hljs-string,
215
+ #farming-crt .crt-markdown .hljs-regexp,
216
+ #farming-crt .crt-markdown .hljs-addition,
217
+ #farming-crt .crt-markdown .hljs-attribute,
218
+ #farming-crt .crt-markdown .hljs-meta .hljs-string {
219
+ color: #a5d6ff;
220
+ }
221
+
222
+ #farming-crt .crt-markdown .hljs-number,
223
+ #farming-crt .crt-markdown .hljs-symbol,
224
+ #farming-crt .crt-markdown .hljs-bullet,
225
+ #farming-crt .crt-markdown .hljs-variable,
226
+ #farming-crt .crt-markdown .hljs-template-variable {
227
+ color: #79c0ff;
228
+ }
229
+
230
+ #farming-crt .crt-markdown .hljs-title,
231
+ #farming-crt .crt-markdown .hljs-title.class_,
232
+ #farming-crt .crt-markdown .hljs-title.function_ {
233
+ color: #d2a8ff;
234
+ }
235
+
236
+ #farming-crt .crt-markdown .hljs-attr,
237
+ #farming-crt .crt-markdown .hljs-property,
238
+ #farming-crt .crt-markdown .hljs-name,
239
+ #farming-crt .crt-markdown .hljs-tag {
240
+ color: #7ee787;
241
+ }
242
+
243
+ #farming-crt .crt-markdown .hljs-built_in,
244
+ #farming-crt .crt-markdown .hljs-type,
245
+ #farming-crt .crt-markdown .hljs-meta {
246
+ color: #ffa657;
247
+ }
248
+
249
+ #farming-crt .crt-markdown .hljs-deletion {
250
+ color: #ffa198;
251
+ }
@@ -17,6 +17,9 @@
17
17
  --crt-border: rgba(12, 204, 104, 0.76);
18
18
  --crt-font: "Departure Mono CRT", "Sarasa Mono SC", "PingFang SC", "Hiragino Sans GB", "Noto Sans Mono CJK SC", "Microsoft YaHei UI", monospace;
19
19
  --crt-terminal-font: "JetBrains Mono", "SF Mono", Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Sarasa Mono SC", "PingFang SC", "Hiragino Sans GB", "Noto Sans Mono CJK SC", "Microsoft YaHei UI", monospace;
20
+ --crt-chat-font-size: 14px;
21
+ --crt-chat-line-height: 20px;
22
+ --crt-meta-font-size: 12px;
20
23
  color: var(--crt-phosphor);
21
24
  background: var(--crt-background);
22
25
  border-color: var(--crt-phosphor);
@@ -330,17 +333,25 @@
330
333
 
331
334
  #farming-crt .agent-header {
332
335
  color: var(--crt-phosphor-bright);
336
+ font-size: 14px;
337
+ line-height: 18px;
333
338
  letter-spacing: 0.015em;
334
339
  }
335
340
 
341
+ #farming-crt .sidebar-item {
342
+ font-size: 14px;
343
+ }
344
+
336
345
  #farming-crt .agent-output {
337
346
  font-family: var(--crt-terminal-font);
338
347
  font-size: 12px;
339
348
  line-height: 1.28;
340
349
  letter-spacing: 0;
341
- text-shadow:
342
- 0 0 1px currentColor,
343
- 0 0 3px rgba(12, 204, 104, 0.22);
350
+ text-shadow: none;
351
+ }
352
+
353
+ #farming-crt .agent-chat-preview-text {
354
+ text-shadow: none;
344
355
  }
345
356
 
346
357
  #farming-crt :where(.key-hint, .agent-item .key-hint, .workspace-history-badge, .input-dialog-content button:not(.workspace-history-item):not(.secondary), .close-btn) {