vectorforce 0.3.2 → 0.3.3
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/CHANGELOG.md +22 -0
- package/README.md +97 -3
- package/bin/vf.js +44 -4
- package/package.json +1 -1
- package/src/mcp/harness-config.js +474 -0
- package/src/mcp/mcp-server.js +4 -4
- package/src/policy/authorizer.js +15 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.3.2] - 2026-11-01
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **First-Class Support for 4 Additional AI Harnesses**:
|
|
14
|
+
- **Cursor IDE**: Added automated configuration for `.cursor/mcp.json` and `.cursorrules` in `HarnessConfig.installCursor`.
|
|
15
|
+
- **Windsurf (Codeium Cascade)**: Added automated configuration for `.windsurf/mcp_config.json` and `.windsurfrules` in `HarnessConfig.installWindsurf`.
|
|
16
|
+
- **GitHub Copilot / VS Code**: Added automated workspace configuration for `.vscode/mcp.json` and `.github/copilot-instructions.md` in `HarnessConfig.installCopilot`.
|
|
17
|
+
- **Kiro IDE**: Added automated configuration for `.kiro/mcp.json`, `kiro.json`, and `.kiro/rules.md` in `HarnessConfig.installKiro`.
|
|
18
|
+
- **Harness Policy & Tool Schema Expansion**:
|
|
19
|
+
- Updated `APPROVED_DESTINATIONS` in `Authorizer` to approve `cursor`, `windsurf`, `github-copilot`, `copilot`, `kiro`, and `kiro-ide`.
|
|
20
|
+
- Updated MCP tool schemas for `get_resume_briefing`, `export_handoff`, `get_timeline`, and `reason_about_task` to accept all newly supported harnesses.
|
|
21
|
+
- **Universal MCP Configuration Guide in Documentation**:
|
|
22
|
+
- Added dedicated installation instructions to `README.md` for Cline / Roo Code, Zed Editor, JetBrains IDEs (IntelliJ, WebStorm, PyCharm), Sourcegraph Cody, Aider, and generic stdio MCP clients.
|
|
23
|
+
- **Comprehensive Unit & Security Test Coverage**:
|
|
24
|
+
- Added automated reversible install/uninstall tests for Cursor, Windsurf, GitHub Copilot, and Kiro IDE (test suite expanded to 79 tests).
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- `vf init`, `vf config install all`, `vf config doctor`, and `vf status` now inspect and provision all 9 AI coding harnesses.
|
|
28
|
+
- Pruned `package.json` package `files` whitelist to strictly include runtime artifacts (`bin/`, `src/`, `studio/dist/`, `CHANGELOG.md`, `LICENSE`, `README.md`).
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
10
32
|
## [0.2.0] - 2026-10-31
|
|
11
33
|
|
|
12
34
|
### Added
|
package/README.md
CHANGED
|
@@ -137,7 +137,7 @@ node bin/vf.js studio
|
|
|
137
137
|
|
|
138
138
|
## Model Context Protocol (MCP)
|
|
139
139
|
|
|
140
|
-
VectorForce exposes a standard stdio JSON-RPC MCP server for direct integration into **Google Antigravity**, **Claude Code**, **Command Code**, **Meta Muse**, and **
|
|
140
|
+
VectorForce exposes a standard stdio JSON-RPC MCP server for direct integration into **Google Antigravity**, **Claude Code**, **Command Code**, **Meta Muse**, **OpenAI Codex**, **Cursor**, **Windsurf**, **GitHub Copilot**, and **Kiro IDE**.
|
|
141
141
|
|
|
142
142
|
> **How MCP Starts:** You **never** need to run `vf mcp` manually in a terminal. Each AI coding agent reads its configuration file below and automatically spawns VectorForce in the background over `stdio`.
|
|
143
143
|
|
|
@@ -148,17 +148,21 @@ VectorForce exposes a standard stdio JSON-RPC MCP server for direct integration
|
|
|
148
148
|
| **Command Code (`cmd`)** | `.mcp.json` & `commandcode.json` | `node bin/vf.js config install command-code` |
|
|
149
149
|
| **Meta Muse (`muse`)** | `.muse/mcp_config.json` & `~/.config/muse/settings.json` | `node bin/vf.js config install muse` |
|
|
150
150
|
| **OpenAI Codex (`codex`)** | `.codex/config.toml` & `~/.codex/config.toml` | `node bin/vf.js config install codex` |
|
|
151
|
+
| **Cursor IDE** | `.cursor/mcp.json` & `.cursorrules` | `node bin/vf.js config install cursor` |
|
|
152
|
+
| **Windsurf (Codeium)** | `.windsurf/mcp_config.json` & `.windsurfrules` | `node bin/vf.js config install windsurf` |
|
|
153
|
+
| **GitHub Copilot / VS Code** | `.vscode/mcp.json` & `.github/copilot-instructions.md` | `node bin/vf.js config install copilot` |
|
|
154
|
+
| **Kiro IDE** | `.kiro/mcp.json` & `kiro.json` | `node bin/vf.js config install kiro` |
|
|
151
155
|
|
|
152
156
|
### Automated Configuration & Health Check
|
|
153
157
|
```bash
|
|
154
|
-
# Auto-configure all supported AI harnesses at once:
|
|
158
|
+
# Auto-configure all 9 supported AI harnesses at once:
|
|
155
159
|
node bin/vf.js config install all
|
|
156
160
|
|
|
157
161
|
# Verify SQLite DB, AGENTS.md, and all MCP client configs:
|
|
158
162
|
node bin/vf.js status
|
|
159
163
|
```
|
|
160
164
|
|
|
161
|
-
### JSON Configuration (Antigravity, Claude Code, Command Code, Muse)
|
|
165
|
+
### JSON Configuration (Antigravity, Claude Code, Command Code, Muse, Cursor, Windsurf, VS Code, Kiro)
|
|
162
166
|
```json
|
|
163
167
|
{
|
|
164
168
|
"mcpServers": {
|
|
@@ -179,6 +183,96 @@ args = ["/absolute/path/to/VectorForce/bin/vf.js", "mcp"]
|
|
|
179
183
|
VF_HARNESS = "codex"
|
|
180
184
|
```
|
|
181
185
|
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## How to Configure & Update MCP for Any Other AI Coding Harness
|
|
189
|
+
|
|
190
|
+
If your AI assistant or IDE is not in the auto-configured list above, you can connect it to VectorForce in seconds using standard MCP configuration:
|
|
191
|
+
|
|
192
|
+
### 1. Cline & Roo Code (VS Code Extension)
|
|
193
|
+
Open VS Code Settings or click the **MCP** icon in the Cline panel:
|
|
194
|
+
- Open `cline_mcp_settings.json` (or `roo-cline_mcp_settings.json`) located at:
|
|
195
|
+
- **macOS:** `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`
|
|
196
|
+
- **Linux:** `~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`
|
|
197
|
+
- **Windows:** `%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json`
|
|
198
|
+
- Add the VectorForce entry:
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"mcpServers": {
|
|
202
|
+
"vectorforce": {
|
|
203
|
+
"command": "npx",
|
|
204
|
+
"args": ["-y", "vectorforce", "mcp"],
|
|
205
|
+
"disabled": false,
|
|
206
|
+
"autoApprove": [
|
|
207
|
+
"list_tasks",
|
|
208
|
+
"check_workspace_drift",
|
|
209
|
+
"get_resume_briefing",
|
|
210
|
+
"save_checkpoint",
|
|
211
|
+
"reason_about_task"
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 2. Zed Editor
|
|
219
|
+
Zed natively supports MCP context servers. Open your Zed configuration (`~/.config/zed/settings.json` or `cmd-,`):
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"context_servers": {
|
|
223
|
+
"vectorforce": {
|
|
224
|
+
"command": {
|
|
225
|
+
"path": "npx",
|
|
226
|
+
"args": ["-y", "vectorforce", "mcp"]
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 3. JetBrains IDEs (IntelliJ IDEA, WebStorm, PyCharm, RustRover)
|
|
234
|
+
For JetBrains IDEs supporting MCP or AI Assistant:
|
|
235
|
+
1. Open **Settings / Preferences** (`Ctrl+Alt+S` or `Cmd+,`).
|
|
236
|
+
2. Search for **Model Context Protocol** or **AI Assistant → Context Providers**.
|
|
237
|
+
3. Click **Add Stdio Server**:
|
|
238
|
+
- **Name:** `vectorforce`
|
|
239
|
+
- **Command:** `node` (or `npx`)
|
|
240
|
+
- **Arguments:** `/path/to/VectorForce/bin/vf.js mcp` (or `-y vectorforce mcp`)
|
|
241
|
+
- **Environment Variables:** `VF_HARNESS=jetbrains`
|
|
242
|
+
|
|
243
|
+
### 4. Sourcegraph Cody
|
|
244
|
+
In Sourcegraph Cody settings (`cody.experimental.mcp.servers` in VS Code or JetBrains):
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"cody.experimental.mcp.servers": {
|
|
248
|
+
"vectorforce": {
|
|
249
|
+
"command": "node",
|
|
250
|
+
"args": ["/path/to/VectorForce/bin/vf.js", "mcp"]
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### 5. Aider (`aider-chat`)
|
|
257
|
+
Aider integrates directly with Git and can ingest VectorForce's immutable architectural briefings:
|
|
258
|
+
```bash
|
|
259
|
+
# Pipe VectorForce briefing directly to Aider on session start:
|
|
260
|
+
node bin/vf.js resume --task <task_id> --dest cli --raw | aider
|
|
261
|
+
|
|
262
|
+
# Or generate project conventions before running aider:
|
|
263
|
+
node bin/vf.js resume --task <task_id> --dest cli --raw > CONVENTIONS.md
|
|
264
|
+
aider
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### 6. Generic MCP Client (Any Tool Speaking JSON-RPC 2.0 over Stdio)
|
|
268
|
+
For any agent running locally, pass:
|
|
269
|
+
- **Executable:** `node`
|
|
270
|
+
- **Arguments:** `["/path/to/bin/vf.js", "mcp"]`
|
|
271
|
+
- **Working Directory:** Path to your project workspace
|
|
272
|
+
- **Environment:** `VF_WORKSPACE=/path/to/project` (optional if working directory matches)
|
|
273
|
+
|
|
274
|
+
Whenever you update VectorForce (`npm update -g vectorforce`), simply restart your AI agent or IDE window to immediately use the latest MCP tools.
|
|
275
|
+
|
|
182
276
|
### Available MCP Tools
|
|
183
277
|
| Tool | Purpose |
|
|
184
278
|
|---|---|
|
package/bin/vf.js
CHANGED
|
@@ -334,11 +334,15 @@ async function main() {
|
|
|
334
334
|
HarnessConfig.installCommandCode(cwd);
|
|
335
335
|
HarnessConfig.installMuseCode(cwd);
|
|
336
336
|
HarnessConfig.installCodex(cwd);
|
|
337
|
+
HarnessConfig.installCursor(cwd);
|
|
338
|
+
HarnessConfig.installWindsurf(cwd);
|
|
339
|
+
HarnessConfig.installCopilot(cwd);
|
|
340
|
+
HarnessConfig.installKiro(cwd);
|
|
337
341
|
const agentsMdPath = join(cwd, 'AGENTS.md');
|
|
338
342
|
if (!existsSync(agentsMdPath)) {
|
|
339
343
|
writeFileSync(
|
|
340
344
|
agentsMdPath,
|
|
341
|
-
`# Agent Continuity Protocol — ${project.name}\n\nThis repository uses **VectorForce** ("Git for AI Context") across Google Antigravity, Meta Muse, Claude Code, Command Code, and
|
|
345
|
+
`# Agent Continuity Protocol — ${project.name}\n\nThis repository uses **VectorForce** ("Git for AI Context") across Google Antigravity, Meta Muse, Claude Code, Command Code, OpenAI Codex, Cursor, Windsurf, GitHub Copilot, and Kiro IDE.\n\n## Workflow\n1. **Start/Resume Task**: Run \`vf tasks active\`, \`vf drift --task <id>\`, and \`vf resume --task <id> --dest <harness>\` (or MCP tools \`list_tasks\`, \`check_workspace_drift\`, \`get_resume_briefing\`, \`reason_about_task\`).\n2. **Save Checkpoint Before Switching IDE**: Run \`vf checkpoint --task <id> --summary "<summary>" --goal "<goal>" --constraint "<constraint>" --decision "<ID>:<Title>:<Rationale>" --next "<next>" --doc "AGENTS.md"\` (or MCP tool \`save_checkpoint\`).\n`,
|
|
342
346
|
'utf8'
|
|
343
347
|
);
|
|
344
348
|
}
|
|
@@ -582,6 +586,22 @@ async function main() {
|
|
|
582
586
|
const p = HarnessConfig.installCodex(cwd);
|
|
583
587
|
installed.push(`Codex -> ${p} (+ ~/.codex/config.toml)`);
|
|
584
588
|
}
|
|
589
|
+
if (target === 'cursor' || target === 'all') {
|
|
590
|
+
const p = HarnessConfig.installCursor(cwd);
|
|
591
|
+
installed.push(`Cursor -> ${p} (+ .cursorrules)`);
|
|
592
|
+
}
|
|
593
|
+
if (target === 'windsurf' || target === 'all') {
|
|
594
|
+
const p = HarnessConfig.installWindsurf(cwd);
|
|
595
|
+
installed.push(`Windsurf -> ${p} (+ .windsurfrules)`);
|
|
596
|
+
}
|
|
597
|
+
if (target === 'copilot' || target === 'github-copilot' || target === 'vscode' || target === 'all') {
|
|
598
|
+
const p = HarnessConfig.installCopilot(cwd);
|
|
599
|
+
installed.push(`GitHub Copilot / VS Code -> ${p} (+ .github/copilot-instructions.md)`);
|
|
600
|
+
}
|
|
601
|
+
if (target === 'kiro' || target === 'kiro-ide' || target === 'all') {
|
|
602
|
+
const p = HarnessConfig.installKiro(cwd);
|
|
603
|
+
installed.push(`Kiro IDE -> ${p} (+ kiro.json)`);
|
|
604
|
+
}
|
|
585
605
|
console.log(`\n✔ Configured harness integration(s):\n - ${installed.join('\n - ')}`);
|
|
586
606
|
console.log(`\n💡 Next step: Restart or reload your AI agent, then ask in chat:\n "List active VectorForce tasks and check workspace drift"`);
|
|
587
607
|
break;
|
|
@@ -594,7 +614,11 @@ async function main() {
|
|
|
594
614
|
{ name: 'Google Antigravity (.agents/mcp_config.json)', ok: existsSync(join(cwd, '.agents', 'mcp_config.json')), path: join(cwd, '.agents', 'mcp_config.json') },
|
|
595
615
|
{ name: 'Claude Code & Command Code (.mcp.json)', ok: existsSync(join(cwd, '.mcp.json')), path: join(cwd, '.mcp.json') },
|
|
596
616
|
{ name: 'Meta Muse (.muse/mcp_config.json)', ok: existsSync(join(cwd, '.muse', 'mcp_config.json')), path: join(cwd, '.muse', 'mcp_config.json') },
|
|
597
|
-
{ name: 'OpenAI Codex (.codex/config.toml)', ok: existsSync(join(cwd, '.codex', 'config.toml')), path: join(cwd, '.codex', 'config.toml') }
|
|
617
|
+
{ name: 'OpenAI Codex (.codex/config.toml)', ok: existsSync(join(cwd, '.codex', 'config.toml')), path: join(cwd, '.codex', 'config.toml') },
|
|
618
|
+
{ name: 'Cursor (.cursor/mcp.json)', ok: existsSync(join(cwd, '.cursor', 'mcp.json')), path: join(cwd, '.cursor', 'mcp.json') },
|
|
619
|
+
{ name: 'Windsurf (.windsurf/mcp_config.json)', ok: existsSync(join(cwd, '.windsurf', 'mcp_config.json')), path: join(cwd, '.windsurf', 'mcp_config.json') },
|
|
620
|
+
{ name: 'GitHub Copilot / VS Code (.vscode/mcp.json)', ok: existsSync(join(cwd, '.vscode', 'mcp.json')), path: join(cwd, '.vscode', 'mcp.json') },
|
|
621
|
+
{ name: 'Kiro IDE (.kiro/mcp.json)', ok: existsSync(join(cwd, '.kiro', 'mcp.json')), path: join(cwd, '.kiro', 'mcp.json') }
|
|
598
622
|
];
|
|
599
623
|
console.log(`\nVectorForce Workspace & MCP Health Check (${cwd}):\n`);
|
|
600
624
|
for (const c of checks) {
|
|
@@ -621,6 +645,18 @@ async function main() {
|
|
|
621
645
|
if (target === 'codex' || target === 'all') {
|
|
622
646
|
if (HarnessConfig.uninstallCodex(cwd)) uninstalled.push('Codex');
|
|
623
647
|
}
|
|
648
|
+
if (target === 'cursor' || target === 'all') {
|
|
649
|
+
if (HarnessConfig.uninstallCursor(cwd)) uninstalled.push('Cursor');
|
|
650
|
+
}
|
|
651
|
+
if (target === 'windsurf' || target === 'all') {
|
|
652
|
+
if (HarnessConfig.uninstallWindsurf(cwd)) uninstalled.push('Windsurf');
|
|
653
|
+
}
|
|
654
|
+
if (target === 'copilot' || target === 'github-copilot' || target === 'vscode' || target === 'all') {
|
|
655
|
+
if (HarnessConfig.uninstallCopilot(cwd)) uninstalled.push('GitHub Copilot / VS Code');
|
|
656
|
+
}
|
|
657
|
+
if (target === 'kiro' || target === 'kiro-ide' || target === 'all') {
|
|
658
|
+
if (HarnessConfig.uninstallKiro(cwd)) uninstalled.push('Kiro IDE');
|
|
659
|
+
}
|
|
624
660
|
console.log(`\n✔ Removed harness integration(s): ${uninstalled.length ? uninstalled.join(', ') : 'none found'}`);
|
|
625
661
|
break;
|
|
626
662
|
}
|
|
@@ -1101,7 +1137,11 @@ VectorForce Harness Configuration:
|
|
|
1101
1137
|
{ name: 'Google Antigravity (.agents/mcp_config.json)', ok: existsSync(join(cwd, '.agents', 'mcp_config.json')) },
|
|
1102
1138
|
{ name: 'Claude Code & Command Code (.mcp.json)', ok: existsSync(join(cwd, '.mcp.json')) },
|
|
1103
1139
|
{ name: 'Meta Muse (.muse/mcp_config.json or musecode.json)', ok: existsSync(join(cwd, '.muse', 'mcp_config.json')) || existsSync(join(cwd, 'musecode.json')) },
|
|
1104
|
-
{ name: 'OpenAI Codex (.codex/config.toml)', ok: existsSync(join(cwd, '.codex', 'config.toml')) }
|
|
1140
|
+
{ name: 'OpenAI Codex (.codex/config.toml)', ok: existsSync(join(cwd, '.codex', 'config.toml')) },
|
|
1141
|
+
{ name: 'Cursor (.cursor/mcp.json)', ok: existsSync(join(cwd, '.cursor', 'mcp.json')) },
|
|
1142
|
+
{ name: 'Windsurf (.windsurf/mcp_config.json)', ok: existsSync(join(cwd, '.windsurf', 'mcp_config.json')) },
|
|
1143
|
+
{ name: 'GitHub Copilot / VS Code (.vscode/mcp.json)', ok: existsSync(join(cwd, '.vscode', 'mcp.json')) },
|
|
1144
|
+
{ name: 'Kiro IDE (.kiro/mcp.json)', ok: existsSync(join(cwd, '.kiro', 'mcp.json')) }
|
|
1105
1145
|
];
|
|
1106
1146
|
console.log(`\nVectorForce Workspace & MCP Status (${cwd}):\n`);
|
|
1107
1147
|
for (const c of checks) {
|
|
@@ -1109,7 +1149,7 @@ VectorForce Harness Configuration:
|
|
|
1109
1149
|
}
|
|
1110
1150
|
console.log(`\n💡 How it works:`);
|
|
1111
1151
|
console.log(` 1. You do NOT need to run "vf mcp" manually.`);
|
|
1112
|
-
console.log(` 2. Your AI agent (Antigravity, Claude Code, Command Code, Muse, Codex) reads its config file above and automatically spawns "vf mcp" over stdio.`);
|
|
1152
|
+
console.log(` 2. Your AI agent (Antigravity, Claude Code, Command Code, Muse, Codex, Cursor, Windsurf, Copilot, Kiro) reads its config file above and automatically spawns "vf mcp" over stdio.`);
|
|
1113
1153
|
console.log(` 3. To verify in your AI chat, ask: "List active VectorForce tasks and check workspace drift"\n`);
|
|
1114
1154
|
break;
|
|
1115
1155
|
}
|
package/package.json
CHANGED
|
@@ -543,4 +543,478 @@ export class HarnessConfig {
|
|
|
543
543
|
|
|
544
544
|
return removed;
|
|
545
545
|
}
|
|
546
|
+
|
|
547
|
+
// ==========================================
|
|
548
|
+
// Cursor IDE Integration
|
|
549
|
+
// ==========================================
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Generate configuration object for Cursor (.cursor/mcp.json).
|
|
553
|
+
*/
|
|
554
|
+
static getCursorServerEntry() {
|
|
555
|
+
return {
|
|
556
|
+
command: 'node',
|
|
557
|
+
args: [HarnessConfig.getBinPath(), 'mcp'],
|
|
558
|
+
env: {
|
|
559
|
+
VF_HARNESS: 'cursor'
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Preview changes to Cursor configuration.
|
|
566
|
+
* @param {string} workspacePath
|
|
567
|
+
*/
|
|
568
|
+
static previewCursor(workspacePath) {
|
|
569
|
+
const dir = join(workspacePath, '.cursor');
|
|
570
|
+
const filePath = join(dir, 'mcp.json');
|
|
571
|
+
let current = null;
|
|
572
|
+
if (existsSync(filePath)) {
|
|
573
|
+
try {
|
|
574
|
+
current = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
575
|
+
} catch {
|
|
576
|
+
current = {};
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
const mergedContent = {
|
|
580
|
+
...(current || {}),
|
|
581
|
+
mcpServers: {
|
|
582
|
+
...(current?.mcpServers || {}),
|
|
583
|
+
vectorforce: HarnessConfig.getCursorServerEntry()
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
return {
|
|
587
|
+
filePath,
|
|
588
|
+
exists: existsSync(filePath),
|
|
589
|
+
currentContent: current,
|
|
590
|
+
mergedContent
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Install Cursor MCP configuration and rules reversibly.
|
|
596
|
+
* @param {string} workspacePath
|
|
597
|
+
* @returns {string} filePath
|
|
598
|
+
*/
|
|
599
|
+
static installCursor(workspacePath) {
|
|
600
|
+
const { filePath, mergedContent } = HarnessConfig.previewCursor(workspacePath);
|
|
601
|
+
const dir = join(workspacePath, '.cursor');
|
|
602
|
+
if (!existsSync(dir)) {
|
|
603
|
+
mkdirSync(dir, { recursive: true, mode: 0o755 });
|
|
604
|
+
}
|
|
605
|
+
writeFileSync(filePath, JSON.stringify(mergedContent, null, 2) + '\n', 'utf8');
|
|
606
|
+
|
|
607
|
+
// Create .cursorrules if missing
|
|
608
|
+
const cursorRulesPath = join(workspacePath, '.cursorrules');
|
|
609
|
+
if (!existsSync(cursorRulesPath)) {
|
|
610
|
+
writeFileSync(
|
|
611
|
+
cursorRulesPath,
|
|
612
|
+
`# VectorForce Agent Protocol (Cursor)\n\nThis workspace uses VectorForce for architectural continuity and drift verification.\n- Check active tasks & drift: Use MCP tools 'list_tasks' & 'check_workspace_drift'\n- Retrieve briefing: Use MCP tool 'get_resume_briefing'\n- Save checkpoint: Use MCP tool 'save_checkpoint'\n`,
|
|
613
|
+
'utf8'
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
if (!isTempWorkspace(workspacePath)) {
|
|
618
|
+
try {
|
|
619
|
+
const globalCursorDir = join(homedir(), '.cursor');
|
|
620
|
+
if (existsSync(globalCursorDir)) {
|
|
621
|
+
const globalMcpPath = join(globalCursorDir, 'mcp.json');
|
|
622
|
+
let globalConfig = {};
|
|
623
|
+
if (existsSync(globalMcpPath)) {
|
|
624
|
+
try {
|
|
625
|
+
globalConfig = JSON.parse(readFileSync(globalMcpPath, 'utf8'));
|
|
626
|
+
} catch {
|
|
627
|
+
globalConfig = {};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
globalConfig.mcpServers = {
|
|
631
|
+
...(globalConfig.mcpServers || {}),
|
|
632
|
+
vectorforce: {
|
|
633
|
+
command: 'node',
|
|
634
|
+
args: [HarnessConfig.getBinPath(), 'mcp', '--workspace', workspacePath],
|
|
635
|
+
env: {
|
|
636
|
+
VF_WORKSPACE: workspacePath,
|
|
637
|
+
VF_HARNESS: 'cursor'
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
writeFileSync(globalMcpPath, JSON.stringify(globalConfig, null, 2) + '\n', 'utf8');
|
|
642
|
+
}
|
|
643
|
+
} catch {}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
return filePath;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Reversibly uninstall VectorForce from Cursor configuration.
|
|
651
|
+
* @param {string} workspacePath
|
|
652
|
+
* @returns {boolean} whether removed
|
|
653
|
+
*/
|
|
654
|
+
static uninstallCursor(workspacePath) {
|
|
655
|
+
const filePath = join(workspacePath, '.cursor', 'mcp.json');
|
|
656
|
+
let removed = false;
|
|
657
|
+
if (existsSync(filePath)) {
|
|
658
|
+
try {
|
|
659
|
+
const config = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
660
|
+
if (config?.mcpServers?.vectorforce) {
|
|
661
|
+
delete config.mcpServers.vectorforce;
|
|
662
|
+
writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
663
|
+
removed = true;
|
|
664
|
+
}
|
|
665
|
+
} catch {}
|
|
666
|
+
}
|
|
667
|
+
return removed;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// ==========================================
|
|
671
|
+
// Windsurf Cascade Integration
|
|
672
|
+
// ==========================================
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Generate configuration object for Windsurf (.windsurf/mcp_config.json).
|
|
676
|
+
*/
|
|
677
|
+
static getWindsurfServerEntry() {
|
|
678
|
+
return {
|
|
679
|
+
command: 'node',
|
|
680
|
+
args: [HarnessConfig.getBinPath(), 'mcp'],
|
|
681
|
+
env: {
|
|
682
|
+
VF_HARNESS: 'windsurf'
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Preview changes to Windsurf configuration.
|
|
689
|
+
* @param {string} workspacePath
|
|
690
|
+
*/
|
|
691
|
+
static previewWindsurf(workspacePath) {
|
|
692
|
+
const dir = join(workspacePath, '.windsurf');
|
|
693
|
+
const filePath = join(dir, 'mcp_config.json');
|
|
694
|
+
let current = null;
|
|
695
|
+
if (existsSync(filePath)) {
|
|
696
|
+
try {
|
|
697
|
+
current = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
698
|
+
} catch {
|
|
699
|
+
current = {};
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
const mergedContent = {
|
|
703
|
+
...(current || {}),
|
|
704
|
+
mcpServers: {
|
|
705
|
+
...(current?.mcpServers || {}),
|
|
706
|
+
vectorforce: HarnessConfig.getWindsurfServerEntry()
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
return {
|
|
710
|
+
filePath,
|
|
711
|
+
exists: existsSync(filePath),
|
|
712
|
+
currentContent: current,
|
|
713
|
+
mergedContent
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Install Windsurf MCP configuration and rules reversibly.
|
|
719
|
+
* @param {string} workspacePath
|
|
720
|
+
* @returns {string} filePath
|
|
721
|
+
*/
|
|
722
|
+
static installWindsurf(workspacePath) {
|
|
723
|
+
const { filePath, mergedContent } = HarnessConfig.previewWindsurf(workspacePath);
|
|
724
|
+
const dir = join(workspacePath, '.windsurf');
|
|
725
|
+
if (!existsSync(dir)) {
|
|
726
|
+
mkdirSync(dir, { recursive: true, mode: 0o755 });
|
|
727
|
+
}
|
|
728
|
+
writeFileSync(filePath, JSON.stringify(mergedContent, null, 2) + '\n', 'utf8');
|
|
729
|
+
|
|
730
|
+
// Create .windsurfrules if missing
|
|
731
|
+
const windsurfRulesPath = join(workspacePath, '.windsurfrules');
|
|
732
|
+
if (!existsSync(windsurfRulesPath)) {
|
|
733
|
+
writeFileSync(
|
|
734
|
+
windsurfRulesPath,
|
|
735
|
+
`# VectorForce Agent Protocol (Windsurf Cascade)\n\nThis workspace uses VectorForce for architectural continuity and drift verification.\n- Check tasks & drift: Call MCP tools 'list_tasks' and 'check_workspace_drift'\n- Resume briefing: Call MCP tool 'get_resume_briefing'\n- Save checkpoint: Call MCP tool 'save_checkpoint'\n`,
|
|
736
|
+
'utf8'
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
if (!isTempWorkspace(workspacePath)) {
|
|
741
|
+
try {
|
|
742
|
+
const globalWindsurfDir = join(homedir(), '.codeium', 'windsurf');
|
|
743
|
+
if (existsSync(globalWindsurfDir)) {
|
|
744
|
+
const globalMcpPath = join(globalWindsurfDir, 'mcp_config.json');
|
|
745
|
+
let globalConfig = {};
|
|
746
|
+
if (existsSync(globalMcpPath)) {
|
|
747
|
+
try {
|
|
748
|
+
globalConfig = JSON.parse(readFileSync(globalMcpPath, 'utf8'));
|
|
749
|
+
} catch {
|
|
750
|
+
globalConfig = {};
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
globalConfig.mcpServers = {
|
|
754
|
+
...(globalConfig.mcpServers || {}),
|
|
755
|
+
vectorforce: {
|
|
756
|
+
command: 'node',
|
|
757
|
+
args: [HarnessConfig.getBinPath(), 'mcp', '--workspace', workspacePath],
|
|
758
|
+
env: {
|
|
759
|
+
VF_WORKSPACE: workspacePath,
|
|
760
|
+
VF_HARNESS: 'windsurf'
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
writeFileSync(globalMcpPath, JSON.stringify(globalConfig, null, 2) + '\n', 'utf8');
|
|
765
|
+
}
|
|
766
|
+
} catch {}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return filePath;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Reversibly uninstall VectorForce from Windsurf configuration.
|
|
774
|
+
* @param {string} workspacePath
|
|
775
|
+
* @returns {boolean} whether removed
|
|
776
|
+
*/
|
|
777
|
+
static uninstallWindsurf(workspacePath) {
|
|
778
|
+
const filePath = join(workspacePath, '.windsurf', 'mcp_config.json');
|
|
779
|
+
let removed = false;
|
|
780
|
+
if (existsSync(filePath)) {
|
|
781
|
+
try {
|
|
782
|
+
const config = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
783
|
+
if (config?.mcpServers?.vectorforce) {
|
|
784
|
+
delete config.mcpServers.vectorforce;
|
|
785
|
+
writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
786
|
+
removed = true;
|
|
787
|
+
}
|
|
788
|
+
} catch {}
|
|
789
|
+
}
|
|
790
|
+
return removed;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// ==========================================
|
|
794
|
+
// GitHub Copilot & VS Code Integration
|
|
795
|
+
// ==========================================
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Generate configuration object for VS Code / GitHub Copilot (.vscode/mcp.json).
|
|
799
|
+
*/
|
|
800
|
+
static getCopilotServerEntry() {
|
|
801
|
+
return {
|
|
802
|
+
command: 'node',
|
|
803
|
+
args: [HarnessConfig.getBinPath(), 'mcp'],
|
|
804
|
+
env: {
|
|
805
|
+
VF_HARNESS: 'copilot'
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Preview changes to Copilot / VS Code configuration.
|
|
812
|
+
* @param {string} workspacePath
|
|
813
|
+
*/
|
|
814
|
+
static previewCopilot(workspacePath) {
|
|
815
|
+
const dir = join(workspacePath, '.vscode');
|
|
816
|
+
const filePath = join(dir, 'mcp.json');
|
|
817
|
+
let current = null;
|
|
818
|
+
if (existsSync(filePath)) {
|
|
819
|
+
try {
|
|
820
|
+
current = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
821
|
+
} catch {
|
|
822
|
+
current = {};
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
const mergedContent = {
|
|
826
|
+
...(current || {}),
|
|
827
|
+
mcpServers: {
|
|
828
|
+
...(current?.mcpServers || {}),
|
|
829
|
+
vectorforce: HarnessConfig.getCopilotServerEntry()
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
return {
|
|
833
|
+
filePath,
|
|
834
|
+
exists: existsSync(filePath),
|
|
835
|
+
currentContent: current,
|
|
836
|
+
mergedContent
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Install GitHub Copilot workspace instructions & VS Code MCP configuration.
|
|
842
|
+
* @param {string} workspacePath
|
|
843
|
+
* @returns {string} filePath
|
|
844
|
+
*/
|
|
845
|
+
static installCopilot(workspacePath) {
|
|
846
|
+
const { filePath, mergedContent } = HarnessConfig.previewCopilot(workspacePath);
|
|
847
|
+
const vscodeDir = join(workspacePath, '.vscode');
|
|
848
|
+
if (!existsSync(vscodeDir)) {
|
|
849
|
+
mkdirSync(vscodeDir, { recursive: true, mode: 0o755 });
|
|
850
|
+
}
|
|
851
|
+
writeFileSync(filePath, JSON.stringify(mergedContent, null, 2) + '\n', 'utf8');
|
|
852
|
+
|
|
853
|
+
// Create .github/copilot-instructions.md if missing
|
|
854
|
+
const githubDir = join(workspacePath, '.github');
|
|
855
|
+
if (!existsSync(githubDir)) {
|
|
856
|
+
mkdirSync(githubDir, { recursive: true, mode: 0o755 });
|
|
857
|
+
}
|
|
858
|
+
const copilotMdPath = join(githubDir, 'copilot-instructions.md');
|
|
859
|
+
if (!existsSync(copilotMdPath)) {
|
|
860
|
+
writeFileSync(
|
|
861
|
+
copilotMdPath,
|
|
862
|
+
`# VectorForce Context Protocol (GitHub Copilot)\n\nThis workspace uses VectorForce for architectural continuity and drift protection.\n- Architectural decisions (ADRs) and invariant constraints are tracked in VectorForce.\n- Check tasks and drift via VectorForce MCP or \`node bin/vf.js drift\`.\n- Always capture progress with \`node bin/vf.js checkpoint\`.\n`,
|
|
863
|
+
'utf8'
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
return filePath;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Reversibly uninstall VectorForce from Copilot / VS Code configuration.
|
|
872
|
+
* @param {string} workspacePath
|
|
873
|
+
* @returns {boolean} whether removed
|
|
874
|
+
*/
|
|
875
|
+
static uninstallCopilot(workspacePath) {
|
|
876
|
+
const filePath = join(workspacePath, '.vscode', 'mcp.json');
|
|
877
|
+
let removed = false;
|
|
878
|
+
if (existsSync(filePath)) {
|
|
879
|
+
try {
|
|
880
|
+
const config = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
881
|
+
if (config?.mcpServers?.vectorforce) {
|
|
882
|
+
delete config.mcpServers.vectorforce;
|
|
883
|
+
writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
884
|
+
removed = true;
|
|
885
|
+
}
|
|
886
|
+
} catch {}
|
|
887
|
+
}
|
|
888
|
+
return removed;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// ==========================================
|
|
892
|
+
// Kiro IDE Integration
|
|
893
|
+
// ==========================================
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Generate configuration object for Kiro IDE (.kiro/mcp.json).
|
|
897
|
+
*/
|
|
898
|
+
static getKiroServerEntry() {
|
|
899
|
+
return {
|
|
900
|
+
command: 'node',
|
|
901
|
+
args: [HarnessConfig.getBinPath(), 'mcp'],
|
|
902
|
+
env: {
|
|
903
|
+
VF_HARNESS: 'kiro'
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Preview changes to Kiro IDE configuration.
|
|
910
|
+
* @param {string} workspacePath
|
|
911
|
+
*/
|
|
912
|
+
static previewKiro(workspacePath) {
|
|
913
|
+
const dir = join(workspacePath, '.kiro');
|
|
914
|
+
const filePath = join(dir, 'mcp.json');
|
|
915
|
+
const kiroJsonPath = join(workspacePath, 'kiro.json');
|
|
916
|
+
|
|
917
|
+
let current = null;
|
|
918
|
+
if (existsSync(filePath)) {
|
|
919
|
+
try {
|
|
920
|
+
current = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
921
|
+
} catch {
|
|
922
|
+
current = {};
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
const mergedContent = {
|
|
926
|
+
...(current || {}),
|
|
927
|
+
mcpServers: {
|
|
928
|
+
...(current?.mcpServers || {}),
|
|
929
|
+
vectorforce: HarnessConfig.getKiroServerEntry()
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
let currentKiroJson = null;
|
|
934
|
+
if (existsSync(kiroJsonPath)) {
|
|
935
|
+
try {
|
|
936
|
+
currentKiroJson = JSON.parse(readFileSync(kiroJsonPath, 'utf8'));
|
|
937
|
+
} catch {
|
|
938
|
+
currentKiroJson = {};
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
const mergedKiroJson = {
|
|
942
|
+
...(currentKiroJson || {}),
|
|
943
|
+
mcpServers: {
|
|
944
|
+
...(currentKiroJson?.mcpServers || {}),
|
|
945
|
+
vectorforce: HarnessConfig.getKiroServerEntry()
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
|
|
949
|
+
return {
|
|
950
|
+
filePath,
|
|
951
|
+
kiroJsonPath,
|
|
952
|
+
exists: existsSync(filePath) || existsSync(kiroJsonPath),
|
|
953
|
+
currentContent: current,
|
|
954
|
+
mergedContent,
|
|
955
|
+
mergedKiroJson
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Install Kiro IDE MCP configuration and rules reversibly.
|
|
961
|
+
* @param {string} workspacePath
|
|
962
|
+
* @returns {string} filePath
|
|
963
|
+
*/
|
|
964
|
+
static installKiro(workspacePath) {
|
|
965
|
+
const { filePath, kiroJsonPath, mergedContent, mergedKiroJson } = HarnessConfig.previewKiro(workspacePath);
|
|
966
|
+
const dir = join(workspacePath, '.kiro');
|
|
967
|
+
if (!existsSync(dir)) {
|
|
968
|
+
mkdirSync(dir, { recursive: true, mode: 0o755 });
|
|
969
|
+
}
|
|
970
|
+
writeFileSync(filePath, JSON.stringify(mergedContent, null, 2) + '\n', 'utf8');
|
|
971
|
+
writeFileSync(kiroJsonPath, JSON.stringify(mergedKiroJson, null, 2) + '\n', 'utf8');
|
|
972
|
+
|
|
973
|
+
// Create .kiro/rules.md if missing
|
|
974
|
+
const rulesPath = join(dir, 'rules.md');
|
|
975
|
+
if (!existsSync(rulesPath)) {
|
|
976
|
+
writeFileSync(
|
|
977
|
+
rulesPath,
|
|
978
|
+
`# VectorForce Agent Steering (Kiro IDE)\n\nThis workspace uses VectorForce for architectural continuity and drift prevention.\n- Use VectorForce MCP tools: 'list_tasks', 'check_workspace_drift', 'get_resume_briefing', 'save_checkpoint'.\n- Strictly adhere to invariant constraints and architectural decisions.\n`,
|
|
979
|
+
'utf8'
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
return filePath;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Reversibly uninstall VectorForce from Kiro IDE configuration.
|
|
988
|
+
* @param {string} workspacePath
|
|
989
|
+
* @returns {boolean} whether removed
|
|
990
|
+
*/
|
|
991
|
+
static uninstallKiro(workspacePath) {
|
|
992
|
+
const filePath = join(workspacePath, '.kiro', 'mcp.json');
|
|
993
|
+
const kiroJsonPath = join(workspacePath, 'kiro.json');
|
|
994
|
+
let removed = false;
|
|
995
|
+
|
|
996
|
+
if (existsSync(filePath)) {
|
|
997
|
+
try {
|
|
998
|
+
const config = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
999
|
+
if (config?.mcpServers?.vectorforce) {
|
|
1000
|
+
delete config.mcpServers.vectorforce;
|
|
1001
|
+
writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
1002
|
+
removed = true;
|
|
1003
|
+
}
|
|
1004
|
+
} catch {}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
if (existsSync(kiroJsonPath)) {
|
|
1008
|
+
try {
|
|
1009
|
+
const config = JSON.parse(readFileSync(kiroJsonPath, 'utf8'));
|
|
1010
|
+
if (config?.mcpServers?.vectorforce) {
|
|
1011
|
+
delete config.mcpServers.vectorforce;
|
|
1012
|
+
writeFileSync(kiroJsonPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
1013
|
+
removed = true;
|
|
1014
|
+
}
|
|
1015
|
+
} catch {}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
return removed;
|
|
1019
|
+
}
|
|
546
1020
|
}
|
package/src/mcp/mcp-server.js
CHANGED
|
@@ -44,7 +44,7 @@ export const MCP_TOOLS = [
|
|
|
44
44
|
task_id: { type: 'string' },
|
|
45
45
|
checkpoint_id: { type: 'string', description: 'Optional specific checkpoint ID. Defaults to latest head.' },
|
|
46
46
|
max_tokens: { type: 'integer', default: 4000, maximum: 8000 },
|
|
47
|
-
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli'] }
|
|
47
|
+
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli', 'cursor', 'windsurf', 'github-copilot', 'copilot', 'kiro', 'kiro-ide'] }
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
},
|
|
@@ -91,7 +91,7 @@ export const MCP_TOOLS = [
|
|
|
91
91
|
task_id: { type: 'string', description: 'Kebab-case task slug' },
|
|
92
92
|
recipient: { type: 'string', description: 'Target developer or audience identity' },
|
|
93
93
|
checkpoint_id: { type: 'string', description: 'Optional specific checkpoint ID to export' },
|
|
94
|
-
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli', 'any'], default: 'any' },
|
|
94
|
+
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli', 'cursor', 'windsurf', 'github-copilot', 'copilot', 'kiro', 'kiro-ide', 'any'], default: 'any' },
|
|
95
95
|
preview: { type: 'boolean', default: false, description: 'Dry run preview without writing file' },
|
|
96
96
|
out_path: { type: 'string', description: 'Optional custom bundle file destination' }
|
|
97
97
|
}
|
|
@@ -117,7 +117,7 @@ export const MCP_TOOLS = [
|
|
|
117
117
|
properties: {
|
|
118
118
|
days: { type: 'integer', default: 7, description: 'Number of past days to include in the recap (defaults to 7)' },
|
|
119
119
|
task_id: { type: 'string', description: 'Optional specific task ID to filter by' },
|
|
120
|
-
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli'] }
|
|
120
|
+
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli', 'cursor', 'windsurf', 'github-copilot', 'copilot', 'kiro', 'kiro-ide'] }
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
},
|
|
@@ -130,7 +130,7 @@ export const MCP_TOOLS = [
|
|
|
130
130
|
properties: {
|
|
131
131
|
task_id: { type: 'string', description: 'Kebab-case task slug' },
|
|
132
132
|
checkpoint_id: { type: 'string', description: 'Optional specific checkpoint ID. Defaults to latest head.' },
|
|
133
|
-
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli'] },
|
|
133
|
+
destination_harness: { type: 'string', enum: ['antigravity', 'command-code', 'muse', 'muse-code', 'pi', 'codex', 'cli', 'cursor', 'windsurf', 'github-copilot', 'copilot', 'kiro', 'kiro-ide'] },
|
|
134
134
|
model: { type: 'string', description: 'Optional model override (e.g. a Meta Llama or Muse model id)' },
|
|
135
135
|
focus: { type: 'string', description: 'Optional question or focus for the reasoning pass' },
|
|
136
136
|
include_code: { type: 'boolean', default: true, description: 'Ground reasoning in the live codebase index' }
|
package/src/policy/authorizer.js
CHANGED
|
@@ -5,7 +5,21 @@ import { ErrorCode, VectorForceError } from '../core/errors.js';
|
|
|
5
5
|
export const MAX_FILE_BYTES = 8192; // 8 KiB per file
|
|
6
6
|
export const MAX_TOTAL_DOCUMENT_BYTES = 65536; // 64 KiB total
|
|
7
7
|
export const ALLOWED_EXTENSIONS = ['.md', '.txt'];
|
|
8
|
-
export const APPROVED_DESTINATIONS = [
|
|
8
|
+
export const APPROVED_DESTINATIONS = [
|
|
9
|
+
'antigravity',
|
|
10
|
+
'command-code',
|
|
11
|
+
'muse',
|
|
12
|
+
'muse-code',
|
|
13
|
+
'pi',
|
|
14
|
+
'codex',
|
|
15
|
+
'cli',
|
|
16
|
+
'cursor',
|
|
17
|
+
'windsurf',
|
|
18
|
+
'github-copilot',
|
|
19
|
+
'copilot',
|
|
20
|
+
'kiro',
|
|
21
|
+
'kiro-ide'
|
|
22
|
+
];
|
|
9
23
|
|
|
10
24
|
export class Authorizer {
|
|
11
25
|
/**
|