@flareum/mcp 0.5.0 → 0.5.1

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 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
- await writeLock(process.cwd(), makeLock(projectIdFromToken(config.token), result.publishedVersionId, outDir, new Date().toISOString()));
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
  };
@@ -128,12 +128,15 @@ export const runFirstPull = async (client, cwd, env, configuredOut, knownVersion
128
128
  // Claimed BEFORE the first write: an interrupted pull leaves files with no completed version,
129
129
  // and without this it would read as somebody else's folder and never be finished.
130
130
  await mkdir(resolve(cwd, dir), { recursive: true });
131
- await writeLock(cwd, makeLock(projectId, IN_FLIGHT, dir, now()));
131
+ // The applied version is carried across every write here: this pull is unattended, and
132
+ // advancing it would consume the diff window before an agent could read it.
133
+ const applied = lock?.appliedVersionId ?? syncedVersion(lock, dir) ?? undefined;
134
+ await writeLock(cwd, makeLock(projectId, IN_FLIGHT, dir, now(), applied));
132
135
  const result = await pullStyles(client, fileWriter(resolve(cwd, dir)));
133
136
  // Recorded only when the WHOLE version landed: pullStyles resolves even when files failed, so
134
137
  // stamping on its return marked a half-pulled folder complete and never retried it.
135
138
  if (!isRetryable(result))
136
- await writeLock(cwd, makeLock(projectId, result.publishedVersionId, dir, now()));
139
+ await writeLock(cwd, makeLock(projectId, result.publishedVersionId, dir, now(), applied));
137
140
  return { ran: true, dir, result };
138
141
  }
139
142
  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) => ({ projectId, syncedVersionId, syncedAt: at, out, ...(prefix ? { 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())?.syncedVersionId ?? '';
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
- return text(formatChanges(await client.changes(String(args.since ?? '')), lockedVersion()));
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
@@ -80,14 +80,14 @@ export const TOOL_DESCRIPTIONS = {
80
80
  // Written for a model that is about to EDIT files: the CSS names first, because those are what it
81
81
  // greps for, and the action stated per line so a rename is never applied as a delete plus an add.
82
82
  export const formatChanges = ({ since, totalChanges, entries, truncated, liveVersionId }, lockedVersion = '') => {
83
- if (!totalChanges)
83
+ if (!totalChanges || !entries.length)
84
84
  return since
85
85
  ? `No changes since ${since}. The project is at ${liveVersionId}.`
86
86
  : `This project has no tokens yet.`;
87
87
  const lines = [
88
88
  since
89
- ? `${totalChanges} change(s) since ${since}. The project is now at ${liveVersionId}.`
90
- : `${totalChanges} change(s). No baseline was given, so this is everything the project has.`,
89
+ ? `${entries.length} change(s) since ${since}. The project is now at ${liveVersionId}.`
90
+ : `${entries.length} change(s). No baseline was given, so this is everything the project has.`,
91
91
  '',
92
92
  ];
93
93
  if (lockedVersion && since && lockedVersion !== since)
@@ -114,7 +114,8 @@ const changeLine = (entry) => {
114
114
  if (change === 'typeChanged')
115
115
  return `${kind} type: ${nameOf(before)} is now ${after?.type} (was ${before?.type})`;
116
116
  if (change === 'valueChanged')
117
- return `${kind} value${mode}: ${nameOf(before)} ${before?.value} → ${after?.value}`;
117
+ return `${kind} value${mode}: ${nameOf(before)} ${before?.value ?? '(not set)'} → `
118
+ + `${after?.value ?? '(not set)'}`;
118
119
  if (change === 'movedCollection')
119
120
  return `${kind} moved collection: ${nameOf(before)} → ${nameOf(after)}`;
120
121
  return `${kind} ${change}: ${nameOf(after ?? before)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flareum/mcp",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Connect a coding agent to a Flareum project's design tokens.",
5
5
  "license": "MIT",
6
6
  "author": "Flareum",