diff --git a/CHANGELOG.md b/CHANGELOG.md index 005dc42..6de05d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,15 +7,31 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning: [S ### Added -- **The pilot grid is now the default workspace shell**, with the previous interface reachable behind a toggle and a mobile layout below 760px. +- **One visual system for the whole web UI, ported from the Codesema UI Kit** (`packages/web/design/ui-kit.html`): 13 colour tokens, a single self-hosted monospace font (Cascadia Mono, 42 KB subset), 14px/1.6 text on a `1ch` × line grid, 1px borders with no radius and no shadow, and shared component classes (`packages/web/src/styles/{tokens,base,kit}.css`). +- **Nine switchable palettes and an AAA contrast variant** (Tokyo Night by default, plus Nord, Gruvbox Dark, Catppuccin Mocha, Bauhaus, Aamis, Aetheria, Arc Blueberry, Artzen), chosen from the repo settings page and remembered per browser, applied before the first paint. +- **The theme picker lives at the bottom of the navigation rail**, above the repo settings entry. - **Decision D17: a turn's visual proof of its own effect is now part of the review.** A `microvm` task can declare and capture a screenshot or a Playwright journey each turn (`proof` in `.codesema/config.json`, a `PROOF: ` line in the agent's reply); the reviewer checks the declaration against the diff and raises a finding only on an unproven visible change or an unexplained failed proof. - **`codesema runbook validate`** validates a hand-edited `.codesema/runbook.json` as-is, without asking an agent for a new proposal. - **The runbook can declare background services**, started in the verification VM ahead of its healthchecks and tests. - **A task now carries its own activity**: the phase a turn is currently in is broadcast live and shown on its card and in the evidence block. - **A turn now emits its recap the moment it ends, and a finished task without one gets it computed on read**, with the microvm verification surfaced alongside it. +### Removed + +- **The pilot grid shell** (tiled agent cards, lanes, lens overlays, mobile list): the workspace is the navigation rail, one flat list of conversations, and one conversation. Tiling and multi-column layouts are deferred. + ### Changed +- **The standalone review mode now shares the dark workspace theme**: the light "Semaphore" palette, the `--codesema-*`/`--cs-*` token families, Instrument Sans and JetBrains Mono are gone, along with the Tailwind token bridge. +- **The conversations rail is one flat list**: a conversation is its title and time between two hairlines, ordered attention first, no grouping by project; a conversation may carry no project. +- **Task, event and finding states are rendered through semantic tones** (`data-tone`, `data-s`, `data-v`, `data-r`) read by CSS, instead of colour tables in TypeScript. +- **The conversation reads as one thread**: the header carries the agent-named title and the description, timestamps sit inline at 12px, the user's message is left-aligned with a `you` gutter, the preparation steps fold into one line, checks summarise per turn, inline code is marked, and the ship action is a single primary button in the header. +- **The rail is icons-only when collapsed and 30ch wide when open**; the three rail lists (conversations, repositories, code review) share the same borderless search line under the same header band. +- **Turns and reviews in flight are blue** (the machine works); amber is reserved for a human being waited on. +- **The conversation is near-monochrome**: the user's prompt is the only filled block, events separate by whitespace instead of hairlines and left rails, identity chips (project, branch, isolation, durations) are one muted meta line with the asked sentence folded behind it, badges keep a box only on a real state (open MR, non-ok verdict), and the composer is a plain frame with a prompt glyph whose send button appears once there is text. +- **Markdown renders everywhere a message shows**: the agent's streaming bubbles are rendered like settled messages, and the renderer now handles blockquotes, pipe tables and horizontal rules, with one shared `.md` style in the kit. +- **`TaskConversation.vue` and `DiffView.vue` are split** into `task-conversation/*` and `diff/*` components with a thin orchestrator each. +- **Emojis and glyphs missing from the shipped font are replaced** by the `G` glyph set (`packages/web/src/glyphs.ts`), so no line ever falls back to a second font. - **A task card stacks its four blocks in one column** (evidence, recap, checks, criteria) instead of a two-by-two grid. - **Every font size in the web UI is now one of seven `--fs-*` tokens declared once in `style.css`**, in rem, replacing 500 hard-coded px values; the dense sizes moved up (nothing below 11px, read text at 14px), and the tests refuse any new px font size in a component. - **Every screenshot and video in the evidence block opens a full-screen viewer** with wheel, button and keyboard zoom, click-to-zoom and drag-to-pan, closed by Escape. diff --git a/bun.lock b/bun.lock index c028b5e..0e9d283 100644 --- a/bun.lock +++ b/bun.lock @@ -19,7 +19,7 @@ }, "packages/cli": { "name": "codesema", - "version": "0.20.0", + "version": "0.21.0", "bin": { "codesema": "dist/index.mjs", }, @@ -35,7 +35,7 @@ }, "packages/contract": { "name": "@codesema/contract", - "version": "0.11.0", + "version": "0.12.0", "devDependencies": { "@types/node": "^26.1.1", "ajv": "^8.20.0", @@ -58,11 +58,9 @@ "vue": "^3.5.39", }, "devDependencies": { - "@tailwindcss/vite": "^4.3.3", "@types/hast": "^3.0.5", "@types/node": "^26.1.1", "@vitejs/plugin-vue": "^6.0.7", - "tailwindcss": "^4.3.3", "typescript": "^6.0.3", "vite": "^8.1.4", "vue-tsc": "^3.3.7", @@ -144,8 +142,6 @@ "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], - "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], - "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], @@ -322,36 +318,6 @@ "@superradcompany/microsandbox-win32-x64-msvc": ["@superradcompany/microsandbox-win32-x64-msvc@0.6.16", "", { "os": "win32", "cpu": "x64" }, "sha512-8vJnOkywYbrYURR3bSt21SHqo5YfyA+96jmExxlOfTlH5wRwbiBt8stnGNlbBd1BFoaPV7WxdINOiHTxuf+sHQ=="], - "@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="], - - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="], - - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.3", "", { "os": "android", "cpu": "arm64" }, "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw=="], - - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw=="], - - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw=="], - - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw=="], - - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ=="], - - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w=="], - - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA=="], - - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w=="], - - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img=="], - - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.3", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ=="], - - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ=="], - - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="], - - "@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], @@ -510,8 +476,6 @@ "empathic": ["empathic@2.0.1", "", {}, "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q=="], - "enhanced-resolve": ["enhanced-resolve@5.24.5", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A=="], - "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], @@ -546,8 +510,6 @@ "global-directory": ["global-directory@5.0.0", "", { "dependencies": { "ini": "6.0.0" } }, "sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w=="], - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], @@ -770,10 +732,6 @@ "strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="], - "tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="], - - "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], - "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], @@ -852,18 +810,6 @@ "@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], - - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], - - "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], - - "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "cliui/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "cosmiconfig-typescript-loader/jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], diff --git a/packages/cli/src/serve.ts b/packages/cli/src/serve.ts index 17f1f7d..68dd598 100644 --- a/packages/cli/src/serve.ts +++ b/packages/cli/src/serve.ts @@ -2011,6 +2011,14 @@ export function devIndexHtml(viteOrigin: string): string { codesema +
diff --git a/packages/web/design/ui-kit.html b/packages/web/design/ui-kit.html new file mode 100644 index 0000000..ccee05d --- /dev/null +++ b/packages/web/design/ui-kit.html @@ -0,0 +1,3006 @@ + + + + + + Codesema UI Kit + + + + + +
+
+ +

Codesema UI Kit

+

+ Un thème, une police, huit couleurs. Chaque composant du workspace est défini ici une + fois, dans tous ses états, puis réutilisé tel quel dans codesema-tools web. +

+
+
+ + + + + + + + + +
+
+ + +
+
+
+ + + +
+
+

Principes

+

+ Cinq règles, pas une de plus. Si un écran les respecte, il ressemble au reste sans + effort. +

+
+
règles
+
+
police
+
+ une seule, monospace, partout. La hiérarchie vient du gras et de la couleur, jamais + d'une deuxième fonte. +
+
grille
+
+ tout est un multiple de 1ch en largeur et d'une ligne + (--row) en hauteur. +
+
couleur
+
+ gris pour le calme, une seule couleur d'accent pour le focus et l'action, quatre + couleurs sémantiques pour l'état. +
+
bordures
+
1px, sans arrondi, sans ombre. La bordure d'une tuile est son état.
+
texte
+
72 caractères max par ligne, interligne 1.6, jamais de blanc pur.
+
+
+ +
+

Couleurs

+

+ Palette Tokyo Night. Les quatre premières font 95 % de l'écran ; l'accent et les + couleurs d'état sont rares, donc visibles. +

+

Fonds & texte

+
+
+ +
+ --bg#1a1b26 · fond +
+
+
+ +
+ --bg-raised#1f2335 · champs, log +
+
+
+ +
+ --bg-hover#292e42 · survol +
+
+
+ +
+ --line#3b4261 · bordures +
+
+
+ +
+ --fg#c0caf5 · texte +
+
+
+ +
+ --fg-dim#8a92bd · secondaire (AA) +
+
+
+ +
+ --fg-muted#565f89 · décoratif seulement +
+
+
+

Accent & état

+
+
+ +
+ --accent#7dcfff · focus, liens, action +
+
+
+ +
+ --info#7aa2f7 · en cours +
+
+
+ +
+ --ok#9ece6a · terminé +
+
+
+ +
+ --warn#e0af68 · en attente +
+
+
+ +
+ --err#f7768e · erreur +
+
+
+ +
+ --alt#bb9af7 · agent custom +
+
+
+
+ +
+

Typographie & espace

+

+ Police : CaskaydiaMono Nerd Font si installée, sinon Cascadia Mono depuis Google + Fonts. Une seule taille de corps ; les titres montent d'un cran, jamais deux. +

+
+
+ h1 · 24px 700 +

Titre de page

+
+
+ h2 · 18px 700 +

Titre de section

+
+
+ h3 · 14px caps +

Sous-titre

+
+
+ body · 14px / 1.6Texte courant, un lien, du code, Ctrl + K, italique, gras. +
+
+ small · 12pxLégende, horodatage, aide contextuelle. +
+
+

+ Espacement : 1ch horizontal, 1 ligne vertical. Padding d'un panneau = 1 ligne × 2ch. Gap + entre tuiles = 1ch. Rien d'autre à mémoriser. +

+
+ +
+

Panneau

+

+ Le titre vit dans la bordure, à droite par défaut. C'est le seul élément décoratif de + tout le kit, et il porte du sens : il nomme le groupe. +

+
+
+ Hardware +
+
PC
+
Inspiron 15 3520
+
cpu
+
i5-1235U
+
mem
+
5.10 GiB / 15.30 GiB (33%)
+
+
+
+ Agents +
+
roster
+
+
claude
+
2 actifs
+
codex
+
inactif
+
custom
+
reviewer
+
+
+
+
+ +
+

Tuile de tâche

+

+ Une tuile = une tâche = un worktree. La couleur de bordure dit l'état, le focus ajoute + un double trait. Aucune icône nécessaire. +

+
+
+
+ 01fix-auth-redirectidle +
+
Aucun agent assigné.
+
⎇ wt/fix-auth
+
+
+
+ 02migrate-bunrunning +
+
claude · lecture package.json › remplace npm scripts…
+
+ ⎇ wt/migrate-bunfocus · 2 +
+
+
+
+ 03add-tile-layoutrunning +
+
codex · écrit src/ui/grid.ts +124 −8
+
⎇ wt/tile-layout4m 12s
+
+
+
+ 04rename-packagewaiting +
+
claude demande : « Garder l'alias nolyra ? »
+
+ ⎇ wt/renamerépondre · Enter +
+
+
+
+ 05lint-cleanupdone +
+
3 fichiers · tests ok · prêt à merger
+
+ ⎇ wt/lintmerge · m +
+
+
+
+ 06upgrade-depserror +
+
+ bun install : conflit de peer dep sur zod@4 +
+
+ ⎇ wt/depsrelancer · r +
+
+
+
+ +
+

Statuts & badges

+

+ Le statut est un point coloré suivi d'un mot. Le badge est un mot dans un cadre fin : il + classe, il ne juge pas. +

+
+ idle + running + waiting + done + error +
+
+ worktree + claude + custom + merged + stale + conflict +
+
+ +
+

Boutons

+

+ Un seul bouton plein par écran. Le raccourci clavier est affiché dans le bouton, pas + dans une infobulle. +

+
+ + + + + +
+
+ +
+

Arbre clé / valeur

+

+ La structure fastfetch : une racine en gras, des branches en caractères de boîte. Sert + aux détails d'une tâche, d'un agent, d'un worktree. +

+
+
migrate-bun
+
tâche #02
+
agent
+
claude · opus
+
worktree
+
.codesema/wt/migrate-bun
+
branche
+
feat/migrate-bun ← main
+
diff
+
+ +312 + −140 · 9 fichiers +
+
durée
+
12m 04s
+
+
+ +
+

Journal

+

+ Sortie brute, jamais reformatée. Horodatage en gris, niveau en couleur, le reste en + texte. +

+
14:30:02 info  worktree créé  .codesema/wt/migrate-bun
+14:30:03 info  agent claude démarré (opus)
+14:31:40 ok    bun install · 412 paquets · 1.8s
+14:33:15 warn  script "postinstall" ignoré (husky → lefthook)
+14:34:01 err   bun test · 2 échecs · src/cli/init.test.ts
+14:34:02 info  agent en attente d'une réponse
+
+ +
+

Champs

+

+ Fond légèrement relevé, bordure qui passe à l'accent au focus. L'erreur est une couleur + de bordure et une ligne de texte, pas une icône. +

+
+
+ kebab-case, devient le nom de branche +
+
+ +
+
+ branche introuvable : « main » (espace final) +
+
+
+ + +
+
+ +
+

Tableau & onglets

+
+ 1Tâches + 2Worktrees + 3Agents +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#tâcheagentétatdiffdurée
01fix-auth-redirectidle
02migrate-bunclauderunning+312 −14012m 04s
03add-tile-layoutcodexrunning+124 −84m 12s
04rename-packageclaudewaiting+18 −182m 50s
05lint-cleanupclaudedone+0 −611m 07s
06upgrade-depscodexerror+2 −20m 38s
+
+
+ +
+

Notifications

+

+ Trait vertical coloré à gauche, clé en gris, message en clair, action à droite. Même + forme pour les trois niveaux. +

+
+ #05lint-cleanup mergé dans mainvoir +
+
+ #04rename-package attend une réponserépondre +
+
+ #06upgrade-deps : bun install a échouérelancer +
+
+ +
+

Workspace assemblé

+

+ Tout ce qui précède, posé ensemble. Barre du haut façon Hyprland : numéros de workspace + à gauche, horloge, état global à droite. +

+
+
+ 123 + Monday 14:34 + 2 + 1 + 1 +
+
+
+
+ 02migrate-bunrunning +
+
+ claude · opus › bun install ok › bun test : 2 échecs › corrige + src/cli/init.test.ts… +
+
⎇ wt/migrate-bun12m 04s
+
+
+
+ 03add-tile-layoutrunning +
+
codex › écrit src/ui/grid.ts › +124 −8
+
⎇ wt/tile-layout4m 12s
+
+
+
+ 04rename-packagewaiting +
+
+ claude demande : « Garder l'alias nolyra dans package.json ? » +
+
+ ⎇ wt/renamerépondre · Enter +
+
+
+
+ 06upgrade-depserror +
+
+ bun install : conflit de peer dep sur zod@4 +
+
+ ⎇ wt/depsrelancer · r +
+
+
+
+

+ Navigation prévue : 19 focus tuile, n nouvelle tâche, + d diff, m merge, Esc retour. +

+
+ +
+

Barre d'app & rail projets

+

+ Traduction de WorkspaceHeader et ProjectsNav. La cloche compte + les tâches qui attendent une réponse, le compteur d'agents ce qui tourne. +

+
+ codesema + + + 2 à répondre + 3 agents + forge hors ligne + + +
+
+
+
projets
+
+ codesema-cli2 · 3 +
+
+
⎇ feat/migrate-bun
+
⎇ fix/auth-redirect
+
!42 rename package
+
+
+ nolyra1 +
+
+ speccov +
+
+
+
+
cellules
+
+ même hauteur, même padding, séparées d'un trait. Un chiffre en clair, le libellé + en gris. +
+
● vert
+
au moins un agent actif sur le projet
+
○ gris
+
projet au repos
+
2 · 3
+
2 attendent une réponse, 3 en cours
+
réglages
+
bouton dans la barre, s'inverse quand le panneau est ouvert
+
+
+
+
+ +
+

File de travail

+

+ Les cartes de WorkQueue, groupées en quatre sections fixes. Le trait gauche + porte le statut, les boutons n'apparaissent que là où une action est possible. +

+
+
⚠ besoin de toi2
+
+ rename-package + « Garder l'alias nolyra dans package.json ? » + codesema-cli⎇ wt/renameclaude · opusattend depuis 4m +
+
+ upgrade-deps + review : 1 critique, 2 majeurs + codesema-cli⎇ wt/depscodex +
+
en cours3
+
+ migrate-bun + + codesema-cli⎇ wt/migrate-bunclaude · opus12m 04s +
+
+ lint-cleanup-2 + file d'attente · position 2nolyra +
+
prêt à expédier1
+
+ lint-cleanup + codesema-cli⎇ wt/lintchecks ✓+0 −61 +
+
▸ terminé14
+
+

Les 9 statuts de tâche

+
+ queueden attente d'un créneau runningagent au travail + ?waiting_for_youquestion posée, humain requis + reviewingreview automatique en cours + review_okprêt à expédier review_kofindings bloquants + shippedpoussé / mergé failederreur, voir la raison + interruptedarrêté par l'utilisateur +
+

+ Même glyphes que execution-status.ts aujourd'hui. Seules les couleurs + changent : elles viennent des tokens. +

+
+ +
+

Conversation

+

+ Le cœur de TaskConversation : en-tête avec actions, trois onglets, fil de + messages, groupe d'outils repliable, question avec réponses rapides, bulle en cours + d'écriture, composeur. +

+
+
+ rename-package + 📌 + + codesema-cli⎇ feat/rename🛡 conteneurattend une réponsetravail 6m 12s · attente 4m 03s +
+
+ ConversationDiff 3Checks ✓ +
+
+
+ toiRenomme le paquet nolyra → codesema partout, garde l'historique git propre. +
+
+ agentJe commence par lister les occurrences, puis je renomme en un seul commit. +
+
+ + outils — 4 appels · rg, 2 × edit, bun + test + +
+ rg nolyra --files-with-matches0.1s +
+
+ 7 fichiers +
+
+ edit package.json +
+
+ edit README.md +
+
+ bun test4.2s +
+
+ 42 pass, 0 fail +
+
+
+ + l'agent travaille… — lecture de + src/cli/init.ts + +
+ read src/cli/init.ts +
+
+
+ Le champ bin.nolyra est utilisé par 3 scripts externes. Garder + l'alias ? +
+ +
+
+
+ agentEn attendant, je prépare le changelog : « Renommage nolyra → codesema, alias + conservé jusqu'à la +
+
+ review · lecture du diff · 3 fichiers0m 41s +
+
+
+ réponse en attente : « garde l'alias » sera envoyée quand l'agent aura fini +
+
+ + + mode question : la réponse débloque l'agent. En mode file, elle part après le tour + en cours. Tâche terminée = composeur remplacé par « reprendre ». +
+
+
+ +
+

Nouvelle tâche & plan

+

+ TaskComposer : prompt, agent, expédition automatique, et le panneau de plan + qui dit exactement ce qui va être créé avant de lancer. +

+
+
+ +
+ + + +
+
+
+

plan

+
+
mode
+
fork depuis main
+
branche
+
feat/migrate-bun (certaine)
+
worktree
+
.codesema/wt/migrate-bun
+
isolation
+
politique · conteneur indisponible
+
agent
+
claude · opus
+
file
+
position 1, démarre tout de suite
+
issue
+
aucune
+
+
+
+
+ +
+

Diff & notes de review

+

+ DiffView : en-tête par fichier, gouttières, trous repliés, notes ancrées + sur une ligne. Le trait gauche de la note porte le kind, le mot porte la + sévérité. +

+
+
+ 3 fichiers · +20 + −6 · 2 notes + +
+
+ src/cli/init.ts✦ 2+18 −4 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
41 lignes
4242export async function init(opts: InitOptions) {
43 + - const pkg = JSON.parse(readFileSync('package.json', 'utf8')); +
43+ const pkg = await readPackage(opts.cwd);
44+ if (!pkg.name) throw new Error('package.json sans name');
+
+
+ securitymajorChemin non validé avant lectureA + B +
+

+ opts.cwd vient de l'utilisateur : un ../ sort du + dépôt. +

+
+const cwd = path.resolve(root, opts.cwd);
+if (!cwd.startsWith(root)) throw new Error('cwd hors du dépôt');
+
+ +
+
+
4445const bin = pkg.bin ?? {};
+
+
+ praiseinfoLecture asynchrone, bon réflexeA +
+
+
4546for (const [name, target] of Object.entries(bin)) {
12 lignes
+
+
+ package.json+2 −2 +
+
+ README.md+0 −0 +
+
+

Sévérité · kind

+
+ criticalmajorminorinfo +
+
+
+ securityfaille, donnée non validée +
+
+ perfcoût inutile +
+
+ conventionstyle, nommage +
+
+ designstructure, découpage +
+
+ praiseà garder tel quel +
+
+ whyquestion sur l'intention +
+
+
+ +
+

Checks

+

+ Onglet Checks : un badge global, un vérificateur par ligne, la sortie repliée. « Jamais + lancé » n'est pas « passé ». +

+
+ checks ✕head 3f2a9c1 · il y a 2 min · source lefthook +
+
+
+ bun run typecheckexit 03.1s +
+
+ bun run lintexit 01.4s +
+
+ bun testexit 14.2s +
+ sortie (12 dernières lignes) +
 src/cli/init.test.ts > refuse un cwd hors dépôt
+  Expected: throw
+  Received: undefined
+42 pass · 1 fail
+
+
+
+ bun run e2etimeout120s +
+
+ bun run buildignoré +
+
+
+ Checks jamais lancésaucune commande configurée · + laisser l'agent proposer une configuration +
+
+ +
+

Verdict & parcours de review

+

+ ReviewShell, StepRail, StepList : un feu + tricolore, une suite d'étapes, une carte par étape avec son risque. +

+
+ à vérifier4 findings · 1 major · + 2 minor · + 1 info·+312 −140 +
+
+ goà vérifierstop +
+
+ MR + 1 lecture + 2 init.ts + 3 scripts + 4 tests + merge +
+
+ 02Lecture asynchrone du package.jsonrisque moyenRemplace le readFileSync par un helper. Touche 2 fichiers, 1 finding. +
+
+ 03Réécriture des scripts npm → bunrisque élevéLe script postinstall disparaît. 4 fichiers, 2 findings. +
+
+ +
+

États système

+

+ Vide, dégradé, confirmation par armement. La règle du code actuel reste : un manque est + nommé, jamais caché. +

+
+ Aucune tâche dans ce projetn pour en créer une, ou glisse une issue + depuis le rail. +
+
+ connexion perdue · nouvelle tentative dans 3s +
+
+ forge injoignable : GITLAB_TOKEN absent. Les MR ne sont pas listées. +
+
+ → second clic →pas de modale, le bouton change de libellé +
+
+ coût inconnu :jamais « 0 $ »·coût borne basse :≥ 0.42 $ +
+
+
+
+ + + + diff --git a/packages/web/index.html b/packages/web/index.html index 8821d8e..3cdfe75 100644 --- a/packages/web/index.html +++ b/packages/web/index.html @@ -4,6 +4,14 @@ codesema +
diff --git a/packages/web/package.json b/packages/web/package.json index 901c086..4fd4f63 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -20,11 +20,9 @@ "vue": "^3.5.39" }, "devDependencies": { - "@tailwindcss/vite": "^4.3.3", "@types/hast": "^3.0.5", "@types/node": "^26.1.1", "@vitejs/plugin-vue": "^6.0.7", - "tailwindcss": "^4.3.3", "typescript": "^6.0.3", "vite": "^8.1.4", "vue-tsc": "^3.3.7" diff --git a/packages/web/public/fonts/cascadia-mono-latin.woff2 b/packages/web/public/fonts/cascadia-mono-latin.woff2 new file mode 100644 index 0000000..ab487c5 Binary files /dev/null and b/packages/web/public/fonts/cascadia-mono-latin.woff2 differ diff --git a/packages/web/public/fonts/instrument-sans-latin.woff2 b/packages/web/public/fonts/instrument-sans-latin.woff2 deleted file mode 100644 index 8611e41..0000000 Binary files a/packages/web/public/fonts/instrument-sans-latin.woff2 and /dev/null differ diff --git a/packages/web/public/fonts/jetbrains-mono-latin.woff2 b/packages/web/public/fonts/jetbrains-mono-latin.woff2 deleted file mode 100644 index 4d09cda..0000000 Binary files a/packages/web/public/fonts/jetbrains-mono-latin.woff2 and /dev/null differ diff --git a/packages/web/src/App.vue b/packages/web/src/App.vue index 5233cc2..99e62cb 100644 --- a/packages/web/src/App.vue +++ b/packages/web/src/App.vue @@ -1,11 +1,9 @@ @@ -92,24 +78,7 @@ onUnmounted(stop) .app-nav { display: flex; justify-content: flex-end; - padding: 14px 20px 0; -} - -.app-nav-btn { - font-size: var(--fs-base); - font-weight: 600; - font-family: inherit; - padding: 6px 12px; - border-radius: 8px; - border: 1px solid var(--codesema-line); - background: var(--codesema-panel); - color: var(--codesema-ink-2); - cursor: pointer; - transition: border-color 0.12s ease; -} - -.app-nav-btn:hover { - border-color: var(--codesema-ink-3); + padding: var(--row) 2ch 0; } .app-state { @@ -118,44 +87,10 @@ onUnmounted(stop) flex-direction: column; align-items: center; justify-content: center; - gap: 14px; - font-size: var(--fs-base); + gap: var(--row); } .app-error { - color: var(--codesema-risk-high); - margin: 0; -} - -.app-retry { - font-size: var(--fs-base); - font-weight: 600; - font-family: inherit; - padding: 7px 14px; - border-radius: 8px; - border: 1px solid var(--codesema-line); - background: var(--codesema-panel); - color: var(--codesema-ink-2); - cursor: pointer; - transition: border-color 0.12s ease; -} - -.app-retry:hover { - border-color: var(--codesema-ink-3); -} - -.app-spinner { - width: 22px; - height: 22px; - border-radius: 50%; - border: 2.5px solid var(--codesema-line); - border-top-color: var(--codesema-accent); - animation: app-spin 0.8s linear infinite; -} - -@keyframes app-spin { - to { - transform: rotate(360deg); - } + color: var(--err); } diff --git a/packages/web/src/components/DiffView.vue b/packages/web/src/components/DiffView.vue index 73a5f4e..b13d4d6 100644 --- a/packages/web/src/components/DiffView.vue +++ b/packages/web/src/components/DiffView.vue @@ -1,16 +1,9 @@ diff --git a/packages/web/src/components/DualConsensusMap.vue b/packages/web/src/components/DualConsensusMap.vue index 422d42c..c8079f3 100644 --- a/packages/web/src/components/DualConsensusMap.vue +++ b/packages/web/src/components/DualConsensusMap.vue @@ -2,6 +2,7 @@ import { computed } from 'vue' import { buildConsensusTree } from '../composables/useConsensusTree' import { sameFile } from '../composables/useDiff' +import { G } from '../glyphs' import type { LiveInput, PartialReview } from '../types' import DualMapNode from './DualMapNode.vue' @@ -50,9 +51,17 @@ const tree = computed(() => buildConsensusTree(previewRows.value)) class="dmap-row" :class="{ 'dmap-row--hot': row.hot }" > - - - + {{ row.path }} @@ -67,118 +76,85 @@ const tree = computed(() => buildConsensusTree(previewRows.value)) diff --git a/packages/web/src/components/DualJudgePanel.vue b/packages/web/src/components/DualJudgePanel.vue index ce2fabd..0bbfa2c 100644 --- a/packages/web/src/components/DualJudgePanel.vue +++ b/packages/web/src/components/DualJudgePanel.vue @@ -1,5 +1,6 @@