@flareum/mcp 0.2.4 → 0.2.6

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/README.md CHANGED
@@ -177,6 +177,11 @@ area — `naming.md` for how a token name is built, `typography.md` for applying
177
177
  its class rather than the mixin behind it. The whole folder is rewritten every run, so do not edit
178
178
  it, and it prints where it wrote (or why it could not) on stderr.
179
179
 
180
+ **`claude mcp add` alone does not write it.** An MCP server starts when a client first connects, so
181
+ nothing runs until you open a session — or run `claude mcp list`, which connects to report status
182
+ and is why the skill sometimes appears then. `flareum pull` writes it too, so one pull sets the
183
+ project up without waiting for a connection.
184
+
180
185
  On the first connection it also **pulls the stylesheets**, once. It looks for the folder this project
181
186
  already keeps its styles in — `src/styles`, `app/styles`, `scss`, and the rest — and writes them to
182
187
  `<that folder>/flareum`, falling back to `styles/flareum` in a project that has none. It says on
package/dist/cli.js CHANGED
@@ -6,6 +6,7 @@ import { FlareumApiError, FlareumClient } from './client.js';
6
6
  import { CONFIG_PATH, cliErrorReport, parseArgs, resolveConfig } from './config.js';
7
7
  import { chooseStylesDir, fileWriter } from './first-pull.js';
8
8
  import { isRetryable, pullReport, pullStyles } from './pull.js';
9
+ import { installSkill, skillInstallReport } from './skill.js';
9
10
  import { watchIntervalMs, watchPublished, watchStartedReport } from './watch.js';
10
11
  // Where the styles go is decided in ONE place, so the CLI and the server never disagree about it.
11
12
  const defaultOut = () => chooseStylesDir(path => existsSync(resolve(process.cwd(), path)));
@@ -58,6 +59,9 @@ try {
58
59
  const outDir = config.out ?? defaultOut();
59
60
  const client = new FlareumClient({ token: config.token, api: config.api });
60
61
  const write = fileWriter(resolve(process.cwd(), outDir));
62
+ // The server writes the skill too, but only when a client connects — `claude mcp add` spawns
63
+ // nothing, so until now the rules arrived on whatever ran first, which was luck.
64
+ console.log(skillInstallReport(await installSkill(process.cwd())));
61
65
  const runPull = async () => {
62
66
  const result = await pullStyles(client, write);
63
67
  console.log(pullReport(result, outDir));
package/dist/server.js CHANGED
@@ -9,11 +9,20 @@ import { FlareumApiError, FlareumClient } from './client.js';
9
9
  import { TOOL_DESCRIPTIONS, formatError, formatSearch, formatVariable } from './tools.js';
10
10
  import { installSkill, skillInstallReport } from './skill.js';
11
11
  import { configuredOut, firstPullReport, runFirstPull } from './first-pull.js';
12
- const client = new FlareumClient({
13
- token: process.env.FLAREUM_TOKEN ?? '',
14
- api: process.env.FLAREUM_API,
15
- projectId: process.env.FLAREUM_PROJECT,
16
- });
12
+ // A missing key threw at module load, and an editor shows that as a Node stack trace with the
13
+ // message buried in it. Say it in one line and exit, the way the CLI already does.
14
+ let client;
15
+ try {
16
+ client = new FlareumClient({
17
+ token: process.env.FLAREUM_TOKEN ?? '',
18
+ api: process.env.FLAREUM_API,
19
+ projectId: process.env.FLAREUM_PROJECT,
20
+ });
21
+ }
22
+ catch (error) {
23
+ console.error(`[flareum] ${error instanceof Error ? error.message : String(error)}`);
24
+ process.exit(1);
25
+ }
17
26
  // Read, never restated: the hardcoded 0.1.0 kept reporting itself from a 0.2.1 package.
18
27
  const { version } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
19
28
  const server = new Server({ name: 'flareum', version }, { capabilities: { tools: {} } });
package/dist/skill.d.ts CHANGED
@@ -7,5 +7,6 @@ export type SkillInstall = {
7
7
  reason: string;
8
8
  };
9
9
  export declare const installSkill: (cwd: string) => Promise<SkillInstall>;
10
+ export declare const installSkillFrom: (source: string, cwd: string) => Promise<SkillInstall>;
10
11
  /** Reported on stderr — stdout carries the JSON-RPC stream and must never be written to. */
11
12
  export declare const skillInstallReport: (result: SkillInstall) => string;
package/dist/skill.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { existsSync } from 'node:fs';
1
2
  import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
2
3
  import { dirname, join } from 'node:path';
3
4
  import { fileURLToPath } from 'node:url';
@@ -14,11 +15,16 @@ const copyTree = async (from, to) => {
14
15
  };
15
16
  // Written on every start, not once: a stale copy of the rules is worse than none, and the files are
16
17
  // generated rather than hand-edited.
17
- export const installSkill = async (cwd) => {
18
- const source = join(dirname(fileURLToPath(import.meta.url)), '..', 'skill');
18
+ export const installSkill = (cwd) => installSkillFrom(join(dirname(fileURLToPath(import.meta.url)), '..', 'skill'), cwd);
19
+ // The source is a parameter so the "wrote nothing" case can be driven, not just reasoned about.
20
+ export const installSkillFrom = async (source, cwd) => {
19
21
  const path = join(cwd, ...SKILL_DIR, 'SKILL.md');
20
22
  try {
21
23
  await copyTree(source, join(cwd, ...SKILL_DIR));
24
+ // copyTree makes directories before it writes, so a source that carries none of the files still
25
+ // leaves a tree that LOOKS installed. Success is the router being on disk, not the walk ending.
26
+ if (!existsSync(path))
27
+ return { ok: false, path, reason: `nothing was written — no SKILL.md under ${source}` };
22
28
  return { ok: true, path };
23
29
  }
24
30
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flareum/mcp",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Connect a coding agent to a Flareum project's design tokens.",
5
5
  "license": "MIT",
6
6
  "author": "Flareum",