@kylewadegrove/cutline-mcp-cli-staging 0.4.0 → 0.6.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.
@@ -1,4 +1,8 @@
1
1
  export declare function initCommand(options: {
2
2
  projectRoot?: string;
3
3
  staging?: boolean;
4
+ sourceSurface?: string;
5
+ campaign?: string;
6
+ queryCluster?: string;
7
+ hostAgent?: string;
4
8
  }): Promise<void>;
@@ -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
  }
@@ -4,4 +4,8 @@ export declare function setupCommand(options: {
4
4
  projectRoot?: string;
5
5
  hideAuditDimension?: string[];
6
6
  hideAuditDimensions?: string;
7
+ sourceSurface?: string;
8
+ campaign?: string;
9
+ queryCluster?: string;
10
+ hostAgent?: string;
7
11
  }): Promise<void>;
@@ -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({ projectRoot: options.projectRoot, staging: options.staging });
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
- .action((opts) => initCommand({ projectRoot: opts.projectRoot, staging: opts.staging }));
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.4.0",
3
+ "version": "0.6.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",