diff --git a/content/docs/guide/architecture-overview.md b/content/docs/guide/architecture-overview.md index efd06396a7..3ae4afafff 100644 --- a/content/docs/guide/architecture-overview.md +++ b/content/docs/guide/architecture-overview.md @@ -13,7 +13,7 @@ ObjectUI enforces a strict separation across three layers. Each layer has clear ``` ┌─────────────────────────────────────────────────────────────────────┐ -│ Layer 1: @objectstack/spec ^4.0.4 (The Protocol) │ +│ Layer 1: @objectstack/spec (The Protocol) │ │ Pure TypeScript type definitions — 12 export modules │ │ ❌ No runtime code. No React. No dependencies. │ └──────────────────────────────┬──────────────────────────────────────┘ @@ -32,7 +32,7 @@ ObjectUI enforces a strict separation across three layers. Each layer has clear ### Layer 1 — `@objectstack/spec` (The Protocol) -The upstream JSON specification for all ObjectStack products. ObjectUI **imports** these types but never redefines them. Located externally; consumed as `@objectstack/spec ^4.0.0`. +The upstream JSON specification for all ObjectStack products. ObjectUI **imports** these types but never redefines them. Located externally and consumed as `@objectstack/spec`; the range each package installs is declared in that package's own `package.json`, under `dependencies`. ### Layer 2 — `@object-ui/types` (The Bridge) diff --git a/content/docs/guide/architecture.md b/content/docs/guide/architecture.md index 705efb64d9..105722ffce 100644 --- a/content/docs/guide/architecture.md +++ b/content/docs/guide/architecture.md @@ -314,7 +314,7 @@ import { cn } from '@/lib/utils' ## Type Safety -ObjectUI is built with **TypeScript 5.0+** in strict mode: +ObjectUI is built with **TypeScript** in strict mode: ```typescript import type { ComponentSchema, ButtonSchema } from '@object-ui/types' diff --git a/content/docs/utilities/create-plugin.mdx b/content/docs/utilities/create-plugin.mdx index c76cc2577c..23dd80a5fa 100644 --- a/content/docs/utilities/create-plugin.mdx +++ b/content/docs/utilities/create-plugin.mdx @@ -133,28 +133,22 @@ export interface AwesomeComponentProps { ### `package.json` -Pre-configured with all necessary settings: - -```json -{ - "name": "@object-ui/plugin-awesome", - "version": "0.1.0", - "description": "An awesome plugin for ObjectUI", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "files": ["dist"], - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "test": "vitest" - }, - "peerDependencies": { - "@object-ui/core": "^0.3.0", - "@object-ui/components": "^0.3.0", - "react": "^18.0.0" - } -} -``` +Pre-configured with all necessary settings: the package identity (`name`, `version`, +`type`, `license`, `description`), the build entry points (`main`, `module`, `types` and +an `exports` map covering both the ES and the UMD bundle), and its `scripts`. + +It also writes three dependency groups: + +- `dependencies` — four `@object-ui` workspace packages plus an icon library, written as + workspace links rather than as published version ranges. Note the field: the generator + puts these under **`dependencies`**, not under `peerDependencies`. +- `peerDependencies` — `react` and `react-dom`, left for the host application to supply. +- `devDependencies` — what the generated Vite build and its tests need. + +Do not transcribe version ranges out of this page into a hand-written manifest. They are +written by one template — the manifest literal in +[`packages/create-plugin/src/index.ts`](https://github.com/objectstack-ai/objectui/blob/main/packages/create-plugin/src/index.ts) — +and reading them there is the only way to see what your scaffold will actually contain. ## Development Workflow diff --git a/packages/layout/README.md b/packages/layout/README.md index 16aaaf78f2..9e588651e9 100644 --- a/packages/layout/README.md +++ b/packages/layout/README.md @@ -17,9 +17,9 @@ pnpm add @object-ui/layout ``` **Peer Dependencies:** -- `react` >= 18.0.0 -- `react-dom` >= 18.0.0 -- `react-router-dom` >= 6.0.0 +- `react` ^18.0.0 || ^19.0.0 +- `react-dom` ^18.0.0 || ^19.0.0 +- `react-router-dom` ^6.0.0 || ^7.0.0 ## Components diff --git a/packages/plugin-chatbot/README.md b/packages/plugin-chatbot/README.md index 6c4582a544..ec59545a9f 100644 --- a/packages/plugin-chatbot/README.md +++ b/packages/plugin-chatbot/README.md @@ -55,7 +55,7 @@ function App() { ### AI Streaming Mode (service-ai) When `api` is set in the schema, the chatbot connects to a backend SSE endpoint -using `@ai-sdk/react` v3 (Vercel UI Message Stream protocol) for streaming, +using `@ai-sdk/react` v4 (Vercel UI Message Stream protocol) for streaming, tool-calling, and production-grade chat: ```tsx diff --git a/scripts/__tests__/doc-version-claims.test.ts b/scripts/__tests__/doc-version-claims.test.ts index 44f765e21b..68a29827fd 100644 --- a/scripts/__tests__/doc-version-claims.test.ts +++ b/scripts/__tests__/doc-version-claims.test.ts @@ -44,12 +44,21 @@ import { fileURLToPath } from 'node:url'; * * 221 files scanned, 38 literals matched, 11 structurally exempt, 27 inventoried. * - * Of the 27, NINE are measurably wrong today and are recorded as `stale` below — + * Of the 27, NINE were measurably wrong at that cut and were recorded as `stale` — * including `@objectstack/spec ^4.0.4` in the architecture overview's layer diagram, - * thirteen majors behind the `^17.0.0-rc.5` every manifest declares. None is fixed - * here: objectui#3697 is a test-only task and every repair is a docs edit. They are - * filed separately; inventorying a known-false line with `kind: 'stale'` records the - * debt instead of blessing it, and still stops a tenth from joining them silently. + * thirteen majors behind the `^17.0.0-rc.5` every manifest declares. None was fixed by + * objectui#3697 itself: that was a test-only task and every repair is a docs edit, so + * they were filed separately. Inventorying a known-false line with `kind: 'stale'` + * recorded the debt instead of blessing it, and still stopped a tenth from joining + * them silently. + * + * EIGHT of those nine have since been paid off — objectui#3708 (the two spec claims and + * the TypeScript one), #3709 (the three scaffolder-output lines) and #3710 (layout's + * peer line and plugin-chatbot's `@ai-sdk/react` major). Their entries left this file in + * the same change, which is the downward half of the ratchet doing its job rather than + * a courtesy. One `stale` entry remains, `packages/plugin-report/README.md`, and it is + * the one repair that belongs on the MANIFEST side: objectui#3690 widens the package's + * `peerDependencies.react`, after which the README is correct without being touched. * * ## Fences are SCANNED — the opposite of `check-doc-links.mjs`, on purpose * @@ -63,13 +72,16 @@ import { fileURLToPath } from 'node:url'; * be designed out. This gate has one, so a false positive costs a single line saying * "illustrative sample, not a claim" — while a miss costs the whole #3645 family again. * The measurement makes the trade concrete: stripping fences drops 12 of the 38 hits, - * and among the dropped are two of the worst live defects — + * and among the dropped were the two worst defects the census found — both of them + * since repaired, which is the argument's strongest evidence rather than a reason to + * delete it. A fence-stripping gate would have reported green over both of these: * - * - `architecture-overview.md:16`, the layer diagram, states `@objectstack/spec ^4.0.4` - * inside an ASCII box (a fence), 13 majors stale; - * - `create-plugin.mdx:152` documents the scaffolder's output as pinning - * `@object-ui/core` `^0.3.0`, when `packages/create-plugin/src/index.ts:143` actually - * writes `workspace:*` dependencies and no such peer at all. + * - `architecture-overview.md`, the layer diagram, stated `@objectstack/spec ^4.0.4` + * inside an ASCII box (a fence), 13 majors stale — fixed by objectui#3708; + * - `create-plugin.mdx` documented the scaffolder's output as pinning + * `@object-ui/core` `^0.3.0`, when the manifest literal in + * `packages/create-plugin/src/index.ts` actually writes workspace-link dependencies + * and no such peer at all — fixed by objectui#3709. * * So: scan fences, absorb the samples in the inventory. The residual hole is stated * rather than implied — a version literal in a file OUTSIDE the two scan roots is @@ -313,10 +325,14 @@ const keyOf = (c: Pick): string => `${c.file} :: ${c.cl * * `anchored` - true today AND checkable against a machine-readable truth in this * tree, so a reviewer can re-verify it in one command. - * `restatement` - a package README restating its OWN package.json. Formally a subclass - * of `anchored`, kept separate because it is the largest class (11 of - * 27) and the one already drifting: this is where a gate that pinned - * README to manifest would pay off next. + * `restatement` - a README restating its OWN package.json. Formally a subclass of + * `anchored`, kept separate because it is the largest class (12 of 21) + * and the one that had already drifted: the two drifted members were + * repaired by objectui#3710 and re-filed here as restatements. Note + * what this class does and does not buy — the equality it names is + * re-verified by a HUMAN reading the manifest, not by this gate, which + * only asks whether a literal was recorded at all. Pinning README to + * manifest mechanically is still the payoff this class is pointing at. * `sample` - illustrative or template content. NOT an assertion about this * repository's versions: a changelog a plugin renders as demo data, or * a package.json skeleton the reader owns after copying it. @@ -325,10 +341,11 @@ const keyOf = (c: Pick): string => `${c.file} :: ${c.cl * can tell us when it stops being true. * `stale` - measured WRONG at the time of writing. Recorded, not blessed. * - * Nine of the 27 are `stale`. None is fixed here: objectui#3697 is a test-only task and - * every one of them is a docs edit. They are filed separately. Inventorying a - * known-false line records the debt where the next reader will trip over it, and the - * ratchet still stops a tenth from joining them unnoticed. + * Nine of the 27 were `stale` at the census. Eight have been paid off (objectui#3708, + * #3709, #3710) and their entries deleted in the same change; ONE remains, and it is + * the one whose repair is a manifest edit rather than a docs edit (objectui#3690). + * Inventorying a known-false line records the debt where the next reader will trip over + * it, and the ratchet still stops a tenth from joining them unnoticed. */ type ClaimKind = 'anchored' | 'restatement' | 'sample' | 'unanchored' | 'stale'; @@ -339,31 +356,18 @@ interface KnownClaim { why: string; } -/** The peer-dependency line 9 package READMEs carry, verbatim from their manifests. */ +/** + * The peer-dependency line 10 package READMEs carry verbatim from their manifests — + * `layout` joined them in objectui#3710, which narrowed its over-promising `>=` spelling + * to the range its manifest actually declares. An eleventh README, `plugin-report`, + * carries the same line WITHOUT the manifest to back it; that one stays `stale` below. + */ const PEER_18_19 = 'react' + TICK + ' ^18.0.0'; const PEER_RESTATEMENT_OK = 'Restates this package peerDependencies.react verbatim; re-verify with a one-line read of the manifest.'; const KNOWN_CLAIMS: KnownClaim[] = [ // --- content/docs ------------------------------------------------------------ - { - file: 'content/docs/guide/architecture-overview.md', - claim: '@objectstack/spec ^4.0.4', - kind: 'stale', - why: 'The layer diagram pins spec ^4.0.4; all 29 manifests declare ^17.0.0-rc.5. Thirteen majors stale, and inside a fence, which is why fences are scanned here.', - }, - { - file: 'content/docs/guide/architecture-overview.md', - claim: '@objectstack/spec ^4.0.0', - kind: 'stale', - why: 'Same page, prose this time ("consumed as @objectstack/spec ^4.0.0"); the truth is ^17.0.0-rc.5 in every packages manifest.', - }, - { - file: 'content/docs/guide/architecture.md', - claim: 'TypeScript 5.0', - kind: 'stale', - why: 'Says "built with TypeScript 5.0+ in strict mode"; all 34 typescript declarations in this repo are ^6.0.3. One major behind.', - }, { file: 'content/docs/guide/ci-cd-pipeline.md', claim: 'Node 22.x', @@ -412,30 +416,13 @@ const KNOWN_CLAIMS: KnownClaim[] = [ kind: 'sample', why: 'Second row of the same fake changelog demo string.', }, - { - file: 'content/docs/utilities/create-plugin.mdx', - claim: '@object-ui/core": "^0.3.0', - kind: 'stale', - why: 'Documents the scaffolder output as a ^0.3.0 peer, but packages/create-plugin/src/index.ts writes @object-ui/core as a workspace:* DEPENDENCY and no such peer exists. Wrong version and wrong field.', - }, - { - file: 'content/docs/utilities/create-plugin.mdx', - claim: '@object-ui/components": "^0.3.0', - kind: 'stale', - why: 'Same block, same defect: the scaffolder emits @object-ui/components as workspace:* under dependencies, never as a ^0.3.0 peer.', - }, - { - file: 'content/docs/utilities/create-plugin.mdx', - claim: 'react": "^18.0.0', - kind: 'stale', - why: 'The scaffolder writes react ^18.0.0 || ^19.0.0 (and a react-dom peer this block omits entirely), so the documented output understates what it generates.', - }, // --- packages//README.md ---------------------------------------------- { file: 'packages/auth/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, { file: 'packages/collaboration/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, { file: 'packages/components/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, { file: 'packages/i18n/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, + { file: 'packages/layout/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, { file: 'packages/mobile/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, { file: 'packages/permissions/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, { file: 'packages/plugin-ai/README.md', claim: PEER_18_19, kind: 'restatement', why: PEER_RESTATEMENT_OK }, @@ -447,12 +434,6 @@ const KNOWN_CLAIMS: KnownClaim[] = [ kind: 'restatement', why: 'Restates this package peerDependencies.react, which is literally ">=18" — the one README whose looser spelling is the manifest spelling.', }, - { - file: 'packages/layout/README.md', - claim: 'react' + TICK + ' >= 18.0.0', - kind: 'stale', - why: 'Claims ">= 18.0.0", which admits React 20; the manifest peer is ^18.0.0 || ^19.0.0 and rejects it. The README is broader than what npm will install.', - }, { file: 'packages/plugin-report/README.md', claim: PEER_18_19, @@ -461,9 +442,9 @@ const KNOWN_CLAIMS: KnownClaim[] = [ }, { file: 'packages/plugin-chatbot/README.md', - claim: '@ai-sdk/react' + TICK + ' v3', - kind: 'stale', - why: 'Prose says the streaming mode uses @ai-sdk/react v3; the manifest dependency is ^4.0.47. A whole major behind, and the only third-party version claim in the corpus.', + claim: '@ai-sdk/react' + TICK + ' v4', + kind: 'restatement', + why: 'Names the major of this package own dependencies["@ai-sdk/react"], which is ^4.0.47. Kept rather than deleted because the reader follows it to the streaming protocol docs; re-verify with a one-line read of the manifest.', }, ];