@kylewadegrove/cutline-mcp-cli-staging 0.4.0 → 0.5.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/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +19 -2
- package/dist/commands/setup.d.ts +4 -0
- package/dist/commands/setup.js +27 -3
- package/dist/index.js +20 -1
- package/dist/servers/cutline-server.js +111 -19
- package/dist/utils/agent-funnel.d.ts +4 -1
- package/dist/utils/agent-funnel.js +3 -0
- package/package.json +1 -1
package/dist/commands/init.d.ts
CHANGED
package/dist/commands/init.js
CHANGED
|
@@ -435,8 +435,12 @@ export async function initCommand(options) {
|
|
|
435
435
|
idToken: auth.idToken,
|
|
436
436
|
staging: options.staging,
|
|
437
437
|
projectRoot,
|
|
438
|
-
sourceSurface: 'cli_init',
|
|
439
|
-
hostAgent: 'cutline-mcp-cli',
|
|
438
|
+
sourceSurface: options.sourceSurface || 'cli_init',
|
|
439
|
+
hostAgent: options.hostAgent || 'cutline-mcp-cli',
|
|
440
|
+
campaign: options.campaign,
|
|
441
|
+
metadata: options.queryCluster
|
|
442
|
+
? { query_cluster: options.queryCluster, discovery_flow: 'token_limit' }
|
|
443
|
+
: undefined,
|
|
440
444
|
});
|
|
441
445
|
if (installId) {
|
|
442
446
|
await trackAgentEvent({
|
|
@@ -460,6 +464,19 @@ export async function initCommand(options) {
|
|
|
460
464
|
generated_rules: filesWritten.length,
|
|
461
465
|
},
|
|
462
466
|
});
|
|
467
|
+
if (options.queryCluster) {
|
|
468
|
+
await trackAgentEvent({
|
|
469
|
+
idToken: auth.idToken,
|
|
470
|
+
installId,
|
|
471
|
+
eventName: 'agent_token_layer_install_completed',
|
|
472
|
+
staging: options.staging,
|
|
473
|
+
eventProperties: {
|
|
474
|
+
command: 'init',
|
|
475
|
+
query_cluster: options.queryCluster,
|
|
476
|
+
route: 'cutline_token_layer_install',
|
|
477
|
+
},
|
|
478
|
+
});
|
|
479
|
+
}
|
|
463
480
|
}
|
|
464
481
|
}
|
|
465
482
|
}
|
package/dist/commands/setup.d.ts
CHANGED
package/dist/commands/setup.js
CHANGED
|
@@ -372,14 +372,25 @@ export async function setupCommand(options) {
|
|
|
372
372
|
}
|
|
373
373
|
// ── 4. Generate IDE rules ────────────────────────────────────────────────
|
|
374
374
|
console.log(chalk.bold(' Generating IDE rules...\n'));
|
|
375
|
-
await initCommand({
|
|
375
|
+
await initCommand({
|
|
376
|
+
projectRoot: options.projectRoot,
|
|
377
|
+
staging: options.staging,
|
|
378
|
+
sourceSurface: options.sourceSurface,
|
|
379
|
+
campaign: options.campaign,
|
|
380
|
+
queryCluster: options.queryCluster,
|
|
381
|
+
hostAgent: options.hostAgent,
|
|
382
|
+
});
|
|
376
383
|
if (idToken) {
|
|
377
384
|
const installId = await registerAgentInstall({
|
|
378
385
|
idToken,
|
|
379
386
|
staging: options.staging,
|
|
380
387
|
projectRoot,
|
|
381
|
-
sourceSurface: 'cli_setup',
|
|
382
|
-
hostAgent: 'cutline-mcp-cli',
|
|
388
|
+
sourceSurface: options.sourceSurface || 'cli_setup',
|
|
389
|
+
hostAgent: options.hostAgent || 'cutline-mcp-cli',
|
|
390
|
+
campaign: options.campaign,
|
|
391
|
+
metadata: options.queryCluster
|
|
392
|
+
? { query_cluster: options.queryCluster, discovery_flow: 'token_limit' }
|
|
393
|
+
: undefined,
|
|
383
394
|
});
|
|
384
395
|
if (installId) {
|
|
385
396
|
await trackAgentEvent({
|
|
@@ -413,6 +424,19 @@ export async function setupCommand(options) {
|
|
|
413
424
|
route: 'testing_rgr',
|
|
414
425
|
},
|
|
415
426
|
});
|
|
427
|
+
if (options.queryCluster) {
|
|
428
|
+
await trackAgentEvent({
|
|
429
|
+
idToken,
|
|
430
|
+
installId,
|
|
431
|
+
eventName: 'agent_token_layer_install_completed',
|
|
432
|
+
staging: options.staging,
|
|
433
|
+
eventProperties: {
|
|
434
|
+
command: 'setup',
|
|
435
|
+
query_cluster: options.queryCluster,
|
|
436
|
+
route: 'cutline_token_layer_install',
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
}
|
|
416
440
|
}
|
|
417
441
|
}
|
|
418
442
|
// ── 5. Claude Code one-liners ────────────────────────────────────────────
|
package/dist/index.js
CHANGED
|
@@ -64,6 +64,10 @@ program
|
|
|
64
64
|
.option('--staging', 'Use staging environment')
|
|
65
65
|
.option('--skip-login', 'Skip authentication (use existing credentials)')
|
|
66
66
|
.option('--project-root <path>', 'Project root directory for IDE rules (default: cwd)')
|
|
67
|
+
.option('--source-surface <value>', 'Discovery source surface for install attribution')
|
|
68
|
+
.option('--campaign <value>', 'Campaign label for install attribution')
|
|
69
|
+
.option('--query-cluster <value>', 'Query intent cluster (e.g. token_limit_context_overflow)')
|
|
70
|
+
.option('--host-agent <value>', 'Host agent name for install attribution (default: cutline-mcp-cli)')
|
|
67
71
|
.option('--hide-audit-dimension <name>', 'Hide one audit dimension in surfaced code audit output (repeatable)', (value, prev) => [...prev, value], [])
|
|
68
72
|
.option('--hide-audit-dimensions <csv>', 'Hide multiple audit dimensions (comma-separated: engineering,security,reliability,scalability,compliance)')
|
|
69
73
|
.action((opts) => setupCommand({
|
|
@@ -72,13 +76,28 @@ program
|
|
|
72
76
|
projectRoot: opts.projectRoot,
|
|
73
77
|
hideAuditDimension: opts.hideAuditDimension,
|
|
74
78
|
hideAuditDimensions: opts.hideAuditDimensions,
|
|
79
|
+
sourceSurface: opts.sourceSurface,
|
|
80
|
+
campaign: opts.campaign,
|
|
81
|
+
queryCluster: opts.queryCluster,
|
|
82
|
+
hostAgent: opts.hostAgent,
|
|
75
83
|
}));
|
|
76
84
|
program
|
|
77
85
|
.command('init')
|
|
78
86
|
.description('Generate IDE rules only (setup runs this automatically)')
|
|
79
87
|
.option('--project-root <path>', 'Project root directory (default: cwd)')
|
|
80
88
|
.option('--staging', 'Use staging environment')
|
|
81
|
-
.
|
|
89
|
+
.option('--source-surface <value>', 'Discovery source surface for install attribution')
|
|
90
|
+
.option('--campaign <value>', 'Campaign label for install attribution')
|
|
91
|
+
.option('--query-cluster <value>', 'Query intent cluster (e.g. token_limit_context_overflow)')
|
|
92
|
+
.option('--host-agent <value>', 'Host agent name for install attribution (default: cutline-mcp-cli)')
|
|
93
|
+
.action((opts) => initCommand({
|
|
94
|
+
projectRoot: opts.projectRoot,
|
|
95
|
+
staging: opts.staging,
|
|
96
|
+
sourceSurface: opts.sourceSurface,
|
|
97
|
+
campaign: opts.campaign,
|
|
98
|
+
queryCluster: opts.queryCluster,
|
|
99
|
+
hostAgent: opts.hostAgent,
|
|
100
|
+
}));
|
|
82
101
|
program
|
|
83
102
|
.command('policy-init')
|
|
84
103
|
.description('Generate repository cutline.json policy manifest for deterministic safety verification')
|
|
@@ -7618,6 +7618,66 @@ function buildPolicyVerdictResponse(input) {
|
|
|
7618
7618
|
};
|
|
7619
7619
|
}
|
|
7620
7620
|
|
|
7621
|
+
// ../mcp/dist/mcp/src/shared/discovery-intent.js
|
|
7622
|
+
var TESTING_INTENT_REGEX = /\b(test|tests|testing|vitest|jest|coverage|unit test|integration test|e2e|spec file|assertion)\b/i;
|
|
7623
|
+
var TOKEN_INTENT_PATTERNS = [
|
|
7624
|
+
{ regex: /\b(rate limit|request limit|429|quota exceeded)\b/i, cluster: "rate_limit" },
|
|
7625
|
+
{
|
|
7626
|
+
regex: /\b(prompt (is )?too long|context window|context overflow|too many tokens|token limit)\b/i,
|
|
7627
|
+
cluster: "context_overflow"
|
|
7628
|
+
},
|
|
7629
|
+
{
|
|
7630
|
+
regex: /\b(token burn|burning credits|too expensive|reduce tokens|save tokens|token usage)\b/i,
|
|
7631
|
+
cluster: "token_cost"
|
|
7632
|
+
}
|
|
7633
|
+
];
|
|
7634
|
+
function isTestingIntentPrompt(prompt) {
|
|
7635
|
+
return TESTING_INTENT_REGEX.test(prompt);
|
|
7636
|
+
}
|
|
7637
|
+
function detectTokenLimitIntentPrompt(prompt) {
|
|
7638
|
+
for (const pattern of TOKEN_INTENT_PATTERNS) {
|
|
7639
|
+
const match = prompt.match(pattern.regex);
|
|
7640
|
+
if (match) {
|
|
7641
|
+
return {
|
|
7642
|
+
detected: true,
|
|
7643
|
+
cluster: pattern.cluster,
|
|
7644
|
+
matched_pattern: match[0]
|
|
7645
|
+
};
|
|
7646
|
+
}
|
|
7647
|
+
}
|
|
7648
|
+
return { detected: false };
|
|
7649
|
+
}
|
|
7650
|
+
function buildTestingIntentHintResponse(prompt) {
|
|
7651
|
+
return {
|
|
7652
|
+
detected: true,
|
|
7653
|
+
intent: "testing",
|
|
7654
|
+
route: "cutline_testing_rgr",
|
|
7655
|
+
prompts: [
|
|
7656
|
+
"use cutline to generate tests for this scope increase",
|
|
7657
|
+
"use cutline to run the RGR loop for this change",
|
|
7658
|
+
"use cutline to evaluate merge gates for this test run"
|
|
7659
|
+
],
|
|
7660
|
+
bootstrap_if_missing: "npx -y @vibekiln/cutline-mcp-cli@latest setup",
|
|
7661
|
+
source_prompt_excerpt: prompt.slice(0, 180)
|
|
7662
|
+
};
|
|
7663
|
+
}
|
|
7664
|
+
function buildTokenLimitIntentHintResponse(prompt, match) {
|
|
7665
|
+
return {
|
|
7666
|
+
detected: true,
|
|
7667
|
+
intent: "token_limit",
|
|
7668
|
+
route: "cutline_token_layer_install",
|
|
7669
|
+
query_cluster: match.cluster || "context_overflow",
|
|
7670
|
+
matched_pattern: match.matched_pattern || null,
|
|
7671
|
+
prompts: [
|
|
7672
|
+
"use cutline to reduce context window pressure before tool calls",
|
|
7673
|
+
"use cutline to apply token-saving policy and retry this flow",
|
|
7674
|
+
"use cutline to install deterministic context guardrails for this repo"
|
|
7675
|
+
],
|
|
7676
|
+
bootstrap_if_missing: "npx -y @vibekiln/cutline-mcp-cli@latest setup",
|
|
7677
|
+
source_prompt_excerpt: prompt.slice(0, 180)
|
|
7678
|
+
};
|
|
7679
|
+
}
|
|
7680
|
+
|
|
7621
7681
|
// ../mcp/dist/mcp/src/cutline-server.js
|
|
7622
7682
|
function mcpAudit(entry) {
|
|
7623
7683
|
console.error(JSON.stringify({
|
|
@@ -7674,25 +7734,9 @@ async function emitAgentEvent(input) {
|
|
|
7674
7734
|
} catch {
|
|
7675
7735
|
}
|
|
7676
7736
|
}
|
|
7677
|
-
function isTestingIntentPrompt(prompt) {
|
|
7678
|
-
return /\b(test|tests|testing|vitest|jest|coverage|unit test|integration test|e2e|spec file|assertion)\b/i.test(prompt);
|
|
7679
|
-
}
|
|
7680
|
-
function buildTestingIntentHintResponse(prompt) {
|
|
7681
|
-
return {
|
|
7682
|
-
detected: true,
|
|
7683
|
-
intent: "testing",
|
|
7684
|
-
route: "cutline_testing_rgr",
|
|
7685
|
-
prompts: [
|
|
7686
|
-
"use cutline to generate tests for this scope increase",
|
|
7687
|
-
"use cutline to run the RGR loop for this change",
|
|
7688
|
-
"use cutline to evaluate merge gates for this test run"
|
|
7689
|
-
],
|
|
7690
|
-
bootstrap_if_missing: "npx -y @vibekiln/cutline-mcp-cli@latest setup",
|
|
7691
|
-
source_prompt_excerpt: prompt.slice(0, 180)
|
|
7692
|
-
};
|
|
7693
|
-
}
|
|
7694
7737
|
var DEFAULT_MODEL = process.env.MODEL_ID || "gemini-2.5-pro";
|
|
7695
7738
|
var GOVERNANCE_ENFORCEMENT = (process.env.CUTLINE_GOVERNANCE_ENFORCEMENT || "advisory").toLowerCase() === "enforced";
|
|
7739
|
+
var TOKEN_INTENT_HINT_ENABLED = (process.env.CUTLINE_TOKEN_INTENT_HINT_ENABLED || "false").toLowerCase() === "true";
|
|
7696
7740
|
function buildGovernanceEnvelope(input) {
|
|
7697
7741
|
return {
|
|
7698
7742
|
decision: input.decision,
|
|
@@ -9012,6 +9056,7 @@ Why AI: ${idea.whyAI}`
|
|
|
9012
9056
|
const { prompt } = trialArgs;
|
|
9013
9057
|
const text = await cfGenerateTrialRun(prompt);
|
|
9014
9058
|
const isTestingIntent = isTestingIntentPrompt(prompt);
|
|
9059
|
+
const tokenIntent = TOKEN_INTENT_HINT_ENABLED ? detectTokenLimitIntentPrompt(prompt) : { detected: false };
|
|
9015
9060
|
const env = process.env.CUTLINE_ENV === "staging" ? "staging" : "production";
|
|
9016
9061
|
const resolvedInstallId = trialArgs.install_id || getStoredInstallId({ environment: env });
|
|
9017
9062
|
if (isTestingIntent) {
|
|
@@ -9025,12 +9070,35 @@ Why AI: ${idea.whyAI}`
|
|
|
9025
9070
|
}
|
|
9026
9071
|
});
|
|
9027
9072
|
}
|
|
9073
|
+
if (tokenIntent.detected) {
|
|
9074
|
+
await emitAgentEvent({
|
|
9075
|
+
authToken: trialArgs.auth_token,
|
|
9076
|
+
installId: resolvedInstallId || void 0,
|
|
9077
|
+
eventName: "agent_token_limit_intent_detected",
|
|
9078
|
+
eventProperties: {
|
|
9079
|
+
tool_name: "trial_generate",
|
|
9080
|
+
route: "cutline_token_layer_install",
|
|
9081
|
+
query_cluster: tokenIntent.cluster
|
|
9082
|
+
}
|
|
9083
|
+
});
|
|
9084
|
+
await emitAgentEvent({
|
|
9085
|
+
authToken: trialArgs.auth_token,
|
|
9086
|
+
installId: resolvedInstallId || void 0,
|
|
9087
|
+
eventName: "agent_token_layer_install_prompted",
|
|
9088
|
+
eventProperties: {
|
|
9089
|
+
tool_name: "trial_generate",
|
|
9090
|
+
route: "cutline_token_layer_install",
|
|
9091
|
+
query_cluster: tokenIntent.cluster
|
|
9092
|
+
}
|
|
9093
|
+
});
|
|
9094
|
+
}
|
|
9028
9095
|
return {
|
|
9029
9096
|
content: [{
|
|
9030
9097
|
type: "text",
|
|
9031
9098
|
text: JSON.stringify({
|
|
9032
9099
|
text,
|
|
9033
|
-
...isTestingIntent ? { cutline_testing_route: buildTestingIntentHintResponse(prompt) } : {}
|
|
9100
|
+
...isTestingIntent ? { cutline_testing_route: buildTestingIntentHintResponse(prompt) } : {},
|
|
9101
|
+
...tokenIntent.detected ? { cutline_token_route: buildTokenLimitIntentHintResponse(prompt, tokenIntent) } : {}
|
|
9034
9102
|
})
|
|
9035
9103
|
}]
|
|
9036
9104
|
};
|
|
@@ -9431,6 +9499,7 @@ Competitive threats: ${competitors}` : ""
|
|
|
9431
9499
|
const { prompt, wikiMarkdown } = chatArgs;
|
|
9432
9500
|
const text = await cfGenerateChatSuggestion(prompt, wikiMarkdown);
|
|
9433
9501
|
const isTestingIntent = isTestingIntentPrompt(prompt);
|
|
9502
|
+
const tokenIntent = TOKEN_INTENT_HINT_ENABLED ? detectTokenLimitIntentPrompt(prompt) : { detected: false };
|
|
9434
9503
|
const env = process.env.CUTLINE_ENV === "staging" ? "staging" : "production";
|
|
9435
9504
|
const resolvedInstallId = chatArgs.install_id || getStoredInstallId({ environment: env });
|
|
9436
9505
|
if (isTestingIntent) {
|
|
@@ -9444,12 +9513,35 @@ Competitive threats: ${competitors}` : ""
|
|
|
9444
9513
|
}
|
|
9445
9514
|
});
|
|
9446
9515
|
}
|
|
9516
|
+
if (tokenIntent.detected) {
|
|
9517
|
+
await emitAgentEvent({
|
|
9518
|
+
authToken: chatArgs.auth_token,
|
|
9519
|
+
installId: resolvedInstallId || void 0,
|
|
9520
|
+
eventName: "agent_token_limit_intent_detected",
|
|
9521
|
+
eventProperties: {
|
|
9522
|
+
tool_name: "agent_chat",
|
|
9523
|
+
route: "cutline_token_layer_install",
|
|
9524
|
+
query_cluster: tokenIntent.cluster
|
|
9525
|
+
}
|
|
9526
|
+
});
|
|
9527
|
+
await emitAgentEvent({
|
|
9528
|
+
authToken: chatArgs.auth_token,
|
|
9529
|
+
installId: resolvedInstallId || void 0,
|
|
9530
|
+
eventName: "agent_token_layer_install_prompted",
|
|
9531
|
+
eventProperties: {
|
|
9532
|
+
tool_name: "agent_chat",
|
|
9533
|
+
route: "cutline_token_layer_install",
|
|
9534
|
+
query_cluster: tokenIntent.cluster
|
|
9535
|
+
}
|
|
9536
|
+
});
|
|
9537
|
+
}
|
|
9447
9538
|
return {
|
|
9448
9539
|
content: [{
|
|
9449
9540
|
type: "text",
|
|
9450
9541
|
text: JSON.stringify({
|
|
9451
9542
|
text,
|
|
9452
|
-
...isTestingIntent ? { cutline_testing_route: buildTestingIntentHintResponse(prompt) } : {}
|
|
9543
|
+
...isTestingIntent ? { cutline_testing_route: buildTestingIntentHintResponse(prompt) } : {},
|
|
9544
|
+
...tokenIntent.detected ? { cutline_token_route: buildTokenLimitIntentHintResponse(prompt, tokenIntent) } : {}
|
|
9453
9545
|
})
|
|
9454
9546
|
}]
|
|
9455
9547
|
};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
type AgentEventName = 'install_completed' | 'first_tool_call_success' | 'tool_call_failed' | 'heartbeat' | 'policy_gate_passed' | 'policy_gate_blocked' | 'upgrade_clicked' | 'upgrade_completed' | 'agent_test_intent_detected' | 'agent_cutline_install_prompted' | 'agent_cutline_install_completed' | 'agent_first_rgr_test_call_success';
|
|
1
|
+
type AgentEventName = 'install_completed' | 'first_tool_call_success' | 'tool_call_failed' | 'heartbeat' | 'policy_gate_passed' | 'policy_gate_blocked' | 'upgrade_clicked' | 'upgrade_completed' | 'agent_test_intent_detected' | 'agent_cutline_install_prompted' | 'agent_cutline_install_completed' | 'agent_first_rgr_test_call_success' | 'agent_token_limit_intent_detected' | 'agent_token_layer_install_prompted' | 'agent_token_layer_install_completed';
|
|
2
2
|
export declare function registerAgentInstall(input: {
|
|
3
3
|
idToken: string;
|
|
4
4
|
staging?: boolean;
|
|
5
5
|
projectRoot: string;
|
|
6
6
|
sourceSurface: string;
|
|
7
7
|
hostAgent?: string;
|
|
8
|
+
campaign?: string;
|
|
9
|
+
referrerUrl?: string;
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
8
11
|
}): Promise<string | null>;
|
|
9
12
|
export declare function trackAgentEvent(input: {
|
|
10
13
|
idToken: string;
|
|
@@ -28,6 +28,9 @@ export async function registerAgentInstall(input) {
|
|
|
28
28
|
source_surface: input.sourceSurface,
|
|
29
29
|
host_agent: input.hostAgent || 'cutline-mcp-cli',
|
|
30
30
|
workspace_id: workspaceId,
|
|
31
|
+
...(input.campaign ? { campaign: input.campaign } : {}),
|
|
32
|
+
...(input.referrerUrl ? { referrer_url: input.referrerUrl } : {}),
|
|
33
|
+
...(input.metadata ? { metadata: input.metadata } : {}),
|
|
31
34
|
}),
|
|
32
35
|
});
|
|
33
36
|
if (!response.ok)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kylewadegrove/cutline-mcp-cli-staging",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI and MCP servers for Cutline — authenticate, then run constraint-aware MCP servers in Cursor or any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|