From 22daf8b76a04f9bc5107a2633be8962a5da0c7c1 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Sun, 31 May 2026 12:14:50 -0700 Subject: [PATCH] laklok: brand domain + piece rename, chat footer/handle fixes - Rename laer-klokken piece -> laklok.mjs (clock chat); laer-klokken.mjs now aliases to it (ff -> freaky-flowers pattern). Chat channel stays "clock" so the DB collection (chat-clock) and assets are untouched. - Wire laklok.com as a branded domain: boot.mjs starting-piece + production host list; disk.mjs same-origin hosts, branded-domain redirect, and the chat nav-key guard so Enter/Backspace/Escape don't bounce out of laklok. - chat: match header/footer chrome to the body bg, animated diagonal-stripe footer with a visible break line, and a top-left corner QR. - disk: disable the cyan A/B/C/D/E LAN device-letter HUD badge for now. - chat-manager: guard the handle lookup so a 200-without-handle can no longer render "@undefined" (degrades to @unknown instead). Co-Authored-By: Claude Opus 4.8 (1M context) --- session-server/chat-manager.mjs | 6 +- system/public/aesthetic.computer/boot.mjs | 8 ++ .../public/aesthetic.computer/disks/chat.mjs | 54 +++++++--- .../aesthetic.computer/disks/laer-klokken.mjs | 99 ++----------------- .../aesthetic.computer/disks/laklok.mjs | 88 +++++++++++++++++ system/public/aesthetic.computer/lib/disk.mjs | 17 +++- 6 files changed, 168 insertions(+), 104 deletions(-) create mode 100644 system/public/aesthetic.computer/disks/laklok.mjs diff --git a/session-server/chat-manager.mjs b/session-server/chat-manager.mjs index 0913cea4c1..1f9a29f59a 100644 --- a/session-server/chat-manager.mjs +++ b/session-server/chat-manager.mjs @@ -657,8 +657,10 @@ export class ChatManager { const response = await fetch(`${host}/handle?for=${prefix}${fromSub}`, options); if (response.status === 200) { const data = await response.json(); - instance.subsToHandles[fromSub] = data.handle; - return "@" + data.handle; + if (data.handle) { + instance.subsToHandles[fromSub] = data.handle; + return "@" + data.handle; + } } } catch (err) { console.error("💬 Handle lookup error:", err); diff --git a/system/public/aesthetic.computer/boot.mjs b/system/public/aesthetic.computer/boot.mjs index bb836cf6c8..e1ce36a798 100644 --- a/system/public/aesthetic.computer/boot.mjs +++ b/system/public/aesthetic.computer/boot.mjs @@ -973,6 +973,8 @@ if (window.acDEBUG === true || window.acDEBUG === false) { window.location.hostname.endsWith(".ac") || window.location.hostname === "notepat.com" || window.location.hostname === "www.notepat.com" || + window.location.hostname === "laklok.com" || + window.location.hostname === "www.laklok.com" || window.location.hostname === "m2w2.whistlegraph.com" || window.acPACK_MODE // Disable debug mode in OBJKT packages ) { @@ -1011,6 +1013,12 @@ if ( ) { window.acSTARTING_PIECE = "notepat"; } +if ( + location.hostname === "laklok.com" || + location.hostname === "www.laklok.com" +) { + window.acSTARTING_PIECE = "laklok"; +} if (window.acSTARTING_PIECE === undefined) window.acSTARTING_PIECE = "prompt"; diff --git a/system/public/aesthetic.computer/disks/chat.mjs b/system/public/aesthetic.computer/disks/chat.mjs index 69ed6ae744..ca1a09235a 100644 --- a/system/public/aesthetic.computer/disks/chat.mjs +++ b/system/public/aesthetic.computer/disks/chat.mjs @@ -417,7 +417,10 @@ async function boot( if (params && params.length > 0) { hud.label("chat"); } - + + // 📱 QR code in the top-left corner, to the left of the HUD label. + hud.qr("https://prompt.ac/chat"); + rowHeight = typeface.blockHeight + 1; const client = otherChat || chat; @@ -746,7 +749,7 @@ function paint( // Default theme const defaultTheme = { background: [100, 100, 145], - chromeBg: [20, 20, 30], // Top/bottom panel bg — framing color around scroll region + chromeBg: [100, 100, 145], // Match background — no banners above/below fold (like laer-klokken) lines: [90, 200, 150, 48], scrollbar: [255, 192, 203], messageText: [255, 255, 255], @@ -1701,15 +1704,44 @@ function paint( // Update handleBtn box for click detection handleBtn.btn.box = new Box(handleBtnX, handleBtnY, btnW, btnH); - // Draw panel background behind both buttons (theme-aware) - const bottomChrome = Array.isArray(theme.chromeBg) ? theme.chromeBg : [theme.chromeBg]; - ink(...bottomChrome, 255).box( - 0, - screen.height - panelHeight, - screen.width, - panelHeight - ); - + // 🎨 Bottom footer background — a slightly different shade than the chrome, + // with subtle animated diagonal stripes. Colors derive from chromeBg so it + // adapts to any theme (blue chat, terracotta laer-klokken, etc). + const panelTop = screen.height - panelHeight; + const chromeArr = Array.isArray(theme.chromeBg) + ? theme.chromeBg + : [theme.chromeBg, theme.chromeBg, theme.chromeBg]; + const footerBg = + theme.footerBg || chromeArr.slice(0, 3).map((c) => Math.max(0, Math.round(c * 0.82))); + const stripeColor = + theme.footerStripe || + chromeArr.slice(0, 3).map((c) => Math.min(255, Math.round(c * 1.3))); + + // Base fill (slightly different from the body/chrome). + ink(...footerBg, 255).box(0, panelTop, screen.width, panelHeight); + + // Animated diagonal stripes scrolling across the footer over time. Each line + // spans exactly the panel height, so it stays within the footer band. + const stripeSpacing = 12; + const stripeOffset = (performance.now() * 0.02) % stripeSpacing; + for (let x = -panelHeight; x < screen.width + stripeSpacing; x += stripeSpacing) { + ink(...stripeColor, 36).line( + x + stripeOffset, + panelTop, + x + stripeOffset + panelHeight, + panelTop + panelHeight, + ); + } + + // Full-width horizontal break above the handle + enter-message buttons. + // Solid (alpha stripped) so it reads clearly over the footer texture. + const breakColor = (Array.isArray(theme.lines) ? theme.lines : [theme.lines]).slice(0, 3); + ink(...breakColor).line(0, panelTop, screen.width, panelTop); + + // Keep the footer stripes animating even when chrome (news ticker) is hidden, + // e.g. in laer-klokken which passes hideChrome. + needsPaint(); + // Use blue color scheme for Log in, pink/magenta for handle (like prompt.mjs) const loginBgColor = currentHandle ? [128, 0, 128] : [0, 0, 128]; const loginBorderColor = 255; diff --git a/system/public/aesthetic.computer/disks/laer-klokken.mjs b/system/public/aesthetic.computer/disks/laer-klokken.mjs index 513ea21228..23f584a40f 100644 --- a/system/public/aesthetic.computer/disks/laer-klokken.mjs +++ b/system/public/aesthetic.computer/disks/laer-klokken.mjs @@ -1,89 +1,10 @@ -// Laer-klokken, 2025.5.08.16.31.51.182 -// Learn the 'clock'! - -/* 📝 Notes - */ - -import { Chat } from "../lib/chat.mjs"; // TODO: Eventually expand to `net.Socket` -import * as chat from "./chat.mjs"; // Import chat everywhere. - -let client; - -function boot({ api, wipe, debug, send, hud }) { - client = new Chat(debug, send); - client.connect("clock"); // Connect to 'clock' chat. - chat.boot(api, client.system); // Use default font - - // � Use MatrixChunky8 (tiny) font for HUD label - hud.tinyLabel(true); - // 📱 Set QR code to appear LEFT of the HUD label (qr-stamp-label mode) - hud.qr("https://prompt.ac/laer-klokken"); - // 🏷️ Ensure label shows piece name (not "chat") - hud.label("laer-klokken"); -} - -function paint($) { - // Custom warm color theme for laer-klokken chat - chat.paint($, { - otherChat: client.system, - hideChrome: true, - theme: { - background: [180, 100, 60], // Warm terracotta/rust background - chromeBg: [180, 100, 60], // Match background — no dark banners above/below fold - lines: [220, 150, 100, 64], // Soft peach lines - scrollbar: [255, 180, 100], // Warm orange scrollbar - messageText: [255, 255, 240], // Brighter cream/off-white text for better contrast - messageBox: [255, 220, 180], // Warm beige for message boxes - log: [100, 255, 220], // Bright cyan/teal for system log messages - logHover: [255, 240, 120], // Bright golden yellow on hover - handle: [255, 160, 120], // Brighter coral for handles - handleHover: [255, 240, 120], // Bright golden yellow on hover - url: [120, 220, 255], // Brighter light blue for contrast - urlHover: [255, 240, 120], // Bright golden yellow on hover - prompt: [200, 255, 180], // Brighter soft green for prompts - promptContent: [120, 220, 255], // Light blue like urls - promptHover: [255, 240, 120], // Bright golden yellow on hover - promptContentHover: [255, 240, 120], // Bright golden yellow on hover - painting: [255, 200, 140], // Brighter peachy orange for paintings - paintingHover: [255, 240, 120], // Bright golden yellow on hover - kidlisp: [255, 140, 200], // Warm pink/magenta for kidlisp - kidlispHover: [255, 240, 120], // Bright golden yellow on hover - timestamp: [220, 180, 150], // Much brighter/lighter brown for timestamps - timestampHover: [255, 240, 120], // Bright golden yellow on hover - heart: [255, 220, 240], // Light pink — pops on warm rust background - } - }); -} - -function act($) { - chat.act($, client.system, { allowDelete: true }); -} - -function sim($) { - chat.sim($); -} - -function leave() { - client.kill(); -} - - -// 📚 Library - -// function beat() { -// // Runs once per system metronome (BPM) tick. -// } - -// function leave() { -// // Runs once before the piece is unloaded. -// } - -// function preview({ ink, wipe }) { -// Render a custom thumbnail image. -// } - -// function icon() { -// Render an application icon, aka favicon. -// } - -// ⚠️ Also available: `brush` and `filter`. +// laer-klokken — alias/shortcut for `laklok` (learn the clock). +// The piece now lives in `laklok.mjs` (backed by laklok.com); this keeps the +// original /laer-klokken path working, mirroring how `ff` aliases to +// `freaky-flowers`. + +// 🥾 Boot (Runs once before first paint and sim) +export function boot({ colon, params, alias }) { + // Pass all parameters through to `laklok`. + alias(`laklok`, colon, params); +} diff --git a/system/public/aesthetic.computer/disks/laklok.mjs b/system/public/aesthetic.computer/disks/laklok.mjs new file mode 100644 index 0000000000..b2039fdcd7 --- /dev/null +++ b/system/public/aesthetic.computer/disks/laklok.mjs @@ -0,0 +1,88 @@ +// laklok, 2025.5.08.16.31.51.182 +// Learn the 'clock'! (formerly `laer-klokken`; that path still aliases here.) +// 🌐 Backed by the branded domain laklok.com. + +/* 📝 Notes + */ + +import { Chat } from "../lib/chat.mjs"; // TODO: Eventually expand to `net.Socket` +import * as chat from "./chat.mjs"; // Import chat everywhere. + +let client; + +function boot({ api, wipe, debug, send, hud }) { + client = new Chat(debug, send); + client.connect("clock"); // Connect to 'clock' chat. (DB stays `chat-clock`.) + chat.boot(api, client.system); // Use default font + + // 📱 Set QR code to appear LEFT of the HUD label (qr-stamp-label mode) + hud.qr("https://laklok.com"); + // 🏷️ Ensure label shows piece name (not "chat") + hud.label("laklok"); +} + +function paint($) { + // Custom warm color theme for laklok chat + chat.paint($, { + otherChat: client.system, + hideChrome: true, + theme: { + background: [180, 100, 60], // Warm terracotta/rust background + chromeBg: [180, 100, 60], // Match background — no dark banners above/below fold + lines: [220, 150, 100, 64], // Soft peach lines + scrollbar: [255, 180, 100], // Warm orange scrollbar + messageText: [255, 255, 240], // Brighter cream/off-white text for better contrast + messageBox: [255, 220, 180], // Warm beige for message boxes + log: [100, 255, 220], // Bright cyan/teal for system log messages + logHover: [255, 240, 120], // Bright golden yellow on hover + handle: [255, 160, 120], // Brighter coral for handles + handleHover: [255, 240, 120], // Bright golden yellow on hover + url: [120, 220, 255], // Brighter light blue for contrast + urlHover: [255, 240, 120], // Bright golden yellow on hover + prompt: [200, 255, 180], // Brighter soft green for prompts + promptContent: [120, 220, 255], // Light blue like urls + promptHover: [255, 240, 120], // Bright golden yellow on hover + promptContentHover: [255, 240, 120], // Bright golden yellow on hover + painting: [255, 200, 140], // Brighter peachy orange for paintings + paintingHover: [255, 240, 120], // Bright golden yellow on hover + kidlisp: [255, 140, 200], // Warm pink/magenta for kidlisp + kidlispHover: [255, 240, 120], // Bright golden yellow on hover + timestamp: [220, 180, 150], // Much brighter/lighter brown for timestamps + timestampHover: [255, 240, 120], // Bright golden yellow on hover + heart: [255, 220, 240], // Light pink — pops on warm rust background + } + }); +} + +function act($) { + chat.act($, client.system, { allowDelete: true }); +} + +function sim($) { + chat.sim($); +} + +function leave() { + client.kill(); +} + + +// 📚 Library + +// function beat() { +// // Runs once per system metronome (BPM) tick. +// } + +// function leave() { +// // Runs once before the piece is unloaded. +// } + +// function preview({ ink, wipe }) { +// Render a custom thumbnail image. +// } + +// function icon() { +// Render an application icon, aka favicon. +// } + +// ⚠️ Also available: `brush` and `filter`. diff --git a/system/public/aesthetic.computer/lib/disk.mjs b/system/public/aesthetic.computer/lib/disk.mjs index faefafa6a0..ca99d9f19d 100644 --- a/system/public/aesthetic.computer/lib/disk.mjs +++ b/system/public/aesthetic.computer/lib/disk.mjs @@ -243,6 +243,8 @@ const SAME_ORIGIN_BUILT_IN_PIECE_HOSTS = new Set([ "www.kidlisp.com", "notepat.com", "www.notepat.com", + "laklok.com", + "www.laklok.com", "p5.aesthetic.computer", "sitemap.aesthetic.computer", ]); @@ -2305,6 +2307,10 @@ function redirectIfBrandedDomain() { send({ type: "web", content: { url: "https://aesthetic.computer/notepat", blank: false } }); return true; } + if (hostname === "laklok.com" || hostname === "www.laklok.com") { + send({ type: "web", content: { url: "https://aesthetic.computer/laklok", blank: false } }); + return true; + } return false; } @@ -8245,7 +8251,10 @@ async function load( $commonApi.jump(`404~${slug}`); } } else { - $commonApi.notice(":(", ["red", "yellow"]); + // At the prompt, a not-found entry isn't a failure — its helper shows + // a "thinking" character + LLM reply instead of a sad face. + if (currentText !== "prompt") + $commonApi.notice(":(", ["red", "yellow"]); } return false; } @@ -11999,6 +12008,7 @@ async function makeFrame({ data: { type, content } }) { system !== "world" && currentText !== "chat" && currentText !== "laer-klokken" && + currentText !== "laklok" && currentText !== "aa" && currentText !== "sign" && currentText !== "jas" && @@ -14444,7 +14454,10 @@ async function makeFrame({ data: { type, content } }) { // 📡 LAN badge superscript - add width for device letter if connected to dev session server // Hide in kidlisp.com embedded mode (NOAUTH_MODE) - const showLanBadge = devIdentity && devIdentity.host && !globalThis.NOAUTH_MODE; + // 🔇 Disabled for now (@jeffrey) — hide the cyan A/B/C/D/E device-letter + // window badge in both dev and production. Restore by uncommenting below. + // const showLanBadge = devIdentity && devIdentity.host && !globalThis.NOAUTH_MODE; + const showLanBadge = false; const lanBadgePadding = showLanBadge ? 10 : 0; // Space for letter + margin w += lanBadgePadding; -- 2.51.2