clast-ai 0.2.0 → 0.2.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clast",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Code index for coding agents: symbol search, exact symbol source, type-aware call graph, references, type hierarchy, change impact, dead code and exact counts for any repository. TypeScript, JavaScript, Python, Java, C#, Go, Rust, C, C++, Ruby, PHP, Swift and Dart.",
5
5
  "author": {
6
6
  "name": "Thomas"
package/README.md CHANGED
@@ -51,8 +51,48 @@ and four slash commands:
51
51
  | `/clast:audit [path]` | Inventory for due diligence or onboarding: size, structure, endpoints, database access, dependencies, dead code |
52
52
  | `/clast:status` | State of the index |
53
53
 
54
- The plugin starts the server from a global `clast-ai` 0.2.x when there is one, otherwise through
55
- `npx clast-ai@0.2` (downloaded on first use). Update with `/plugin update clast@clast`.
54
+ The plugin starts the server from a global `clast-ai` that is at least as new as the plugin, otherwise
55
+ through `npx clast-ai@<plugin version>` (downloaded on first use).
56
+
57
+ ### Upgrading from an older install
58
+
59
+ If clast is already set up the old way (`npm install -g clast-ai` plus `claude mcp add`, or through
60
+ the old VS Code extension), install the plugin and restart. That is all, provided Node.js is 22.22 or
61
+ newer (0.1 ran on Node 18; check with `node --version`):
62
+
63
+ ```
64
+ /plugin marketplace add xls/clast
65
+ /plugin install clast@clast
66
+ ```
67
+
68
+ The first session after that cleans up in the background, once per plugin version:
69
+
70
+ - clast servers registered with `claude mcp add`, for all projects or for single ones, are removed
71
+ (the plugin provides the server; with both, every tool would be listed twice),
72
+ - entries the old VS Code extension wrote into `.claude/settings.local.json` are removed,
73
+ - the v0.1 index file `.clast/clast.db` is deleted (the new index is rebuilt by itself).
74
+
75
+ Restart Claude Code once more and `/mcp` shows a single `clast` server.
76
+
77
+ One case is left to you: a project whose `.mcp.json` lists clast. That file is shared with a team, so
78
+ it is never changed, and in that project the server stays listed twice until the entry is removed
79
+ from the file (`clast-ai migrate` names the file).
80
+
81
+ Optional: `npm uninstall -g clast-ai` removes the old global package. The plugin does not need it; it
82
+ only uses a global install that is at least as new as the plugin itself.
83
+
84
+ To see what would be removed, or to do it by hand (for example when you keep using the plain MCP
85
+ server and only want the old index gone):
86
+
87
+ ```bash
88
+ clast-ai migrate # report only
89
+ clast-ai migrate --apply # remove the leftovers
90
+ ```
91
+
92
+ What was removed is logged to `migrate.log` in the plugin's data folder. `CLAST_NO_MIGRATE=1` switches
93
+ the automatic clean-up off.
94
+
95
+ Later plugin updates: `/plugin marketplace update clast`, then `/plugin update clast@clast`.
56
96
 
57
97
  ### As a plain MCP server
58
98
 
@@ -62,7 +102,8 @@ claude mcp add -s user clast clast-ai
62
102
  ```
63
103
 
64
104
  `-s user` registers the server for all projects. This gives the tools without the skill and the slash
65
- commands. Use one of the two ways, not both: with both, every tool is listed twice.
105
+ commands. Use one of the two ways, not both: with both, every tool is listed twice (the plugin removes
106
+ a registration made this way when it is installed later).
66
107
 
67
108
  Either way, restart Claude Code (or "Developer: Reload Window" in VS Code) and run `/mcp`: `clast`
68
109
  should be listed with 15 tools. The first start indexes the project in the background (seconds, about
@@ -398,6 +439,21 @@ Known limitations).
398
439
 
399
440
  ## Changelog
400
441
 
442
+ ### 0.2.2
443
+
444
+ - The clean-up of older installs also finds servers registered as `node .../dist/server/index.js` (how
445
+ the 0.1 README registered a build from source) and reads the configuration from `CLAUDE_CONFIG_DIR`
446
+ when that is set. Both were found by installing the plugin into an empty configuration next to an
447
+ old-style registration.
448
+
449
+ ### 0.2.1
450
+
451
+ - `clast-ai migrate`: finds and removes what older installs left behind (duplicate MCP registrations
452
+ next to the plugin, entries written by the old VS Code extension, the v0.1 index file). The plugin
453
+ runs it automatically, once per version, at the first session after an install or update.
454
+ - The plugin uses a global `clast-ai` only when it is at least as new as the plugin itself, so a
455
+ plugin update is not held back by an older global install.
456
+
401
457
  ### 0.2.0
402
458
 
403
459
  New tools (7 to 13):
@@ -450,7 +506,7 @@ Other:
450
506
 
451
507
  - Swift and Dart added (14 languages).
452
508
  - All dependencies updated (MCP SDK 1.32, web-tree-sitter 0.27).
453
- - 283 tests, plus `bench/bench.mjs`, `bench/resolution.mjs` and the A/B harness `bench/ab.mjs`.
509
+ - 291 tests, plus `bench/bench.mjs`, `bench/resolution.mjs` and the A/B harness `bench/ab.mjs`.
454
510
  - Installable as a Claude Code plugin from this repository (`/plugin marketplace add xls/clast`,
455
511
  `/plugin install clast@clast`): the MCP server, a usage skill, and the slash commands
456
512
  `/clast:deadcode`, `/clast:impact`, `/clast:audit` and `/clast:status`. The old VS Code extension
@@ -466,10 +522,12 @@ Other:
466
522
 
467
523
  ### Upgrading from 0.1
468
524
 
525
+ How to upgrade: see [Upgrading from an older install](#upgrading-from-an-older-install). What changed:
526
+
469
527
  - Node.js 22.22+ is required (was 18).
470
528
  - The index moved from `.clast/clast.db` (sql.js) to `.clast/index.db` (`node:sqlite`). Nothing is
471
- migrated: the index is a cache and is rebuilt on first start. The old file is ignored and can be
472
- deleted.
529
+ migrated: the index is a cache and is rebuilt on first start. The old file is ignored; the plugin
530
+ (or `clast-ai migrate --apply`) deletes it.
473
531
  - A later schema change deletes and rebuilds the index automatically (the schema is at version 26).
474
532
  - Tool output is compact text instead of JSON.
475
533
  - `clast_call_graph` defaults to depth 1 and gained `within` and `includeTests`.
package/dist/cli.js CHANGED
@@ -33,6 +33,8 @@ usage: clast-ai [command] [args] [--root <dir>]
33
33
  unused [path] dead code [--kind k] [--lang l] [--limit n] [--no-exported]
34
34
  stats [what] [name] exact counts: inventory | symbols | subtypes | calls | text | imports | endpoints | database
35
35
  [--kind k] [--on receiver] [--path p] [--lang l] [--group-by g] [--depth n] [--limit n] [--tests]
36
+ migrate [--apply] find (and with --apply remove) what older installs left behind: duplicate
37
+ MCP registrations next to the plugin, the v0.1 index file
36
38
  parse <file> [--json] debug: show what the extractor produces for a file
37
39
  ast <file> debug: dump the tree-sitter syntax tree
38
40
 
@@ -54,7 +56,7 @@ const CLI_NAMES = {
54
56
  clast_status: 'clast-ai status',
55
57
  };
56
58
  const BOOLEAN_FLAGS = new Set([
57
- 'force', 'json', 'regex', 'no-body', 'no-scan', 'no-tests', 'tests', 'uncertain', 'help', 'version', 'all', 'no-exported',
59
+ 'force', 'json', 'regex', 'no-body', 'no-scan', 'no-tests', 'tests', 'uncertain', 'help', 'version', 'all', 'no-exported', 'apply', 'auto',
58
60
  ]);
59
61
  function parseArgs(argv) {
60
62
  const positional = [];
@@ -100,6 +102,13 @@ async function main() {
100
102
  await startServer();
101
103
  return;
102
104
  }
105
+ if (cmd === 'migrate') {
106
+ const { migrate } = await import('./migrate.js');
107
+ const out = await migrate({ apply: flags.has('apply'), auto: flags.has('auto'), force: flags.has('force'), cwd: str('root') });
108
+ if (out)
109
+ console.log(out);
110
+ return;
111
+ }
103
112
  if (cmd === 'parse' || cmd === 'ast') {
104
113
  const file = positional[0];
105
114
  if (!file)
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,2EAA2E;AAC3E,wEAAwE;AACxE,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,IAAI,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAkB,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,IAAI,GAAG,YAAY,OAAO;;;;;;;;;;;;;;;;;;;;;;;;4EAwB4C,CAAC;AAE7E,MAAM,SAAS,GAA2B;IACxC,YAAY,EAAE,iBAAiB;IAC/B,iBAAiB,EAAE,iBAAiB;IACpC,gBAAgB,EAAE,4BAA4B;IAC9C,gBAAgB,EAAE,eAAe;IACjC,eAAe,EAAE,oBAAoB;IACrC,kBAAkB,EAAE,kBAAkB;IACtC,cAAc,EAAE,mBAAmB;IACnC,UAAU,EAAE,eAAe;IAC3B,aAAa,EAAE,kBAAkB;IACjC,WAAW,EAAE,gBAAgB;IAC7B,YAAY,EAAE,iBAAiB;IAC/B,YAAY,EAAE,iBAAiB;IAC/B,aAAa,EAAE,gBAAgB;IAC/B,YAAY,EAAE,iBAAiB;CAChC,CAAC;AAOF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa;CAC1H,CAAC,CAAC;AAEH,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACnB,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,EAAE,KAAK,CAAC,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;iBACrD,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;;gBACvF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;YAC1C,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,CAAC,CAAS,EAAsB,EAAE;QAC5C,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAsB,EAAE;QAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,CAAC,CAAC;IAEF,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEvE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACzC,IAAI,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,CAAC;QACvE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC1D,MAAM,WAAW,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAClC,IAAI,GAAG,KAAK,KAAK;YAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAChF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAClD,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5E,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE;gBACjG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE;gBAC1E,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACnE,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9H,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAE,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACjG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,MAAM,4BAA4B,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtF,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpF,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,MAAM,EAAE,CAAC;gBACX,iEAAiE;gBACjE,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChE,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1D,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3F,IAAI,GAAW,CAAC;QAChB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,QAAQ;gBACX,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxB,MAAM;YACR,KAAK,UAAU,CAAC;YAChB,KAAK,KAAK;gBACR,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACnD,MAAM;YACR,KAAK,SAAS,CAAC;YACf,KAAK,MAAM;gBACT,GAAG,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;gBACzG,MAAM;YACR,KAAK,QAAQ;gBACX,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE;oBACtB,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;iBAC1G,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS;gBACZ,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE;oBAC1B,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;iBACpG,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,SAAS,CAAC;YACf,KAAK,SAAS,CAAC;YACf,KAAK,OAAO;gBACV,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;oBACzB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;oBAC5C,SAAS,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;oBACzC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;iBACjH,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,WAAW,CAAC;YACjB,KAAK,OAAO;gBACV,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;oBACzB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;oBAC7G,SAAS,EAAE,GAAG,CAAC,WAAW,CAAmD;iBAC9E,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,MAAM,CAAC;YACZ,KAAK,YAAY;gBACf,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;gBACjH,MAAM;YACR,KAAK,MAAM;gBACT,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE;oBACpB,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;oBAC9F,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,YAAY;iBAClC,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,SAAS;gBACZ,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,QAAQ;gBACX,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACrH,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,MAAM;gBACT,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE;oBACtB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;oBAC7F,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;iBACvD,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;gBACxG,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACpD,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBACrB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAE,UAAU,CAAC,CAAC,CAAuB,CAAC,CAAC,CAAC,SAAS;oBAChE,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;oBACzE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;oBACtE,OAAO,EAAE,GAAG,CAAC,UAAU,CAAyB,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;oBAC1F,YAAY,EAAE,YAAY,KAAK,IAAI;iBACpC,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;YACD;gBACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,OAAO,IAAI,EAAE,CAAC,CAAC;gBACpD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;QACX,CAAC;QACD,mEAAmE;QACnE,OAAO,CAAC,GAAG,CACT,GAAG;aACA,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aACjD,OAAO,CAAC,qBAAqB,EAAE,aAAa,CAAC;aAC7C,OAAO,CAAC,wBAAwB,EAAE,SAAS,CAAC;aAC5C,OAAO,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CACvD,CAAC;QACF,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACrD,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,2EAA2E;AAC3E,wEAAwE;AACxE,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,IAAI,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAkB,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,IAAI,GAAG,YAAY,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;4EA0B4C,CAAC;AAE7E,MAAM,SAAS,GAA2B;IACxC,YAAY,EAAE,iBAAiB;IAC/B,iBAAiB,EAAE,iBAAiB;IACpC,gBAAgB,EAAE,4BAA4B;IAC9C,gBAAgB,EAAE,eAAe;IACjC,eAAe,EAAE,oBAAoB;IACrC,kBAAkB,EAAE,kBAAkB;IACtC,cAAc,EAAE,mBAAmB;IACnC,UAAU,EAAE,eAAe;IAC3B,aAAa,EAAE,kBAAkB;IACjC,WAAW,EAAE,gBAAgB;IAC7B,YAAY,EAAE,iBAAiB;IAC/B,YAAY,EAAE,iBAAiB;IAC/B,aAAa,EAAE,gBAAgB;IAC/B,YAAY,EAAE,iBAAiB;CAChC,CAAC;AAOF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;CAC3I,CAAC,CAAC;AAEH,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACnB,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,EAAE,KAAK,CAAC,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;iBACrD,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;;gBACvF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;YAC1C,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,CAAC,CAAS,EAAsB,EAAE;QAC5C,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAsB,EAAE;QAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,CAAC,CAAC;IAEF,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEvE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACzC,IAAI,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,CAAC;QACvE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC1D,MAAM,WAAW,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/H,IAAI,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAClC,IAAI,GAAG,KAAK,KAAK;YAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAChF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAClD,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5E,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE;gBACjG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE;gBAC1E,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACnE,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9H,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAE,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACjG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,MAAM,4BAA4B,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtF,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpF,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,MAAM,EAAE,CAAC;gBACX,iEAAiE;gBACjE,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChE,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1D,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3F,IAAI,GAAW,CAAC;QAChB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,QAAQ;gBACX,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxB,MAAM;YACR,KAAK,UAAU,CAAC;YAChB,KAAK,KAAK;gBACR,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACnD,MAAM;YACR,KAAK,SAAS,CAAC;YACf,KAAK,MAAM;gBACT,GAAG,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;gBACzG,MAAM;YACR,KAAK,QAAQ;gBACX,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE;oBACtB,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;iBAC1G,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS;gBACZ,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE;oBAC1B,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;iBACpG,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,SAAS,CAAC;YACf,KAAK,SAAS,CAAC;YACf,KAAK,OAAO;gBACV,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;oBACzB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;oBAC5C,SAAS,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;oBACzC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;iBACjH,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,WAAW,CAAC;YACjB,KAAK,OAAO;gBACV,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;oBACzB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;oBAC7G,SAAS,EAAE,GAAG,CAAC,WAAW,CAAmD;iBAC9E,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,MAAM,CAAC;YACZ,KAAK,YAAY;gBACf,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;gBACjH,MAAM;YACR,KAAK,MAAM;gBACT,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE;oBACpB,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;oBAC9F,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,YAAY;iBAClC,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,SAAS;gBACZ,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,QAAQ;gBACX,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACrH,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,MAAM;gBACT,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE;oBACtB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;oBAC7F,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;iBACvD,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;gBACxG,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACpD,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBACrB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAE,UAAU,CAAC,CAAC,CAAuB,CAAC,CAAC,CAAC,SAAS;oBAChE,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;oBACzE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;oBACtE,OAAO,EAAE,GAAG,CAAC,UAAU,CAAyB,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;oBAC1F,YAAY,EAAE,YAAY,KAAK,IAAI;iBACpC,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;YACD;gBACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,OAAO,IAAI,EAAE,CAAC,CAAC;gBACpD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;QACX,CAAC;QACD,mEAAmE;QACnE,OAAO,CAAC,GAAG,CACT,GAAG;aACA,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aACjD,OAAO,CAAC,qBAAqB,EAAE,aAAa,CAAC;aAC7C,OAAO,CAAC,wBAAwB,EAAE,SAAS,CAAC;aAC5C,OAAO,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CACvD,CAAC;QACF,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACrD,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface MigrateOptions {
2
+ /** Make the changes. Default: only report. */
3
+ apply?: boolean;
4
+ /** Run from the plugin at session start: once per version, silent, only when the plugin is installed. */
5
+ auto?: boolean;
6
+ /** Remove hand-made registrations even when the plugin is not installed. */
7
+ force?: boolean;
8
+ home?: string;
9
+ cwd?: string;
10
+ /** Replaces `claude mcp remove` (tests). Returns true on success. */
11
+ remove?: (name: string, scope: 'user' | 'local', cwd: string) => boolean;
12
+ }
13
+ export type Action = {
14
+ kind: 'mcp';
15
+ scope: 'user' | 'local';
16
+ name: string;
17
+ dir: string;
18
+ command: string;
19
+ } | {
20
+ kind: 'settings';
21
+ file: string;
22
+ name: string;
23
+ } | {
24
+ kind: 'index';
25
+ files: string[];
26
+ } | {
27
+ kind: 'shared';
28
+ file: string;
29
+ name: string;
30
+ };
31
+ export declare function pluginInstalled(home: string): boolean;
32
+ /** Everything an older install left behind, without changing anything. */
33
+ export declare function planMigration(home: string, cwd: string): Action[];
34
+ export declare function migrate(opts?: MigrateOptions): Promise<string>;
@@ -0,0 +1,205 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join, resolve } from 'node:path';
5
+ import { VERSION } from './version.js';
6
+ /** A registration of this server: by name, by the `clast-ai` binary, or by a path to its cli.js. */
7
+ function isClast(_name, entry) {
8
+ if (!entry || typeof entry !== 'object')
9
+ return false;
10
+ const command = String(entry.command ?? '');
11
+ const args = Array.isArray(entry.args) ? entry.args.map(String) : [];
12
+ if (/(^|[\\/])clast-ai(\.cmd|\.exe)?$/i.test(command))
13
+ return true;
14
+ // dist/cli.js, and dist/server/index.js as the 0.1 README registered a build from source.
15
+ if (args.some(a => /clast[^\\/]*[\\/]dist[\\/](cli|server[\\/]index)\.js$/i.test(a)))
16
+ return true;
17
+ // `npx clast-ai`, `npx -y clast-ai@0.1`
18
+ if (/(^|[\\/])npx(\.cmd)?$/i.test(command) && args.some(a => /^clast-ai(@|$)/.test(a)))
19
+ return true;
20
+ return false;
21
+ }
22
+ function readJson(path) {
23
+ try {
24
+ return JSON.parse(readFileSync(path, 'utf8'));
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ function describe(entry) {
31
+ return [entry.command ?? '', ...(Array.isArray(entry.args) ? entry.args.map(String) : [])].join(' ').trim();
32
+ }
33
+ /** Is the clast plugin installed for this user? */
34
+ /**
35
+ * Where Claude Code keeps its configuration: `~/.claude.json` and `~/.claude/`, or both inside
36
+ * CLAUDE_CONFIG_DIR when that is set.
37
+ */
38
+ function claudePaths(home) {
39
+ const dir = process.env.CLAUDE_CONFIG_DIR;
40
+ return dir
41
+ ? { config: join(dir, '.claude.json'), plugins: join(dir, 'plugins') }
42
+ : { config: join(home, '.claude.json'), plugins: join(home, '.claude', 'plugins') };
43
+ }
44
+ export function pluginInstalled(home) {
45
+ const installed = readJson(join(claudePaths(home).plugins, 'installed_plugins.json'));
46
+ const plugins = (installed?.plugins ?? {});
47
+ return Object.keys(plugins).some(id => /^clast@/.test(id));
48
+ }
49
+ /** Everything an older install left behind, without changing anything. */
50
+ export function planMigration(home, cwd) {
51
+ const actions = [];
52
+ const config = readJson(claudePaths(home).config);
53
+ const servers = (config?.mcpServers ?? {});
54
+ for (const [name, entry] of Object.entries(servers)) {
55
+ if (isClast(name, entry))
56
+ actions.push({ kind: 'mcp', scope: 'user', name, dir: cwd, command: describe(entry) });
57
+ }
58
+ const projects = (config?.projects ?? {});
59
+ for (const [dir, project] of Object.entries(projects)) {
60
+ for (const [name, entry] of Object.entries(project?.mcpServers ?? {})) {
61
+ if (isClast(name, entry))
62
+ actions.push({ kind: 'mcp', scope: 'local', name, dir, command: describe(entry) });
63
+ }
64
+ }
65
+ // Written by the old VS Code extension.
66
+ const settingsFile = join(cwd, '.claude', 'settings.local.json');
67
+ const settings = readJson(settingsFile);
68
+ for (const [name, entry] of Object.entries((settings?.mcpServers ?? {}))) {
69
+ if (isClast(name, entry))
70
+ actions.push({ kind: 'settings', file: settingsFile, name });
71
+ }
72
+ // The v0.1 index. v0.2 keeps its own file (.clast/index.db) and never reads this one.
73
+ const old = ['clast.db', 'clast.db-wal', 'clast.db-shm'].map(f => join(cwd, '.clast', f)).filter(f => existsSync(f));
74
+ if (old.length)
75
+ actions.push({ kind: 'index', files: old });
76
+ // A team's shared file is theirs to change.
77
+ const sharedFile = join(cwd, '.mcp.json');
78
+ const shared = readJson(sharedFile);
79
+ for (const [name, entry] of Object.entries((shared?.mcpServers ?? {}))) {
80
+ if (isClast(name, entry))
81
+ actions.push({ kind: 'shared', file: sharedFile, name });
82
+ }
83
+ return actions;
84
+ }
85
+ function claudeRemove(name, scope, cwd) {
86
+ const windows = process.platform === 'win32';
87
+ // Fixed words plus a server name restricted to safe characters: nothing to escape.
88
+ if (!/^[\w.-]+$/.test(name))
89
+ return false;
90
+ const result = windows
91
+ ? spawnSync(`claude mcp remove ${name} -s ${scope}`, { cwd, shell: true, stdio: 'ignore', windowsHide: true, timeout: 30_000 })
92
+ : spawnSync('claude', ['mcp', 'remove', name, '-s', scope], { cwd, stdio: 'ignore', timeout: 30_000 });
93
+ return result.status === 0;
94
+ }
95
+ function line(a) {
96
+ switch (a.kind) {
97
+ case 'mcp':
98
+ return a.scope === 'user'
99
+ ? `server "${a.name}" registered for all projects (${a.command})`
100
+ : `server "${a.name}" registered for ${a.dir} (${a.command})`;
101
+ case 'settings':
102
+ return `server "${a.name}" in ${a.file} (written by the old VS Code extension)`;
103
+ case 'index':
104
+ return `v0.1 index: ${a.files.join(', ')}`;
105
+ case 'shared':
106
+ return `server "${a.name}" in ${a.file} (shared with your team: not changed; remove it there if everyone uses the plugin)`;
107
+ }
108
+ }
109
+ export async function migrate(opts = {}) {
110
+ const home = opts.home ?? homedir();
111
+ const cwd = resolve(opts.cwd ?? process.env.CLAST_PROJECT_DIR ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd());
112
+ const stateDir = process.env.CLAUDE_PLUGIN_DATA || join(home, '.clast-ai');
113
+ const marker = join(stateDir, 'migrated.json');
114
+ const plugin = pluginInstalled(home);
115
+ if (opts.auto) {
116
+ // Only the plugin starts this, but be sure: without it the registrations are the only install there is.
117
+ if (!plugin)
118
+ return '';
119
+ const done = readJson(marker);
120
+ const fresh = done?.version !== VERSION;
121
+ // The registrations are checked once per version; a project's old index whenever it is seen.
122
+ const plan = planMigration(home, cwd).filter(a => a.kind === 'index' || (fresh && a.kind !== 'shared'));
123
+ const report = plan.length ? apply(plan, opts) : [];
124
+ try {
125
+ mkdirSync(stateDir, { recursive: true });
126
+ if (fresh)
127
+ writeFileSync(marker, JSON.stringify({ version: VERSION, at: new Date().toISOString() }) + '\n');
128
+ if (report.length) {
129
+ appendFileSync(join(stateDir, 'migrate.log'), `${new Date().toISOString()} clast ${VERSION}\n${report.map(r => ' ' + r).join('\n')}\n`);
130
+ }
131
+ }
132
+ catch {
133
+ // A read-only home directory must not stop the server.
134
+ }
135
+ return report.join('\n');
136
+ }
137
+ const plan = planMigration(home, cwd);
138
+ const out = [];
139
+ const removable = plan.filter(a => a.kind !== 'shared');
140
+ const blocked = !plugin && !opts.force;
141
+ if (plan.length === 0) {
142
+ out.push('nothing to migrate: no older clast registration or index found.');
143
+ }
144
+ else if (!opts.apply) {
145
+ out.push(`found ${plan.length} leftover${plan.length === 1 ? '' : 's'} of an older clast install:`);
146
+ for (const a of plan)
147
+ out.push(` - ${line(a)}`);
148
+ if (removable.length) {
149
+ out.push(blocked
150
+ ? 'The clast plugin is not installed, so the registrations above are your only install. Install the plugin ' +
151
+ '(/plugin marketplace add xls/clast, /plugin install clast@clast) and run this again, or pass --force.'
152
+ : 'Run `clast-ai migrate --apply` to remove them (the plugin provides the server).');
153
+ }
154
+ }
155
+ else {
156
+ const todo = blocked ? removable.filter(a => a.kind === 'index') : removable;
157
+ out.push(...apply(todo, opts));
158
+ for (const a of plan.filter(p => p.kind === 'shared'))
159
+ out.push(`left alone: ${line(a)}`);
160
+ if (blocked && removable.some(a => a.kind !== 'index')) {
161
+ out.push('registrations kept: the clast plugin is not installed (pass --force to remove them anyway).');
162
+ }
163
+ if (todo.some(a => a.kind === 'mcp' || a.kind === 'settings'))
164
+ out.push('Restart Claude Code to apply.');
165
+ }
166
+ if (!plugin)
167
+ out.push('plugin: not installed.');
168
+ return out.join('\n');
169
+ }
170
+ function apply(plan, opts) {
171
+ const remove = opts.remove ?? claudeRemove;
172
+ const report = [];
173
+ for (const a of plan) {
174
+ try {
175
+ if (a.kind === 'mcp') {
176
+ if (a.scope === 'local' && !existsSync(a.dir)) {
177
+ report.push(`skipped (directory no longer exists): ${line(a)}`);
178
+ continue;
179
+ }
180
+ report.push(`${remove(a.name, a.scope, a.dir) ? 'removed' : 'could not remove (is the claude CLI on PATH?)'}: ${line(a)}`);
181
+ }
182
+ else if (a.kind === 'settings') {
183
+ const settings = readJson(a.file);
184
+ const servers = settings?.mcpServers;
185
+ if (settings && servers && a.name in servers) {
186
+ delete servers[a.name];
187
+ if (Object.keys(servers).length === 0)
188
+ delete settings.mcpServers;
189
+ writeFileSync(a.file, JSON.stringify(settings, null, 2) + '\n');
190
+ report.push(`removed: ${line(a)}`);
191
+ }
192
+ }
193
+ else if (a.kind === 'index') {
194
+ for (const f of a.files)
195
+ rmSync(f, { force: true });
196
+ report.push(`deleted: ${line(a)}`);
197
+ }
198
+ }
199
+ catch (err) {
200
+ report.push(`failed: ${line(a)}: ${err instanceof Error ? err.message : err}`);
201
+ }
202
+ }
203
+ return report;
204
+ }
205
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Package version (keep in sync with package.json; checked by a test). */
2
- export declare const VERSION = "0.2.0";
2
+ export declare const VERSION = "0.2.2";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Package version (keep in sync with package.json; checked by a test). */
2
- export const VERSION = '0.2.0';
2
+ export const VERSION = '0.2.2';
3
3
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clast-ai",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Code index MCP server for LLM coding agents: ranked symbol search, exact symbol source, type-aware call graph, references, type hierarchy and git change impact",
5
5
  "main": "dist/engine.js",
6
6
  "bin": {
package/plugin/server.mjs CHANGED
@@ -2,17 +2,26 @@
2
2
  // Starts the clast MCP server for the Claude Code plugin. A plugin is installed by cloning the
3
3
  // repository, which has no build output, so the server is taken from the first place that has one:
4
4
  // 1. this checkout, when it has been built (a development clone),
5
- // 2. a global `clast-ai` of the same major.minor version,
6
- // 3. `npx clast-ai@<major.minor>` (downloaded on first use, cached afterwards).
5
+ // 2. a global `clast-ai` of the same minor version that is at least as new as the plugin,
6
+ // 3. `npx clast-ai@<plugin version>` (downloaded on first use, cached afterwards).
7
7
  // Standard input and output are passed straight through: they carry the MCP protocol.
8
+ //
9
+ // After the server is up it also runs `clast-ai migrate --apply --auto` in the background. That
10
+ // removes, once per version, what an older install left behind (hand-made MCP registrations that
11
+ // would list every tool twice, the v0.1 index file), so installing or upgrading the plugin is
12
+ // all a user has to do.
8
13
  import { spawn, spawnSync } from 'node:child_process';
9
14
  import { existsSync, readFileSync } from 'node:fs';
15
+ import { tmpdir } from 'node:os';
10
16
  import { dirname, join } from 'node:path';
11
17
  import { fileURLToPath } from 'node:url';
12
18
 
13
19
  const root = join(dirname(fileURLToPath(import.meta.url)), '..');
14
- const wanted = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version.split('.').slice(0, 2).join('.');
20
+ const version = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version;
21
+ const [major, minor, patch] = version.split('.').map(Number);
15
22
  const windows = process.platform === 'win32';
23
+ // The project the server indexes: the same order the server itself uses.
24
+ const projectDir = process.env.CLAST_PROJECT_DIR ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
16
25
  const log = msg => process.stderr.write(`[clast plugin] ${msg}\n`);
17
26
 
18
27
  function pick() {
@@ -24,27 +33,46 @@ function pick() {
24
33
  ? spawnSync('clast-ai --version', { encoding: 'utf8', shell: true, windowsHide: true })
25
34
  : spawnSync('clast-ai', ['--version'], { encoding: 'utf8', windowsHide: true });
26
35
  const found = probe.status === 0 ? probe.stdout.trim() : '';
27
- if (found.startsWith(wanted + '.')) {
36
+ const [fMajor, fMinor, fPatch] = found.split('.').map(Number);
37
+ if (found && fMajor === major && fMinor === minor && fPatch >= patch) {
28
38
  return { command: 'clast-ai', args: [], shell: windows, what: `global clast-ai ${found}` };
29
39
  }
30
- if (found) log(`global clast-ai is ${found}, the plugin needs ${wanted}.x: using npx instead`);
31
- return { command: 'npx', args: ['-y', `clast-ai@${wanted}`], shell: windows, what: `npx clast-ai@${wanted}` };
40
+ if (found) log(`global clast-ai is ${found}, the plugin is ${version}: using npx instead (npm install -g clast-ai updates it)`);
41
+ // npx runs from a neutral directory: inside a folder whose package.json is itself called clast-ai it
42
+ // would take that folder for the package and start whatever `clast-ai` is on PATH.
43
+ return { command: 'npx', args: ['-y', `clast-ai@${version}`], shell: windows, what: `npx clast-ai@${version}`, cwd: tmpdir() };
32
44
  }
33
45
 
34
- const major = Number(process.versions.node.split('.')[0]);
35
- if (major < 22) {
46
+ /** Run the chosen clast-ai with extra arguments. Through a shell (.cmd shims on Windows) the command is one string of fixed words. */
47
+ function run(choice, extra, options) {
48
+ const args = [...choice.args, ...extra];
49
+ if (choice.cwd) options = { ...options, cwd: choice.cwd, env: { ...process.env, CLAST_PROJECT_DIR: projectDir } };
50
+ return choice.shell
51
+ ? spawn([choice.command, ...args].join(' '), { ...options, shell: true, windowsHide: true })
52
+ : spawn(choice.command, args, { ...options, windowsHide: true });
53
+ }
54
+
55
+ if (Number(process.versions.node.split('.')[0]) < 22) {
36
56
  log(`Node.js 22.22 or newer is required (this is ${process.versions.node}).`);
37
57
  process.exit(1);
38
58
  }
39
59
  const choice = pick();
40
60
  log(`starting ${choice.what}`);
41
- // Through a shell (needed for .cmd shims on Windows) the command goes in as one string of fixed words.
42
- const child = choice.shell
43
- ? spawn([choice.command, ...choice.args].join(' '), { stdio: 'inherit', shell: true, windowsHide: true })
44
- : spawn(choice.command, choice.args, { stdio: 'inherit', windowsHide: true });
61
+ const child = run(choice, [], { stdio: 'inherit' });
45
62
  child.on('error', err => {
46
63
  log(`could not start the server: ${err.message}. Install it with: npm install -g clast-ai`);
47
64
  process.exit(1);
48
65
  });
49
66
  child.on('exit', (code, signal) => process.exit(code ?? (signal ? 1 : 0)));
50
67
  for (const sig of ['SIGINT', 'SIGTERM']) process.on(sig, () => child.kill(sig));
68
+
69
+ // Clean up after older installs, without holding up or disturbing the server (no shared stdio).
70
+ if (process.env.CLAST_NO_MIGRATE !== '1') {
71
+ try {
72
+ const cleanup = run(choice, ['migrate', '--apply', '--auto'], { stdio: 'ignore', detached: !windows });
73
+ cleanup.on('error', () => {});
74
+ cleanup.unref();
75
+ } catch {
76
+ // Never let the cleanup stop the server.
77
+ }
78
+ }
package/src/cli.ts CHANGED
@@ -35,6 +35,8 @@ usage: clast-ai [command] [args] [--root <dir>]
35
35
  unused [path] dead code [--kind k] [--lang l] [--limit n] [--no-exported]
36
36
  stats [what] [name] exact counts: inventory | symbols | subtypes | calls | text | imports | endpoints | database
37
37
  [--kind k] [--on receiver] [--path p] [--lang l] [--group-by g] [--depth n] [--limit n] [--tests]
38
+ migrate [--apply] find (and with --apply remove) what older installs left behind: duplicate
39
+ MCP registrations next to the plugin, the v0.1 index file
38
40
  parse <file> [--json] debug: show what the extractor produces for a file
39
41
  ast <file> debug: dump the tree-sitter syntax tree
40
42
 
@@ -63,7 +65,7 @@ interface Parsed {
63
65
  }
64
66
 
65
67
  const BOOLEAN_FLAGS = new Set([
66
- 'force', 'json', 'regex', 'no-body', 'no-scan', 'no-tests', 'tests', 'uncertain', 'help', 'version', 'all', 'no-exported',
68
+ 'force', 'json', 'regex', 'no-body', 'no-scan', 'no-tests', 'tests', 'uncertain', 'help', 'version', 'all', 'no-exported', 'apply', 'auto',
67
69
  ]);
68
70
 
69
71
  function parseArgs(argv: string[]): Parsed {
@@ -105,6 +107,13 @@ async function main(): Promise<void> {
105
107
  return;
106
108
  }
107
109
 
110
+ if (cmd === 'migrate') {
111
+ const { migrate } = await import('./migrate.js');
112
+ const out = await migrate({ apply: flags.has('apply'), auto: flags.has('auto'), force: flags.has('force'), cwd: str('root') });
113
+ if (out) console.log(out);
114
+ return;
115
+ }
116
+
108
117
  if (cmd === 'parse' || cmd === 'ast') {
109
118
  const file = positional[0];
110
119
  if (!file) throw new Error(`usage: clast-ai ${cmd} <file>`);
package/src/migrate.ts ADDED
@@ -0,0 +1,225 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join, resolve } from 'node:path';
5
+ import { VERSION } from './version.js';
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // clast-ai migrate: remove what older installs left behind
9
+ // ---------------------------------------------------------------------------
10
+ //
11
+ // Before the plugin, clast was registered by hand (`claude mcp add`) or by the old VS Code extension
12
+ // (`.claude/settings.local.json`). With the plugin installed those registrations start a second copy
13
+ // of the server and list every tool twice. This finds them, and the v0.1 index file, and removes them.
14
+
15
+ export interface MigrateOptions {
16
+ /** Make the changes. Default: only report. */
17
+ apply?: boolean;
18
+ /** Run from the plugin at session start: once per version, silent, only when the plugin is installed. */
19
+ auto?: boolean;
20
+ /** Remove hand-made registrations even when the plugin is not installed. */
21
+ force?: boolean;
22
+ home?: string;
23
+ cwd?: string;
24
+ /** Replaces `claude mcp remove` (tests). Returns true on success. */
25
+ remove?: (name: string, scope: 'user' | 'local', cwd: string) => boolean;
26
+ }
27
+
28
+ export type Action =
29
+ | { kind: 'mcp'; scope: 'user' | 'local'; name: string; dir: string; command: string }
30
+ | { kind: 'settings'; file: string; name: string }
31
+ | { kind: 'index'; files: string[] }
32
+ | { kind: 'shared'; file: string; name: string };
33
+
34
+ interface ServerEntry {
35
+ command?: string;
36
+ args?: unknown[];
37
+ }
38
+
39
+ /** A registration of this server: by name, by the `clast-ai` binary, or by a path to its cli.js. */
40
+ function isClast(_name: string, entry: ServerEntry | undefined): boolean {
41
+ if (!entry || typeof entry !== 'object') return false;
42
+ const command = String(entry.command ?? '');
43
+ const args = Array.isArray(entry.args) ? entry.args.map(String) : [];
44
+ if (/(^|[\\/])clast-ai(\.cmd|\.exe)?$/i.test(command)) return true;
45
+ // dist/cli.js, and dist/server/index.js as the 0.1 README registered a build from source.
46
+ if (args.some(a => /clast[^\\/]*[\\/]dist[\\/](cli|server[\\/]index)\.js$/i.test(a))) return true;
47
+ // `npx clast-ai`, `npx -y clast-ai@0.1`
48
+ if (/(^|[\\/])npx(\.cmd)?$/i.test(command) && args.some(a => /^clast-ai(@|$)/.test(a))) return true;
49
+ return false;
50
+ }
51
+
52
+ function readJson(path: string): Record<string, unknown> | null {
53
+ try {
54
+ return JSON.parse(readFileSync(path, 'utf8')) as Record<string, unknown>;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ function describe(entry: ServerEntry): string {
61
+ return [entry.command ?? '', ...(Array.isArray(entry.args) ? entry.args.map(String) : [])].join(' ').trim();
62
+ }
63
+
64
+ /** Is the clast plugin installed for this user? */
65
+ /**
66
+ * Where Claude Code keeps its configuration: `~/.claude.json` and `~/.claude/`, or both inside
67
+ * CLAUDE_CONFIG_DIR when that is set.
68
+ */
69
+ function claudePaths(home: string): { config: string; plugins: string } {
70
+ const dir = process.env.CLAUDE_CONFIG_DIR;
71
+ return dir
72
+ ? { config: join(dir, '.claude.json'), plugins: join(dir, 'plugins') }
73
+ : { config: join(home, '.claude.json'), plugins: join(home, '.claude', 'plugins') };
74
+ }
75
+
76
+ export function pluginInstalled(home: string): boolean {
77
+ const installed = readJson(join(claudePaths(home).plugins, 'installed_plugins.json'));
78
+ const plugins = (installed?.plugins ?? {}) as Record<string, unknown>;
79
+ return Object.keys(plugins).some(id => /^clast@/.test(id));
80
+ }
81
+
82
+ /** Everything an older install left behind, without changing anything. */
83
+ export function planMigration(home: string, cwd: string): Action[] {
84
+ const actions: Action[] = [];
85
+ const config = readJson(claudePaths(home).config);
86
+ const servers = (config?.mcpServers ?? {}) as Record<string, ServerEntry>;
87
+ for (const [name, entry] of Object.entries(servers)) {
88
+ if (isClast(name, entry)) actions.push({ kind: 'mcp', scope: 'user', name, dir: cwd, command: describe(entry) });
89
+ }
90
+ const projects = (config?.projects ?? {}) as Record<string, { mcpServers?: Record<string, ServerEntry> }>;
91
+ for (const [dir, project] of Object.entries(projects)) {
92
+ for (const [name, entry] of Object.entries(project?.mcpServers ?? {})) {
93
+ if (isClast(name, entry)) actions.push({ kind: 'mcp', scope: 'local', name, dir, command: describe(entry) });
94
+ }
95
+ }
96
+ // Written by the old VS Code extension.
97
+ const settingsFile = join(cwd, '.claude', 'settings.local.json');
98
+ const settings = readJson(settingsFile);
99
+ for (const [name, entry] of Object.entries((settings?.mcpServers ?? {}) as Record<string, ServerEntry>)) {
100
+ if (isClast(name, entry)) actions.push({ kind: 'settings', file: settingsFile, name });
101
+ }
102
+ // The v0.1 index. v0.2 keeps its own file (.clast/index.db) and never reads this one.
103
+ const old = ['clast.db', 'clast.db-wal', 'clast.db-shm'].map(f => join(cwd, '.clast', f)).filter(f => existsSync(f));
104
+ if (old.length) actions.push({ kind: 'index', files: old });
105
+ // A team's shared file is theirs to change.
106
+ const sharedFile = join(cwd, '.mcp.json');
107
+ const shared = readJson(sharedFile);
108
+ for (const [name, entry] of Object.entries((shared?.mcpServers ?? {}) as Record<string, ServerEntry>)) {
109
+ if (isClast(name, entry)) actions.push({ kind: 'shared', file: sharedFile, name });
110
+ }
111
+ return actions;
112
+ }
113
+
114
+ function claudeRemove(name: string, scope: 'user' | 'local', cwd: string): boolean {
115
+ const windows = process.platform === 'win32';
116
+ // Fixed words plus a server name restricted to safe characters: nothing to escape.
117
+ if (!/^[\w.-]+$/.test(name)) return false;
118
+ const result = windows
119
+ ? spawnSync(`claude mcp remove ${name} -s ${scope}`, { cwd, shell: true, stdio: 'ignore', windowsHide: true, timeout: 30_000 })
120
+ : spawnSync('claude', ['mcp', 'remove', name, '-s', scope], { cwd, stdio: 'ignore', timeout: 30_000 });
121
+ return result.status === 0;
122
+ }
123
+
124
+ function line(a: Action): string {
125
+ switch (a.kind) {
126
+ case 'mcp':
127
+ return a.scope === 'user'
128
+ ? `server "${a.name}" registered for all projects (${a.command})`
129
+ : `server "${a.name}" registered for ${a.dir} (${a.command})`;
130
+ case 'settings':
131
+ return `server "${a.name}" in ${a.file} (written by the old VS Code extension)`;
132
+ case 'index':
133
+ return `v0.1 index: ${a.files.join(', ')}`;
134
+ case 'shared':
135
+ return `server "${a.name}" in ${a.file} (shared with your team: not changed; remove it there if everyone uses the plugin)`;
136
+ }
137
+ }
138
+
139
+ export async function migrate(opts: MigrateOptions = {}): Promise<string> {
140
+ const home = opts.home ?? homedir();
141
+ const cwd = resolve(opts.cwd ?? process.env.CLAST_PROJECT_DIR ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd());
142
+ const stateDir = process.env.CLAUDE_PLUGIN_DATA || join(home, '.clast-ai');
143
+ const marker = join(stateDir, 'migrated.json');
144
+ const plugin = pluginInstalled(home);
145
+
146
+ if (opts.auto) {
147
+ // Only the plugin starts this, but be sure: without it the registrations are the only install there is.
148
+ if (!plugin) return '';
149
+ const done = readJson(marker);
150
+ const fresh = done?.version !== VERSION;
151
+ // The registrations are checked once per version; a project's old index whenever it is seen.
152
+ const plan = planMigration(home, cwd).filter(a => a.kind === 'index' || (fresh && a.kind !== 'shared'));
153
+ const report = plan.length ? apply(plan, opts) : [];
154
+ try {
155
+ mkdirSync(stateDir, { recursive: true });
156
+ if (fresh) writeFileSync(marker, JSON.stringify({ version: VERSION, at: new Date().toISOString() }) + '\n');
157
+ if (report.length) {
158
+ appendFileSync(join(stateDir, 'migrate.log'), `${new Date().toISOString()} clast ${VERSION}\n${report.map(r => ' ' + r).join('\n')}\n`);
159
+ }
160
+ } catch {
161
+ // A read-only home directory must not stop the server.
162
+ }
163
+ return report.join('\n');
164
+ }
165
+
166
+ const plan = planMigration(home, cwd);
167
+ const out: string[] = [];
168
+ const removable = plan.filter(a => a.kind !== 'shared');
169
+ const blocked = !plugin && !opts.force;
170
+ if (plan.length === 0) {
171
+ out.push('nothing to migrate: no older clast registration or index found.');
172
+ } else if (!opts.apply) {
173
+ out.push(`found ${plan.length} leftover${plan.length === 1 ? '' : 's'} of an older clast install:`);
174
+ for (const a of plan) out.push(` - ${line(a)}`);
175
+ if (removable.length) {
176
+ out.push(
177
+ blocked
178
+ ? 'The clast plugin is not installed, so the registrations above are your only install. Install the plugin ' +
179
+ '(/plugin marketplace add xls/clast, /plugin install clast@clast) and run this again, or pass --force.'
180
+ : 'Run `clast-ai migrate --apply` to remove them (the plugin provides the server).'
181
+ );
182
+ }
183
+ } else {
184
+ const todo = blocked ? removable.filter(a => a.kind === 'index') : removable;
185
+ out.push(...apply(todo, opts));
186
+ for (const a of plan.filter(p => p.kind === 'shared')) out.push(`left alone: ${line(a)}`);
187
+ if (blocked && removable.some(a => a.kind !== 'index')) {
188
+ out.push('registrations kept: the clast plugin is not installed (pass --force to remove them anyway).');
189
+ }
190
+ if (todo.some(a => a.kind === 'mcp' || a.kind === 'settings')) out.push('Restart Claude Code to apply.');
191
+ }
192
+ if (!plugin) out.push('plugin: not installed.');
193
+ return out.join('\n');
194
+ }
195
+
196
+ function apply(plan: Action[], opts: MigrateOptions): string[] {
197
+ const remove = opts.remove ?? claudeRemove;
198
+ const report: string[] = [];
199
+ for (const a of plan) {
200
+ try {
201
+ if (a.kind === 'mcp') {
202
+ if (a.scope === 'local' && !existsSync(a.dir)) {
203
+ report.push(`skipped (directory no longer exists): ${line(a)}`);
204
+ continue;
205
+ }
206
+ report.push(`${remove(a.name, a.scope, a.dir) ? 'removed' : 'could not remove (is the claude CLI on PATH?)'}: ${line(a)}`);
207
+ } else if (a.kind === 'settings') {
208
+ const settings = readJson(a.file);
209
+ const servers = settings?.mcpServers as Record<string, unknown> | undefined;
210
+ if (settings && servers && a.name in servers) {
211
+ delete servers[a.name];
212
+ if (Object.keys(servers).length === 0) delete settings.mcpServers;
213
+ writeFileSync(a.file, JSON.stringify(settings, null, 2) + '\n');
214
+ report.push(`removed: ${line(a)}`);
215
+ }
216
+ } else if (a.kind === 'index') {
217
+ for (const f of a.files) rmSync(f, { force: true });
218
+ report.push(`deleted: ${line(a)}`);
219
+ }
220
+ } catch (err) {
221
+ report.push(`failed: ${line(a)}: ${err instanceof Error ? err.message : err}`);
222
+ }
223
+ }
224
+ return report;
225
+ }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Package version (keep in sync with package.json; checked by a test). */
2
- export const VERSION = '0.2.0';
2
+ export const VERSION = '0.2.2';
package/tsconfig.json CHANGED
@@ -20,4 +20,4 @@
20
20
  },
21
21
  "include": ["src/**/*.ts"],
22
22
  "exclude": ["node_modules", "dist", "test"]
23
- }
23
+ }