@vpxa/aikit 0.1.355 → 0.1.357

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.355",
3
+ "version": "0.1.357",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -122,7 +122,7 @@
122
122
  },
123
123
  "scripts": {
124
124
  "postinstall": "node ./bin/postinstall-managed-launcher.mjs",
125
- "build": "node scripts/build.mjs",
125
+ "build": "node scripts/build.mjs && node packages/claude-desktop/scripts/build-mcpb.mjs",
126
126
  "typecheck": "tsc -b tsconfig.build.json --emitDeclarationOnly",
127
127
  "clean": "turbo run clean && rimraf --glob node_modules \"packages/*/node_modules\"",
128
128
  "lint": "biome check .",
@@ -141,6 +141,7 @@
141
141
  "release": "node scripts/release.mjs",
142
142
  "release:dry": "node scripts/release.mjs --dry-run",
143
143
  "nodeprune": "pnpm -s dlx npkill -D -y && pnpm store prune && pnpm clean",
144
+ "build:mcpb": "node packages/claude-desktop/scripts/build-mcpb.mjs",
144
145
  "test:watch": "vitest",
145
146
  "validate": "pnpm build && pnpm test && pnpm lint:fix && pnpm typecheck"
146
147
  }
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED — pipe relay for AI Kit MCP server.
3
+ //
4
+ // Resolves the managed install path (~/.aikit/current-version.json)
5
+ // and spawns the server with stdio pipes for GUI-host compatibility.
6
+ //
7
+ import { spawn } from 'node:child_process';
8
+ import { existsSync, readFileSync } from 'node:fs';
9
+ import { homedir } from 'node:os';
10
+ import { delimiter, join } from 'node:path';
11
+
12
+ const VERSION_FILE = join(homedir(), '.aikit', 'current-version.json');
13
+
14
+ function getServerPath() {
15
+ if (!existsSync(VERSION_FILE)) return null;
16
+ try {
17
+ const { version } = JSON.parse(readFileSync(VERSION_FILE, 'utf-8'));
18
+ const p = join(homedir(), '.aikit', 'versions', 'v' + version, 'packages', 'server', 'dist', 'bin.js');
19
+ return existsSync(p) ? p : null;
20
+ } catch { return null; }
21
+ }
22
+
23
+ function findNodeOnPath() {
24
+ const names = process.platform === 'win32' ? ['node.exe', 'node'] : ['node'];
25
+ for (const dir of (process.env.PATH || '').split(delimiter)) {
26
+ if (!dir) continue;
27
+ for (const name of names) {
28
+ const candidate = join(dir, name);
29
+ if (existsSync(candidate)) return candidate;
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+
35
+ function getNodePath() {
36
+ const candidates = [
37
+ process.env.AIKIT_NODE_PATH,
38
+ findNodeOnPath(),
39
+ process.platform === 'win32' ? 'C:\\nvm4w\\nodejs\\node.exe' : null,
40
+ process.platform === 'win32' ? 'C:\\Program Files\\nodejs\\node.exe' : null,
41
+ process.platform === 'win32' ? join(process.env.LOCALAPPDATA || '', 'Programs', 'nodejs', 'node.exe') : null,
42
+ process.execPath,
43
+ ];
44
+ for (const candidate of candidates) {
45
+ if (candidate && existsSync(candidate)) return candidate;
46
+ }
47
+ return process.execPath;
48
+ }
49
+
50
+ const serverPath = getServerPath();
51
+ if (!serverPath) {
52
+ process.stderr.write('AI Kit not found. Install: npx @vpxa/aikit install\n');
53
+ process.exit(1);
54
+ }
55
+ const nodePath = getNodePath();
56
+
57
+ // Spawn with pipe mode for GUI host compatibility
58
+ const child = spawn(nodePath, [serverPath, 'serve'], {
59
+ stdio: ['pipe', 'pipe', 'pipe'],
60
+ env: process.env,
61
+ });
62
+
63
+ // Relay stdin/stderr between host and server
64
+ process.stdin.on('data', (chunk) => {
65
+ if (!child.stdin.destroyed && !child.stdin.writableEnded) child.stdin.write(chunk);
66
+ });
67
+ process.stdin.on('end', () => {
68
+ if (!child.stdin.destroyed && !child.stdin.writableEnded) child.stdin.end();
69
+ });
70
+ child.stderr.pipe(process.stderr);
71
+ child.stdin.on('error', (err) => {
72
+ if (err?.code !== 'EPIPE' && err?.code !== 'ERR_STREAM_WRITE_AFTER_END') {
73
+ process.stderr.write('aikit stdin: ' + err.message + '\n');
74
+ }
75
+ });
76
+
77
+ let childStdoutBuffer = '';
78
+ function sendToChild(message) {
79
+ if (!child.stdin.destroyed && !child.stdin.writableEnded) {
80
+ child.stdin.write(JSON.stringify(message) + '\n');
81
+ }
82
+ }
83
+
84
+ // Claude Desktop can close .mcpb transports if the server asks roots/list
85
+ // before initialize completes. Answer that bootstrap request inside the
86
+ // relay and let AI Kit use its existing configured-root/cwd fallback.
87
+ child.stdout.setEncoding('utf8');
88
+ child.stdout.on('data', (chunk) => {
89
+ childStdoutBuffer += chunk;
90
+ for (;;) {
91
+ const newline = childStdoutBuffer.indexOf('\n');
92
+ if (newline < 0) break;
93
+ const line = childStdoutBuffer.slice(0, newline);
94
+ childStdoutBuffer = childStdoutBuffer.slice(newline + 1);
95
+ const trimmed = line.trim();
96
+ if (!trimmed) { process.stdout.write(line + '\n'); continue; }
97
+ try {
98
+ const message = JSON.parse(trimmed);
99
+ if (message?.method === 'roots/list' && message.id !== undefined) {
100
+ sendToChild({ jsonrpc: '2.0', id: message.id, result: { roots: [] } });
101
+ continue;
102
+ }
103
+ } catch {}
104
+ process.stdout.write(line + '\n');
105
+ }
106
+ });
107
+ child.stdout.on('end', () => {
108
+ if (childStdoutBuffer) process.stdout.write(childStdoutBuffer);
109
+ });
110
+
111
+ child.once('error', (err) => {
112
+ process.stderr.write('aikit: ' + err.message + '\n');
113
+ process.exit(1);
114
+ });
115
+ child.once('exit', (code, signal) => {
116
+ process.exit(signal === 'SIGINT' ? 130 : signal === 'SIGTERM' ? 143 : code ?? 1);
117
+ });
118
+ for (const sig of ['SIGINT', 'SIGTERM']) {
119
+ process.once(sig, () => { if (!child.killed) child.kill(sig); });
120
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@vpxa/aikit-claude-desktop",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "description": "AI Kit MCP Bundle for Claude Desktop — one-click .mcpb install",
7
+ "scripts": {
8
+ "build:mcpb": "node scripts/build-mcpb.mjs",
9
+ "clean": "rimraf dist *.mcpb"
10
+ }
11
+ }