Files
max-sixty__worktrunk/docs/astro.config.mjs
T
Maximilian Roos cff085edf9 docs: fix misplaced copy buttons by dropping terminal frames (#4090)
On every shell code block the copy button sat 40px below the top of the
code: on the second line of multi-line blocks, and hanging below
one-line blocks such as `wt merge --no-ff` on /merge/. Shell blocks were
Expressive Code terminal frames, and the terminal plugin deleted their
title bar, but Expressive Code still offsets the copy button by that
bar's height.

## Changes

- `docs/astro.config.mjs` sets `defaultProps: { frame: 'code' }`, so no
block is a terminal frame and there is no title bar to remove. The
plugin's header-removal hook and its `props.frame = 'terminal'` go, and
so does the `wt-commands-only` class: mobile wrapping in `custom.css`
now keys on whether a block contains captured output
(`:has(.wt-output)`).
- Blocks with several commands had a whole-block copy button and
per-line buttons in the same corner, handed over on hover by opacity. A
hidden button still takes clicks, so clicking a line's button could copy
the whole block, and on touch screens one button covered another. Most
of these blocks are lists of alternatives, so they now get only per-line
buttons, and the hover rule is deleted.
- Those blocks wrap (Expressive Code's `wrap` prop) unless they carry
captured output, since a per-line button sits at the end of its line and
scrolled out of view on the long `jq` examples on /list/. A per-line
button is no taller than its line, so buttons on adjacent lines no
longer overlap.
- The two multi-command blocks that only work run in order, the FAQ's
stash recipe and the `Equivalent to:` block under `wt step diff`'s **How
it works** (in `src/cli/step.rs`), are now `bash` fences, the form
`docs/CLAUDE.md` prescribes for a copyable recipe, so they keep one copy
button for the whole recipe. Terminal `--help` renders `console` and
`bash` fences alike (it strips `$ `), and the help snapshots are
unchanged.

## Side effect

Expressive Code strips comment lines only from what terminal frames
copy. The eight `bash` and `powershell` blocks with comments on
/shell-integration/ now copy them, as console blocks already did. Pasted
into zsh without `interactivecomments`, each comment line prints
`command not found: #`; the commands still run.

## Tests

A browser test checks every copy button on every page, at 393px with
touch and at 1376px, for three things: it sits on the line it copies, it
is inside the visible code, and it doesn't overlap another button. These
checks fail against worktrunk.dev and against a build without the wrap
and the height cap. The built-site and plugin tests now expect per-line
payloads and no block payload on multi-command blocks, and a plugin test
pins that blocks carrying output never wrap.

> _This was written by Claude Code on behalf of max-sixty_

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_013U96NY8qKtZhavBSwnfCYq

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-13 10:00:25 -07:00

89 lines
2.7 KiB
JavaScript

import { unified } from '@astrojs/markdown-remark';
import sitemap from '@astrojs/sitemap';
import starlight from '@astrojs/starlight';
import { defineConfig } from 'astro/config';
import { rehypePagefindCommandReferences } from './src/plugins/pagefind-command-references.mjs';
import { rehypeResponsiveTables } from './src/plugins/responsive-tables.mjs';
import { rehypeStableHeadingIds } from './src/plugins/stable-heading-ids.mjs';
import { sidebar } from './src/site-navigation.mjs';
import { sitemapCompatibility } from './src/plugins/sitemap-compatibility.mjs';
import {
pluginWorktrunkTerminal,
rehypeComparisonCommands,
} from './src/plugins/worktrunk-terminal.mjs';
import {
worktrunkDarkCodeTheme,
worktrunkLightCodeTheme,
} from './src/themes/worktrunk-code.mjs';
const repository = 'https://github.com/max-sixty/worktrunk';
const site = 'https://worktrunk.dev';
export default defineConfig({
site,
devToolbar: {
enabled: false,
},
markdown: {
processor: unified({
rehypePlugins: [
rehypeStableHeadingIds,
rehypePagefindCommandReferences,
rehypeComparisonCommands,
rehypeResponsiveTables,
],
}),
},
integrations: [
starlight({
title: 'Worktrunk',
description: 'Git worktree management for parallel AI agent workflows.',
disable404Route: true,
favicon: '/favicon.png',
logo: {
src: './public/logo.png',
alt: 'Worktrunk',
},
social: [
{ icon: 'github', label: 'GitHub', href: repository },
],
tableOfContents: {
minHeadingLevel: 1,
maxHeadingLevel: 2,
},
editLink: {
baseUrl: `${repository}/edit/main/docs/`,
},
customCss: ['./src/styles/custom.css'],
components: {
Footer: './src/components/Footer.astro',
Head: './src/components/Head.astro',
PageTitle: './src/components/PageTitle.astro',
Pagination: './src/components/Pagination.astro',
SocialIcons: './src/components/SocialIcons.astro',
ThemeSelect: './src/components/ThemeSelect.astro',
},
expressiveCode: {
// Shell examples render as plain code, without terminal window chrome.
defaultProps: { frame: 'code' },
plugins: [pluginWorktrunkTerminal()],
themes: [worktrunkDarkCodeTheme, worktrunkLightCodeTheme],
useStarlightUiThemeColors: true,
styleOverrides: {
borderRadius: '0',
codeFontFamily: 'var(--sl-font-mono)',
frames: {
frameBoxShadowCssValue: 'none',
},
},
},
sidebar,
}),
sitemap({
filter: (page) => ![`${site}/404/`, `${site}/worktrunk/`].includes(page),
}),
sitemapCompatibility(),
],
});