@vibekiln/cutline-mcp-cli 0.13.0 → 0.15.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.
- package/README.md +15 -0
- package/dist/auth/callback.d.ts +1 -1
- package/dist/auth/callback.js +9 -1
- package/dist/commands/login.js +4 -1
- package/dist/commands/serve.d.ts +4 -0
- package/dist/commands/serve.js +19 -6
- package/dist/commands/setup.js +17 -8
- package/dist/index.js +4 -2
- package/dist/servers/{chunk-RUCYK3TR.js → chunk-FHWY2TYO.js} +349 -89
- package/dist/servers/chunk-Q5V4VTF5.js +3180 -0
- package/dist/servers/{chunk-KMUSQOTJ.js → chunk-WTLGBZBN.js} +15 -1
- package/dist/servers/cutline-server.js +1218 -4011
- package/dist/servers/{data-client-RY2DCLME.js → data-client-3OADPXXN.js} +45 -3
- package/dist/servers/exploration-server.js +1 -1
- package/dist/servers/integrations-server.js +2 -2
- package/dist/servers/output-server.js +1 -1
- package/dist/servers/premortem-server.js +30 -65
- package/dist/servers/slopburn-server.js +10069 -0
- package/dist/servers/tools-server.js +67 -6
- package/package.json +5 -3
- package/server.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
npm install -g @vibekiln/cutline-mcp-cli@latest
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
`@vibekiln/cutline-mcp-cli` includes the standard Cutline MCP servers and **SlopBurn** (the product quality engineering roguelike RPG mode) in the same install.
|
|
18
|
+
|
|
19
|
+
If you want a dedicated SlopBurn-first CLI with separate onboarding/config UX, use:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g @vibekiln/slopburn-cli
|
|
23
|
+
slopburn setup
|
|
24
|
+
slopburn serve
|
|
25
|
+
```
|
|
26
|
+
|
|
17
27
|
### Docker
|
|
18
28
|
|
|
19
29
|
```bash
|
|
@@ -62,6 +72,11 @@ Cutline interprets intent and tier:
|
|
|
62
72
|
| **AI Personas** — stakeholder feedback on features | — | Full access |
|
|
63
73
|
| **Idea Validation** — fast-track from free web validation | — | Included |
|
|
64
74
|
|
|
75
|
+
### SlopBurn
|
|
76
|
+
|
|
77
|
+
SlopBurn is a **product quality engineering roguelike RPG** built into the Cutline MCP ecosystem.
|
|
78
|
+
It turns deep-dive + verification loops into game progression, where test checks act like encounters, XP tracks quality gains, and MCP servers unlock as spells.
|
|
79
|
+
|
|
65
80
|
## 54 MCP Tools
|
|
66
81
|
|
|
67
82
|
### Free Tier
|
package/dist/auth/callback.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export interface CallbackResult {
|
|
|
2
2
|
token: string;
|
|
3
3
|
email?: string;
|
|
4
4
|
}
|
|
5
|
-
export type CallbackSource = 'login' | 'setup' | 'upgrade';
|
|
5
|
+
export type CallbackSource = 'login' | 'setup' | 'upgrade' | 'slopburn';
|
|
6
6
|
export declare function startCallbackServer(source?: CallbackSource): Promise<CallbackResult>;
|
package/dist/auth/callback.js
CHANGED
|
@@ -59,12 +59,20 @@ export async function startCallbackServer(source = 'login') {
|
|
|
59
59
|
<div class="checkmark">✓</div>
|
|
60
60
|
<h1>You're in!</h1>
|
|
61
61
|
${email ? `<p class="email">${email}</p>` : ''}
|
|
62
|
-
${source === 'login' ? `
|
|
62
|
+
${(source === 'login' || source === 'slopburn') ? `
|
|
63
63
|
<div class="steps">
|
|
64
64
|
<h3>Next in your terminal</h3>
|
|
65
|
+
${source === 'slopburn'
|
|
66
|
+
? `
|
|
67
|
+
<div class="step"><span class="num">1</span><span>Run <code>slopburn setup --staging</code> to install SlopBurn MCP config</span></div>
|
|
68
|
+
<div class="step"><span class="num">2</span><span>Run <code>slopburn serve --staging</code> to start the SlopBurn server</span></div>
|
|
69
|
+
<div class="step"><span class="num">3</span><span>Tell your agent: <em>"start slopburn and create my first run"</em></span></div>
|
|
70
|
+
`
|
|
71
|
+
: `
|
|
65
72
|
<div class="step"><span class="num">1</span><span>Run <code>cutline-mcp init</code> to generate IDE rules</span></div>
|
|
66
73
|
<div class="step"><span class="num">2</span><span>Run <code>cutline-mcp setup</code> to connect MCP servers</span></div>
|
|
67
74
|
<div class="step"><span class="num">3</span><span>Ask your agent: <em>"Run an engineering audit"</em></span></div>
|
|
75
|
+
`}
|
|
68
76
|
</div>` : `
|
|
69
77
|
<div class="steps">
|
|
70
78
|
<h3>Go back to your terminal</h3>
|
package/dist/commands/login.js
CHANGED
|
@@ -91,7 +91,10 @@ export async function loginCommand(options) {
|
|
|
91
91
|
}
|
|
92
92
|
// Start callback server
|
|
93
93
|
spinner.text = 'Waiting for authentication...';
|
|
94
|
-
const
|
|
94
|
+
const envSource = process.env.CUTLINE_MCP_AUTH_SOURCE;
|
|
95
|
+
const validSource = (value) => value === 'login' || value === 'setup' || value === 'upgrade' || value === 'slopburn';
|
|
96
|
+
const callbackSource = options.source ?? (validSource(envSource) ? envSource : 'login');
|
|
97
|
+
const serverPromise = startCallbackServer(callbackSource);
|
|
95
98
|
// Open browser — default is the quick email-only flow
|
|
96
99
|
let authUrl = `${config.AUTH_URL}?callback=${encodeURIComponent(config.CALLBACK_URL)}`;
|
|
97
100
|
if (options.signup) {
|
package/dist/commands/serve.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
export declare const SERVER_MAP: Record<string, string>;
|
|
1
2
|
interface ServeOptions {
|
|
2
3
|
http?: boolean;
|
|
3
4
|
host?: string;
|
|
4
5
|
port?: string;
|
|
5
6
|
path?: string;
|
|
7
|
+
staging?: boolean;
|
|
6
8
|
}
|
|
9
|
+
export declare function resolveServerFileName(serverName: string): string | null;
|
|
10
|
+
export declare function resolveServerBundlePath(serverName: string, baseDir?: string): string | null;
|
|
7
11
|
export declare function serveCommand(serverName: string, options?: ServeOptions): void;
|
|
8
12
|
export {};
|
package/dist/commands/serve.js
CHANGED
|
@@ -4,14 +4,22 @@ import { resolve, dirname } from 'node:path';
|
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { existsSync } from 'node:fs';
|
|
6
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const SERVER_MAP = {
|
|
7
|
+
export const SERVER_MAP = {
|
|
8
8
|
constraints: 'cutline-server.js',
|
|
9
9
|
premortem: 'premortem-server.js',
|
|
10
10
|
exploration: 'exploration-server.js',
|
|
11
11
|
tools: 'tools-server.js',
|
|
12
12
|
output: 'output-server.js',
|
|
13
13
|
integrations: 'integrations-server.js',
|
|
14
|
+
slopburn: 'slopburn-server.js',
|
|
14
15
|
};
|
|
16
|
+
export function resolveServerFileName(serverName) {
|
|
17
|
+
return SERVER_MAP[serverName] ?? null;
|
|
18
|
+
}
|
|
19
|
+
export function resolveServerBundlePath(serverName, baseDir = __dirname) {
|
|
20
|
+
const fileName = resolveServerFileName(serverName);
|
|
21
|
+
return fileName ? resolve(baseDir, '../servers', fileName) : null;
|
|
22
|
+
}
|
|
15
23
|
function handleChildMessage(message, pending) {
|
|
16
24
|
const parsed = message;
|
|
17
25
|
const id = normalizeId(parsed?.id);
|
|
@@ -72,9 +80,12 @@ function serveHttpBridge(serverName, serverPath, opts) {
|
|
|
72
80
|
console.error(`Invalid --port value: ${opts.port}`);
|
|
73
81
|
process.exit(1);
|
|
74
82
|
}
|
|
83
|
+
const childEnv = opts.staging
|
|
84
|
+
? { ...process.env, CUTLINE_ENV: 'staging' }
|
|
85
|
+
: process.env;
|
|
75
86
|
const child = spawn(process.execPath, [serverPath], {
|
|
76
87
|
stdio: ['pipe', 'pipe', 'inherit'],
|
|
77
|
-
env:
|
|
88
|
+
env: childEnv,
|
|
78
89
|
});
|
|
79
90
|
const pending = new Map();
|
|
80
91
|
let stdoutBuffer = Buffer.alloc(0);
|
|
@@ -216,18 +227,20 @@ function serveHttpBridge(serverName, serverPath, opts) {
|
|
|
216
227
|
});
|
|
217
228
|
}
|
|
218
229
|
export function serveCommand(serverName, options = {}) {
|
|
219
|
-
const
|
|
220
|
-
if (!
|
|
230
|
+
const serverPath = resolveServerBundlePath(serverName);
|
|
231
|
+
if (!serverPath) {
|
|
221
232
|
const valid = Object.keys(SERVER_MAP).join(', ');
|
|
222
233
|
console.error(`Unknown server: "${serverName}". Valid names: ${valid}`);
|
|
223
234
|
process.exit(1);
|
|
224
235
|
}
|
|
225
|
-
const serverPath = resolve(__dirname, '../servers', fileName);
|
|
226
236
|
if (!existsSync(serverPath)) {
|
|
227
237
|
console.error(`Server bundle not found at ${serverPath}`);
|
|
228
238
|
console.error('The package may not have been built correctly.');
|
|
229
239
|
process.exit(1);
|
|
230
240
|
}
|
|
241
|
+
const childEnv = options.staging
|
|
242
|
+
? { ...process.env, CUTLINE_ENV: 'staging' }
|
|
243
|
+
: process.env;
|
|
231
244
|
if (options.http) {
|
|
232
245
|
serveHttpBridge(serverName, serverPath, options);
|
|
233
246
|
return;
|
|
@@ -236,7 +249,7 @@ export function serveCommand(serverName, options = {}) {
|
|
|
236
249
|
try {
|
|
237
250
|
execFileSync(process.execPath, [serverPath], {
|
|
238
251
|
stdio: 'inherit',
|
|
239
|
-
env:
|
|
252
|
+
env: childEnv,
|
|
240
253
|
});
|
|
241
254
|
}
|
|
242
255
|
catch (err) {
|
package/dist/commands/setup.js
CHANGED
|
@@ -27,6 +27,7 @@ const SERVER_NAMES = [
|
|
|
27
27
|
'tools',
|
|
28
28
|
'output',
|
|
29
29
|
'integrations',
|
|
30
|
+
'slopburn',
|
|
30
31
|
];
|
|
31
32
|
const AUDIT_DIMENSIONS = ['engineering', 'security', 'reliability', 'scalability', 'compliance'];
|
|
32
33
|
async function detectTier(options) {
|
|
@@ -146,7 +147,7 @@ function writeAuditVisibilityConfig(hiddenDimensions) {
|
|
|
146
147
|
mkdirSync(configDir, { recursive: true });
|
|
147
148
|
writeFileSync(configPath, JSON.stringify(next, null, 2) + '\n');
|
|
148
149
|
}
|
|
149
|
-
function resolveServeRuntime() {
|
|
150
|
+
function resolveServeRuntime(options) {
|
|
150
151
|
// Optional explicit override for advanced environments.
|
|
151
152
|
if (process.env.CUTLINE_MCP_BIN?.trim()) {
|
|
152
153
|
return {
|
|
@@ -167,18 +168,22 @@ function resolveServeRuntime() {
|
|
|
167
168
|
// Fallback for machines without a global install.
|
|
168
169
|
const voltaNpx = join(homedir(), '.volta', 'bin', 'npx');
|
|
169
170
|
const npxCommand = existsSync(voltaNpx) ? voltaNpx : 'npx';
|
|
171
|
+
const packageName = options?.staging
|
|
172
|
+
? '@kylewadegrove/cutline-mcp-cli-staging@latest'
|
|
173
|
+
: '@vibekiln/cutline-mcp-cli@latest';
|
|
170
174
|
return {
|
|
171
175
|
command: npxCommand,
|
|
172
|
-
argsPrefix: ['-y',
|
|
176
|
+
argsPrefix: ['-y', packageName],
|
|
173
177
|
source: 'npx',
|
|
174
178
|
};
|
|
175
179
|
}
|
|
176
|
-
function buildServerConfig(runtime) {
|
|
180
|
+
function buildServerConfig(runtime, options) {
|
|
177
181
|
const config = {};
|
|
182
|
+
const envArgs = options?.staging ? ['--staging'] : [];
|
|
178
183
|
for (const name of SERVER_NAMES) {
|
|
179
184
|
config[`cutline-${name}`] = {
|
|
180
185
|
command: runtime.command,
|
|
181
|
-
args: [...runtime.argsPrefix, 'serve', name],
|
|
186
|
+
args: [...runtime.argsPrefix, 'serve', name, ...envArgs],
|
|
182
187
|
};
|
|
183
188
|
}
|
|
184
189
|
return config;
|
|
@@ -338,8 +343,8 @@ export async function setupCommand(options) {
|
|
|
338
343
|
console.log(chalk.dim(' Hidden audit dimensions: none\n'));
|
|
339
344
|
}
|
|
340
345
|
// ── 3. Write MCP server config to IDEs ───────────────────────────────────
|
|
341
|
-
const runtime = resolveServeRuntime();
|
|
342
|
-
const serverConfig = buildServerConfig(runtime);
|
|
346
|
+
const runtime = resolveServeRuntime({ staging: options.staging });
|
|
347
|
+
const serverConfig = buildServerConfig(runtime, { staging: options.staging });
|
|
343
348
|
const home = homedir();
|
|
344
349
|
const ideConfigs = [
|
|
345
350
|
{ name: 'Cursor', path: join(home, '.cursor', 'mcp.json') },
|
|
@@ -443,8 +448,9 @@ export async function setupCommand(options) {
|
|
|
443
448
|
console.log(chalk.bold(' Claude Code one-liner alternative:\n'));
|
|
444
449
|
console.log(chalk.dim(' If you prefer `claude mcp add` instead of ~/.claude.json:\n'));
|
|
445
450
|
const coreServers = ['constraints', 'premortem', 'tools', 'exploration'];
|
|
451
|
+
const stagingArg = options.staging ? ' --staging' : '';
|
|
446
452
|
for (const name of coreServers) {
|
|
447
|
-
const invocation = [runtime.command, ...runtime.argsPrefix, 'serve', name].join(' ');
|
|
453
|
+
const invocation = [runtime.command, ...runtime.argsPrefix, 'serve', name].join(' ') + stagingArg;
|
|
448
454
|
console.log(chalk.cyan(` claude mcp add cutline-${name} -- ${invocation}`));
|
|
449
455
|
}
|
|
450
456
|
console.log();
|
|
@@ -492,7 +498,10 @@ export async function setupCommand(options) {
|
|
|
492
498
|
}
|
|
493
499
|
console.log();
|
|
494
500
|
console.log(chalk.dim(` cutline-mcp v${version} · docs: https://thecutline.ai/docs/setup`));
|
|
495
|
-
|
|
501
|
+
const bootstrapPackage = options.staging
|
|
502
|
+
? '@kylewadegrove/cutline-mcp-cli-staging@latest'
|
|
503
|
+
: '@vibekiln/cutline-mcp-cli@latest';
|
|
504
|
+
console.log(chalk.dim(' Testing bootstrap:'), chalk.cyan(`npx -y ${bootstrapPackage} setup${options.staging ? ' --staging' : ''}`));
|
|
496
505
|
console.log(chalk.dim(' Optional repo policy contract:'), chalk.cyan('cutline-mcp policy-init'));
|
|
497
506
|
console.log();
|
|
498
507
|
}
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-
|
|
|
17
17
|
const program = new Command();
|
|
18
18
|
program
|
|
19
19
|
.name('cutline-mcp')
|
|
20
|
-
.description('CLI and MCP servers for Cutline')
|
|
20
|
+
.description('CLI and MCP servers for Cutline, including SlopBurn (a product quality engineering roguelike RPG)')
|
|
21
21
|
.version(pkg.version);
|
|
22
22
|
program
|
|
23
23
|
.command('login')
|
|
@@ -47,7 +47,8 @@ program
|
|
|
47
47
|
.action(upgradeCommand);
|
|
48
48
|
program
|
|
49
49
|
.command('serve <server>')
|
|
50
|
-
.description('Start an MCP server (constraints, premortem, exploration, tools, output, integrations)')
|
|
50
|
+
.description('Start an MCP server (constraints, premortem, exploration, tools, output, integrations, slopburn)')
|
|
51
|
+
.option('--staging', 'Use staging environment')
|
|
51
52
|
.option('--http', 'Expose the selected stdio server over an HTTP bridge')
|
|
52
53
|
.option('--host <host>', 'HTTP bind host for bridge mode (default: 0.0.0.0)')
|
|
53
54
|
.option('--port <port>', 'HTTP port for bridge mode (default: 8080)')
|
|
@@ -57,6 +58,7 @@ program
|
|
|
57
58
|
host: opts.host,
|
|
58
59
|
port: opts.port,
|
|
59
60
|
path: opts.path,
|
|
61
|
+
staging: opts.staging,
|
|
60
62
|
}));
|
|
61
63
|
program
|
|
62
64
|
.command('setup')
|