@lifeaitools/clauth 1.19.3 → 1.19.4

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.
@@ -766,8 +766,11 @@ function dashboardHtml(port, whitelist, isStaged = false, initWriteToken = null)
766
766
  .build-label{font-size:.85rem;color:#94a3b8;flex:1}
767
767
  .build-label strong{color:#e2e8f0}
768
768
  .build-meta{font-family:'Courier New',monospace;font-size:.75rem;color:#64748b}
769
- .tintin-panel{display:none;position:fixed;top:0;right:0;bottom:0;z-index:80;width:min(420px,calc(100vw - 24px));background:#081c1a;border-left:1px solid #14532d;padding:1rem 1.25rem;box-shadow:-22px 0 60px rgba(0,0,0,.42);overflow:auto}
770
- .tintin-panel.open{display:block}
769
+ .tintin-tab{position:fixed;top:50%;right:0;transform:translateY(-50%);z-index:81;writing-mode:vertical-rl;text-orientation:mixed;background:linear-gradient(180deg,#103c2f,#0f2f3f);color:#86efac;border:1px solid #166534;border-right:none;border-radius:8px 0 0 8px;padding:14px 6px;font-size:.78rem;font-weight:700;cursor:pointer;letter-spacing:.5px;transition:all .2s}
770
+ .tintin-tab:hover{background:linear-gradient(180deg,#14532d,#155e75);color:#bbf7d0;padding-right:10px}
771
+ .tintin-tab.active{background:#081c1a;border-color:#22c55e;color:#bbf7d0}
772
+ .tintin-panel{position:fixed;top:0;right:-440px;bottom:0;z-index:80;width:min(420px,calc(100vw - 24px));background:#081c1a;border-left:1px solid #14532d;padding:0;box-shadow:-22px 0 60px rgba(0,0,0,.42);display:flex;flex-direction:column;transition:right .25s ease}
773
+ .tintin-panel.open{right:0}
771
774
  .tintin-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:.8rem}
772
775
  .tintin-title{font-size:.95rem;font-weight:700;color:#dcfce7}
773
776
  .tintin-sub{font-size:.78rem;color:#6ee7b7;margin-top:2px}
@@ -950,7 +953,6 @@ function dashboardHtml(port, whitelist, isStaged = false, initWriteToken = null)
950
953
  <button class="btn-refresh" onclick="loadServices()">↻ Refresh</button>
951
954
  <button class="btn-add" onclick="toggleAddService()">+ Add Service</button>
952
955
  <button class="btn-check" id="check-btn" onclick="checkAll()">⬤ Check All</button>
953
- <button class="btn-monkey" id="tintin-btn" onclick="toggleTinTinPanel()" title="Open TinTin local CLI dispatch panel">TinTin</button>
954
956
  <button class="btn-ccandme" id="ccandme-btn" onclick="launchCCandMe()" title="Launch CCandMe — 4-pane WezTerm: Claude + Codex + Me">⚡ CCandMe</button>
955
957
  <button class="btn-lock" id="unlock-writes-btn" onclick="unlockWrites()" title="Enter password to enable saving changes this browser session (needed after a daemon restart when auto-unlocked via --pw)">🔓 Unlock Writes</button>
956
958
  <button class="btn-lock" onclick="lockVault()">🔒 Lock</button>
@@ -1079,31 +1081,35 @@ function dashboardHtml(port, whitelist, isStaged = false, initWriteToken = null)
1079
1081
  </div>
1080
1082
  </div>
1081
1083
 
1084
+ <div class="tintin-tab" id="tintin-tab" onclick="toggleTinTinPanel()">TinTin</div>
1082
1085
  <div class="tintin-panel" id="tintin-panel">
1083
- <div class="tintin-head">
1084
- <div>
1085
- <div class="tintin-title">TinTin — clauth CLI dispatch</div>
1086
- <div class="tintin-sub">Dispatches a Claude CLI agent with clauth context. Uses sonnet-4-6 model. Routes: /monkey/dispatch → Claude CLI → /monkey/dispatch/:job_id.</div>
1086
+ <div class="tintin-head" style="padding:12px 16px;border-bottom:1px solid #14532d;flex-shrink:0">
1087
+ <div style="display:flex;align-items:center;justify-content:space-between">
1088
+ <div class="tintin-title">TinTin</div>
1089
+ <button class="btn-cancel" onclick="toggleTinTinPanel()" style="font-size:16px;padding:2px 6px">x</button>
1087
1090
  </div>
1088
- <button class="btn-cancel" onclick="toggleTinTinPanel()">Close</button>
1091
+ <div class="tintin-sub">claude-sonnet-4-6 · clauth CLI dispatch</div>
1089
1092
  </div>
1090
- <div class="tintin-grid">
1091
- <div class="tintin-field">
1092
- <label>App slug</label>
1093
- <input class="tintin-input" id="tintin-app" value="clauth-dashboard" spellcheck="false" autocomplete="off">
1093
+ <div id="tintin-messages" style="flex:1;min-height:0;overflow-y:auto;padding:12px 16px;display:flex;flex-direction:column;gap:10px">
1094
+ <div style="font-size:.78rem;color:#6ee7b7;font-style:italic">Ask anything. Runs a Claude CLI agent with full clauth + repo context.</div>
1095
+ </div>
1096
+ <div style="padding:10px 16px;border-top:1px solid #14532d;flex-shrink:0">
1097
+ <div class="tintin-grid" style="margin-bottom:8px">
1098
+ <div class="tintin-field">
1099
+ <label>CWD</label>
1100
+ <input class="tintin-input" id="tintin-cwd" value="C:\\Dev\\regen-root" spellcheck="false" autocomplete="off">
1101
+ </div>
1102
+ <div class="tintin-field">
1103
+ <label>App</label>
1104
+ <input class="tintin-input" id="tintin-app" value="clauth" spellcheck="false" autocomplete="off">
1105
+ </div>
1094
1106
  </div>
1095
- <div class="tintin-field">
1096
- <label>CWD</label>
1097
- <input class="tintin-input" id="tintin-cwd" value="C:\\Dev\\regen-root" spellcheck="false" autocomplete="off">
1107
+ <textarea class="tintin-textarea" id="tintin-prompt" spellcheck="false" placeholder="Ask TinTin..." style="min-height:64px;margin-bottom:8px"></textarea>
1108
+ <div style="display:flex;gap:8px;align-items:center">
1109
+ <button class="btn-tintin" id="tintin-send" onclick="sendTinTinMessage()" style="flex:1">Send</button>
1110
+ <span class="tintin-status" id="tintin-status">idle</span>
1098
1111
  </div>
1099
1112
  </div>
1100
- <textarea class="tintin-textarea" id="tintin-prompt" spellcheck="false">Reply exactly: tintin-dashboard-ok</textarea>
1101
- <div class="tintin-actions">
1102
- <button class="btn-monkey" id="tintin-send" onclick="sendTinTinMessage()">Dispatch</button>
1103
- <button class="btn-check" onclick="fillTinTinSmoke()" style="padding:7px 12px">Smoke Prompt</button>
1104
- <span class="tintin-status" id="tintin-status">idle</span>
1105
- </div>
1106
- <div class="tintin-result" id="tintin-result"></div>
1107
1113
  </div>
1108
1114
 
1109
1115
 
@@ -1510,8 +1516,10 @@ let tintinPollTimer = null;
1510
1516
 
1511
1517
  function toggleTinTinPanel() {
1512
1518
  const panel = document.getElementById("tintin-panel");
1519
+ const tab = document.getElementById("tintin-tab");
1513
1520
  if (!panel) return;
1514
1521
  panel.classList.toggle("open");
1522
+ if (tab) tab.classList.toggle("active");
1515
1523
  }
1516
1524
 
1517
1525
  function fillTinTinSmoke() {
@@ -1526,12 +1534,20 @@ function setTinTinStatus(text) {
1526
1534
  if (el) el.textContent = text || "";
1527
1535
  }
1528
1536
 
1537
+ function appendTinTinMessage(role, text) {
1538
+ const container = document.getElementById("tintin-messages");
1539
+ if (!container || !text) return;
1540
+ const bubble = document.createElement("div");
1541
+ bubble.style.cssText = role === "user"
1542
+ ? "background:#14532d;border:1px solid #166534;border-radius:8px;padding:8px 10px;font-size:.82rem;color:#bbf7d0;white-space:pre-wrap;word-break:break-word;align-self:flex-end;max-width:90%"
1543
+ : "background:#0a1f1a;border:1px solid #134e4a;border-radius:8px;padding:8px 10px;font-size:.82rem;color:#86efac;font-family:'Courier New',monospace;white-space:pre-wrap;word-break:break-word;max-width:95%;max-height:300px;overflow:auto";
1544
+ bubble.textContent = text;
1545
+ container.appendChild(bubble);
1546
+ container.scrollTop = container.scrollHeight;
1547
+ }
1548
+
1529
1549
  function setTinTinResult(text, open) {
1530
- const el = document.getElementById("tintin-result");
1531
- if (!el) return;
1532
- el.textContent = text || "";
1533
- if (open) el.classList.add("open");
1534
- else el.classList.remove("open");
1550
+ if (open && text) appendTinTinMessage("assistant", text);
1535
1551
  }
1536
1552
 
1537
1553
  async function sendTinTinMessage() {
@@ -1563,9 +1579,10 @@ async function sendTinTinMessage() {
1563
1579
  }
1564
1580
  };
1565
1581
 
1582
+ appendTinTinMessage("user", prompt);
1583
+ if (promptEl) promptEl.value = "";
1566
1584
  if (sendBtn) { sendBtn.disabled = true; sendBtn.textContent = "Dispatching..."; }
1567
- setTinTinStatus("dispatching " + jobId);
1568
- setTinTinResult("", false);
1585
+ setTinTinStatus("dispatching");
1569
1586
  try {
1570
1587
  const response = await fetch(BASE + "/monkey/dispatch", {
1571
1588
  method: "POST",
@@ -1602,17 +1619,10 @@ async function pollTinTinJob(jobId, attempt) {
1602
1619
  tintinPollTimer = setTimeout(function() { pollTinTinJob(jobId, attempt + 1); }, 1500);
1603
1620
  return;
1604
1621
  }
1605
- setTinTinStatus(job.status + " exit " + job.exit_code);
1606
- const out = [
1607
- "status: " + job.status,
1608
- "job: " + jobId,
1609
- "cwd: " + (job.cwd || ""),
1610
- "",
1611
- "stdout:",
1612
- job.stdout || "",
1613
- job.stderr ? "\\nstderr:\\n" + job.stderr : ""
1614
- ].join("\\n");
1615
- setTinTinResult(out, true);
1622
+ setTinTinStatus(job.status === "completed" ? "done" : job.status);
1623
+ const out = (job.stdout || "").trim();
1624
+ if (out) appendTinTinMessage("assistant", out);
1625
+ if (job.stderr && job.stderr.trim()) appendTinTinMessage("assistant", "stderr: " + job.stderr.trim());
1616
1626
  } catch (err) {
1617
1627
  setTinTinStatus("poll error");
1618
1628
  setTinTinResult(err && err.message ? err.message : String(err), true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.19.3",
3
+ "version": "1.19.4",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {