modelstat 0.2.0 → 0.3.1

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/cli.mjs CHANGED
@@ -137,6 +137,62 @@ var init_git = __esm({
137
137
  }
138
138
  });
139
139
 
140
+ // ../../packages/parsers/src/git-outcome.ts
141
+ import { execFile as execFile2 } from "child_process";
142
+ import { promisify as promisify2 } from "util";
143
+ function parseGitLog(stdout) {
144
+ const out = [];
145
+ for (const record of stdout.split(RS)) {
146
+ const rec = record.trim();
147
+ if (!rec) continue;
148
+ const [sha = "", committedAt = "", subject = "", ...rest] = rec.split(FS);
149
+ out.push({ sha, committedAt, subject, body: rest.join(FS) });
150
+ }
151
+ return out;
152
+ }
153
+ function findMergeCommitForPr(commits, prNumber) {
154
+ const re = new RegExp(`(^|\\D)#${prNumber}(\\D|$)`);
155
+ return commits.find((c) => re.test(c.subject)) ?? null;
156
+ }
157
+ function isReverted(commits, mergeSha) {
158
+ if (!mergeSha) return false;
159
+ const short = mergeSha.slice(0, 7);
160
+ return commits.some(
161
+ (c) => c.body.includes(`This reverts commit ${mergeSha}`) || c.body.includes(`This reverts commit ${short}`)
162
+ );
163
+ }
164
+ function outcomeFromCommits(commits, prNumber) {
165
+ const merge = findMergeCommitForPr(commits, prNumber);
166
+ if (!merge) return { merged: false, merged_at: null, reverted: false };
167
+ return {
168
+ merged: true,
169
+ merged_at: merge.committedAt || null,
170
+ reverted: isReverted(commits, merge.sha)
171
+ };
172
+ }
173
+ async function checkPullRequestOutcome(cwd, prNumber) {
174
+ try {
175
+ const { stdout } = await pexec2("git", ["log", "-n", "1000", `--format=${GIT_LOG_FORMAT}`], {
176
+ cwd,
177
+ timeout: 4e3,
178
+ maxBuffer: 16 * 1024 * 1024
179
+ });
180
+ return outcomeFromCommits(parseGitLog(stdout), prNumber);
181
+ } catch {
182
+ return null;
183
+ }
184
+ }
185
+ var pexec2, FS, RS, GIT_LOG_FORMAT;
186
+ var init_git_outcome = __esm({
187
+ "../../packages/parsers/src/git-outcome.ts"() {
188
+ "use strict";
189
+ pexec2 = promisify2(execFile2);
190
+ FS = "";
191
+ RS = "";
192
+ GIT_LOG_FORMAT = `%H${FS}%cI${FS}%s${FS}%b${RS}`;
193
+ }
194
+ });
195
+
140
196
  // ../../packages/core/src/billing.ts
141
197
  var MILLION, FREE_INCLUDED_TOKENS, TEAM_INCLUDED_PER_SEAT;
142
198
  var init_billing = __esm({
@@ -4540,7 +4596,7 @@ var init_redact_floor = __esm({
4540
4596
  pattern: /(?:sk|pk|rk)_test_[A-Za-z0-9]{24,}/g,
4541
4597
  replacement: "<REDACTED:stripe_test_key>"
4542
4598
  },
4543
- // Discord bot token (was daemon-sdk-only — the canonical drift example).
4599
+ // Discord bot token (was caught by only one redactor — the canonical drift example).
4544
4600
  {
4545
4601
  name: "discord_token",
4546
4602
  pattern: /[MN][A-Za-z\d]{23}\.[\w-]{6}\.[\w-]{27}/g,
@@ -4938,7 +4994,16 @@ var init_session_metadata = __esm({
4938
4994
  number: external_exports.number().int().positive(),
4939
4995
  url: external_exports.string().max(400).nullable().default(null),
4940
4996
  source: RefSource.default("content"),
4941
- confidence: external_exports.number().min(0).max(1).default(0.9)
4997
+ confidence: external_exports.number().min(0).max(1).default(0.9),
4998
+ // On-device verified-outcome signals — filled by the parsers' local git-check
4999
+ // (`checkPullRequestOutcome`) when the PR's repo is on disk. `null` = unknown;
5000
+ // the server's CPVO engine classifies verified/failed from these. Mirrors
5001
+ // core's `PullRequestRef` field-for-field.
5002
+ merged: external_exports.boolean().nullable().optional(),
5003
+ merged_at: external_exports.string().max(40).nullable().optional(),
5004
+ reverted: external_exports.boolean().nullable().optional(),
5005
+ hotfixed: external_exports.boolean().nullable().optional(),
5006
+ reopened: external_exports.boolean().nullable().optional()
4942
5007
  });
4943
5008
  CommitRef = external_exports.object({
4944
5009
  /** 7–40 char hex SHA. */
@@ -5135,7 +5200,7 @@ var init_schemas = __esm({
5135
5200
  scripts: external_exports.array(external_exports.object({ token: external_exports.string().max(200), summary: external_exports.string().max(200) })).max(8).default([]),
5136
5201
  /** Extractor confidence in [0, 1]. */
5137
5202
  confidence: external_exports.number().min(0).max(1).default(0),
5138
- /** Provenance of the extraction, e.g. `shell.v2`. */
5203
+ /** Provenance of the extraction, e.g. `shell.v3`. */
5139
5204
  extractor: external_exports.string().max(40)
5140
5205
  }).strict();
5141
5206
  ToolCallWire = external_exports.object({
@@ -5325,6 +5390,214 @@ var init_src = __esm({
5325
5390
  }
5326
5391
  });
5327
5392
 
5393
+ // ../../packages/parsers/src/tool-action/executable.ts
5394
+ function splitStatements(command) {
5395
+ const out = [];
5396
+ let cur = "";
5397
+ let single = false;
5398
+ let double = false;
5399
+ for (let i = 0; i < command.length; i++) {
5400
+ const c = command[i];
5401
+ if (single) {
5402
+ cur += c;
5403
+ if (c === "'") single = false;
5404
+ continue;
5405
+ }
5406
+ if (double) {
5407
+ if (c === "\\" && i + 1 < command.length) {
5408
+ cur += c + command[i + 1];
5409
+ i++;
5410
+ continue;
5411
+ }
5412
+ cur += c;
5413
+ if (c === '"') double = false;
5414
+ continue;
5415
+ }
5416
+ if (c === "'") {
5417
+ single = true;
5418
+ cur += c;
5419
+ continue;
5420
+ }
5421
+ if (c === '"') {
5422
+ double = true;
5423
+ cur += c;
5424
+ continue;
5425
+ }
5426
+ if (c === "\\" && i + 1 < command.length) {
5427
+ cur += c + command[i + 1];
5428
+ i++;
5429
+ continue;
5430
+ }
5431
+ if (c === "#" && (cur === "" || /\s$/.test(cur))) {
5432
+ out.push(cur);
5433
+ cur = "";
5434
+ while (i + 1 < command.length && command[i + 1] !== "\n") i++;
5435
+ continue;
5436
+ }
5437
+ if (c === "\n" || c === ";") {
5438
+ out.push(cur);
5439
+ cur = "";
5440
+ continue;
5441
+ }
5442
+ if (c === "&" || c === "|") {
5443
+ out.push(cur);
5444
+ cur = "";
5445
+ if (command[i + 1] === c) i++;
5446
+ continue;
5447
+ }
5448
+ cur += c;
5449
+ }
5450
+ out.push(cur);
5451
+ return out;
5452
+ }
5453
+ function basename(token) {
5454
+ const parts = token.split("/");
5455
+ return parts[parts.length - 1] ?? token;
5456
+ }
5457
+ function stripOpener(token) {
5458
+ let t = token;
5459
+ if (t.startsWith("$(")) t = t.slice(2);
5460
+ else if (t.startsWith("(")) t = t.slice(1);
5461
+ if (t.startsWith("`")) t = t.slice(1);
5462
+ return t;
5463
+ }
5464
+ function substitutionProgram(token) {
5465
+ const rhs = token.slice(token.indexOf("=") + 1);
5466
+ if (rhs.startsWith("$((")) return null;
5467
+ if (rhs.startsWith("$(") || rhs.startsWith("`")) {
5468
+ const inner = stripOpener(rhs);
5469
+ return inner || null;
5470
+ }
5471
+ return null;
5472
+ }
5473
+ function looksLikeProgram(cand) {
5474
+ if (!PROGRAM.test(cand)) return false;
5475
+ if (/^\d+$/.test(cand)) return false;
5476
+ if ((cand.match(/\./g)?.length ?? 0) >= 2) return false;
5477
+ const lower = cand.toLowerCase();
5478
+ return !DATA_EXTENSIONS.some((ext) => lower.endsWith(ext));
5479
+ }
5480
+ function scanStatement(stmt) {
5481
+ for (const tok of stmt.split(/\s+/).filter(Boolean)) {
5482
+ let t = tok;
5483
+ if (BRACKETS.has(t) || FUNCTION_DEF.test(t) || WRAPPERS.has(t)) continue;
5484
+ if (ASSIGNMENT.test(t)) {
5485
+ const sub = substitutionProgram(t);
5486
+ if (sub) t = sub;
5487
+ else continue;
5488
+ }
5489
+ const cand = basename(stripOpener(t).replace(/[)"'`;,]+$/, "")).toLowerCase();
5490
+ if (!cand || cand.startsWith("-")) break;
5491
+ if (NOISE_BUILTINS.has(cand)) return { builtin: cand };
5492
+ if (looksLikeProgram(cand)) return { program: cand };
5493
+ break;
5494
+ }
5495
+ return {};
5496
+ }
5497
+ function extractExecutable(command) {
5498
+ let fallback = null;
5499
+ for (const raw of splitStatements(command)) {
5500
+ const stmt = raw.trim();
5501
+ if (!stmt || stmt.startsWith("#")) continue;
5502
+ const { program, builtin } = scanStatement(stmt);
5503
+ if (program) {
5504
+ return program.length > MAX_EXECUTABLE_CHARS ? OTHER_BUCKET : program;
5505
+ }
5506
+ if (builtin && !fallback) fallback = builtin;
5507
+ }
5508
+ return fallback ?? OTHER_BUCKET;
5509
+ }
5510
+ var OTHER_BUCKET, MAX_EXECUTABLE_CHARS, WRAPPERS, BRACKETS, NOISE_BUILTINS, DATA_EXTENSIONS, ASSIGNMENT, FUNCTION_DEF, PROGRAM;
5511
+ var init_executable = __esm({
5512
+ "../../packages/parsers/src/tool-action/executable.ts"() {
5513
+ "use strict";
5514
+ OTHER_BUCKET = "(other)";
5515
+ MAX_EXECUTABLE_CHARS = 80;
5516
+ WRAPPERS = /* @__PURE__ */ new Set([
5517
+ "sudo",
5518
+ "doas",
5519
+ "env",
5520
+ "command",
5521
+ "exec",
5522
+ "builtin",
5523
+ "nohup",
5524
+ "setsid",
5525
+ "time",
5526
+ "nice",
5527
+ "ionice",
5528
+ "chrt",
5529
+ "stdbuf",
5530
+ "xargs",
5531
+ // control-flow openers that immediately precede a command
5532
+ "then",
5533
+ "do",
5534
+ "else"
5535
+ ]);
5536
+ BRACKETS = /* @__PURE__ */ new Set(["{", "}", "(", ")"]);
5537
+ NOISE_BUILTINS = /* @__PURE__ */ new Set([
5538
+ "cd",
5539
+ "pushd",
5540
+ "popd",
5541
+ "echo",
5542
+ "printf",
5543
+ "export",
5544
+ "unset",
5545
+ "set",
5546
+ "readonly",
5547
+ "typeset",
5548
+ "declare",
5549
+ "local",
5550
+ "alias",
5551
+ "source",
5552
+ ".",
5553
+ "eval",
5554
+ ":",
5555
+ "true",
5556
+ "false",
5557
+ "read",
5558
+ "wait",
5559
+ "trap",
5560
+ "umask",
5561
+ "shift",
5562
+ "return",
5563
+ "getopts",
5564
+ "hash",
5565
+ "let",
5566
+ "test",
5567
+ "[",
5568
+ "[[",
5569
+ // loop / conditional keywords
5570
+ "for",
5571
+ "while",
5572
+ "until",
5573
+ "if",
5574
+ "elif",
5575
+ "fi",
5576
+ "case",
5577
+ "esac",
5578
+ "select",
5579
+ "function",
5580
+ "done"
5581
+ ]);
5582
+ DATA_EXTENSIONS = [
5583
+ ".output",
5584
+ ".txt",
5585
+ ".log",
5586
+ ".json",
5587
+ ".jsonl",
5588
+ ".md",
5589
+ ".csv",
5590
+ ".tmp",
5591
+ ".out",
5592
+ ".git",
5593
+ ".lock"
5594
+ ];
5595
+ ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=/;
5596
+ FUNCTION_DEF = /^[A-Za-z_][A-Za-z0-9_]*\(\)?$/;
5597
+ PROGRAM = /^[A-Za-z0-9][A-Za-z0-9._+-]*$/;
5598
+ }
5599
+ });
5600
+
5328
5601
  // ../../packages/parsers/src/tool-action/scripts.ts
5329
5602
  function detectScriptRefs(command) {
5330
5603
  const refs = [];
@@ -5397,9 +5670,9 @@ function extractToolAction(call) {
5397
5670
  let param_shape = null;
5398
5671
  let command_redacted = null;
5399
5672
  if (command != null) {
5400
- const [head = "", ...rest] = command.trim().split(/\s+/);
5401
- executable = basename(head) || null;
5402
- param_shape = clampChars(paramShape(rest.join(" ")), MAX_FIELD_CHARS) || null;
5673
+ executable = extractExecutable(command);
5674
+ const args = command.trim().split(/\s+/).slice(1).join(" ");
5675
+ param_shape = clampChars(paramShape(args), MAX_FIELD_CHARS) || null;
5403
5676
  command_redacted = clampChars(redact(command, call.cwd ?? void 0).text, MAX_FIELD_CHARS) || null;
5404
5677
  }
5405
5678
  return {
@@ -5414,7 +5687,9 @@ function extractToolAction(call) {
5414
5687
  command_redacted,
5415
5688
  scripts: [],
5416
5689
  confidence: 0,
5417
- extractor: `${surface}.v1`
5690
+ // Per-surface provenance. shell bumped to v3 (normalized executable, see
5691
+ // `extractExecutable`); builtin/mcp extraction is unchanged → still v1.
5692
+ extractor: `${surface}.${surface === "shell" ? "v3" : "v1"}`
5418
5693
  };
5419
5694
  }
5420
5695
  function extractLocalToolContext(call) {
@@ -5435,14 +5710,13 @@ function shellCommandOf(input) {
5435
5710
  }
5436
5711
  return null;
5437
5712
  }
5438
- function basename(token) {
5439
- return token.split("/").pop() ?? token;
5440
- }
5441
5713
  var MAX_FIELD_CHARS;
5442
5714
  var init_tool_action = __esm({
5443
5715
  "../../packages/parsers/src/tool-action/index.ts"() {
5444
5716
  "use strict";
5445
5717
  init_src();
5718
+ init_executable();
5719
+ init_executable();
5446
5720
  init_scripts();
5447
5721
  MAX_FIELD_CHARS = 16384;
5448
5722
  }
@@ -8367,11 +8641,11 @@ var init_cursor = __esm({
8367
8641
  });
8368
8642
 
8369
8643
  // ../../packages/parsers/src/discovery/index.ts
8370
- import { execFile as execFile2, execSync } from "child_process";
8644
+ import { execFile as execFile3, execSync } from "child_process";
8371
8645
  import { existsSync as existsSync3, statSync } from "fs";
8372
8646
  import { homedir, platform } from "os";
8373
8647
  import { join as join2, resolve as resolve2 } from "path";
8374
- import { promisify as promisify2 } from "util";
8648
+ import { promisify as promisify3 } from "util";
8375
8649
  async function discover(options = {}) {
8376
8650
  const os2 = platform() === "darwin" ? "macos" : "linux";
8377
8651
  const skip = new Set(options.skip ?? []);
@@ -8496,7 +8770,7 @@ function classifyInstallMethod(binPath, os2) {
8496
8770
  }
8497
8771
  async function safeVersionProbe(binPath) {
8498
8772
  try {
8499
- const { stdout } = await pexec2(binPath, ["--version"], { timeout: 1500 });
8773
+ const { stdout } = await pexec3(binPath, ["--version"], { timeout: 1500 });
8500
8774
  return stdout.trim().split(/\s+/).pop() ?? null;
8501
8775
  } catch {
8502
8776
  return null;
@@ -8701,11 +8975,11 @@ function dedupeIdentities(list) {
8701
8975
  }
8702
8976
  return Array.from(seen.values());
8703
8977
  }
8704
- var pexec2, H, SOURCES;
8978
+ var pexec3, H, SOURCES;
8705
8979
  var init_discovery = __esm({
8706
8980
  "../../packages/parsers/src/discovery/index.ts"() {
8707
8981
  "use strict";
8708
- pexec2 = promisify2(execFile2);
8982
+ pexec3 = promisify3(execFile3);
8709
8983
  H = (p) => p.startsWith("~") ? p.replace("~", homedir()) : p;
8710
8984
  SOURCES = [
8711
8985
  {
@@ -8797,6 +9071,7 @@ var init_src2 = __esm({
8797
9071
  "use strict";
8798
9072
  init_types();
8799
9073
  init_git();
9074
+ init_git_outcome();
8800
9075
  init_tool_action();
8801
9076
  init_claude_code();
8802
9077
  init_codex();
@@ -21668,7 +21943,7 @@ var require_mock_interceptor = __commonJS({
21668
21943
  var require_mock_client = __commonJS({
21669
21944
  "../../node_modules/.pnpm/undici@7.25.0/node_modules/undici/lib/mock/mock-client.js"(exports, module) {
21670
21945
  "use strict";
21671
- var { promisify: promisify4 } = __require("util");
21946
+ var { promisify: promisify5 } = __require("util");
21672
21947
  var Client = require_client();
21673
21948
  var { buildMockDispatch } = require_mock_utils();
21674
21949
  var {
@@ -21716,7 +21991,7 @@ var require_mock_client = __commonJS({
21716
21991
  this[kDispatches] = [];
21717
21992
  }
21718
21993
  async [kClose]() {
21719
- await promisify4(this[kOriginalClose])();
21994
+ await promisify5(this[kOriginalClose])();
21720
21995
  this[kConnected] = 0;
21721
21996
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
21722
21997
  }
@@ -21929,7 +22204,7 @@ var require_mock_call_history = __commonJS({
21929
22204
  var require_mock_pool = __commonJS({
21930
22205
  "../../node_modules/.pnpm/undici@7.25.0/node_modules/undici/lib/mock/mock-pool.js"(exports, module) {
21931
22206
  "use strict";
21932
- var { promisify: promisify4 } = __require("util");
22207
+ var { promisify: promisify5 } = __require("util");
21933
22208
  var Pool = require_pool();
21934
22209
  var { buildMockDispatch } = require_mock_utils();
21935
22210
  var {
@@ -21977,7 +22252,7 @@ var require_mock_pool = __commonJS({
21977
22252
  this[kDispatches] = [];
21978
22253
  }
21979
22254
  async [kClose]() {
21980
- await promisify4(this[kOriginalClose])();
22255
+ await promisify5(this[kOriginalClose])();
21981
22256
  this[kConnected] = 0;
21982
22257
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
21983
22258
  }
@@ -34612,25 +34887,25 @@ var init_constants2 = __esm({
34612
34887
 
34613
34888
  // ../../node_modules/.pnpm/stubborn-fs@2.0.0/node_modules/stubborn-fs/dist/index.js
34614
34889
  import fs from "fs";
34615
- import { promisify as promisify3 } from "util";
34616
- var FS, dist_default;
34890
+ import { promisify as promisify4 } from "util";
34891
+ var FS2, dist_default;
34617
34892
  var init_dist2 = __esm({
34618
34893
  "../../node_modules/.pnpm/stubborn-fs@2.0.0/node_modules/stubborn-fs/dist/index.js"() {
34619
34894
  "use strict";
34620
34895
  init_dist();
34621
34896
  init_dist();
34622
34897
  init_constants2();
34623
- FS = {
34898
+ FS2 = {
34624
34899
  attempt: {
34625
34900
  /* ASYNC */
34626
- chmod: attemptify_async_default(promisify3(fs.chmod), ATTEMPTIFY_CHANGE_ERROR_OPTIONS),
34627
- chown: attemptify_async_default(promisify3(fs.chown), ATTEMPTIFY_CHANGE_ERROR_OPTIONS),
34628
- close: attemptify_async_default(promisify3(fs.close), ATTEMPTIFY_NOOP_OPTIONS),
34629
- fsync: attemptify_async_default(promisify3(fs.fsync), ATTEMPTIFY_NOOP_OPTIONS),
34630
- mkdir: attemptify_async_default(promisify3(fs.mkdir), ATTEMPTIFY_NOOP_OPTIONS),
34631
- realpath: attemptify_async_default(promisify3(fs.realpath), ATTEMPTIFY_NOOP_OPTIONS),
34632
- stat: attemptify_async_default(promisify3(fs.stat), ATTEMPTIFY_NOOP_OPTIONS),
34633
- unlink: attemptify_async_default(promisify3(fs.unlink), ATTEMPTIFY_NOOP_OPTIONS),
34901
+ chmod: attemptify_async_default(promisify4(fs.chmod), ATTEMPTIFY_CHANGE_ERROR_OPTIONS),
34902
+ chown: attemptify_async_default(promisify4(fs.chown), ATTEMPTIFY_CHANGE_ERROR_OPTIONS),
34903
+ close: attemptify_async_default(promisify4(fs.close), ATTEMPTIFY_NOOP_OPTIONS),
34904
+ fsync: attemptify_async_default(promisify4(fs.fsync), ATTEMPTIFY_NOOP_OPTIONS),
34905
+ mkdir: attemptify_async_default(promisify4(fs.mkdir), ATTEMPTIFY_NOOP_OPTIONS),
34906
+ realpath: attemptify_async_default(promisify4(fs.realpath), ATTEMPTIFY_NOOP_OPTIONS),
34907
+ stat: attemptify_async_default(promisify4(fs.stat), ATTEMPTIFY_NOOP_OPTIONS),
34908
+ unlink: attemptify_async_default(promisify4(fs.unlink), ATTEMPTIFY_NOOP_OPTIONS),
34634
34909
  /* SYNC */
34635
34910
  chmodSync: attemptify_sync_default(fs.chmodSync, ATTEMPTIFY_CHANGE_ERROR_OPTIONS),
34636
34911
  chownSync: attemptify_sync_default(fs.chownSync, ATTEMPTIFY_CHANGE_ERROR_OPTIONS),
@@ -34644,14 +34919,14 @@ var init_dist2 = __esm({
34644
34919
  },
34645
34920
  retry: {
34646
34921
  /* ASYNC */
34647
- close: retryify_async_default(promisify3(fs.close), RETRYIFY_OPTIONS),
34648
- fsync: retryify_async_default(promisify3(fs.fsync), RETRYIFY_OPTIONS),
34649
- open: retryify_async_default(promisify3(fs.open), RETRYIFY_OPTIONS),
34650
- readFile: retryify_async_default(promisify3(fs.readFile), RETRYIFY_OPTIONS),
34651
- rename: retryify_async_default(promisify3(fs.rename), RETRYIFY_OPTIONS),
34652
- stat: retryify_async_default(promisify3(fs.stat), RETRYIFY_OPTIONS),
34653
- write: retryify_async_default(promisify3(fs.write), RETRYIFY_OPTIONS),
34654
- writeFile: retryify_async_default(promisify3(fs.writeFile), RETRYIFY_OPTIONS),
34922
+ close: retryify_async_default(promisify4(fs.close), RETRYIFY_OPTIONS),
34923
+ fsync: retryify_async_default(promisify4(fs.fsync), RETRYIFY_OPTIONS),
34924
+ open: retryify_async_default(promisify4(fs.open), RETRYIFY_OPTIONS),
34925
+ readFile: retryify_async_default(promisify4(fs.readFile), RETRYIFY_OPTIONS),
34926
+ rename: retryify_async_default(promisify4(fs.rename), RETRYIFY_OPTIONS),
34927
+ stat: retryify_async_default(promisify4(fs.stat), RETRYIFY_OPTIONS),
34928
+ write: retryify_async_default(promisify4(fs.write), RETRYIFY_OPTIONS),
34929
+ writeFile: retryify_async_default(promisify4(fs.writeFile), RETRYIFY_OPTIONS),
34655
34930
  /* SYNC */
34656
34931
  closeSync: retryify_sync_default(fs.closeSync, RETRYIFY_OPTIONS),
34657
34932
  fsyncSync: retryify_sync_default(fs.fsyncSync, RETRYIFY_OPTIONS),
@@ -34663,7 +34938,7 @@ var init_dist2 = __esm({
34663
34938
  writeFileSync: retryify_sync_default(fs.writeFileSync, RETRYIFY_OPTIONS)
34664
34939
  }
34665
34940
  };
34666
- dist_default = FS;
34941
+ dist_default = FS2;
34667
34942
  }
34668
34943
  });
34669
34944
 
@@ -45914,6 +46189,7 @@ async function buildSessionMetadata(segments, events, opts = {}) {
45914
46189
  const evs = eventsBySession.get(sessionId) ?? [];
45915
46190
  const segs = segsBySession.get(sessionId) ?? [];
45916
46191
  const parts = [];
46192
+ const slugToCwd = /* @__PURE__ */ new Map();
45917
46193
  const cwds = /* @__PURE__ */ new Set();
45918
46194
  for (const e of evs) {
45919
46195
  if (e.cwd) cwds.add(e.cwd);
@@ -45948,6 +46224,7 @@ async function buildSessionMetadata(segments, events, opts = {}) {
45948
46224
  g = null;
45949
46225
  }
45950
46226
  if (!g?.remote_slug) continue;
46227
+ slugToCwd.set(g.remote_slug.toLowerCase(), cwd);
45951
46228
  const refs = emptyDetectedRefs();
45952
46229
  refs.repos.push({
45953
46230
  host: g.remote_host ?? null,
@@ -45977,6 +46254,21 @@ async function buildSessionMetadata(segments, events, opts = {}) {
45977
46254
  }
45978
46255
  }
45979
46256
  const meta = dedupeSessionMetadata(parts);
46257
+ if (opts.checkPrOutcome && meta.pull_requests.length > 0) {
46258
+ for (const pr of meta.pull_requests) {
46259
+ const cwd = pr.slug ? slugToCwd.get(pr.slug.toLowerCase()) : void 0;
46260
+ if (!cwd) continue;
46261
+ try {
46262
+ const o = await opts.checkPrOutcome(cwd, pr.number);
46263
+ if (o) {
46264
+ pr.merged = o.merged;
46265
+ pr.merged_at = o.merged_at;
46266
+ pr.reverted = o.reverted;
46267
+ }
46268
+ } catch {
46269
+ }
46270
+ }
46271
+ }
45980
46272
  if (!isEmptySessionMetadata(meta)) out[sessionId] = meta;
45981
46273
  } catch {
45982
46274
  }
@@ -47245,7 +47537,8 @@ async function buildSessionMetadata2(segments, events) {
47245
47537
  const a = await getAdapters();
47246
47538
  return buildSessionMetadata(segments, events, {
47247
47539
  resolveGit: resolveGitContext,
47248
- extractLinks: a.extractLinks
47540
+ extractLinks: a.extractLinks,
47541
+ checkPrOutcome: checkPullRequestOutcome
47249
47542
  });
47250
47543
  }
47251
47544
  async function enrichScripts(drafts, contexts = []) {
@@ -47489,7 +47782,7 @@ var init_scan = __esm({
47489
47782
  init_api();
47490
47783
  init_config2();
47491
47784
  init_pipeline2();
47492
- DAEMON_VERSION = true ? "daemon-0.2.0" : "daemon-dev";
47785
+ DAEMON_VERSION = true ? "daemon-0.3.1" : "daemon-dev";
47493
47786
  BATCH_MAX_EVENTS = INGEST_BATCH_MAX_EVENTS;
47494
47787
  BATCH_MAX_TOOL_CALLS = 2e4;
47495
47788
  BATCH_BUFFER_HARD_CAP = BATCH_MAX_EVENTS * 2;
@@ -49999,7 +50292,7 @@ var init_daemon = __esm({
49999
50292
  init_machine_key();
50000
50293
  init_scan();
50001
50294
  init_single_flight();
50002
- DAEMON_VERSION2 = true ? "daemon-0.2.0" : "daemon-dev";
50295
+ DAEMON_VERSION2 = true ? "daemon-0.3.1" : "daemon-dev";
50003
50296
  HEARTBEAT_INTERVAL_MS = 1e4;
50004
50297
  SCAN_INTERVAL_MS = 5 * 60 * 1e3;
50005
50298
  DISCOVERY_INTERVAL_MS = 6e4;
@@ -50601,7 +50894,7 @@ function tryOpenBrowser(url) {
50601
50894
  return false;
50602
50895
  }
50603
50896
  }
50604
- var DAEMON_VERSION3 = true ? "daemon-0.2.0" : "daemon-dev";
50897
+ var DAEMON_VERSION3 = true ? "daemon-0.3.1" : "daemon-dev";
50605
50898
  function osFamily() {
50606
50899
  const p = platform5();
50607
50900
  if (p === "darwin") return "macos";