Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,6 @@ jobs:
run: npx knip --workspace apps/desktop
- name: Knip (packages/ui)
run: npx knip --workspace packages/ui
# Dead-CSS governance. Lived only under `check:release`, so a regression
# stayed invisible until a release was cut; it was red on main when this
# step was added. Same class of source-scanning guard as knip above.
- name: Dead CSS
run: node scripts/check-dead-css.mjs --check
# Storybook fidelity: every Product/* story must name the real user path
# to the state it renders. Presence is mechanical; truth stays with the
# reviewer. See apps/desktop/stories/FIDELITY.md.
- name: Story annotations
run: node scripts/check-story-annotations.mjs

test_workspaces:
needs: changes
if: needs.changes.outputs.standard_workspaces != ''
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/renderer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ Acknowledged transitional states — not TODOs; track work in issues/PRs.
## Contracts & guardrails

- Product design intent: `DESIGN.md`.
- CSS cascade / layer / `!important` / dead-CSS / token rules: `docs/frontend-css-governance.md`. The dead-CSS check runs from the repo root via `check:release` (`scripts/check-dead-css.mjs --check`); its baseline is `scripts/check-dead-css-baseline.json`.
- CSS cascade / layer / `!important` / dead-CSS / token rules: `docs/frontend-css-governance.md`.
- Component state, ARIA, token, and copy behavior is owned by source and focused contract tests.
- Where prose disagrees with code or behavioral tests, code and tests are the source of truth. CSS conventions are checked by review, focused `scripts/check-*.mjs` commands, and rendered-surface verification; the former source-scanning CSS contract suite has been removed. Build/test entry points are the npm scripts in the root `package.json` (see the top-level `README.md`).
- Where prose disagrees with code or behavioral tests, code and tests are the source of truth. CSS conventions are checked by review and rendered-surface verification. Build/test entry points are the npm scripts in the root `package.json` (see the top-level `README.md`).
3 changes: 1 addition & 2 deletions apps/desktop/src/renderer/maka-tokens.css
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,7 @@
The product used to alias four ladder rungs here — heading 16 / stat 20 /
ui 14 / caption 12 — so a call site could name a size. A call site names a
ROLE now (see the role table below), and the size is the role's own atom,
so all four reached zero consumers and are gone; check-dead-css found
them, and type-scale-contract.test.ts asserts they stay gone.
so all four reached zero consumers and are gone.

The ladder they aliased is still the authority: it is generated by the
Astryx type scale in astryx-theme/makaTheme.ts (`{base: 14, ratio: 1.125}`),
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/stories/FIDELITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ So each story carries a `// Real path:` comment directly above it, naming how a
export const Populated: Story = { … }
```

The annotation is prose on purpose. Its value is that someone traced the path and wrote it down; a machine-checkable schema would be satisfied by a plausible-looking lie just as easily. So the convention splits along what a machine can decide. `scripts/check-story-annotations.mjs` checks that the sentence *exists*, and fails on any export it cannot classify rather than skipping it — write stories as `export const Name: Story = …` and nothing else. **It cannot tell you the sentence is true.** Only a reviewer following the call chain can, and reviewing that sentence is the point of writing it. The script's header explains why it stops there.
The annotation is prose on purpose. Its value is that someone traced the path and wrote it down; a mechanical presence check would be satisfied by a plausible-looking lie just as easily. Only a reviewer following the call chain can determine whether it is true.

Two of the first batch of annotations were wrong, and both were caught by reading rather than by running anything: one named a path through a builder that cannot produce the state (`CommandPaletteDisabledCommand`), and one named two hosts for a frame that is only one of them. Write the sentence narrow enough to be falsifiable — the host, the builder, the gate — because a sentence vague enough to always be true buys nothing.

Expand Down
25 changes: 8 additions & 17 deletions docs/frontend-css-governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,18 @@ Astryx reset and component layers come first; Maka base tokens and product `comp
- Component-local properties are allowed only with a `/* local: ... */` comment.
- Do not add raw colors, radii, or ungoverned z-index values.

## 6. Dead CSS
## 6. How these rules are checked

- `scripts/check-dead-css.mjs` scans `apps/desktop/src/renderer/styles/**/*.css` and `apps/desktop/src/renderer/reference-shell.css`.
- Runtime-generated class names that static search cannot find must be explicitly allowlisted.
- Change `scripts/check-dead-css-baseline.json` only after review confirms the class-count change.

## 7. How these rules are checked

The rules above are conventions enforced in review, plus the fast scripts that
survive as their own commands — `check-dead-css`, `check-a11y`, and
`check-console`. The source-scanning contract suite that used to re-assert them
as tests is gone: it charged every refactor a rewrite of its own guards while
catching only what a linter should.
These rules are conventions enforced in review. Static correctness belongs to
Biome, Knip, and typecheck; accessibility keeps its focused check. CSS usage and
Story prose are not decided by repository-wide regex baselines.

- Renderer CSS behavior is verified where it renders: Storybook, the app, or an
e2e assertion on the real surface.
- A rule worth machine-enforcing belongs in a `scripts/check-*.mjs` (fast,
one job, no build) rather than a test that regexes the source tree.
- Remove selectors with the source or surface that owned them instead of
maintaining an allowlist of strings that may be generated at runtime.

## 8. Change order
## 7. Change order

When changing renderer CSS:

Expand All @@ -65,9 +57,8 @@ When changing renderer CSS:
3. Remove dead selectors.
4. Remove remaining `!important` only after primitive and layer ownership is stable.

## 9. Governing principles
## 8. Governing principles

- Make CI guards trustworthy before structural convergence.
- Delete dead CSS before aesthetic refactoring.
- Resolve shared `Button`, `Textarea`, and `EmptyState` overrides at the component API seam instead of accumulating renderer specificity.
- Every change to cascade order requires the narrowest relevant regression check on the rendered surface.
24 changes: 6 additions & 18 deletions docs/frontend-css-governance.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,15 @@ Astryx reset 和组件层在前,Maka base token 与产品 `components` 在后
- radius
- 未纳入约束体系的 z-index

## 6. Dead CSS 规则
## 6. 这些规则靠什么保证

- dead CSS 检查脚本是:
- `scripts/check-dead-css.mjs`
- 当前扫描范围包括:
- `apps/desktop/src/renderer/styles/**/*.css`
- `apps/desktop/src/renderer/reference-shell.css`
- 如果某个 class 是运行时动态生成、源码静态搜索不到,必须在脚本 allowlist 中明确登记。
- 如果 dead class 数量变化,只有在评审明确确认的前提下,才允许修改 `scripts/check-dead-css-baseline.json`。

## 7. 这些规则靠什么保证

靠评审时的约定,加上仍然独立存在的快速脚本:`check-dead-css`、`check-a11y`、
`check-console`。原来用测试把这些规则再断言一遍的源码扫描套件已经
删除——它让每次重构都要顺手改写自己的护栏,抓到的却只是 linter 该抓的东西。
这些规则靠评审保证。静态正确性交给 Biome、Knip 和 typecheck;accessibility
保留聚焦的检查。CSS 使用关系和 Story 文案不再由全仓 regex baseline 决定。

- renderer CSS 的行为在它真正渲染的地方验证:Storybook、app,或对真实界面的 e2e 断言。
- 真的值得机器强制的规则,写成 `scripts/check-*.mjs`(快、单一职责、不依赖构建),
而不是写成一个正则扫源码树的测试。
- selector 应随其 source 或 surface 一起删除,不维护运行时字符串 allowlist。

## 8. 推荐改动顺序
## 7. 推荐改动顺序

调整 renderer CSS 时,建议按下面顺序推进:

Expand All @@ -76,7 +64,7 @@ Astryx reset 和组件层在前,Maka base token 与产品 `components` 在后
3. 清理 dead selector。
4. 只有在 primitive / layer 架构已经稳定后,再移除剩余 `!important`。

## 9. 当前治理原则
## 8. 当前治理原则

- 先保证 CI 护栏可信,再做结构收敛。
- 先删 dead CSS,再谈样式“美化性重构”。
Expand Down
2 changes: 1 addition & 1 deletion docs/settings-astryx-deep-review.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
Badge;彩色药丸只保留真正的计数/枚举 `Token`。
4. **逐页清理 C4/C5/C6**(按第三节清单),记忆页单独做(动作收纳进
`MoreMenu`、条目行化)。
5. **验证闭环**:四组合(zh/en × light/dark)截图全过;check-dead-css 归零
5. **验证闭环**:四组合(zh/en × light/dark)截图全过;dead CSS review 归零
(预计再删 memory.css/permission.css/health.css 大半);typecheck + 全检查。

预计削减:settings 专属 CSS 从 ~1900 行降到 <600 行;页面代码同步变薄。
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"check:stale": "node scripts/check-stale-dist.mjs",
"generate:third-party-notices": "node scripts/generate-third-party-notices.mjs",
"check:third-party-notices": "node scripts/generate-third-party-notices.mjs --check",
"check:release": "npm run check:stale && npm run check:third-party-notices && node scripts/check-dead-css.mjs --check",
"check:release": "npm run check:stale && npm run check:third-party-notices",
"package:macos-arm64": "node scripts/package-macos-arm64.mjs",
"verify:macos-arm64": "node scripts/verify-macos-arm64-dmg.mjs",
"package:windows-x64": "node scripts/package-windows-x64.mjs",
Expand Down
6 changes: 1 addition & 5 deletions packages/ui/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -749,11 +749,7 @@
`.maka-tool-terminal-*` family is currently unreachable:
`previewVariants({part: 'terminal-*'})` has no call site — `TerminalPreview`
renders `maka-tool-output-stack` / `ShellOutputBody` / `ToolCodeBlock`
instead — and `check-dead-css` cannot see that because the literals still
exist in `previewVariants`. The alternative is an exemption whose reason is
"nothing renders this", which is a fact about call sites recorded in a
stylesheet and would outlive the day someone wires the family back up.
Deleting the family is its own change. */
instead. Deleting the family is its own change. */
.maka-tool-terminal-exit {
font: var(--maka-text-heading-5);
height: var(--h-control-sm); display: inline-flex; align-items: center; white-space: nowrap; padding: 1px var(--space-1-5); border-radius: var(--radius-pill); background: var(--foreground-5); color: var(--foreground-secondary); letter-spacing: var(--tracking-wide); }
Expand Down
5 changes: 0 additions & 5 deletions scripts/check-dead-css-baseline.json

This file was deleted.

Loading
Loading