@flareum/mcp 0.5.0 → 0.5.8
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/cli.js +3 -1
- package/dist/first-pull.js +10 -4
- package/dist/lock.d.ts +3 -1
- package/dist/lock.js +11 -1
- package/dist/server.js +8 -4
- package/dist/tools.js +7 -5
- package/package.json +1 -1
- package/skill/SKILL.md +57 -73
- package/skill/references/applying.md +0 -70
package/dist/cli.js
CHANGED
|
@@ -69,7 +69,9 @@ try {
|
|
|
69
69
|
// The server reads this lock to decide whether to pull. Without it a CLI pull was invisible,
|
|
70
70
|
// and the next connection fetched the same version again.
|
|
71
71
|
if (!isRetryable(result))
|
|
72
|
-
|
|
72
|
+
// An explicit pull is the deliberate act applying.md ends on, so it advances BOTH: these
|
|
73
|
+
// stylesheets, and the version the code is now written against.
|
|
74
|
+
await writeLock(process.cwd(), makeLock(projectIdFromToken(config.token), result.publishedVersionId, outDir, new Date().toISOString(), result.publishedVersionId));
|
|
73
75
|
console.log(pullReport(result, outDir));
|
|
74
76
|
return result;
|
|
75
77
|
};
|
package/dist/first-pull.js
CHANGED
|
@@ -101,14 +101,17 @@ export const configuredOut = (cwd, env) => {
|
|
|
101
101
|
};
|
|
102
102
|
export const runFirstPull = async (client, cwd, env, configuredOut, knownVersion, now = () => new Date().toISOString()) => {
|
|
103
103
|
const exists = path => existsSync(resolve(cwd, path));
|
|
104
|
-
|
|
104
|
+
// Any FILE, at any depth. An empty directory tree is what a git clean leaves behind, not somebody
|
|
105
|
+
// else's work — counting those as content refused to ever pull again.
|
|
106
|
+
const holdsNoFiles = (dir) => {
|
|
105
107
|
try {
|
|
106
|
-
return readdirSync(
|
|
108
|
+
return readdirSync(dir, { withFileTypes: true }).every(entry => entry.isDirectory() && holdsNoFiles(join(dir, entry.name)));
|
|
107
109
|
}
|
|
108
110
|
catch {
|
|
109
111
|
return true;
|
|
110
112
|
}
|
|
111
113
|
};
|
|
114
|
+
const isEmpty = path => holdsNoFiles(resolve(cwd, path));
|
|
112
115
|
const dir = chooseStylesDir(exists, configuredOut);
|
|
113
116
|
if (!autoPullEnabled(env))
|
|
114
117
|
return { ran: false, reason: 'disabled', dir };
|
|
@@ -128,12 +131,15 @@ export const runFirstPull = async (client, cwd, env, configuredOut, knownVersion
|
|
|
128
131
|
// Claimed BEFORE the first write: an interrupted pull leaves files with no completed version,
|
|
129
132
|
// and without this it would read as somebody else's folder and never be finished.
|
|
130
133
|
await mkdir(resolve(cwd, dir), { recursive: true });
|
|
131
|
-
|
|
134
|
+
// The applied version is carried across every write here: this pull is unattended, and
|
|
135
|
+
// advancing it would consume the diff window before an agent could read it.
|
|
136
|
+
const applied = lock?.appliedVersionId ?? syncedVersion(lock, dir) ?? undefined;
|
|
137
|
+
await writeLock(cwd, makeLock(projectId, IN_FLIGHT, dir, now(), applied));
|
|
132
138
|
const result = await pullStyles(client, fileWriter(resolve(cwd, dir)));
|
|
133
139
|
// Recorded only when the WHOLE version landed: pullStyles resolves even when files failed, so
|
|
134
140
|
// stamping on its return marked a half-pulled folder complete and never retried it.
|
|
135
141
|
if (!isRetryable(result))
|
|
136
|
-
await writeLock(cwd, makeLock(projectId, result.publishedVersionId, dir, now()));
|
|
142
|
+
await writeLock(cwd, makeLock(projectId, result.publishedVersionId, dir, now(), applied));
|
|
137
143
|
return { ran: true, dir, result };
|
|
138
144
|
}
|
|
139
145
|
catch (error) {
|
package/dist/lock.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const LOCK_PATH = ".flareum/lock.json";
|
|
|
2
2
|
export type Lock = {
|
|
3
3
|
projectId: string;
|
|
4
4
|
syncedVersionId: string;
|
|
5
|
+
appliedVersionId?: string;
|
|
5
6
|
syncedAt: string;
|
|
6
7
|
out: string;
|
|
7
8
|
prefix?: string;
|
|
@@ -12,7 +13,8 @@ export declare const readLock: (cwd: string) => Lock | null;
|
|
|
12
13
|
export declare const owns: (lock: Lock | null, dir: string) => boolean;
|
|
13
14
|
export declare const syncedVersion: (lock: Lock | null, dir: string) => string | null;
|
|
14
15
|
export declare const writeLock: (cwd: string, lock: Lock) => Promise<void>;
|
|
15
|
-
export declare const makeLock: (projectId: string, syncedVersionId: string, out: string, at: string, prefix?: string) => Lock;
|
|
16
|
+
export declare const makeLock: (projectId: string, syncedVersionId: string, out: string, at: string, appliedVersionId?: string, prefix?: string) => Lock;
|
|
17
|
+
export declare const appliedVersion: (lock: Lock | null) => string;
|
|
16
18
|
export declare const LEGACY_STAMP = ".flareum-version";
|
|
17
19
|
export declare const legacyVersion: (cwd: string, dir: string) => string | null;
|
|
18
20
|
export declare const legacyStampExists: (cwd: string, dir: string) => boolean;
|
package/dist/lock.js
CHANGED
|
@@ -20,7 +20,17 @@ export const writeLock = async (cwd, lock) => {
|
|
|
20
20
|
await mkdir(dirname(path), { recursive: true });
|
|
21
21
|
await writeFile(path, `${JSON.stringify(lock, null, 2)}\n`, 'utf8');
|
|
22
22
|
};
|
|
23
|
-
export const makeLock = (projectId, syncedVersionId, out, at, prefix) => ({
|
|
23
|
+
export const makeLock = (projectId, syncedVersionId, out, at, appliedVersionId, prefix) => ({
|
|
24
|
+
projectId, syncedVersionId, syncedAt: at, out,
|
|
25
|
+
...(appliedVersionId ? { appliedVersionId } : {}),
|
|
26
|
+
...(prefix ? { prefix } : {}),
|
|
27
|
+
});
|
|
28
|
+
// What an agent diffs FROM. Falls back to the stylesheets for a lock written before this field, and
|
|
29
|
+
// never returns the in-flight sentinel — a pull half-done is not a version anything was applied to.
|
|
30
|
+
export const appliedVersion = (lock) => {
|
|
31
|
+
const applied = lock?.appliedVersionId ?? lock?.syncedVersionId;
|
|
32
|
+
return !applied || applied === IN_FLIGHT ? '' : applied;
|
|
33
|
+
};
|
|
24
34
|
// A project pulled by 0.2.x recorded the version in a stamp beside the stylesheets. Adopted rather
|
|
25
35
|
// than ignored, so an upgrade does not re-pull a version already on disk.
|
|
26
36
|
export const LEGACY_STAMP = '.flareum-version';
|
package/dist/server.js
CHANGED
|
@@ -11,10 +11,10 @@ import { installSkill, skillInstallReport } from './skill.js';
|
|
|
11
11
|
import { configuredOut, firstPullReport, runFirstPull } from './first-pull.js';
|
|
12
12
|
import { projectConfigReport, writeProjectConfig } from './project-config.js';
|
|
13
13
|
import { checkKey } from './key-check.js';
|
|
14
|
-
import { readLock } from './lock.js';
|
|
14
|
+
import { appliedVersion, readLock } from './lock.js';
|
|
15
15
|
// The agent should not have to be told which version to diff from — the lock in the project is the
|
|
16
16
|
// answer, and asking the model to supply it invites a guess.
|
|
17
|
-
const lockedVersion = () => readLock(process.cwd())
|
|
17
|
+
const lockedVersion = () => appliedVersion(readLock(process.cwd()));
|
|
18
18
|
// A missing key threw at module load, and an editor shows that as a Node stack trace with the
|
|
19
19
|
// message buried in it. Say it in one line and exit, the way the CLI already does.
|
|
20
20
|
let client;
|
|
@@ -75,8 +75,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
75
75
|
try {
|
|
76
76
|
if (request.params.name === 'flareum_search')
|
|
77
77
|
return text(formatSearch(await client.search(String(args.query ?? ''), Number(args.limit) || undefined)));
|
|
78
|
-
if (request.params.name === 'flareum_changes_since')
|
|
79
|
-
|
|
78
|
+
if (request.params.name === 'flareum_changes_since') {
|
|
79
|
+
// Defaulted here, not left to the model: the lock is the answer, and asking for it invites a guess.
|
|
80
|
+
const locked = lockedVersion();
|
|
81
|
+
const since = String(args.since ?? '') || locked;
|
|
82
|
+
return text(formatChanges(await client.changes(since), locked));
|
|
83
|
+
}
|
|
80
84
|
if (request.params.name === 'flareum_get')
|
|
81
85
|
return text(formatVariable(await client.variable(String(args.path ?? ''))));
|
|
82
86
|
return text(`Unknown tool: ${request.params.name}`);
|
package/dist/tools.js
CHANGED
|
@@ -72,7 +72,8 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
72
72
|
get: 'Read one design token in full: its value in every mode, its type, which components use it, and '
|
|
73
73
|
+ 'which other tokens reference it. Use it to judge what a change would affect before making one.',
|
|
74
74
|
changes: 'List what changed in Flareum since the version this project last synced. Call it when the user '
|
|
75
|
-
+ 'asks to
|
|
75
|
+
+ 'says "update flareum", or asks to sync, update or migrate tokens, and at the start of a '
|
|
76
|
+
+ 'session in a project that has a '
|
|
76
77
|
+ '.flareum/lock.json. A rename reads as a rename with both names, so rewrite the call sites '
|
|
77
78
|
+ 'rather than deleting and adding. A removed token carries what to use instead. Read every '
|
|
78
79
|
+ 'entry before editing anything, and say what you are about to change.',
|
|
@@ -80,14 +81,14 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
80
81
|
// Written for a model that is about to EDIT files: the CSS names first, because those are what it
|
|
81
82
|
// greps for, and the action stated per line so a rename is never applied as a delete plus an add.
|
|
82
83
|
export const formatChanges = ({ since, totalChanges, entries, truncated, liveVersionId }, lockedVersion = '') => {
|
|
83
|
-
if (!totalChanges)
|
|
84
|
+
if (!totalChanges || !entries.length)
|
|
84
85
|
return since
|
|
85
86
|
? `No changes since ${since}. The project is at ${liveVersionId}.`
|
|
86
87
|
: `This project has no tokens yet.`;
|
|
87
88
|
const lines = [
|
|
88
89
|
since
|
|
89
|
-
? `${
|
|
90
|
-
: `${
|
|
90
|
+
? `${entries.length} change(s) since ${since}. The project is now at ${liveVersionId}.`
|
|
91
|
+
: `${entries.length} change(s). No baseline was given, so this is everything the project has.`,
|
|
91
92
|
'',
|
|
92
93
|
];
|
|
93
94
|
if (lockedVersion && since && lockedVersion !== since)
|
|
@@ -114,7 +115,8 @@ const changeLine = (entry) => {
|
|
|
114
115
|
if (change === 'typeChanged')
|
|
115
116
|
return `${kind} type: ${nameOf(before)} is now ${after?.type} (was ${before?.type})`;
|
|
116
117
|
if (change === 'valueChanged')
|
|
117
|
-
return `${kind} value${mode}: ${nameOf(before)} ${before?.value} →
|
|
118
|
+
return `${kind} value${mode}: ${nameOf(before)} ${before?.value ?? '(not set)'} → `
|
|
119
|
+
+ `${after?.value ?? '(not set)'}`;
|
|
118
120
|
if (change === 'movedCollection')
|
|
119
121
|
return `${kind} moved collection: ${nameOf(before)} → ${nameOf(after)}`;
|
|
120
122
|
return `${kind} ${change}: ${nameOf(after ?? before)}`;
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -5,106 +5,90 @@ description: Use the project's Flareum design tokens instead of literal values.
|
|
|
5
5
|
|
|
6
6
|
# Flareum design tokens
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
of them
|
|
10
|
-
the `flareum_search` and `flareum_get` tools.
|
|
8
|
+
Tokens live in Flareum. `flareum_search` and `flareum_get` read them; the CSS/SCSS in the repo is a
|
|
9
|
+
rendering of them.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
Names below use **`[prefix]`** for this project's own prefix — the string every `cssName` starts
|
|
12
|
+
with. Substitute it; never write `[prefix]` itself.
|
|
14
13
|
|
|
15
14
|
## The one rule
|
|
16
15
|
|
|
17
16
|
**Search before you write a literal value, and before you propose a token name.**
|
|
18
17
|
|
|
19
|
-
A hardcoded `#5B8DEF` is a token that escaped the system.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
or a component name.
|
|
18
|
+
A hardcoded `#5B8DEF` is a token that escaped the system. An invented `color/border/muted` beside an
|
|
19
|
+
existing `color/border/secondary` is worse — it looks like a decision, and nobody reconciles the two.
|
|
20
|
+
Search takes a hex, an rgb(), a path fragment, a comment phrase, or a component name.
|
|
23
21
|
|
|
24
|
-
##
|
|
22
|
+
## Before the first token in a project
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
Three checks. All three fail silently — a correct `var([prefix]-…)` renders as nothing, which reads
|
|
25
|
+
as the token being wrong rather than missing.
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
| Any text — a heading, a label, body copy, a pseudo-element's `content` | [references/typography.md](references/typography.md) |
|
|
32
|
-
| A token name, or judging one that already exists | [references/naming.md](references/naming.md) |
|
|
33
|
-
| Applying what `flareum_changes_since` returned — a sync, an update, a migration | [references/applying.md](references/applying.md) |
|
|
34
|
-
|
|
35
|
-
## Before the first token: check the stylesheets are imported
|
|
36
|
-
|
|
37
|
-
A token only resolves if the pulled stylesheets are actually loaded. `flareum pull` writes them into
|
|
38
|
-
the project — it does not wire them in, because which file is the global entry point is the
|
|
39
|
-
project's decision, not the tool's.
|
|
27
|
+
**1. Are they on disk?** Look in `src/styles/flareum/`, or wherever `out` in `.flareum/config.json`
|
|
28
|
+
points. If it is missing or holds no stylesheets:
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
**Find the pulled files** (`src/styles/flareum/`, or wherever `out` in `.flareum/config.json`
|
|
46
|
-
points), then **find the global stylesheet** — the one the app already loads for everything:
|
|
30
|
+
```bash
|
|
31
|
+
npx -y -p @flareum/mcp flareum pull
|
|
32
|
+
```
|
|
47
33
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
| Angular | the `styles` entry in `angular.json` — commonly `src/styles.scss` |
|
|
51
|
-
| Vite / React / Vue | the CSS imported by the entry module — `src/main.tsx`, `src/index.css` |
|
|
52
|
-
| Next.js | `app/globals.css`, imported by the root layout |
|
|
53
|
-
| Plain | whatever the HTML `<link>`s |
|
|
34
|
+
Pull into the folder this project already keeps styles in. If the default would miss it:
|
|
35
|
+
`npx -y -p @flareum/mcp flareum pull --out app/styles/flareum`.
|
|
54
36
|
|
|
55
|
-
|
|
37
|
+
**2. Are they imported?** Add it to the global stylesheet, at the top:
|
|
56
38
|
|
|
57
39
|
```scss
|
|
58
|
-
@use './styles/flareum/main';
|
|
59
|
-
```
|
|
60
|
-
```css
|
|
61
|
-
@import './styles/flareum/main.css'; /* plain CSS */
|
|
40
|
+
@use './styles/flareum/main';
|
|
62
41
|
```
|
|
63
42
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`--
|
|
43
|
+
That file is the `styles` entry in `angular.json` (usually `src/styles.scss`), `app/globals.css` in
|
|
44
|
+
Next.js, or whatever the entry module imports. Confirm it worked — build, or grep the built CSS for a
|
|
45
|
+
`--[prefix]-` declaration.
|
|
67
46
|
|
|
68
|
-
|
|
69
|
-
|
|
47
|
+
**3. Are they current?** Call `flareum_changes_since`. If it reports changes, the local stylesheets
|
|
48
|
+
are behind the designer — a token you are about to use may have been renamed or removed. **Say what
|
|
49
|
+
changed and ask before updating. Do not pull silently.** On yes, follow "Update Flareum". On no, use
|
|
50
|
+
the tokens as they are on disk and say which choices may be affected.
|
|
70
51
|
|
|
71
|
-
|
|
52
|
+
**Never write tokens against stylesheets that are not there.**
|
|
72
53
|
|
|
73
|
-
|
|
74
|
-
says what has changed since — a rename reads as a rename, a removed token carries what to use
|
|
75
|
-
instead. Reach for it when the user asks to sync, update or migrate tokens, and at the start of a
|
|
76
|
-
session in a project that has a lock.
|
|
54
|
+
## "Update Flareum"
|
|
77
55
|
|
|
78
|
-
|
|
79
|
-
reports itself synced while still referencing dead tokens:
|
|
80
|
-
[references/applying.md](references/applying.md).
|
|
56
|
+
When the user says **update flareum**, or asks to sync or migrate tokens:
|
|
81
57
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
58
|
+
1. `flareum_changes_since`.
|
|
59
|
+
2. **Say what it means** — how many renames, removals and value changes, and how many files each
|
|
60
|
+
rename touches. A removal with a recorded successor is substituted; one **without** is reported
|
|
61
|
+
and left alone: you have no basis for choosing a successor, and a guess is how a design system
|
|
62
|
+
quietly acquires wrong semantics.
|
|
63
|
+
3. **Ask before changing anything.** A no stops there.
|
|
64
|
+
4. On yes: **rewrite the call sites first, pull last.** The pull brings the stylesheets AND records
|
|
65
|
+
the project as synced, so pulling first then failing halfway leaves a project that reports itself
|
|
66
|
+
current while still using dead tokens. Rewrite names only — a value change needs no code edit.
|
|
85
67
|
|
|
86
|
-
|
|
87
|
-
- **`No confident match for "…"`** — the listed tokens are **nearest neighbours, not matches**. One
|
|
88
|
-
of them is often the thing you want under a name you would not have guessed. **Do not create a
|
|
89
|
-
token or hardcode a value on the strength of this.** Ask which to use, or search again with the
|
|
90
|
-
value rather than the name.
|
|
68
|
+
If nothing has changed, say so in one line and stop.
|
|
91
69
|
|
|
92
|
-
|
|
70
|
+
## Reading a search result
|
|
93
71
|
|
|
94
|
-
|
|
72
|
+
- **`Match for "…"`** — use it. The `cssName` is ready to paste.
|
|
73
|
+
- **`No confident match for "…"`** — these are nearest neighbours, not matches. One is often what
|
|
74
|
+
you want under a name you would not have guessed. **Do not invent a token or hardcode a value on the
|
|
75
|
+
strength of this.** Ask which to use, or search again by value.
|
|
95
76
|
|
|
96
|
-
|
|
77
|
+
## If the token does not exist
|
|
97
78
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
79
|
+
The integration is **read-only** — nothing writes to Flareum. Say which token is missing and what it
|
|
80
|
+
is for, propose a name that fits [the grammar](references/naming.md), and do not hardcode the value
|
|
81
|
+
and move on.
|
|
101
82
|
|
|
102
|
-
##
|
|
83
|
+
## Before changing a token
|
|
103
84
|
|
|
104
|
-
`flareum_get` reports
|
|
85
|
+
`flareum_get` reports **component usage** (which components consume it) and **referrers** (which
|
|
86
|
+
tokens reference it, and would break). No usage data means **unknown**, not unused — grep the repo
|
|
87
|
+
before treating a token as safe to change.
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
- **referrers** — which other tokens reference it, and would break.
|
|
89
|
+
## By topic
|
|
108
90
|
|
|
109
|
-
|
|
110
|
-
|
|
91
|
+
| Writing | Read |
|
|
92
|
+
|---|---|
|
|
93
|
+
| Any text — heading, label, body copy, a pseudo-element's `content` | [references/typography.md](references/typography.md) |
|
|
94
|
+
| A token name, or judging one that exists | [references/naming.md](references/naming.md) |
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# Applying what changed
|
|
2
|
-
|
|
3
|
-
Read this when `flareum_changes_since` returns entries, or the user asks to sync, update or migrate
|
|
4
|
-
tokens.
|
|
5
|
-
|
|
6
|
-
## The order is the safety
|
|
7
|
-
|
|
8
|
-
**Rewrite the call sites first. Pull last.**
|
|
9
|
-
|
|
10
|
-
`flareum pull` brings the new stylesheets AND stamps `.flareum/lock.json`, which is what records the
|
|
11
|
-
project as synced. Pull first and a rewrite that fails halfway leaves the lock advanced over a
|
|
12
|
-
codebase still referencing dead tokens — the next session reports nothing to do, and the breakage is
|
|
13
|
-
invisible. Pull last and a failed rewrite simply leaves the project where it was.
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
1. flareum_changes_since read every entry before editing anything
|
|
17
|
-
2. show the developer what you are about to change, and what you cannot
|
|
18
|
-
3. rewrite the call sites names only
|
|
19
|
-
4. npx -p @flareum/mcp flareum pull the new tree, and the lock
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Do not update `lock.json` by hand. It is stamped by a successful pull, and stamping it any other way
|
|
23
|
-
is claiming work that did not happen.
|
|
24
|
-
|
|
25
|
-
## What you may change, and what you may not
|
|
26
|
-
|
|
27
|
-
| You may | You may not |
|
|
28
|
-
|---|---|
|
|
29
|
-
| Rewrite `var(--old)` → `var(--new)` across the repo | Change a **value**. Only a name. |
|
|
30
|
-
| Substitute a removed token's recorded replacement | Guess a replacement when none is recorded |
|
|
31
|
-
| Replace the pulled `variables/` tree by pulling | Hand-edit anything inside it — it is generated |
|
|
32
|
-
| Report what you could not resolve | Silently skip an entry |
|
|
33
|
-
|
|
34
|
-
## Entry by entry
|
|
35
|
-
|
|
36
|
-
**`renamed` / `moved`** — one entry carries both names. Rewrite every occurrence of `before.cssName`
|
|
37
|
-
to `after.cssName`. It is a rename: do not delete the old and add the new, and do not touch the value.
|
|
38
|
-
|
|
39
|
-
**`viaFolder`** — this rename is part of a whole folder moving. Apply it as one prefix rewrite across
|
|
40
|
-
the members rather than N independent edits, and say so once rather than N times.
|
|
41
|
-
|
|
42
|
-
**`deleted` with a replacement** — substitute it. The replacement is what the designer recorded as
|
|
43
|
-
the successor, and it may be a token, a formula or a literal.
|
|
44
|
-
|
|
45
|
-
**`deleted` with NO replacement** — **report it and leave it alone.** You have no basis for choosing
|
|
46
|
-
a successor, and a plausible-looking guess is how a design system quietly acquires wrong semantics.
|
|
47
|
-
Name the token, name the files that use it, and let the developer decide.
|
|
48
|
-
|
|
49
|
-
**`valueChanged`** — nothing to do in the code. The value lives in the stylesheets the pull replaces;
|
|
50
|
-
a call site referencing the token gets the new value for free. Mention it only if the change is large
|
|
51
|
-
enough that someone should look at the result.
|
|
52
|
-
|
|
53
|
-
**`typeChanged`** — the token still exists under the same name, but it is a different kind of value
|
|
54
|
-
now (a colour that became a number). The call sites may still compile and be wrong. Report each one;
|
|
55
|
-
do not rewrite them silently.
|
|
56
|
-
|
|
57
|
-
**`added`** — nothing to apply. Worth mentioning only if it replaces something you are about to
|
|
58
|
-
report as removed.
|
|
59
|
-
|
|
60
|
-
**`reordered`** — ignore. It affects the order tokens are emitted in, not any call site.
|
|
61
|
-
|
|
62
|
-
## Before you touch a file
|
|
63
|
-
|
|
64
|
-
Say what you are about to do, in the developer's terms: how many call sites, in how many files, and
|
|
65
|
-
what you will not be touching. A migration nobody agreed to is a migration nobody can review.
|
|
66
|
-
|
|
67
|
-
## When it does not go cleanly
|
|
68
|
-
|
|
69
|
-
Report what failed and **do not pull**. A partial rewrite with the old stylesheets still in place is
|
|
70
|
-
a working project; a partial rewrite with the lock advanced is a broken one that claims to be current.
|