From fd81656c3d119cbf91ebcab7b10ba53abbae0b93 Mon Sep 17 00:00:00 2001 From: Yunfei He Date: Mon, 15 Jun 2026 00:08:12 +0800 Subject: [PATCH] docs: adopt Project Context Records (PCR) for agent docs (#188) Replace the homegrown "Context Engineering" convention with the canonical Project Context Records (PCR) block in AGENTS.md, and migrate the .agents/docs/ records to match. - cross-links: [[wiki-link]] -> relative markdown [name](./name.md) - provenance: the old "Maintainer decision (DATE): KEEP" markers -> canonical [VOUCHED @hyf0] stamps (dates dropped, KEEP/OVERRIDE verdicts kept), covering every variant ((DATE, user-blessed), (maintainer decision DATE), and "(Decision recorded after review surfaced it.)") - methodology prose describing the mechanism reworded to the vouch vocabulary (generic [VOUCHED @handle]) Co-authored-by: Claude Opus 4.8 (1M context) --- .agents/docs/accessibility-api.md | 8 ++-- .agents/docs/api-contract.md | 8 ++-- .agents/docs/component-authoring.md | 6 +-- .agents/docs/ink-divergences.md | 69 ++++++++++++++--------------- AGENTS.md | 34 ++++++++------ 5 files changed, 66 insertions(+), 59 deletions(-) diff --git a/.agents/docs/accessibility-api.md b/.agents/docs/accessibility-api.md index 545ea5a..96a8d95 100644 --- a/.agents/docs/accessibility-api.md +++ b/.agents/docs/accessibility-api.md @@ -1,11 +1,11 @@ # Accessibility (ARIA + screen-reader) API How vue-tui exposes ARIA and renders screen-reader (SR) output, and why. Companion to the -aria-camelCase blessed entry in [[ink-divergences]]; `renderToString` being layout-only and the +aria-camelCase vouched entry in [ink-divergences](./ink-divergences.md); `renderToString` being layout-only and the `useWindowSize` name are now Ink parity (not divergences), and the reactive-refs return shape is covered by the shallowRef entry there. This file keeps the _why_ and the researched / run-verified findings those entries deliberately omit, so they are not re-derived expensively. The exported aria -types are part of the public contract — see [[api-contract]]. +types are part of the public contract — see [api-contract](./api-contract.md). ## The constraint that shapes everything @@ -29,7 +29,7 @@ to receive them and no browser to read them. `aria-role` ports from Ink/HTML unchanged — it is the runtime-compatible escape, not the type-safe path. - This is a Vue-idiom + reasonableness choice, **not parity** (Ink is kebab). See the - "Why align to Ink — and when not to" principle in [[ink-divergences]]. + "Why align to Ink — and when not to" principle in [ink-divergences](./ink-divergences.md). ## Type-safety boundary (run-verified: `tsc` + `vue-tsc`) @@ -80,7 +80,7 @@ sees the non-empty string as truthy) where ARIA says visible; bare / `={true}` h suite — the public string API does not surface SR (Ink also keeps its SR-string rendering test-internal). - **`renderScreenReaderOutput(node)`:** the linearizer that walks the host tree's - `internal_accessibility`. **`/internal`-only** (maintainer decision 2026-06-14). Ink keeps its + `internal_accessibility`. **`/internal`-only** [VOUCHED @hyf0]. Ink keeps its counterpart (`renderNodeToScreenReaderOutput`) module-internal and never exports it; we match that. It was never usefully public anyway — its only parameter type (`TuiNode`) and the node-construction primitives needed to build one are not in the public barrel, so a public diff --git a/.agents/docs/api-contract.md b/.agents/docs/api-contract.md index 8bfbb89..305b170 100644 --- a/.agents/docs/api-contract.md +++ b/.agents/docs/api-contract.md @@ -1,7 +1,7 @@ # Public API contract & surface What is — and isn't — part of `@vue-tui/runtime`'s public contract, and how the contract is -tested. (Behavioral _divergences_ from Ink live in [[ink-divergences]]; this file is about the +tested. (Behavioral _divergences_ from Ink live in [ink-divergences](./ink-divergences.md); this file is about the SHAPE of the public surface itself.) ## The contract = public exports **and their user-consumable types** @@ -24,7 +24,7 @@ Because it is contract, it is **tested, not merely shipped**: `@ts-expect-error`. Type-only exports are erased at runtime, so the _type_ surface is guarded individually rather than exhaustively snapshotted. - Type-_safety_ behavior is established by RUNNING the type-checker against real usage (`tsc` for - TSX, `vue-tsc` for templates), never assumed. See [[accessibility-api]] for a worked example — + TSX, `vue-tsc` for templates), never assumed. See [accessibility-api](./accessibility-api.md) for a worked example — which aria spellings the compiler does and does not catch, proven with both tools. ## `/internal` is NOT the contract @@ -42,7 +42,7 @@ Placement rule for any export: Packaging/build internals (the `exports` field shape, `.mjs` paths, `dist` layout) are likewise **not** part of the behavioral/type contract and are not aligned to Ink — see the alignment-scope -note in [[ink-divergences]]. +note in [ink-divergences](./ink-divergences.md). ### Accepted incidental exposure: `TuiNode` via `TuiApp` @@ -53,4 +53,4 @@ non-fix, not a contract**: `_container` is a Vue-internal field no consumer uses is cosmetic (zero functional impact), and type-only surface isn't held to strict SemVer. Narrowing it (`App` / a `Pick` allowlist) was considered and skipped as ceremony for a cosmetic gain on a pre-1.0 library. Treat `TuiNode`-through-`TuiApp` as out-of-contract; don't -re-flag it. (Decision recorded after review surfaced it.) +re-flag it. [VOUCHED @hyf0] diff --git a/.agents/docs/component-authoring.md b/.agents/docs/component-authoring.md index 7def710..e9bb4bd 100644 --- a/.agents/docs/component-authoring.md +++ b/.agents/docs/component-authoring.md @@ -30,8 +30,8 @@ The deciding distinction — get this right and the split falls out: → **provide/inject**, never parent-walking or `.name` matching. `Text` and `Transform` `provide(TextContextKey, true)`; `Text` and `Newline` `inject` it. Template-friendly, matches vue-tui's existing `AppContextKey` / `FocusContext` style, and is the - maintainer-endorsed Vue idiom (provide/inject outnumbers slot inspection 4–20× in the - libraries surveyed). It replaced the old, duplicated `getCurrentInstance()` parent walk. + well-established Vue idiom (provide/inject outnumbers slot inspection 4–20× in the + libraries surveyed). It replaced the old, duplicated `getCurrentInstance()` parent walk. [VOUCHED @hyf0] - **"What are my children's actual contents?"** (filter inert/`Comment` vnodes, detect emptiness) → **render function** + `slots.default()`. A `