@planu/cli 4.3.15 → 4.3.16

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/index.js CHANGED
@@ -33,8 +33,9 @@ if (firstArg && KNOWN_COMMANDS.includes(firstArg)) {
33
33
  process.exit(0);
34
34
  }
35
35
  // Minimal static imports — only what createMcpServer() needs at module load time.
36
- // Everything else is dynamically imported to keep the module evaluation fast and
37
- // let initialize respond before the heavy tool graph loads.
36
+ // The official tool surface is registered in main() before transport connection
37
+ // so the first MCP tools/list response is complete for hosts that ignore
38
+ // notifications/tools/list_changed.
38
39
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
39
40
  import { SERVER_INSTRUCTIONS } from './config/server-instructions.js';
40
41
  import { PLANU_VERSION } from './config/version.js';
@@ -44,13 +45,10 @@ function createMcpServer() {
44
45
  instructions: SERVER_INSTRUCTIONS,
45
46
  capabilities: { tools: {}, resources: {}, prompts: {} },
46
47
  }));
47
- // Pre-initialize tool/resource/prompt request handlers BEFORE transport connects.
48
+ // Pre-initialize resource/prompt request handlers BEFORE transport connects.
48
49
  // McpServer calls registerCapabilities + sets up list/call handlers only on the
49
50
  // FIRST invocation of each surface. After this, later registrations only update
50
51
  // in-memory registries — safe to call even after transport connects.
51
- s.registerTool('_planu_boot', { description: 'Planu is starting…', inputSchema: {} }, () => ({
52
- content: [],
53
- }));
54
52
  s.registerResource('_planu_boot', '_planu://boot', {}, () => ({ contents: [] }));
55
53
  s.registerPrompt('_planu_boot', { title: 'Planu Boot', description: 'Internal prompt handler bootstrap', argsSchema: {} }, () => ({
56
54
  messages: [],
@@ -59,13 +57,13 @@ function createMcpServer() {
59
57
  }
60
58
  // Primary server instance — created immediately at module load with minimal deps.
61
59
  const server = createMcpServer();
62
- // Loads all modules and registers tools after the MCP handshake has completed.
60
+ // Loads post-handshake modules after the MCP handshake has completed.
63
61
  // Separated from main() to keep main() within the 80-line function budget.
64
- async function setupPostHandshake(handshakeGate) {
62
+ async function setupPostHandshake(handshakeGate, officialToolNames) {
65
63
  // Wait for initialize + notifications/initialized before firing any notifications.
66
64
  await handshakeGate;
67
65
  const envKey = process.env.SDD_LICENSE_KEY;
68
- const [{ bootstrapAutopilotHandlers }, { registerAgentSquadHandlers }, { startupSync }, { checkForUpdates }, { setConnectedClient }, { handleActivateLicense }, { GroupManager }, { setGroupManager }, { registerSddTools, OFFICIAL_SDD_TOOL_NAMES },] = await Promise.all([
66
+ const [{ bootstrapAutopilotHandlers }, { registerAgentSquadHandlers }, { startupSync }, { checkForUpdates }, { setConnectedClient }, { handleActivateLicense }, { GroupManager }, { setGroupManager },] = await Promise.all([
69
67
  import('./engine/autopilot/bootstrap.js'),
70
68
  import('./tools/register-agent-squad-tools.js'),
71
69
  import('./tools/sync-spec-state-handler.js'),
@@ -74,7 +72,6 @@ async function setupPostHandshake(handshakeGate) {
74
72
  import('./tools/activate-license.js'),
75
73
  import('./engine/tool-groups/group-manager.js'),
76
74
  import('./tools/tool-group-handler.js'),
77
- import('./tools/register-sdd-tools.js'),
78
75
  ]);
79
76
  // SPEC-450: Wire autopilot trigger rules to the event bus
80
77
  bootstrapAutopilotHandlers();
@@ -121,9 +118,6 @@ async function setupPostHandshake(handshakeGate) {
121
118
  });
122
119
  }
123
120
  }
124
- // Register the single official SDD MCP surface and UX surfaces.
125
- registerSddTools(server);
126
- getRegisteredTools().get('_planu_boot')?.disable();
127
121
  try {
128
122
  const { registerPlanuMcpResources, registerPlanuMcpPrompts } = await import('./hosts/claude-code/ux/index.js');
129
123
  registerPlanuMcpResources(server);
@@ -138,7 +132,7 @@ async function setupPostHandshake(handshakeGate) {
138
132
  server.sendToolListChanged();
139
133
  });
140
134
  await groupManager.init();
141
- for (const toolName of OFFICIAL_SDD_TOOL_NAMES) {
135
+ for (const toolName of officialToolNames) {
142
136
  toolMap.get(toolName)?.enable();
143
137
  }
144
138
  setGroupManager(groupManager);
@@ -147,9 +141,14 @@ async function setupPostHandshake(handshakeGate) {
147
141
  }
148
142
  // Start server
149
143
  async function main() {
150
- // Dynamic imports keep startup lean evaluated only after the process is alive.
151
- const { selectTransport } = await import('./transports/transport-factory.js');
152
- // Gate all heavy loading until the MCP handshake completes (initialize +
144
+ // Register the official tools before connecting transport. Some hosts cache the
145
+ // first tools/list response and do not reliably consume list_changed updates.
146
+ const [{ selectTransport }, { registerSddTools, OFFICIAL_SDD_TOOL_NAMES }] = await Promise.all([
147
+ import('./transports/transport-factory.js'),
148
+ import('./tools/register-sdd-tools.js'),
149
+ ]);
150
+ registerSddTools(server);
151
+ // Gate non-tool startup work until the MCP handshake completes (initialize +
153
152
  // notifications/initialized). This guarantees the initialize response goes out
154
153
  // before any notifications/tools/list_changed events, which is required by the
155
154
  // MCP protocol. Without this gate module evaluation (synchronous, ~3-4 s) blocks
@@ -175,9 +174,8 @@ async function main() {
175
174
  await new Promise((res) => {
176
175
  setImmediate(res);
177
176
  });
178
- // Fire-and-forget: setupPostHandshake awaits the gate then loads everything.
179
- // Module loading starts NOW — after initialize is already handled above.
180
- void setupPostHandshake(handshakeGate);
177
+ // Fire-and-forget: setupPostHandshake awaits the gate before optional startup work.
178
+ void setupPostHandshake(handshakeGate, OFFICIAL_SDD_TOOL_NAMES);
181
179
  }
182
180
  process.on('uncaughtException', (error) => {
183
181
  /* v8 ignore next 1 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "4.3.15",
3
+ "version": "4.3.16",
4
4
  "description": "Planu — MCP Server for Spec Driven Development with native Rust acceleration for hot paths. Cross-platform (Linux/macOS/Windows, x64/arm64, glibc/musl).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -34,14 +34,14 @@
34
34
  "packageName": "@planu/core"
35
35
  },
36
36
  "optionalDependencies": {
37
- "@planu/core-darwin-arm64": "4.3.15",
38
- "@planu/core-darwin-x64": "4.3.15",
39
- "@planu/core-linux-arm64-gnu": "4.3.15",
40
- "@planu/core-linux-arm64-musl": "4.3.15",
41
- "@planu/core-linux-x64-gnu": "4.3.15",
42
- "@planu/core-linux-x64-musl": "4.3.15",
43
- "@planu/core-win32-arm64-msvc": "4.3.15",
44
- "@planu/core-win32-x64-msvc": "4.3.15"
37
+ "@planu/core-darwin-arm64": "4.3.16",
38
+ "@planu/core-darwin-x64": "4.3.16",
39
+ "@planu/core-linux-arm64-gnu": "4.3.16",
40
+ "@planu/core-linux-arm64-musl": "4.3.16",
41
+ "@planu/core-linux-x64-gnu": "4.3.16",
42
+ "@planu/core-linux-x64-musl": "4.3.16",
43
+ "@planu/core-win32-arm64-msvc": "4.3.16",
44
+ "@planu/core-win32-x64-msvc": "4.3.16"
45
45
  },
46
46
  "engines": {
47
47
  "node": ">=24.0.0"
package/planu-native.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dev.planu.native",
3
3
  "displayName": "Planu Native Lightweight Surface",
4
- "version": "4.3.15",
4
+ "version": "4.3.16",
5
5
  "packageName": "@planu/cli",
6
6
  "modes": {
7
7
  "lightweight": {
package/planu-plugin.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dev.planu.cli",
3
3
  "displayName": "Planu — Spec Driven Development",
4
4
  "description": "Manage software specs, estimations, and autonomous SDD workflows. Language-agnostic MCP server for Claude Code.",
5
- "version": "4.3.15",
5
+ "version": "4.3.16",
6
6
  "icon": "assets/plugin/icon.svg",
7
7
  "command": ["npx", "@planu/cli@latest"],
8
8
  "packageName": "@planu/cli",