vectorforce 0.3.3 → 0.3.7

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 CHANGED
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.3.5] - 2026-11-04
11
+
12
+ ### Added
13
+ - Dynamic project semantic topology layout and AST import dependency edge mapping in Studio `/api/graph`.
14
+ - Live workspace AST entity symbols extraction and allowlisted document evidence collection (SHA-256 digests and file sizes) in `/api/memory`.
15
+ - Task scope selector and live Git branch/commit/dirty badges in the Studio header.
16
+
17
+ ### Fixed
18
+ - Studio Project Graph and Memory views now dynamically reflect the active workspace repository rather than fallback mock structures.
19
+ - Dashboard metric cards (Health Score, AI Reasoning, Ontology & Memory, Provenance Chain) and recent checkpoint cards are now interactive and route to their respective views (`timeline`, `settings`, `memory`, `graph`).
20
+
21
+ ## [0.3.4] - 2026-11-04
22
+
23
+ ### Fixed
24
+ - Cross-platform MCP availability: generated harness configs now use the absolute Node.js runtime (`process.execPath`) with `"type": "stdio"` instead of bare `node`, so GUI-launched clients on Windows, macOS, and Linux can spawn `vf mcp` even when `node` is not on their PATH.
25
+ - MCP protocol compatibility: the stdio server negotiates `protocolVersion` (`2025-11-25`, `2025-06-18`, `2025-03-26`, `2024-11-05`), reports the package version, answers `resources/list`, `resources/templates/list`, `prompts/list`, and JSON-RPC batches, and keeps `stdout` reserved for JSON-RPC in `vf mcp` mode.
26
+ - VS Code / Copilot: `.vscode/mcp.json` is now written under the top-level `servers` key (the only shape VS Code reads); legacy `mcpServers.vectorforce` entries are migrated on install and removed on uninstall.
27
+ - Kiro IDE: workspace config is now written to `.kiro/settings/mcp.json` (the path Kiro reads) with steering in `.kiro/steering/vectorforce.md`; the legacy `.kiro/mcp.json` entry is migrated.
28
+ - Meta Muse: `installMuseCode` now always ensures the global `~/.config/muse/settings.json` entry under the `mcpServers` key (the block Muse Code actually reads; a stale `mcp_servers.vectorforce` entry is migrated) with no workspace pin so one entry serves every project, and no longer deletes unrelated user keys.
29
+ - Antigravity: global config prefers `~/.gemini/config/mcp_config.json` with fallback to `~/.gemini/antigravity/mcp_config.json`.
30
+ - Codex TOML now embeds quoted absolute paths for both the Node runtime and `bin/vf.js`.
31
+
32
+ ### Changed
33
+ - `vf init` no longer creates every harness config at once: it auto-detects harnesses already in use (marker files/dirs), installs only those, and otherwise creates none while printing the exact follow-up commands. Override with `vf init --harness <id[,...]|all|none>` or `vf init --all`.
34
+ - Added `vf config list` showing supported harnesses with detected/configured status; `vf config install`/`uninstall` reject unknown harness names with that hint.
35
+ - `vf doctor`, `vf status`, and `vf config doctor` now verify the VectorForce entry exists instead of only the file.
36
+
10
37
  ## [0.3.2] - 2026-11-01
11
38
 
12
39
  ### Added
package/README.md CHANGED
@@ -27,6 +27,85 @@ VectorForce provides an immutable, cryptographic context layer that tracks:
27
27
 
28
28
  ---
29
29
 
30
+ ## Architecture & System Topology
31
+
32
+ VectorForce is engineered with a strict **Local-First & Zero Runtime Dependency** design. It operates entirely through Node.js built-ins (`node:sqlite`, `node:crypto`, `node:http`, `node:fs`) and integrates seamlessly across local IDEs, multi-agent MCP bridges, and zero-knowledge cloud sync.
33
+
34
+ ```mermaid
35
+ flowchart TD
36
+ subgraph AI_Harnesses["AI Coding Agent Ecosystem (MCP Protocol)"]
37
+ A1["⚡ Google Antigravity"]
38
+ A2["🦙 Meta Muse"]
39
+ A3["⌘ Claude / Command Code"]
40
+ A4["◈ OpenAI Codex"]
41
+ A5["🖱️ Cursor IDE"]
42
+ A6["🌊 Windsurf Cascade"]
43
+ A7["🐙 GitHub Copilot"]
44
+ A8["⚡ Kiro IDE"]
45
+ end
46
+
47
+ subgraph VectorForce_Core["VectorForce Core Engine (Zero Runtime Dependencies)"]
48
+ direction TB
49
+ MCP["MCP Server & JSON-RPC Bridge\n(src/mcp/mcp-server.js • stdio)"]
50
+ CLI["CLI Control Interface\n(bin/vf.js • init, status, drift, resume)"]
51
+
52
+ AUTH["Zero-Leak Policy Authorizer\n(src/policy/authorizer.js • Symlink & Containment Guard)"]
53
+
54
+ subgraph Operations["Operations & Synthesis Services"]
55
+ CHK["Checkpoint Service\n(Claims vs Evidence Fencing)"]
56
+ BRF["Briefing & Drift Service\n(Git HEAD & SHA-256 Hash Matching)"]
57
+ RSN["AI Reasoning Service\n(Meta Muse • Fireworks • Llama 3.3)"]
58
+ HDF["Handoff Service\n(HMAC-SHA256 Manifest Export/Import)"]
59
+ end
60
+
61
+ subgraph Providers["Zero-Dep Workspace Observers"]
62
+ GIT["Git Provider\n(Branch, Commit SHA, Diff, Dirty Tree)"]
63
+ DOC["Document Provider\n(Allowlisted Spec Reader & SHA-256 Hashes)"]
64
+ AST["Code Index Provider\n(AST Symbols & Import Dependency Graph)"]
65
+ end
66
+
67
+ DB[("Local SQLite WAL Store\n(.vectorforce/vectorforce.db\nnode:sqlite WAL mode)")]
68
+ end
69
+
70
+ subgraph Studio_UI["Local VectorForce Studio (Web UI)"]
71
+ WEB["Studio HTTP Server (127.0.0.1:3210)\nReact + Vite + Tailwind + XYFlow"]
72
+ end
73
+
74
+ subgraph Cloud_Layer["VectorForce Cloud (Modal.com / E2EE Sync)"]
75
+ REMOTE["Zero-Knowledge Wire & Hub\nX25519 ECDH + AES-256-GCM + Ed25519 Signature\n(Multi-Project Hub • PM Interpreter Portal)"]
76
+ end
77
+
78
+ %% Wiring
79
+ A1 & A2 & A3 & A4 & A5 & A6 & A7 & A8 <-->|"stdio JSON-RPC 2.0"| MCP
80
+ CLI --> AUTH
81
+ MCP --> AUTH
82
+ AUTH --> Operations
83
+ Operations <--> Providers
84
+ Operations <--> DB
85
+ DB <--> WEB
86
+ Operations <-->|"vf push / vf pull\n(Encrypted Ciphertext)"| REMOTE
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Tech Stack Overview
92
+
93
+ VectorForce adheres to strict architectural purity, ensuring rock-solid stability, privacy, and speed without bloated dependency chains.
94
+
95
+ | Layer | Technology | Rationale / Key Capabilities |
96
+ | :--- | :--- | :--- |
97
+ | **Runtime & Core** | **Node.js (>= 22.5.0 ESM)** | Pure ES Modules, fast startup, native cross-platform support (macOS, Linux, Windows). |
98
+ | **Backend Dependencies** | **Zero External Runtime Dependencies** | Powered 100% by Node.js built-ins: `node:sqlite`, `node:crypto`, `node:http`, `node:fs`, `node:child_process`, `node:os`. |
99
+ | **Storage Engine** | **`node:sqlite` (WAL Mode)** | Local-first, zero-configuration database (`.vectorforce/vectorforce.db`) with Write-Ahead Logging for atomic concurrent reads/writes. |
100
+ | **Cryptographic Security** | **`node:crypto` (HMAC-SHA256, AES-256-GCM, X25519, Ed25519)** | Tamper-evident handoffs, verifiable file digests, and end-to-end zero-knowledge multi-machine sync. |
101
+ | **Protocol Integration** | **Model Context Protocol (MCP)** | JSON-RPC 2.0 over standard I/O (`stdio`), 9 deterministic tools, and auto-configuration for 8+ AI harnesses. |
102
+ | **AI Reasoning Layer** | **Meta Muse & Llama 3.3** | Native adapters for **Meta Muse (`muse-spark-1.3`)**, **Meta Muse Spark Open** (Fireworks AI / OpenRouter), Local **Ollama**, **OpenAI**, and **Anthropic** with graceful offline briefing fallback. |
103
+ | **AST & Code Indexer** | **Custom Zero-Dependency Regex/Tokenizer Indexer** | Extracts symbols (classes, functions, interfaces), imports, and module dependency graphs without heavy external parser bloat. |
104
+ | **Local Studio Frontend** | **React 18 + Vite + Tailwind CSS + XYFlow** | Interactive architecture control center, live blast radius inspector, Claims vs Evidence timeline, and memory console. |
105
+ | **Cloud Remote Sync** | **Modal.com Serverless Container (Debian + Node 22)** | Zero-Knowledge E2EE relay hub, scale-to-zero serverless deployment, PM Interpreter, and Multi-Project switcher. |
106
+
107
+ ---
108
+
30
109
  ## VectorForce Studio (Web UI)
31
110
 
32
111
  VectorForce includes a local-first engineering control center:
@@ -47,9 +126,12 @@ node bin/vf.js studio
47
126
 
48
127
  ## Quickstart
49
128
 
50
- ### 1. Initialize a Project
129
+ ### 1. Initialize a Project (auto-detects your AI harness)
51
130
  ```bash
52
131
  node bin/vf.js init
132
+ # Only detected harnesses are configured; repos with no harness get no MCP files yet.
133
+ node bin/vf.js config list # supported harnesses + detected/configured status
134
+ node bin/vf.js config install cursor # or: --harness on init, or install all
53
135
  ```
54
136
 
55
137
  ### 2. Create and Select a Task
@@ -139,19 +221,19 @@ node bin/vf.js studio
139
221
 
140
222
  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
223
 
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`.
224
+ > **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`. Generated entries use the absolute Node.js runtime path, so GUI-launched clients find it even when `node` is not on their PATH (common on Windows).
143
225
 
144
226
  | AI Coding Client | Config File Read by Client | 1-Command Auto-Setup |
145
227
  |---|---|---|
146
- | **Google Antigravity** | `.agents/mcp_config.json` & `~/.gemini/antigravity/mcp_config.json` | `node bin/vf.js config install antigravity` |
228
+ | **Google Antigravity** | `.agents/mcp_config.json` & `~/.gemini/config/mcp_config.json` (or `~/.gemini/antigravity/mcp_config.json`) | `node bin/vf.js config install antigravity` |
147
229
  | **Claude Code (`claude`)** | `.mcp.json` (project root) | `node bin/vf.js config install claude-code` |
148
230
  | **Command Code (`cmd`)** | `.mcp.json` & `commandcode.json` | `node bin/vf.js config install command-code` |
149
- | **Meta Muse (`muse`)** | `.muse/mcp_config.json` & `~/.config/muse/settings.json` | `node bin/vf.js config install muse` |
231
+ | **Meta Muse (`muse`)** | `~/.config/muse/settings.json` (global `mcpServers`; `.muse/mcp_config.json` kept as mirror) | `node bin/vf.js config install muse` |
150
232
  | **OpenAI Codex (`codex`)** | `.codex/config.toml` & `~/.codex/config.toml` | `node bin/vf.js config install codex` |
151
233
  | **Cursor IDE** | `.cursor/mcp.json` & `.cursorrules` | `node bin/vf.js config install cursor` |
152
234
  | **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` |
235
+ | **GitHub Copilot / VS Code** | `.vscode/mcp.json` (top-level `servers`) & `.github/copilot-instructions.md` | `node bin/vf.js config install copilot` |
236
+ | **Kiro IDE** | `.kiro/settings/mcp.json` & `kiro.json` | `node bin/vf.js config install kiro` |
155
237
 
156
238
  ### Automated Configuration & Health Check
157
239
  ```bash
@@ -167,7 +249,7 @@ node bin/vf.js status
167
249
  {
168
250
  "mcpServers": {
169
251
  "vectorforce": {
170
- "command": "node",
252
+ "command": "/absolute/path/to/node",
171
253
  "args": ["/absolute/path/to/VectorForce/bin/vf.js", "mcp"]
172
254
  }
173
255
  }
@@ -177,7 +259,7 @@ node bin/vf.js status
177
259
  ### TOML Configuration (OpenAI Codex CLI: `.codex/config.toml`)
178
260
  ```toml
179
261
  [mcp_servers.vectorforce]
180
- command = "node"
262
+ command = "/absolute/path/to/node"
181
263
  args = ["/absolute/path/to/VectorForce/bin/vf.js", "mcp"]
182
264
  [mcp_servers.vectorforce.env]
183
265
  VF_HARNESS = "codex"
package/bin/vf.js CHANGED
@@ -146,7 +146,7 @@ function printUsage() {
146
146
  VectorForce (vf) - Git for AI Engineering Context
147
147
 
148
148
  Usage:
149
- vf init [project_name] Initialize current workspace
149
+ vf init [project_name] [--harness <id|all|none>] Init workspace (auto-detects harnesses)
150
150
  vf task <id> [title] Create or register a task
151
151
  vf tasks [active|completed|all] List tasks in workspace
152
152
  vf policy list List allowed document paths
@@ -162,7 +162,7 @@ Usage:
162
162
  vf studio [options] Launch VectorForce Studio web control center
163
163
  vf ui [options] Alias for vf studio
164
164
  vf mcp Start stdio MCP server for Antigravity / Command Code
165
- vf config Display MCP configuration snippet for harnesses
165
+ vf config list|install|doctor List, install, or check harness MCP integrations
166
166
  vf help Show this help
167
167
 
168
168
  Checkpoint options:
@@ -235,7 +235,15 @@ function parseFlags(args) {
235
235
  rationale: parts.slice(2).join(':') || 'Approved architecture decision'
236
236
  });
237
237
  } else if (arg === '--harness' && args[i + 1]) {
238
- flags.harness = args[++i];
238
+ const harnessValue = args[++i];
239
+ flags.harness = harnessValue;
240
+ flags.harnessList = (flags.harnessList || []).concat(
241
+ harnessValue.split(',').map((value) => value.trim()).filter(Boolean)
242
+ );
243
+ } else if (arg === '--all') {
244
+ flags.all = true;
245
+ } else if (arg === '--none') {
246
+ flags.none = true;
239
247
  } else if (arg === '--author' && args[i + 1]) {
240
248
  flags.author = args[++i];
241
249
  } else if (arg === '--next' && args[i + 1]) {
@@ -330,14 +338,34 @@ async function main() {
330
338
  case 'init': {
331
339
  const name = args[1] && !args[1].startsWith('--') ? args[1] : null;
332
340
  const project = projectService.initProject(cwd, name);
333
- HarnessConfig.installAntigravity(cwd);
334
- HarnessConfig.installCommandCode(cwd);
335
- HarnessConfig.installMuseCode(cwd);
336
- HarnessConfig.installCodex(cwd);
337
- HarnessConfig.installCursor(cwd);
338
- HarnessConfig.installWindsurf(cwd);
339
- HarnessConfig.installCopilot(cwd);
340
- HarnessConfig.installKiro(cwd);
341
+ const harnessRequest = flags.harnessList && flags.harnessList.length > 0 ? flags.harnessList : null;
342
+ let harnessTargets = [];
343
+ if (flags.all || (harnessRequest && harnessRequest.some((h) => h.toLowerCase() === 'all'))) {
344
+ harnessTargets = HarnessConfig.getSupportedHarnesses().map((h) => h.id);
345
+ } else if (flags.none || (harnessRequest && harnessRequest.some((h) => h.toLowerCase() === 'none'))) {
346
+ harnessTargets = [];
347
+ } else if (harnessRequest) {
348
+ const unknown = [];
349
+ for (const requested of harnessRequest) {
350
+ const resolved = HarnessConfig.resolveHarnessId(requested);
351
+ if (resolved && !harnessTargets.includes(resolved)) harnessTargets.push(resolved);
352
+ else if (!resolved) unknown.push(requested);
353
+ }
354
+ if (unknown.length > 0) {
355
+ console.error(`Unknown harness: ${unknown.join(', ')}. Run "vf config list" for supported values.`);
356
+ process.exit(1);
357
+ }
358
+ } else {
359
+ harnessTargets = HarnessConfig.detectHarnesses(cwd).map((h) => h.id);
360
+ }
361
+ const installedHarnesses = [];
362
+ for (const id of harnessTargets) {
363
+ try {
364
+ installedHarnesses.push({ id, path: HarnessConfig.installHarness(cwd, id) });
365
+ } catch (err) {
366
+ console.warn(`Warning: failed to configure ${id}: ${err.message}`);
367
+ }
368
+ }
341
369
  const agentsMdPath = join(cwd, 'AGENTS.md');
342
370
  if (!existsSync(agentsMdPath)) {
343
371
  writeFileSync(
@@ -347,6 +375,13 @@ async function main() {
347
375
  );
348
376
  }
349
377
  console.log(`Initialized VectorForce project: ${project.name} (${project.project_id})`);
378
+ if (installedHarnesses.length > 0) {
379
+ console.log(`Configured harness integration(s): ${installedHarnesses.map((h) => h.id).join(', ')}`);
380
+ console.log('For other harnesses, run "vf config list" or "vf config install <harness|all>".');
381
+ } else {
382
+ console.log('No harness detected, so no MCP configs were created.');
383
+ console.log('Run "vf config list" to see supported harnesses, then "vf config install <harness>".');
384
+ }
350
385
  break;
351
386
  }
352
387
 
@@ -551,6 +586,8 @@ async function main() {
551
586
  }
552
587
 
553
588
  case 'mcp': {
589
+ console.log = (...args) => console.error(...args);
590
+ console.info = (...args) => console.error(...args);
554
591
  const server = new McpServer({ store, projectService, checkpointService, briefingService, handoffService, reasoningService }, cwd);
555
592
  server.connect(process.stdin, process.stdout);
556
593
  process.on('SIGINT', () => {
@@ -568,57 +605,63 @@ async function main() {
568
605
  case 'config': {
569
606
  const sub = args[1];
570
607
  if (sub === 'install' || sub === 'setup') {
571
- const target = (args[2] || 'all').toLowerCase();
572
- const installed = [];
573
- if (target === 'antigravity' || target === 'all') {
574
- const p = HarnessConfig.installAntigravity(cwd);
575
- installed.push(`Google Antigravity -> ${p} (+ ~/.gemini/antigravity/mcp_config.json)`);
576
- }
577
- if (target === 'command-code' || target === 'cmd' || target === 'claude' || target === 'claude-code' || target === 'all') {
578
- const p = HarnessConfig.installCommandCode(cwd);
579
- installed.push(`Command Code / Claude Code -> .mcp.json & ${p}`);
580
- }
581
- if (target === 'muse' || target === 'muse-code' || target === 'all') {
582
- const p = HarnessConfig.installMuseCode(cwd);
583
- installed.push(`Meta Muse -> ${p} (+ ~/.config/muse/settings.json)`);
584
- }
585
- if (target === 'codex' || target === 'all') {
586
- const p = HarnessConfig.installCodex(cwd);
587
- installed.push(`Codex -> ${p} (+ ~/.codex/config.toml)`);
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)`);
608
+ const raw = (args[2] || 'all').toLowerCase();
609
+ const installNotes = {
610
+ antigravity: (p) => `Google Antigravity -> ${p} (+ global ~/.gemini MCP config when present)`,
611
+ 'command-code': (p) => `Command Code / Claude Code -> .mcp.json & ${p}`,
612
+ muse: (p) => `Meta Muse -> ${p} (+ ~/.config/muse/settings.json)`,
613
+ codex: (p) => `Codex -> ${p} (+ ~/.codex/config.toml)`,
614
+ cursor: (p) => `Cursor -> ${p} (+ .cursorrules)`,
615
+ windsurf: (p) => `Windsurf -> ${p} (+ .windsurfrules)`,
616
+ copilot: (p) => `GitHub Copilot / VS Code -> ${p} (+ .github/copilot-instructions.md)`,
617
+ kiro: (p) => `Kiro IDE -> ${p} (+ kiro.json)`
618
+ };
619
+ let targets = [];
620
+ if (raw === 'all') {
621
+ targets = HarnessConfig.getSupportedHarnesses().map((h) => h.id);
622
+ } else {
623
+ const resolved = HarnessConfig.resolveHarnessId(raw);
624
+ if (!resolved) {
625
+ console.error(`Unknown harness "${args[2]}". Run "vf config list" for supported values.`);
626
+ process.exit(1);
627
+ }
628
+ targets = [resolved];
596
629
  }
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)`);
630
+ const installed = [];
631
+ for (const id of targets) {
632
+ installed.push(installNotes[id](HarnessConfig.installHarness(cwd, id)));
604
633
  }
605
634
  console.log(`\n✔ Configured harness integration(s):\n - ${installed.join('\n - ')}`);
606
635
  console.log(`\n💡 Next step: Restart or reload your AI agent, then ask in chat:\n "List active VectorForce tasks and check workspace drift"`);
607
636
  break;
608
637
  }
609
638
 
639
+ if (sub === 'list' || sub === 'harnesses') {
640
+ const detected = new Set(HarnessConfig.detectHarnesses(cwd).map((h) => h.id));
641
+ console.log(`\nSupported AI harnesses (${cwd}):\n`);
642
+ for (const harness of HarnessConfig.getSupportedHarnesses()) {
643
+ const aliases = harness.aliases ? ` (aliases: ${harness.aliases.join(', ')})` : '';
644
+ const detectedMark = detected.has(harness.id) ? 'detected' : 'not detected';
645
+ const configuredMark = HarnessConfig.isHarnessConfigured(cwd, harness.id) ? 'configured' : 'not configured';
646
+ console.log(` ${harness.id}${aliases}: ${harness.label} [${detectedMark}] [${configuredMark}]`);
647
+ }
648
+ console.log('\nSetup one harness: vf config install <harness> (e.g. vf config install cursor)');
649
+ console.log('Setup all harnesses: vf config install all\n');
650
+ break;
651
+ }
652
+
610
653
  if (sub === 'doctor' || sub === 'check') {
611
654
  const checks = [
612
655
  { name: 'SQLite Database (.vectorforce/vectorforce.db)', ok: existsSync(getDbPath(cwd)), path: getDbPath(cwd) },
613
656
  { name: 'Agent Protocol Rules (AGENTS.md)', ok: existsSync(join(cwd, 'AGENTS.md')), path: join(cwd, 'AGENTS.md') },
614
- { name: 'Google Antigravity (.agents/mcp_config.json)', ok: existsSync(join(cwd, '.agents', 'mcp_config.json')), path: join(cwd, '.agents', 'mcp_config.json') },
615
- { name: 'Claude Code & Command Code (.mcp.json)', ok: existsSync(join(cwd, '.mcp.json')), path: join(cwd, '.mcp.json') },
616
- { name: 'Meta Muse (.muse/mcp_config.json)', ok: existsSync(join(cwd, '.muse', 'mcp_config.json')), path: join(cwd, '.muse', 'mcp_config.json') },
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') }
657
+ { name: 'Google Antigravity (.agents/mcp_config.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'antigravity'), path: join(cwd, '.agents', 'mcp_config.json') },
658
+ { name: 'Claude Code & Command Code (.mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'command-code'), path: join(cwd, '.mcp.json') },
659
+ { name: 'Meta Muse (.muse/mcp_config.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'muse'), path: join(cwd, '.muse', 'mcp_config.json') },
660
+ { name: 'OpenAI Codex (.codex/config.toml)', ok: HarnessConfig.isHarnessConfigured(cwd, 'codex'), path: join(cwd, '.codex', 'config.toml') },
661
+ { name: 'Cursor (.cursor/mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'cursor'), path: join(cwd, '.cursor', 'mcp.json') },
662
+ { name: 'Windsurf (.windsurf/mcp_config.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'windsurf'), path: join(cwd, '.windsurf', 'mcp_config.json') },
663
+ { name: 'GitHub Copilot / VS Code (.vscode/mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'copilot'), path: join(cwd, '.vscode', 'mcp.json') },
664
+ { name: 'Kiro IDE (.kiro/settings/mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'kiro'), path: join(cwd, '.kiro', 'settings', 'mcp.json') }
622
665
  ];
623
666
  console.log(`\nVectorForce Workspace & MCP Health Check (${cwd}):\n`);
624
667
  for (const c of checks) {
@@ -631,31 +674,22 @@ async function main() {
631
674
  }
632
675
 
633
676
  if (sub === 'uninstall' || sub === 'remove') {
634
- const target = (args[2] || 'all').toLowerCase();
635
- const uninstalled = [];
636
- if (target === 'antigravity' || target === 'all') {
637
- if (HarnessConfig.uninstallAntigravity(cwd)) uninstalled.push('Antigravity');
638
- }
639
- if (target === 'command-code' || target === 'cmd' || target === 'all') {
640
- if (HarnessConfig.uninstallCommandCode(cwd)) uninstalled.push('Command Code');
677
+ const raw = (args[2] || 'all').toLowerCase();
678
+ const displayNames = { antigravity: 'Antigravity', 'command-code': 'Command Code', muse: 'Muse Code', codex: 'Codex', cursor: 'Cursor', windsurf: 'Windsurf', copilot: 'GitHub Copilot / VS Code', kiro: 'Kiro IDE' };
679
+ let targets = [];
680
+ if (raw === 'all') {
681
+ targets = HarnessConfig.getSupportedHarnesses().map((h) => h.id);
682
+ } else {
683
+ const resolved = HarnessConfig.resolveHarnessId(raw);
684
+ if (!resolved) {
685
+ console.error(`Unknown harness "${args[2]}". Run "vf config list" for supported values.`);
686
+ process.exit(1);
687
+ }
688
+ targets = [resolved];
641
689
  }
642
- if (target === 'muse' || target === 'muse-code' || target === 'all') {
643
- if (HarnessConfig.uninstallMuseCode(cwd)) uninstalled.push('Muse Code');
644
- }
645
- if (target === 'codex' || target === 'all') {
646
- if (HarnessConfig.uninstallCodex(cwd)) uninstalled.push('Codex');
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');
690
+ const uninstalled = [];
691
+ for (const id of targets) {
692
+ if (HarnessConfig.uninstallHarness(cwd, id)) uninstalled.push(displayNames[id]);
659
693
  }
660
694
  console.log(`\n✔ Removed harness integration(s): ${uninstalled.length ? uninstalled.join(', ') : 'none found'}`);
661
695
  break;
@@ -879,7 +913,7 @@ VectorForce Harness Configuration:
879
913
  {
880
914
  "mcpServers": {
881
915
  "vectorforce": {
882
- "command": "node",
916
+ "command": "${process.execPath}",
883
917
  "args": ["${binPath}", "mcp"]
884
918
  }
885
919
  }
@@ -891,7 +925,7 @@ VectorForce Harness Configuration:
891
925
  {
892
926
  "mcpServers": {
893
927
  "vectorforce": {
894
- "command": "node",
928
+ "command": "${process.execPath}",
895
929
  "args": ["${binPath}", "mcp"],
896
930
  "env": { "VF_HARNESS": "muse-code" }
897
931
  }
@@ -906,7 +940,7 @@ VectorForce Harness Configuration:
906
940
  File: .codex/config.toml (or codex.json)
907
941
  Content:
908
942
  [mcp_servers.vectorforce]
909
- command = "node"
943
+ command = "${process.execPath}"
910
944
  args = ["${binPath}", "mcp"]
911
945
  [mcp_servers.vectorforce.env]
912
946
  VF_HARNESS = "codex"
@@ -943,6 +977,9 @@ VectorForce Harness Configuration:
943
977
  VF_OPENROUTER_MODEL=deepseek/deepseek-v4.1-flash-1017 # default
944
978
 
945
979
  Privacy: set VF_LLM_ALLOW_CODE=false (or run with --no-code) to keep source out of the prompt.
980
+
981
+ Harnesses: run "vf config list" to see detected/configured harnesses,
982
+ then "vf config install <harness|all>" to configure one or all of them.
946
983
  `);
947
984
  break;
948
985
  }
@@ -983,9 +1020,15 @@ VectorForce Harness Configuration:
983
1020
  const remoteProjectId = flags.project || remote.remoteProjectId || 'default';
984
1021
  const project = projectService.getProjectForWorkspace(cwd);
985
1022
  const tasks = store.listTasks(project.project_id);
986
- const machineId = `${hostname()}-local`;
1023
+ const rawHost = hostname();
1024
+ const machineId = flags.machine || (
1025
+ rawHost.toLowerCase().includes('lenovo') ? `Lenovo Laptop (${rawHost})` :
1026
+ rawHost.toLowerCase().includes('macbook') || process.platform === 'darwin' ? `MacBook Pro (${rawHost})` :
1027
+ `${rawHost} (${process.platform})`
1028
+ );
1029
+ const devIdentity = flags.dev || `${process.env.USER || 'developer'}`;
987
1030
 
988
- console.log(`🔄 Pushing local context (${project.name}) -> ${targetUrl} ...`);
1031
+ console.log(`🔄 Pushing local context (${project.name}) -> ${targetUrl} [Machine: ${machineId}] ...`);
989
1032
 
990
1033
  for (const t of tasks) {
991
1034
  if (flags.task && t.task_id !== flags.task) continue;
@@ -999,8 +1042,8 @@ VectorForce Harness Configuration:
999
1042
  projectId: remoteProjectId,
1000
1043
  taskId: t.task_id,
1001
1044
  title: t.title || t.task_id,
1002
- assignee: `${process.env.USER || 'developer'}@local-mac`,
1003
- role: `Local Workspace (${basename(cwd)})`,
1045
+ assignee: devIdentity,
1046
+ role: `Workspace (${basename(cwd)})`,
1004
1047
  priority: 'P0',
1005
1048
  machineId,
1006
1049
  harness: flags.harness || 'antigravity'
@@ -1025,13 +1068,17 @@ VectorForce Harness Configuration:
1025
1068
  taskId: cp.task_id,
1026
1069
  senderMachineId: machineId,
1027
1070
  recipientMachineId: 'computer-2-meta-muse-cloud',
1028
- authorName: `${cp.author?.name || process.env.USER || 'developer'} (${basename(cwd)})`,
1029
- authorHarness: cp.author?.harness || 'antigravity',
1071
+ authorName: `${cp.author?.name || devIdentity} (${basename(cwd)})`,
1072
+ authorHarness: cp.author?.harness || flags.harness || 'antigravity',
1030
1073
  summary: cp.summary,
1031
1074
  goals: cp.claims?.goals || [],
1032
1075
  constraints: cp.claims?.constraints || [],
1033
1076
  decisions: cp.claims?.decisions || [],
1034
- nextSteps: cp.claims?.next_steps || []
1077
+ nextSteps: cp.claims?.next_steps || [],
1078
+ gitCommit: cp.evidence?.git?.commit || null,
1079
+ gitBranch: cp.evidence?.git?.branch || 'main',
1080
+ gitDirty: cp.evidence?.git?.dirty !== undefined ? Boolean(cp.evidence.git.dirty) : false,
1081
+ documents: (cp.evidence?.documents || []).map((d) => d.path)
1035
1082
  })
1036
1083
  });
1037
1084
  lastResp = await res.json();
@@ -1134,14 +1181,14 @@ VectorForce Harness Configuration:
1134
1181
  const checks = [
1135
1182
  { name: 'SQLite Database (.vectorforce/vectorforce.db)', ok: existsSync(getDbPath(cwd)) },
1136
1183
  { name: 'Agent Protocol Rules (AGENTS.md)', ok: existsSync(join(cwd, 'AGENTS.md')) },
1137
- { name: 'Google Antigravity (.agents/mcp_config.json)', ok: existsSync(join(cwd, '.agents', 'mcp_config.json')) },
1138
- { name: 'Claude Code & Command Code (.mcp.json)', ok: existsSync(join(cwd, '.mcp.json')) },
1139
- { name: 'Meta Muse (.muse/mcp_config.json or musecode.json)', ok: existsSync(join(cwd, '.muse', 'mcp_config.json')) || existsSync(join(cwd, 'musecode.json')) },
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')) }
1184
+ { name: 'Google Antigravity (.agents/mcp_config.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'antigravity') },
1185
+ { name: 'Claude Code & Command Code (.mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'command-code') },
1186
+ { name: 'Meta Muse (.muse/mcp_config.json or musecode.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'muse') },
1187
+ { name: 'OpenAI Codex (.codex/config.toml)', ok: HarnessConfig.isHarnessConfigured(cwd, 'codex') },
1188
+ { name: 'Cursor (.cursor/mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'cursor') },
1189
+ { name: 'Windsurf (.windsurf/mcp_config.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'windsurf') },
1190
+ { name: 'GitHub Copilot / VS Code (.vscode/mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'copilot') },
1191
+ { name: 'Kiro IDE (.kiro/settings/mcp.json)', ok: HarnessConfig.isHarnessConfigured(cwd, 'kiro') }
1145
1192
  ];
1146
1193
  console.log(`\nVectorForce Workspace & MCP Status (${cwd}):\n`);
1147
1194
  for (const c of checks) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vectorforce",
3
- "version": "0.3.3",
3
+ "version": "0.3.7",
4
4
  "description": "Portable engineering context platform - Git for AI context",
5
5
  "type": "module",
6
6
  "main": "src/index.js",