@whenlabs/when 0.7.3 → 0.8.1
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/dist/{chunk-FJBDHGXG.js → chunk-3PDLNC63.js} +55 -20
- package/dist/index.js +2 -2
- package/dist/{install-O4QZ3TA4.js → install-HPF26YW2.js} +3 -3
- package/dist/mcp.js +26 -1
- package/dist/{uninstall-5LRMB2EV.js → uninstall-X5NO3Z6I.js} +1 -1
- package/package.json +2 -2
- package/dist/index.d.ts +0 -2
- package/dist/mcp.d.ts +0 -2
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
// src/utils/mcp-config.ts
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
6
|
+
import { resolve } from "path";
|
|
5
7
|
function registerServer(name, command) {
|
|
8
|
+
try {
|
|
9
|
+
execSync(`claude mcp remove -s user ${name}`, { stdio: "pipe" });
|
|
10
|
+
} catch {
|
|
11
|
+
}
|
|
6
12
|
try {
|
|
7
13
|
execSync(`claude mcp add -s user ${name} -- ${command}`, { stdio: "pipe" });
|
|
8
|
-
return { success: true, message: `MCP server "${name}" registered
|
|
14
|
+
return { success: true, message: `MCP server "${name}" registered.` };
|
|
9
15
|
} catch (err) {
|
|
10
16
|
const output = err instanceof Error && "stderr" in err ? err.stderr?.toString() ?? "" : "";
|
|
11
|
-
if (output.includes("already exists") || output.includes("already registered")) {
|
|
12
|
-
return { success: true, message: `MCP server "${name}" is already registered.` };
|
|
13
|
-
}
|
|
14
17
|
return {
|
|
15
18
|
success: false,
|
|
16
19
|
message: `Failed to register "${name}": ${output || (err instanceof Error ? err.message : String(err))}`
|
|
@@ -32,27 +35,59 @@ function unregisterServer(name) {
|
|
|
32
35
|
};
|
|
33
36
|
}
|
|
34
37
|
}
|
|
38
|
+
function cleanLegacyMcpJson() {
|
|
39
|
+
let dir = process.cwd();
|
|
40
|
+
const root = resolve("/");
|
|
41
|
+
while (dir !== root) {
|
|
42
|
+
const mcpJson = resolve(dir, ".mcp.json");
|
|
43
|
+
if (existsSync(mcpJson)) {
|
|
44
|
+
try {
|
|
45
|
+
const data = JSON.parse(readFileSync(mcpJson, "utf-8"));
|
|
46
|
+
if (data?.mcpServers?.["velocity-mcp"]) {
|
|
47
|
+
delete data.mcpServers["velocity-mcp"];
|
|
48
|
+
writeFileSync(mcpJson, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
49
|
+
return mcpJson;
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
dir = resolve(dir, "..");
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
35
58
|
function registerMcpServer() {
|
|
36
|
-
const velocity = registerServer("velocity-mcp", "npx @whenlabs/velocity-mcp");
|
|
37
59
|
const whenlabs = registerServer("whenlabs", "npx @whenlabs/when when-mcp");
|
|
60
|
+
const legacyCleanup = unregisterServer("velocity-mcp");
|
|
61
|
+
const cleanedFile = cleanLegacyMcpJson();
|
|
62
|
+
const messages = [whenlabs.message];
|
|
63
|
+
if (legacyCleanup.success && !legacyCleanup.message.includes("was not registered")) {
|
|
64
|
+
messages.push("Removed legacy velocity-mcp from user config (now bundled in whenlabs)");
|
|
65
|
+
}
|
|
66
|
+
if (cleanedFile) {
|
|
67
|
+
messages.push(`Removed legacy velocity-mcp from ${cleanedFile}`);
|
|
68
|
+
}
|
|
38
69
|
return {
|
|
39
|
-
success:
|
|
40
|
-
message:
|
|
70
|
+
success: whenlabs.success,
|
|
71
|
+
message: messages.join("\n ")
|
|
41
72
|
};
|
|
42
73
|
}
|
|
43
74
|
function unregisterMcpServer() {
|
|
44
|
-
const velocity = unregisterServer("velocity-mcp");
|
|
45
75
|
const whenlabs = unregisterServer("whenlabs");
|
|
76
|
+
const velocity = unregisterServer("velocity-mcp");
|
|
77
|
+
const messages = [whenlabs.message];
|
|
78
|
+
if (velocity.success && !velocity.message.includes("was not registered")) {
|
|
79
|
+
messages.push(velocity.message);
|
|
80
|
+
}
|
|
46
81
|
return {
|
|
47
|
-
success:
|
|
48
|
-
message:
|
|
82
|
+
success: whenlabs.success,
|
|
83
|
+
message: messages.join("\n ")
|
|
49
84
|
};
|
|
50
85
|
}
|
|
51
86
|
|
|
52
87
|
// src/utils/editor-config.ts
|
|
53
88
|
import { join } from "path";
|
|
54
89
|
import { homedir } from "os";
|
|
55
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
90
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync } from "fs";
|
|
56
91
|
var MCP_SERVERS = {
|
|
57
92
|
"velocity-mcp": { command: "npx", args: ["@whenlabs/velocity-mcp"] },
|
|
58
93
|
whenlabs: { command: "when-mcp", args: [] }
|
|
@@ -69,16 +104,16 @@ function getConfigPath(editor) {
|
|
|
69
104
|
}
|
|
70
105
|
}
|
|
71
106
|
function readJsonFile(filePath) {
|
|
72
|
-
if (!
|
|
107
|
+
if (!existsSync2(filePath)) return {};
|
|
73
108
|
try {
|
|
74
|
-
return JSON.parse(
|
|
109
|
+
return JSON.parse(readFileSync2(filePath, "utf-8"));
|
|
75
110
|
} catch {
|
|
76
111
|
return {};
|
|
77
112
|
}
|
|
78
113
|
}
|
|
79
114
|
function ensureDir(filePath) {
|
|
80
115
|
const dir = filePath.substring(0, filePath.lastIndexOf("/"));
|
|
81
|
-
if (!
|
|
116
|
+
if (!existsSync2(dir)) {
|
|
82
117
|
mkdirSync(dir, { recursive: true });
|
|
83
118
|
}
|
|
84
119
|
}
|
|
@@ -94,7 +129,7 @@ function installCursorOrWindsurf(editor) {
|
|
|
94
129
|
}
|
|
95
130
|
};
|
|
96
131
|
ensureDir(configPath);
|
|
97
|
-
|
|
132
|
+
writeFileSync2(configPath, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
98
133
|
return { editor, success: true, message: `${capitalize(editor)}: MCP servers registered at ${configPath}` };
|
|
99
134
|
}
|
|
100
135
|
function installVSCode() {
|
|
@@ -113,12 +148,12 @@ function installVSCode() {
|
|
|
113
148
|
}
|
|
114
149
|
};
|
|
115
150
|
ensureDir(configPath);
|
|
116
|
-
|
|
151
|
+
writeFileSync2(configPath, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
117
152
|
return { editor: "vscode", success: true, message: `VS Code: MCP servers registered at ${configPath}` };
|
|
118
153
|
}
|
|
119
154
|
function uninstallCursorOrWindsurf(editor) {
|
|
120
155
|
const configPath = getConfigPath(editor);
|
|
121
|
-
if (!
|
|
156
|
+
if (!existsSync2(configPath)) {
|
|
122
157
|
return { editor, success: true, message: `${capitalize(editor)}: config not found, nothing to remove` };
|
|
123
158
|
}
|
|
124
159
|
const existing = readJsonFile(configPath);
|
|
@@ -127,12 +162,12 @@ function uninstallCursorOrWindsurf(editor) {
|
|
|
127
162
|
delete mcpServers[key];
|
|
128
163
|
}
|
|
129
164
|
const updated = { ...existing, mcpServers };
|
|
130
|
-
|
|
165
|
+
writeFileSync2(configPath, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
131
166
|
return { editor, success: true, message: `${capitalize(editor)}: MCP servers removed from ${configPath}` };
|
|
132
167
|
}
|
|
133
168
|
function uninstallVSCode() {
|
|
134
169
|
const configPath = getConfigPath("vscode");
|
|
135
|
-
if (!
|
|
170
|
+
if (!existsSync2(configPath)) {
|
|
136
171
|
return { editor: "vscode", success: true, message: "VS Code: config not found, nothing to remove" };
|
|
137
172
|
}
|
|
138
173
|
const existing = readJsonFile(configPath);
|
|
@@ -145,7 +180,7 @@ function uninstallVSCode() {
|
|
|
145
180
|
...existing,
|
|
146
181
|
mcp: { ...mcpSection, servers }
|
|
147
182
|
};
|
|
148
|
-
|
|
183
|
+
writeFileSync2(configPath, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
149
184
|
return { editor: "vscode", success: true, message: `VS Code: MCP servers removed from ${configPath}` };
|
|
150
185
|
}
|
|
151
186
|
function capitalize(s) {
|
package/dist/index.js
CHANGED
|
@@ -495,11 +495,11 @@ function createInitCommand() {
|
|
|
495
495
|
var program = new Command4();
|
|
496
496
|
program.name("when").version("0.1.0").description("The WhenLabs developer toolkit \u2014 6 tools, one install");
|
|
497
497
|
program.command("install").description("Install all WhenLabs tools globally (MCP server + CLAUDE.md instructions)").option("--cursor", "Install MCP servers into Cursor (~/.cursor/mcp.json)").option("--vscode", "Install MCP servers into VS Code (settings.json)").option("--windsurf", "Install MCP servers into Windsurf (~/.codeium/windsurf/mcp_config.json)").option("--all", "Install MCP servers into all supported editors").action(async (options) => {
|
|
498
|
-
const { install } = await import("./install-
|
|
498
|
+
const { install } = await import("./install-HPF26YW2.js");
|
|
499
499
|
await install(options);
|
|
500
500
|
});
|
|
501
501
|
program.command("uninstall").description("Remove all WhenLabs tools").option("--cursor", "Remove MCP servers from Cursor").option("--vscode", "Remove MCP servers from VS Code").option("--windsurf", "Remove MCP servers from Windsurf").option("--all", "Remove MCP servers from all supported editors").action(async (options) => {
|
|
502
|
-
const { uninstall } = await import("./uninstall-
|
|
502
|
+
const { uninstall } = await import("./uninstall-X5NO3Z6I.js");
|
|
503
503
|
await uninstall(options);
|
|
504
504
|
});
|
|
505
505
|
program.command("status").description("Show installation status and velocity stats").action(async () => {
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ALL_EDITORS,
|
|
4
4
|
installForEditor,
|
|
5
5
|
registerMcpServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3PDLNC63.js";
|
|
7
7
|
import {
|
|
8
8
|
injectBlock
|
|
9
9
|
} from "./chunk-NYUYV3UL.js";
|
|
@@ -19,7 +19,7 @@ var CLAUDE_MD_CONTENT = `# WhenLabs Toolkit
|
|
|
19
19
|
|
|
20
20
|
## Task Timing (velocity-mcp)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Velocity tools are part of the unified \`whenlabs\` MCP server. Follow these rules for EVERY session:
|
|
23
23
|
|
|
24
24
|
1. **Before starting any discrete coding task**, call \`velocity_start_task\` with:
|
|
25
25
|
- Appropriate \`category\` (scaffold, implement, refactor, debug, test, config, docs, deploy)
|
|
@@ -46,7 +46,7 @@ You have access to \`velocity-mcp\` tools. Follow these rules for EVERY session:
|
|
|
46
46
|
|
|
47
47
|
## WhenLabs MCP Tools (ALWAYS prefer these over shell commands)
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
All six tools (including velocity) are available through the unified \`whenlabs\` MCP server. **ALWAYS use these MCP tools instead of running shell commands like lsof, grep, or manual checks.** These tools are purpose-built and give better results:
|
|
50
50
|
|
|
51
51
|
| When to use | Call this tool | NOT this |
|
|
52
52
|
|-------------|---------------|----------|
|
package/dist/mcp.js
CHANGED
|
@@ -9,6 +9,15 @@ import { resolve, dirname, join } from "path";
|
|
|
9
9
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
11
|
import { homedir } from "os";
|
|
12
|
+
import {
|
|
13
|
+
initDb,
|
|
14
|
+
TaskQueries,
|
|
15
|
+
registerStartTask,
|
|
16
|
+
registerEndTask,
|
|
17
|
+
registerEstimate,
|
|
18
|
+
registerStats,
|
|
19
|
+
registerHistory
|
|
20
|
+
} from "@whenlabs/velocity-mcp/lib";
|
|
12
21
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
22
|
function findBin(name) {
|
|
14
23
|
const pkgRoot = resolve(__dirname, "..");
|
|
@@ -91,8 +100,16 @@ Note: Conflicts found in project "${projectName}".`);
|
|
|
91
100
|
}
|
|
92
101
|
var server = new McpServer({
|
|
93
102
|
name: "whenlabs",
|
|
94
|
-
version: "0.
|
|
103
|
+
version: "0.2.0"
|
|
95
104
|
});
|
|
105
|
+
var velocityDb = initDb();
|
|
106
|
+
var velocityQueries = new TaskQueries(velocityDb);
|
|
107
|
+
var s = server;
|
|
108
|
+
registerStartTask(s, velocityQueries);
|
|
109
|
+
registerEndTask(s, velocityQueries);
|
|
110
|
+
registerEstimate(s, velocityQueries);
|
|
111
|
+
registerStats(s, velocityQueries);
|
|
112
|
+
registerHistory(s, velocityQueries);
|
|
96
113
|
function formatOutput(result) {
|
|
97
114
|
const parts = [];
|
|
98
115
|
if (result.stdout.trim()) parts.push(result.stdout.trim());
|
|
@@ -580,6 +597,14 @@ server.tool(
|
|
|
580
597
|
return { content: [{ type: "text", text: outputText }] };
|
|
581
598
|
}
|
|
582
599
|
);
|
|
600
|
+
process.on("SIGINT", () => {
|
|
601
|
+
velocityDb.close();
|
|
602
|
+
process.exit(0);
|
|
603
|
+
});
|
|
604
|
+
process.on("SIGTERM", () => {
|
|
605
|
+
velocityDb.close();
|
|
606
|
+
process.exit(0);
|
|
607
|
+
});
|
|
583
608
|
async function main() {
|
|
584
609
|
const transport = new StdioServerTransport();
|
|
585
610
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whenlabs/when",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "The WhenLabs developer toolkit — 6 tools, one install",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@whenlabs/berth": "^0.1.0",
|
|
34
34
|
"@whenlabs/envalid": "^0.1.2",
|
|
35
35
|
"@whenlabs/stale": "^0.1.0",
|
|
36
|
-
"@whenlabs/velocity-mcp": "^0.1.
|
|
36
|
+
"@whenlabs/velocity-mcp": "^0.1.2",
|
|
37
37
|
"@whenlabs/vow": "^0.1.3",
|
|
38
38
|
"commander": "^12.0.0",
|
|
39
39
|
"zod": "^4.3.6"
|
package/dist/index.d.ts
DELETED
package/dist/mcp.d.ts
DELETED