trueicon 0.2.0 → 0.2.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/README.md CHANGED
@@ -339,6 +339,39 @@ npm run typecheck # tsc --noEmit
339
339
 
340
340
  CI runs lint, typecheck and tests on Node 20 and 22 for every push and pull request.
341
341
 
342
+ ### Tests
343
+
344
+ | Command | What it checks | Network |
345
+ | --- | --- | --- |
346
+ | `npm test` | Adapter parsing and every tool (`search_icons`, `get_icon`, `list_providers`) for all 9 providers, using the small fixtures in `tests/fixtures/` | No |
347
+ | `npm run smoke` | Every provider against the real npm packages: several pinned releases plus the current latest, checking the icon count and a few well-known icons | Yes |
348
+
349
+ The fixtures only change when someone edits them, so they can't catch a provider that changes its package format upstream. `npm run smoke` does. Run `npm run smoke -- lucide tabler` to check only some providers. CI runs it on pull requests that change `src/providers/`, `src/indexer/` or `src/cache/`, and every Monday against the latest releases.
350
+
351
+ ### Testing and debugging locally
352
+
353
+ These scripts build the server and run it against `playground/`, a sample project that lists all 9 providers at their latest versions. They use a separate cache in `.cache/dev/`, so your real `~/.trueicon` cache is untouched.
354
+
355
+ ```sh
356
+ # Call one tool and print the result
357
+ npm run dev:call -- list_providers
358
+ npm run dev:call -- search_icons query="trash can" limit=5
359
+ npm run dev:call -- search_icons query=trash provider=lucide version=1.47.0
360
+ npm run dev:call -- get_icon name=Trash2 provider=lucide
361
+
362
+ # Open the MCP Inspector web UI on the local build
363
+ npm run dev:inspect
364
+
365
+ # Same, with the Node debugger on port 9229
366
+ npm run dev:debug
367
+ ```
368
+
369
+ - **Arguments** are `key=value` pairs. Numbers and booleans are parsed, so `limit=5` is sent as a number.
370
+ - **Another project:** set `TRUEICON_PROJECT_DIR` to test against its `package.json` and `.iconmcp.json`, e.g. `TRUEICON_PROJECT_DIR=~/code/my-app npm run dev:inspect`.
371
+ - **Rebuild indexes:** add `--fresh` to delete the dev cache first, e.g. `npm run dev:call -- --fresh search_icons query=trash`. Use it after changing an adapter.
372
+ - **Breakpoints:** run `npm run dev:debug`, then in VS Code use **Debug: Attach to Node Process**, or open `chrome://inspect` in Chrome. Source maps are on, so breakpoints work in the `.ts` files under `src/`. Set them, then call a tool from the Inspector.
373
+ - **Logging:** stdout carries the MCP protocol, so log with `console.error`. It shows in the terminal for `dev:call` and in the Inspector's server log for `dev:inspect`.
374
+
342
375
  ### Extending `synonyms.json`
343
376
 
344
377
  `src/synonyms/synonyms.json` maps a term to extra search terms:
@@ -367,6 +400,8 @@ CI runs lint, typecheck and tests on Node 20 and 22 for every push and pull requ
367
400
  - Put a comment at the top of the adapter describing the package's file layout, as the existing adapters do.
368
401
  3. **Wire it up** in `src/providers/adapters/index.ts` by adding it to `ADAPTERS` under the provider id.
369
402
  4. **Test it.** Add a small pinned fixture under `tests/fixtures/<provider>/` that mirrors the package layout, with a few real icon files plus any files the adapter must skip. Then add `tests/adapters/<provider>.test.ts`, covering name mapping, import paths, SVG output and `buildIndex` record ids like the existing adapter tests. `tests/adapters/common.test.ts` fails if a registered provider has no adapter.
403
+ 5. **Add it to the tool tests** by adding a case to `CASES` in `tests/providers-tools.test.ts`: the fixture, a search query, one icon with its exact import line, and a deprecated alias if the package has them. The test fails if a registered provider has no case.
404
+ 6. **Add smoke targets** to `TARGETS` in `scripts/smoke.mjs`: a few well-known import names and a minimum icon count well below the real one. Then run `npm run smoke -- <provider>` to check it against the real published package.
370
405
 
371
406
  ## License
372
407
 
@@ -3,55 +3,102 @@ import { join } from "node:path";
3
3
  import { LiteralCursor } from "../jsLiteral.js";
4
4
  import { renderSvg, toSvgAttrs } from "../svg.js";
5
5
  /*
6
- * lucide-react layout: dist/esm/icons/<kebab-name>.js, one ESM module per icon:
6
+ * lucide-react layout: dist/esm/icons/<kebab-name>.js (.mjs from 1.x), one ESM module per icon.
7
+ * The module body has changed across releases; all three shapes are supported:
7
8
  *
8
- * const Trash2 = createLucideIcon("Trash2", [["path", { d: "...", key: "..." }], ...]);
9
+ * older 0.x: const Trash2 = createLucideIcon("Trash2", [["path", { d: "...", key: "..." }], ...]);
10
+ * later 0.x - 1.46: const __iconNode = [["path", { ... }], ...];
11
+ * const Trash2 = createLucideIcon("trash-2", __iconNode);
12
+ * 1.47+: const __iconData = { name: "trash-2", size: 24, node: [...], aliases: ["..."] };
13
+ * const Trash2 = createLucideIcon(__iconData);
9
14
  *
10
- * Deprecated alias names ship as re-export modules (`export { default } from './target.js'`);
11
- * they are not indexed separately but added to the target icon's tags so old names still match.
12
- * lucide-react ships no categories or tags of its own.
15
+ * The import name always comes from the `const <Name> = createLucideIcon(` binding, because the
16
+ * string argument is the component name in older releases but the kebab name in later ones.
17
+ *
18
+ * Deprecated alias names ship as re-export modules (`export { default } from './target.js'`), and
19
+ * from 1.47 also in __iconData.aliases. They are not indexed separately but added to the target
20
+ * icon's tags so old names still match. lucide-react ships no categories or tags of its own.
13
21
  */
14
22
  const ICONS_DIR = join("dist", "esm", "icons");
15
- const CREATE_CALL = /createLucideIcon\(\s*/;
16
- const ALIAS_EXPORT = /export\s*\{\s*default\s*\}\s*from\s*['"]\.\/([\w-]+)\.js['"]/;
17
- function parseNodes(cursor) {
18
- const nodes = cursor.array();
23
+ const MODULE_FILE = /^(?<name>[\w-]+)\.m?js$/;
24
+ const CREATE_CALL = /const\s+(?<importName>[\w$]+)\s*=\s*createLucideIcon\(\s*/;
25
+ const ICON_NODE = /const\s+__iconNode\s*=\s*/;
26
+ const ICON_DATA = /const\s+__iconData\s*=\s*/;
27
+ const ALIAS_EXPORT = /export\s*\{\s*default\s*\}\s*from\s*['"]\.\/([\w-]+)\.m?js['"]/;
28
+ function toNodes(cursor, nodes) {
29
+ if (!Array.isArray(nodes))
30
+ cursor.fail("expected an array of [tag, attrs]");
19
31
  return nodes.map((node) => {
20
32
  if (!Array.isArray(node) || typeof node[0] !== "string")
21
33
  cursor.fail("expected [tag, attrs]");
22
34
  return { tag: node[0], attr: toSvgAttrs(node[1]), child: [] };
23
35
  });
24
36
  }
37
+ /** Reads the value assigned by `const <binding> = ` in src. */
38
+ function readBinding(src, binding) {
39
+ const match = binding.exec(src);
40
+ if (!match)
41
+ return undefined;
42
+ const cursor = new LiteralCursor(src, match.index + match[0].length);
43
+ return { cursor, value: cursor.value() };
44
+ }
45
+ function parseModule(src) {
46
+ const call = CREATE_CALL.exec(src);
47
+ if (!call)
48
+ return undefined;
49
+ const importName = call.groups.importName;
50
+ const data = readBinding(src, ICON_DATA);
51
+ if (data) {
52
+ const { value } = data;
53
+ const cursor = data.cursor;
54
+ if (!value || typeof value !== "object" || Array.isArray(value))
55
+ cursor.fail("expected __iconData object");
56
+ const aliases = Array.isArray(value.aliases) ? value.aliases.filter((a) => typeof a === "string") : [];
57
+ return { importName, nodes: toNodes(cursor, value.node ?? null), aliases };
58
+ }
59
+ const iconNode = readBinding(src, ICON_NODE);
60
+ if (iconNode)
61
+ return { importName, nodes: toNodes(iconNode.cursor, iconNode.value), aliases: [] };
62
+ // Older 0.x: createLucideIcon("<Name>", [...nodes]).
63
+ const cursor = new LiteralCursor(src, call.index + call[0].length);
64
+ cursor.string();
65
+ cursor.expect(",");
66
+ return { importName, nodes: toNodes(cursor, cursor.array()), aliases: [] };
67
+ }
25
68
  export function parseIcons(packageDir) {
26
69
  const dir = join(packageDir, ICONS_DIR);
27
70
  const icons = new Map();
28
71
  const aliases = [];
29
- for (const file of readdirSync(dir).filter((f) => f.endsWith(".js")).sort()) {
30
- const name = file.slice(0, -".js".length);
72
+ for (const file of readdirSync(dir).sort()) {
73
+ const name = MODULE_FILE.exec(file)?.groups?.name;
74
+ if (!name)
75
+ continue;
31
76
  const src = readFileSync(join(dir, file), "utf8");
32
- const call = CREATE_CALL.exec(src);
33
- if (!call) {
77
+ const icon = parseModule(src);
78
+ if (!icon) {
34
79
  const alias = ALIAS_EXPORT.exec(src);
35
80
  if (alias)
36
81
  aliases.push([name, alias[1]]);
37
82
  continue;
38
83
  }
39
- const cursor = new LiteralCursor(src, call.index + call[0].length);
40
- const importName = cursor.string();
41
- cursor.expect(",");
42
84
  icons.set(name, {
43
85
  name,
44
- importName,
86
+ importName: icon.importName,
45
87
  importPath: "lucide-react",
46
88
  style: "outline",
47
89
  set: "lucide",
48
90
  categories: [],
49
91
  tags: [],
50
- svg: renderSvg(parseNodes(cursor)),
92
+ svg: renderSvg(icon.nodes),
51
93
  });
94
+ for (const alias of icon.aliases)
95
+ aliases.push([alias, name]);
96
+ }
97
+ for (const [alias, target] of aliases) {
98
+ const tags = icons.get(target)?.tags;
99
+ if (tags && !tags.includes(alias))
100
+ tags.push(alias);
52
101
  }
53
- for (const [alias, target] of aliases)
54
- icons.get(target)?.tags?.push(alias);
55
102
  return [...icons.values()];
56
103
  }
57
104
  //# sourceMappingURL=lucide.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lucide.js","sourceRoot":"","sources":["../../../src/providers/adapters/lucide.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lucide.js","sourceRoot":"","sources":["../../../src/providers/adapters/lucide.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { ensureIndex } from "../config/ensureIndex.js";
3
3
  import { CONFIG_FILE, loadProjectConfig } from "../config/loadConfig.js";
4
+ import { toKebabCase } from "../providers/adapter.js";
4
5
  import { getProvider } from "../providers/registry.js";
5
6
  import { loadIndex } from "../search/search.js";
6
7
  import { jsonToolResult, resolveContext, resolveVersion, usageSnippet } from "./context.js";
@@ -9,7 +10,13 @@ function findRecord(records, name) {
9
10
  if (exact)
10
11
  return exact;
11
12
  const lower = name.toLowerCase();
12
- return records.find((r) => r.name.toLowerCase() === lower || r.importName.toLowerCase() === lower);
13
+ const caseInsensitive = records.find((r) => r.name.toLowerCase() === lower || r.importName.toLowerCase() === lower);
14
+ if (caseInsensitive)
15
+ return caseInsensitive;
16
+ // Deprecated or renamed icons are kept as alias tags on the current icon, e.g. lucide 1.47
17
+ // renamed trash-2 to trash, so "Trash2" resolves to the Trash record.
18
+ const kebab = toKebabCase(name);
19
+ return records.find((r) => r.tags.some((tag) => tag === lower || tag === kebab));
13
20
  }
14
21
  /** Looks up one icon by name or import name and returns its full record plus an import snippet. */
15
22
  export async function getIconTool(input, ctx) {
@@ -1 +1 @@
1
- {"version":3,"file":"getIcon.js","sourceRoot":"","sources":["../../src/tools/getIcon.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getIcon.js","sourceRoot":"","sources":["../../src/tools/getIcon.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trueicon",
3
3
  "mcpName": "io.github.manikumarkv/trueicon",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "description": "MCP server that lets AI coding assistants search the icon packages actually installed in your project.",
6
6
  "license": "MIT",
7
7
  "author": "manikumarkv",
@@ -43,7 +43,11 @@
43
43
  "typecheck": "tsc --noEmit",
44
44
  "test": "vitest run",
45
45
  "lint": "eslint",
46
- "prepublishOnly": "npm run build"
46
+ "prepublishOnly": "npm run build",
47
+ "dev:call": "npm run build --silent && node scripts/dev.mjs call",
48
+ "dev:inspect": "npm run build --silent && node scripts/dev.mjs inspect",
49
+ "dev:debug": "npm run build --silent && node scripts/dev.mjs inspect --debug",
50
+ "smoke": "npm run build --silent && node scripts/smoke.mjs"
47
51
  },
48
52
  "dependencies": {
49
53
  "@modelcontextprotocol/sdk": "^1.30.1",