@triedotdev/mcp 1.0.143 → 1.0.145

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 CHANGED
@@ -374,9 +374,15 @@ Links PRs to changed files and to Linear tickets mentioned in PR descriptions. R
374
374
  # Via MCP
375
375
  trie_cloud_fix action:configure apiKey:"key-..."
376
376
  trie_cloud_fix action:dispatch issueIds:["issue-1", "issue-2"]
377
+
378
+ # Force cloud dispatch (bypass triage when user explicitly wants cloud)
379
+ trie_cloud_fix action:dispatch forceCloud:true
380
+
381
+ # Ad-hoc dispatch (no scan issues — e.g. from trie_propose_fix)
382
+ trie_cloud_fix action:dispatch file:"src/storage/tiered-storage.ts" issue:"Concurrent file writes corrupt ledger" fix:"Add file locking and atomic writes"
377
383
  ```
378
384
 
379
- The cloud agent runs in an isolated VM, applies the fix, runs tests, captures screenshots, and opens a PR. Requires `CURSOR_API_KEY`. Use `trie_fix action:route` first to see which issues qualify.
385
+ The cloud agent runs in an isolated VM, applies the fix, runs tests, captures screenshots, and opens a PR. Requires `CURSOR_API_KEY`. Use `trie_fix action:route` first to see which issues qualify. Add `forceCloud:true` to bypass triage when you explicitly want cloud.
380
386
 
381
387
  ### Fix Triage System
382
388
 
@@ -5520,7 +5520,7 @@ import { join as join2 } from "path";
5520
5520
  import { execSync } from "child_process";
5521
5521
 
5522
5522
  // src/integrations/cursor-cloud-agent.ts
5523
- var BASE_URL = "https://api.cursor.com/v1";
5523
+ var BASE_URL = "https://api.cursor.com/v0";
5524
5524
  var CursorCloudAgentClient = class {
5525
5525
  apiKey;
5526
5526
  constructor(apiKey) {
@@ -5528,13 +5528,16 @@ var CursorCloudAgentClient = class {
5528
5528
  }
5529
5529
  /**
5530
5530
  * Dispatch an issue to a cloud agent for fixing.
5531
+ * Uses Cursor Background Agent API: POST /agents
5531
5532
  */
5532
5533
  async dispatch(issue, triageResult, repoUrl, branch) {
5533
- const prompt = this.buildPrompt(issue, triageResult);
5534
+ const promptText = this.buildPrompt(issue, triageResult);
5534
5535
  const body = {
5535
- prompt,
5536
- repo: repoUrl,
5537
- branch,
5536
+ prompt: { text: promptText },
5537
+ source: {
5538
+ repository: repoUrl,
5539
+ ref: branch
5540
+ },
5538
5541
  metadata: {
5539
5542
  issueId: issue.id,
5540
5543
  file: issue.file,
@@ -5543,19 +5546,20 @@ var CursorCloudAgentClient = class {
5543
5546
  agent: issue.agent
5544
5547
  }
5545
5548
  };
5546
- const res = await this.request("POST", "/agents/tasks", body);
5549
+ const res = await this.request("POST", "/agents", body);
5547
5550
  return {
5548
5551
  jobId: res.id ?? res.taskId ?? res.jobId,
5549
5552
  status: "dispatched",
5550
5553
  artifactUrls: [],
5551
- dispatchedAt: (/* @__PURE__ */ new Date()).toISOString()
5554
+ dispatchedAt: res.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
5552
5555
  };
5553
5556
  }
5554
5557
  /**
5555
5558
  * Poll job status.
5559
+ * Uses Cursor Background Agent API: GET /agents/:id
5556
5560
  */
5557
5561
  async poll(jobId) {
5558
- const res = await this.request("GET", `/agents/tasks/${jobId}`);
5562
+ const res = await this.request("GET", `/agents/${jobId}`);
5559
5563
  const status = mapStatus(res.status);
5560
5564
  const prUrl = extractPrUrl(res);
5561
5565
  const artifactUrls = this.extractArtifacts(res);
@@ -5565,14 +5569,15 @@ var CursorCloudAgentClient = class {
5565
5569
  * Get artifact URLs for a completed job.
5566
5570
  */
5567
5571
  async getArtifacts(jobId) {
5568
- const res = await this.request("GET", `/agents/tasks/${jobId}`);
5572
+ const res = await this.request("GET", `/agents/${jobId}`);
5569
5573
  return this.extractArtifacts(res);
5570
5574
  }
5571
5575
  /**
5572
5576
  * Cancel a running job.
5577
+ * Uses Cursor Background Agent API: DELETE /agents/:id
5573
5578
  */
5574
5579
  async cancelJob(jobId) {
5575
- await this.request("DELETE", `/agents/tasks/${jobId}`);
5580
+ await this.request("DELETE", `/agents/${jobId}`);
5576
5581
  }
5577
5582
  // --------------------------------------------------------------------------
5578
5583
  // Internal
@@ -5616,7 +5621,10 @@ var CursorCloudAgentClient = class {
5616
5621
  );
5617
5622
  }
5618
5623
  if (res.status === 404) {
5619
- throw new Error(`Job not found: ${path2}`);
5624
+ const isLaunch = path2 === "/agents" && method === "POST";
5625
+ throw new Error(
5626
+ isLaunch ? "Cursor Background Agent API endpoint not found. Ensure your Cursor API key has Background Agent access (cursor.com/dashboard \u2192 Integrations)." : `Job not found: ${path2}`
5627
+ );
5620
5628
  }
5621
5629
  if (res.status >= 500) {
5622
5630
  throw new Error(
@@ -6381,33 +6389,61 @@ var TrieCloudFixTool = class {
6381
6389
  const apiKey = await this.resolveApiKey(workDir);
6382
6390
  if (!apiKey) return this.setupGuard();
6383
6391
  const config = await loadAutonomyConfig(workDir);
6392
+ const forceCloud = args?.forceCloud === true;
6384
6393
  console.log("About to resolve issues...");
6385
- const allIssues = await this.resolveIssues(args?.issueIds);
6386
- console.log(`Resolved ${allIssues.length} issues`);
6394
+ let allIssues = await this.resolveIssues(args?.issueIds);
6395
+ if (allIssues.length === 0 && args?.file && args?.issue && args?.fix) {
6396
+ const adHocId = `ad-hoc-${Date.now()}`;
6397
+ allIssues = [{
6398
+ id: adHocId,
6399
+ severity: args.severity ?? "critical",
6400
+ effort: args.effort ?? "hard",
6401
+ issue: args.issue,
6402
+ fix: args.fix,
6403
+ file: args.file,
6404
+ line: args.line ?? 1,
6405
+ confidence: 0.9,
6406
+ autoFixable: false,
6407
+ agent: "user",
6408
+ category: args.category
6409
+ }];
6410
+ console.log(`Created ad-hoc issue ${adHocId} for cloud dispatch`);
6411
+ }
6387
6412
  if (allIssues.length === 0) {
6388
- return this.text("No issues to dispatch. Run trie_scan to detect new issues, or check memory with trie_memory action:recent.");
6413
+ return this.text("No issues to dispatch. Run trie_scan to detect new issues, or check memory with trie_memory action:recent. For ad-hoc fixes, pass file, issue, and fix.");
6389
6414
  }
6390
6415
  const { results, summary } = triageIssues(allIssues, void 0, void 0, config);
6391
6416
  const lines = [];
6392
- lines.push(formatTriageTable(results, allIssues));
6393
- lines.push("");
6394
- for (const issue of allIssues) {
6395
- const r = results.get(issue.id);
6396
- if (r && r.strategy !== "cloud-agent") {
6397
- lines.push(`Skipped ${issue.id}: routed to ${r.strategy} (score ${r.score >= 0 ? "+" : ""}${r.score} \u2014 ${r.reasons.join(", ")})`);
6417
+ const toDispatch = forceCloud ? allIssues : summary.cloudAgent;
6418
+ if (forceCloud) {
6419
+ lines.push("FIX ROUTING PLAN (forceCloud: bypassing triage)");
6420
+ lines.push("\u2500".repeat(68));
6421
+ for (const issue of allIssues) {
6422
+ lines.push(` ${shortPath2(issue.file)}:${issue.line ?? "?"} \u2192 cloud-agent (user requested)`);
6423
+ }
6424
+ lines.push("");
6425
+ } else {
6426
+ lines.push(formatTriageTable(results, allIssues));
6427
+ lines.push("");
6428
+ for (const issue of allIssues) {
6429
+ const r = results.get(issue.id);
6430
+ if (r && r.strategy !== "cloud-agent") {
6431
+ lines.push(`Skipped ${issue.id}: routed to ${r.strategy} (score ${r.score >= 0 ? "+" : ""}${r.score} \u2014 ${r.reasons.join(", ")})`);
6432
+ }
6433
+ }
6434
+ if (summary.cloudAgent.length === 0) {
6435
+ lines.push("\nNo issues qualify for cloud dispatch. Use trie_fix for local fixes.");
6436
+ lines.push("To force cloud dispatch: trie_cloud_fix action:dispatch forceCloud:true");
6437
+ return this.text(lines.join("\n"));
6398
6438
  }
6399
- }
6400
- if (summary.cloudAgent.length === 0) {
6401
- lines.push("\nNo issues qualify for cloud dispatch. Use trie_fix for local fixes.");
6402
- return this.text(lines.join("\n"));
6403
6439
  }
6404
6440
  const client = new CursorCloudAgentClient(apiKey);
6405
6441
  const repoUrl = this.getRepoUrl(workDir);
6406
6442
  const branch = this.getBranch(workDir);
6407
6443
  const store = await this.loadJobs(workDir);
6408
6444
  lines.push("\nDISPATCHED");
6409
- for (const issue of summary.cloudAgent) {
6410
- const triageResult = results.get(issue.id);
6445
+ for (const issue of toDispatch) {
6446
+ const triageResult = forceCloud ? { strategy: "cloud-agent", score: 6, confidence: 1, reasons: ["forceCloud: user requested cloud dispatch"], fallback: "local-ai" } : results.get(issue.id);
6411
6447
  try {
6412
6448
  const job = await client.dispatch(issue, triageResult, repoUrl, branch);
6413
6449
  store.jobs[issue.id] = {
@@ -7879,7 +7915,7 @@ var CHAT_TOOLS = [
7879
7915
  },
7880
7916
  {
7881
7917
  name: "trie_cloud_fix",
7882
- description: 'Dispatch issues to Cursor Cloud agents for verified, test-passing fixes. Use when the user asks to "spin up Cursor Cloud agent", "dispatch to cloud", or "run cloud fix". Requires CURSOR_API_KEY (set in Config \u2192 API Keys \u2192 Cursor, or export CURSOR_API_KEY). Actions: configure (save API key), dispatch (send issues to cloud), status (check job status), artifacts (get PR/screenshots).',
7918
+ description: 'Dispatch to Cursor Cloud agents. Default: triage routes issues. When user explicitly says they want cloud (e.g. "fix with cloud agent") \u2014 pass forceCloud:true to honor their choice, do not reject. For ad-hoc (no scan issues): pass file, issue, fix from prior trie_propose_fix. Actions: configure, dispatch, status, artifacts, cancel.',
7883
7919
  input_schema: {
7884
7920
  type: "object",
7885
7921
  properties: {
@@ -7897,6 +7933,17 @@ var CHAT_TOOLS = [
7897
7933
  items: { type: "string" },
7898
7934
  description: "Issue IDs to dispatch (for action:dispatch). Omit to dispatch all cloud-eligible issues."
7899
7935
  },
7936
+ forceCloud: {
7937
+ type: "boolean",
7938
+ description: "When true, bypass triage and dispatch ALL issues to cloud. Use when user explicitly requests cloud fix."
7939
+ },
7940
+ file: {
7941
+ type: "string",
7942
+ description: "For ad-hoc dispatch: file path (use with issue and fix when no scan issues)"
7943
+ },
7944
+ issue: { type: "string", description: "For ad-hoc dispatch: issue description" },
7945
+ fix: { type: "string", description: "For ad-hoc dispatch: suggested fix" },
7946
+ line: { type: "number", description: "For ad-hoc dispatch: line number" },
7900
7947
  jobId: {
7901
7948
  type: "string",
7902
7949
  description: "Job ID for action:artifacts or action:cancel"
@@ -8268,6 +8315,13 @@ ${truncated}`;
8268
8315
  if (input.apiKey) cloudFixArgs.apiKey = String(input.apiKey);
8269
8316
  if (Array.isArray(input.issueIds)) cloudFixArgs.issueIds = input.issueIds;
8270
8317
  if (input.jobId) cloudFixArgs.jobId = String(input.jobId);
8318
+ if (input.forceCloud === true) cloudFixArgs.forceCloud = true;
8319
+ if (input.file) cloudFixArgs.file = String(input.file);
8320
+ if (input.issue) cloudFixArgs.issue = String(input.issue);
8321
+ if (input.fix) cloudFixArgs.fix = String(input.fix);
8322
+ if (typeof input.line === "number") cloudFixArgs.line = input.line;
8323
+ if (input.severity) cloudFixArgs.severity = String(input.severity);
8324
+ if (input.effort) cloudFixArgs.effort = String(input.effort);
8271
8325
  const result = await cloudFixTool.execute(cloudFixArgs);
8272
8326
  return textFromResult(result);
8273
8327
  }
@@ -8452,10 +8506,17 @@ async function buildContext(workDir, dashboardState) {
8452
8506
  return parts.length > 0 ? parts.join("\n\n") : "No context data available yet.";
8453
8507
  }
8454
8508
  function chatHistoryToMessages(history) {
8455
- return history.map((m) => ({
8456
- role: m.role,
8457
- content: m.content
8458
- }));
8509
+ return history.map((m) => {
8510
+ let content = m.content;
8511
+ const fixes = m.pendingFixes ?? (m.pendingFix ? [m.pendingFix] : []);
8512
+ if (fixes.length > 0) {
8513
+ const fixCtx = fixes.map((f) => `file: ${f.file}, goal: ${f.goal}, violation: ${f.violation}${f.suggestedFix ? `, suggestedFix: ${f.suggestedFix}` : ""}`).join("; ");
8514
+ content = content ? `${content}
8515
+
8516
+ [Proposed fix context: ${fixCtx}]` : `[Proposed fix context: ${fixCtx}]`;
8517
+ }
8518
+ return { role: m.role, content };
8519
+ });
8459
8520
  }
8460
8521
  var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
8461
8522
 
@@ -8508,11 +8569,12 @@ var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
8508
8569
  5. AFTER the tool call completes, the system will ask for user confirmation - do NOT add your own confirmation message
8509
8570
  6. When the user says "yes", "yes to all", or "no", the system handles spawning Claude Code automatically
8510
8571
 
8511
- **When user asks to "spin up Cursor Cloud agent", "dispatch to cloud", or "run cloud fix":**
8512
- - You HAVE trie_cloud_fix \u2014 use it! Call trie_cloud_fix with action:dispatch to send issues to Cursor Cloud agents.
8513
- - If the tool returns "Cloud Agent dispatch requires a Cursor API key", tell the user: "Your Cursor API key isn't configured. Press 's' to open Config \u2192 API Keys \u2192 Cursor and add it, or run: trie_cloud_fix action:configure apiKey:"your-key""
8572
+ **When user asks to dispatch or fix with Cursor Cloud agent:**
8573
+ - Default: Call trie_cloud_fix action:dispatch \u2014 triage runs and routes issues as usual.
8574
+ - If user EXPLICITLY says they want cloud (e.g. "fix it with cloud agent", "I want cloud", "use cursor cloud"): add forceCloud:true so triage does not override their choice. Do NOT suggest local fix instead \u2014 honor their request.
8575
+ - If there are no scan issues but the conversation has a recent trie_propose_fix: use ad-hoc dispatch with file, issue, fix from that context.
8576
+ - If the tool returns "Cloud Agent dispatch requires a Cursor API key", tell the user to configure it.
8514
8577
  - For status: trie_cloud_fix action:status
8515
- - The key must be in Config (API Keys \u2192 Cursor) or set as CURSOR_API_KEY env var
8516
8578
 
8517
8579
  Examples:
8518
8580
  - User: "do we have emojis?" \u2192 Check nudges first. If none or unclear: Call trie_scan_for_goal_violations to scan the codebase.
@@ -8520,7 +8582,8 @@ Examples:
8520
8582
  - User: "fix the emoji violations" \u2192 Find ALL emoji violations in nudges, call trie_propose_fixes_batch ONCE with all fixes, then STOP
8521
8583
  - User responds "yes to all" after proposal \u2192 Just say "Spawning Claude Code to fix all files..." The system handles it.
8522
8584
  - User: "search for TODO comments" \u2192 If there's a goal about TODOs, use trie_scan_for_goal_violations. Otherwise explain no such goal exists.
8523
- - User: "spin up Cursor Cloud agent" or "check our hypotheses with cloud" \u2192 Call trie_cloud_fix action:dispatch (or status first to see existing jobs).
8585
+ - User: "fix it with cloud agent" (explicit) \u2192 Call trie_cloud_fix action:dispatch forceCloud:true \u2014 honor their choice, don't suggest local.
8586
+ - User: "dispatch to cloud" (generic) \u2192 Call trie_cloud_fix action:dispatch \u2014 triage as usual.
8524
8587
 
8525
8588
  Answer concisely. Reference specific files, decisions, and patterns when relevant.`;
8526
8589
  function ChatView() {
@@ -9603,4 +9666,4 @@ export {
9603
9666
  GitHubBranchesTool,
9604
9667
  InteractiveDashboard
9605
9668
  };
9606
- //# sourceMappingURL=chunk-AIJF67CF.js.map
9669
+ //# sourceMappingURL=chunk-JTGKHPDR.js.map