zz-meridian 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adopt.js +3 -3
- package/dist/files.js +5 -0
- package/dist/migrations.js +8 -0
- package/dist/ownership.js +1 -1
- package/dist/reconcile.js +1 -1
- package/dist/session.js +2 -2
- package/package.json +1 -1
- package/payload/CHANGELOG.md +34 -0
- package/payload/docs/data-display.md +2 -2
- package/payload/docs/distribution.md +5 -4
- package/payload/docs/testing.md +1 -1
- package/payload/package.json +17 -16
- package/payload/pnpm-lock.yaml +918 -892
- package/payload/pnpm-workspace.yaml +0 -2
- package/payload/scripts/lib/budgets.ts +5 -1
- package/payload/scripts/lib/sizes.ts +24 -0
- package/payload/scripts/sizes.ts +56 -32
- package/payload/scripts/verify.baseline.json +26 -0
- package/payload/scripts/verify.config.ts +4 -12
- package/payload/scripts/verify.ts +9 -2
- package/payload/skills/zz-meridian/references/existing-project.md +2 -2
- package/payload/skills/zz-meridian/references/live.md +9 -8
- package/payload/skills/zz-meridian/references/ownership.md +1 -1
- package/payload/skills/zz-meridian/references/standard.md +3 -2
- package/payload/skills/zz-meridian/references/update.md +3 -2
- package/payload/skills/zz-meridian/references/validation.md +1 -1
- package/payload/src/components/charts/column-chart/README.md +9 -7
- package/payload/src/components/charts/column-chart/index.tsx +23 -12
- package/payload/src/components/charts/column-chart/preview.tsx +12 -1
- package/payload/src/components/patterns/activity-feed/README.md +2 -2
- package/payload/src/components/patterns/activity-feed/index.tsx +5 -3
- package/payload/src/components/patterns/activity-feed/preview.tsx +2 -2
- package/payload/src/components/patterns/data-table/README.md +1 -1
- package/payload/src/components/patterns/data-table/index.tsx +4 -1
- package/payload/src/components/patterns/data-table/preview.tsx +2 -1
- package/payload/src/components/patterns/rail/README.md +1 -1
- package/payload/src/components/patterns/rail/index.tsx +12 -2
- package/payload/src/components/ui/button/README.md +2 -2
- package/payload/src/components/ui/button/index.tsx +9 -6
- package/payload/src/lib/live.ts +10 -9
- package/payload/src/styles/base.css +14 -0
- package/payload/src/views/console-chrome.tsx +4 -1
- package/payload/tests/activity-feed-link.test.tsx +23 -0
- package/payload/tests/button-busy.test.tsx +38 -0
- package/payload/tests/column-chart-no-data.test.tsx +5 -1
- package/payload/tests/column-chart-stacked.test.tsx +23 -0
- package/payload/tests/data-table.test.tsx +11 -0
- package/payload/tests/live-client.test.tsx +37 -1
- package/payload/tests/rail-current-held.test.tsx +32 -0
- package/payload/tests/verify-sizes.test.ts +11 -2
package/dist/adopt.js
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import fs from 'node:fs';
|
|
10
10
|
import path from 'node:path';
|
|
11
|
-
import { VERSION, brandArgs, effectiveBrand, inside, installSkill, jsoncExtras, packageManager, payloadBytes, payloadFiles, readJsonc, readPayload, relativeImports, run, runTool, sha256, writeIn, writeManifest, } from './files.js';
|
|
11
|
+
import { VERSION, brandArgs, effectiveBrand, inside, installArgs, installSkill, jsoncExtras, packageManager, payloadBytes, payloadFiles, readJsonc, readPayload, relativeImports, run, runTool, sha256, writeIn, writeManifest, } from './files.js';
|
|
12
12
|
import { BRIEF_TEMPLATE, managedBlock, upsertManagedBlock } from './context.js';
|
|
13
13
|
import { FIXED, adoptSetOf, managedPaths } from './ownership.js';
|
|
14
14
|
/** The template's dependencies a dashboard built from these files needs. */
|
|
15
15
|
const DEPS = ['next', 'react', 'react-dom', 'radix-ui', 'lucide-react', 'clsx', 'tailwind-merge', 'react-markdown', 'remark-gfm', 'ai', '@ai-sdk/react', 'zod'];
|
|
16
|
-
const DEV_DEPS = ['typescript', '@types/node', '@types/react', '@types/react-dom', 'tailwindcss', '@tailwindcss/postcss', 'eslint', 'eslint-config-next', 'vitest', '@vitejs/plugin-react', 'jsdom', '@testing-library/react', '@testing-library/jest-dom'];
|
|
16
|
+
const DEV_DEPS = ['typescript', '@types/node', '@types/react', '@types/react-dom', 'tailwindcss', '@tailwindcss/postcss', 'eslint', 'eslint-config-next', 'vitest', '@vitejs/plugin-react', 'jsdom', '@testing-library/react', '@testing-library/dom', '@testing-library/jest-dom'];
|
|
17
17
|
const SCRIPTS = ['typecheck', 'test', 'tokens', 'check', 'contrast', 'gate', 'audit', 'verify', 'brand', 'shot', 'interactions', 'keyboard', 'vitals'];
|
|
18
18
|
const major = (spec) => Number(/(\d+)/.exec(spec)?.[1] ?? NaN);
|
|
19
19
|
const TS = /\.(ts|tsx)$/;
|
|
@@ -356,7 +356,7 @@ Rename or move them, then run adopt again.`);
|
|
|
356
356
|
let typed = 'not run (--no-install)';
|
|
357
357
|
if (o.install) {
|
|
358
358
|
say(`\nInstalling with ${pm}…`);
|
|
359
|
-
if (run(pm,
|
|
359
|
+
if (run(pm, installArgs(pm), root).status !== 0)
|
|
360
360
|
return fail(`${pm} install failed (above). Fix it, then run ${pm} install and ${pm} run typecheck.`);
|
|
361
361
|
// Route types first (LayoutProps, PageProps), as the gate does.
|
|
362
362
|
runTool(root, 'next/dist/bin/next', ['typegen']);
|
package/dist/files.js
CHANGED
|
@@ -77,6 +77,11 @@ export function packageManager(root) {
|
|
|
77
77
|
return 'bun';
|
|
78
78
|
return 'npm';
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* The install that follows Meridian's own edit to package.json. pnpm freezes the lockfile where `CI` is set and refuses
|
|
82
|
+
* the edit it was run to take in, so it is asked to write the lockfile; the other managers write it as they are.
|
|
83
|
+
*/
|
|
84
|
+
export const installArgs = (pm) => (pm === 'pnpm' ? ['install', '--no-frozen-lockfile'] : ['install']);
|
|
80
85
|
/** A tool in the project's node_modules, run as `node <its script>`: no shell and no .cmd shim on any platform. */
|
|
81
86
|
export function runTool(root, entry, args, quiet = true) {
|
|
82
87
|
return spawnSync(process.execPath, [path.join(root, 'node_modules', entry), ...args], { cwd: root, encoding: 'utf8', stdio: quiet ? 'pipe' : 'inherit' });
|
package/dist/migrations.js
CHANGED
|
@@ -462,6 +462,14 @@ export const RELEASE_MIGRATIONS = [
|
|
|
462
462
|
instructions: 'Bring `tests/verify-suite-outcome.test.ts` over from the release as it has it. A file of your own that calls `finalOutcome` passes the tiers, `finalOutcome({ full, timed }, notRun)`, where it passed whether the run was full (`finalOutcome(true, notRun)`): `references/validation.md` describes the tiers, `pnpm verify`, `--full` and `--timed`.',
|
|
463
463
|
checks: ['gate'],
|
|
464
464
|
},
|
|
465
|
+
{
|
|
466
|
+
id: 'no-data-mark',
|
|
467
|
+
since: '0.19.0',
|
|
468
|
+
applies: (root) => matching(root, (rel, src) => importsOf(rel, src).some(({ from }) => from === 'src/components/charts/column-chart') && /\.bg-fill-track['"]\)\)\.not\.toBeNull\(\)/.test(src)),
|
|
469
|
+
summary: 'A Column chart\'s period with no data draws a dashed hairline on the baseline, where it drew a `fill-track` track the height of the scale.',
|
|
470
|
+
instructions: 'Bring `tests/column-chart-no-data.test.tsx` over from the release as it has it. Since 0.19.0 `src/components/charts/column-chart/index.tsx` draws no column for a `null` period: its box has no height, a dashed hairline (`data-no-data-mark`) keeps the slot, and the word stands over it, because the track was the tallest mark on the chart. A test of your own that finds `.bg-fill-track` or `[data-track]` in a no-data column finds `[data-no-data-mark]` instead.',
|
|
471
|
+
checks: ['gate'],
|
|
472
|
+
},
|
|
465
473
|
];
|
|
466
474
|
/**
|
|
467
475
|
* A test of the rail that stands over a fake `ResizeObserver` answering `observe` with nothing (0.16.2). The lookbehind
|
package/dist/ownership.js
CHANGED
|
@@ -7,7 +7,7 @@ export const FIXED = [...LIB, 'src/lib/assistant/prompt.ts', 'src/views/console-
|
|
|
7
7
|
/** The one rule, a plain-English line per clause. `references/ownership.md` renders it, so the guidance cannot drift. */
|
|
8
8
|
export const OWNERSHIP = [
|
|
9
9
|
'Managed: the payload files under `tokens/`, `src/styles/` and `src/components/`, except each component\'s `README.md` and `preview.tsx`.',
|
|
10
|
-
'Managed: the distributed scripts under `scripts/`, except `scripts/verify.config.ts`, the
|
|
10
|
+
'Managed: the distributed scripts under `scripts/`, except `scripts/verify.config.ts`, the size baseline `optional:scripts/verify.baseline.json` (first-load JS and the HTML of each page) and a team-local `optional:scripts/check.local.ts`.',
|
|
11
11
|
'Managed: the library helpers `src/lib/cn.ts`, `src/lib/format.ts`, `src/lib/format-date.ts`, `src/lib/period.ts`, `src/lib/color.ts`, `src/lib/host.ts`, `src/lib/preferences.ts`, `src/lib/csv.ts`, `src/lib/safe-markdown.ts`, `src/lib/logo.ts`, `src/lib/collection.ts`, `src/lib/explore.ts`, `src/lib/live.ts`, `src/lib/shared-context.ts`, `src/lib/agent-guidance.ts`, `src/lib/insight.ts` and `src/lib/facts.ts`, and the assistant prompt `src/lib/assistant/prompt.ts`.',
|
|
12
12
|
'Managed: `src/views/console-chrome.tsx` and `tests/setup.ts`.',
|
|
13
13
|
'Managed: `optional:scripts/package.json`, only when the adopt or create that set the project up generated it for this project shape.',
|
package/dist/reconcile.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { builtinModules } from 'node:module';
|
|
4
4
|
import { upsertManagedBlock } from './context.js';
|
|
5
5
|
/** Adopt's dev dependencies and scripts, which `update` also needs. They mirror `DEV_DEPS` and `SCRIPTS` in adopt.ts. */
|
|
6
|
-
export const TOOLCHAIN = ['typescript', '@types/node', '@types/react', '@types/react-dom', 'tailwindcss', '@tailwindcss/postcss', 'eslint', 'eslint-config-next', 'vitest', '@vitejs/plugin-react', 'jsdom', '@testing-library/react', '@testing-library/jest-dom'];
|
|
6
|
+
export const TOOLCHAIN = ['typescript', '@types/node', '@types/react', '@types/react-dom', 'tailwindcss', '@tailwindcss/postcss', 'eslint', 'eslint-config-next', 'vitest', '@vitejs/plugin-react', 'jsdom', '@testing-library/react', '@testing-library/dom', '@testing-library/jest-dom'];
|
|
7
7
|
export const MERIDIAN_SCRIPTS = ['typecheck', 'test', 'tokens', 'check', 'contrast', 'gate', 'audit', 'verify', 'brand', 'shot', 'interactions', 'keyboard', 'vitals'];
|
|
8
8
|
const isObj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
9
9
|
/**
|
package/dist/session.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import fs from 'node:fs';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { managedBlock } from './context.js';
|
|
10
|
-
import { inside, packageManager, run as spawn, sha256 } from './files.js';
|
|
10
|
+
import { inside, installArgs, packageManager, run as spawn, sha256 } from './files.js';
|
|
11
11
|
import { aliasesOf, canonicalImports } from './imports.js';
|
|
12
12
|
import { changedPaths, takeInventory } from './inventory.js';
|
|
13
13
|
import { renderMergeReport } from './merge-report.js';
|
|
@@ -273,7 +273,7 @@ function install(ctx, session, j, pm) {
|
|
|
273
273
|
if (before.exists && !fs.existsSync(backup))
|
|
274
274
|
writeAtomic(backup, fs.readFileSync(inside(root, lock)));
|
|
275
275
|
const t0 = performance.now();
|
|
276
|
-
const r = ctx.run(pm,
|
|
276
|
+
const r = ctx.run(pm, installArgs(pm), root);
|
|
277
277
|
const ms = performance.now() - t0;
|
|
278
278
|
writeAtomic(path.join(session, 'evidence', '0-install.log'), r.output);
|
|
279
279
|
j.validation = [{ command: `${pm} install`, exitCode: r.status, evidenceFile: 'evidence/0-install.log' }, ...j.validation.filter((v) => !isInstall(v))];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zz-meridian",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Bring ZZ Meridian, a dashboard design system, into a Next.js project, or start a new dashboard on it. Copies the files in; nothing depends on this package at runtime.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/payload/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
Every release of ZZ Meridian, newest first. Versions follow semver: a removed or renamed token, prop or card is major; a new card, token or variant is minor; a corrected value is a patch. Each entry says what breaks and what to do instead.
|
|
4
4
|
|
|
5
|
+
## [0.19.0] · 2026-10-19
|
|
6
|
+
|
|
7
|
+
### Breaking
|
|
8
|
+
|
|
9
|
+
- **Every page's HTML is held to its own baseline, and measured gzipped** ([#57](https://github.com/zhixuan312/zz-meridian/issues/57), [#56](https://github.com/zhixuan312/zz-meridian/issues/56)). `scripts/sizes.ts` measures a page's HTML as a person downloads it, the complete streamed response gzipped, where it measured the uncompressed bytes of the routes in `budgets.htmlKb` only. `node scripts/sizes.ts --write-baseline --base <url>`, against the running build, records the HTML of every page (no API, no dynamic segment, not the not-found screen) beside the first-load figures in `scripts/verify.baseline.json`, and `pnpm verify` holds each to `budgets.htmlGrowthPct` (5%) over its own figure, as first-load JS is held. A growth you accept is recorded once, with the same command, rather than by editing numbers. `budgets.htmlKb` stays as an optional absolute cap, now in gzipped KiB: a cap set on uncompressed bytes is several times too loose, so lower it to the gzipped figure `pnpm verify` prints, or remove it and rely on the baseline. Until the baseline holds `html`, the HTML line is a warning, and `pnpm verify --full` refuses, naming the command. Under `partialPrefetching` Next.js writes each shell's static trees into a page's HTML twice; gzipped, the second copy costs a few KiB rather than tens, so the figure follows the page.
|
|
10
|
+
|
|
11
|
+
### New
|
|
12
|
+
|
|
13
|
+
- **A stacked Column chart's part can take a categorical slot** ([#61](https://github.com/zhixuan312/zz-meridian/issues/61)). `ColumnPart.color` (1 to 6) draws the part in `series-<n>`, as `TrendSeries.color` does, for parts that are identities, such as teams, or for two or more usual outcomes, which one neutral would make one. A part with no slot, Other among them, is neutral, and status colours stay out of such a chart: coral and saffron read as a warning beside a real one. `docs/data-display.md`'s Parts of one whole says when to use it.
|
|
14
|
+
- **`DataTable` takes `retrying`** ([#59](https://github.com/zhixuan312/zz-meridian/issues/59)): its error state's Retry is busy while the person's retry is on its way. Pass it for their own press only.
|
|
15
|
+
- **`ActivityEvent.href`** ([#63](https://github.com/zhixuan312/zz-meridian/issues/63)) links an event's object to its record, with the arrow that says it stays in the product.
|
|
16
|
+
- **`Rail` takes `declared`**, every destination the product declares; `ConsoleRail` passes it from the whole navigation.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **A busy Button keeps its focus** ([#58](https://github.com/zhixuan312/zz-meridian/issues/58)). It was `disabled`, so a focused button that turned busy from anything but its own press, a Retry whose read a live hint or a poll started, lost focus to the page and the next Tab began again at the top. It is `aria-disabled` now, stays in the tab order, and drops a press while busy, a submit's included; `aria-busy` and the spinner are unchanged. A test of yours that expects a busy button to be `disabled` expects `aria-disabled="true"`.
|
|
21
|
+
- **A Column chart's period with no data is no longer its tallest mark** ([#60](https://github.com/zhixuan312/zz-meridian/issues/60)). It drew a `fill-track` track the height of the scale, which in light theme read as the biggest period. It draws no column now, a dashed hairline just above the baseline, and its word ("No data") stands over it where a value would. The hairline carries `data-no-data-mark` where the track carried `data-track`. `npx zz-meridian@latest update` lists `migration:no-data-mark` for a project whose copy of `tests/column-chart-no-data.test.tsx` still expects the track: bring the release's over.
|
|
22
|
+
- **The rail lights nothing for an address under a destination the person does not hold** ([#62](https://github.com/zhixuan312/zz-meridian/issues/62)). It lit the longest destination they held, so someone refused `/admin/audit` saw `/admin` lit. The current page is found among every declared destination and lit only when their rail holds it. A product that passed `current=''` to work around it can stop.
|
|
23
|
+
- **A Button's class list is 178 bytes, not 394** ([#56](https://github.com/zhixuan312/zz-meridian/issues/56)): the frame every button shares is the `.btn` class in `src/styles/base.css`, so a table of row actions does not repeat it on every instance.
|
|
24
|
+
|
|
25
|
+
## [0.18.1] · 2026-10-19
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Next.js 16.4.2**, from 16.3.8. 16.4.1 carries fixes for two critical advisories, remote code execution through a `use cache` function that returns a typed array (GHSA-673q-mjm6-r5xr) and through the Image Optimization API with SVG files (GHSA-2464-fhr4-w9xw), and a high one, denial of service through Server Actions (GHSA-p3m5-59mp-jv5r); 16.3 has no release that carries them. `npx zz-meridian@latest update` raises `next` and `eslint-config-next` to `16.4.2` in a project's `package.json`; run your package manager's install after it.
|
|
30
|
+
- **The other dependencies, within their majors**: React 19.3.1, `ai` 7.0.143 with `@ai-sdk/react` 4.0.147, `@ai-sdk/anthropic` 4.0.82 and `@ai-sdk/openai-compatible` 3.0.71, `radix-ui` 1.8.1, `lucide-react` 1.59.0, `zod` 4.6.7, and for development `vitest` 5.0.5, `jsdom` 30.1.3 and `@vitejs/plugin-react` 6.1.2.
|
|
31
|
+
- **`@testing-library/jest-dom` 7**, which needs `@testing-library/dom` as a dependency of the project's own. `adopt` and `update` add `@testing-library/dom` `^10.4.2` to `devDependencies`; `update` raises jest-dom to 7 where Meridian wrote it and asks you to where you chose your own. The matchers are unchanged.
|
|
32
|
+
- TypeScript stays at 5.9 and ESLint at 9: `typescript-eslint` supports TypeScript below 6.1, and `eslint-plugin-react`, `eslint-plugin-import` and `eslint-plugin-jsx-a11y`, which `eslint-config-next` installs, do not yet declare ESLint 10.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **`update` and `adopt` install where `CI` is set.** Both change `package.json` and then run the project's install, and pnpm freezes the lockfile where `CI` is set, so an update that raised a dependency failed with `ERR_PNPM_OUTDATED_LOCKFILE` in CI or under an agent that sets it. With pnpm they now run `pnpm install --no-frozen-lockfile`; npm, yarn and bun run `install` as before.
|
|
37
|
+
- **A client navigation no longer reads the new page's collections again** ([#54](https://github.com/zhixuan312/zz-meridian/issues/54)). 0.18.0 sent the revisions a page was served only on the tab's first stream, so a press in the rail to a page that follows other collections reopened the stream without them, and every collection that page follows was read by its server and again by the stream's resync. `src/lib/live.ts` now sends them on every open that follows a change of the names, and only a reopen after a gap (an error, a tab shown again, the poll's retry) resyncs every name. A created project takes the fix with `npx zz-meridian@latest update`.
|
|
38
|
+
|
|
5
39
|
## [0.18.0] · 2026-10-19
|
|
6
40
|
|
|
7
41
|
### Breaking
|
|
@@ -36,7 +36,7 @@ Two measures of different size are two charts on one Meridian, not one chart wit
|
|
|
36
36
|
- **Magnitude**: one hue, light to dark, built from the accent and the surface (the heatmap).
|
|
37
37
|
- **Magnitude by rank**: a Heatmap's step is a cell's share of the largest cell (`max`) unless one outlier would leave every other cell at the lowest step. Then it is ranked (`scale="quantile"`): the cells above zero take five steps of equal count. A step no longer says how much, so the legend's upper end reads the value the top step starts at ("900 or more") in place of "More", and the readout and the hidden table give each cell's exact value.
|
|
38
38
|
- **State**: positive, warning, critical, always with a word or an icon.
|
|
39
|
-
- **Parts of one whole**: one hue. The parts share the accent, mixed into the surface, deepest at the bottom and paler upward (the stacked Trend chart and the stacked Column chart take the same mix), with a 1px hairline of the card between neighbours and at most four parts, the fourth being Other. When the parts are outcomes they carry a tone instead: the usual outcome is neutral (`chart-neutral-strong`), one that needs somebody is warning or critical, the accent never stands beside a tone, and the positive colour is never the usual case.
|
|
39
|
+
- **Parts of one whole**: one hue. The parts share the accent, mixed into the surface, deepest at the bottom and paler upward (the stacked Trend chart and the stacked Column chart take the same mix), with a 1px hairline of the card between neighbours and at most four parts, the fourth being Other. When the parts are outcomes they carry a tone instead: the usual outcome is neutral (`chart-neutral-strong`), one that needs somebody is warning or critical, the accent never stands beside a tone, and the positive colour is never the usual case. Parts that are identities (teams), or two or more usual outcomes that one neutral would make one, take the categorical slots instead, in order (`series-1` onward, as Identity above), and a part with no slot is neutral. Status colours stay out of such a chart, as the accent stays out of a toned one, since coral and saffron read as a warning beside a real one: a chart with an outcome that needs somebody is a toned chart.
|
|
40
40
|
|
|
41
41
|
Text never wears a series colour; values and labels stay in ink.
|
|
42
42
|
|
|
@@ -68,7 +68,7 @@ A period still in progress is counted in no total, change or finding. A figure f
|
|
|
68
68
|
- The figure is set tight (the hero figure at `tracking-display`, a card's figure at -0.03em); its unit steps down to half size in `ink-3`; money steps its cents down; compact counts keep their decimal (`2.9M`).
|
|
69
69
|
- Tabular figures where numbers stack or change in place (tables, axes, readouts, and a tile's or the Featured metric's figure, which changes as the Meridian moves); proportional for a standalone figure that stays put.
|
|
70
70
|
- A missing value is a dash, never zero. Every figure names its period and unit somewhere visible.
|
|
71
|
-
- A period with no data is a gap in a chart, never a zero and never left out: a `null` keeps its place on the time axis. A Trend chart's and a Sparkline's line breaks at it; a Column chart's column keeps its slot
|
|
71
|
+
- A period with no data is a gap in a chart, never a zero and never left out: a `null` keeps its place on the time axis. A Trend chart's and a Sparkline's line breaks at it; a Column chart's column keeps its slot with a dashed hairline on the baseline, never a mark that stands up from it, and reads "No data" (or the product's word, `noData`) at rest, pointed at and in the table, and the scale leaves it out.
|
|
72
72
|
- A Heatmap of hours names the timezone its hours are cut in, in its readout, its announcement and its table: UTC unless the product passes `timezone`. A product that cuts its days at local midnight cuts its hours there too and names the zone, so a local Monday stays in Monday's row. The template's Usage passes the product's reporting timezone, `app.timezone`, as its Heatmap's `timezone` and names it in its cards and its context, so a product that sets that zone keeps its hours cut in it.
|
|
73
73
|
- A delta's arrow carries direction; its colour carries the judgement, which depends on the measure (latency down is good).
|
|
74
74
|
- A change says what it is against, in words beside it: "vs previous period" unless the caller says otherwise ("vs the week before"). The Featured metric and the Metric tile take the words as `compare`. On a wall of compact tiles the card that holds the wall says it once, and a tile draws the change's figure alone.
|
|
@@ -75,7 +75,7 @@ Then, in this order:
|
|
|
75
75
|
the accent and the contrast gate. Then it writes Meridian's managed block into their `AGENTS.md`, and `docs/brief.md`
|
|
76
76
|
when they have none.
|
|
77
77
|
5. Installs the skill and writes the manifest.
|
|
78
|
-
6. Runs their package manager's install, `next typegen` and `tsc --noEmit`, and prints the result and the next step:
|
|
78
|
+
6. Runs their package manager's install (pnpm with `--no-frozen-lockfile`, since adopt has just changed `package.json`), `next typegen` and `tsc --noEmit`, and prints the result and the next step:
|
|
79
79
|
the skill's Route A from step 2, with the template to read from at the same version.
|
|
80
80
|
|
|
81
81
|
Three things make the copy safe in someone else's project. Meridian's own files import each other by relative path,
|
|
@@ -107,7 +107,8 @@ three edits named below. It needs a project that adopted or created Meridian 0.3
|
|
|
107
107
|
2. **Update.** `npx zz-meridian@latest update` from a clean git tree (or with `--allow-dirty`). It writes the plan first
|
|
108
108
|
(`.meridian/update/<version>/state.json`, the journal, `MERGE.md`, an empty `resolutions.json`, the `base/`, `ours/`
|
|
109
109
|
and `new/` copies of every staged file, and a `backup/` preimage of every path it changes), then applies the safe
|
|
110
|
-
changes, then runs the install
|
|
110
|
+
changes, then runs the install (pnpm with `--no-frozen-lockfile`, which CI would otherwise refuse after the edit to
|
|
111
|
+
`package.json`). Applied: untouched replacements, additions and untouched removals. Staged: every
|
|
111
112
|
managed file the team changed or deleted, or collided with. The only team files it edits are `package.json` (missing
|
|
112
113
|
dependencies and scripts, older ones of the same major, and entries still exactly as the earlier release wrote them;
|
|
113
114
|
the framework `next`, `react` and `react-dom` is always among them), the managed block in `AGENTS.md`, and the
|
|
@@ -147,10 +148,10 @@ Two environment variables exist for the updater's own tests and are used only wh
|
|
|
147
148
|
reports as `migration:<id>` because it cannot make them. An entry applies when the project's recorded version is older
|
|
148
149
|
than its `since` and the target is not, and its `applies(root)` returns the paths that still have the old shape, or
|
|
149
150
|
null. It only reads, and only team-owned files (the ownership rule's managed paths are skipped); a file it cannot read is
|
|
150
|
-
absent. A project already on the new shape gets no line. Every entry carries `gate` and `build` as its checks (`verify-modes`, `agent-reads-section`, `nav-needs`, `agent-reads-own-group`, `agent-does-here-section`, `marker-measured-on-observe`, `view-page-matched-as-next`, `journey-moved`, `today-in-timezone` and `
|
|
151
|
+
absent. A project already on the new shape gets no line. Every entry carries `gate` and `build` as its checks (`verify-modes`, `agent-reads-section`, `nav-needs`, `agent-reads-own-group`, `agent-does-here-section`, `marker-measured-on-observe`, `view-page-matched-as-next`, `journey-moved`, `today-in-timezone`, `verify-tiers` and `no-data-mark`, `gate` alone), and its
|
|
151
152
|
instructions name the section of a reference (`cache.md`, `live.md`, `validation.md`, `agents.md`, `customize.md`), of the Start guide or of `docs/assistant.md` to follow.
|
|
152
153
|
|
|
153
|
-
|
|
154
|
+
Sixteen arrived after 0.5.0 and are resolved as the skill's `references/update.md` says: `share-view-context` and `agent-reads-section` (0.9.0), `assistant-view-tools` (0.10.0), `nav-needs` (0.13.0), `agent-reads-own-group` (0.15.0), `refusal-declared`, `managed-exports-removed`, `view-tool-page-explore`, `agent-does-here-section` and `sample-pages-renamed` (0.16.0), `marker-measured-on-observe` (0.16.2), `view-page-matched-as-next`, `journey-moved` and `today-in-timezone` (0.16.3), `verify-tiers` (0.17.0), and `no-data-mark` (0.19.0). The ten of 0.5.0 are:
|
|
154
155
|
|
|
155
156
|
| Id | Reported when a team-owned file still has | Completion step |
|
|
156
157
|
|----|-------------------------------------------|-----------------|
|
package/payload/docs/testing.md
CHANGED
|
@@ -125,7 +125,7 @@ Every check Meridian runs has one row, named by a key: a gate step, a group of t
|
|
|
125
125
|
| `verify/build` | large | functional | change | no | `pnpm verify` | 9.6 s at 40d29c7 | One production build. |
|
|
126
126
|
| `verify/route policy` | large | non-functional | change | no | `pnpm verify` | 0.1 s at 40d29c7 | Every route is declared static or dynamic as its policy says. |
|
|
127
127
|
| `verify/first-load` | large | non-functional | change | no | `pnpm verify` | 0.3 s at 40d29c7 | The first-load size of each route is within its budget. |
|
|
128
|
-
| `verify/html` | large | non-functional | change | no | `pnpm verify` |
|
|
128
|
+
| `verify/html` | large | non-functional | change | no | `pnpm verify` | 1.5 s at dbf4106 | Every page's served HTML, gzipped, is within `htmlGrowthPct` of its own baseline figure and under any `htmlKb` cap. |
|
|
129
129
|
| `verify/navigation` | large | functional | change | no | `pnpm verify` | 92.5 s at 269d307 | From a press in the rail, each route's shell, data and first interaction arrive, on desktop and through the phone drawer, judged on function only, never on time; up to three routes, every rail route under `--full` or `--timed`. |
|
|
130
130
|
| `verify/timing` | large | performance | timed | yes | `pnpm verify --timed` | 88.2 s at fa5bbff | The same navigation of every rail route, with each shell, data and interaction time judged against its budget. |
|
|
131
131
|
| `verify/personas` | large | functional | on request | no | `pnpm verify --as viewer` | 937.8 s at fa5bbff (the five personas) | Signed in as each named persona, the rail shows the routes that persona may open and a denied route draws its refusal. |
|
package/payload/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zz-meridian-template",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "ZZ Meridian: a dashboard design system and starter. Six layers, from DTCG tokens through four layers of React components to product workspaces, and a Design Atlas, in a light and a dark theme.",
|
|
@@ -30,34 +30,35 @@
|
|
|
30
30
|
"keyboard": "node scripts/keyboard.ts"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@ai-sdk/anthropic": "4.0.
|
|
34
|
-
"@ai-sdk/openai-compatible": "3.0.
|
|
35
|
-
"@ai-sdk/react": "4.0.
|
|
36
|
-
"ai": "7.0.
|
|
33
|
+
"@ai-sdk/anthropic": "4.0.82",
|
|
34
|
+
"@ai-sdk/openai-compatible": "3.0.71",
|
|
35
|
+
"@ai-sdk/react": "4.0.147",
|
|
36
|
+
"ai": "7.0.143",
|
|
37
37
|
"clsx": "^2.1.1",
|
|
38
|
-
"lucide-react": "^1.
|
|
39
|
-
"next": "16.
|
|
40
|
-
"radix-ui": "^1.
|
|
41
|
-
"react": "19.3.
|
|
42
|
-
"react-dom": "19.3.
|
|
38
|
+
"lucide-react": "^1.59.0",
|
|
39
|
+
"next": "16.4.2",
|
|
40
|
+
"radix-ui": "^1.8.1",
|
|
41
|
+
"react": "19.3.1",
|
|
42
|
+
"react-dom": "19.3.1",
|
|
43
43
|
"react-markdown": "^10.1.0",
|
|
44
44
|
"remark-gfm": "^4.0.1",
|
|
45
45
|
"tailwind-merge": "^3.7.0",
|
|
46
|
-
"zod": "4.6.
|
|
46
|
+
"zod": "4.6.7"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@tailwindcss/postcss": "^4.3.3",
|
|
50
|
-
"@testing-library/
|
|
50
|
+
"@testing-library/dom": "^10.4.2",
|
|
51
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
51
52
|
"@testing-library/react": "^16.3.3",
|
|
52
53
|
"@types/node": "^24",
|
|
53
54
|
"@types/react": "^19.3.0",
|
|
54
55
|
"@types/react-dom": "^19.3.0",
|
|
55
|
-
"@vitejs/plugin-react": "^6.1.
|
|
56
|
+
"@vitejs/plugin-react": "^6.1.2",
|
|
56
57
|
"eslint": "^9.39.5",
|
|
57
|
-
"eslint-config-next": "16.
|
|
58
|
-
"jsdom": "^30.1.
|
|
58
|
+
"eslint-config-next": "16.4.2",
|
|
59
|
+
"jsdom": "^30.1.3",
|
|
59
60
|
"tailwindcss": "^4.3.3",
|
|
60
61
|
"typescript": "5.9.3",
|
|
61
|
-
"vitest": "^5.0.
|
|
62
|
+
"vitest": "^5.0.5"
|
|
62
63
|
}
|
|
63
64
|
}
|