cursor-route 0.1.7 → 0.1.9

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/src/health.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { execSync } from "node:child_process";
2
2
  import { allAdapters } from "./adapters/index.ts";
3
+ import { isMidDeepSeekProven, midDeepSeekProofDetail } from "./adapters/claude-ds.ts";
3
4
  import { config } from "./config.ts";
4
5
  import { isTmuxAvailable } from "./tmux.ts";
5
6
  import { commandExists } from "./util.ts";
@@ -13,6 +14,9 @@ export interface HealthReport {
13
14
  ok: boolean;
14
15
  detail: string;
15
16
  }>;
17
+ lanes: {
18
+ mid: { worker: "claude-ds"; deepseek: boolean; detail: string };
19
+ };
16
20
  }
17
21
 
18
22
  export function runHealth(): HealthReport {
@@ -58,6 +62,15 @@ export function runHealth(): HealthReport {
58
62
  });
59
63
  }
60
64
 
65
+ // Informational: mid is proven DeepSeek (not the overall OR-gate).
66
+ const midOk = isMidDeepSeekProven();
67
+ const midDetail = midDeepSeekProofDetail();
68
+ checks.push({
69
+ name: "lane:mid",
70
+ ok: midOk,
71
+ detail: midDetail,
72
+ });
73
+
61
74
  // Optional supervisor probe (v0 skill-only; Cursor CLI agent is informational)
62
75
  const agentBin =
63
76
  (commandExists("agent") && "agent") ||
@@ -99,6 +112,9 @@ export function runHealth(): HealthReport {
99
112
  product: config.product,
100
113
  version: config.version,
101
114
  checks,
115
+ lanes: {
116
+ mid: { worker: "claude-ds", deepseek: midOk, detail: midDetail },
117
+ },
102
118
  };
103
119
  }
104
120
 
@@ -118,5 +134,10 @@ export function printHealth(report: HealthReport, asJson: boolean): void {
118
134
  console.log("");
119
135
  console.log("Fix the ✗ items, then re-run: cursor-route health");
120
136
  console.log("Tip: start with one worker (grok OR claude-ds) before parallel demos.");
137
+ } else if (report.checks.some((c) => c.name === "lane:mid" && !c.ok)) {
138
+ console.log("");
139
+ console.log(
140
+ "Tip: health OK without a DeepSeek mid — --lane mid will fail until lane:mid is ✓.",
141
+ );
121
142
  }
122
143
  }
package/src/jobs.ts CHANGED
@@ -37,7 +37,7 @@ export interface Job {
37
37
  status: JobStatus;
38
38
  worker: WorkerKind;
39
39
  lane?: Lane;
40
- /** Mid-lane DeepSeek model alias (flash|pro). Only set for claude-ds. */
40
+ /** Mid-lane DeepSeek model alias (flash|pro). Set for claude-ds and deepseek. */
41
41
  model?: DsModelAlias;
42
42
  prompt: string;
43
43
  cwd: string;
@@ -105,6 +105,53 @@ export function writeJob(job: Job): void {
105
105
  writeSecure(jobPaths(job.id).json, JSON.stringify(job, null, 2));
106
106
  }
107
107
 
108
+ /** Evidence tree for status --json. Parent must capture; claim is never auto-green. */
109
+ export interface JobEvidence {
110
+ spawn: {
111
+ jobId: string;
112
+ worker: WorkerKind;
113
+ lane: Lane | null;
114
+ model: DsModelAlias | null;
115
+ startedAt: string;
116
+ };
117
+ execute: {
118
+ status: JobStatus;
119
+ exitCode: number | null;
120
+ tmuxSession: string;
121
+ pid: number | null;
122
+ sessionAlive: boolean;
123
+ };
124
+ verify: {
125
+ captureHint: string;
126
+ logBytes: number | null;
127
+ claim: "unverified";
128
+ };
129
+ }
130
+
131
+ export function jobEvidence(job: Job, sessionAlive: boolean): JobEvidence {
132
+ return {
133
+ spawn: {
134
+ jobId: job.id,
135
+ worker: job.worker,
136
+ lane: job.lane ?? null,
137
+ model: job.model ?? null,
138
+ startedAt: job.startedAt ?? job.createdAt,
139
+ },
140
+ execute: {
141
+ status: job.status,
142
+ exitCode: job.exitCode ?? null,
143
+ tmuxSession: job.tmuxSession,
144
+ pid: job.pid ?? null,
145
+ sessionAlive,
146
+ },
147
+ verify: {
148
+ captureHint: `cursor-route capture ${job.id}`,
149
+ logBytes: job.logBytes ?? null,
150
+ claim: "unverified",
151
+ },
152
+ };
153
+ }
154
+
108
155
  function pidAlive(pid: number): boolean {
109
156
  try {
110
157
  process.kill(pid, 0);
@@ -118,6 +165,8 @@ function pidAlive(pid: number): boolean {
118
165
  encoding: "utf8",
119
166
  stdio: ["ignore", "pipe", "ignore"],
120
167
  });
168
+ // spawnSync does not throw on EPERM (macOS sandbox); empty stdout is not "dead".
169
+ if (r.error || r.status !== 0) return true;
121
170
  const state = (r.stdout || "").trim();
122
171
  return state !== "" && !state.startsWith("Z");
123
172
  } catch {
@@ -231,7 +280,7 @@ export interface StartOptions {
231
280
  prompt: string;
232
281
  worker?: WorkerKind;
233
282
  lane?: Lane;
234
- /** Mid-lane DeepSeek: flash (default) | pro. Ignored by grok/openrouter. */
283
+ /** Mid-lane DeepSeek: flash (default) | pro (claude-ds + deepseek). Ignored by grok/openrouter. */
235
284
  model?: DsModelAlias;
236
285
  /** Concrete DeepSeek id (preserves pro[1m]). Derived from --model / env when unset. */
237
286
  modelId?: string;
@@ -284,7 +333,7 @@ export function startJob(opts: StartOptions): {
284
333
 
285
334
  let model: DsModelAlias | undefined;
286
335
  let modelId: string | undefined;
287
- if (worker === "claude-ds") {
336
+ if (worker === "claude-ds" || worker === "deepseek") {
288
337
  if (opts.model) {
289
338
  model = opts.model;
290
339
  modelId = opts.modelId ?? DS_MODEL_IDS[opts.model];
@@ -312,6 +361,7 @@ export function startJob(opts: StartOptions): {
312
361
  alwaysApprove,
313
362
  model,
314
363
  modelId,
364
+ dryRun: Boolean(opts.dryRun),
315
365
  });
316
366
  } catch (e) {
317
367
  try {
@@ -493,7 +543,7 @@ export function cleanJobs(olderThanDays = 7): number {
493
543
  t < cutoff &&
494
544
  (job.status === "completed" || job.status === "failed" || job.status === "killed")
495
545
  ) {
496
- for (const ext of [".json", ".prompt", ".log"] as const) {
546
+ for (const ext of [".json", ".prompt", ".log", ".dsh-patch.yml"] as const) {
497
547
  const fp = underJobsDir(id, ext);
498
548
  if (existsSync(fp)) unlinkSync(fp);
499
549
  }