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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +64 -6
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/migrate.d.ts +34 -0
- package/dist/migrate.js +205 -0
- package/dist/migrate.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/plugin/server.mjs +40 -12
- package/src/cli.ts +10 -1
- package/src/migrate.ts +225 -0
- package/src/version.ts +1 -1
- package/tsconfig.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clast",
|
|
3
|
-
"version": "0.2.
|
|
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`
|
|
55
|
-
`npx clast-ai
|
|
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
|
-
-
|
|
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
|
|
472
|
-
|
|
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":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -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>;
|
package/dist/migrate.js
ADDED
|
@@ -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.
|
|
2
|
+
export declare const VERSION = "0.2.2";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clast-ai",
|
|
3
|
-
"version": "0.2.
|
|
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
|
|
6
|
-
// 3. `npx clast-ai@<
|
|
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
|
|
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
|
-
|
|
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
|
|
31
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
-
|
|
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.
|
|
2
|
+
export const VERSION = '0.2.2';
|
package/tsconfig.json
CHANGED