modelstat 0.0.50 → 0.0.52

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
@@ -77,6 +77,17 @@ var init_git = __esm({
77
77
  }
78
78
  });
79
79
 
80
+ // ../../packages/core/src/billing.ts
81
+ var MILLION, FREE_INCLUDED_TOKENS, TEAM_INCLUDED_PER_SEAT;
82
+ var init_billing = __esm({
83
+ "../../packages/core/src/billing.ts"() {
84
+ "use strict";
85
+ MILLION = 1000000n;
86
+ FREE_INCLUDED_TOKENS = 100n * MILLION;
87
+ TEAM_INCLUDED_PER_SEAT = 250n * MILLION;
88
+ }
89
+ });
90
+
80
91
  // ../../packages/core/src/enums.ts
81
92
  var AGENTS, PROVIDERS, IDENTITY_OWNER_SCOPES, INSTALL_METHODS, OS_FAMILIES, EVENT_KINDS, TOOL_CALL_STATUSES, COMPANION_PHASES, CLASSIFICATION_CONFIDENCE;
82
93
  var init_enums = __esm({
@@ -195,6 +206,72 @@ var init_enums = __esm({
195
206
  }
196
207
  });
197
208
 
209
+ // ../../packages/core/src/ids.ts
210
+ function ulid(seedTime) {
211
+ const t = seedTime ?? Date.now();
212
+ let timeStr = "";
213
+ let ts = t;
214
+ for (let i = 9; i >= 0; i--) {
215
+ timeStr = ULID_ALPHABET[ts % 32] + timeStr;
216
+ ts = Math.floor(ts / 32);
217
+ }
218
+ const bytes = new Uint8Array(16);
219
+ globalThis.crypto.getRandomValues(bytes);
220
+ let randStr = "";
221
+ for (let i = 0; i < 16; i++) {
222
+ randStr += ULID_ALPHABET[bytes[i] % 32];
223
+ }
224
+ return timeStr + randStr;
225
+ }
226
+ function sourceEventId(deviceId, sourceOrFilePath, byteOffsetMaybe) {
227
+ let key;
228
+ if (typeof sourceOrFilePath === "string") {
229
+ const byteOffset = byteOffsetMaybe ?? 0;
230
+ key = `fs::${sourceOrFilePath}::${byteOffset}`;
231
+ } else if ("file" in sourceOrFilePath) {
232
+ key = `fs::${sourceOrFilePath.file}::${sourceOrFilePath.byteOffset}`;
233
+ } else if ("lineUuid" in sourceOrFilePath) {
234
+ key = `uuid::${sourceOrFilePath.lineUuid}`;
235
+ } else {
236
+ key = `web::${sourceOrFilePath.host}::${sourceOrFilePath.conversationId}::${sourceOrFilePath.messageId}`;
237
+ }
238
+ const s = `${deviceId}::${key}`;
239
+ let h = 5381n;
240
+ for (let i = 0; i < s.length; i++) {
241
+ h = h * 33n ^ BigInt(s.charCodeAt(i));
242
+ h &= 0xffffffffffffffffn;
243
+ }
244
+ return `evt_${h.toString(36)}`;
245
+ }
246
+ function segmentId(sessionId, startedAtMs, endedAtMs, sourceEventIds) {
247
+ const sorted = [...sourceEventIds].sort().join(",");
248
+ const s = `${sessionId}|${startedAtMs}|${endedAtMs}|${sorted}`;
249
+ let h = 5381n;
250
+ for (let i = 0; i < s.length; i++) {
251
+ h = h * 33n ^ BigInt(s.charCodeAt(i));
252
+ h &= 0xffffffffffffffffn;
253
+ }
254
+ return `seg_${h.toString(36)}`;
255
+ }
256
+ function paramShape(args) {
257
+ const MASK = "\xA7";
258
+ return args.split(/[ \t\n\r\f]+/).filter((t) => t.length > 0).map((t) => {
259
+ if (t.startsWith("-")) {
260
+ const eq = t.indexOf("=");
261
+ return eq === -1 ? t : `${t.slice(0, eq + 1)}${MASK}`;
262
+ }
263
+ return MASK;
264
+ }).join(" ");
265
+ }
266
+ var ULID_ALPHABET, batchId;
267
+ var init_ids = __esm({
268
+ "../../packages/core/src/ids.ts"() {
269
+ "use strict";
270
+ ULID_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
271
+ batchId = () => ulid();
272
+ }
273
+ });
274
+
198
275
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
199
276
  var util, objectUtil, ZodParsedType, getParsedType;
200
277
  var init_util = __esm({
@@ -942,9 +1019,9 @@ var init_types2 = __esm({
942
1019
  return this._cachedPath;
943
1020
  }
944
1021
  };
945
- handleResult = (ctx, result) => {
946
- if (isValid(result)) {
947
- return { success: true, data: result.value };
1022
+ handleResult = (ctx, result2) => {
1023
+ if (isValid(result2)) {
1024
+ return { success: true, data: result2.value };
948
1025
  } else {
949
1026
  if (!ctx.common.issues.length) {
950
1027
  throw new Error("Validation failed but no issues detected.");
@@ -992,21 +1069,21 @@ var init_types2 = __esm({
992
1069
  };
993
1070
  }
994
1071
  _parseSync(input) {
995
- const result = this._parse(input);
996
- if (isAsync(result)) {
1072
+ const result2 = this._parse(input);
1073
+ if (isAsync(result2)) {
997
1074
  throw new Error("Synchronous parse encountered promise.");
998
1075
  }
999
- return result;
1076
+ return result2;
1000
1077
  }
1001
1078
  _parseAsync(input) {
1002
- const result = this._parse(input);
1003
- return Promise.resolve(result);
1079
+ const result2 = this._parse(input);
1080
+ return Promise.resolve(result2);
1004
1081
  }
1005
1082
  parse(data, params) {
1006
- const result = this.safeParse(data, params);
1007
- if (result.success)
1008
- return result.data;
1009
- throw result.error;
1083
+ const result2 = this.safeParse(data, params);
1084
+ if (result2.success)
1085
+ return result2.data;
1086
+ throw result2.error;
1010
1087
  }
1011
1088
  safeParse(data, params) {
1012
1089
  const ctx = {
@@ -1021,8 +1098,8 @@ var init_types2 = __esm({
1021
1098
  data,
1022
1099
  parsedType: getParsedType(data)
1023
1100
  };
1024
- const result = this._parseSync({ data, path: ctx.path, parent: ctx });
1025
- return handleResult(ctx, result);
1101
+ const result2 = this._parseSync({ data, path: ctx.path, parent: ctx });
1102
+ return handleResult(ctx, result2);
1026
1103
  }
1027
1104
  "~validate"(data) {
1028
1105
  const ctx = {
@@ -1038,9 +1115,9 @@ var init_types2 = __esm({
1038
1115
  };
1039
1116
  if (!this["~standard"].async) {
1040
1117
  try {
1041
- const result = this._parseSync({ data, path: [], parent: ctx });
1042
- return isValid(result) ? {
1043
- value: result.value
1118
+ const result2 = this._parseSync({ data, path: [], parent: ctx });
1119
+ return isValid(result2) ? {
1120
+ value: result2.value
1044
1121
  } : {
1045
1122
  issues: ctx.common.issues
1046
1123
  };
@@ -1054,17 +1131,17 @@ var init_types2 = __esm({
1054
1131
  };
1055
1132
  }
1056
1133
  }
1057
- return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result) ? {
1058
- value: result.value
1134
+ return this._parseAsync({ data, path: [], parent: ctx }).then((result2) => isValid(result2) ? {
1135
+ value: result2.value
1059
1136
  } : {
1060
1137
  issues: ctx.common.issues
1061
1138
  });
1062
1139
  }
1063
1140
  async parseAsync(data, params) {
1064
- const result = await this.safeParseAsync(data, params);
1065
- if (result.success)
1066
- return result.data;
1067
- throw result.error;
1141
+ const result2 = await this.safeParseAsync(data, params);
1142
+ if (result2.success)
1143
+ return result2.data;
1144
+ throw result2.error;
1068
1145
  }
1069
1146
  async safeParseAsync(data, params) {
1070
1147
  const ctx = {
@@ -1080,8 +1157,8 @@ var init_types2 = __esm({
1080
1157
  parsedType: getParsedType(data)
1081
1158
  };
1082
1159
  const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });
1083
- const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
1084
- return handleResult(ctx, result);
1160
+ const result2 = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
1161
+ return handleResult(ctx, result2);
1085
1162
  }
1086
1163
  refine(check, message) {
1087
1164
  const getIssueProperties = (val) => {
@@ -1094,13 +1171,13 @@ var init_types2 = __esm({
1094
1171
  }
1095
1172
  };
1096
1173
  return this._refinement((val, ctx) => {
1097
- const result = check(val);
1174
+ const result2 = check(val);
1098
1175
  const setError = () => ctx.addIssue({
1099
1176
  code: ZodIssueCode.custom,
1100
1177
  ...getIssueProperties(val)
1101
1178
  });
1102
- if (typeof Promise !== "undefined" && result instanceof Promise) {
1103
- return result.then((data) => {
1179
+ if (typeof Promise !== "undefined" && result2 instanceof Promise) {
1180
+ return result2.then((data) => {
1104
1181
  if (!data) {
1105
1182
  setError();
1106
1183
  return false;
@@ -1109,7 +1186,7 @@ var init_types2 = __esm({
1109
1186
  }
1110
1187
  });
1111
1188
  }
1112
- if (!result) {
1189
+ if (!result2) {
1113
1190
  setError();
1114
1191
  return false;
1115
1192
  } else {
@@ -2533,14 +2610,14 @@ var init_types2 = __esm({
2533
2610
  if (ctx.common.async) {
2534
2611
  return Promise.all([...ctx.data].map((item, i) => {
2535
2612
  return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
2536
- })).then((result2) => {
2537
- return ParseStatus.mergeArray(status2, result2);
2613
+ })).then((result3) => {
2614
+ return ParseStatus.mergeArray(status2, result3);
2538
2615
  });
2539
2616
  }
2540
- const result = [...ctx.data].map((item, i) => {
2617
+ const result2 = [...ctx.data].map((item, i) => {
2541
2618
  return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
2542
2619
  });
2543
- return ParseStatus.mergeArray(status2, result);
2620
+ return ParseStatus.mergeArray(status2, result2);
2544
2621
  }
2545
2622
  get element() {
2546
2623
  return this._def.type;
@@ -2920,18 +2997,18 @@ var init_types2 = __esm({
2920
2997
  const { ctx } = this._processInputParams(input);
2921
2998
  const options = this._def.options;
2922
2999
  function handleResults(results) {
2923
- for (const result of results) {
2924
- if (result.result.status === "valid") {
2925
- return result.result;
3000
+ for (const result2 of results) {
3001
+ if (result2.result.status === "valid") {
3002
+ return result2.result;
2926
3003
  }
2927
3004
  }
2928
- for (const result of results) {
2929
- if (result.result.status === "dirty") {
2930
- ctx.common.issues.push(...result.ctx.common.issues);
2931
- return result.result;
3005
+ for (const result2 of results) {
3006
+ if (result2.result.status === "dirty") {
3007
+ ctx.common.issues.push(...result2.ctx.common.issues);
3008
+ return result2.result;
2932
3009
  }
2933
3010
  }
2934
- const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));
3011
+ const unionErrors = results.map((result2) => new ZodError(result2.ctx.common.issues));
2935
3012
  addIssueToContext(ctx, {
2936
3013
  code: ZodIssueCode.invalid_union,
2937
3014
  unionErrors
@@ -2969,15 +3046,15 @@ var init_types2 = __esm({
2969
3046
  },
2970
3047
  parent: null
2971
3048
  };
2972
- const result = option._parseSync({
3049
+ const result2 = option._parseSync({
2973
3050
  data: ctx.data,
2974
3051
  path: ctx.path,
2975
3052
  parent: childCtx
2976
3053
  });
2977
- if (result.status === "valid") {
2978
- return result;
2979
- } else if (result.status === "dirty" && !dirty) {
2980
- dirty = { result, ctx: childCtx };
3054
+ if (result2.status === "valid") {
3055
+ return result2;
3056
+ } else if (result2.status === "dirty" && !dirty) {
3057
+ dirty = { result: result2, ctx: childCtx };
2981
3058
  }
2982
3059
  if (childCtx.common.issues.length) {
2983
3060
  issues.push(childCtx.common.issues);
@@ -3484,9 +3561,9 @@ var init_types2 = __esm({
3484
3561
  error.addIssue(makeArgsIssue(args, e));
3485
3562
  throw error;
3486
3563
  });
3487
- const result = await Reflect.apply(fn, this, parsedArgs);
3488
- const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => {
3489
- error.addIssue(makeReturnsIssue(result, e));
3564
+ const result2 = await Reflect.apply(fn, this, parsedArgs);
3565
+ const parsedReturns = await me._def.returns._def.type.parseAsync(result2, params).catch((e) => {
3566
+ error.addIssue(makeReturnsIssue(result2, e));
3490
3567
  throw error;
3491
3568
  });
3492
3569
  return parsedReturns;
@@ -3498,10 +3575,10 @@ var init_types2 = __esm({
3498
3575
  if (!parsedArgs.success) {
3499
3576
  throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);
3500
3577
  }
3501
- const result = Reflect.apply(fn, this, parsedArgs.data);
3502
- const parsedReturns = me._def.returns.safeParse(result, params);
3578
+ const result2 = Reflect.apply(fn, this, parsedArgs.data);
3579
+ const parsedReturns = me._def.returns.safeParse(result2, params);
3503
3580
  if (!parsedReturns.success) {
3504
- throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);
3581
+ throw new ZodError([makeReturnsIssue(result2, parsedReturns.error)]);
3505
3582
  }
3506
3583
  return parsedReturns.data;
3507
3584
  });
@@ -3746,43 +3823,43 @@ var init_types2 = __esm({
3746
3823
  return Promise.resolve(processed).then(async (processed2) => {
3747
3824
  if (status2.value === "aborted")
3748
3825
  return INVALID;
3749
- const result = await this._def.schema._parseAsync({
3826
+ const result2 = await this._def.schema._parseAsync({
3750
3827
  data: processed2,
3751
3828
  path: ctx.path,
3752
3829
  parent: ctx
3753
3830
  });
3754
- if (result.status === "aborted")
3831
+ if (result2.status === "aborted")
3755
3832
  return INVALID;
3756
- if (result.status === "dirty")
3757
- return DIRTY(result.value);
3833
+ if (result2.status === "dirty")
3834
+ return DIRTY(result2.value);
3758
3835
  if (status2.value === "dirty")
3759
- return DIRTY(result.value);
3760
- return result;
3836
+ return DIRTY(result2.value);
3837
+ return result2;
3761
3838
  });
3762
3839
  } else {
3763
3840
  if (status2.value === "aborted")
3764
3841
  return INVALID;
3765
- const result = this._def.schema._parseSync({
3842
+ const result2 = this._def.schema._parseSync({
3766
3843
  data: processed,
3767
3844
  path: ctx.path,
3768
3845
  parent: ctx
3769
3846
  });
3770
- if (result.status === "aborted")
3847
+ if (result2.status === "aborted")
3771
3848
  return INVALID;
3772
- if (result.status === "dirty")
3773
- return DIRTY(result.value);
3849
+ if (result2.status === "dirty")
3850
+ return DIRTY(result2.value);
3774
3851
  if (status2.value === "dirty")
3775
- return DIRTY(result.value);
3776
- return result;
3852
+ return DIRTY(result2.value);
3853
+ return result2;
3777
3854
  }
3778
3855
  }
3779
3856
  if (effect.type === "refinement") {
3780
3857
  const executeRefinement = (acc) => {
3781
- const result = effect.refinement(acc, checkCtx);
3858
+ const result2 = effect.refinement(acc, checkCtx);
3782
3859
  if (ctx.common.async) {
3783
- return Promise.resolve(result);
3860
+ return Promise.resolve(result2);
3784
3861
  }
3785
- if (result instanceof Promise) {
3862
+ if (result2 instanceof Promise) {
3786
3863
  throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
3787
3864
  }
3788
3865
  return acc;
@@ -3820,18 +3897,18 @@ var init_types2 = __esm({
3820
3897
  });
3821
3898
  if (!isValid(base))
3822
3899
  return INVALID;
3823
- const result = effect.transform(base.value, checkCtx);
3824
- if (result instanceof Promise) {
3900
+ const result2 = effect.transform(base.value, checkCtx);
3901
+ if (result2 instanceof Promise) {
3825
3902
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
3826
3903
  }
3827
- return { status: status2.value, value: result };
3904
+ return { status: status2.value, value: result2 };
3828
3905
  } else {
3829
3906
  return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
3830
3907
  if (!isValid(base))
3831
3908
  return INVALID;
3832
- return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
3909
+ return Promise.resolve(effect.transform(base.value, checkCtx)).then((result2) => ({
3833
3910
  status: status2.value,
3834
- value: result
3911
+ value: result2
3835
3912
  }));
3836
3913
  });
3837
3914
  }
@@ -3928,18 +4005,18 @@ var init_types2 = __esm({
3928
4005
  issues: []
3929
4006
  }
3930
4007
  };
3931
- const result = this._def.innerType._parse({
4008
+ const result2 = this._def.innerType._parse({
3932
4009
  data: newCtx.data,
3933
4010
  path: newCtx.path,
3934
4011
  parent: {
3935
4012
  ...newCtx
3936
4013
  }
3937
4014
  });
3938
- if (isAsync(result)) {
3939
- return result.then((result2) => {
4015
+ if (isAsync(result2)) {
4016
+ return result2.then((result3) => {
3940
4017
  return {
3941
4018
  status: "valid",
3942
- value: result2.status === "valid" ? result2.value : this._def.catchValue({
4019
+ value: result3.status === "valid" ? result3.value : this._def.catchValue({
3943
4020
  get error() {
3944
4021
  return new ZodError(newCtx.common.issues);
3945
4022
  },
@@ -3950,7 +4027,7 @@ var init_types2 = __esm({
3950
4027
  } else {
3951
4028
  return {
3952
4029
  status: "valid",
3953
- value: result.status === "valid" ? result.value : this._def.catchValue({
4030
+ value: result2.status === "valid" ? result2.value : this._def.catchValue({
3954
4031
  get error() {
3955
4032
  return new ZodError(newCtx.common.issues);
3956
4033
  },
@@ -4064,14 +4141,14 @@ var init_types2 = __esm({
4064
4141
  };
4065
4142
  ZodReadonly = class extends ZodType {
4066
4143
  _parse(input) {
4067
- const result = this._def.innerType._parse(input);
4144
+ const result2 = this._def.innerType._parse(input);
4068
4145
  const freeze = (data) => {
4069
4146
  if (isValid(data)) {
4070
4147
  data.value = Object.freeze(data.value);
4071
4148
  }
4072
4149
  return data;
4073
4150
  };
4074
- return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
4151
+ return isAsync(result2) ? result2.then((data) => freeze(data)) : freeze(result2);
4075
4152
  }
4076
4153
  unwrap() {
4077
4154
  return this._def.innerType;
@@ -4311,8 +4388,223 @@ var init_zod = __esm({
4311
4388
  }
4312
4389
  });
4313
4390
 
4391
+ // ../../packages/core/src/policies.ts
4392
+ function compilePolicyPatterns(bundle) {
4393
+ const out = [];
4394
+ for (const p of bundle.patterns) {
4395
+ const flags = `g${p.flags ?? ""}`;
4396
+ try {
4397
+ out.push({ name: p.name, pattern: new RegExp(p.regex, flags) });
4398
+ } catch {
4399
+ }
4400
+ }
4401
+ return out;
4402
+ }
4403
+ var RedactionPattern, RedactionPolicyBundle, POLICIES_BUNDLED_FALLBACK, POLICIES_CONFIG_KIND;
4404
+ var init_policies = __esm({
4405
+ "../../packages/core/src/policies.ts"() {
4406
+ "use strict";
4407
+ init_zod();
4408
+ RedactionPattern = external_exports.object({
4409
+ /** Stable label for the `[REDACTED:name]` placeholder. */
4410
+ name: external_exports.string().min(1).max(64).regex(/^[a-z0-9_]+$/, "name must be lowercase a-z0-9_"),
4411
+ /** JS regex source. Compiled with the `g` flag on the client. */
4412
+ regex: external_exports.string().min(1).max(1e3),
4413
+ /** Optional extra flags; `g` is always added. Limited to `i m s u`. */
4414
+ flags: external_exports.string().max(8).regex(/^[imsu]*$/, "only i m s u flags allowed").optional()
4415
+ });
4416
+ RedactionPolicyBundle = external_exports.object({
4417
+ version: external_exports.number().int().nonnegative(),
4418
+ /** Additive patterns unioned ON TOP of the bundled floor. There is, by
4419
+ * design, no way to express removal — only addition. */
4420
+ patterns: external_exports.array(RedactionPattern).max(256)
4421
+ });
4422
+ POLICIES_BUNDLED_FALLBACK = { version: 0, patterns: [] };
4423
+ POLICIES_CONFIG_KIND = {
4424
+ kind: "policies",
4425
+ schema: RedactionPolicyBundle,
4426
+ bundledFallback: POLICIES_BUNDLED_FALLBACK
4427
+ };
4428
+ }
4429
+ });
4430
+
4431
+ // ../../packages/core/src/redact-floor.ts
4432
+ var SECRET_FLOOR;
4433
+ var init_redact_floor = __esm({
4434
+ "../../packages/core/src/redact-floor.ts"() {
4435
+ "use strict";
4436
+ SECRET_FLOOR = [
4437
+ {
4438
+ name: "anthropic_key",
4439
+ pattern: /sk-ant-[A-Za-z0-9_-]{20,}/g,
4440
+ replacement: "<REDACTED:anthropic_key>"
4441
+ },
4442
+ {
4443
+ name: "openai_key",
4444
+ pattern: /sk-(?:proj-)?[A-Za-z0-9_-]{20,}/g,
4445
+ replacement: "<REDACTED:openai_key>"
4446
+ },
4447
+ {
4448
+ name: "google_api_key",
4449
+ pattern: /AIza[0-9A-Za-z_-]{35}/g,
4450
+ replacement: "<REDACTED:google_api_key>"
4451
+ },
4452
+ {
4453
+ name: "aws_access_key",
4454
+ pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
4455
+ replacement: "<REDACTED:aws_access_key>"
4456
+ },
4457
+ { name: "github_pat", pattern: /ghp_[A-Za-z0-9]{36,}/g, replacement: "<REDACTED:github_pat>" },
4458
+ {
4459
+ name: "github_oauth",
4460
+ pattern: /gho_[A-Za-z0-9]{36,}/g,
4461
+ replacement: "<REDACTED:github_oauth>"
4462
+ },
4463
+ {
4464
+ name: "github_app",
4465
+ pattern: /gh[sur]_[A-Za-z0-9]{36,}/g,
4466
+ replacement: "<REDACTED:github_app>"
4467
+ },
4468
+ {
4469
+ name: "slack_token",
4470
+ pattern: /xox[aboprs]-[A-Za-z0-9-]{10,}/g,
4471
+ replacement: "<REDACTED:slack_token>"
4472
+ },
4473
+ {
4474
+ name: "stripe_live_key",
4475
+ pattern: /(?:sk|pk|rk)_live_[A-Za-z0-9]{24,}/g,
4476
+ replacement: "<REDACTED:stripe_live_key>"
4477
+ },
4478
+ {
4479
+ name: "stripe_test_key",
4480
+ pattern: /(?:sk|pk|rk)_test_[A-Za-z0-9]{24,}/g,
4481
+ replacement: "<REDACTED:stripe_test_key>"
4482
+ },
4483
+ // Discord bot token (was agent-sdk-only — the canonical drift example).
4484
+ {
4485
+ name: "discord_token",
4486
+ pattern: /[MN][A-Za-z\d]{23}\.[\w-]{6}\.[\w-]{27}/g,
4487
+ replacement: "<REDACTED:discord_token>"
4488
+ },
4489
+ {
4490
+ name: "jwt",
4491
+ pattern: /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g,
4492
+ replacement: "<REDACTED:jwt>"
4493
+ },
4494
+ // Full PEM block (was header-only in the wire floor — this redacts the body too).
4495
+ {
4496
+ name: "private_key_header",
4497
+ pattern: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,
4498
+ replacement: "<REDACTED:private_key>"
4499
+ },
4500
+ // modelstat's own device bearer — agents must never ship their credential.
4501
+ {
4502
+ name: "modelstat_device_secret",
4503
+ pattern: /ds_live_[A-Za-z0-9_-]{32,}/g,
4504
+ replacement: "<REDACTED:modelstat_device_secret>"
4505
+ },
4506
+ // Generic env-style KEY=VALUE where KEY names a secret. Keeps the var name.
4507
+ {
4508
+ name: "env_secret",
4509
+ pattern: /\b([A-Z][A-Z0-9_]*(?:TOKEN|KEY|SECRET|PASSWORD|PASSWD|API)[A-Z0-9_]*)\s*[:=]\s*['"]?([^\s'"]{12,})['"]?/g,
4510
+ replacement: "$1=<REDACTED:env_secret>"
4511
+ },
4512
+ {
4513
+ name: "bearer_header",
4514
+ pattern: /Bearer\s+[A-Za-z0-9._~+/-]{20,}=*/g,
4515
+ replacement: "Bearer <REDACTED:bearer>"
4516
+ },
4517
+ {
4518
+ name: "db_url_with_password",
4519
+ pattern: /\b(postgres|mysql|mongodb|redis|amqp)(?:\+[a-z]+)?:\/\/[^:\s]+:([^@\s]+)@/gi,
4520
+ replacement: "$1://<user>:<REDACTED:db_password>@"
4521
+ },
4522
+ // Generic 40-char base64-ish blob (e.g. an AWS secret access key on its own).
4523
+ // Most generic ⇒ last, so specific patterns claim their matches first.
4524
+ {
4525
+ name: "aws_secret_key",
4526
+ pattern: /(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])/g,
4527
+ replacement: "<REDACTED:aws_secret_key>"
4528
+ }
4529
+ ];
4530
+ }
4531
+ });
4532
+
4533
+ // ../../packages/core/src/redact.ts
4534
+ function setRemoteRedactionPatterns(patterns) {
4535
+ remotePatterns = patterns;
4536
+ }
4537
+ function entropy(s) {
4538
+ const freq = /* @__PURE__ */ new Map();
4539
+ for (const c of s) freq.set(c, (freq.get(c) ?? 0) + 1);
4540
+ let h = 0;
4541
+ for (const n of freq.values()) {
4542
+ const p = n / s.length;
4543
+ h -= p * Math.log2(p);
4544
+ }
4545
+ return h;
4546
+ }
4547
+ function redact(text, repoRootAbs) {
4548
+ let out = text;
4549
+ const counts = {
4550
+ secrets_found: 0,
4551
+ emails_redacted: 0,
4552
+ paths_redacted_absolute: 0
4553
+ };
4554
+ for (const { name, pattern } of SECRET_FLOOR) {
4555
+ out = out.replace(pattern, () => {
4556
+ counts.secrets_found += 1;
4557
+ return `[REDACTED:${name}]`;
4558
+ });
4559
+ }
4560
+ for (const { name, pattern } of remotePatterns) {
4561
+ out = out.replace(pattern, () => {
4562
+ counts.secrets_found += 1;
4563
+ return `[REDACTED:${name}]`;
4564
+ });
4565
+ }
4566
+ out = out.replace(TOKEN_CANDIDATE, (match) => {
4567
+ if (/^[a-f0-9]+$/i.test(match)) return match;
4568
+ if (/^[A-Z]+$/.test(match)) return match;
4569
+ const hasLetter = /[A-Za-z]/.test(match);
4570
+ const hasDigit = /\d/.test(match);
4571
+ const hasUpper = /[A-Z]/.test(match);
4572
+ const hasLower = /[a-z]/.test(match);
4573
+ if (!(hasLetter && hasDigit && hasUpper && hasLower)) return match;
4574
+ if (entropy(match) < 3.6) return match;
4575
+ counts.secrets_found += 1;
4576
+ return `[REDACTED:hi-entropy]`;
4577
+ });
4578
+ out = out.replace(EMAIL_PATTERN, () => {
4579
+ counts.emails_redacted += 1;
4580
+ return "[REDACTED:email]";
4581
+ });
4582
+ const pathReplacer = (match) => {
4583
+ if (repoRootAbs && match.startsWith(repoRootAbs)) {
4584
+ return match.slice(repoRootAbs.length).replace(/^\/+/, "./");
4585
+ }
4586
+ counts.paths_redacted_absolute += 1;
4587
+ return "[REDACTED:abs-path]";
4588
+ };
4589
+ out = out.replace(ABSOLUTE_PATH_MACOS, pathReplacer);
4590
+ out = out.replace(ABSOLUTE_PATH_LINUX, pathReplacer);
4591
+ return { text: out, counts };
4592
+ }
4593
+ var remotePatterns, EMAIL_PATTERN, ABSOLUTE_PATH_MACOS, ABSOLUTE_PATH_LINUX, TOKEN_CANDIDATE;
4594
+ var init_redact = __esm({
4595
+ "../../packages/core/src/redact.ts"() {
4596
+ "use strict";
4597
+ init_redact_floor();
4598
+ remotePatterns = [];
4599
+ EMAIL_PATTERN = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
4600
+ ABSOLUTE_PATH_MACOS = /\/Users\/[^\s"'`)]+/g;
4601
+ ABSOLUTE_PATH_LINUX = /\/home\/[^\s"'`)]+/g;
4602
+ TOKEN_CANDIDATE = /[A-Za-z0-9/+=_-]{32,}/g;
4603
+ }
4604
+ });
4605
+
4314
4606
  // ../../packages/core/src/schemas.ts
4315
- var TokenUsage, GitContext, RawEvent, RedactionReport, TaxonomyHintRooted, Segment, ToolCallWire, IngestBatch, HeartbeatPayload, DeviceEnrollment, DeviceSelfRegister, DeviceClaimRequest, ProcessingMetadata, RedactionPolicy, DetectedInstallation, DetectedIdentity, DiscoveryReport, ClassificationConfidenceEnum;
4607
+ var TokenUsage, GitContext, RawEvent, RedactionReport, TaxonomyHintRooted, Segment, ToolAction, ToolCallWire, IngestBatch, HeartbeatPayload, DeviceEnrollment, DeviceSelfRegister, DeviceClaimRequest, ProcessingMetadata, RedactionPolicy, DetectedInstallation, DetectedIdentity, DiscoveryReport, ClassificationConfidenceEnum;
4316
4608
  var init_schemas = __esm({
4317
4609
  "../../packages/core/src/schemas.ts"() {
4318
4610
  "use strict";
@@ -4405,18 +4697,51 @@ var init_schemas = __esm({
4405
4697
  abstract: external_exports.string().max(512),
4406
4698
  /** Tokens spent inside this segment only. */
4407
4699
  tokens: TokenUsage,
4408
- /** Tags with strongly-typed root keys. Server merges with its own
4409
- * classifier output and files any novel names as taxonomy proposals. */
4700
+ /** Tags with strongly-typed root keys. The server may merge these with
4701
+ * its own classifier output. */
4410
4702
  tags: external_exports.array(TaxonomyHintRooted).max(40).default([]),
4411
4703
  /** Counts of what was stripped. */
4412
4704
  redaction: RedactionReport,
4413
4705
  /** `source_event_id`s covered by this segment. Used for dedupe + replay. */
4414
4706
  source_event_ids: external_exports.array(external_exports.string()).max(2e3),
4415
4707
  /** Optional embedding of the abstract (BGE-small-en-v1.5, 384 dims).
4416
- * Present when the companion has an Embedder adapter configured.
4417
- * Reserved for server-side similarity / clustering. */
4708
+ * Present when the companion has an Embedder adapter configured. */
4418
4709
  abstract_embedding: external_exports.array(external_exports.number()).length(384).optional()
4419
4710
  });
4711
+ ToolAction = external_exports.object({
4712
+ /** Where it ran: `shell`, `mcp`, `builtin`, `browser`. (tier 0) */
4713
+ surface: external_exports.string().max(40),
4714
+ /** Concrete program/operation, or a generic bucket token. (tier 0 | bucket) */
4715
+ executable: external_exports.string().max(80).nullable().default(null),
4716
+ /** Verb/intent (`restart`, `read`, …). (tier 0) */
4717
+ action: external_exports.string().max(40).nullable().default(null),
4718
+ /** What it acts on (`deployment`, `file`, …). (tier 0) */
4719
+ object: external_exports.string().max(60).nullable().default(null),
4720
+ /** Governed safe flags (`destructive`, `remote`, …). (tier 0) */
4721
+ qualifiers: external_exports.array(external_exports.string().max(40)).max(8).default([]),
4722
+ /** Value-masked argument skeleton (every value → `§`). (tier 1) */
4723
+ param_shape: external_exports.string().max(200).nullable().default(null),
4724
+ /** Relevant non-sensitive keywords (e.g. ["rollout","restart","prod"]),
4725
+ * OpenAI-redacted on-device. (tier 0) */
4726
+ keywords: external_exports.array(external_exports.string().max(40)).max(12).default([]),
4727
+ /** Human-readable command summary (e.g. "redeploying service payments-api"),
4728
+ * OpenAI-redacted on-device. (tier 0) */
4729
+ abstract: external_exports.string().max(200).nullable().default(null),
4730
+ /** The compliance-redacted command text — PII/secrets stripped on-device
4731
+ * (SOC2/GDPR), org-internal infra intact; the server derives semantics from
4732
+ * it. Un-redacted raw never ships. (tier 0, post-redaction) */
4733
+ command_redacted: external_exports.string().max(1e3).nullable().default(null),
4734
+ /** Per-script content abstracts for any script/bash FILES the command runs
4735
+ * — summarized on-device by the local model, then redacted. Ordered by
4736
+ * appearance; `token` is the script's token exactly as it appears in
4737
+ * `command_redacted`, so the backend deterministically zips each `summary`
4738
+ * to its place when ingesting the command + its scripts. (tier 0) */
4739
+ scripts: external_exports.array(external_exports.object({ token: external_exports.string().max(200), summary: external_exports.string().max(200) })).max(8).default([]),
4740
+ /** Extractor confidence in [0, 1]. */
4741
+ confidence: external_exports.number().min(0).max(1).default(0),
4742
+ /** Provenance of the extraction, e.g. `shell.v2`. */
4743
+ extractor: external_exports.string().max(40)
4744
+ }).strict();
4420
4745
  ToolCallWire = external_exports.object({
4421
4746
  /** tool_use block `id` / codex `call_id`; parsers fall back to a
4422
4747
  * deterministic `tc_<djb2-base36>` of `${source_event_id}|${call_index}`
@@ -4456,9 +4781,9 @@ var init_schemas = __esm({
4456
4781
  /** Model of the assistant message that issued the call. `<synthetic>`
4457
4782
  * kept verbatim per the PR #12 attribution rules. */
4458
4783
  model: external_exports.string().max(120).nullable(),
4459
- /** ONLY for shell-ish tools: command verbs from the fixed allowlist
4460
- * (@modelstat/parsers/shell-families). Never raw command text. */
4461
- command_families: external_exports.array(external_exports.string().max(40)).max(3).default([])
4784
+ /** On-device action decomposition nested + additive, `null` when nothing
4785
+ * was extracted. Replaces `command_families`. */
4786
+ action: ToolAction.nullable().default(null)
4462
4787
  });
4463
4788
  IngestBatch = external_exports.object({
4464
4789
  batch_id: external_exports.string(),
@@ -4469,7 +4794,7 @@ var init_schemas = __esm({
4469
4794
  segments: external_exports.array(Segment).max(2e3).default([]),
4470
4795
  /** Per-call tool invocations (additive — old agents omit it, old
4471
4796
  * servers ignore it). See ToolCallWire for the privacy contract:
4472
- * hashes / byte sizes / allowlisted verbs only, never payloads. */
4797
+ * hashes / byte sizes / governed action tokens only, never payloads. */
4473
4798
  tool_calls: external_exports.array(ToolCallWire).max(2e4).default([]),
4474
4799
  /** Optional per-session metadata hint: which installation produced them, etc. */
4475
4800
  session_installs: external_exports.record(
@@ -4481,11 +4806,10 @@ var init_schemas = __esm({
4481
4806
  ).optional(),
4482
4807
  /** Optional per-session titles — session_id → short redacted title
4483
4808
  * (≤120 chars) produced by the companion's local titler from the
4484
- * session's segment abstracts. Server-side this is last-write-wins
4485
- * per session; companions recompute it from the full session view on
4486
- * every upload, so the latest batch always carries the freshest
4487
- * title. Absent for runtimes without a titler (older agents, no-op
4488
- * browser summariser) — the server keeps whatever it has. */
4809
+ * session's segment abstracts. Companions recompute it from the full
4810
+ * session view on every upload, so the latest batch always carries the
4811
+ * freshest title. Absent for runtimes without a titler (older agents,
4812
+ * no-op browser summariser). */
4489
4813
  session_titles: external_exports.record(external_exports.string(), external_exports.string().max(120)).optional()
4490
4814
  });
4491
4815
  HeartbeatPayload = external_exports.object({
@@ -4583,304 +4907,136 @@ var init_schemas = __esm({
4583
4907
  }
4584
4908
  });
4585
4909
 
4586
- // ../../packages/core/src/ids.ts
4587
- function ulid(seedTime) {
4588
- const t = seedTime ?? Date.now();
4589
- let timeStr = "";
4590
- let ts = t;
4591
- for (let i = 9; i >= 0; i--) {
4592
- timeStr = ULID_ALPHABET[ts % 32] + timeStr;
4593
- ts = Math.floor(ts / 32);
4594
- }
4595
- const bytes = new Uint8Array(16);
4596
- globalThis.crypto.getRandomValues(bytes);
4597
- let randStr = "";
4598
- for (let i = 0; i < 16; i++) {
4599
- randStr += ULID_ALPHABET[bytes[i] % 32];
4600
- }
4601
- return timeStr + randStr;
4602
- }
4603
- function sourceEventId(deviceId, sourceOrFilePath, byteOffsetMaybe) {
4604
- let key;
4605
- if (typeof sourceOrFilePath === "string") {
4606
- const byteOffset = byteOffsetMaybe ?? 0;
4607
- key = `fs::${sourceOrFilePath}::${byteOffset}`;
4608
- } else if ("file" in sourceOrFilePath) {
4609
- key = `fs::${sourceOrFilePath.file}::${sourceOrFilePath.byteOffset}`;
4610
- } else if ("lineUuid" in sourceOrFilePath) {
4611
- key = `uuid::${sourceOrFilePath.lineUuid}`;
4612
- } else {
4613
- key = `web::${sourceOrFilePath.host}::${sourceOrFilePath.conversationId}::${sourceOrFilePath.messageId}`;
4614
- }
4615
- const s = `${deviceId}::${key}`;
4616
- let h = 5381n;
4617
- for (let i = 0; i < s.length; i++) {
4618
- h = h * 33n ^ BigInt(s.charCodeAt(i));
4619
- h &= 0xffffffffffffffffn;
4620
- }
4621
- return `evt_${h.toString(36)}`;
4622
- }
4623
- function segmentId(sessionId, startedAtMs, endedAtMs, sourceEventIds) {
4624
- const sorted = [...sourceEventIds].sort().join(",");
4625
- const s = `${sessionId}|${startedAtMs}|${endedAtMs}|${sorted}`;
4626
- let h = 5381n;
4627
- for (let i = 0; i < s.length; i++) {
4628
- h = h * 33n ^ BigInt(s.charCodeAt(i));
4629
- h &= 0xffffffffffffffffn;
4630
- }
4631
- return `seg_${h.toString(36)}`;
4632
- }
4633
- var ULID_ALPHABET, batchId;
4634
- var init_ids = __esm({
4635
- "../../packages/core/src/ids.ts"() {
4910
+ // ../../packages/core/src/index.ts
4911
+ var init_src = __esm({
4912
+ "../../packages/core/src/index.ts"() {
4636
4913
  "use strict";
4637
- ULID_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
4638
- batchId = () => ulid();
4914
+ init_billing();
4915
+ init_enums();
4916
+ init_ids();
4917
+ init_policies();
4918
+ init_redact();
4919
+ init_redact_floor();
4920
+ init_schemas();
4639
4921
  }
4640
4922
  });
4641
4923
 
4642
- // ../../packages/core/src/redact.ts
4643
- function entropy(s) {
4644
- const freq = /* @__PURE__ */ new Map();
4645
- for (const c of s) freq.set(c, (freq.get(c) ?? 0) + 1);
4646
- let h = 0;
4647
- for (const n of freq.values()) {
4648
- const p = n / s.length;
4649
- h -= p * Math.log2(p);
4924
+ // ../../packages/parsers/src/tool-action/scripts.ts
4925
+ function detectScriptRefs(command) {
4926
+ const refs = [];
4927
+ for (const segment of command.split(SEGMENT_SEP)) {
4928
+ const tokens = segment.trim().split(/\s+/).filter(Boolean);
4929
+ tokens.forEach((tok, i) => {
4930
+ const t = stripQuotes(tok);
4931
+ if (!t || t.startsWith("-") || t.includes("://")) return;
4932
+ const looksLikeScript = SCRIPT_EXT.test(t) || // ends in a script extension
4933
+ t.startsWith("./") || t.startsWith("../") || // an explicit relative executable
4934
+ i === 0 && t.includes("/");
4935
+ if (looksLikeScript) refs.push(t);
4936
+ });
4650
4937
  }
4651
- return h;
4938
+ return refs;
4652
4939
  }
4653
- function redact(text, repoRootAbs) {
4654
- let out = text;
4655
- const counts = {
4656
- secrets_found: 0,
4657
- emails_redacted: 0,
4658
- paths_redacted_absolute: 0
4940
+ function scriptCandidates(ref, roots) {
4941
+ const out = [];
4942
+ const push = (p) => {
4943
+ if (p && !out.includes(p)) out.push(p);
4659
4944
  };
4660
- for (const { name, pattern } of SECRET_PATTERNS) {
4661
- out = out.replace(pattern, () => {
4662
- counts.secrets_found += 1;
4663
- return `[REDACTED:${name}]`;
4664
- });
4945
+ if (isAbsolute(ref)) push(ref);
4946
+ for (const root of roots) {
4947
+ if (root) push(joinPath(root, ref));
4665
4948
  }
4666
- out = out.replace(TOKEN_CANDIDATE, (match) => {
4667
- if (/^[a-f0-9]+$/i.test(match)) return match;
4668
- if (/^[A-Z]+$/.test(match)) return match;
4669
- const hasLetter = /[A-Za-z]/.test(match);
4670
- const hasDigit = /\d/.test(match);
4671
- const hasUpper = /[A-Z]/.test(match);
4672
- const hasLower = /[a-z]/.test(match);
4673
- if (!(hasLetter && hasDigit && hasUpper && hasLower)) return match;
4674
- if (entropy(match) < 3.6) return match;
4675
- counts.secrets_found += 1;
4676
- return `[REDACTED:hi-entropy]`;
4677
- });
4678
- out = out.replace(EMAIL_PATTERN, () => {
4679
- counts.emails_redacted += 1;
4680
- return "[REDACTED:email]";
4681
- });
4682
- const pathReplacer = (match) => {
4683
- if (repoRootAbs && match.startsWith(repoRootAbs)) {
4684
- return match.slice(repoRootAbs.length).replace(/^\/+/, "./");
4685
- }
4686
- counts.paths_redacted_absolute += 1;
4687
- return "[REDACTED:abs-path]";
4688
- };
4689
- out = out.replace(ABSOLUTE_PATH_MACOS, pathReplacer);
4690
- out = out.replace(ABSOLUTE_PATH_LINUX, pathReplacer);
4691
- return { text: out, counts };
4949
+ push(ref);
4950
+ return out.sort(
4951
+ (a, b) => Number(isAbsolute(b)) - Number(isAbsolute(a)) || b.length - a.length
4952
+ );
4692
4953
  }
4693
- var SECRET_PATTERNS, EMAIL_PATTERN, ABSOLUTE_PATH_MACOS, ABSOLUTE_PATH_LINUX, TOKEN_CANDIDATE;
4694
- var init_redact = __esm({
4695
- "../../packages/core/src/redact.ts"() {
4696
- "use strict";
4697
- SECRET_PATTERNS = [
4698
- { name: "anthropic_key", pattern: /sk-ant-[A-Za-z0-9_-]{20,}/g },
4699
- { name: "openai_key", pattern: /sk-(?:proj-)?[A-Za-z0-9_-]{20,}/g },
4700
- { name: "google_api_key", pattern: /AIza[0-9A-Za-z_-]{35}/g },
4701
- { name: "aws_access_key", pattern: /AKIA[0-9A-Z]{16}/g },
4702
- { name: "aws_secret_key", pattern: /(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])/g },
4703
- { name: "github_pat", pattern: /ghp_[A-Za-z0-9]{36}/g },
4704
- { name: "github_oauth", pattern: /gho_[A-Za-z0-9]{36}/g },
4705
- { name: "github_app", pattern: /gh[sur]_[A-Za-z0-9]{36}/g },
4706
- { name: "slack_token", pattern: /xox[baprs]-[A-Za-z0-9-]{10,}/g },
4707
- { name: "stripe_live_key", pattern: /sk_live_[A-Za-z0-9]{24,}/g },
4708
- { name: "stripe_test_key", pattern: /sk_test_[A-Za-z0-9]{24,}/g },
4709
- { name: "jwt", pattern: /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g },
4710
- { name: "private_key_header", pattern: /-----BEGIN [A-Z ]+PRIVATE KEY-----/g }
4711
- ];
4712
- EMAIL_PATTERN = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
4713
- ABSOLUTE_PATH_MACOS = /\/Users\/[^\s"'`)]+/g;
4714
- ABSOLUTE_PATH_LINUX = /\/home\/[^\s"'`)]+/g;
4715
- TOKEN_CANDIDATE = /[A-Za-z0-9/+=_-]{32,}/g;
4954
+ function resolveScriptPath(ref, roots, exists) {
4955
+ for (const cand of scriptCandidates(ref, roots)) {
4956
+ if (exists(cand)) return cand;
4716
4957
  }
4717
- });
4718
-
4719
- // ../../packages/core/src/billing.ts
4720
- var MILLION, FREE_INCLUDED_TOKENS, TEAM_INCLUDED_PER_SEAT;
4721
- var init_billing = __esm({
4722
- "../../packages/core/src/billing.ts"() {
4723
- "use strict";
4724
- MILLION = 1000000n;
4725
- FREE_INCLUDED_TOKENS = 100n * MILLION;
4726
- TEAM_INCLUDED_PER_SEAT = 250n * MILLION;
4958
+ return null;
4959
+ }
4960
+ function isAbsolute(p) {
4961
+ return p.startsWith("/") || /^[A-Za-z]:[\\/]/.test(p);
4962
+ }
4963
+ function joinPath(root, rel) {
4964
+ return `${root.replace(/\/+$/, "")}/${rel.replace(/^\.\//, "")}`;
4965
+ }
4966
+ function stripQuotes(token) {
4967
+ if (token.length >= 2) {
4968
+ const a = token[0];
4969
+ const b = token[token.length - 1];
4970
+ if (a === "'" && b === "'" || a === '"' && b === '"') return token.slice(1, -1);
4727
4971
  }
4728
- });
4729
-
4730
- // ../../packages/core/src/index.ts
4731
- var init_src = __esm({
4732
- "../../packages/core/src/index.ts"() {
4972
+ return token;
4973
+ }
4974
+ var SEGMENT_SEP, SCRIPT_EXT;
4975
+ var init_scripts = __esm({
4976
+ "../../packages/parsers/src/tool-action/scripts.ts"() {
4733
4977
  "use strict";
4734
- init_enums();
4735
- init_schemas();
4736
- init_ids();
4737
- init_redact();
4738
- init_billing();
4978
+ SEGMENT_SEP = /\s*(?:&&|\|\||[;|&\n])\s*/;
4979
+ SCRIPT_EXT = /\.(sh|bash|zsh|ksh|fish|py|rb|js|mjs|cjs|ts|tsx|pl|php|lua|ps1|bat|cmd|r|jl|groovy|kts)$/i;
4739
4980
  }
4740
4981
  });
4741
4982
 
4742
- // ../../packages/parsers/src/shell-families/index.ts
4743
- function extractCommandFamilies(command) {
4744
- const families = [];
4745
- for (const part of splitCommandParts(command)) {
4746
- const verb = leadingVerb(part);
4747
- if (!verb || !ALLOWLIST.has(verb)) continue;
4748
- if (!families.includes(verb)) families.push(verb);
4749
- if (families.length >= MAX_COMMAND_FAMILIES) break;
4983
+ // ../../packages/parsers/src/tool-action/index.ts
4984
+ function extractToolAction(call) {
4985
+ const isMcp = call.server.startsWith("mcp:");
4986
+ const command = isMcp ? null : shellCommandOf(call.input);
4987
+ const surface = isMcp ? "mcp" : command != null ? "shell" : "builtin";
4988
+ let executable = call.name || null;
4989
+ let param_shape = null;
4990
+ let command_redacted = null;
4991
+ if (command != null) {
4992
+ const [head = "", ...rest] = command.trim().split(/\s+/);
4993
+ executable = basename(head) || null;
4994
+ param_shape = paramShape(rest.join(" ")) || null;
4995
+ command_redacted = redact(command, call.cwd ?? void 0).text.slice(0, MAX_COMMAND_REDACTED) || null;
4750
4996
  }
4751
- return families;
4997
+ return {
4998
+ surface,
4999
+ executable,
5000
+ action: null,
5001
+ object: null,
5002
+ qualifiers: [],
5003
+ param_shape,
5004
+ keywords: [],
5005
+ abstract: null,
5006
+ command_redacted,
5007
+ scripts: [],
5008
+ confidence: 0,
5009
+ extractor: `${surface}.v1`
5010
+ };
4752
5011
  }
4753
- function splitCommandParts(command) {
4754
- const parts = [];
4755
- let current = "";
4756
- let inSingle = false;
4757
- let inDouble = false;
4758
- for (let i = 0; i < command.length; i++) {
4759
- const ch = command[i];
4760
- if (!inSingle && ch === "\\") {
4761
- current += ch + (command[i + 1] ?? "");
4762
- i++;
4763
- continue;
4764
- }
4765
- if (ch === "'" && !inDouble) {
4766
- inSingle = !inSingle;
4767
- current += ch;
4768
- continue;
4769
- }
4770
- if (ch === '"' && !inSingle) {
4771
- inDouble = !inDouble;
4772
- current += ch;
4773
- continue;
4774
- }
4775
- if (!inSingle && !inDouble) {
4776
- if (ch === ";" || ch === "|" || ch === "\n") {
4777
- parts.push(current);
4778
- current = "";
4779
- continue;
4780
- }
4781
- if (ch === "&" && command[i + 1] === "&") {
4782
- parts.push(current);
4783
- current = "";
4784
- i++;
4785
- continue;
4786
- }
4787
- }
4788
- current += ch;
4789
- }
4790
- parts.push(current);
4791
- return parts;
5012
+ function extractLocalToolContext(call) {
5013
+ if (call.server.startsWith("mcp:")) return null;
5014
+ const command = shellCommandOf(call.input);
5015
+ if (command == null) return null;
5016
+ return { command, cwd: call.cwd ?? null };
4792
5017
  }
4793
- function leadingVerb(part) {
4794
- const tokens = part.trim().split(/\s+/);
4795
- let i = 0;
4796
- while (i < tokens.length) {
4797
- const tok = stripQuotes(tokens[i] ?? "");
4798
- if (tok === "") {
4799
- i++;
4800
- continue;
5018
+ function shellCommandOf(input) {
5019
+ if (typeof input === "string") return input.trim() ? input : null;
5020
+ if (input && typeof input === "object") {
5021
+ const cmd = input.command ?? input.cmd;
5022
+ if (typeof cmd === "string") return cmd.trim() ? cmd : null;
5023
+ if (Array.isArray(cmd)) {
5024
+ const parts = cmd.filter((p) => typeof p === "string");
5025
+ if (parts.length) return parts.join(" ");
4801
5026
  }
4802
- if (VAR_ASSIGNMENT.test(tok)) {
4803
- i++;
4804
- continue;
4805
- }
4806
- if (WRAPPERS.has(tok)) {
4807
- i++;
4808
- while (i < tokens.length && (tokens[i] ?? "").startsWith("-")) i++;
4809
- continue;
4810
- }
4811
- const base = tok.split("/").pop() ?? tok;
4812
- return base === "" ? null : base;
4813
5027
  }
4814
5028
  return null;
4815
5029
  }
4816
- function stripQuotes(token) {
4817
- if (token.length >= 2) {
4818
- const first = token[0];
4819
- const last = token[token.length - 1];
4820
- if (first === "'" && last === "'" || first === '"' && last === '"') {
4821
- return token.slice(1, -1);
4822
- }
4823
- }
4824
- return token;
5030
+ function basename(token) {
5031
+ return token.split("/").pop() ?? token;
4825
5032
  }
4826
- var SHELL_FAMILY_ALLOWLIST, MAX_COMMAND_FAMILIES, ALLOWLIST, WRAPPERS, VAR_ASSIGNMENT;
4827
- var init_shell_families = __esm({
4828
- "../../packages/parsers/src/shell-families/index.ts"() {
5033
+ var MAX_COMMAND_REDACTED;
5034
+ var init_tool_action = __esm({
5035
+ "../../packages/parsers/src/tool-action/index.ts"() {
4829
5036
  "use strict";
4830
- SHELL_FAMILY_ALLOWLIST = [
4831
- "git",
4832
- "npm",
4833
- "pnpm",
4834
- "npx",
4835
- "yarn",
4836
- "node",
4837
- "python",
4838
- "python3",
4839
- "pytest",
4840
- "pip",
4841
- "pip3",
4842
- "cargo",
4843
- "rustc",
4844
- "go",
4845
- "make",
4846
- "cmake",
4847
- "docker",
4848
- "docker-compose",
4849
- "kubectl",
4850
- "helm",
4851
- "terraform",
4852
- "gh",
4853
- "aws",
4854
- "gcloud",
4855
- "az",
4856
- "curl",
4857
- "wget",
4858
- "rg",
4859
- "grep",
4860
- "find",
4861
- "sed",
4862
- "awk",
4863
- "jq",
4864
- "psql",
4865
- "mysql",
4866
- "redis-cli",
4867
- "brew",
4868
- "apt",
4869
- "tsx",
4870
- "vitest",
4871
- "jest",
4872
- "playwright",
4873
- "ruby",
4874
- "bundle",
4875
- "mvn",
4876
- "gradle",
4877
- "ls",
4878
- "cat"
4879
- ];
4880
- MAX_COMMAND_FAMILIES = 3;
4881
- ALLOWLIST = new Set(SHELL_FAMILY_ALLOWLIST);
4882
- WRAPPERS = /* @__PURE__ */ new Set(["sudo", "env", "time", "nice"]);
4883
- VAR_ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=/;
5037
+ init_src();
5038
+ init_scripts();
5039
+ MAX_COMMAND_REDACTED = 1e3;
4884
5040
  }
4885
5041
  });
4886
5042
 
@@ -4977,17 +5133,16 @@ function extractExcerpt(content) {
4977
5133
  const truncated = cleaned.slice(0, 320);
4978
5134
  return truncated.length > 0 ? truncated : void 0;
4979
5135
  }
4980
- function commandFamiliesFor(server, name, input) {
4981
- if (server !== "builtin" || !SHELL_TOOL_NAMES.has(name)) return [];
4982
- if (typeof input !== "object" || input === null) return [];
4983
- const command = input.command;
4984
- return typeof command === "string" ? extractCommandFamilies(command) : [];
4985
- }
4986
5136
  function buildToolCallDraft(opts) {
4987
5137
  const { server, name } = splitObservedToolName(opts.observedName);
4988
5138
  const hashes = hashArgs(opts.input);
5139
+ const external_call_id = typeof opts.rawCallId === "string" && opts.rawCallId.trim() !== "" ? opts.rawCallId.trim().slice(0, 120) : fallbackCallId(opts.sourceEventId, opts.callIndex);
5140
+ if (opts.contexts) {
5141
+ const local = extractLocalToolContext({ server, name, input: opts.input, cwd: opts.cwd });
5142
+ if (local) opts.contexts.push({ external_call_id, ...local });
5143
+ }
4989
5144
  return {
4990
- external_call_id: typeof opts.rawCallId === "string" && opts.rawCallId.trim() !== "" ? opts.rawCallId.trim().slice(0, 120) : fallbackCallId(opts.sourceEventId, opts.callIndex),
5145
+ external_call_id,
4991
5146
  session_id: opts.sessionId,
4992
5147
  source_event_id: opts.sourceEventId,
4993
5148
  agent: "claude_code",
@@ -5005,12 +5160,13 @@ function buildToolCallDraft(opts) {
5005
5160
  args_bytes: hashes.args_bytes,
5006
5161
  result_bytes: 0,
5007
5162
  model: opts.model,
5008
- command_families: commandFamiliesFor(server, name, opts.input)
5163
+ action: extractToolAction({ server, name, input: opts.input, cwd: opts.cwd })
5009
5164
  };
5010
5165
  }
5011
5166
  async function parseClaudeCodeJsonl(ctx) {
5012
5167
  const events = [];
5013
5168
  const toolCalls = [];
5169
+ const scriptContexts = [];
5014
5170
  const pendingByCallId = /* @__PURE__ */ new Map();
5015
5171
  let chunk = [];
5016
5172
  let emitted = 0;
@@ -5133,7 +5289,9 @@ async function parseClaudeCodeJsonl(ctx) {
5133
5289
  startedAt: a.timestamp,
5134
5290
  // Model verbatim from the issuing assistant message —
5135
5291
  // including "<synthetic>" (same rule as the event below).
5136
- model: a.message?.model ?? null
5292
+ model: a.message?.model ?? null,
5293
+ cwd,
5294
+ contexts: scriptContexts
5137
5295
  });
5138
5296
  const identity = toolIdentity(draft.server, draft.name);
5139
5297
  aggregate[identity] = (aggregate[identity] ?? 0) + 1;
@@ -5244,7 +5402,9 @@ async function parseClaudeCodeJsonl(ctx) {
5244
5402
  // No issuing assistant message on this line — attribute to the
5245
5403
  // session's last real model, same as user_message attribution
5246
5404
  // (lastModel never holds "<synthetic>", per the rule above).
5247
- model: lastModel
5405
+ model: lastModel,
5406
+ cwd,
5407
+ contexts: scriptContexts
5248
5408
  });
5249
5409
  toolCalls.push(draft);
5250
5410
  if (typeof t.id === "string" && t.id) pendingByCallId.set(t.id, draft);
@@ -5256,6 +5416,7 @@ async function parseClaudeCodeJsonl(ctx) {
5256
5416
  return {
5257
5417
  events,
5258
5418
  toolCalls,
5419
+ scriptContexts,
5259
5420
  stats: { rawLines, emittedEvents: emitted, skipped },
5260
5421
  sourceFile: ctx.sourceFile
5261
5422
  };
@@ -5274,22 +5435,14 @@ async function quickChecksum(path5) {
5274
5435
  for await (const chunk of stream) h.update(chunk);
5275
5436
  return { size: st.size, mtime: st.mtimeMs, tailHash: h.digest("hex").slice(0, 16) };
5276
5437
  }
5277
- var SHELL_TOOL_NAMES;
5278
5438
  var init_claude_code = __esm({
5279
5439
  "../../packages/parsers/src/claude-code/index.ts"() {
5280
5440
  "use strict";
5281
5441
  init_src();
5282
5442
  init_git();
5283
- init_shell_families();
5443
+ init_tool_action();
5284
5444
  init_tool_hash();
5285
5445
  init_types();
5286
- SHELL_TOOL_NAMES = /* @__PURE__ */ new Set([
5287
- "Bash",
5288
- "shell",
5289
- "local_shell_call",
5290
- "exec_command",
5291
- "run_terminal_cmd"
5292
- ]);
5293
5446
  }
5294
5447
  });
5295
5448
 
@@ -5302,20 +5455,6 @@ function deriveSessionIdFromRolloutPath(path5) {
5302
5455
  );
5303
5456
  return m ? m[1] ?? null : null;
5304
5457
  }
5305
- function commandFieldToString(cmd) {
5306
- if (typeof cmd === "string") return cmd || null;
5307
- if (Array.isArray(cmd)) {
5308
- const parts = cmd.filter((p) => typeof p === "string");
5309
- if (parts.length === 0) return null;
5310
- const head = (parts[0] ?? "").split("/").pop() ?? "";
5311
- const flag = parts[1] ?? "";
5312
- if (parts.length >= 3 && SHELL_WRAPPER_BINARIES.has(head) && /^-[a-z]*c[a-z]*$/i.test(flag)) {
5313
- return parts.slice(2).join("\n");
5314
- }
5315
- return parts.join(" ");
5316
- }
5317
- return null;
5318
- }
5319
5458
  function firstString(...values) {
5320
5459
  for (const v of values) {
5321
5460
  if (typeof v === "string" && v) return v;
@@ -5327,13 +5466,11 @@ function extractToolCallPayload(pt, p) {
5327
5466
  const failed = p.status === "failed";
5328
5467
  if (pt === "local_shell_call") {
5329
5468
  const action = p.action && typeof p.action === "object" ? p.action : null;
5330
- const command = commandFieldToString(action?.command);
5331
5469
  return {
5332
5470
  callId,
5333
5471
  server: "builtin",
5334
5472
  name: "shell",
5335
5473
  input: action,
5336
- commandFamilies: command ? extractCommandFamilies(command) : [],
5337
5474
  failed
5338
5475
  };
5339
5476
  }
@@ -5347,17 +5484,12 @@ function extractToolCallPayload(pt, p) {
5347
5484
  } catch {
5348
5485
  }
5349
5486
  }
5350
- if (SHELL_TOOL_NAMES2.has(observed)) {
5351
- const rec = input && typeof input === "object" && !Array.isArray(input) ? input : null;
5352
- const command = commandFieldToString(
5353
- rec?.command ?? rec?.cmd ?? (typeof input === "string" ? input : null)
5354
- );
5487
+ if (SHELL_TOOL_NAMES.has(observed)) {
5355
5488
  return {
5356
5489
  callId,
5357
5490
  server: "builtin",
5358
5491
  name: "shell",
5359
5492
  input,
5360
- commandFamilies: command ? extractCommandFamilies(command) : [],
5361
5493
  failed
5362
5494
  };
5363
5495
  }
@@ -5368,12 +5500,11 @@ function extractToolCallPayload(pt, p) {
5368
5500
  server: `mcp:${normalizeToolName(p.server).slice(0, 116)}`,
5369
5501
  name: normalizeToolName(observed),
5370
5502
  input,
5371
- commandFamilies: [],
5372
5503
  failed
5373
5504
  };
5374
5505
  }
5375
5506
  const { server, name } = splitObservedToolName(observed);
5376
- return { callId, server, name, input, commandFamilies: [], failed };
5507
+ return { callId, server, name, input, failed };
5377
5508
  }
5378
5509
  function outputIndicatesError(p) {
5379
5510
  const out = p.output ?? p.result;
@@ -5386,6 +5517,7 @@ function outputIndicatesError(p) {
5386
5517
  async function parseCodexRollout(ctx) {
5387
5518
  const events = [];
5388
5519
  const toolCalls = [];
5520
+ const scriptContexts = [];
5389
5521
  let chunk = [];
5390
5522
  let emitted = 0;
5391
5523
  const emit = async (e) => {
@@ -5468,8 +5600,16 @@ async function parseCodexRollout(ctx) {
5468
5600
  }
5469
5601
  const srcId = sourceEventId(ctx.deviceId, ctx.sourceFile, offsetAtLineStart);
5470
5602
  const { args_hash, signature_hash, args_bytes } = hashArgs(extracted.input);
5603
+ const externalCallId = (extracted.callId ?? fallbackCallId(srcId, 0)).slice(0, 120);
5604
+ const localCtx = extractLocalToolContext({
5605
+ server: extracted.server,
5606
+ name: extracted.name,
5607
+ input: extracted.input,
5608
+ cwd
5609
+ });
5610
+ if (localCtx) scriptContexts.push({ external_call_id: externalCallId, ...localCtx });
5471
5611
  const draft = {
5472
- external_call_id: (extracted.callId ?? fallbackCallId(srcId, 0)).slice(0, 120),
5612
+ external_call_id: externalCallId,
5473
5613
  session_id: sessionId,
5474
5614
  source_event_id: srcId,
5475
5615
  agent: "codex_cli",
@@ -5486,7 +5626,12 @@ async function parseCodexRollout(ctx) {
5486
5626
  args_bytes,
5487
5627
  result_bytes: 0,
5488
5628
  model,
5489
- command_families: extracted.commandFamilies
5629
+ action: extractToolAction({
5630
+ server: extracted.server,
5631
+ name: extracted.name,
5632
+ input: extracted.input,
5633
+ cwd
5634
+ })
5490
5635
  };
5491
5636
  toolCalls.push(draft);
5492
5637
  if (extracted.callId) openCalls.set(extracted.callId, draft);
@@ -5598,17 +5743,18 @@ async function parseCodexRollout(ctx) {
5598
5743
  return {
5599
5744
  events,
5600
5745
  toolCalls,
5746
+ scriptContexts,
5601
5747
  stats: { rawLines, emittedEvents: emitted, skipped },
5602
5748
  sourceFile: ctx.sourceFile
5603
5749
  };
5604
5750
  }
5605
- var TOOL_CALL_PAYLOAD_TYPES, TOOL_CALL_OUTPUT_PAYLOAD_TYPES, SHELL_TOOL_NAMES2, SHELL_WRAPPER_BINARIES;
5751
+ var TOOL_CALL_PAYLOAD_TYPES, TOOL_CALL_OUTPUT_PAYLOAD_TYPES, SHELL_TOOL_NAMES;
5606
5752
  var init_codex = __esm({
5607
5753
  "../../packages/parsers/src/codex/index.ts"() {
5608
5754
  "use strict";
5609
5755
  init_src();
5610
5756
  init_git();
5611
- init_shell_families();
5757
+ init_tool_action();
5612
5758
  init_tool_hash();
5613
5759
  init_types();
5614
5760
  TOOL_CALL_PAYLOAD_TYPES = /* @__PURE__ */ new Set([
@@ -5623,13 +5769,12 @@ var init_codex = __esm({
5623
5769
  "custom_tool_call_output",
5624
5770
  "mcp_tool_call_output"
5625
5771
  ]);
5626
- SHELL_TOOL_NAMES2 = /* @__PURE__ */ new Set([
5772
+ SHELL_TOOL_NAMES = /* @__PURE__ */ new Set([
5627
5773
  "shell",
5628
5774
  "local_shell_call",
5629
5775
  "exec_command",
5630
5776
  "run_terminal_cmd"
5631
5777
  ]);
5632
- SHELL_WRAPPER_BINARIES = /* @__PURE__ */ new Set(["bash", "sh", "zsh", "dash", "fish"]);
5633
5778
  }
5634
5779
  });
5635
5780
 
@@ -8192,6 +8337,7 @@ var init_src2 = __esm({
8192
8337
  "use strict";
8193
8338
  init_types();
8194
8339
  init_git();
8340
+ init_tool_action();
8195
8341
  init_claude_code();
8196
8342
  init_codex();
8197
8343
  init_cursor();
@@ -12030,12 +12176,12 @@ var require_infra = __commonJS({
12030
12176
  var assert2 = __require("assert");
12031
12177
  var { utf8DecodeBytes } = require_encoding();
12032
12178
  function collectASequenceOfCodePoints(condition, input, position) {
12033
- let result = "";
12179
+ let result2 = "";
12034
12180
  while (position.position < input.length && condition(input[position.position])) {
12035
- result += input[position.position];
12181
+ result2 += input[position.position];
12036
12182
  position.position++;
12037
12183
  }
12038
- return result;
12184
+ return result2;
12039
12185
  }
12040
12186
  function collectASequenceOfCodePointsFast(char, input, position) {
12041
12187
  const idx = input.indexOf(char, position.position);
@@ -12080,16 +12226,16 @@ var require_infra = __commonJS({
12080
12226
  if ((2 << 15) - 1 > length) {
12081
12227
  return String.fromCharCode.apply(null, input);
12082
12228
  }
12083
- let result = "";
12229
+ let result2 = "";
12084
12230
  let i = 0;
12085
12231
  let addition = (2 << 15) - 1;
12086
12232
  while (i < length) {
12087
12233
  if (i + addition > length) {
12088
12234
  addition = length - i;
12089
12235
  }
12090
- result += String.fromCharCode.apply(null, input.subarray(i, i += addition));
12236
+ result2 += String.fromCharCode.apply(null, input.subarray(i, i += addition));
12091
12237
  }
12092
- return result;
12238
+ return result2;
12093
12239
  }
12094
12240
  var invalidIsomorphicEncodeValueRegex = /[^\x00-\xFF]/;
12095
12241
  function isomorphicEncode(input) {
@@ -12114,12 +12260,12 @@ var require_infra = __commonJS({
12114
12260
  return lead === 0 && trail === str.length - 1 ? str : str.slice(lead, trail + 1);
12115
12261
  }
12116
12262
  function serializeJavascriptValueToJSONString(value) {
12117
- const result = JSON.stringify(value);
12118
- if (result === void 0) {
12263
+ const result2 = JSON.stringify(value);
12264
+ if (result2 === void 0) {
12119
12265
  throw new TypeError("Value is not JSON serializable");
12120
12266
  }
12121
- assert2(typeof result === "string");
12122
- return result;
12267
+ assert2(typeof result2 === "string");
12268
+ return result2;
12123
12269
  }
12124
12270
  module.exports = {
12125
12271
  collectASequenceOfCodePoints,
@@ -12506,9 +12652,9 @@ var require_runtime_features = __commonJS({
12506
12652
  * @returns {boolean}
12507
12653
  */
12508
12654
  #detectRuntimeFeature(feature) {
12509
- const result = detectRuntimeFeature(feature);
12510
- this.#map.set(feature, result);
12511
- return result;
12655
+ const result2 = detectRuntimeFeature(feature);
12656
+ this.#map.set(feature, result2);
12657
+ return result2;
12512
12658
  }
12513
12659
  };
12514
12660
  var instance = new RuntimeFeatures();
@@ -12773,16 +12919,16 @@ var require_webidl = __commonJS({
12773
12919
  message: `${argument} ("${webidl.util.TypeValueToString(O)}") is not an Object.`
12774
12920
  });
12775
12921
  }
12776
- const result = {};
12922
+ const result2 = {};
12777
12923
  if (!types.isProxy(O)) {
12778
12924
  const keys2 = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)];
12779
12925
  for (const key of keys2) {
12780
12926
  const keyName = webidl.util.Stringify(key);
12781
12927
  const typedKey = keyConverter(key, prefix, `Key ${keyName} in ${argument}`);
12782
12928
  const typedValue = valueConverter(O[key], prefix, `${argument}[${keyName}]`);
12783
- result[typedKey] = typedValue;
12929
+ result2[typedKey] = typedValue;
12784
12930
  }
12785
- return result;
12931
+ return result2;
12786
12932
  }
12787
12933
  const keys = Reflect.ownKeys(O);
12788
12934
  for (const key of keys) {
@@ -12790,10 +12936,10 @@ var require_webidl = __commonJS({
12790
12936
  if (desc?.enumerable) {
12791
12937
  const typedKey = keyConverter(key, prefix, argument);
12792
12938
  const typedValue = valueConverter(O[key], prefix, argument);
12793
- result[typedKey] = typedValue;
12939
+ result2[typedKey] = typedValue;
12794
12940
  }
12795
12941
  }
12796
- return result;
12942
+ return result2;
12797
12943
  };
12798
12944
  };
12799
12945
  webidl.interfaceConverter = function(TypeCheck, name) {
@@ -13489,20 +13635,20 @@ var require_util2 = __commonJS({
13489
13635
  }
13490
13636
  const { [keyIndex]: key, [valueIndex]: value } = values[index];
13491
13637
  this.#index = index + 1;
13492
- let result;
13638
+ let result2;
13493
13639
  switch (this.#kind) {
13494
13640
  case "key":
13495
- result = key;
13641
+ result2 = key;
13496
13642
  break;
13497
13643
  case "value":
13498
- result = value;
13644
+ result2 = value;
13499
13645
  break;
13500
13646
  case "key+value":
13501
- result = [key, value];
13647
+ result2 = [key, value];
13502
13648
  break;
13503
13649
  }
13504
13650
  return {
13505
- value: result,
13651
+ value: result2,
13506
13652
  done: false
13507
13653
  };
13508
13654
  }
@@ -14109,8 +14255,8 @@ var require_formdata_parser = __commonJS({
14109
14255
  throw parsingError("expected CRLF");
14110
14256
  }
14111
14257
  position.position += 2;
14112
- const result = parseMultipartFormDataHeaders(input, position);
14113
- let { name, filename, contentType, encoding } = result;
14258
+ const result2 = parseMultipartFormDataHeaders(input, position);
14259
+ let { name, filename, contentType, encoding } = result2;
14114
14260
  position.position += 2;
14115
14261
  let body;
14116
14262
  {
@@ -14530,8 +14676,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
14530
14676
  if (action != null) {
14531
14677
  ;
14532
14678
  (async () => {
14533
- const result = action();
14534
- const iterator = result?.[Symbol.asyncIterator]?.();
14679
+ const result2 = action();
14680
+ const iterator = result2?.[Symbol.asyncIterator]?.();
14535
14681
  if (iterator) {
14536
14682
  for await (const bytes of iterator) {
14537
14683
  if (isErrored(stream)) break;
@@ -14539,8 +14685,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
14539
14685
  controller.enqueue(new Uint8Array(bytes));
14540
14686
  }
14541
14687
  }
14542
- } else if (result?.length && !isErrored(stream)) {
14543
- controller.enqueue(typeof result === "string" ? textEncoder.encode(result) : new Uint8Array(result));
14688
+ } else if (result2?.length && !isErrored(stream)) {
14689
+ controller.enqueue(typeof result2 === "string" ? textEncoder.encode(result2) : new Uint8Array(result2));
14544
14690
  }
14545
14691
  queueMicrotask(() => readableStreamClose(controller));
14546
14692
  })();
@@ -15906,17 +16052,17 @@ var require_client_h2 = __commonJS({
15906
16052
  }
15907
16053
  } = http2;
15908
16054
  function parseH2Headers(headers) {
15909
- const result = [];
16055
+ const result2 = [];
15910
16056
  for (const [name, value] of Object.entries(headers)) {
15911
16057
  if (Array.isArray(value)) {
15912
16058
  for (const subvalue of value) {
15913
- result.push(Buffer.from(name), Buffer.from(subvalue));
16059
+ result2.push(Buffer.from(name), Buffer.from(subvalue));
15914
16060
  }
15915
16061
  } else {
15916
- result.push(Buffer.from(name), Buffer.from(value));
16062
+ result2.push(Buffer.from(name), Buffer.from(value));
15917
16063
  }
15918
16064
  }
15919
- return result;
16065
+ return result2;
15920
16066
  }
15921
16067
  function connectH2(client, socket) {
15922
16068
  client[kSocket] = socket;
@@ -17526,11 +17672,11 @@ var require_balanced_pool = __commonJS({
17526
17672
  return this;
17527
17673
  }
17528
17674
  _updateBalancedPoolStats() {
17529
- let result = 0;
17675
+ let result2 = 0;
17530
17676
  for (let i = 0; i < this[kClients].length; i++) {
17531
- result = getGreatestCommonDivisor(this[kClients][i][kWeight], result);
17677
+ result2 = getGreatestCommonDivisor(this[kClients][i][kWeight], result2);
17532
17678
  }
17533
- this[kGreatestCommonDivisor] = result;
17679
+ this[kGreatestCommonDivisor] = result2;
17534
17680
  }
17535
17681
  removeUpstream(upstream) {
17536
17682
  const upstreamOrigin = util2.parseOrigin(upstream).origin;
@@ -17772,26 +17918,26 @@ var require_agent = __commonJS({
17772
17918
  if (this[kOrigins].size >= this[kOptions].maxOrigins && !this[kOrigins].has(key)) {
17773
17919
  throw new MaxOriginsReachedError();
17774
17920
  }
17775
- const result = this[kClients].get(key);
17776
- let dispatcher = result && result.dispatcher;
17921
+ const result2 = this[kClients].get(key);
17922
+ let dispatcher = result2 && result2.dispatcher;
17777
17923
  if (!dispatcher) {
17778
17924
  const closeClientIfUnused = (connected) => {
17779
- const result2 = this[kClients].get(key);
17780
- if (result2) {
17781
- if (connected) result2.count -= 1;
17782
- if (result2.count <= 0) {
17925
+ const result3 = this[kClients].get(key);
17926
+ if (result3) {
17927
+ if (connected) result3.count -= 1;
17928
+ if (result3.count <= 0) {
17783
17929
  this[kClients].delete(key);
17784
- if (!result2.dispatcher.destroyed) {
17785
- result2.dispatcher.close();
17930
+ if (!result3.dispatcher.destroyed) {
17931
+ result3.dispatcher.close();
17786
17932
  }
17787
17933
  }
17788
17934
  this[kOrigins].delete(key);
17789
17935
  }
17790
17936
  };
17791
17937
  dispatcher = this[kFactory](opts.origin, this[kOptions]).on("drain", this[kOnDrain]).on("connect", (origin, targets) => {
17792
- const result2 = this[kClients].get(key);
17793
- if (result2) {
17794
- result2.count += 1;
17938
+ const result3 = this[kClients].get(key);
17939
+ if (result3) {
17940
+ result3.count += 1;
17795
17941
  }
17796
17942
  this[kOnConnect](origin, targets);
17797
17943
  }).on("disconnect", (origin, targets, err) => {
@@ -20723,20 +20869,20 @@ var require_mock_utils = __commonJS({
20723
20869
  }
20724
20870
  function generateKeyValues(data) {
20725
20871
  const keys = Object.keys(data);
20726
- const result = [];
20872
+ const result2 = [];
20727
20873
  for (let i = 0; i < keys.length; ++i) {
20728
20874
  const key = keys[i];
20729
20875
  const value = data[key];
20730
20876
  const name = Buffer.from(`${key}`);
20731
20877
  if (Array.isArray(value)) {
20732
20878
  for (let j = 0; j < value.length; ++j) {
20733
- result.push(name, Buffer.from(`${value[j]}`));
20879
+ result2.push(name, Buffer.from(`${value[j]}`));
20734
20880
  }
20735
20881
  } else {
20736
- result.push(name, Buffer.from(`${value}`));
20882
+ result2.push(name, Buffer.from(`${value}`));
20737
20883
  }
20738
20884
  }
20739
- return result;
20885
+ return result2;
20740
20886
  }
20741
20887
  function getStatusText(statusCode) {
20742
20888
  return STATUS_CODES[statusCode] || "unknown";
@@ -21210,16 +21356,16 @@ var require_mock_call_history = __commonJS({
21210
21356
  }
21211
21357
  toString() {
21212
21358
  const options = { betweenKeyValueSeparator: "->", betweenPairSeparator: "|" };
21213
- let result = "";
21359
+ let result2 = "";
21214
21360
  this.toMap().forEach((value, key) => {
21215
21361
  if (typeof value === "string" || value === void 0 || value === null) {
21216
- result = `${result}${key}${options.betweenKeyValueSeparator}${value}${options.betweenPairSeparator}`;
21362
+ result2 = `${result2}${key}${options.betweenKeyValueSeparator}${value}${options.betweenPairSeparator}`;
21217
21363
  }
21218
21364
  if (typeof value === "object" && value !== null || Array.isArray(value)) {
21219
- result = `${result}${key}${options.betweenKeyValueSeparator}${JSON.stringify(value)}${options.betweenPairSeparator}`;
21365
+ result2 = `${result2}${key}${options.betweenKeyValueSeparator}${JSON.stringify(value)}${options.betweenPairSeparator}`;
21220
21366
  }
21221
21367
  });
21222
- return result.slice(0, -1);
21368
+ return result2.slice(0, -1);
21223
21369
  }
21224
21370
  };
21225
21371
  var MockCallHistory = class {
@@ -21562,20 +21708,20 @@ var require_mock_agent = __commonJS({
21562
21708
  return this[kOptions] && this[kOptions].connections === 1 ? new MockClient(origin, mockOptions) : new MockPool(origin, mockOptions);
21563
21709
  }
21564
21710
  [kMockAgentGet](origin) {
21565
- const result = this[kClients].get(origin);
21566
- if (result?.dispatcher) {
21567
- return result.dispatcher;
21711
+ const result2 = this[kClients].get(origin);
21712
+ if (result2?.dispatcher) {
21713
+ return result2.dispatcher;
21568
21714
  }
21569
21715
  if (typeof origin !== "string") {
21570
21716
  const dispatcher = this[kFactory]("http://localhost:9999");
21571
21717
  this[kMockAgentSet](origin, dispatcher);
21572
21718
  return dispatcher;
21573
21719
  }
21574
- for (const [keyMatcher, result2] of Array.from(this[kClients])) {
21575
- if (result2 && typeof keyMatcher !== "string" && matchValue(keyMatcher, origin)) {
21720
+ for (const [keyMatcher, result3] of Array.from(this[kClients])) {
21721
+ if (result3 && typeof keyMatcher !== "string" && matchValue(keyMatcher, origin)) {
21576
21722
  const dispatcher = this[kFactory](origin);
21577
21723
  this[kMockAgentSet](origin, dispatcher);
21578
- dispatcher[kDispatches] = result2.dispatcher[kDispatches];
21724
+ dispatcher[kDispatches] = result3.dispatcher[kDispatches];
21579
21725
  return dispatcher;
21580
21726
  }
21581
21727
  }
@@ -21585,7 +21731,7 @@ var require_mock_agent = __commonJS({
21585
21731
  }
21586
21732
  pendingInterceptors() {
21587
21733
  const mockAgentClients = this[kClients];
21588
- return Array.from(mockAgentClients.entries()).flatMap(([origin, result]) => result.dispatcher[kDispatches].map((dispatch) => ({ ...dispatch, origin }))).filter(({ pending: pending2 }) => pending2);
21734
+ return Array.from(mockAgentClients.entries()).flatMap(([origin, result2]) => result2.dispatcher[kDispatches].map((dispatch) => ({ ...dispatch, origin }))).filter(({ pending: pending2 }) => pending2);
21589
21735
  }
21590
21736
  assertNoPendingInterceptors({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) {
21591
21737
  const pending2 = this.pendingInterceptors();
@@ -21695,7 +21841,7 @@ var require_snapshot_utils = __commonJS({
21695
21841
  var require_snapshot_recorder = __commonJS({
21696
21842
  "../../node_modules/.pnpm/undici@7.25.0/node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
21697
21843
  "use strict";
21698
- var { writeFile, readFile, mkdir: mkdir2 } = __require("fs/promises");
21844
+ var { writeFile: writeFile2, readFile: readFile2, mkdir: mkdir3 } = __require("fs/promises");
21699
21845
  var { dirname: dirname9, resolve: resolve6 } = __require("path");
21700
21846
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
21701
21847
  var { InvalidArgumentError, UndiciError } = require_errors();
@@ -21897,7 +22043,7 @@ var require_snapshot_recorder = __commonJS({
21897
22043
  throw new InvalidArgumentError("Snapshot path is required");
21898
22044
  }
21899
22045
  try {
21900
- const data = await readFile(resolve6(path5), "utf8");
22046
+ const data = await readFile2(resolve6(path5), "utf8");
21901
22047
  const parsed = JSON.parse(data);
21902
22048
  if (Array.isArray(parsed)) {
21903
22049
  this.#snapshots.clear();
@@ -21927,12 +22073,12 @@ var require_snapshot_recorder = __commonJS({
21927
22073
  throw new InvalidArgumentError("Snapshot path is required");
21928
22074
  }
21929
22075
  const resolvedPath = resolve6(path5);
21930
- await mkdir2(dirname9(resolvedPath), { recursive: true });
22076
+ await mkdir3(dirname9(resolvedPath), { recursive: true });
21931
22077
  const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
21932
22078
  hash,
21933
22079
  snapshot
21934
22080
  }));
21935
- await writeFile(resolvedPath, JSON.stringify(data, null, 2), { flush: true });
22081
+ await writeFile2(resolvedPath, JSON.stringify(data, null, 2), { flush: true });
21936
22082
  }
21937
22083
  /**
21938
22084
  * Clears all recorded snapshots
@@ -23714,8 +23860,8 @@ var require_date = __commonJS({
23714
23860
  }
23715
23861
  second = (code1 - 48) * 10 + (code2 - 48);
23716
23862
  }
23717
- const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
23718
- return result.getUTCDay() === weekday ? result : void 0;
23863
+ const result2 = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
23864
+ return result2.getUTCDay() === weekday ? result2 : void 0;
23719
23865
  }
23720
23866
  function parseAscTimeDate(date) {
23721
23867
  if (date.length !== 24 || date[7] !== " " || date[10] !== " " || date[19] !== " ") {
@@ -23877,8 +24023,8 @@ var require_date = __commonJS({
23877
24023
  return void 0;
23878
24024
  }
23879
24025
  const year = (yearDigit1 - 48) * 1e3 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48);
23880
- const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
23881
- return result.getUTCDay() === weekday ? result : void 0;
24026
+ const result2 = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
24027
+ return result2.getUTCDay() === weekday ? result2 : void 0;
23882
24028
  }
23883
24029
  function parseRfc850Date(date) {
23884
24030
  let commaIndex = -1;
@@ -24027,8 +24173,8 @@ var require_date = __commonJS({
24027
24173
  }
24028
24174
  second = (code1 - 48) * 10 + (code2 - 48);
24029
24175
  }
24030
- const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
24031
- return result.getUTCDay() === weekday ? result : void 0;
24176
+ const result2 = new Date(Date.UTC(year, monthIdx, day, hour, minute, second));
24177
+ return result2.getUTCDay() === weekday ? result2 : void 0;
24032
24178
  }
24033
24179
  module.exports = {
24034
24180
  parseHttpDate
@@ -24232,11 +24378,11 @@ var require_cache_handler = __commonJS({
24232
24378
  });
24233
24379
  }
24234
24380
  };
24235
- const result = this.#store.get(this.#cacheKey);
24236
- if (result && typeof result.then === "function") {
24237
- result.then(handle304);
24381
+ const result2 = this.#store.get(this.#cacheKey);
24382
+ if (result2 && typeof result2.then === "function") {
24383
+ result2.then(handle304);
24238
24384
  } else {
24239
- handle304(result);
24385
+ handle304(result2);
24240
24386
  }
24241
24387
  } else {
24242
24388
  if (typeof resHeaders.etag === "string" && isEtagUsable(resHeaders.etag)) {
@@ -24705,11 +24851,11 @@ var require_cache2 = __commonJS({
24705
24851
  }
24706
24852
  var nop = () => {
24707
24853
  };
24708
- function needsRevalidation(result, cacheControlDirectives, { headers = {} }) {
24854
+ function needsRevalidation(result2, cacheControlDirectives, { headers = {} }) {
24709
24855
  if (cacheControlDirectives?.["no-cache"]) {
24710
24856
  return true;
24711
24857
  }
24712
- if (result.cacheControlDirectives?.["no-cache"] && !Array.isArray(result.cacheControlDirectives["no-cache"])) {
24858
+ if (result2.cacheControlDirectives?.["no-cache"] && !Array.isArray(result2.cacheControlDirectives["no-cache"])) {
24713
24859
  return true;
24714
24860
  }
24715
24861
  if (headers["if-modified-since"] || headers["if-none-match"]) {
@@ -24717,29 +24863,29 @@ var require_cache2 = __commonJS({
24717
24863
  }
24718
24864
  return false;
24719
24865
  }
24720
- function isStale(result, cacheControlDirectives) {
24866
+ function isStale(result2, cacheControlDirectives) {
24721
24867
  const now = Date.now();
24722
- if (now > result.staleAt) {
24868
+ if (now > result2.staleAt) {
24723
24869
  if (cacheControlDirectives?.["max-stale"]) {
24724
- const gracePeriod = result.staleAt + cacheControlDirectives["max-stale"] * 1e3;
24870
+ const gracePeriod = result2.staleAt + cacheControlDirectives["max-stale"] * 1e3;
24725
24871
  return now > gracePeriod;
24726
24872
  }
24727
24873
  return true;
24728
24874
  }
24729
24875
  if (cacheControlDirectives?.["min-fresh"]) {
24730
- const timeLeftTillStale = result.staleAt - now;
24876
+ const timeLeftTillStale = result2.staleAt - now;
24731
24877
  const threshold = cacheControlDirectives["min-fresh"] * 1e3;
24732
24878
  return timeLeftTillStale <= threshold;
24733
24879
  }
24734
24880
  return false;
24735
24881
  }
24736
- function withinStaleWhileRevalidateWindow(result) {
24737
- const staleWhileRevalidate = result.cacheControlDirectives?.["stale-while-revalidate"];
24882
+ function withinStaleWhileRevalidateWindow(result2) {
24883
+ const staleWhileRevalidate = result2.cacheControlDirectives?.["stale-while-revalidate"];
24738
24884
  if (!staleWhileRevalidate) {
24739
24885
  return false;
24740
24886
  }
24741
24887
  const now = Date.now();
24742
- const staleWhileRevalidateExpiry = result.staleAt + staleWhileRevalidate * 1e3;
24888
+ const staleWhileRevalidateExpiry = result2.staleAt + staleWhileRevalidate * 1e3;
24743
24889
  return now <= staleWhileRevalidateExpiry;
24744
24890
  }
24745
24891
  function handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl) {
@@ -24772,8 +24918,8 @@ var require_cache2 = __commonJS({
24772
24918
  }
24773
24919
  return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler));
24774
24920
  }
24775
- function sendCachedValue(handler, opts, result, age, context, isStale2) {
24776
- const stream = util2.isStream(result.body) ? result.body : Readable3.from(result.body ?? []);
24921
+ function sendCachedValue(handler, opts, result2, age, context, isStale2) {
24922
+ const stream = util2.isStream(result2.body) ? result2.body : Readable3.from(result2.body ?? []);
24777
24923
  assert2(!stream.destroyed, "stream should not be destroyed");
24778
24924
  assert2(!stream.readableDidRead, "stream should not be readableDidRead");
24779
24925
  const controller = {
@@ -24813,11 +24959,11 @@ var require_cache2 = __commonJS({
24813
24959
  if (stream.destroyed) {
24814
24960
  return;
24815
24961
  }
24816
- const headers = { ...result.headers, age: String(age) };
24962
+ const headers = { ...result2.headers, age: String(age) };
24817
24963
  if (isStale2) {
24818
24964
  headers.warning = '110 - "response is stale"';
24819
24965
  }
24820
- handler.onResponseStart?.(controller, result.statusCode, headers, result.statusMessage);
24966
+ handler.onResponseStart?.(controller, result2.statusCode, headers, result2.statusMessage);
24821
24967
  if (opts.method === "HEAD") {
24822
24968
  stream.destroy();
24823
24969
  } else {
@@ -24826,38 +24972,38 @@ var require_cache2 = __commonJS({
24826
24972
  });
24827
24973
  }
24828
24974
  }
24829
- function handleResult2(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl, result) {
24830
- if (!result) {
24975
+ function handleResult2(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl, result2) {
24976
+ if (!result2) {
24831
24977
  return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl);
24832
24978
  }
24833
24979
  const now = Date.now();
24834
- if (now > result.deleteAt) {
24980
+ if (now > result2.deleteAt) {
24835
24981
  return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler));
24836
24982
  }
24837
- const age = Math.round((now - result.cachedAt) / 1e3);
24983
+ const age = Math.round((now - result2.cachedAt) / 1e3);
24838
24984
  if (reqCacheControl?.["max-age"] && age >= reqCacheControl["max-age"]) {
24839
24985
  return dispatch(opts, handler);
24840
24986
  }
24841
- const stale = isStale(result, reqCacheControl);
24842
- const revalidate = needsRevalidation(result, reqCacheControl, opts);
24987
+ const stale = isStale(result2, reqCacheControl);
24988
+ const revalidate = needsRevalidation(result2, reqCacheControl, opts);
24843
24989
  if (stale || revalidate) {
24844
24990
  if (util2.isStream(opts.body) && util2.bodyLength(opts.body) !== 0) {
24845
24991
  return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler));
24846
24992
  }
24847
- if (!revalidate && withinStaleWhileRevalidateWindow(result)) {
24848
- sendCachedValue(handler, opts, result, age, null, true);
24993
+ if (!revalidate && withinStaleWhileRevalidateWindow(result2)) {
24994
+ sendCachedValue(handler, opts, result2, age, null, true);
24849
24995
  queueMicrotask(() => {
24850
24996
  const headers2 = {
24851
24997
  ...opts.headers,
24852
- "if-modified-since": new Date(result.cachedAt).toUTCString()
24998
+ "if-modified-since": new Date(result2.cachedAt).toUTCString()
24853
24999
  };
24854
- if (result.etag) {
24855
- headers2["if-none-match"] = result.etag;
25000
+ if (result2.etag) {
25001
+ headers2["if-none-match"] = result2.etag;
24856
25002
  }
24857
- if (result.vary) {
24858
- for (const key in result.vary) {
24859
- if (result.vary[key] != null) {
24860
- headers2[key] = result.vary[key];
25003
+ if (result2.vary) {
25004
+ for (const key in result2.vary) {
25005
+ if (result2.vary[key] != null) {
25006
+ headers2[key] = result2.vary[key];
24861
25007
  }
24862
25008
  }
24863
25009
  }
@@ -24886,21 +25032,21 @@ var require_cache2 = __commonJS({
24886
25032
  return true;
24887
25033
  }
24888
25034
  let withinStaleIfErrorThreshold = false;
24889
- const staleIfErrorExpiry = result.cacheControlDirectives["stale-if-error"] ?? reqCacheControl?.["stale-if-error"];
25035
+ const staleIfErrorExpiry = result2.cacheControlDirectives["stale-if-error"] ?? reqCacheControl?.["stale-if-error"];
24890
25036
  if (staleIfErrorExpiry) {
24891
- withinStaleIfErrorThreshold = now < result.staleAt + staleIfErrorExpiry * 1e3;
25037
+ withinStaleIfErrorThreshold = now < result2.staleAt + staleIfErrorExpiry * 1e3;
24892
25038
  }
24893
25039
  const headers = {
24894
25040
  ...opts.headers,
24895
- "if-modified-since": new Date(result.cachedAt).toUTCString()
25041
+ "if-modified-since": new Date(result2.cachedAt).toUTCString()
24896
25042
  };
24897
- if (result.etag) {
24898
- headers["if-none-match"] = result.etag;
25043
+ if (result2.etag) {
25044
+ headers["if-none-match"] = result2.etag;
24899
25045
  }
24900
- if (result.vary) {
24901
- for (const key in result.vary) {
24902
- if (result.vary[key] != null) {
24903
- headers[key] = result.vary[key];
25046
+ if (result2.vary) {
25047
+ for (const key in result2.vary) {
25048
+ if (result2.vary[key] != null) {
25049
+ headers[key] = result2.vary[key];
24904
25050
  }
24905
25051
  }
24906
25052
  }
@@ -24912,9 +25058,9 @@ var require_cache2 = __commonJS({
24912
25058
  new CacheRevalidationHandler(
24913
25059
  (success, context) => {
24914
25060
  if (success) {
24915
- sendCachedValue(handler, opts, result, age, context, stale);
24916
- } else if (util2.isStream(result.body)) {
24917
- result.body.on("error", nop).destroy();
25061
+ sendCachedValue(handler, opts, result2, age, context, stale);
25062
+ } else if (util2.isStream(result2.body)) {
25063
+ result2.body.on("error", nop).destroy();
24918
25064
  }
24919
25065
  },
24920
25066
  new CacheHandler(globalOpts, cacheKey, handler),
@@ -24925,7 +25071,7 @@ var require_cache2 = __commonJS({
24925
25071
  if (util2.isStream(opts.body)) {
24926
25072
  opts.body.on("error", nop).destroy();
24927
25073
  }
24928
- sendCachedValue(handler, opts, result, age, null, false);
25074
+ sendCachedValue(handler, opts, result2, age, null, false);
24929
25075
  }
24930
25076
  module.exports = (opts = {}) => {
24931
25077
  const {
@@ -24987,16 +25133,16 @@ var require_cache2 = __commonJS({
24987
25133
  return dispatch(opts2, handler);
24988
25134
  }
24989
25135
  const cacheKey = makeCacheKey(opts2);
24990
- const result = store2.get(cacheKey);
24991
- if (result && typeof result.then === "function") {
24992
- return result.then((result2) => handleResult2(
25136
+ const result2 = store2.get(cacheKey);
25137
+ if (result2 && typeof result2.then === "function") {
25138
+ return result2.then((result3) => handleResult2(
24993
25139
  dispatch,
24994
25140
  globalOpts,
24995
25141
  cacheKey,
24996
25142
  handler,
24997
25143
  opts2,
24998
25144
  reqCacheControl,
24999
- result2
25145
+ result3
25000
25146
  ));
25001
25147
  } else {
25002
25148
  return handleResult2(
@@ -25006,7 +25152,7 @@ var require_cache2 = __commonJS({
25006
25152
  handler,
25007
25153
  opts2,
25008
25154
  reqCacheControl,
25009
- result
25155
+ result2
25010
25156
  );
25011
25157
  }
25012
25158
  };
@@ -25099,8 +25245,8 @@ var require_decompress = __commonJS({
25099
25245
  decompressor.on("readable", () => {
25100
25246
  let chunk;
25101
25247
  while ((chunk = decompressor.read()) !== null) {
25102
- const result = super.onResponseData(controller, chunk);
25103
- if (result === false) {
25248
+ const result2 = super.onResponseData(controller, chunk);
25249
+ if (result2 === false) {
25104
25250
  break;
25105
25251
  }
25106
25252
  }
@@ -27720,12 +27866,12 @@ var require_subresource_integrity = __commonJS({
27720
27866
  return false;
27721
27867
  };
27722
27868
  function getStrongestMetadata(metadataList) {
27723
- const result = [];
27869
+ const result2 = [];
27724
27870
  let strongest = null;
27725
27871
  for (const item of metadataList) {
27726
27872
  assert2(isValidSRIHashAlgorithm(item.alg), "Invalid SRI hash algorithm token");
27727
- if (result.length === 0) {
27728
- result.push(item);
27873
+ if (result2.length === 0) {
27874
+ result2.push(item);
27729
27875
  strongest = item;
27730
27876
  continue;
27731
27877
  }
@@ -27740,16 +27886,16 @@ var require_subresource_integrity = __commonJS({
27740
27886
  continue;
27741
27887
  } else if (newAlgorithmIndex > currentAlgorithmIndex) {
27742
27888
  strongest = item;
27743
- result[0] = item;
27744
- result.length = 1;
27889
+ result2[0] = item;
27890
+ result2.length = 1;
27745
27891
  } else {
27746
- result.push(item);
27892
+ result2.push(item);
27747
27893
  }
27748
27894
  }
27749
- return result;
27895
+ return result2;
27750
27896
  }
27751
27897
  function parseMetadata(metadata) {
27752
- const result = [];
27898
+ const result2 = [];
27753
27899
  for (const item of metadata.split(" ")) {
27754
27900
  const expressionAndOptions = item.split("?", 1);
27755
27901
  const algorithmExpression = expressionAndOptions[0];
@@ -27766,9 +27912,9 @@ var require_subresource_integrity = __commonJS({
27766
27912
  alg: algorithm,
27767
27913
  val: base64Value
27768
27914
  };
27769
- result.push(metadata2);
27915
+ result2.push(metadata2);
27770
27916
  }
27771
- return result;
27917
+ return result2;
27772
27918
  }
27773
27919
  var applyAlgorithmToBytes = (algorithm, bytes) => {
27774
27920
  return crypto3.hash(algorithm, bytes, "base64");
@@ -31717,10 +31863,10 @@ var require_websocket = __commonJS({
31717
31863
  const wasClean = this.#handler.closeState.has(sentCloseFrameState.SENT) && this.#handler.closeState.has(sentCloseFrameState.RECEIVED);
31718
31864
  let code = 1005;
31719
31865
  let reason = "";
31720
- const result = this.#parser?.closingInfo;
31721
- if (result && !result.error) {
31722
- code = result.code ?? 1005;
31723
- reason = result.reason;
31866
+ const result2 = this.#parser?.closingInfo;
31867
+ if (result2 && !result2.error) {
31868
+ code = result2.code ?? 1005;
31869
+ reason = result2.reason;
31724
31870
  }
31725
31871
  this.#handler.readyState = states.CLOSED;
31726
31872
  if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
@@ -32157,12 +32303,12 @@ var require_websocketstream = __commonJS({
32157
32303
  if (!this.#handler.wasEverConnected) {
32158
32304
  this.#openedPromise.reject(new WebSocketError("Socket never opened"));
32159
32305
  }
32160
- const result = this.#parser?.closingInfo;
32161
- let code = result?.code ?? 1005;
32306
+ const result2 = this.#parser?.closingInfo;
32307
+ let code = result2?.code ?? 1005;
32162
32308
  if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
32163
32309
  code = 1006;
32164
32310
  }
32165
- const reason = result?.reason == null ? "" : utf8DecodeBytes(Buffer.from(result.reason));
32311
+ const reason = result2?.reason == null ? "" : utf8DecodeBytes(Buffer.from(result2.reason));
32166
32312
  if (wasClean) {
32167
32313
  this.#readableStreamController.close();
32168
32314
  if (!this.#writableStream.locked) {
@@ -33007,10 +33153,11 @@ function expBackoff(attempt) {
33007
33153
  const i = Math.min(Math.max(attempt, 0), BACKOFF_MS.length - 1);
33008
33154
  return BACKOFF_MS[i];
33009
33155
  }
33010
- var BACKOFF_MS, BACKSTOP_SCAN_MS;
33156
+ var INGEST_BATCH_MAX_EVENTS, BACKOFF_MS, BACKSTOP_SCAN_MS;
33011
33157
  var init_config = __esm({
33012
33158
  "../../packages/companion-core/src/config/index.ts"() {
33013
33159
  "use strict";
33160
+ INGEST_BATCH_MAX_EVENTS = 1e3;
33014
33161
  BACKOFF_MS = [1e3, 2500, 5e3, 1e4, 2e4, 6e4];
33015
33162
  BACKSTOP_SCAN_MS = 5 * 6e4;
33016
33163
  }
@@ -33133,7 +33280,7 @@ var init_http = __esm({
33133
33280
  },
33134
33281
  // wellFormedStringify, not JSON.stringify: a truncated-emoji
33135
33282
  // lone surrogate in any excerpt 400s the whole batch on the
33136
- // serde_json side. See the helper's doc comment.
33283
+ // ingest server's strict JSON decoder. See the helper's doc comment.
33137
33284
  body: wellFormedStringify(batch)
33138
33285
  });
33139
33286
  } catch (err) {
@@ -33286,8 +33433,8 @@ var require_main = __commonJS({
33286
33433
  options = options || {};
33287
33434
  const vaultPath = _vaultPath(options);
33288
33435
  options.path = vaultPath;
33289
- const result = DotenvModule.configDotenv(options);
33290
- if (!result.parsed) {
33436
+ const result2 = DotenvModule.configDotenv(options);
33437
+ if (!result2.parsed) {
33291
33438
  const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
33292
33439
  err.code = "MISSING_DATA";
33293
33440
  throw err;
@@ -33298,7 +33445,7 @@ var require_main = __commonJS({
33298
33445
  for (let i = 0; i < length; i++) {
33299
33446
  try {
33300
33447
  const key = keys[i].trim();
33301
- const attrs = _instructions(result, key);
33448
+ const attrs = _instructions(result2, key);
33302
33449
  decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
33303
33450
  break;
33304
33451
  } catch (error) {
@@ -33327,7 +33474,7 @@ var require_main = __commonJS({
33327
33474
  }
33328
33475
  return "";
33329
33476
  }
33330
- function _instructions(result, dotenvKey) {
33477
+ function _instructions(result2, dotenvKey) {
33331
33478
  let uri;
33332
33479
  try {
33333
33480
  uri = new URL(dotenvKey);
@@ -33352,7 +33499,7 @@ var require_main = __commonJS({
33352
33499
  throw err;
33353
33500
  }
33354
33501
  const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
33355
- const ciphertext = result.parsed[environmentKey];
33502
+ const ciphertext = result2.parsed[environmentKey];
33356
33503
  if (!ciphertext) {
33357
33504
  const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
33358
33505
  err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
@@ -34240,14 +34387,14 @@ var init_temp = __esm({
34240
34387
  }
34241
34388
  },
34242
34389
  truncate: (filePath) => {
34243
- const basename4 = path2.basename(filePath);
34244
- if (basename4.length <= LIMIT_BASENAME_LENGTH)
34390
+ const basename5 = path2.basename(filePath);
34391
+ if (basename5.length <= LIMIT_BASENAME_LENGTH)
34245
34392
  return filePath;
34246
- const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename4);
34393
+ const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename5);
34247
34394
  if (!truncable)
34248
34395
  return filePath;
34249
- const truncationLength = basename4.length - LIMIT_BASENAME_LENGTH;
34250
- return `${filePath.slice(0, -basename4.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
34396
+ const truncationLength = basename5.length - LIMIT_BASENAME_LENGTH;
34397
+ return `${filePath.slice(0, -basename5.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
34251
34398
  }
34252
34399
  };
34253
34400
  node_default(Temp.purgeSyncAll);
@@ -36239,10 +36386,10 @@ var require_keyword = __commonJS({
36239
36386
  if (def.async && !schemaEnv.$async)
36240
36387
  throw new Error("async keyword in sync schema");
36241
36388
  }
36242
- function useKeyword(gen, keyword, result) {
36243
- if (result === void 0)
36389
+ function useKeyword(gen, keyword, result2) {
36390
+ if (result2 === void 0)
36244
36391
  throw new Error(`keyword "${keyword}" failed to compile`);
36245
- return gen.scopeValue("keyword", typeof result == "function" ? { ref: result } : { ref: result, code: (0, codegen_1.stringify)(result) });
36392
+ return gen.scopeValue("keyword", typeof result2 == "function" ? { ref: result2 } : { ref: result2, code: (0, codegen_1.stringify)(result2) });
36246
36393
  }
36247
36394
  function validSchemaType(schema, schemaType, allowUndefined = false) {
36248
36395
  return !schemaType.length || schemaType.some((st) => st === "array" ? Array.isArray(schema) : st === "object" ? schema && typeof schema == "object" && !Array.isArray(schema) : typeof schema == st || allowUndefined && typeof schema == "undefined");
@@ -42016,7 +42163,7 @@ var init_debounce_fn = __esm({
42016
42163
  }
42017
42164
  let timeout;
42018
42165
  let maxTimeout;
42019
- let result;
42166
+ let result2;
42020
42167
  const debouncedFunction = function(...arguments_) {
42021
42168
  const context = this;
42022
42169
  const later = () => {
@@ -42026,7 +42173,7 @@ var init_debounce_fn = __esm({
42026
42173
  maxTimeout = void 0;
42027
42174
  }
42028
42175
  if (after) {
42029
- result = inputFunction.apply(context, arguments_);
42176
+ result2 = inputFunction.apply(context, arguments_);
42030
42177
  }
42031
42178
  };
42032
42179
  const maxLater = () => {
@@ -42036,7 +42183,7 @@ var init_debounce_fn = __esm({
42036
42183
  timeout = void 0;
42037
42184
  }
42038
42185
  if (after) {
42039
- result = inputFunction.apply(context, arguments_);
42186
+ result2 = inputFunction.apply(context, arguments_);
42040
42187
  }
42041
42188
  };
42042
42189
  const shouldCallNow = before && !timeout;
@@ -42046,9 +42193,9 @@ var init_debounce_fn = __esm({
42046
42193
  maxTimeout = setTimeout(maxLater, maxWait);
42047
42194
  }
42048
42195
  if (shouldCallNow) {
42049
- result = inputFunction.apply(context, arguments_);
42196
+ result2 = inputFunction.apply(context, arguments_);
42050
42197
  }
42051
- return result;
42198
+ return result2;
42052
42199
  };
42053
42200
  mimicFunction(debouncedFunction, inputFunction);
42054
42201
  debouncedFunction.cancel = () => {
@@ -43042,9 +43189,9 @@ var require_range = __commonJS({
43042
43189
  if (rangeMap.size > 1 && rangeMap.has("")) {
43043
43190
  rangeMap.delete("");
43044
43191
  }
43045
- const result = [...rangeMap.values()];
43046
- cache.set(memoKey, result);
43047
- return result;
43192
+ const result2 = [...rangeMap.values()];
43193
+ cache.set(memoKey, result2);
43194
+ return result2;
43048
43195
  }
43049
43196
  intersects(range, options) {
43050
43197
  if (!(range instanceof _Range)) {
@@ -43098,16 +43245,16 @@ var require_range = __commonJS({
43098
43245
  var isNullSet = (c) => c.value === "<0.0.0-0";
43099
43246
  var isAny = (c) => c.value === "";
43100
43247
  var isSatisfiable = (comparators, options) => {
43101
- let result = true;
43248
+ let result2 = true;
43102
43249
  const remainingComparators = comparators.slice();
43103
43250
  let testComparator = remainingComparators.pop();
43104
- while (result && remainingComparators.length) {
43105
- result = remainingComparators.every((otherComparator) => {
43251
+ while (result2 && remainingComparators.length) {
43252
+ result2 = remainingComparators.every((otherComparator) => {
43106
43253
  return testComparator.intersects(otherComparator, options);
43107
43254
  });
43108
43255
  testComparator = remainingComparators.pop();
43109
43256
  }
43110
- return result;
43257
+ return result2;
43111
43258
  };
43112
43259
  var parseComparator = (comp, options) => {
43113
43260
  comp = comp.replace(re[t.BUILD], "");
@@ -44886,15 +45033,15 @@ function ingestClient() {
44886
45033
  return _ingest;
44887
45034
  }
44888
45035
  async function uploadBatch(batch) {
44889
- const result = await ingestClient().upload(batch);
44890
- if (result.kind !== "commit") {
44891
- throw new Error(`upload failed: ${result.reason}`);
45036
+ const result2 = await ingestClient().upload(batch);
45037
+ if (result2.kind !== "commit") {
45038
+ throw new Error(`upload failed: ${result2.reason}`);
44892
45039
  }
44893
45040
  return {
44894
- accepted: result.response.accepted,
44895
- new_sessions: result.response.new_sessions,
44896
- updated_sessions: result.response.updated_sessions,
44897
- batch_id: result.response.batch_id
45041
+ accepted: result2.response.accepted,
45042
+ new_sessions: result2.response.new_sessions,
45043
+ updated_sessions: result2.response.updated_sessions,
45044
+ batch_id: result2.response.batch_id
44898
45045
  };
44899
45046
  }
44900
45047
  var import_undici, DeviceMeUnauthorized, _ingest;
@@ -45237,6 +45384,38 @@ var init_title = __esm({
45237
45384
  }
45238
45385
  });
45239
45386
 
45387
+ // ../../packages/companion-core/src/pipeline/script-summary.ts
45388
+ function buildScriptSummaryUserPrompt(input) {
45389
+ const body = input.content.slice(0, SCRIPT_SUMMARY_INPUT_MAX_CHARS);
45390
+ return [
45391
+ `Script reference: ${input.ref}`,
45392
+ "Contents:",
45393
+ "```",
45394
+ body,
45395
+ "```",
45396
+ "",
45397
+ "One sentence (\u2264200 chars): what does running this script do?"
45398
+ ].join("\n");
45399
+ }
45400
+ var SCRIPT_SUMMARY_OUTPUT_MAX_CHARS, SCRIPT_SUMMARY_TEMPERATURE, SCRIPT_SUMMARY_MAX_TOKENS, SCRIPT_SUMMARY_INPUT_MAX_CHARS, SCRIPT_SUMMARY_SYSTEM_PROMPT;
45401
+ var init_script_summary = __esm({
45402
+ "../../packages/companion-core/src/pipeline/script-summary.ts"() {
45403
+ "use strict";
45404
+ SCRIPT_SUMMARY_OUTPUT_MAX_CHARS = 200;
45405
+ SCRIPT_SUMMARY_TEMPERATURE = 0.2;
45406
+ SCRIPT_SUMMARY_MAX_TOKENS = 120;
45407
+ SCRIPT_SUMMARY_INPUT_MAX_CHARS = 6e3;
45408
+ SCRIPT_SUMMARY_SYSTEM_PROMPT = `You summarise what a script file does, for an engineer scanning a dashboard.
45409
+
45410
+ Rules:
45411
+ - Output ONE plain sentence (at most 200 characters) stating what the script DOES when it runs.
45412
+ - Be concrete and factual: the actions it performs and the systems it touches.
45413
+ - No preamble ("This script\u2026"), no markdown, no quotes, no line breaks.
45414
+ - Do not invent behaviour that is not in the file. If the file is trivial or unreadable, say so briefly.
45415
+ - Never include secrets, tokens, passwords, or personal data, even if they appear in the file.`;
45416
+ }
45417
+ });
45418
+
45240
45419
  // ../../packages/companion-core/src/pipeline/index.ts
45241
45420
  async function buildSegmentsForSession(events, adapters2, onProgress) {
45242
45421
  if (events.length === 0) return [];
@@ -45549,6 +45728,7 @@ var init_pipeline = __esm({
45549
45728
  init_cognition();
45550
45729
  init_prompts();
45551
45730
  init_title();
45731
+ init_script_summary();
45552
45732
  SEGMENT_TIME_GAP_MS = 15 * 6e4;
45553
45733
  SEGMENT_TOPIC_THRESHOLD = 0.35;
45554
45734
  SEGMENT_MAX_TURNS = 100;
@@ -45806,8 +45986,8 @@ var init_ollama = __esm({
45806
45986
  });
45807
45987
 
45808
45988
  // ../../packages/companion-core/src/node/llama.ts
45809
- import { mkdir } from "fs/promises";
45810
45989
  import { existsSync as existsSync7 } from "fs";
45990
+ import { mkdir } from "fs/promises";
45811
45991
  import { homedir as homedir5 } from "os";
45812
45992
  import { dirname as dirname5, join as join5 } from "path";
45813
45993
  function defaultLlamaConfig() {
@@ -45839,23 +46019,17 @@ async function ensureLlamaModel(cfg = defaultLlamaConfig()) {
45839
46019
  await mkdir(dirname5(cfg.modelPath), { recursive: true });
45840
46020
  const res = await fetch(cfg.modelUrl);
45841
46021
  if (!res.ok || !res.body) {
45842
- throw new Error(
45843
- `model download failed: ${res.status} ${res.statusText} (${cfg.modelUrl})`
45844
- );
46022
+ throw new Error(`model download failed: ${res.status} ${res.statusText} (${cfg.modelUrl})`);
45845
46023
  }
45846
46024
  const total = Number(res.headers.get("content-length") ?? 0);
45847
46025
  const totalMb = total > 0 ? (total / (1024 * 1024)).toFixed(0) : "?";
45848
- console.log(
45849
- `[modelstat] downloading summariser model (~${totalMb} MB) \u2192 ${cfg.modelPath}`
45850
- );
46026
+ console.log(`[modelstat] downloading summariser model (~${totalMb} MB) \u2192 ${cfg.modelPath}`);
45851
46027
  const tmp = `${cfg.modelPath}.partial`;
45852
46028
  const { createWriteStream: createWriteStream2 } = await import("fs");
45853
46029
  const { Readable: Readable3 } = await import("stream");
45854
- const { rename } = await import("fs/promises");
46030
+ const { rename: rename2 } = await import("fs/promises");
45855
46031
  const out = createWriteStream2(tmp);
45856
- const isTty = Boolean(
45857
- process.stdout.isTTY
45858
- );
46032
+ const isTty = Boolean(process.stdout.isTTY);
45859
46033
  let received = 0;
45860
46034
  let lastLog = 0;
45861
46035
  let lastBytes = 0;
@@ -45899,7 +46073,7 @@ async function ensureLlamaModel(cfg = defaultLlamaConfig()) {
45899
46073
  });
45900
46074
  renderProgress(true);
45901
46075
  if (isTty) process.stdout.write("\n");
45902
- await rename(tmp, cfg.modelPath);
46076
+ await rename2(tmp, cfg.modelPath);
45903
46077
  console.log(`[modelstat] summariser model ready (${cfg.modelPath})`);
45904
46078
  return cfg.modelPath;
45905
46079
  }
@@ -45920,6 +46094,9 @@ async function loadOnce(cfg) {
45920
46094
  const entitlerContext = await model.createContext({
45921
46095
  contextSize: cfg.contextSize
45922
46096
  });
46097
+ const scriptContext = await model.createContext({
46098
+ contextSize: cfg.contextSize
46099
+ });
45923
46100
  const summarizer = new llamaMod.LlamaChatSession({
45924
46101
  contextSequence: summariserContext.getSequence(),
45925
46102
  systemPrompt: SUMMARISER_SYSTEM_PROMPT
@@ -45932,7 +46109,11 @@ async function loadOnce(cfg) {
45932
46109
  contextSequence: entitlerContext.getSequence(),
45933
46110
  systemPrompt: TITLER_SYSTEM_PROMPT
45934
46111
  });
45935
- loaded = { summarizer, cognizer, entitler };
46112
+ const scriptSummarizer2 = new llamaMod.LlamaChatSession({
46113
+ contextSequence: scriptContext.getSequence(),
46114
+ systemPrompt: SCRIPT_SUMMARY_SYSTEM_PROMPT
46115
+ });
46116
+ loaded = { summarizer, cognizer, entitler, scriptSummarizer: scriptSummarizer2 };
45936
46117
  return loaded;
45937
46118
  })();
45938
46119
  try {
@@ -46022,12 +46203,42 @@ function llamaEntitle(cfg = defaultLlamaConfig()) {
46022
46203
  }
46023
46204
  };
46024
46205
  }
46206
+ function llamaScriptSummarize(cfg = defaultLlamaConfig()) {
46207
+ return async ({ ref, content }) => {
46208
+ if (!content || content.trim().length === 0) return null;
46209
+ let loadedSessions;
46210
+ try {
46211
+ loadedSessions = await loadOnce(cfg);
46212
+ } catch {
46213
+ return null;
46214
+ }
46215
+ const { scriptSummarizer: scriptSummarizer2 } = loadedSessions;
46216
+ const run = inflight.then(async () => {
46217
+ scriptSummarizer2.resetChatHistory();
46218
+ const raw = await scriptSummarizer2.prompt(buildScriptSummaryUserPrompt({ ref, content }), {
46219
+ temperature: SCRIPT_SUMMARY_TEMPERATURE,
46220
+ // Qwen3.5 reasons before answering — give it room on top of the
46221
+ // one-sentence answer budget; the slice below enforces the cap.
46222
+ maxTokens: SCRIPT_SUMMARY_MAX_TOKENS + 400
46223
+ });
46224
+ const oneLine = stripThinking(raw ?? "").replace(/\s+/g, " ").trim();
46225
+ return oneLine ? oneLine.slice(0, SCRIPT_SUMMARY_OUTPUT_MAX_CHARS) : null;
46226
+ });
46227
+ inflight = run.catch(() => void 0);
46228
+ try {
46229
+ return await run;
46230
+ } catch {
46231
+ return null;
46232
+ }
46233
+ };
46234
+ }
46025
46235
  var DEFAULT_LLAMA_MODEL_URL, LLAMA_MAX_TOKENS, loaded, loadPromise, inflight;
46026
46236
  var init_llama = __esm({
46027
46237
  "../../packages/companion-core/src/node/llama.ts"() {
46028
46238
  "use strict";
46029
- init_prompts();
46030
46239
  init_cognition();
46240
+ init_prompts();
46241
+ init_script_summary();
46031
46242
  init_title();
46032
46243
  DEFAULT_LLAMA_MODEL_URL = "https://huggingface.co/lmstudio-community/Qwen3.5-4B-GGUF/resolve/main/Qwen3.5-4B-Q4_K_M.gguf";
46033
46244
  LLAMA_MAX_TOKENS = 1024;
@@ -46135,6 +46346,7 @@ __export(node_exports, {
46135
46346
  ensureLlamaModel: () => ensureLlamaModel,
46136
46347
  llamaCognize: () => llamaCognize,
46137
46348
  llamaEntitle: () => llamaEntitle,
46349
+ llamaScriptSummarize: () => llamaScriptSummarize,
46138
46350
  llamaSummarize: () => llamaSummarize,
46139
46351
  ollamaCognize: () => ollamaCognize,
46140
46352
  ollamaEmbed: () => ollamaEmbed,
@@ -46264,22 +46476,92 @@ var init_privacy_filter = __esm({
46264
46476
  }
46265
46477
  });
46266
46478
 
46479
+ // src/enrich-scripts.ts
46480
+ function defaultRoots(cwd) {
46481
+ if (!cwd) return [];
46482
+ const seg = cwd.replace(/\/+$/, "").split("/");
46483
+ const ancestors = [];
46484
+ for (let i = seg.length; i >= Math.max(1, seg.length - 3); i--) {
46485
+ ancestors.push(seg.slice(0, i).join("/") || "/");
46486
+ }
46487
+ const subdirs = ["scripts", "bin", "tools", "ci", ".github/scripts"];
46488
+ const roots = [...ancestors];
46489
+ for (const a of ancestors) for (const s of subdirs) roots.push(`${a}/${s}`);
46490
+ return roots;
46491
+ }
46492
+ async function enrichToolCallScripts(drafts, contexts, deps) {
46493
+ if (contexts.length === 0) return;
46494
+ const ctxById = new Map(contexts.map((c) => [c.external_call_id, c]));
46495
+ for (const draft of drafts) {
46496
+ if (!draft.action) continue;
46497
+ const ctx = ctxById.get(draft.external_call_id);
46498
+ if (!ctx) continue;
46499
+ try {
46500
+ await enrichOneAction(draft.action, ctx, deps);
46501
+ } catch {
46502
+ }
46503
+ }
46504
+ }
46505
+ async function enrichOneAction(action, ctx, deps) {
46506
+ const redactedCommand = action.command_redacted;
46507
+ if (!redactedCommand) return;
46508
+ const refs = detectScriptRefs(ctx.command);
46509
+ if (refs.length === 0) return;
46510
+ const roots = (deps.roots ?? defaultRoots)(ctx.cwd);
46511
+ const seen = /* @__PURE__ */ new Set();
46512
+ const out = [];
46513
+ for (const ref of refs) {
46514
+ if (out.length >= MAX_SCRIPTS_PER_CALL) break;
46515
+ const token = redact(ref, ctx.cwd ?? void 0).text.trim();
46516
+ if (!token || token.startsWith("[REDACTED") || seen.has(token)) continue;
46517
+ if (!redactedCommand.includes(token)) continue;
46518
+ const path5 = resolveScriptPath(ref, roots, deps.exists);
46519
+ if (!path5) continue;
46520
+ let content;
46521
+ try {
46522
+ content = await deps.readFile(path5);
46523
+ } catch {
46524
+ continue;
46525
+ }
46526
+ if (!content.trim()) continue;
46527
+ const summaryRaw = await deps.summarize({ ref, content });
46528
+ if (!summaryRaw) continue;
46529
+ const summary = redact(summaryRaw).text.trim().slice(0, MAX_SUMMARY_CHARS);
46530
+ if (!summary) continue;
46531
+ seen.add(token);
46532
+ out.push({ token, summary });
46533
+ }
46534
+ if (out.length > 0) action.scripts = out;
46535
+ }
46536
+ var MAX_SCRIPTS_PER_CALL, MAX_SUMMARY_CHARS;
46537
+ var init_enrich_scripts = __esm({
46538
+ "src/enrich-scripts.ts"() {
46539
+ "use strict";
46540
+ init_src();
46541
+ init_src2();
46542
+ MAX_SCRIPTS_PER_CALL = 8;
46543
+ MAX_SUMMARY_CHARS = 200;
46544
+ }
46545
+ });
46546
+
46267
46547
  // src/pipeline.ts
46268
46548
  var pipeline_exports = {};
46269
46549
  __export(pipeline_exports, {
46270
46550
  buildSegments: () => buildSegments,
46271
46551
  buildSessionTitles: () => buildSessionTitles2,
46552
+ enrichScripts: () => enrichScripts,
46272
46553
  preflightSummariser: () => preflightSummariser
46273
46554
  });
46555
+ import { existsSync as existsSync8 } from "fs";
46556
+ import { readFile as fsReadFile } from "fs/promises";
46274
46557
  async function bundledAdapters() {
46275
46558
  const llamaCfg = defaultLlamaConfig();
46276
46559
  return {
46277
- // transformers.js BGE-small embedder — the same model the server
46278
- // uses, so segment vectors land in the same 384-dim space as
46279
- // leaf-description vectors and cosine similarity is directly
46280
- // meaningful. (This path used to ship vector-less with empty
46281
- // arrays; hooking embeddings here gives proper segment-vs-leaf
46282
- // matching at classify time.)
46560
+ // transformers.js BGE-small embedder — the wire embedding is
46561
+ // 384-dim (BGE-small), so segment vectors are directly comparable
46562
+ // across runtimes via cosine similarity. (This path used to ship
46563
+ // vector-less with empty arrays; hooking embeddings here attaches a
46564
+ // real abstract embedding to each segment.)
46283
46565
  embed: createTransformersJsEmbedder(),
46284
46566
  summarize: llamaSummarize(llamaCfg),
46285
46567
  tokenize: (text) => Math.max(1, Math.ceil(text.length / 4)),
@@ -46309,9 +46591,7 @@ async function getAdapters() {
46309
46591
  `modelstat agent can't start: the bundled summariser (node-llama-cpp) failed to load. Re-run \`modelstat connect\` (or \`npm i -g modelstat\`) so the native runtime is re-staged beside the bundle. Underlying error: ${err.message}`
46310
46592
  );
46311
46593
  }
46312
- console.log(
46313
- "[modelstat] using bundled local summariser (Qwen3.5-4B, runs on this machine)"
46314
- );
46594
+ console.log("[modelstat] using bundled local summariser (Qwen3.5-4B, runs on this machine)");
46315
46595
  adapters = await bundledAdapters();
46316
46596
  return adapters;
46317
46597
  }
@@ -46322,6 +46602,19 @@ async function buildSessionTitles2(segments) {
46322
46602
  const a = await getAdapters();
46323
46603
  return buildSessionTitles(segments, a.entitle);
46324
46604
  }
46605
+ async function enrichScripts(drafts, contexts = []) {
46606
+ if (contexts.length === 0 || drafts.length === 0) return;
46607
+ await getAdapters();
46608
+ if (!scriptSummarizer) scriptSummarizer = llamaScriptSummarize(defaultLlamaConfig());
46609
+ await enrichToolCallScripts(drafts, contexts, {
46610
+ summarize: scriptSummarizer,
46611
+ exists: existsSync8,
46612
+ readFile: async (path5) => {
46613
+ const buf = await fsReadFile(path5);
46614
+ return buf.subarray(0, MAX_SCRIPT_READ_BYTES).toString("utf8");
46615
+ }
46616
+ });
46617
+ }
46325
46618
  async function preflightSummariser() {
46326
46619
  const a = await getAdapters();
46327
46620
  const out = await a.summarize({
@@ -46335,14 +46628,17 @@ async function preflightSummariser() {
46335
46628
  }
46336
46629
  return out.length > 60 ? `${out.slice(0, 57)}\u2026` : out;
46337
46630
  }
46338
- var adapters;
46631
+ var adapters, MAX_SCRIPT_READ_BYTES, scriptSummarizer;
46339
46632
  var init_pipeline2 = __esm({
46340
46633
  "src/pipeline.ts"() {
46341
46634
  "use strict";
46342
- init_pipeline();
46343
46635
  init_node2();
46636
+ init_pipeline();
46344
46637
  init_privacy_filter();
46638
+ init_enrich_scripts();
46345
46639
  adapters = null;
46640
+ MAX_SCRIPT_READ_BYTES = 64 * 1024;
46641
+ scriptSummarizer = null;
46346
46642
  }
46347
46643
  });
46348
46644
 
@@ -46372,7 +46668,7 @@ async function scanAll(cb = {}) {
46372
46668
  path: full,
46373
46669
  parse: async (sink2) => {
46374
46670
  const r = await parseClaudeCodeJsonl({ deviceId, sourceFile: full, onEvents: sink2 });
46375
- return { toolCalls: r.toolCalls ?? [] };
46671
+ return { toolCalls: r.toolCalls ?? [], scriptContexts: r.scriptContexts ?? [] };
46376
46672
  }
46377
46673
  });
46378
46674
  }
@@ -46396,7 +46692,7 @@ async function scanAll(cb = {}) {
46396
46692
  path: full,
46397
46693
  parse: async (sink2) => {
46398
46694
  const r = await parseCodexRollout({ deviceId, sourceFile: full, onEvents: sink2 });
46399
- return { toolCalls: r.toolCalls ?? [] };
46695
+ return { toolCalls: r.toolCalls ?? [], scriptContexts: r.scriptContexts ?? [] };
46400
46696
  }
46401
46697
  });
46402
46698
  }
@@ -46489,6 +46785,14 @@ async function scanAll(cb = {}) {
46489
46785
  filesScanned += 1;
46490
46786
  try {
46491
46787
  const r = await job.parse(sink);
46788
+ try {
46789
+ await enrichScripts(r.toolCalls, r.scriptContexts ?? []);
46790
+ } catch (e) {
46791
+ console.warn(
46792
+ ` ! script-summary enrichment skipped for ${job.path}:`,
46793
+ e.message
46794
+ );
46795
+ }
46492
46796
  await bufferToolCalls(r.toolCalls);
46493
46797
  if (cs) pendingCursors.push({ path: job.path, cs });
46494
46798
  } catch (e) {
@@ -46503,13 +46807,14 @@ var init_scan = __esm({
46503
46807
  "src/scan.ts"() {
46504
46808
  "use strict";
46505
46809
  init_src3();
46810
+ init_config();
46506
46811
  init_queue();
46507
46812
  init_src2();
46508
46813
  init_api();
46509
46814
  init_config2();
46510
46815
  init_pipeline2();
46511
- AGENT_VERSION = true ? "agent-0.0.50" : "agent-dev";
46512
- BATCH_MAX_EVENTS = 2e3;
46816
+ AGENT_VERSION = true ? "agent-0.0.52" : "agent-dev";
46817
+ BATCH_MAX_EVENTS = INGEST_BATCH_MAX_EVENTS;
46513
46818
  BATCH_MAX_TOOL_CALLS = 2e4;
46514
46819
  BATCH_BUFFER_HARD_CAP = BATCH_MAX_EVENTS * 2;
46515
46820
  ZERO_TOKENS = {
@@ -46525,7 +46830,7 @@ var init_scan = __esm({
46525
46830
  // src/lock.ts
46526
46831
  import {
46527
46832
  closeSync,
46528
- existsSync as existsSync9,
46833
+ existsSync as existsSync10,
46529
46834
  mkdirSync as mkdirSync4,
46530
46835
  openSync,
46531
46836
  readFileSync as readFileSync5,
@@ -46725,6 +47030,250 @@ var init_processing_version = __esm({
46725
47030
  }
46726
47031
  });
46727
47032
 
47033
+ // ../../packages/remote-config/src/loader.ts
47034
+ function getFetch(env2) {
47035
+ return env2.fetch ?? fetch;
47036
+ }
47037
+ async function fetchConfig(kind, env2) {
47038
+ const url = `${env2.apiUrl.replace(/\/+$/, "")}/v1/config/${encodeURIComponent(kind.kind)}`;
47039
+ let body;
47040
+ try {
47041
+ const res = await getFetch(env2)(url);
47042
+ if (!res.ok) throw new Error(`status ${res.status}`);
47043
+ body = await res.json();
47044
+ } catch (e) {
47045
+ env2.logger?.warn?.(`[remote-config] ${kind.kind} fetch failed`, e);
47046
+ return null;
47047
+ }
47048
+ const parsed = kind.schema.safeParse(body);
47049
+ if (!parsed.success) {
47050
+ env2.logger?.warn?.(`[remote-config] ${kind.kind} payload schema invalid`);
47051
+ return null;
47052
+ }
47053
+ return { value: parsed.data, version: parsed.data.version };
47054
+ }
47055
+ async function readCachedConfig(kind, env2) {
47056
+ if (!env2.cache) return null;
47057
+ let raw;
47058
+ try {
47059
+ raw = await env2.cache.read(kind.kind);
47060
+ } catch (e) {
47061
+ env2.logger?.warn?.(`[remote-config] ${kind.kind} cache read failed`, e);
47062
+ return null;
47063
+ }
47064
+ if (raw == null) return null;
47065
+ const parsed = kind.schema.safeParse(raw);
47066
+ if (!parsed.success) {
47067
+ env2.logger?.warn?.(`[remote-config] ${kind.kind} disk cache rejected`);
47068
+ return null;
47069
+ }
47070
+ return { value: parsed.data, version: parsed.data.version };
47071
+ }
47072
+ async function writeCache(kind, env2, value) {
47073
+ if (!env2.cache) return;
47074
+ try {
47075
+ await env2.cache.write(kind.kind, value);
47076
+ } catch (e) {
47077
+ env2.logger?.warn?.(`[remote-config] ${kind.kind} cache write failed`, e);
47078
+ }
47079
+ }
47080
+ function result(kind, value, version, source) {
47081
+ return { kind, value, version, source };
47082
+ }
47083
+ var RemoteConfigStore;
47084
+ var init_loader = __esm({
47085
+ "../../packages/remote-config/src/loader.ts"() {
47086
+ "use strict";
47087
+ RemoteConfigStore = class {
47088
+ env;
47089
+ kinds;
47090
+ state = /* @__PURE__ */ new Map();
47091
+ constructor(env2, kinds) {
47092
+ this.env = env2;
47093
+ this.kinds = new Map(kinds.map((k) => [k.kind, k]));
47094
+ for (const k of kinds) {
47095
+ this.state.set(k.kind, {
47096
+ value: k.bundledFallback,
47097
+ version: k.bundledFallback.version,
47098
+ source: "bundled"
47099
+ });
47100
+ }
47101
+ }
47102
+ /** Seed from the disk cache without touching the network — the instant,
47103
+ * offline-safe startup path. Call once, then `refreshAll` in the
47104
+ * background. Anything not on disk (or rejected) stays on its fallback. */
47105
+ async initFromCache() {
47106
+ await Promise.all(
47107
+ [...this.kinds.values()].map(async (k) => {
47108
+ const cached2 = await readCachedConfig(k, this.env);
47109
+ const current = this.state.get(k.kind);
47110
+ if (cached2 && (!current || cached2.version >= current.version)) {
47111
+ this.state.set(k.kind, { value: cached2.value, version: cached2.version, source: "disk" });
47112
+ }
47113
+ })
47114
+ );
47115
+ }
47116
+ /** Fetch one kind, swapping it in only if strictly newer. Never throws
47117
+ * and never downgrades the held value on failure. */
47118
+ async refresh(kindName) {
47119
+ const kind = this.kinds.get(kindName);
47120
+ if (!kind) throw new Error(`unknown config kind: ${kindName}`);
47121
+ const current = this.state.get(kindName);
47122
+ const currentVersion = current?.version ?? kind.bundledFallback.version;
47123
+ const fetched = await fetchConfig(kind, this.env);
47124
+ if (!fetched) return;
47125
+ if (fetched.version <= currentVersion) return;
47126
+ await writeCache(kind, this.env, fetched.value);
47127
+ this.state.set(kindName, { value: fetched.value, version: fetched.version, source: "remote" });
47128
+ }
47129
+ async refreshAll() {
47130
+ await Promise.all([...this.kinds.keys()].map((k) => this.refresh(k)));
47131
+ }
47132
+ /** The current best value for a kind. Total — falls back to bundled. */
47133
+ get(kindName) {
47134
+ const entry = this.state.get(kindName);
47135
+ if (!entry) throw new Error(`unknown config kind: ${kindName}`);
47136
+ return entry.value;
47137
+ }
47138
+ /** Like `get`, but also reports the version + provenance. */
47139
+ getResult(kindName) {
47140
+ const entry = this.state.get(kindName);
47141
+ if (!entry) throw new Error(`unknown config kind: ${kindName}`);
47142
+ return result(kindName, entry.value, entry.version, entry.source);
47143
+ }
47144
+ };
47145
+ }
47146
+ });
47147
+
47148
+ // ../../packages/remote-config/src/schema.ts
47149
+ var VersionedConfig;
47150
+ var init_schema = __esm({
47151
+ "../../packages/remote-config/src/schema.ts"() {
47152
+ "use strict";
47153
+ init_zod();
47154
+ VersionedConfig = external_exports.object({
47155
+ version: external_exports.number().int().nonnegative()
47156
+ });
47157
+ }
47158
+ });
47159
+
47160
+ // ../../packages/remote-config/src/types.ts
47161
+ var init_types3 = __esm({
47162
+ "../../packages/remote-config/src/types.ts"() {
47163
+ "use strict";
47164
+ }
47165
+ });
47166
+
47167
+ // ../../packages/remote-config/src/index.ts
47168
+ var init_src4 = __esm({
47169
+ "../../packages/remote-config/src/index.ts"() {
47170
+ "use strict";
47171
+ init_loader();
47172
+ init_schema();
47173
+ init_types3();
47174
+ }
47175
+ });
47176
+
47177
+ // ../../packages/remote-config/src/node.ts
47178
+ import { chmod, mkdir as mkdir2, readFile, rename, writeFile } from "fs/promises";
47179
+ import { homedir as homedir10 } from "os";
47180
+ import { join as join10 } from "path";
47181
+ function defaultRoot() {
47182
+ return join10(homedir10(), ".modelstat", "config");
47183
+ }
47184
+ function safeKind(kind) {
47185
+ if (!/^[a-z0-9_-]{1,64}$/.test(kind)) throw new Error(`unsafe config kind: ${kind}`);
47186
+ return kind;
47187
+ }
47188
+ function createNodeDiskCache(opts = {}) {
47189
+ const dir = opts.dir ?? defaultRoot();
47190
+ async function writeAtomic2(path5, data) {
47191
+ const tmp = `${path5}.${process.pid}.tmp`;
47192
+ await writeFile(tmp, data, { mode: 384 });
47193
+ await rename(tmp, path5);
47194
+ try {
47195
+ await chmod(path5, 384);
47196
+ } catch {
47197
+ }
47198
+ }
47199
+ return {
47200
+ async read(kind) {
47201
+ const k = safeKind(kind);
47202
+ try {
47203
+ const raw = await readFile(join10(dir, `${k}.json`), "utf8");
47204
+ return JSON.parse(raw);
47205
+ } catch {
47206
+ return null;
47207
+ }
47208
+ },
47209
+ async write(kind, payload) {
47210
+ const k = safeKind(kind);
47211
+ await mkdir2(dir, { recursive: true, mode: 448 });
47212
+ await writeAtomic2(join10(dir, `${k}.json`), `${JSON.stringify(payload)}
47213
+ `);
47214
+ }
47215
+ };
47216
+ }
47217
+ var init_node3 = __esm({
47218
+ "../../packages/remote-config/src/node.ts"() {
47219
+ "use strict";
47220
+ }
47221
+ });
47222
+
47223
+ // ../../packages/companion-core/src/policies/index.ts
47224
+ var policies_exports = {};
47225
+ __export(policies_exports, {
47226
+ createPolicyRefresher: () => createPolicyRefresher
47227
+ });
47228
+ function createPolicyRefresher(opts) {
47229
+ const env2 = {
47230
+ apiUrl: opts.apiUrl,
47231
+ cache: createNodeDiskCache(opts.cacheDir ? { dir: opts.cacheDir } : {}),
47232
+ ...opts.fetch ? { fetch: opts.fetch } : {},
47233
+ ...opts.logger ? { logger: opts.logger } : {}
47234
+ };
47235
+ const store2 = new RemoteConfigStore(env2, [policiesKind]);
47236
+ let timer = null;
47237
+ const apply = () => {
47238
+ const bundle = store2.get("policies");
47239
+ setRemoteRedactionPatterns(compilePolicyPatterns(bundle));
47240
+ };
47241
+ const refresh = async () => {
47242
+ await store2.refresh("policies");
47243
+ apply();
47244
+ };
47245
+ return {
47246
+ async start() {
47247
+ await store2.initFromCache();
47248
+ apply();
47249
+ void refresh().catch(() => {
47250
+ });
47251
+ timer = setInterval(
47252
+ () => void refresh().catch(() => {
47253
+ }),
47254
+ opts.intervalMs ?? DEFAULT_REFRESH_MS
47255
+ );
47256
+ timer.unref?.();
47257
+ },
47258
+ refresh,
47259
+ stop() {
47260
+ if (timer) clearInterval(timer);
47261
+ timer = null;
47262
+ }
47263
+ };
47264
+ }
47265
+ var DEFAULT_REFRESH_MS, policiesKind;
47266
+ var init_policies2 = __esm({
47267
+ "../../packages/companion-core/src/policies/index.ts"() {
47268
+ "use strict";
47269
+ init_src();
47270
+ init_src4();
47271
+ init_node3();
47272
+ DEFAULT_REFRESH_MS = 15 * 60 * 1e3;
47273
+ policiesKind = POLICIES_CONFIG_KIND;
47274
+ }
47275
+ });
47276
+
46728
47277
  // ../../node_modules/.pnpm/readdirp@4.1.2/node_modules/readdirp/esm/index.js
46729
47278
  import { stat as stat3, lstat, readdir as readdir2, realpath } from "fs/promises";
46730
47279
  import { Readable as Readable2 } from "stream";
@@ -46892,10 +47441,10 @@ var init_esm = __esm({
46892
47441
  }
46893
47442
  async _formatEntry(dirent, path5) {
46894
47443
  let entry;
46895
- const basename4 = this._isDirent ? dirent.name : dirent;
47444
+ const basename5 = this._isDirent ? dirent.name : dirent;
46896
47445
  try {
46897
- const fullPath = presolve(pjoin(path5, basename4));
46898
- entry = { path: prelative(this._root, fullPath), fullPath, basename: basename4 };
47446
+ const fullPath = presolve(pjoin(path5, basename5));
47447
+ entry = { path: prelative(this._root, fullPath), fullPath, basename: basename5 };
46899
47448
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
46900
47449
  } catch (err) {
46901
47450
  this._onError(err);
@@ -47424,9 +47973,9 @@ var init_handler = __esm({
47424
47973
  _watchWithNodeFs(path5, listener) {
47425
47974
  const opts = this.fsw.options;
47426
47975
  const directory = sysPath.dirname(path5);
47427
- const basename4 = sysPath.basename(path5);
47976
+ const basename5 = sysPath.basename(path5);
47428
47977
  const parent = this.fsw._getWatchedDir(directory);
47429
- parent.add(basename4);
47978
+ parent.add(basename5);
47430
47979
  const absolutePath = sysPath.resolve(path5);
47431
47980
  const options = {
47432
47981
  persistent: opts.persistent
@@ -47436,7 +47985,7 @@ var init_handler = __esm({
47436
47985
  let closer;
47437
47986
  if (opts.usePolling) {
47438
47987
  const enableBin = opts.interval !== opts.binaryInterval;
47439
- options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
47988
+ options.interval = enableBin && isBinaryPath(basename5) ? opts.binaryInterval : opts.interval;
47440
47989
  closer = setFsWatchFileListener(path5, absolutePath, options, {
47441
47990
  listener,
47442
47991
  rawEmitter: this.fsw._emitRaw
@@ -47459,10 +48008,10 @@ var init_handler = __esm({
47459
48008
  return;
47460
48009
  }
47461
48010
  const dirname9 = sysPath.dirname(file);
47462
- const basename4 = sysPath.basename(file);
48011
+ const basename5 = sysPath.basename(file);
47463
48012
  const parent = this.fsw._getWatchedDir(dirname9);
47464
48013
  let prevStats = stats;
47465
- if (parent.has(basename4))
48014
+ if (parent.has(basename5))
47466
48015
  return;
47467
48016
  const listener = async (path5, newStats) => {
47468
48017
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
@@ -47487,9 +48036,9 @@ var init_handler = __esm({
47487
48036
  prevStats = newStats2;
47488
48037
  }
47489
48038
  } catch (error) {
47490
- this.fsw._remove(dirname9, basename4);
48039
+ this.fsw._remove(dirname9, basename5);
47491
48040
  }
47492
- } else if (parent.has(basename4)) {
48041
+ } else if (parent.has(basename5)) {
47493
48042
  const at = newStats.atimeMs;
47494
48043
  const mt = newStats.mtimeMs;
47495
48044
  if (!at || at <= mt || mt !== prevStats.mtimeMs) {
@@ -48453,7 +49002,7 @@ __export(daemon_exports, {
48453
49002
  setQueue: () => setQueue,
48454
49003
  setStat: () => setStat
48455
49004
  });
48456
- import { existsSync as existsSync10, statSync as statSync2 } from "fs";
49005
+ import { existsSync as existsSync11, statSync as statSync2 } from "fs";
48457
49006
  function setPhase(phase, message) {
48458
49007
  status.phase = phase;
48459
49008
  status.message = message ?? null;
@@ -48533,12 +49082,12 @@ async function sendHeartbeat() {
48533
49082
  writeLocalStatus(body).catch(() => void 0);
48534
49083
  }
48535
49084
  async function rotateRunawayLogs() {
48536
- const { homedir: homedir11 } = await import("os");
48537
- const { join: join13 } = await import("path");
48538
- const { open: open2, stat: stat6, truncate, writeFile } = await import("fs/promises");
48539
- const dir = join13(homedir11(), ".modelstat", "logs");
49085
+ const { homedir: homedir12 } = await import("os");
49086
+ const { join: join14 } = await import("path");
49087
+ const { open: open2, stat: stat6, truncate, writeFile: writeFile2 } = await import("fs/promises");
49088
+ const dir = join14(homedir12(), ".modelstat", "logs");
48540
49089
  for (const name of ["out.log", "err.log"]) {
48541
- const p = join13(dir, name);
49090
+ const p = join14(dir, name);
48542
49091
  try {
48543
49092
  const st = await stat6(p);
48544
49093
  if (st.size <= LOG_MAX_BYTES) continue;
@@ -48547,7 +49096,7 @@ async function rotateRunawayLogs() {
48547
49096
  try {
48548
49097
  const buf = Buffer.alloc(keep);
48549
49098
  await fh.read(buf, 0, keep, st.size - keep);
48550
- await writeFile(p.replace(/\.log$/, ".old.log"), buf);
49099
+ await writeFile2(p.replace(/\.log$/, ".old.log"), buf);
48551
49100
  } finally {
48552
49101
  await fh.close();
48553
49102
  }
@@ -48560,21 +49109,21 @@ async function rotateRunawayLogs() {
48560
49109
  }
48561
49110
  }
48562
49111
  async function writeLocalStatus(snapshot) {
48563
- const { homedir: homedir11 } = await import("os");
48564
- const { join: join13 } = await import("path");
48565
- const { writeFile, mkdir: mkdir2, rename } = await import("fs/promises");
49112
+ const { homedir: homedir12 } = await import("os");
49113
+ const { join: join14 } = await import("path");
49114
+ const { writeFile: writeFile2, mkdir: mkdir3, rename: rename2 } = await import("fs/promises");
48566
49115
  if (!lastStatusPath) {
48567
- const dir = join13(homedir11(), ".modelstat");
49116
+ const dir = join14(homedir12(), ".modelstat");
48568
49117
  try {
48569
- await mkdir2(dir, { recursive: true });
49118
+ await mkdir3(dir, { recursive: true });
48570
49119
  } catch {
48571
49120
  }
48572
- lastStatusPath = join13(dir, "last-status.json");
49121
+ lastStatusPath = join14(dir, "last-status.json");
48573
49122
  }
48574
49123
  const tmp = `${lastStatusPath}.tmp`;
48575
49124
  try {
48576
- await writeFile(tmp, JSON.stringify({ ...snapshot, written_at: (/* @__PURE__ */ new Date()).toISOString() }));
48577
- await rename(tmp, lastStatusPath);
49125
+ await writeFile2(tmp, JSON.stringify({ ...snapshot, written_at: (/* @__PURE__ */ new Date()).toISOString() }));
49126
+ await rename2(tmp, lastStatusPath);
48578
49127
  } catch {
48579
49128
  }
48580
49129
  }
@@ -48604,7 +49153,7 @@ async function runScanCycle(reason) {
48604
49153
  const r = await scanAll({
48605
49154
  onFile(path5, index, total) {
48606
49155
  setProgress(index + 1, total);
48607
- setMessage(`Scanning ${index + 1}/${total}: ${basename3(path5)}`);
49156
+ setMessage(`Scanning ${index + 1}/${total}: ${basename4(path5)}`);
48608
49157
  },
48609
49158
  onProgress(p) {
48610
49159
  const sess = p.sessionTotal > 1 ? ` \xB7 session ${p.session}/${p.sessionTotal}` : "";
@@ -48638,7 +49187,7 @@ async function runScanCycle(reason) {
48638
49187
  function requestScan(reason) {
48639
49188
  return scanRunner.trigger(reason);
48640
49189
  }
48641
- function basename3(p) {
49190
+ function basename4(p) {
48642
49191
  return p.split("/").pop() ?? p;
48643
49192
  }
48644
49193
  async function runDaemon(opts = {}) {
@@ -48694,20 +49243,26 @@ async function runDaemon(opts = {}) {
48694
49243
  }
48695
49244
  await runDiscovery();
48696
49245
  await requestScan("startup");
49246
+ try {
49247
+ const { createPolicyRefresher: createPolicyRefresher2 } = await Promise.resolve().then(() => (init_policies2(), policies_exports));
49248
+ await createPolicyRefresher2({ apiUrl: state.apiUrl }).start();
49249
+ } catch (err) {
49250
+ setMessage(`policy refresh unavailable: ${err.message}`);
49251
+ }
48697
49252
  const chokidar = (await Promise.resolve().then(() => (init_esm2(), esm_exports))).default;
48698
- const { homedir: homedir11, platform: platform6 } = await import("os");
48699
- const { join: join13 } = await import("path");
48700
- const home2 = homedir11();
49253
+ const { homedir: homedir12, platform: platform6 } = await import("os");
49254
+ const { join: join14 } = await import("path");
49255
+ const home2 = homedir12();
48701
49256
  const dirs = [
48702
- join13(home2, ".claude/projects"),
48703
- join13(home2, ".codex/sessions"),
48704
- join13(home2, ".cursor/ai-tracking"),
48705
- join13(home2, ".gemini"),
49257
+ join14(home2, ".claude/projects"),
49258
+ join14(home2, ".codex/sessions"),
49259
+ join14(home2, ".cursor/ai-tracking"),
49260
+ join14(home2, ".gemini"),
48706
49261
  ...platform6() === "darwin" ? [
48707
- join13(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
48708
- join13(home2, "Library/Application Support/Claude")
48709
- ] : [join13(home2, ".config/Cursor/User/workspaceStorage")]
48710
- ].filter((p) => existsSync10(p) && statSync2(p).isDirectory());
49262
+ join14(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
49263
+ join14(home2, "Library/Application Support/Claude")
49264
+ ] : [join14(home2, ".config/Cursor/User/workspaceStorage")]
49265
+ ].filter((p) => existsSync11(p) && statSync2(p).isDirectory());
48711
49266
  setPhase("watching", `Watching ${dirs.length} directories`);
48712
49267
  const watcher = chokidar.watch(dirs, {
48713
49268
  persistent: true,
@@ -48724,9 +49279,9 @@ async function runDaemon(opts = {}) {
48724
49279
  }, 1e3);
48725
49280
  };
48726
49281
  watcher.on("add", (p) => {
48727
- if (p.endsWith(".jsonl") || p.endsWith(".db")) scheduleScan(`add ${basename3(p)}`);
49282
+ if (p.endsWith(".jsonl") || p.endsWith(".db")) scheduleScan(`add ${basename4(p)}`);
48728
49283
  }).on("change", (p) => {
48729
- if (p.endsWith(".jsonl") || p.endsWith(".db")) scheduleScan(`change ${basename3(p)}`);
49284
+ if (p.endsWith(".jsonl") || p.endsWith(".db")) scheduleScan(`change ${basename4(p)}`);
48730
49285
  }).on("error", (e) => {
48731
49286
  setMessage(`watcher error: ${e.message}`);
48732
49287
  });
@@ -48758,7 +49313,7 @@ var init_daemon = __esm({
48758
49313
  init_machine_key();
48759
49314
  init_scan();
48760
49315
  init_single_flight();
48761
- AGENT_VERSION2 = true ? "agent-0.0.50" : "agent-dev";
49316
+ AGENT_VERSION2 = true ? "agent-0.0.52" : "agent-dev";
48762
49317
  HEARTBEAT_INTERVAL_MS = 1e4;
48763
49318
  SCAN_INTERVAL_MS = 5 * 60 * 1e3;
48764
49319
  DISCOVERY_INTERVAL_MS = 6e4;
@@ -48786,37 +49341,37 @@ var watch_exports = {};
48786
49341
  __export(watch_exports, {
48787
49342
  watchForever: () => watchForever
48788
49343
  });
48789
- import { existsSync as existsSync11 } from "fs";
48790
- import { homedir as homedir10, platform as platform4 } from "os";
48791
- import { join as join12 } from "path";
49344
+ import { existsSync as existsSync12 } from "fs";
49345
+ import { homedir as homedir11, platform as platform4 } from "os";
49346
+ import { join as join13 } from "path";
48792
49347
  function resolveWatchDirs() {
48793
- const home2 = homedir10();
48794
- const xdgConfig = process.env.XDG_CONFIG_HOME ?? join12(home2, ".config");
48795
- const xdgData = process.env.XDG_DATA_HOME ?? join12(home2, ".local/share");
49348
+ const home2 = homedir11();
49349
+ const xdgConfig = process.env.XDG_CONFIG_HOME ?? join13(home2, ".config");
49350
+ const xdgData = process.env.XDG_DATA_HOME ?? join13(home2, ".local/share");
48796
49351
  const candidates = [
48797
49352
  // universal (default HOME-rooted CLI data dirs)
48798
- join12(home2, ".claude/projects"),
48799
- join12(home2, ".codex/sessions"),
48800
- join12(home2, ".cursor/ai-tracking"),
48801
- join12(home2, ".gemini"),
48802
- join12(home2, ".aider"),
49353
+ join13(home2, ".claude/projects"),
49354
+ join13(home2, ".codex/sessions"),
49355
+ join13(home2, ".cursor/ai-tracking"),
49356
+ join13(home2, ".gemini"),
49357
+ join13(home2, ".aider"),
48803
49358
  // XDG / Linux
48804
- join12(xdgConfig, "claude/projects"),
48805
- join12(xdgConfig, "codex/sessions"),
48806
- join12(xdgConfig, "Cursor/User/workspaceStorage"),
48807
- join12(xdgConfig, "Code/User/workspaceStorage"),
48808
- join12(xdgConfig, "Code - Insiders/User/workspaceStorage"),
48809
- join12(xdgData, "claude/projects"),
49359
+ join13(xdgConfig, "claude/projects"),
49360
+ join13(xdgConfig, "codex/sessions"),
49361
+ join13(xdgConfig, "Cursor/User/workspaceStorage"),
49362
+ join13(xdgConfig, "Code/User/workspaceStorage"),
49363
+ join13(xdgConfig, "Code - Insiders/User/workspaceStorage"),
49364
+ join13(xdgData, "claude/projects"),
48810
49365
  // macOS
48811
49366
  ...platform4() === "darwin" ? [
48812
- join12(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
48813
- join12(home2, "Library/Application Support/Claude"),
48814
- join12(home2, "Library/Application Support/Code/User/workspaceStorage"),
48815
- join12(home2, "Library/Application Support/Windsurf/User/workspaceStorage"),
48816
- join12(home2, "Library/Application Support/Zed")
49367
+ join13(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
49368
+ join13(home2, "Library/Application Support/Claude"),
49369
+ join13(home2, "Library/Application Support/Code/User/workspaceStorage"),
49370
+ join13(home2, "Library/Application Support/Windsurf/User/workspaceStorage"),
49371
+ join13(home2, "Library/Application Support/Zed")
48817
49372
  ] : []
48818
49373
  ];
48819
- return Array.from(new Set(candidates)).filter((p) => existsSync11(p));
49374
+ return Array.from(new Set(candidates)).filter((p) => existsSync12(p));
48820
49375
  }
48821
49376
  async function safeScan(reason) {
48822
49377
  if (scanning) {
@@ -48883,15 +49438,15 @@ init_config2();
48883
49438
  init_identity();
48884
49439
  init_machine_key();
48885
49440
  init_scan();
48886
- import { spawn } from "child_process";
49441
+ import { spawn as spawn2 } from "child_process";
48887
49442
  import { arch as cpuArch, hostname as hostname2, platform as platform5, release } from "os";
48888
49443
  import { createInterface as createInterface3 } from "readline";
48889
49444
 
48890
49445
  // src/service.ts
48891
- import { spawnSync as spawnSync2 } from "child_process";
49446
+ import { spawn, spawnSync as spawnSync2 } from "child_process";
48892
49447
  import {
48893
49448
  copyFileSync,
48894
- existsSync as existsSync8,
49449
+ existsSync as existsSync9,
48895
49450
  mkdirSync as mkdirSync3,
48896
49451
  readFileSync as readFileSync4,
48897
49452
  realpathSync,
@@ -48927,7 +49482,7 @@ function installBundle() {
48927
49482
  mkdirSync3(logDir(), { recursive: true });
48928
49483
  const src = runningCliPath();
48929
49484
  const dest = installedCliPath();
48930
- if (!existsSync8(src)) {
49485
+ if (!existsSync9(src)) {
48931
49486
  throw new Error(
48932
49487
  `Can't find the CLI bundle to install from (${src}). Are you running a local dev build?`
48933
49488
  );
@@ -48946,7 +49501,7 @@ function sourceLlamaVersion(sourceCli) {
48946
49501
  let d = dirname6(realpathSync(req.resolve("node-llama-cpp")));
48947
49502
  for (let i = 0; i < 10; i++) {
48948
49503
  const pj = join7(d, "package.json");
48949
- if (existsSync8(pj)) {
49504
+ if (existsSync9(pj)) {
48950
49505
  const p = JSON.parse(readFileSync4(pj, "utf8"));
48951
49506
  if (p.name === "node-llama-cpp" && p.version) return p.version;
48952
49507
  }
@@ -48963,10 +49518,7 @@ function installNativeRuntime(sourceCli) {
48963
49518
  const dest = binDir();
48964
49519
  try {
48965
49520
  const have = JSON.parse(
48966
- readFileSync4(
48967
- join7(dest, "node_modules", "node-llama-cpp", "package.json"),
48968
- "utf8"
48969
- )
49521
+ readFileSync4(join7(dest, "node_modules", "node-llama-cpp", "package.json"), "utf8")
48970
49522
  );
48971
49523
  if (have.version === version) return [`node-llama-cpp@${version} (cached)`];
48972
49524
  } catch {
@@ -49013,7 +49565,7 @@ function locateTrayExecutable() {
49013
49565
  "/Applications/ModelstatTray.app/Contents/MacOS/modelstat-tray"
49014
49566
  ];
49015
49567
  for (const p of candidates) {
49016
- if (existsSync8(p)) return p;
49568
+ if (existsSync9(p)) return p;
49017
49569
  }
49018
49570
  return null;
49019
49571
  }
@@ -49085,7 +49637,7 @@ function macUninstall() {
49085
49637
  const target = `gui/${uid}/${SERVICE_LABEL}`;
49086
49638
  launchctl(["bootout", target]);
49087
49639
  const plist = plistPath();
49088
- if (existsSync8(plist)) {
49640
+ if (existsSync9(plist)) {
49089
49641
  try {
49090
49642
  unlinkSync(plist);
49091
49643
  } catch {
@@ -49148,7 +49700,7 @@ function linuxInstall() {
49148
49700
  function linuxUninstall() {
49149
49701
  systemctl(["disable", "--now", `${SYSTEMD_UNIT}.service`]);
49150
49702
  const unit = systemdUnitPath();
49151
- if (existsSync8(unit)) {
49703
+ if (existsSync9(unit)) {
49152
49704
  try {
49153
49705
  unlinkSync(unit);
49154
49706
  } catch {
@@ -49192,7 +49744,7 @@ function logsDir() {
49192
49744
  }
49193
49745
  function installTrayApp(sourceAppPath) {
49194
49746
  if (platform3() !== "darwin") return null;
49195
- if (!existsSync8(sourceAppPath)) return null;
49747
+ if (!existsSync9(sourceAppPath)) return null;
49196
49748
  const dest = join7(home(), "Applications", "ModelstatTray.app");
49197
49749
  mkdirSync3(dirname6(dest), { recursive: true });
49198
49750
  spawnSync2("rm", ["-rf", dest]);
@@ -49202,7 +49754,7 @@ function installTrayApp(sourceAppPath) {
49202
49754
  }
49203
49755
  return { installedAt: dest };
49204
49756
  }
49205
- function bundledTrayAppPath() {
49757
+ async function bundledTrayAppPath(progress) {
49206
49758
  if (platform3() !== "darwin") return null;
49207
49759
  const here2 = dirname6(fileURLToPath2(import.meta.url));
49208
49760
  const candidates = [
@@ -49212,24 +49764,55 @@ function bundledTrayAppPath() {
49212
49764
  join7(here2, "..", "..", "tray-mac", "build", "ModelstatTray.app")
49213
49765
  ];
49214
49766
  for (const c of candidates) {
49215
- if (existsSync8(c)) return c;
49767
+ if (existsSync9(c)) return c;
49216
49768
  }
49217
- const sourceDirs = [
49218
- join7(here2, "..", "vendor", "tray-mac"),
49219
- join7(here2, "..", "..", "tray-mac")
49220
- ];
49769
+ const sourceDirs = [join7(here2, "..", "vendor", "tray-mac"), join7(here2, "..", "..", "tray-mac")];
49221
49770
  for (const src of sourceDirs) {
49222
49771
  const build = join7(src, "build-app.sh");
49223
- if (!existsSync8(build)) continue;
49772
+ if (!existsSync9(build)) continue;
49224
49773
  if (!hasSwift()) return null;
49225
- const r = spawnSync2("bash", [build], { cwd: src, encoding: "utf8" });
49226
- if (r.status === 0) {
49774
+ const code = await runTrayBuild(src, build, progress);
49775
+ if (code === 0) {
49227
49776
  const app = join7(src, "build", "ModelstatTray.app");
49228
- if (existsSync8(app)) return app;
49777
+ if (existsSync9(app)) return app;
49229
49778
  }
49230
49779
  }
49231
49780
  return null;
49232
49781
  }
49782
+ function createLineSplitter(onLine) {
49783
+ let buf = "";
49784
+ return {
49785
+ push(chunk) {
49786
+ buf += chunk;
49787
+ for (; ; ) {
49788
+ const nl = buf.indexOf("\n");
49789
+ if (nl === -1) break;
49790
+ const line = buf.slice(0, nl).trimEnd();
49791
+ buf = buf.slice(nl + 1);
49792
+ if (line) onLine(line);
49793
+ }
49794
+ },
49795
+ flush() {
49796
+ const line = buf.trim();
49797
+ buf = "";
49798
+ if (line) onLine(line);
49799
+ }
49800
+ };
49801
+ }
49802
+ function runTrayBuild(cwd, buildScript, progress) {
49803
+ return new Promise((resolve6) => {
49804
+ const child = spawn("bash", [buildScript], { cwd });
49805
+ const splitter = createLineSplitter((line) => progress?.onLine?.(line));
49806
+ const pump = (chunk) => splitter.push(chunk.toString("utf8"));
49807
+ child.stdout?.on("data", pump);
49808
+ child.stderr?.on("data", pump);
49809
+ child.on("error", () => resolve6(null));
49810
+ child.on("close", (code) => {
49811
+ splitter.flush();
49812
+ resolve6(code);
49813
+ });
49814
+ });
49815
+ }
49233
49816
  function hasSwift() {
49234
49817
  const r = spawnSync2("swift", ["--version"], { encoding: "utf8" });
49235
49818
  return r.status === 0;
@@ -49313,7 +49896,7 @@ function tryOpenBrowser(url) {
49313
49896
  const cmd = p === "darwin" ? "open" : p === "win32" ? "cmd" : "xdg-open";
49314
49897
  const args = p === "win32" ? ["/c", "start", "", url] : [url];
49315
49898
  try {
49316
- const child = spawn(cmd, args, {
49899
+ const child = spawn2(cmd, args, {
49317
49900
  stdio: "ignore",
49318
49901
  detached: true
49319
49902
  });
@@ -49323,7 +49906,7 @@ function tryOpenBrowser(url) {
49323
49906
  return false;
49324
49907
  }
49325
49908
  }
49326
- var AGENT_VERSION3 = true ? "agent-0.0.50" : "agent-dev";
49909
+ var AGENT_VERSION3 = true ? "agent-0.0.52" : "agent-dev";
49327
49910
  function osFamily() {
49328
49911
  const p = platform5();
49329
49912
  if (p === "darwin") return "macos";
@@ -49418,6 +50001,54 @@ function emitEvent(opts, event, fields = {}) {
49418
50001
  process.stdout.write(`${JSON.stringify({ v: 1, ts: Date.now(), event, ...fields })}
49419
50002
  `);
49420
50003
  }
50004
+ function createTrayBuildUi(opts) {
50005
+ const isTty = !opts.json && process.stdout.isTTY === true;
50006
+ let startedAt = null;
50007
+ let ticker = null;
50008
+ const paintTicker = () => {
50009
+ if (startedAt === null) return;
50010
+ const s = Math.round((Date.now() - startedAt) / 1e3);
50011
+ process.stdout.write(`\r \x1B[2m\u23F3 compiling menu-bar tray from source\u2026 ${s}s\x1B[0m\x1B[K`);
50012
+ };
50013
+ const begin = () => {
50014
+ if (startedAt !== null) return;
50015
+ startedAt = Date.now();
50016
+ emitEvent(opts, "tray_build_started", {});
50017
+ if (!opts.json) {
50018
+ process.stdout.write(
50019
+ " \x1B[2mno prebuilt tray found \u2014 compiling a small Swift app locally (first run only, ~1 min)\x1B[0m\n"
50020
+ );
50021
+ }
50022
+ if (isTty) {
50023
+ paintTicker();
50024
+ ticker = setInterval(paintTicker, 1e3);
50025
+ ticker.unref?.();
50026
+ }
50027
+ };
50028
+ return {
50029
+ onLine: (line) => {
50030
+ begin();
50031
+ emitEvent(opts, "tray_build_progress", { line });
50032
+ if (isTty) {
50033
+ process.stdout.write(`\r\x1B[K \x1B[2m${line}\x1B[0m
50034
+ `);
50035
+ } else if (!opts.json) {
50036
+ process.stdout.write(` ${line}
50037
+ `);
50038
+ }
50039
+ },
50040
+ finish: () => {
50041
+ if (ticker) {
50042
+ clearInterval(ticker);
50043
+ ticker = null;
50044
+ }
50045
+ if (isTty && startedAt !== null) process.stdout.write("\r\x1B[K");
50046
+ const elapsed = startedAt === null ? null : Date.now() - startedAt;
50047
+ if (elapsed !== null) emitEvent(opts, "tray_build_done", { elapsed_ms: elapsed });
50048
+ return elapsed;
50049
+ }
50050
+ };
50051
+ }
49421
50052
  async function cmdConnect(opts) {
49422
50053
  const step = (msg) => {
49423
50054
  if (opts.json) return;
@@ -49477,9 +50108,10 @@ async function cmdConnect(opts) {
49477
50108
  }
49478
50109
  }
49479
50110
  }
50111
+ const apiBase = state.apiUrl.replace(/\/$/, "");
49480
50112
  const claimCode = state.claimCode ?? "(unknown)";
49481
- const claimUrl = state.claimUrl ?? `https://modelstat.ai/device/${claimCode}`;
49482
- const agentUrl = `https://modelstat.ai/device/${claimCode}/agent`;
50113
+ const claimUrl = state.claimUrl ?? `${apiBase}/device/${claimCode}`;
50114
+ const agentUrl = `${apiBase}/device/${claimCode}/agent`;
49483
50115
  emitEvent(opts, "registered", {
49484
50116
  device_uuid: state.deviceUuid,
49485
50117
  device_id: state.deviceId,
@@ -49489,12 +50121,18 @@ async function cmdConnect(opts) {
49489
50121
  });
49490
50122
  if (platform5() === "darwin") {
49491
50123
  step("Installing menu-bar tray (macOS)");
50124
+ const buildUi = createTrayBuildUi(opts);
49492
50125
  try {
49493
- const src = bundledTrayAppPath();
50126
+ const src = await bundledTrayAppPath({ onLine: buildUi.onLine });
50127
+ const buildMs = buildUi.finish();
49494
50128
  if (src) {
50129
+ if (buildMs !== null) ok(`tray compiled from source in ${Math.round(buildMs / 1e3)}s`);
49495
50130
  const out = installTrayApp(src);
49496
50131
  if (out) {
49497
- emitEvent(opts, "tray_installed", { path: out.installedAt });
50132
+ emitEvent(opts, "tray_installed", {
50133
+ path: out.installedAt,
50134
+ ...buildMs !== null ? { build_ms: buildMs } : {}
50135
+ });
49498
50136
  ok(`tray at ${out.installedAt}`);
49499
50137
  }
49500
50138
  } else {
@@ -49502,6 +50140,7 @@ async function cmdConnect(opts) {
49502
50140
  warn("no bundled tray \u2014 skipping (install Xcode CLI tools and re-run to get the icon)");
49503
50141
  }
49504
50142
  } catch (e) {
50143
+ buildUi.finish();
49505
50144
  emitEvent(opts, "tray_install_failed", { error: e.message });
49506
50145
  warn(`tray install skipped: ${e.message}`);
49507
50146
  }
@@ -49705,11 +50344,11 @@ function fmtTokens(v) {
49705
50344
  }
49706
50345
  async function readLocalStatus() {
49707
50346
  try {
49708
- const { homedir: homedir11 } = await import("os");
49709
- const { join: join13 } = await import("path");
49710
- const { readFile } = await import("fs/promises");
49711
- const p = join13(homedir11(), ".modelstat", "last-status.json");
49712
- const txt = await readFile(p, "utf8");
50347
+ const { homedir: homedir12 } = await import("os");
50348
+ const { join: join14 } = await import("path");
50349
+ const { readFile: readFile2 } = await import("fs/promises");
50350
+ const p = join14(homedir12(), ".modelstat", "last-status.json");
50351
+ const txt = await readFile2(p, "utf8");
49713
50352
  return JSON.parse(txt);
49714
50353
  } catch {
49715
50354
  return null;