ninja-terminals 2.2.2 → 2.2.4
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/cli.js +35 -5
- package/mcp-server.js +44 -17
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -121,21 +121,51 @@ if (hasFlag('--setup')) {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
// 4.
|
|
124
|
+
// 4. Add required MCP dependencies (Playwright + Fetch)
|
|
125
|
+
// These are needed for browser automation and API calls
|
|
126
|
+
|
|
127
|
+
if (!mcpConfig.mcpServers['playwright']) {
|
|
128
|
+
mcpConfig.mcpServers['playwright'] = {
|
|
129
|
+
command: 'npx',
|
|
130
|
+
args: ['@anthropic-ai/playwright-mcp@latest']
|
|
131
|
+
};
|
|
132
|
+
console.log(`✅ Added Playwright MCP (browser automation)`);
|
|
133
|
+
} else {
|
|
134
|
+
console.log(`✅ Playwright MCP already configured`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!mcpConfig.mcpServers['fetch']) {
|
|
138
|
+
mcpConfig.mcpServers['fetch'] = {
|
|
139
|
+
command: 'npx',
|
|
140
|
+
args: ['@anthropic-ai/fetch-mcp@latest']
|
|
141
|
+
};
|
|
142
|
+
console.log(`✅ Added Fetch MCP (API calls)`);
|
|
143
|
+
} else {
|
|
144
|
+
console.log(`✅ Fetch MCP already configured`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Save updated config with all MCPs
|
|
148
|
+
fs.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2) + '\n');
|
|
149
|
+
|
|
150
|
+
// 5. Check for Claude in Chrome (optional but recommended)
|
|
125
151
|
const chromeExt = mcpConfig.mcpServers['claude-in-chrome'];
|
|
126
152
|
if (chromeExt) {
|
|
127
|
-
console.log(`✅ Claude in Chrome detected`);
|
|
153
|
+
console.log(`✅ Claude in Chrome detected (recommended)`);
|
|
128
154
|
} else {
|
|
129
|
-
console.log(
|
|
130
|
-
console.log(` For browser automation, install: https://github.com/anthropics/claude-in-chrome`);
|
|
155
|
+
console.log(`ℹ️ Claude in Chrome not found (optional - Playwright will be used)`);
|
|
131
156
|
}
|
|
132
157
|
|
|
133
158
|
console.log(`
|
|
134
159
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
135
160
|
✨ Setup complete!
|
|
136
161
|
|
|
162
|
+
MCPs configured:
|
|
163
|
+
• ninja-terminals - orchestrates parallel Claude Code instances
|
|
164
|
+
• playwright - browser automation (screenshots, clicks, reading)
|
|
165
|
+
• fetch - API calls to /api/terminals
|
|
166
|
+
|
|
137
167
|
Next steps:
|
|
138
|
-
1. Restart Claude Code to load MCP
|
|
168
|
+
1. Restart Claude Code to load MCP servers
|
|
139
169
|
2. Run: npx ninja-terminals
|
|
140
170
|
3. Or use MCP tools directly in Claude Code
|
|
141
171
|
|
package/mcp-server.js
CHANGED
|
@@ -694,24 +694,51 @@ mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
694
694
|
|
|
695
695
|
// ── Start Servers ───────────────────────────────────────────
|
|
696
696
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
for (let i = 0; i < terminalCount; i++) {
|
|
709
|
-
const label = labels[i] || `T${i + 1}`;
|
|
710
|
-
spawnTerminal(label, [], process.cwd(), 'pro');
|
|
711
|
-
console.error(` Spawned ${label}`);
|
|
712
|
-
}
|
|
713
|
-
console.error(`All ${terminalCount} terminals ready`);
|
|
697
|
+
// Check if port is in use
|
|
698
|
+
function isPortInUse(port) {
|
|
699
|
+
return new Promise((resolve) => {
|
|
700
|
+
const net = require('net');
|
|
701
|
+
const server = net.createServer();
|
|
702
|
+
server.once('error', () => resolve(true));
|
|
703
|
+
server.once('listening', () => {
|
|
704
|
+
server.close();
|
|
705
|
+
resolve(false);
|
|
706
|
+
});
|
|
707
|
+
server.listen(port, '127.0.0.1');
|
|
714
708
|
});
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Proxy mode flag - when true, MCP tools should call existing server via HTTP
|
|
712
|
+
let proxyMode = false;
|
|
713
|
+
|
|
714
|
+
async function main() {
|
|
715
|
+
// Check if server.js is already running on port 3300
|
|
716
|
+
const portInUse = await isPortInUse(HTTP_PORT);
|
|
717
|
+
|
|
718
|
+
if (portInUse) {
|
|
719
|
+
// Proxy mode: server.js is already running, just run MCP on stdio
|
|
720
|
+
proxyMode = true;
|
|
721
|
+
console.error(`Ninja Terminals server already running on port ${HTTP_PORT}`);
|
|
722
|
+
console.error('MCP server starting in proxy mode (will use existing server)');
|
|
723
|
+
} else {
|
|
724
|
+
// Standalone mode: start our own HTTP server
|
|
725
|
+
httpServer.listen(HTTP_PORT, () => {
|
|
726
|
+
console.error(`Ninja Terminals HTTP server running on http://localhost:${HTTP_PORT}`);
|
|
727
|
+
|
|
728
|
+
// Auto-spawn terminals based on tier (NINJA_TERMINAL_COUNT env var)
|
|
729
|
+
// Free = 2, Paid = 4
|
|
730
|
+
const terminalCount = parseInt(process.env.NINJA_TERMINAL_COUNT || '2', 10);
|
|
731
|
+
const labels = ['T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8'];
|
|
732
|
+
|
|
733
|
+
console.error(`Auto-spawning ${terminalCount} terminals...`);
|
|
734
|
+
for (let i = 0; i < terminalCount; i++) {
|
|
735
|
+
const label = labels[i] || `T${i + 1}`;
|
|
736
|
+
spawnTerminal(label, [], process.cwd(), 'pro');
|
|
737
|
+
console.error(` Spawned ${label}`);
|
|
738
|
+
}
|
|
739
|
+
console.error(`All ${terminalCount} terminals ready`);
|
|
740
|
+
});
|
|
741
|
+
}
|
|
715
742
|
|
|
716
743
|
// Start MCP server on stdio
|
|
717
744
|
const transport = new StdioServerTransport();
|
package/package.json
CHANGED