@danieltmn/tamnora 0.24.2 → 0.25.1

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 (83) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/harness/packages/cli/src/commands/repl.js +18 -2
  3. package/harness/packages/cli/src/commands/run.js +5 -1
  4. package/harness/packages/cli/src/commands/tui.js +5 -1
  5. package/harness/packages/cli/src/lib/runtime.js +2 -0
  6. package/harness/packages/cli/src/tui/app.js +22 -2
  7. package/harness/packages/cli/src/tui/layout.js +1 -1
  8. package/harness/packages/core/src/agent/runAgent.js +5 -2
  9. package/harness/packages/core/src/agents/index.js +141 -0
  10. package/harness/packages/core/src/config/index.js +1 -0
  11. package/harness/packages/core/src/index.js +10 -0
  12. package/harness/packages/core/src/providers/index.js +3 -1
  13. package/harness/packages/core/src/providers/ollama.js +4 -1
  14. package/harness/packages/core/src/providers/openaiCompatible.js +6 -1
  15. package/harness/packages/core/src/providers/openrouter.js +5 -1
  16. package/harness/packages/core/src/providers/presets.js +4 -3
  17. package/harness/packages/core/src/providers/reasoning.js +58 -0
  18. package/harness/packages/core/test/agents.test.js +111 -0
  19. package/harness/packages/core/test/reasoning.test.js +43 -0
  20. package/harness/packages/server/public/app.js +868 -834
  21. package/harness/packages/server/public/appearance.js +4 -0
  22. package/harness/packages/server/public/boot.js +49 -0
  23. package/harness/packages/server/public/chat.js +1 -0
  24. package/harness/packages/server/public/chrome.js +946 -852
  25. package/harness/packages/server/public/commands.js +448 -405
  26. package/harness/packages/server/public/core.js +229 -216
  27. package/harness/packages/server/public/favicon.ico +0 -0
  28. package/harness/packages/server/public/icons/icon-128x128.png +0 -0
  29. package/harness/packages/server/public/icons/icon-144x144.png +0 -0
  30. package/harness/packages/server/public/icons/icon-152x152.png +0 -0
  31. package/harness/packages/server/public/icons/icon-192x192.png +0 -0
  32. package/harness/packages/server/public/icons/icon-384x384.png +0 -0
  33. package/harness/packages/server/public/icons/icon-512x512.png +0 -0
  34. package/harness/packages/server/public/icons/icon-72x72.png +0 -0
  35. package/harness/packages/server/public/icons/icon-96x96.png +0 -0
  36. package/harness/packages/server/public/icons/logo.png +0 -0
  37. package/harness/packages/server/public/icons/logo_dark.png +0 -0
  38. package/harness/packages/server/public/icons/logo_light.png +0 -0
  39. package/harness/packages/server/public/icons/tamnora.ico +0 -0
  40. package/harness/packages/server/public/icons (1).zip +0 -0
  41. package/harness/packages/server/public/index.html +161 -101
  42. package/harness/packages/server/public/landing/boot.js +16 -0
  43. package/harness/packages/server/public/landing/index.html +123 -59
  44. package/harness/packages/server/public/landing/landing.js +11 -9
  45. package/harness/packages/server/public/logo.png +0 -0
  46. package/harness/packages/server/public/markdown.js +1 -1
  47. package/harness/packages/server/public/sessions.js +1 -0
  48. package/harness/packages/server/public/settings.js +1322 -1080
  49. package/harness/packages/server/public/settingsNav.js +82 -0
  50. package/harness/packages/server/public/styles.css +2807 -2525
  51. package/harness/packages/server/public/system.js +2 -2
  52. package/harness/packages/server/src/lib/agents.js +74 -0
  53. package/harness/packages/server/src/lib/appearance.js +4 -0
  54. package/harness/packages/server/src/lib/channels/telegram/run.js +1 -0
  55. package/harness/packages/server/src/lib/prompt.js +11 -3
  56. package/harness/packages/server/src/lib/restart.js +20 -0
  57. package/harness/packages/server/src/lib/scheduler.js +4 -0
  58. package/harness/packages/server/src/lib/securityHeaders.js +53 -0
  59. package/harness/packages/server/src/lib/sessionView.js +1 -0
  60. package/harness/packages/server/src/lib/skills.js +13 -0
  61. package/harness/packages/server/src/lib/tasks.js +71 -23
  62. package/harness/packages/server/src/routes/agents.js +88 -0
  63. package/harness/packages/server/src/routes/chat.js +9 -1
  64. package/harness/packages/server/src/routes/providers.js +7 -0
  65. package/harness/packages/server/src/routes/reload.js +46 -0
  66. package/harness/packages/server/src/routes/sessions.js +3 -1
  67. package/harness/packages/server/src/server.js +13 -1
  68. package/harness/packages/server/test/accessibility.test.js +72 -0
  69. package/harness/packages/server/test/agents.test.js +194 -0
  70. package/harness/packages/server/test/appearance.test.js +4 -0
  71. package/harness/packages/server/test/consoleModules.test.js +133 -57
  72. package/harness/packages/server/test/consoleTabs.test.js +228 -0
  73. package/harness/packages/server/test/docsSync.test.js +73 -0
  74. package/harness/packages/server/test/landingLogin.test.js +89 -0
  75. package/harness/packages/server/test/markdownSecurity.test.js +80 -0
  76. package/harness/packages/server/test/reload.test.js +95 -0
  77. package/harness/packages/server/test/securityHeaders.test.js +109 -0
  78. package/harness/packages/server/test/settingsNav.test.js +90 -0
  79. package/harness/packages/server/test/themeCss.js +110 -0
  80. package/harness/packages/server/test/themes.test.js +72 -0
  81. package/harness/scripts/restart.mjs +101 -0
  82. package/harness/tamnora.example.json +1 -0
  83. package/package.json +1 -1
@@ -8,24 +8,7 @@
8
8
  <link rel="apple-touch-icon" href="/icons/icon-192x192.png" />
9
9
  <link rel="manifest" href="/manifest.webmanifest" />
10
10
  <meta name="theme-color" content="#231a17" />
11
- <script>
12
- (function () {
13
- var THEMES = ['paper', 'dark', 'midnight', 'nord', 'dracula', 'solarized', 'solarized-dark', 'bosque', 'vino', 'vercel', 'dark-plus', 'github', 'github-dark'];
14
- var DARK = ['dark', 'midnight', 'nord', 'dracula', 'solarized-dark', 'vercel', 'dark-plus', 'github-dark'];
15
- var theme = null;
16
- try {
17
- theme = localStorage.getItem('tamnora-console-theme');
18
- } catch {
19
- theme = null;
20
- }
21
- if (theme === 'light') theme = 'paper';
22
- if (THEMES.indexOf(theme) < 0) {
23
- theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'paper';
24
- }
25
- document.documentElement.dataset.theme = theme;
26
- document.documentElement.dataset.scheme = DARK.indexOf(theme) >= 0 ? 'dark' : 'light';
27
- })();
28
- </script>
11
+ <script src="/landing/boot.js"></script>
29
12
  <link rel="preconnect" href="https://fonts.googleapis.com" />
30
13
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
31
14
  <link
@@ -400,6 +383,118 @@
400
383
  --page-tint: linear-gradient(180deg, rgba(13, 17, 23, 0.4), rgba(22, 27, 34, 0.4));
401
384
  }
402
385
 
386
+ html[data-theme='arena'] {
387
+ color-scheme: light;
388
+ --paper: #f6efdd;
389
+ --paper-2: #ece2c9;
390
+ --ink: #2c2419;
391
+ --muted: #6b5c42;
392
+ --line: rgba(44, 36, 25, 0.16);
393
+ --border-strong: rgba(44, 36, 25, 0.35);
394
+ --accent: #9c5c22;
395
+ --accent-dark: #7e4718;
396
+ --glass: rgba(250, 245, 232, 0.75);
397
+ --nav: #4c4335;
398
+ --copy: #574c3a;
399
+ --hint: #77684c;
400
+ --label: #5f5544;
401
+ --kicker: #6b5c42;
402
+ --surface: rgba(250, 245, 232, 0.58);
403
+ --surface-strong: rgba(250, 245, 232, 0.8);
404
+ --field-bg: rgba(255, 252, 244, 0.72);
405
+ --btn-bg: var(--ink);
406
+ --btn-fg: #fbf6ea;
407
+ --btn-hover: #3c3226;
408
+ --footer: rgba(76, 67, 53, 0.62);
409
+ --page-outer: #d9d2c2;
410
+ --page-bg: linear-gradient(90deg, rgba(250, 245, 232, 0.74) 0%, rgba(250, 245, 232, 0.42) 43%, rgba(250, 245, 232, 0.12) 100%), url("/img/fondo-agentes.webp") center/cover fixed no-repeat;
411
+ --page-tint: linear-gradient(180deg, rgba(246, 239, 221, 0.24), rgba(226, 216, 194, 0.24));
412
+ }
413
+
414
+ html[data-theme='hielo'] {
415
+ color-scheme: light;
416
+ --paper: #edf3f7;
417
+ --paper-2: #dae6ee;
418
+ --ink: #1c2a35;
419
+ --muted: #51626e;
420
+ --line: rgba(28, 42, 53, 0.16);
421
+ --border-strong: rgba(28, 42, 53, 0.35);
422
+ --accent: #2b6a8c;
423
+ --accent-dark: #1f5470;
424
+ --glass: rgba(240, 246, 250, 0.75);
425
+ --nav: #35434e;
426
+ --copy: #46545e;
427
+ --hint: #5b6c78;
428
+ --label: #4c5a66;
429
+ --kicker: #51626e;
430
+ --surface: rgba(240, 246, 250, 0.58);
431
+ --surface-strong: rgba(240, 246, 250, 0.8);
432
+ --field-bg: rgba(252, 254, 255, 0.72);
433
+ --btn-bg: var(--ink);
434
+ --btn-fg: #f2f8fc;
435
+ --btn-hover: #2c3b46;
436
+ --footer: rgba(53, 67, 78, 0.62);
437
+ --page-outer: #ccd8e0;
438
+ --page-bg: linear-gradient(90deg, rgba(240, 246, 250, 0.74) 0%, rgba(240, 246, 250, 0.42) 43%, rgba(240, 246, 250, 0.12) 100%), url("/img/fondo-agentes.webp") center/cover fixed no-repeat;
439
+ --page-tint: linear-gradient(180deg, rgba(221, 232, 240, 0.24), rgba(202, 218, 230, 0.24));
440
+ }
441
+
442
+ html[data-theme='mocha'] {
443
+ color-scheme: dark;
444
+ --paper: #211912;
445
+ --paper-2: #2b2116;
446
+ --ink: #f0e5d2;
447
+ --muted: #b3a288;
448
+ --line: rgba(240, 229, 210, 0.16);
449
+ --border-strong: rgba(240, 229, 210, 0.3);
450
+ --accent: #e0a878;
451
+ --accent-dark: #c98d5f;
452
+ --glass: rgba(38, 29, 20, 0.8);
453
+ --nav: #cfc2ac;
454
+ --copy: #bfae94;
455
+ --hint: #a89679;
456
+ --label: #b8a88e;
457
+ --kicker: #b3a288;
458
+ --surface: rgba(240, 229, 210, 0.07);
459
+ --surface-strong: rgba(240, 229, 210, 0.15);
460
+ --field-bg: rgba(240, 229, 210, 0.06);
461
+ --btn-bg: var(--accent);
462
+ --btn-fg: #241a10;
463
+ --btn-hover: #c98d5f;
464
+ --footer: rgba(224, 205, 180, 0.5);
465
+ --page-outer: #15100a;
466
+ --page-bg: linear-gradient(90deg, rgba(24, 18, 11, 0.82) 0%, rgba(24, 18, 11, 0.6) 43%, rgba(24, 18, 11, 0.32) 100%), url("/img/fondo-agentes.webp") center/cover fixed no-repeat;
467
+ --page-tint: linear-gradient(180deg, rgba(33, 25, 18, 0.32), rgba(42, 32, 22, 0.32));
468
+ }
469
+
470
+ html[data-theme='ebano'] {
471
+ color-scheme: dark;
472
+ --paper: #14191f;
473
+ --paper-2: #1c242c;
474
+ --ink: #e3ebf2;
475
+ --muted: #93a2ae;
476
+ --line: rgba(227, 235, 242, 0.14);
477
+ --border-strong: rgba(227, 235, 242, 0.28);
478
+ --accent: #6fa8c9;
479
+ --accent-dark: #5489a7;
480
+ --glass: rgba(21, 27, 34, 0.8);
481
+ --nav: #c3d0da;
482
+ --copy: #adbac6;
483
+ --hint: #8b9aa6;
484
+ --label: #9fadb9;
485
+ --kicker: #93a2ae;
486
+ --surface: rgba(227, 235, 242, 0.07);
487
+ --surface-strong: rgba(227, 235, 242, 0.15);
488
+ --field-bg: rgba(227, 235, 242, 0.05);
489
+ --btn-bg: var(--accent);
490
+ --btn-fg: #10161c;
491
+ --btn-hover: #5489a7;
492
+ --footer: rgba(215, 226, 235, 0.5);
493
+ --page-outer: #0c1014;
494
+ --page-bg: linear-gradient(90deg, rgba(12, 16, 20, 0.85) 0%, rgba(12, 16, 20, 0.6) 43%, rgba(12, 16, 20, 0.32) 100%), url("/img/fondo-agentes.webp") center/cover fixed no-repeat;
495
+ --page-tint: linear-gradient(180deg, rgba(20, 25, 31, 0.32), rgba(28, 36, 44, 0.32));
496
+ }
497
+
403
498
  * { box-sizing: border-box; }
404
499
 
405
500
  html, body {
@@ -439,10 +534,10 @@
439
534
  .logo { display: flex; align-items: center; gap: 13px; text-decoration: none; color: var(--ink); }
440
535
 
441
536
  .logo-mark {
442
- width: 39px;
443
- height: 39px;
444
- border: 1px solid var(--border-strong);
445
- border-radius: 11px;
537
+ width: 45px;
538
+ height: 45px;
539
+ /* border: 1px solid var(--border-strong); */
540
+ /* border-radius: 11px; */
446
541
  display: grid;
447
542
  place-items: center;
448
543
  overflow: hidden;
@@ -462,7 +557,8 @@
462
557
  .logo-text small {
463
558
  display: block;
464
559
  margin-top: 2px;
465
- font: 500 8px var(--mono);
560
+ padding-left: 5px;
561
+ font: 500 9px var(--mono);
466
562
  letter-spacing: 0.24em;
467
563
  color: var(--hint);
468
564
  text-transform: uppercase;
@@ -509,7 +605,7 @@
509
605
  grid-template-columns: 1.08fr 0.92fr;
510
606
  align-items: center;
511
607
  gap: 70px;
512
- padding: 42px 0 80px;
608
+ padding: 42px 0 40px;
513
609
  }
514
610
 
515
611
  .kicker {
@@ -745,8 +841,6 @@
745
841
  </a>
746
842
 
747
843
  <nav>
748
- <a href="#inicio">Inicio</a>
749
- <a href="#caracteristicas">Características</a>
750
844
  <button type="button" id="theme-toggle" class="nav-icon" title="cambiar tema" aria-label="cambiar tema">
751
845
  <svg class="ico-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
752
846
  <circle cx="12" cy="12" r="4" />
@@ -756,13 +850,12 @@
756
850
  <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" />
757
851
  </svg>
758
852
  </button>
759
- <a href="#acceso" class="nav-login">Ingresar</a>
760
853
  </nav>
761
854
  </header>
762
855
 
763
856
  <main class="hero" id="inicio">
764
857
  <section>
765
- <div class="kicker">Harness de agentes IA</div>
858
+ <!-- <div class="kicker">Harness de agentes IA</div> -->
766
859
 
767
860
  <h1>Tamnora<br /><span>Harness</span></h1>
768
861
 
@@ -772,37 +865,8 @@
772
865
  navegador headless, narra su progreso y hace trazable cada corrida.
773
866
  </p>
774
867
 
775
- <div class="actions">
776
- <a href="#acceso" class="btn btn-primary">Ingresar al sistema</a>
777
- <a href="#caracteristicas" class="btn btn-secondary">Conocer más</a>
778
- </div>
779
-
780
- <div class="features" id="caracteristicas">
781
- <div class="feature">
782
- <div class="feature-icon">◈</div>
783
- <div><b>Local</b><span>Corre en tu máquina; el estado vive en tu casa.</span></div>
784
- </div>
785
- <div class="feature">
786
- <div class="feature-icon">↗</div>
787
- <div><b>Accesible</b><span>Consola web, TUI y Telegram; túnel con QR.</span></div>
788
- </div>
789
- <div class="feature">
790
- <div class="feature-icon">✓</div>
791
- <div><b>Control</b><span>Permisos allow/ask/deny y runs trazables.</span></div>
792
- </div>
793
- <div class="feature">
794
- <div class="feature-icon">◎</div>
795
- <div><b>Navegador</b><span>Screenshot y errores de consola de una página.</span></div>
796
- </div>
797
- <div class="feature">
798
- <div class="feature-icon">♪</div>
799
- <div><b>Voz</b><span>Narra el progreso y manda audio bajo pedido.</span></div>
800
- </div>
801
- <div class="feature">
802
- <div class="feature-icon">⌘</div>
803
- <div><b>Multi-modelo</b><span>OpenRouter, OpenAI, Claude, Gemini y Ollama.</span></div>
804
- </div>
805
- </div>
868
+
869
+
806
870
  </section>
807
871
 
808
872
  <section class="login-wrap" id="acceso">
@@ -11,15 +11,17 @@ const forgot = document.getElementById('forgot');
11
11
  const enterDirect = document.getElementById('enter-direct');
12
12
  const themeToggle = document.getElementById('theme-toggle');
13
13
 
14
- themeToggle.addEventListener('click', () => {
15
- const next = nextTheme(document.documentElement.dataset.theme);
16
- document.documentElement.dataset.theme = next;
17
- try {
18
- localStorage.setItem('tamnora-console-theme', next);
19
- } catch {
20
- // storage unavailable
21
- }
22
- });
14
+ if (themeToggle) {
15
+ themeToggle.addEventListener('click', () => {
16
+ const next = nextTheme(document.documentElement.dataset.theme);
17
+ document.documentElement.dataset.theme = next;
18
+ try {
19
+ localStorage.setItem('tamnora-console-theme', next);
20
+ } catch {
21
+ // storage unavailable
22
+ }
23
+ });
24
+ }
23
25
 
24
26
  function showToast(text) {
25
27
  toast.textContent = text;
@@ -110,7 +110,7 @@ export function highlight(code, lang) {
110
110
  }
111
111
 
112
112
  function inline(text) {
113
- let out = escapeHtml(text);
113
+ let out = escapeHtml(text).replace(/\uE000/g, '');
114
114
  const codes = [];
115
115
  out = out.replace(/`([^`]+)`/g, (_, code) => {
116
116
  codes.push(code);
@@ -52,6 +52,7 @@ export function registerSession(session, messages = [], tokens = { in: 0, out: 0
52
52
  provider: session.provider || '',
53
53
  model: session.model || '',
54
54
  mode: session.mode || '',
55
+ effort: session.effort || '',
55
56
  working: false,
56
57
  tokens,
57
58
  lastTurn: { prompt: 0, completion: 0 },