openclaw/apps/web/app/globals.css

744 lines
14 KiB
CSS
Raw Normal View History

@import "tailwindcss";
:root {
--color-bg: #0a0a0a;
--color-surface: #141414;
--color-surface-hover: #1a1a1a;
--color-border: #262626;
--color-text: #ededed;
--color-text-muted: #888;
--color-accent: #e85d3a;
--color-accent-hover: #f06a47;
}
body {
background: var(--color-bg);
color: var(--color-text);
font-family:
"Inter",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
sans-serif;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 6px;
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
::-webkit-scrollbar-track {
background: transparent;
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
::-webkit-scrollbar-thumb {
background: var(--color-border);
border-radius: 3px;
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
::-webkit-scrollbar-thumb:hover {
background: var(--color-text-muted);
}
2026-02-11 16:45:07 -08:00
/* ========================================
Workspace Prose (markdown document view)
======================================== */
.workspace-prose {
color: var(--color-text);
line-height: 1.75;
font-size: 0.9375rem;
}
.workspace-prose h1,
.workspace-prose h2,
.workspace-prose h3,
.workspace-prose h4,
.workspace-prose h5,
.workspace-prose h6 {
color: var(--color-text);
font-weight: 600;
margin-top: 2em;
margin-bottom: 0.75em;
line-height: 1.3;
}
.workspace-prose h1 {
font-size: 1.75rem;
border-bottom: 1px solid var(--color-border);
padding-bottom: 0.5rem;
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
2026-02-11 16:45:07 -08:00
.workspace-prose h2 {
font-size: 1.375rem;
border-bottom: 1px solid var(--color-border);
padding-bottom: 0.4rem;
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
.workspace-prose h3 {
font-size: 1.125rem;
}
.workspace-prose h4 {
font-size: 1rem;
}
2026-02-11 16:45:07 -08:00
.workspace-prose p {
margin-bottom: 1em;
}
.workspace-prose a {
color: #60a5fa;
text-decoration: underline;
text-underline-offset: 2px;
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
2026-02-11 16:45:07 -08:00
.workspace-prose a:hover {
color: #93bbfd;
}
.workspace-prose strong {
color: var(--color-text);
font-weight: 600;
}
.workspace-prose em {
font-style: italic;
}
.workspace-prose ul,
.workspace-prose ol {
margin-bottom: 1em;
padding-left: 1.5em;
}
.workspace-prose ul {
list-style-type: disc;
}
.workspace-prose ol {
list-style-type: decimal;
}
.workspace-prose li {
margin-bottom: 0.25em;
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
.workspace-prose li>ul,
.workspace-prose li>ol {
2026-02-11 16:45:07 -08:00
margin-top: 0.25em;
margin-bottom: 0;
}
.workspace-prose blockquote {
border-left: 3px solid var(--color-accent);
padding: 0.5em 1em;
margin: 1em 0;
background: var(--color-surface);
border-radius: 0 0.5rem 0.5rem 0;
color: var(--color-text-muted);
}
.workspace-prose code {
font-family: "SF Mono", "Fira Code", "JetBrains Mono", monospace;
font-size: 0.85em;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 0.25rem;
padding: 0.15em 0.35em;
}
.workspace-prose pre {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 0.5rem;
padding: 1em;
overflow-x: auto;
margin: 1em 0;
}
.workspace-prose pre code {
background: transparent;
border: none;
padding: 0;
font-size: 0.85em;
line-height: 1.6;
}
.workspace-prose hr {
border: none;
border-top: 1px solid var(--color-border);
margin: 2em 0;
}
.workspace-prose table {
width: 100%;
border-collapse: collapse;
margin: 1em 0;
font-size: 0.875rem;
}
.workspace-prose th {
text-align: left;
font-weight: 600;
padding: 0.6em 0.75em;
border-bottom: 2px solid var(--color-border);
color: var(--color-text-muted);
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.workspace-prose td {
padding: 0.5em 0.75em;
border-bottom: 1px solid var(--color-border);
}
.workspace-prose tr:hover td {
background: var(--color-surface-hover);
}
.workspace-prose img {
max-width: 100%;
border-radius: 0.5rem;
margin: 1em 0;
}
/* Task list (GFM) */
.workspace-prose input[type="checkbox"] {
appearance: none;
width: 1em;
height: 1em;
border: 1.5px solid var(--color-border);
border-radius: 0.2em;
vertical-align: middle;
margin-right: 0.4em;
position: relative;
}
.workspace-prose input[type="checkbox"]:checked {
background: var(--color-accent);
border-color: var(--color-accent);
}
.workspace-prose input[type="checkbox"]:checked::after {
content: "";
position: absolute;
left: 3px;
top: 1px;
width: 4px;
height: 8px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
/* ========================================
Tiptap Markdown Editor
======================================== */
/* Editor container layout */
.markdown-editor-container {
display: flex;
flex-direction: column;
min-height: 0;
}
/* Tiptap contenteditable area -- inherits workspace-prose via parent */
.editor-content-area {
flex: 1;
padding: 1rem 1.5rem 2rem;
min-height: 300px;
}
.editor-content-area .tiptap {
outline: none;
min-height: 200px;
}
.editor-content-area .tiptap:focus {
outline: none;
}
/* Placeholder */
.editor-content-area .tiptap p.is-editor-empty:first-child::before {
content: attr(data-placeholder);
float: left;
color: var(--color-text-muted);
opacity: 0.5;
pointer-events: none;
height: 0;
}
/* Tiptap task list (editable checkboxes) */
.editor-content-area .tiptap ul[data-type="taskList"] {
list-style: none;
padding-left: 0;
}
.editor-content-area .tiptap ul[data-type="taskList"] li {
display: flex;
align-items: flex-start;
gap: 0.5em;
margin-bottom: 0.25em;
}
.editor-content-area .tiptap ul[data-type="taskList"] li label {
flex-shrink: 0;
margin-top: 0.25em;
}
.editor-content-area .tiptap ul[data-type="taskList"] li label input[type="checkbox"] {
appearance: none;
width: 1em;
height: 1em;
border: 1.5px solid var(--color-border);
border-radius: 0.2em;
cursor: pointer;
position: relative;
}
.editor-content-area .tiptap ul[data-type="taskList"] li label input[type="checkbox"]:checked {
background: var(--color-accent);
border-color: var(--color-accent);
}
.editor-content-area .tiptap ul[data-type="taskList"] li label input[type="checkbox"]:checked::after {
content: "";
position: absolute;
left: 3px;
top: 1px;
width: 4px;
height: 8px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
Ironclaw rebrand: new identity, animated CLI banner, and iron palette Rebrand the project from the OpenClaw/Lobster identity to Ironclaw with a new iron-metallic visual language across CLI and web UI. ## CLI identity - Rename default CLI name from `openclaw` to `ironclaw` (keep `openclaw` in KNOWN_CLI_NAMES and regex for backward compat) - Set process.title to `ironclaw`; update all `[openclaw]` log prefixes to `[ironclaw]` - Add `IRONCLAW_*` env var checks (IRONCLAW_HIDE_BANNER, IRONCLAW_NO_RESPAWN, IRONCLAW_NODE_OPTIONS_READY, IRONCLAW_TAGLINE_INDEX) with fallback to legacy `OPENCLAW_*` variants ## Animated ASCII banner - Replace the old lobster block-art with a figlet "ANSI Shadow" font IRONCLAW ASCII wordmark - Add `gradient-string` dependency for terminal gradient rendering - Implement iron shimmer animation: a bright highlight sweeps across the ASCII art (~2.5 s at 12 fps, 3 full gradient cycles) using a rotating iron-to-silver color array - Make `emitCliBanner` async to support the animation; update all call sites (preaction hook, route, run-main) to await it - Move banner emission earlier in `runCli()` so it appears for all invocations (bare command, subcommands, help) with the existing bannerEmitted guard preventing double-emission ## Iron palette and theme - Rename LOBSTER_PALETTE → IRON_PALETTE in `src/terminal/palette.ts` with new cool-steel color tokens (steel grey accent, bright silver highlight, dark iron dim, steel bl info) - Re-export LOBSTER_PALETTE as backward-compatible alias - Update `src/terminal/theme.ts` to import and use IRON_PALETTE ## Tagline cleanup - Remove lobster-themed, Apple-specific, and platform-joke taglines - Fix smart-quote and em-dash formatting across remaining taglines - Add "Holiday taglines" comment grouping for date-gated entries ## Web UI - Add `framer-motion`, `fuse.js`, and `next-themes` to web app deps - Add custom font files: Bookerly (regular/bold/italic), SpaceGrotesk (light/regular/medium/semibold/bold), FoundationTitlesHand - Update chat panel labels: "OpenClaw Chat" → "Ironclaw Chat", "Message OpenClaw..." → "Message Ironclaw..." - Update sidebar header: "OpenClaw Dench" → "Ironclaw" - CSS formatting cleanup: expand single-lins, add consistent blank lines between selector blocks, normalize child combinator spacing (li > ul → li>ul)
2026-02-11 23:26:05 -08:00
.editor-content-area .tiptap ul[data-type="taskList"] li>div {
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
flex: 1;
}
/* Images in editor */
.editor-content-area .tiptap .editor-image {
max-width: 100%;
height: auto;
border-radius: 0.5rem;
margin: 1em 0;
cursor: default;
}
.editor-content-area .tiptap .editor-image.ProseMirror-selectednode {
outline: 2px solid var(--color-accent);
outline-offset: 2px;
border-radius: 0.5rem;
}
/* Table editing */
.editor-content-area .tiptap table {
border-collapse: collapse;
width: 100%;
margin: 1em 0;
}
.editor-content-area .tiptap th,
.editor-content-area .tiptap td {
border: 1px solid var(--color-border);
padding: 0.5em 0.75em;
position: relative;
}
.editor-content-area .tiptap th {
background: var(--color-surface);
font-weight: 600;
}
.editor-content-area .tiptap .selectedCell {
background: rgba(232, 93, 58, 0.08);
}
/* --- Toolbar --- */
.editor-toolbar {
display: flex;
align-items: center;
gap: 2px;
padding: 0.375rem 1.5rem;
border-bottom: 1px solid var(--color-border);
background: var(--color-bg);
flex-shrink: 0;
flex-wrap: wrap;
}
.editor-toolbar-group {
display: flex;
align-items: center;
gap: 1px;
}
.editor-toolbar-divider {
width: 1px;
height: 1.25rem;
background: var(--color-border);
margin: 0 0.375rem;
}
.editor-toolbar-btn {
display: flex;
align-items: center;
justify-content: center;
width: 1.75rem;
height: 1.75rem;
border-radius: 0.25rem;
border: none;
background: transparent;
color: var(--color-text-muted);
cursor: pointer;
font-size: 0.75rem;
font-weight: 500;
transition: all 0.1s;
}
.editor-toolbar-btn:hover {
background: var(--color-surface-hover);
color: var(--color-text);
}
.editor-toolbar-btn-active {
background: rgba(232, 93, 58, 0.12);
color: var(--color-accent);
}
.editor-toolbar-btn-active:hover {
background: rgba(232, 93, 58, 0.18);
}
/* --- Bubble menu --- */
.bubble-menu {
display: flex;
align-items: center;
gap: 1px;
padding: 0.25rem;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 0.5rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.bubble-menu-btn {
display: flex;
align-items: center;
justify-content: center;
width: 1.75rem;
height: 1.75rem;
border-radius: 0.25rem;
border: none;
background: transparent;
color: var(--color-text-muted);
cursor: pointer;
font-size: 0.8rem;
transition: all 0.1s;
}
.bubble-menu-btn:hover {
background: var(--color-surface-hover);
color: var(--color-text);
}
.bubble-menu-btn-active {
color: var(--color-accent);
background: rgba(232, 93, 58, 0.12);
}
/* --- Sticky top bar (save + read toggle) --- */
.editor-top-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5rem 1.5rem;
border-bottom: 1px solid var(--color-border);
background: var(--color-bg);
flex-shrink: 0;
position: sticky;
top: 0;
z-index: 20;
}
.editor-top-bar-left {
display: flex;
align-items: center;
gap: 0.5rem;
}
.editor-top-bar-right {
display: flex;
align-items: center;
gap: 0.75rem;
}
.editor-save-indicator {
font-size: 0.75rem;
}
.editor-save-unsaved {
color: #f59e0b;
}
.editor-save-saved {
color: #22c55e;
}
.editor-save-error {
color: #f87171;
}
.editor-save-hint {
font-size: 0.7rem;
color: var(--color-text-muted);
opacity: 0.6;
padding: 0.15rem 0.4rem;
background: var(--color-surface);
border-radius: 0.25rem;
border: 1px solid var(--color-border);
}
.editor-save-button {
padding: 0.35rem 1rem;
font-size: 0.8rem;
font-weight: 500;
border-radius: 0.375rem;
border: none;
background: var(--color-accent);
color: white;
cursor: pointer;
transition: all 0.15s;
}
.editor-save-button:hover:not(:disabled) {
background: var(--color-accent-hover);
}
.editor-save-button:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* --- Edit / Read mode toggle --- */
.editor-mode-toggle {
display: flex;
align-items: center;
gap: 0.375rem;
padding: 0.3rem 0.6rem;
font-size: 0.75rem;
font-weight: 500;
border-radius: 0.375rem;
border: 1px solid var(--color-border);
background: var(--color-surface);
color: var(--color-text-muted);
cursor: pointer;
transition: all 0.15s;
}
.editor-mode-toggle:hover {
background: var(--color-surface-hover);
color: var(--color-text);
border-color: var(--color-text-muted);
}
/* ========================================
Slash Command Popup
======================================== */
.slash-cmd-popup {
max-height: 320px;
overflow-y: auto;
min-width: 240px;
max-width: 320px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 0.5rem;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
padding: 0.25rem;
}
.slash-cmd-empty {
padding: 0.75rem 1rem;
font-size: 0.8rem;
color: var(--color-text-muted);
text-align: center;
}
.slash-cmd-item {
display: flex;
align-items: center;
gap: 0.625rem;
width: 100%;
padding: 0.5rem 0.625rem;
border: none;
background: transparent;
border-radius: 0.375rem;
cursor: pointer;
text-align: left;
transition: background 0.1s;
}
.slash-cmd-item:hover,
.slash-cmd-item-active {
background: var(--color-surface-hover);
}
.slash-cmd-item-icon {
display: flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
border-radius: 0.25rem;
background: var(--color-bg);
border: 1px solid var(--color-border);
color: var(--color-text-muted);
flex-shrink: 0;
}
.slash-cmd-icon-text {
font-size: 0.65rem;
font-weight: 700;
color: var(--color-text-muted);
}
.slash-cmd-item-body {
display: flex;
flex-direction: column;
min-width: 0;
}
.slash-cmd-item-title {
font-size: 0.8rem;
font-weight: 500;
color: var(--color-text);
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.slash-cmd-item-desc {
font-size: 0.7rem;
color: var(--color-text-muted);
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Dench workspace: unified @ mention search, entry detail modal, and workspace link system New libraries: - workspace-links.ts: builders, parsers, and type guards for workspace URLs (/workspace?path=... for files/objects, /workspace?entry=objName:id for entries). Replaces ad-hoc relative-path links with real navigable URLs. - search-index.ts: useSearchIndex hook that fetches a unified search index from the API and provides Fuse.js-powered fuzzy search across files, objects, and database entries. Exposes a stable ref-based search function safe for capture in tiptap extensions. New API routes: - GET /api/workspace/search-index: builds a flat search index from the filesystem tree (knowledge/, reports/, top-level files) and all DuckDB object entries with display-field labels and preview fields. - GET /api/workspace/objects/[name]/entries/[id]: fetches a single entry with all field values, resolved relation labels, reverse relations (incoming links from other objects), and the effective display field. New component: - EntryDetailModal: slide-over modal for viewing an individual entry's fields, enum badges, user avatars, clickable relation chips (navigate to related entries), reverse relation sections, and timestamps. Supports Escape to close and backdrop click dismiss. Slash command refactor (slash-command.tsx): - New createWorkspaceMention(searchFn) replaces the old file-only @ mention with unified search across files, objects, and entries. - searchItemToSlashItem() converts search index items into tiptap suggestion items with proper icons, badges (object name pill for entries), and link insertion commands using real workspace URLs. - Legacy createFileMention(tree) now delegates to createWorkspaceMention with a simple substring-match fallback for when no search index is available. Editor integration (markdown-editor.tsx, document-view.tsx): - MarkdownEditor accepts optional searchFn prop; when provided, uses createWorkspaceMention instead of the legacy createFileMention. - Link click interception now uses the shared isWorkspaceLink() helper and registers handlers in capture phase for reliable interception. - DocumentView forwards searchFn to editor and adds a delegated click handler in read mode to intercept workspace links and navigate via onNavigate. Object table (object-table.tsx): - Added onEntryClick prop; table rows are now clickable with cursor-pointer styling, firing the callback with the entry ID. Workspace page (page.tsx): - Integrates useSearchIndex hook and passes search function down to editor. - Entry detail modal state with URL synchronization (?entry=objName:id param). - New resolveNode() with fallback strategies: exact match, knowledge/ prefix toggle, and last-segment object name matching. - Unified handleEditorNavigate() dispatches /workspace?entry=... to the modal and /workspace?path=... to file/object navigation. - URL bar syncs with activePath via router.replace (no full page reloads). - Top-level container click safety net catches any workspace link clicks that bubble up unhandled. Styles (globals.css): - Added .slash-cmd-item-badge for object-name pills in the @ mention popup.
2026-02-11 21:41:23 -08:00
.slash-cmd-item-badge {
display: inline-block;
margin-left: 6px;
padding: 1px 6px;
font-size: 0.6rem;
font-weight: 500;
text-transform: capitalize;
border-radius: 999px;
background: rgba(232, 93, 58, 0.12);
color: var(--color-accent);
vertical-align: middle;
line-height: 1.4;
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
/* ========================================
Report Block (in-editor)
======================================== */
.report-block-wrapper {
position: relative;
margin: 1em 0;
border-radius: 0.75rem;
border: 1px solid var(--color-border);
overflow: hidden;
}
.report-block-wrapper[data-selected] {
border-color: var(--color-accent);
box-shadow: 0 0 0 1px var(--color-accent);
}
.report-block-toolbar {
display: flex;
align-items: center;
gap: 0.25rem;
padding: 0.375rem 0.5rem;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
}
.report-block-btn {
display: flex;
align-items: center;
gap: 0.25rem;
padding: 0.2rem 0.5rem;
font-size: 0.7rem;
font-weight: 500;
border-radius: 0.25rem;
border: 1px solid var(--color-border);
background: var(--color-bg);
color: var(--color-text-muted);
cursor: pointer;
transition: all 0.1s;
}
.report-block-btn:hover {
background: var(--color-surface-hover);
color: var(--color-text);
}
.report-block-btn-danger:hover {
background: rgba(248, 113, 113, 0.1);
color: #f87171;
border-color: rgba(248, 113, 113, 0.3);
}
.report-block-source {
position: relative;
}
.report-block-source-label {
position: absolute;
top: 0.375rem;
right: 0.5rem;
font-size: 0.6rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--color-text-muted);
opacity: 0.5;
pointer-events: none;
}
.report-block-textarea {
width: 100%;
padding: 1rem;
background: var(--color-bg);
color: var(--color-text);
border: none;
outline: none;
font-family: "SF Mono", "Fira Code", "JetBrains Mono", monospace;
font-size: 0.8rem;
line-height: 1.5;
resize: vertical;
min-height: 100px;
}
.report-block-error {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem;
background: rgba(248, 113, 113, 0.05);
color: #f87171;
font-size: 0.8rem;
}