@kylewadegrove/cutline-mcp-cli-staging 0.2.0 → 0.4.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 +12 -0
- package/dist/commands/init.js +12 -0
- package/dist/commands/setup.js +15 -0
- package/dist/servers/cutline-server.js +163 -36
- package/dist/utils/agent-funnel.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,6 +35,16 @@ cutline-mcp setup
|
|
|
35
35
|
|
|
36
36
|
Then ask your AI agent: **"use cutline"**
|
|
37
37
|
|
|
38
|
+
For test-heavy flows, use the explicit bootstrap + route:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx -y @vibekiln/cutline-mcp-cli@latest setup
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then ask:
|
|
45
|
+
- `Write tests for this PR`
|
|
46
|
+
- `use cutline to generate and run constraint-grounded tests for this scope increase`
|
|
47
|
+
|
|
38
48
|
Cutline interprets intent and tier:
|
|
39
49
|
- Natural variants also work: `use cutline to ...`, `using cutline, ...`, `with cutline ...`
|
|
40
50
|
- Free/default: runs `code_audit` (generic codebase scan)
|
|
@@ -185,6 +195,8 @@ The `init` command creates rules that make your AI coding agent follow the Red-G
|
|
|
185
195
|
3. **Verify** — Run a code audit to check coverage
|
|
186
196
|
4. **Complete** — Mark the phase done to update readiness scores
|
|
187
197
|
|
|
198
|
+
When the agent detects testing intent (write/generate/validate tests), it should route through Cutline first and, if not configured, prompt the install bootstrap command above before continuing.
|
|
199
|
+
|
|
188
200
|
### Compliance Frameworks
|
|
189
201
|
|
|
190
202
|
Cutline auto-detects your stack and loads the appropriate compliance constraints:
|
package/dist/commands/init.js
CHANGED
|
@@ -129,6 +129,12 @@ If the user invokes Cutline naturally (for example: **"use cutline"**, **"use cu
|
|
|
129
129
|
- Free/default intent: run \`code_audit(project_root)\` (aka "security vibe check")
|
|
130
130
|
- Premium product-linked intent: run \`engineering_audit(product_id, project_root)\`
|
|
131
131
|
- Feature implementation intent: run \`rgr_plan(...)\` then \`constraints_auto(...)\`
|
|
132
|
+
|
|
133
|
+
## Testing Intent Auto-Route
|
|
134
|
+
|
|
135
|
+
If asked to write, generate, validate, or improve tests, route to Cutline first:
|
|
136
|
+
- If Cutline MCP is missing, provide install bootstrap: \`npx -y @vibekiln/cutline-mcp-cli@latest setup\`
|
|
137
|
+
- Then run: \`use cutline to generate and run constraint-grounded tests for this scope increase\`
|
|
132
138
|
`;
|
|
133
139
|
}
|
|
134
140
|
function cursorConstraintsRule(config, tier) {
|
|
@@ -219,6 +225,12 @@ If the user invokes Cutline naturally (for example: **"use cutline"**, **"use cu
|
|
|
219
225
|
- Free/default intent: \`code_audit(project_root)\` (aka "security vibe check")
|
|
220
226
|
- Premium product-linked intent: \`engineering_audit(product_id, project_root)\`
|
|
221
227
|
- Feature implementation intent: \`rgr_plan(...)\` then \`constraints_auto(...)\`
|
|
228
|
+
|
|
229
|
+
## Testing Intent Auto-Route
|
|
230
|
+
|
|
231
|
+
If asked to write, generate, validate, or improve tests, route to Cutline first:
|
|
232
|
+
- If Cutline MCP is missing, provide install bootstrap: \`npx -y @vibekiln/cutline-mcp-cli@latest setup\`
|
|
233
|
+
- Then run: \`use cutline to generate and run constraint-grounded tests for this scope increase\`
|
|
222
234
|
`;
|
|
223
235
|
}
|
|
224
236
|
function ensureGitignore(projectRoot, patterns) {
|
package/dist/commands/setup.js
CHANGED
|
@@ -403,6 +403,16 @@ export async function setupCommand(options) {
|
|
|
403
403
|
flow: 'onboarding',
|
|
404
404
|
},
|
|
405
405
|
});
|
|
406
|
+
await trackAgentEvent({
|
|
407
|
+
idToken,
|
|
408
|
+
installId,
|
|
409
|
+
eventName: 'agent_cutline_install_completed',
|
|
410
|
+
staging: options.staging,
|
|
411
|
+
eventProperties: {
|
|
412
|
+
command: 'setup',
|
|
413
|
+
route: 'testing_rgr',
|
|
414
|
+
},
|
|
415
|
+
});
|
|
406
416
|
}
|
|
407
417
|
}
|
|
408
418
|
// ── 5. Claude Code one-liners ────────────────────────────────────────────
|
|
@@ -424,9 +434,11 @@ export async function setupCommand(options) {
|
|
|
424
434
|
const items = [
|
|
425
435
|
{ cmd: 'use cutline', desc: 'Magic phrase (also works with "use cutline to...", "using cutline...", "with cutline...") — Cutline infers intent and routes to the right flow' },
|
|
426
436
|
{ cmd: 'Run a deep dive on my product idea', desc: 'Pre-mortem analysis — risks, assumptions, experiments' },
|
|
437
|
+
{ cmd: 'Write tests for this PR', desc: 'Testing intent shortcut — Cutline should route to graph-grounded test generation + RGR verification loop' },
|
|
427
438
|
{ cmd: 'Plan this feature with constraints from my product', desc: 'RGR plan — constraint-aware implementation roadmap' },
|
|
428
439
|
{ cmd: 'Run a security vibe check on this codebase', desc: 'Free security vibe check (`code_audit`) — security, reliability, and scalability (generic, not product-linked)' },
|
|
429
440
|
{ cmd: 'Run an engineering vibe check for my product', desc: 'Premium deep vibe check (`engineering_audit`) — product-linked analysis + RGR remediation plan' },
|
|
441
|
+
{ cmd: 'use cutline to generate and run tests for this scope increase', desc: 'Preferred prompt for pervasive red/green loop execution' },
|
|
430
442
|
{ cmd: 'Check constraints for src/api/upload.ts', desc: 'Get NFR boundaries for a specific file' },
|
|
431
443
|
{ cmd: 'Generate .cutline.md for my product', desc: 'Write the constraint routing engine' },
|
|
432
444
|
{ cmd: 'What does my persona think about X?', desc: 'AI persona feedback on features' },
|
|
@@ -441,6 +453,8 @@ export async function setupCommand(options) {
|
|
|
441
453
|
const items = [
|
|
442
454
|
{ cmd: 'use cutline', desc: 'Magic phrase (also works with "use cutline to...", "using cutline...", "with cutline...") — Cutline routes to the highest-value free flow for your intent' },
|
|
443
455
|
{ cmd: 'Run a security vibe check on this codebase', desc: 'Free security vibe check (`code_audit`) — security, reliability, and scalability scan (3/month free)' },
|
|
456
|
+
{ cmd: 'Write tests for this PR', desc: 'Testing intent shortcut — prompts install/setup guidance if Cutline MCP is missing' },
|
|
457
|
+
{ cmd: 'use cutline to generate tests for this scope increase', desc: 'Runs free-tier test-oriented routing and verification guidance where available' },
|
|
444
458
|
{ cmd: 'Explore a product idea', desc: 'Free 6-act discovery flow to identify pain points and opportunities' },
|
|
445
459
|
{ cmd: 'Continue my exploration session', desc: 'Resume and refine an existing free exploration conversation' },
|
|
446
460
|
];
|
|
@@ -454,6 +468,7 @@ export async function setupCommand(options) {
|
|
|
454
468
|
}
|
|
455
469
|
console.log();
|
|
456
470
|
console.log(chalk.dim(` cutline-mcp v${version} · docs: https://thecutline.ai/docs/setup`));
|
|
471
|
+
console.log(chalk.dim(' Testing bootstrap:'), chalk.cyan('npx -y @vibekiln/cutline-mcp-cli@latest setup'));
|
|
457
472
|
console.log(chalk.dim(' Optional repo policy contract:'), chalk.cyan('cutline-mcp policy-init'));
|
|
458
473
|
console.log();
|
|
459
474
|
}
|
|
@@ -6596,6 +6596,11 @@ async function handleCodeAudit(args, deps) {
|
|
|
6596
6596
|
},
|
|
6597
6597
|
sensitiveDataCount: scanResult.sensitive_data.fields.length,
|
|
6598
6598
|
rgrPlan,
|
|
6599
|
+
rgrAutoTrigger: {
|
|
6600
|
+
enabled: true,
|
|
6601
|
+
onScopeIncrease: true,
|
|
6602
|
+
executionMode: "local_vitest"
|
|
6603
|
+
},
|
|
6599
6604
|
securityGaps: graphAnalysis.securityGaps
|
|
6600
6605
|
}
|
|
6601
6606
|
};
|
|
@@ -7573,6 +7578,46 @@ function evaluateRepoPolicy(requirements, observed) {
|
|
|
7573
7578
|
};
|
|
7574
7579
|
}
|
|
7575
7580
|
|
|
7581
|
+
// ../mcp/dist/mcp/src/shared/repo-policy-response.js
|
|
7582
|
+
function resolveTelemetryAttribution(input) {
|
|
7583
|
+
if (input.providedInstallId) {
|
|
7584
|
+
return "provided";
|
|
7585
|
+
}
|
|
7586
|
+
if (input.resolvedInstallId) {
|
|
7587
|
+
return "auto_resolved";
|
|
7588
|
+
}
|
|
7589
|
+
return "missing";
|
|
7590
|
+
}
|
|
7591
|
+
function buildInvalidPolicyResponse(input) {
|
|
7592
|
+
return {
|
|
7593
|
+
status: "invalid_policy",
|
|
7594
|
+
certification_id: `policy_${(input.now || /* @__PURE__ */ new Date()).getTime()}`,
|
|
7595
|
+
blocking_reasons: [`Policy manifest not found at ${input.manifestPath}`],
|
|
7596
|
+
required_actions: [
|
|
7597
|
+
"Create policy manifest: cutline-mcp policy-init",
|
|
7598
|
+
"Commit cutline.json and re-run validate_repo_policy"
|
|
7599
|
+
],
|
|
7600
|
+
telemetry_attribution: input.telemetryAttribution,
|
|
7601
|
+
generated_at: (input.now || /* @__PURE__ */ new Date()).toISOString()
|
|
7602
|
+
};
|
|
7603
|
+
}
|
|
7604
|
+
function buildPolicyVerdictResponse(input) {
|
|
7605
|
+
return {
|
|
7606
|
+
status: input.verdict.status,
|
|
7607
|
+
certification_id: `policy_${(input.now || /* @__PURE__ */ new Date()).getTime()}`,
|
|
7608
|
+
manifest_path: input.manifestPath,
|
|
7609
|
+
policy_name: input.policyName || "cutline-policy",
|
|
7610
|
+
schema_version: input.schemaVersion || "unknown",
|
|
7611
|
+
verification_requirements: input.verdict.verification_requirements,
|
|
7612
|
+
observed_evidence: input.observedEvidence,
|
|
7613
|
+
telemetry_attribution: input.telemetryAttribution,
|
|
7614
|
+
checks: input.verdict.checks,
|
|
7615
|
+
blocking_reasons: input.verdict.blocking_reasons,
|
|
7616
|
+
required_actions: input.verdict.required_actions,
|
|
7617
|
+
generated_at: (input.now || /* @__PURE__ */ new Date()).toISOString()
|
|
7618
|
+
};
|
|
7619
|
+
}
|
|
7620
|
+
|
|
7576
7621
|
// ../mcp/dist/mcp/src/cutline-server.js
|
|
7577
7622
|
function mcpAudit(entry) {
|
|
7578
7623
|
console.error(JSON.stringify({
|
|
@@ -7609,6 +7654,43 @@ async function emitPolicyGateEvent(input) {
|
|
|
7609
7654
|
} catch {
|
|
7610
7655
|
}
|
|
7611
7656
|
}
|
|
7657
|
+
async function emitAgentEvent(input) {
|
|
7658
|
+
if (!input.authToken || !input.installId)
|
|
7659
|
+
return;
|
|
7660
|
+
const siteUrl = (process.env.NEXT_PUBLIC_SITE_URL || "https://thecutline.ai").replace(/\/$/, "");
|
|
7661
|
+
try {
|
|
7662
|
+
await fetch(`${siteUrl}/api/agent/event`, {
|
|
7663
|
+
method: "POST",
|
|
7664
|
+
headers: {
|
|
7665
|
+
"Content-Type": "application/json",
|
|
7666
|
+
Authorization: `Bearer ${input.authToken}`
|
|
7667
|
+
},
|
|
7668
|
+
body: JSON.stringify({
|
|
7669
|
+
install_id: input.installId,
|
|
7670
|
+
event_name: input.eventName,
|
|
7671
|
+
event_properties: input.eventProperties || {}
|
|
7672
|
+
})
|
|
7673
|
+
});
|
|
7674
|
+
} catch {
|
|
7675
|
+
}
|
|
7676
|
+
}
|
|
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
|
+
}
|
|
7612
7694
|
var DEFAULT_MODEL = process.env.MODEL_ID || "gemini-2.5-pro";
|
|
7613
7695
|
var GOVERNANCE_ENFORCEMENT = (process.env.CUTLINE_GOVERNANCE_ENFORCEMENT || "advisory").toLowerCase() === "enforced";
|
|
7614
7696
|
function buildGovernanceEnvelope(input) {
|
|
@@ -8116,7 +8198,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
8116
8198
|
type: "object",
|
|
8117
8199
|
properties: {
|
|
8118
8200
|
prompt: { type: "string" },
|
|
8119
|
-
wikiMarkdown: { type: "string" }
|
|
8201
|
+
wikiMarkdown: { type: "string" },
|
|
8202
|
+
auth_token: { type: "string", description: "Optional auth token for telemetry attribution" },
|
|
8203
|
+
install_id: { type: "string", description: "Optional install ID for telemetry attribution" }
|
|
8120
8204
|
},
|
|
8121
8205
|
required: ["prompt"]
|
|
8122
8206
|
}
|
|
@@ -8145,7 +8229,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
8145
8229
|
inputSchema: {
|
|
8146
8230
|
type: "object",
|
|
8147
8231
|
properties: {
|
|
8148
|
-
prompt: { type: "string" }
|
|
8232
|
+
prompt: { type: "string" },
|
|
8233
|
+
auth_token: { type: "string", description: "Optional auth token for telemetry attribution" },
|
|
8234
|
+
install_id: { type: "string", description: "Optional install ID for telemetry attribution" }
|
|
8149
8235
|
},
|
|
8150
8236
|
required: ["prompt"]
|
|
8151
8237
|
}
|
|
@@ -8581,17 +8667,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
8581
8667
|
},
|
|
8582
8668
|
{
|
|
8583
8669
|
name: "get_assurance_manifest",
|
|
8584
|
-
description:
|
|
8670
|
+
description: `\u{1F513} AUTHENTICATED-FREE - Fetch signed assurance proof for "prove it's safe", "production-ready", and audit verification prompts.`,
|
|
8585
8671
|
inputSchema: {
|
|
8586
8672
|
type: "object",
|
|
8587
8673
|
properties: {
|
|
8588
|
-
url: { type: "string", description: "Optional assurance URL override (default: NEXT_PUBLIC_SITE_URL/.well-known/cutline-assurance.json)" }
|
|
8674
|
+
url: { type: "string", description: "Optional assurance URL override (default: NEXT_PUBLIC_SITE_URL/.well-known/cutline-assurance.json). Use target app domain when verifying deployed builds." }
|
|
8589
8675
|
}
|
|
8590
8676
|
}
|
|
8591
8677
|
},
|
|
8592
8678
|
{
|
|
8593
8679
|
name: "validate_repo_policy",
|
|
8594
|
-
description:
|
|
8680
|
+
description: "\u{1F513} AUTHENTICATED-FREE - Run deterministic policy validation for secure/deploy-ready/audit prompts and return a machine-readable verdict object.",
|
|
8595
8681
|
inputSchema: {
|
|
8596
8682
|
type: "object",
|
|
8597
8683
|
properties: {
|
|
@@ -8922,9 +9008,32 @@ Why AI: ${idea.whyAI}`
|
|
|
8922
9008
|
};
|
|
8923
9009
|
}
|
|
8924
9010
|
if (name2 === "trial_generate") {
|
|
8925
|
-
const
|
|
9011
|
+
const trialArgs = args;
|
|
9012
|
+
const { prompt } = trialArgs;
|
|
8926
9013
|
const text = await cfGenerateTrialRun(prompt);
|
|
8927
|
-
|
|
9014
|
+
const isTestingIntent = isTestingIntentPrompt(prompt);
|
|
9015
|
+
const env = process.env.CUTLINE_ENV === "staging" ? "staging" : "production";
|
|
9016
|
+
const resolvedInstallId = trialArgs.install_id || getStoredInstallId({ environment: env });
|
|
9017
|
+
if (isTestingIntent) {
|
|
9018
|
+
await emitAgentEvent({
|
|
9019
|
+
authToken: trialArgs.auth_token,
|
|
9020
|
+
installId: resolvedInstallId || void 0,
|
|
9021
|
+
eventName: "agent_test_intent_detected",
|
|
9022
|
+
eventProperties: {
|
|
9023
|
+
tool_name: "trial_generate",
|
|
9024
|
+
route: "cutline_testing_rgr"
|
|
9025
|
+
}
|
|
9026
|
+
});
|
|
9027
|
+
}
|
|
9028
|
+
return {
|
|
9029
|
+
content: [{
|
|
9030
|
+
type: "text",
|
|
9031
|
+
text: JSON.stringify({
|
|
9032
|
+
text,
|
|
9033
|
+
...isTestingIntent ? { cutline_testing_route: buildTestingIntentHintResponse(prompt) } : {}
|
|
9034
|
+
})
|
|
9035
|
+
}]
|
|
9036
|
+
};
|
|
8928
9037
|
}
|
|
8929
9038
|
if (name2 === "get_assurance_manifest") {
|
|
8930
9039
|
const { url } = args;
|
|
@@ -8958,7 +9067,10 @@ Why AI: ${idea.whyAI}`
|
|
|
8958
9067
|
await resolveAuthContextFree(policyArgs.auth_token);
|
|
8959
9068
|
const env = process.env.CUTLINE_ENV === "staging" ? "staging" : "production";
|
|
8960
9069
|
const resolvedInstallId = policyArgs.install_id || getStoredInstallId({ environment: env });
|
|
8961
|
-
const telemetryAttribution =
|
|
9070
|
+
const telemetryAttribution = resolveTelemetryAttribution({
|
|
9071
|
+
providedInstallId: policyArgs.install_id,
|
|
9072
|
+
resolvedInstallId: resolvedInstallId || void 0
|
|
9073
|
+
});
|
|
8962
9074
|
const { existsSync, readFileSync } = await import("node:fs");
|
|
8963
9075
|
const { resolve, join: join4 } = await import("node:path");
|
|
8964
9076
|
const manifestPath = resolve(policyArgs.manifest_path || join4(policyArgs.project_root, "cutline.json"));
|
|
@@ -8975,17 +9087,10 @@ Why AI: ${idea.whyAI}`
|
|
|
8975
9087
|
return {
|
|
8976
9088
|
content: [{
|
|
8977
9089
|
type: "text",
|
|
8978
|
-
text: JSON.stringify({
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
required_actions: [
|
|
8983
|
-
"Create policy manifest: cutline-mcp policy-init",
|
|
8984
|
-
"Commit cutline.json and re-run validate_repo_policy"
|
|
8985
|
-
],
|
|
8986
|
-
telemetry_attribution: telemetryAttribution,
|
|
8987
|
-
generated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
8988
|
-
}, null, 2)
|
|
9090
|
+
text: JSON.stringify(buildInvalidPolicyResponse({
|
|
9091
|
+
manifestPath,
|
|
9092
|
+
telemetryAttribution
|
|
9093
|
+
}), null, 2)
|
|
8989
9094
|
}]
|
|
8990
9095
|
};
|
|
8991
9096
|
}
|
|
@@ -9012,20 +9117,14 @@ Why AI: ${idea.whyAI}`
|
|
|
9012
9117
|
return {
|
|
9013
9118
|
content: [{
|
|
9014
9119
|
type: "text",
|
|
9015
|
-
text: JSON.stringify({
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
telemetry_attribution: telemetryAttribution,
|
|
9024
|
-
checks: verdict.checks,
|
|
9025
|
-
blocking_reasons: verdict.blocking_reasons,
|
|
9026
|
-
required_actions: verdict.required_actions,
|
|
9027
|
-
generated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
9028
|
-
}, null, 2)
|
|
9120
|
+
text: JSON.stringify(buildPolicyVerdictResponse({
|
|
9121
|
+
verdict,
|
|
9122
|
+
manifestPath,
|
|
9123
|
+
policyName: manifest?.policy_name,
|
|
9124
|
+
schemaVersion: manifest?.schema_version,
|
|
9125
|
+
observedEvidence: policyArgs.observed || {},
|
|
9126
|
+
telemetryAttribution
|
|
9127
|
+
}), null, 2)
|
|
9029
9128
|
}]
|
|
9030
9129
|
};
|
|
9031
9130
|
}
|
|
@@ -9328,9 +9427,32 @@ Competitive threats: ${competitors}` : ""
|
|
|
9328
9427
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
9329
9428
|
}
|
|
9330
9429
|
case "agent_chat": {
|
|
9331
|
-
const
|
|
9430
|
+
const chatArgs = args;
|
|
9431
|
+
const { prompt, wikiMarkdown } = chatArgs;
|
|
9332
9432
|
const text = await cfGenerateChatSuggestion(prompt, wikiMarkdown);
|
|
9333
|
-
|
|
9433
|
+
const isTestingIntent = isTestingIntentPrompt(prompt);
|
|
9434
|
+
const env = process.env.CUTLINE_ENV === "staging" ? "staging" : "production";
|
|
9435
|
+
const resolvedInstallId = chatArgs.install_id || getStoredInstallId({ environment: env });
|
|
9436
|
+
if (isTestingIntent) {
|
|
9437
|
+
await emitAgentEvent({
|
|
9438
|
+
authToken: chatArgs.auth_token,
|
|
9439
|
+
installId: resolvedInstallId || void 0,
|
|
9440
|
+
eventName: "agent_test_intent_detected",
|
|
9441
|
+
eventProperties: {
|
|
9442
|
+
tool_name: "agent_chat",
|
|
9443
|
+
route: "cutline_testing_rgr"
|
|
9444
|
+
}
|
|
9445
|
+
});
|
|
9446
|
+
}
|
|
9447
|
+
return {
|
|
9448
|
+
content: [{
|
|
9449
|
+
type: "text",
|
|
9450
|
+
text: JSON.stringify({
|
|
9451
|
+
text,
|
|
9452
|
+
...isTestingIntent ? { cutline_testing_route: buildTestingIntentHintResponse(prompt) } : {}
|
|
9453
|
+
})
|
|
9454
|
+
}]
|
|
9455
|
+
};
|
|
9334
9456
|
}
|
|
9335
9457
|
// Integrations
|
|
9336
9458
|
case "integrations_create_issues": {
|
|
@@ -10899,6 +11021,11 @@ ${JSON.stringify(metrics, null, 2)}` }
|
|
|
10899
11021
|
...plan,
|
|
10900
11022
|
entity: rgrMatched[0].name,
|
|
10901
11023
|
complexity,
|
|
11024
|
+
auto_execution: {
|
|
11025
|
+
scope_increase_triggers_rgr: true,
|
|
11026
|
+
mode: "pervasive",
|
|
11027
|
+
expected_runner: "local_vitest"
|
|
11028
|
+
},
|
|
10902
11029
|
governance
|
|
10903
11030
|
}, null, 2)
|
|
10904
11031
|
}]
|
|
@@ -11425,7 +11552,7 @@ Meta: ${JSON.stringify({
|
|
|
11425
11552
|
mode: "product",
|
|
11426
11553
|
codeContext: payload.codeContext || null
|
|
11427
11554
|
});
|
|
11428
|
-
runInput.productId = newJobId;
|
|
11555
|
+
runInput.productId = String(auditArgs.product_id || newJobId);
|
|
11429
11556
|
await updatePremortem(newJobId, { payload: runInput });
|
|
11430
11557
|
return { jobId: newJobId };
|
|
11431
11558
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type AgentEventName = 'install_completed' | 'first_tool_call_success' | 'tool_call_failed' | 'heartbeat' | 'policy_gate_passed' | 'policy_gate_blocked' | 'upgrade_clicked' | 'upgrade_completed';
|
|
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';
|
|
2
2
|
export declare function registerAgentInstall(input: {
|
|
3
3
|
idToken: string;
|
|
4
4
|
staging?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kylewadegrove/cutline-mcp-cli-staging",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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",
|