@whenlabs/when 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,19 +33,27 @@ function unregisterServer(name) {
33
33
  }
34
34
  }
35
35
  function registerMcpServer() {
36
- const velocity = registerServer("velocity-mcp", "npx @whenlabs/velocity-mcp");
37
36
  const whenlabs = registerServer("whenlabs", "npx @whenlabs/when when-mcp");
37
+ const legacyCleanup = unregisterServer("velocity-mcp");
38
+ const messages = [whenlabs.message];
39
+ if (legacyCleanup.success && !legacyCleanup.message.includes("was not registered")) {
40
+ messages.push("Removed legacy standalone velocity-mcp (now bundled in whenlabs)");
41
+ }
38
42
  return {
39
- success: velocity.success && whenlabs.success,
40
- message: [velocity.message, whenlabs.message].join("\n ")
43
+ success: whenlabs.success,
44
+ message: messages.join("\n ")
41
45
  };
42
46
  }
43
47
  function unregisterMcpServer() {
44
- const velocity = unregisterServer("velocity-mcp");
45
48
  const whenlabs = unregisterServer("whenlabs");
49
+ const velocity = unregisterServer("velocity-mcp");
50
+ const messages = [whenlabs.message];
51
+ if (velocity.success && !velocity.message.includes("was not registered")) {
52
+ messages.push(velocity.message);
53
+ }
46
54
  return {
47
- success: velocity.success && whenlabs.success,
48
- message: [velocity.message, whenlabs.message].join("\n ")
55
+ success: whenlabs.success,
56
+ message: messages.join("\n ")
49
57
  };
50
58
  }
51
59
 
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-O4QZ3TA4.js");
498
+ const { install } = await import("./install-JRDDTX6Y.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-5LRMB2EV.js");
502
+ const { uninstall } = await import("./uninstall-QQ2Y3AQ3.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-FJBDHGXG.js";
6
+ } from "./chunk-2Y7YZAIR.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
- You have access to \`velocity-mcp\` tools. Follow these rules for EVERY session:
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
- You have access to the \`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:
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.1.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());
@@ -104,8 +121,8 @@ server.tool(
104
121
  "Scan for documentation drift \u2014 detect when docs say one thing and code says another",
105
122
  {
106
123
  path: z.string().optional().describe("Project directory to scan (defaults to cwd)"),
107
- deep: z.boolean().optional().describe("Enable AI-powered deep analysis"),
108
- git: z.boolean().optional().describe("Enable git history staleness checks"),
124
+ deep: z.coerce.boolean().optional().describe("Enable AI-powered deep analysis"),
125
+ git: z.coerce.boolean().optional().describe("Enable git history staleness checks"),
109
126
  format: z.enum(["terminal", "json", "markdown", "sarif"]).optional().describe("Output format")
110
127
  },
111
128
  async ({ path, deep, git, format }) => {
@@ -171,7 +188,7 @@ server.tool(
171
188
  "Generate .env.schema from an existing .env file \u2014 bootstrap type-safe env validation",
172
189
  {
173
190
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
174
- force: z.boolean().optional().describe("Overwrite existing schema")
191
+ force: z.coerce.boolean().optional().describe("Overwrite existing schema")
175
192
  },
176
193
  async ({ path, force }) => {
177
194
  const args = ["init"];
@@ -284,8 +301,8 @@ server.tool(
284
301
  "berth_kill",
285
302
  "Kill processes on a specific port \u2014 free up a port for your dev server",
286
303
  {
287
- port: z.number().optional().describe("Port number to free"),
288
- dev: z.boolean().optional().describe("Kill all dev processes (node, python, ruby, etc.)")
304
+ port: z.coerce.number().optional().describe("Port number to free"),
305
+ dev: z.coerce.boolean().optional().describe("Kill all dev processes (node, python, ruby, etc.)")
289
306
  },
290
307
  async ({ port, dev }) => {
291
308
  const args = ["kill"];
@@ -352,7 +369,7 @@ server.tool(
352
369
  "Auto-resolve all port conflicts and prepare a project to start cleanly",
353
370
  {
354
371
  project: z.string().describe("Registered project name"),
355
- dryRun: z.boolean().optional().describe("Show what would be done without making changes")
372
+ dryRun: z.coerce.boolean().optional().describe("Show what would be done without making changes")
356
373
  },
357
374
  async ({ project, dryRun }) => {
358
375
  const args = ["start", project];
@@ -378,7 +395,7 @@ server.tool(
378
395
  {
379
396
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
380
397
  targets: z.string().optional().describe("Comma-separated targets: claude,cursor,copilot,agents,all"),
381
- force: z.boolean().optional().describe("Overwrite existing files without prompting")
398
+ force: z.coerce.boolean().optional().describe("Overwrite existing files without prompting")
382
399
  },
383
400
  async ({ path, targets, force }) => {
384
401
  const args = ["init"];
@@ -396,7 +413,7 @@ server.tool(
396
413
  "Regenerate AI context files from .aware.json \u2014 update CLAUDE.md, .cursorrules, etc.",
397
414
  {
398
415
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
399
- dryRun: z.boolean().optional().describe("Show what would change without writing files")
416
+ dryRun: z.coerce.boolean().optional().describe("Show what would change without writing files")
400
417
  },
401
418
  async ({ path, dryRun }) => {
402
419
  const args = ["sync"];
@@ -458,7 +475,7 @@ server.tool(
458
475
  "Scan dependency licenses \u2014 summarize all licenses in the project",
459
476
  {
460
477
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
461
- production: z.boolean().optional().describe("Skip devDependencies"),
478
+ production: z.coerce.boolean().optional().describe("Skip devDependencies"),
462
479
  format: z.enum(["terminal", "json"]).optional().describe("Output format")
463
480
  },
464
481
  async ({ path, production, format }) => {
@@ -477,7 +494,7 @@ server.tool(
477
494
  "Validate dependency licenses against policy \u2014 flag violations before release",
478
495
  {
479
496
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
480
- production: z.boolean().optional().describe("Skip devDependencies")
497
+ production: z.coerce.boolean().optional().describe("Skip devDependencies")
481
498
  },
482
499
  async ({ path, production }) => {
483
500
  const args = ["check"];
@@ -510,8 +527,8 @@ server.tool(
510
527
  {
511
528
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
512
529
  filter: z.string().optional().describe('Show only subtrees containing this license (e.g. "GPL")'),
513
- depth: z.number().optional().describe("Max tree depth"),
514
- production: z.boolean().optional().describe("Skip devDependencies")
530
+ depth: z.coerce.number().optional().describe("Max tree depth"),
531
+ production: z.coerce.boolean().optional().describe("Skip devDependencies")
515
532
  },
516
533
  async ({ path, filter, depth, production }) => {
517
534
  const args = ["tree"];
@@ -529,8 +546,8 @@ server.tool(
529
546
  "Suggest alternative packages for license policy violations \u2014 find compliant replacements",
530
547
  {
531
548
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
532
- production: z.boolean().optional().describe("Skip devDependencies"),
533
- limit: z.number().optional().describe("Max alternatives per package")
549
+ production: z.coerce.boolean().optional().describe("Skip devDependencies"),
550
+ limit: z.coerce.number().optional().describe("Max alternatives per package")
534
551
  },
535
552
  async ({ path, production, limit }) => {
536
553
  const args = ["fix"];
@@ -549,7 +566,7 @@ server.tool(
549
566
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
550
567
  format: z.enum(["json", "csv", "markdown"]).optional().describe("Export format (default: json)"),
551
568
  output: z.string().optional().describe("Output file path"),
552
- production: z.boolean().optional().describe("Skip devDependencies")
569
+ production: z.coerce.boolean().optional().describe("Skip devDependencies")
553
570
  },
554
571
  async ({ path, format, output, production }) => {
555
572
  const args = ["export"];
@@ -568,7 +585,7 @@ server.tool(
568
585
  {
569
586
  path: z.string().optional().describe("Project directory (defaults to cwd)"),
570
587
  output: z.string().optional().describe("Output file (default: THIRD_PARTY_LICENSES.md)"),
571
- production: z.boolean().optional().describe("Skip devDependencies")
588
+ production: z.coerce.boolean().optional().describe("Skip devDependencies")
572
589
  },
573
590
  async ({ path, output, production }) => {
574
591
  const args = ["attribution"];
@@ -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);
@@ -3,7 +3,7 @@ import {
3
3
  ALL_EDITORS,
4
4
  uninstallForEditor,
5
5
  unregisterMcpServer
6
- } from "./chunk-FJBDHGXG.js";
6
+ } from "./chunk-2Y7YZAIR.js";
7
7
  import {
8
8
  removeBlock
9
9
  } from "./chunk-NYUYV3UL.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whenlabs/when",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "The WhenLabs developer toolkit — 6 tools, one install",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -29,12 +29,12 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@modelcontextprotocol/sdk": "^1.29.0",
32
- "@whenlabs/aware": "^0.1.0",
32
+ "@whenlabs/aware": "^0.1.2",
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.0",
37
- "@whenlabs/vow": "^0.1.0",
36
+ "@whenlabs/velocity-mcp": "^0.1.2",
37
+ "@whenlabs/vow": "^0.1.3",
38
38
  "commander": "^12.0.0",
39
39
  "zod": "^4.3.6"
40
40
  },
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
-
2
- export { }
package/dist/mcp.d.ts DELETED
@@ -1,2 +0,0 @@
1
-
2
- export { }