mantisai-cli 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -99
- package/bin/mantis.js +406 -23
- package/lib/constants.js +13 -0
- package/lib/container.js +63 -0
- package/lib/impl/claude-skills-service.js +13 -0
- package/lib/impl/fast-glob-codebase-indexer.js +114 -0
- package/lib/impl/file-config-store.js +38 -0
- package/lib/impl/fs-csv-reader.js +12 -0
- package/lib/impl/http-mantis-client.js +108 -0
- package/lib/impl/inquirer-ui-service.js +73 -0
- package/lib/impl/mcp-client-service.js +64 -0
- package/lib/impl/opencode-skills-service.js +17 -0
- package/lib/impl/space-repository.js +72 -0
- package/lib/interfaces/codebase-indexer.js +5 -0
- package/lib/interfaces/config-store.js +11 -0
- package/lib/interfaces/csv-reader.js +5 -0
- package/lib/interfaces/index.js +7 -0
- package/lib/interfaces/mantis-client.js +13 -0
- package/lib/interfaces/mcp-client.js +6 -0
- package/lib/interfaces/space-repository.js +13 -0
- package/lib/interfaces/ui.js +13 -0
- package/lib/services/context-service.js +22 -0
- package/lib/services/map-service.js +114 -0
- package/lib/services/query-service.js +50 -0
- package/lib/services/selection-service.js +174 -0
- package/lib/services/setup-service.js +81 -0
- package/lib/services/tool-service.js +26 -0
- package/lib/types.js +30 -0
- package/lib/utils/cli-args.js +29 -0
- package/lib/utils/package-root.js +7 -0
- package/lib/utils/skills-sync.js +43 -0
- package/lib/{space-id.js → utils/space-id.js} +0 -1
- package/lib/utils/threads.js +12 -0
- package/lib/utils/tool-args.js +38 -0
- package/lib/utils/url.js +33 -0
- package/package.json +4 -7
- package/skills/codebase/SKILL.md +8 -6
- package/skills/connect/SKILL.md +10 -26
- package/skills/createmap/SKILL.md +5 -3
- package/skills/mantis/SKILL.md +48 -32
- package/skills/select/SKILL.md +12 -9
- package/skills/space/SKILL.md +10 -47
- package/skills/status/SKILL.md +4 -9
- package/skills/thread/SKILL.md +15 -27
- package/.claude-plugin/marketplace.json +0 -14
- package/.claude-plugin/plugin.json +0 -18
- package/.mcp.json +0 -11
- package/bin/mantis-list-spaces.js +0 -32
- package/bin/mantis-list-threads.js +0 -32
- package/bin/mantis-mcp-headers.js +0 -9
- package/bin/mantis-pick-space.js +0 -5
- package/bin/mantis-pick-thread.js +0 -5
- package/bin/mantis-resolve-space.js +0 -25
- package/bin/mantis-select.js +0 -7
- package/bin/mantis-set-space.js +0 -31
- package/bin/mantis-set-thread.js +0 -34
- package/bin/mantis-setup.js +0 -59
- package/bin/mantis-status.js +0 -15
- package/lib/api.js +0 -100
- package/lib/claude-plugin.js +0 -150
- package/lib/codebase-csv.js +0 -115
- package/lib/config.js +0 -65
- package/lib/csv.js +0 -10
- package/lib/fetch.js +0 -36
- package/lib/list-cli.js +0 -55
- package/lib/map-create.js +0 -148
- package/lib/mcp-config.js +0 -50
- package/lib/picker.js +0 -150
- package/lib/spaces.js +0 -48
- package/lib/ui.js +0 -73
- /package/lib/{fields.js → utils/fields.js} +0 -0
package/README.md
CHANGED
|
@@ -1,120 +1,47 @@
|
|
|
1
1
|
# mantisai-cli
|
|
2
2
|
|
|
3
|
-
Mantis developer CLI —
|
|
3
|
+
Mantis developer CLI — spaces, maps, MCP tools for AI agents, and editor skill sync.
|
|
4
4
|
|
|
5
|
-
> **Naming
|
|
5
|
+
> **Naming:** repo [`KellisLab/mantis-cli`](https://github.com/KellisLab/mantis-cli), npm package **`mantisai-cli`**, binary **`mantis`**.
|
|
6
|
+
|
|
7
|
+
Full docs (VitePress):
|
|
8
|
+
|
|
9
|
+
- [Overview](https://mantis.csail.mit.edu/docs/mantis-cli/)
|
|
10
|
+
- [Install](https://mantis.csail.mit.edu/docs/mantis-cli/install)
|
|
11
|
+
- [Claude Code](https://mantis.csail.mit.edu/docs/mantis-cli/claude-code)
|
|
12
|
+
- [OpenCode](https://mantis.csail.mit.edu/docs/mantis-cli/opencode)
|
|
13
|
+
|
|
14
|
+
Source: `Mantis/docs/mantis-cli/`
|
|
6
15
|
|
|
7
16
|
## Requirements
|
|
8
17
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- A Mantis **Developer API key** (`live_…`) from https://mantis.csail.mit.edu/developer/#keys
|
|
12
|
-
- (Optional, for plugin features) [Claude Code](https://code.claude.com) (`claude` on your PATH)
|
|
18
|
+
- Node.js 18+
|
|
19
|
+
- Mantis API + Developer key from https://mantis.csail.mit.edu/developer/#keys
|
|
13
20
|
|
|
14
21
|
## Install
|
|
15
22
|
|
|
16
23
|
```bash
|
|
17
24
|
npm install -g mantisai-cli
|
|
18
25
|
mantis setup
|
|
26
|
+
mantis setup claude # optional: Claude Code skills
|
|
27
|
+
mantis use get_space_context
|
|
19
28
|
```
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
Config: `~/.mantis/config.json`
|
|
22
31
|
|
|
23
32
|
## Commands
|
|
24
33
|
|
|
25
34
|
| Command | Description |
|
|
26
|
-
|
|
27
|
-
| `mantis setup` |
|
|
28
|
-
| `mantis status` |
|
|
29
|
-
| `mantis select [space\|thread\|both]` | Switch
|
|
30
|
-
| `mantis
|
|
31
|
-
| `mantis
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
# Create a new private space and load a CSV as a map
|
|
39
|
-
mantis create map ./data.csv \
|
|
40
|
-
--space-mode new --space-name "Sales" --private \
|
|
41
|
-
--map-name "Q4 Pipeline" \
|
|
42
|
-
--title-column name --semantic-column description --numeric-column revenue
|
|
43
|
-
|
|
44
|
-
# Add a map to an existing space
|
|
45
|
-
mantis create map ./more-data.csv \
|
|
46
|
-
--space-mode existing --space-id <uuid> \
|
|
47
|
-
--map-name "Cohort 2"
|
|
48
|
-
|
|
49
|
-
# Index your repo into Mantis
|
|
50
|
-
mantis create codebase . --create-map --space-mode new --space-name "Repo Index" --private
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Claude Code integration
|
|
54
|
-
|
|
55
|
-
After `mantis setup`:
|
|
56
|
-
|
|
57
|
-
1. Open Claude Code (restart if it was already running).
|
|
58
|
-
2. `/plugin` → enable **mantis @ mantis-plugins** (user scope) if needed.
|
|
59
|
-
3. `/reload-plugins`
|
|
60
|
-
4. Confirm with `/mantis:status`.
|
|
61
|
-
|
|
62
|
-
### Slash commands
|
|
63
|
-
|
|
64
|
-
| Command | Description |
|
|
65
|
-
|---------|-------------|
|
|
66
|
-
| `/mantis:connect` | Run setup / reconnect |
|
|
67
|
-
| `/mantis:space` | Change space (search or paste a `/space/{uuid}` link) |
|
|
68
|
-
| `/mantis:thread` | Change thread (space state) |
|
|
69
|
-
| `/mantis:status` | Show current space, thread, and MCP URL |
|
|
70
|
-
| `/mantis:select` | Quick space/thread selection |
|
|
71
|
-
|
|
72
|
-
After changing **thread**, run `/reload-plugins` so MCP picks up the new `X-Space-State-ID` header.
|
|
73
|
-
|
|
74
|
-
### Paste a space link
|
|
75
|
-
|
|
76
|
-
In `mantis setup` or `/mantis:space`, paste a URL such as:
|
|
77
|
-
|
|
78
|
-
`https://mantis.csail.mit.edu/space/1e1ed055-c869-4b78-b41f-4216a44049d4/`
|
|
79
|
-
|
|
80
|
-
Use the same Mantis API base URL as the space you are targeting (local vs production).
|
|
81
|
-
|
|
82
|
-
## Update
|
|
83
|
-
|
|
84
|
-
**CLI**:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
npm install -g mantisai-cli@latest
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**Plugin (slash commands, MCP, skills)** — in Claude Code:
|
|
91
|
-
|
|
92
|
-
```text
|
|
93
|
-
/plugin marketplace update mantis-plugins
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
Then update **mantis@mantis-plugins** and `/reload-plugins`.
|
|
97
|
-
|
|
98
|
-
## Manual plugin install
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
claude plugin marketplace add KellisLab/mantis-cli
|
|
102
|
-
claude plugin install mantis@mantis-plugins --scope user
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Enable in `/plugin`, then `/reload-plugins`.
|
|
106
|
-
|
|
107
|
-
## Migrating from `mantis-claude-code`
|
|
108
|
-
|
|
109
|
-
If you previously installed the package as `mantis-claude-code`, migrate with:
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
npm uninstall -g mantis-claude-code
|
|
113
|
-
npm install -g mantisai-cli
|
|
114
|
-
mantis setup
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Your local config at `~/.mantis/claude-code/config.json` is preserved.
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `mantis setup [claude\|opencode]` | API + space/thread, or sync editor skills |
|
|
37
|
+
| `mantis status` | Current config |
|
|
38
|
+
| `mantis select [space\|thread\|both]` | Switch space/thread |
|
|
39
|
+
| `mantis spaces list\|resolve\|set` | Scriptable space ops (JSON) |
|
|
40
|
+
| `mantis threads list\|new\|set` | Scriptable thread ops (JSON) |
|
|
41
|
+
| `mantis tools` | List MCP tools |
|
|
42
|
+
| `mantis use <tool>` | Call an MCP tool (JSON output) |
|
|
43
|
+
| `mantis create map <file>` | Map from CSV/XLSX |
|
|
44
|
+
| `mantis create codebase [root]` | Index repo; optional `--create-map` |
|
|
118
45
|
|
|
119
46
|
## npm
|
|
120
47
|
|
package/bin/mantis.js
CHANGED
|
@@ -1,111 +1,494 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
|
|
2
3
|
import path from 'node:path';
|
|
4
|
+
|
|
3
5
|
import { Command } from 'commander';
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import {
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
import { getContainer } from '../lib/container.js';
|
|
10
|
+
|
|
11
|
+
import { parseUseCommand } from '../lib/utils/tool-args.js';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const c = getContainer();
|
|
16
|
+
|
|
17
|
+
const { map, codebaseIndexer, tools, ui, setup, selection, context, query } = c;
|
|
8
18
|
|
|
9
19
|
const program = new Command();
|
|
10
20
|
|
|
21
|
+
|
|
22
|
+
|
|
11
23
|
function defaultCodebaseOut(root) {
|
|
24
|
+
|
|
12
25
|
const base = path.basename(path.resolve(root || process.cwd())) || 'codebase';
|
|
26
|
+
|
|
13
27
|
return path.resolve(process.cwd(), `${base}-codebase.csv`);
|
|
28
|
+
|
|
14
29
|
}
|
|
15
30
|
|
|
31
|
+
|
|
32
|
+
|
|
16
33
|
function addMapOptions(cmd) {
|
|
34
|
+
|
|
17
35
|
return cmd
|
|
36
|
+
|
|
18
37
|
.option('--space-mode <mode>', 'new or existing')
|
|
38
|
+
|
|
19
39
|
.option('--space-id <uuid>', 'existing Mantis space id')
|
|
40
|
+
|
|
20
41
|
.option('--space-name <name>', 'new space name or display name for existing space')
|
|
42
|
+
|
|
21
43
|
.option('--space-search <query>', 'search text for choosing an existing space')
|
|
44
|
+
|
|
22
45
|
.option('--public', 'make a new space public')
|
|
46
|
+
|
|
23
47
|
.option('--private', 'make a new space private')
|
|
48
|
+
|
|
24
49
|
.option('--map-name <name>', 'map name')
|
|
50
|
+
|
|
25
51
|
.option('--title-column <columns>', 'comma-separated title column names')
|
|
52
|
+
|
|
26
53
|
.option('--semantic-column <columns>', 'comma-separated semantic column names')
|
|
54
|
+
|
|
27
55
|
.option('--numeric-column <columns>', 'comma-separated numeric column names')
|
|
56
|
+
|
|
28
57
|
.option('--categoric-column <columns>', 'comma-separated categorical column names')
|
|
58
|
+
|
|
29
59
|
.option('--date-column <columns>', 'comma-separated date column names')
|
|
60
|
+
|
|
30
61
|
.option('--links-column <columns>', 'comma-separated link column names')
|
|
62
|
+
|
|
31
63
|
.option('--delete-column <columns>', 'comma-separated ignored column names')
|
|
64
|
+
|
|
32
65
|
.option('--data-types <json>', 'raw data_types JSON array')
|
|
33
|
-
|
|
34
|
-
.option('--
|
|
66
|
+
|
|
67
|
+
.option('--activate', 'set created space/thread as active context')
|
|
68
|
+
|
|
69
|
+
.option('--no-activate', 'do not update active space/thread')
|
|
70
|
+
|
|
35
71
|
.option('--thread-name <name>', 'thread name when activating');
|
|
72
|
+
|
|
36
73
|
}
|
|
37
74
|
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
function addListOptions(cmd) {
|
|
78
|
+
|
|
79
|
+
return cmd
|
|
80
|
+
|
|
81
|
+
.option('--filter <query>', 'search filter')
|
|
82
|
+
|
|
83
|
+
.option('--offset <n>', 'pagination offset', (v) => parseInt(v, 10) || 0)
|
|
84
|
+
|
|
85
|
+
.option('--limit <n>', 'page size', (v) => parseInt(v, 10) || 4);
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async function listTools() {
|
|
92
|
+
|
|
93
|
+
const data = await tools.listTools();
|
|
94
|
+
|
|
95
|
+
console.log(JSON.stringify(data, null, 2));
|
|
96
|
+
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
38
101
|
program
|
|
102
|
+
|
|
39
103
|
.name('mantis')
|
|
40
|
-
|
|
41
|
-
.
|
|
104
|
+
|
|
105
|
+
.description('Mantis CLI — spaces, maps, and MCP tools for AI agents')
|
|
106
|
+
|
|
107
|
+
.version('3.0.0');
|
|
108
|
+
|
|
109
|
+
|
|
42
110
|
|
|
43
111
|
program
|
|
44
|
-
|
|
45
|
-
.
|
|
46
|
-
|
|
112
|
+
|
|
113
|
+
.command('setup [provider]')
|
|
114
|
+
|
|
115
|
+
.description('Configure Mantis, or install skills for claude/opencode')
|
|
116
|
+
|
|
117
|
+
.action(async (provider) => {
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
|
|
121
|
+
if (!provider) return setup.run();
|
|
122
|
+
|
|
123
|
+
setup.runProvider(provider);
|
|
124
|
+
|
|
125
|
+
} catch (e) {
|
|
126
|
+
|
|
127
|
+
ui.die(e.message || String(e));
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
|
|
47
134
|
|
|
48
135
|
program
|
|
136
|
+
|
|
49
137
|
.command('status')
|
|
50
|
-
|
|
51
|
-
.
|
|
138
|
+
|
|
139
|
+
.description('Show current Mantis config')
|
|
140
|
+
|
|
141
|
+
.action(() => {
|
|
142
|
+
|
|
143
|
+
const s = context.status();
|
|
144
|
+
|
|
145
|
+
console.log('Mantis — status\n');
|
|
146
|
+
|
|
147
|
+
console.log(`Config: ${s.configPath}`);
|
|
148
|
+
|
|
149
|
+
console.log(`API: ${s.apiBaseUrl}`);
|
|
150
|
+
|
|
151
|
+
console.log(`MCP: ${s.mcpUrl}`);
|
|
152
|
+
|
|
153
|
+
console.log(`API key: ${s.apiKeyHint}`);
|
|
154
|
+
|
|
155
|
+
console.log(`Space: ${s.spaceName} (${s.spaceId})`);
|
|
156
|
+
|
|
157
|
+
console.log(`Thread: ${s.threadName} (${s.threadId})`);
|
|
158
|
+
|
|
159
|
+
if (!s.hasThread) {
|
|
160
|
+
|
|
161
|
+
console.log('\nNo thread selected. Run: mantis select thread');
|
|
162
|
+
|
|
163
|
+
process.exit(1);
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
|
|
52
170
|
|
|
53
171
|
program
|
|
172
|
+
|
|
54
173
|
.command('select')
|
|
55
|
-
|
|
174
|
+
|
|
175
|
+
.description('Select active space and thread')
|
|
176
|
+
|
|
56
177
|
.argument('[target]', 'space, thread, or both', 'both')
|
|
178
|
+
|
|
57
179
|
.action(async (target) => {
|
|
58
|
-
|
|
59
|
-
if (target === '
|
|
60
|
-
|
|
180
|
+
|
|
181
|
+
if (target === 'space') return selection.pickSpace();
|
|
182
|
+
|
|
183
|
+
if (target === 'thread') return selection.pickThread();
|
|
184
|
+
|
|
185
|
+
ui.banner('Mantis — switch space / thread');
|
|
186
|
+
|
|
187
|
+
await selection.pickSpace();
|
|
188
|
+
|
|
189
|
+
await selection.pickThread();
|
|
190
|
+
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
const spaces = program.command('spaces').description('List, resolve, or set spaces');
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
addListOptions(spaces.command('list').description('List spaces (JSON)')).action(async (opts) => {
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
|
|
203
|
+
const data = await query.spacesForPrompt(opts.filter || '', { limit: opts.limit, offset: opts.offset });
|
|
204
|
+
|
|
205
|
+
console.log(JSON.stringify(data));
|
|
206
|
+
|
|
207
|
+
} catch (e) {
|
|
208
|
+
|
|
209
|
+
console.error(JSON.stringify({ error: e.message }));
|
|
210
|
+
|
|
211
|
+
process.exit(1);
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
spaces
|
|
220
|
+
|
|
221
|
+
.command('resolve')
|
|
222
|
+
|
|
223
|
+
.description('Resolve a space link or UUID (JSON)')
|
|
224
|
+
|
|
225
|
+
.argument('<query>', 'space link or UUID')
|
|
226
|
+
|
|
227
|
+
.action(async (queryText) => {
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
|
|
231
|
+
const data = await selection.resolveSpace(queryText);
|
|
232
|
+
|
|
233
|
+
console.log(JSON.stringify(data));
|
|
234
|
+
|
|
235
|
+
} catch (e) {
|
|
236
|
+
|
|
237
|
+
console.error(JSON.stringify({ error: e.message }));
|
|
238
|
+
|
|
239
|
+
process.exit(1);
|
|
240
|
+
|
|
241
|
+
}
|
|
242
|
+
|
|
61
243
|
});
|
|
62
244
|
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
spaces
|
|
248
|
+
|
|
249
|
+
.command('set')
|
|
250
|
+
|
|
251
|
+
.description('Set active space by UUID')
|
|
252
|
+
|
|
253
|
+
.argument('<uuid>', 'space UUID')
|
|
254
|
+
|
|
255
|
+
.argument('[name]', 'display name')
|
|
256
|
+
|
|
257
|
+
.action((uuid, name) => console.log(JSON.stringify(selection.setSpace(uuid, name || ''))));
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
const threads = program.command('threads').description('List or set threads in the active space');
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
addListOptions(threads.command('list').description('List threads (JSON)')).action(async (opts) => {
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
|
|
269
|
+
const data = await query.threadsForPrompt(opts.filter || '', { limit: opts.limit, offset: opts.offset });
|
|
270
|
+
|
|
271
|
+
console.log(JSON.stringify(data));
|
|
272
|
+
|
|
273
|
+
} catch (e) {
|
|
274
|
+
|
|
275
|
+
console.error(JSON.stringify({ error: e.message }));
|
|
276
|
+
|
|
277
|
+
process.exit(1);
|
|
278
|
+
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
threads
|
|
286
|
+
|
|
287
|
+
.command('new')
|
|
288
|
+
|
|
289
|
+
.description('Create and activate a new thread')
|
|
290
|
+
|
|
291
|
+
.argument('[name]', 'thread name')
|
|
292
|
+
|
|
293
|
+
.action(async (name) => {
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
|
|
297
|
+
const result = await selection.setThread('--new', name);
|
|
298
|
+
|
|
299
|
+
console.log(JSON.stringify(result));
|
|
300
|
+
|
|
301
|
+
} catch (e) {
|
|
302
|
+
|
|
303
|
+
console.error(e.message || String(e));
|
|
304
|
+
|
|
305
|
+
process.exit(1);
|
|
306
|
+
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
threads
|
|
314
|
+
|
|
315
|
+
.command('set')
|
|
316
|
+
|
|
317
|
+
.description('Set active thread by UUID')
|
|
318
|
+
|
|
319
|
+
.argument('<uuid>', 'thread UUID')
|
|
320
|
+
|
|
321
|
+
.argument('[name]', 'display name')
|
|
322
|
+
|
|
323
|
+
.action(async (uuid, name) => {
|
|
324
|
+
|
|
325
|
+
try {
|
|
326
|
+
|
|
327
|
+
const result = await selection.setThread(uuid, name);
|
|
328
|
+
|
|
329
|
+
console.log(JSON.stringify(result));
|
|
330
|
+
|
|
331
|
+
} catch (e) {
|
|
332
|
+
|
|
333
|
+
console.error(e.message || String(e));
|
|
334
|
+
|
|
335
|
+
process.exit(1);
|
|
336
|
+
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
const toolsCmd = program.command('tools').description('MCP tools available via mantis use');
|
|
344
|
+
|
|
345
|
+
toolsCmd.command('list', { isDefault: true }).description('List tools (JSON)').action(async () => {
|
|
346
|
+
|
|
347
|
+
try {
|
|
348
|
+
|
|
349
|
+
await listTools();
|
|
350
|
+
|
|
351
|
+
} catch (e) {
|
|
352
|
+
|
|
353
|
+
console.error(JSON.stringify({ error: e.message }));
|
|
354
|
+
|
|
355
|
+
process.exit(1);
|
|
356
|
+
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
program
|
|
364
|
+
|
|
365
|
+
.command('use <tool>')
|
|
366
|
+
|
|
367
|
+
.description('Call a Mantis MCP tool (prints JSON)')
|
|
368
|
+
|
|
369
|
+
.allowUnknownOption()
|
|
370
|
+
|
|
371
|
+
.action(async () => {
|
|
372
|
+
|
|
373
|
+
try {
|
|
374
|
+
|
|
375
|
+
const { tool, args } = parseUseCommand(process.argv);
|
|
376
|
+
|
|
377
|
+
const result = await tools.useTool(tool, args);
|
|
378
|
+
|
|
379
|
+
console.log(JSON.stringify(result, null, 2));
|
|
380
|
+
|
|
381
|
+
} catch (e) {
|
|
382
|
+
|
|
383
|
+
ui.die(e.message || String(e));
|
|
384
|
+
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
63
391
|
const create = program.command('create').description('Create Mantis resources from local inputs');
|
|
64
392
|
|
|
393
|
+
|
|
394
|
+
|
|
65
395
|
addMapOptions(create
|
|
396
|
+
|
|
66
397
|
.command('map')
|
|
398
|
+
|
|
67
399
|
.description('Create a Mantis map from a local CSV/XLSX file')
|
|
400
|
+
|
|
68
401
|
.argument('<file>', 'CSV/XLSX file path'))
|
|
402
|
+
|
|
69
403
|
.action(async (file, opts) => {
|
|
404
|
+
|
|
70
405
|
try {
|
|
406
|
+
|
|
71
407
|
if (opts.private) opts.public = false;
|
|
72
|
-
|
|
408
|
+
|
|
409
|
+
const result = await map.createMap(path.resolve(file), opts);
|
|
410
|
+
|
|
73
411
|
console.log(JSON.stringify(result, null, 2));
|
|
412
|
+
|
|
74
413
|
} catch (e) {
|
|
75
|
-
|
|
414
|
+
|
|
415
|
+
ui.die(e.message || String(e));
|
|
416
|
+
|
|
76
417
|
}
|
|
418
|
+
|
|
77
419
|
});
|
|
78
420
|
|
|
421
|
+
|
|
422
|
+
|
|
79
423
|
addMapOptions(create
|
|
424
|
+
|
|
80
425
|
.command('codebase')
|
|
426
|
+
|
|
81
427
|
.description('Index a local codebase into CSV, optionally creating a Mantis map')
|
|
428
|
+
|
|
82
429
|
.argument('[root]', 'codebase root', '.')
|
|
430
|
+
|
|
83
431
|
.option('--out <file>', 'output CSV path')
|
|
432
|
+
|
|
84
433
|
.option('--max-chars <n>', 'max characters stored per file', (v) => Number(v), 12000)
|
|
434
|
+
|
|
85
435
|
.option('--create-map', 'create a Mantis map after writing the CSV'))
|
|
436
|
+
|
|
86
437
|
.action(async (root, opts) => {
|
|
438
|
+
|
|
87
439
|
try {
|
|
440
|
+
|
|
88
441
|
if (opts.private) opts.public = false;
|
|
442
|
+
|
|
89
443
|
const out = path.resolve(opts.out || defaultCodebaseOut(root));
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
444
|
+
|
|
445
|
+
const result = await codebaseIndexer.index(root, out, { maxChars: opts.maxChars });
|
|
446
|
+
|
|
447
|
+
ui.success(`Indexed ${result.count} files`);
|
|
448
|
+
|
|
449
|
+
ui.info(`CSV: ${result.outFile}`);
|
|
450
|
+
|
|
451
|
+
if (result.skipped?.length) {
|
|
452
|
+
|
|
453
|
+
ui.info(`Skipped ${result.skipped.length} binary file(s) (e.g. ${result.skipped.slice(0, 3).join(', ')})`);
|
|
454
|
+
|
|
455
|
+
}
|
|
456
|
+
|
|
93
457
|
if (opts.createMap) {
|
|
94
|
-
|
|
458
|
+
|
|
459
|
+
const mapResult = await map.createMap(result.outFile, {
|
|
460
|
+
|
|
95
461
|
...opts,
|
|
462
|
+
|
|
96
463
|
mapName: opts.mapName || `${path.basename(path.resolve(root))} Code Index`,
|
|
464
|
+
|
|
97
465
|
titleColumn: opts.titleColumn || 'path',
|
|
466
|
+
|
|
98
467
|
semanticColumn: opts.semanticColumn || 'summary,content,imports',
|
|
468
|
+
|
|
99
469
|
categoricColumn: opts.categoricColumn || 'language,kind,extension',
|
|
470
|
+
|
|
100
471
|
numericColumn: opts.numericColumn || 'loc,bytes',
|
|
472
|
+
|
|
101
473
|
});
|
|
474
|
+
|
|
102
475
|
console.log(JSON.stringify({ csv: result, map: mapResult }, null, 2));
|
|
476
|
+
|
|
103
477
|
} else {
|
|
478
|
+
|
|
104
479
|
console.log(JSON.stringify(result, null, 2));
|
|
480
|
+
|
|
105
481
|
}
|
|
482
|
+
|
|
106
483
|
} catch (e) {
|
|
107
|
-
|
|
484
|
+
|
|
485
|
+
ui.die(e.message || String(e));
|
|
486
|
+
|
|
108
487
|
}
|
|
488
|
+
|
|
109
489
|
});
|
|
110
490
|
|
|
491
|
+
|
|
492
|
+
|
|
111
493
|
program.parseAsync(process.argv);
|
|
494
|
+
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const DEFAULT_API_BASE = 'https://kellis-h200-1.csail.mit.edu';
|
|
2
|
+
export const DEFAULT_THREAD_NAME = 'Main';
|
|
3
|
+
export const DEVELOPER_PORTAL_URL = 'https://mantis.csail.mit.edu/developer/#keys';
|
|
4
|
+
export const CONFIG_NAME = 'config.json';
|
|
5
|
+
export const BROWSE_PAGE = 20;
|
|
6
|
+
export const API_PAGE = 100;
|
|
7
|
+
|
|
8
|
+
/** MCP tools disabled in CLI — use `mantis create map` / setup instead */
|
|
9
|
+
export const DISABLED_MCP_TOOLS = new Set([
|
|
10
|
+
'create_space',
|
|
11
|
+
'create_map_from_url',
|
|
12
|
+
'modify_map_from_url',
|
|
13
|
+
]);
|