unbrowse 9.0.4 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/runtime/cli.js CHANGED
@@ -5,6 +5,7 @@ var __create = Object.create;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __defProp = Object.defineProperty;
7
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
9
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
10
  function __accessProp(key) {
10
11
  return this[key];
@@ -31,6 +32,23 @@ var __toESM = (mod, isNodeMode, target) => {
31
32
  cache.set(mod, to);
32
33
  return to;
33
34
  };
35
+ var __toCommonJS = (from) => {
36
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
37
+ if (entry)
38
+ return entry;
39
+ entry = __defProp({}, "__esModule", { value: true });
40
+ if (from && typeof from === "object" || typeof from === "function") {
41
+ for (var key of __getOwnPropNames(from))
42
+ if (!__hasOwnProp.call(entry, key))
43
+ __defProp(entry, key, {
44
+ get: __accessProp.bind(from, key),
45
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
46
+ });
47
+ }
48
+ __moduleCache.set(from, entry);
49
+ return entry;
50
+ };
51
+ var __moduleCache;
34
52
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
35
53
  var __returnValue = (v) => v;
36
54
  function __exportSetter(name, newValue) {
@@ -6131,6 +6149,98 @@ async function payAndRetry(fullUrl, options) {
6131
6149
  var LOBSTER_PAY_TIMEOUT_MS = 30000, cachedCommand2 = undefined;
6132
6150
  var init_lobster_pay = () => {};
6133
6151
 
6152
+ // .tmp-runtime-src/proof/input-censor.ts
6153
+ var exports_input_censor = {};
6154
+ __export(exports_input_censor, {
6155
+ isSensitiveFieldName: () => isSensitiveFieldName,
6156
+ commitValue: () => commitValue,
6157
+ censorSkillForPersistence: () => censorSkillForPersistence,
6158
+ censorInputBody: () => censorInputBody
6159
+ });
6160
+ import { createHash as createHash5 } from "node:crypto";
6161
+ function looksLikePointer(v) {
6162
+ return /^(op|keychain|bw|arg|vault):\/\//.test(v);
6163
+ }
6164
+ function commitValue(value) {
6165
+ return `sha256:${createHash5("sha256").update(value).digest("hex")}`;
6166
+ }
6167
+ function isSensitiveFieldName(name) {
6168
+ return SENSITIVE_FIELD.test(name);
6169
+ }
6170
+ function censorInputBody(body, prefix = "") {
6171
+ const commitments = {};
6172
+ let didCensor = false;
6173
+ const walk = (val, keyName, path2) => {
6174
+ if (val && typeof val === "object" && !Array.isArray(val)) {
6175
+ const out = {};
6176
+ for (const [k, v] of Object.entries(val)) {
6177
+ out[k] = walk(v, k, path2 ? `${path2}.${k}` : k);
6178
+ }
6179
+ return out;
6180
+ }
6181
+ if (Array.isArray(val)) {
6182
+ return val.map((v, i) => walk(v, keyName, `${path2}[${i}]`));
6183
+ }
6184
+ const sensitive = isSensitiveFieldName(keyName) || typeof val === "string" && looksLikePointer(val);
6185
+ if (sensitive && (typeof val === "string" || typeof val === "number" || typeof val === "boolean")) {
6186
+ const commitment = commitValue(String(val));
6187
+ commitments[path2 || keyName] = commitment;
6188
+ didCensor = true;
6189
+ return commitment;
6190
+ }
6191
+ return val;
6192
+ };
6193
+ const censored = walk(body, prefix, prefix);
6194
+ return { censored, commitments, didCensor };
6195
+ }
6196
+ function censorSkillForPersistence(skill) {
6197
+ if (!skill || !Array.isArray(skill.endpoints))
6198
+ return { skill, didCensor: false };
6199
+ let didCensor = false;
6200
+ const endpoints = skill.endpoints.map((ep) => {
6201
+ const method = String(ep.method ?? "GET").toUpperCase();
6202
+ const body = ep.body;
6203
+ if (method === "GET" || method === "HEAD" || body == null)
6204
+ return ep;
6205
+ const res = censorInputBody(body);
6206
+ if (!res.didCensor)
6207
+ return ep;
6208
+ didCensor = true;
6209
+ return {
6210
+ ...ep,
6211
+ body: res.censored,
6212
+ input_commitments: res.commitments
6213
+ };
6214
+ });
6215
+ if (!didCensor)
6216
+ return { skill, didCensor: false };
6217
+ return { skill: { ...skill, endpoints }, didCensor: true };
6218
+ }
6219
+ var SENSITIVE_FIELD;
6220
+ var init_input_censor = __esm(() => {
6221
+ SENSITIVE_FIELD = new RegExp([
6222
+ "pass(word|wd|phrase)?",
6223
+ "secret",
6224
+ "token",
6225
+ "api[_-]?key",
6226
+ "apikey",
6227
+ "auth(orization|_token)?",
6228
+ "access[_-]?key",
6229
+ "client[_-]?secret",
6230
+ "private[_-]?key",
6231
+ "mnemonic",
6232
+ "seed[_-]?phrase",
6233
+ "ssn",
6234
+ "credit[_-]?card",
6235
+ "card[_-]?number",
6236
+ "cvv",
6237
+ "pin",
6238
+ "otp",
6239
+ "session[_-]?id",
6240
+ "cookie"
6241
+ ].join("|"), "i");
6242
+ });
6243
+
6134
6244
  // .tmp-runtime-src/client/index.ts
6135
6245
  var exports_client = {};
6136
6246
  __export(exports_client, {
@@ -6171,6 +6281,7 @@ __export(exports_client, {
6171
6281
  looksLikeSkillId: () => looksLikeSkillId,
6172
6282
  loadConfig: () => loadConfig,
6173
6283
  listSkills: () => listSkills,
6284
+ listLocalSkills: () => listLocalSkills,
6174
6285
  isX402Error: () => isX402Error,
6175
6286
  isValidAgentEmail: () => isValidAgentEmail,
6176
6287
  isLocalOnlyMode: () => isLocalOnlyMode,
@@ -6209,7 +6320,7 @@ __export(exports_client, {
6209
6320
  import { readFileSync as readFileSync9, writeFileSync as writeFileSync4, existsSync as existsSync12, mkdirSync as mkdirSync5, readdirSync as readdirSync3, unlinkSync } from "fs";
6210
6321
  import { join as join15 } from "path";
6211
6322
  import { homedir as homedir13, hostname, release as osRelease } from "os";
6212
- import { randomBytes as randomBytes5, createHash as createHash5 } from "crypto";
6323
+ import { randomBytes as randomBytes5, createHash as createHash6 } from "crypto";
6213
6324
  import { createInterface } from "readline";
6214
6325
  import { execSync as execSync2 } from "child_process";
6215
6326
  function getApiBaseUrl() {
@@ -6553,7 +6664,7 @@ function getApiKey() {
6553
6664
  function hashApiKey(key) {
6554
6665
  if (!key || key === "local-only")
6555
6666
  return "";
6556
- return createHash5("sha256").update(key).digest("hex");
6667
+ return createHash6("sha256").update(key).digest("hex");
6557
6668
  }
6558
6669
  function getAgentId() {
6559
6670
  const config = loadConfig();
@@ -7127,7 +7238,9 @@ function writeSkillCache(skill, scopeId) {
7127
7238
  }
7128
7239
  }
7129
7240
  }
7130
- writeFileSync4(skillCachePath(skill.skill_id), JSON.stringify(skill), "utf-8");
7241
+ const { censorSkillForPersistence: censorSkillForPersistence2 } = (init_input_censor(), __toCommonJS(exports_input_censor));
7242
+ const { skill: persistable } = censorSkillForPersistence2(skill);
7243
+ writeFileSync4(skillCachePath(skill.skill_id), JSON.stringify(persistable), "utf-8");
7131
7244
  } catch {}
7132
7245
  }
7133
7246
  function cachePublishedSkill(skill, scopeId) {
@@ -7169,6 +7282,29 @@ function getRecentLocalSkill(skillId, scopeId) {
7169
7282
  }
7170
7283
  return null;
7171
7284
  }
7285
+ function listLocalSkills() {
7286
+ const bySkillId = new Map;
7287
+ for (const s of recentLocalSkills.values()) {
7288
+ if (s?.skill_id)
7289
+ bySkillId.set(s.skill_id, s);
7290
+ }
7291
+ try {
7292
+ const dir = getSkillCacheDir();
7293
+ if (existsSync12(dir)) {
7294
+ for (const f of readdirSync3(dir)) {
7295
+ if (!f.endsWith(".json"))
7296
+ continue;
7297
+ const id = f.slice(0, -5);
7298
+ if (bySkillId.has(id))
7299
+ continue;
7300
+ const s = readSkillCache(id);
7301
+ if (s?.skill_id)
7302
+ bySkillId.set(s.skill_id, s);
7303
+ }
7304
+ }
7305
+ } catch {}
7306
+ return [...bySkillId.values()];
7307
+ }
7172
7308
  function normalizeIntent(value) {
7173
7309
  return (value ?? "").trim().toLowerCase();
7174
7310
  }
@@ -8713,7 +8849,7 @@ function helpExit(subcommand, spec, opts = {}) {
8713
8849
  var EX_USAGE = 64, EX_SOFTWARE = 70, EX_GENERIC = 1;
8714
8850
 
8715
8851
  // .tmp-runtime-src/cli-v7/_stateless.ts
8716
- import { randomBytes as randomBytes6, createHash as createHash6 } from "node:crypto";
8852
+ import { randomBytes as randomBytes6, createHash as createHash7 } from "node:crypto";
8717
8853
  function bytesToHex4(b) {
8718
8854
  let h = "";
8719
8855
  for (let i = 0;i < b.length; i++)
@@ -8738,7 +8874,7 @@ function freshNonce() {
8738
8874
  return bytesToBase642(new Uint8Array(randomBytes6(32)));
8739
8875
  }
8740
8876
  async function deriveCacheKeyFromSignature(signature) {
8741
- const hashHex = createHash6("sha256").update(signature).digest("hex");
8877
+ const hashHex = createHash7("sha256").update(signature).digest("hex");
8742
8878
  return hashHex.slice(0, 32);
8743
8879
  }
8744
8880
  function sanitizeErrorHint(err) {
@@ -8887,15 +9023,15 @@ var init__stateless = __esm(() => {
8887
9023
  });
8888
9024
 
8889
9025
  // .tmp-runtime-src/cli-v7/_act-audit.ts
8890
- import { createHash as createHash7 } from "node:crypto";
9026
+ import { createHash as createHash8 } from "node:crypto";
8891
9027
  function sha256Hex(s) {
8892
- return createHash7("sha256").update(s, "utf8").digest("hex");
9028
+ return createHash8("sha256").update(s, "utf8").digest("hex");
8893
9029
  }
8894
9030
  function deriveBreathActContextHash(sessionId, actType, selector, url, nowMs = Date.now()) {
8895
9031
  const bucket = Math.floor(nowMs / FIVE_MINUTES_MS).toString();
8896
9032
  const sel = selector ?? "";
8897
9033
  const payload = `${sessionId}:${actType}:${sel}:${url}:${bucket}`;
8898
- return createHash7("sha256").update(payload, "utf8").digest("hex");
9034
+ return createHash8("sha256").update(payload, "utf8").digest("hex");
8899
9035
  }
8900
9036
  async function emitBreathActStateless(input) {
8901
9037
  const nowMs = input.nowMs ?? Date.now();
@@ -49720,12 +49856,12 @@ import {
49720
49856
  } from "node:fs/promises";
49721
49857
  import { homedir as homedir17 } from "node:os";
49722
49858
  import { join as join21 } from "node:path";
49723
- import { createHash as createHash8 } from "node:crypto";
49859
+ import { createHash as createHash9 } from "node:crypto";
49724
49860
  function statelessTmpRoot() {
49725
49861
  return join21(homedir17(), ".unbrowse", "tmp");
49726
49862
  }
49727
49863
  function sessionTmpDir(sessionId) {
49728
- const hash = createHash8("sha256").update(sessionId).digest("hex").slice(0, 16);
49864
+ const hash = createHash9("sha256").update(sessionId).digest("hex").slice(0, 16);
49729
49865
  return join21(statelessTmpRoot(), hash);
49730
49866
  }
49731
49867
  function sessionPath(sessionId) {
@@ -49920,7 +50056,7 @@ var init_go = __esm(() => {
49920
50056
  });
49921
50057
 
49922
50058
  // .tmp-runtime-src/values/adapters/arg.ts
49923
- import { createHash as createHash9 } from "node:crypto";
50059
+ import { createHash as createHash10 } from "node:crypto";
49924
50060
  function walkPath(scope, path11) {
49925
50061
  const segs = path11.split("/").filter((s) => s.length > 0);
49926
50062
  if (segs.length === 0) {
@@ -49983,7 +50119,7 @@ class ArgAdapter {
49983
50119
  }
49984
50120
  const raw = walkPath(ctx.argScope, pointer.path);
49985
50121
  const value = valueToBytes(raw);
49986
- const h = createHash9("sha256");
50122
+ const h = createHash10("sha256");
49987
50123
  h.update(value);
49988
50124
  h.update(nonce);
49989
50125
  const commitment = new Uint8Array(h.digest());
@@ -50085,7 +50221,7 @@ var init_stderr_filter = __esm(() => {
50085
50221
 
50086
50222
  // .tmp-runtime-src/values/adapters/bw.ts
50087
50223
  import { spawn as spawn4 } from "node:child_process";
50088
- import { createHash as createHash10 } from "node:crypto";
50224
+ import { createHash as createHash11 } from "node:crypto";
50089
50225
  function parseBwPath(path11) {
50090
50226
  const idx = path11.indexOf("/");
50091
50227
  if (idx < 0) {
@@ -50308,7 +50444,7 @@ class BwAdapter {
50308
50444
  if (value.length === 0) {
50309
50445
  throw new AdapterError("adapter_exit_nonzero", `bw returned empty value for ${pointer.raw}`);
50310
50446
  }
50311
- const h = createHash10("sha256");
50447
+ const h = createHash11("sha256");
50312
50448
  h.update(value);
50313
50449
  h.update(nonce);
50314
50450
  const commitment = new Uint8Array(h.digest());
@@ -50341,7 +50477,7 @@ var init_bw = __esm(() => {
50341
50477
 
50342
50478
  // .tmp-runtime-src/values/adapters/keychain.ts
50343
50479
  import { spawn as spawn5 } from "node:child_process";
50344
- import { createHash as createHash11 } from "node:crypto";
50480
+ import { createHash as createHash12 } from "node:crypto";
50345
50481
  import { existsSync as existsSync18 } from "node:fs";
50346
50482
  import { homedir as homedir18, platform as platform3 } from "node:os";
50347
50483
  import { join as join22 } from "node:path";
@@ -50475,7 +50611,7 @@ class KeychainAdapter {
50475
50611
  if (value.length === 0) {
50476
50612
  throw new AdapterError("adapter_exit_nonzero", `security returned empty value for keychain://${service}/${account}`);
50477
50613
  }
50478
- const h = createHash11("sha256");
50614
+ const h = createHash12("sha256");
50479
50615
  h.update(value);
50480
50616
  h.update(nonce);
50481
50617
  const commitment = new Uint8Array(h.digest());
@@ -50515,7 +50651,7 @@ var init_keychain = __esm(() => {
50515
50651
 
50516
50652
  // .tmp-runtime-src/values/adapters/op.ts
50517
50653
  import { spawn as spawn6 } from "node:child_process";
50518
- import { createHash as createHash12 } from "node:crypto";
50654
+ import { createHash as createHash13 } from "node:crypto";
50519
50655
  function whichOp() {
50520
50656
  return "op";
50521
50657
  }
@@ -50637,7 +50773,7 @@ class OpAdapter {
50637
50773
  if (value.length === 0) {
50638
50774
  throw new AdapterError("adapter_exit_nonzero", `op read returned empty value for ${pointer.raw}`);
50639
50775
  }
50640
- const h = createHash12("sha256");
50776
+ const h = createHash13("sha256");
50641
50777
  h.update(value);
50642
50778
  h.update(nonce);
50643
50779
  const commitment = new Uint8Array(h.digest());
@@ -50690,7 +50826,7 @@ function parse2(uri) {
50690
50826
  }
50691
50827
  return { scheme, path: path11, raw: uri };
50692
50828
  }
50693
- function looksLikePointer(value) {
50829
+ function looksLikePointer2(value) {
50694
50830
  if (typeof value !== "string")
50695
50831
  return false;
50696
50832
  const m = POINTER_RE.exec(value);
@@ -50803,7 +50939,7 @@ __export(exports_fill, {
50803
50939
  handler: () => handler5,
50804
50940
  deriveContextHash: () => deriveContextHash
50805
50941
  });
50806
- import { randomBytes as randomBytes7, createHash as createHash13 } from "node:crypto";
50942
+ import { randomBytes as randomBytes7, createHash as createHash14 } from "node:crypto";
50807
50943
  function canonicalizeSignedFragment2(body) {
50808
50944
  return JSON.stringify({
50809
50945
  pointer: body.pointer,
@@ -50815,10 +50951,10 @@ function canonicalizeSignedFragment2(body) {
50815
50951
  function deriveContextHash(sessionId, selector, url, nowMs = Date.now()) {
50816
50952
  const bucket = Math.floor(nowMs / FIVE_MINUTES_MS2).toString();
50817
50953
  const payload = `${sessionId}:${selector}:${url}:${bucket}`;
50818
- return createHash13("sha256").update(payload, "utf8").digest("hex");
50954
+ return createHash14("sha256").update(payload, "utf8").digest("hex");
50819
50955
  }
50820
50956
  function sha256Hex3(s) {
50821
- return createHash13("sha256").update(s, "utf8").digest("hex");
50957
+ return createHash14("sha256").update(s, "utf8").digest("hex");
50822
50958
  }
50823
50959
  function bytesToHex5(b) {
50824
50960
  let h = "";
@@ -50883,7 +51019,7 @@ async function handler5(parsed, opts) {
50883
51019
  }
50884
51020
  let pointerUri;
50885
51021
  const inlineArgScope = parseArgScope(parsed);
50886
- if (looksLikePointer(pointerArg)) {
51022
+ if (looksLikePointer2(pointerArg)) {
50887
51023
  pointerUri = pointerArg;
50888
51024
  } else {
50889
51025
  pointerUri = "arg://__inline__";
@@ -51030,7 +51166,7 @@ var exports_type = {};
51030
51166
  __export(exports_type, {
51031
51167
  handler: () => handler6
51032
51168
  });
51033
- import { randomBytes as randomBytes8, createHash as createHash14 } from "node:crypto";
51169
+ import { randomBytes as randomBytes8, createHash as createHash15 } from "node:crypto";
51034
51170
  function canonicalizeSignedFragment3(body) {
51035
51171
  return JSON.stringify({
51036
51172
  pointer: body.pointer,
@@ -51042,10 +51178,10 @@ function canonicalizeSignedFragment3(body) {
51042
51178
  function deriveContextHash2(sessionId, url, nowMs = Date.now()) {
51043
51179
  const bucket = Math.floor(nowMs / FIVE_MINUTES_MS3).toString();
51044
51180
  const payload = `${sessionId}:__focus__:${url}:${bucket}`;
51045
- return createHash14("sha256").update(payload, "utf8").digest("hex");
51181
+ return createHash15("sha256").update(payload, "utf8").digest("hex");
51046
51182
  }
51047
51183
  function sha256Hex4(s) {
51048
- return createHash14("sha256").update(s, "utf8").digest("hex");
51184
+ return createHash15("sha256").update(s, "utf8").digest("hex");
51049
51185
  }
51050
51186
  function bytesToHex6(b) {
51051
51187
  let h = "";
@@ -51111,7 +51247,7 @@ async function handler6(parsed, opts) {
51111
51247
  process.exit(EX_GENERIC);
51112
51248
  }
51113
51249
  const sessionFlag = typeof parsed.flags.session === "string" ? parsed.flags.session : undefined;
51114
- const isPointerPath = looksLikePointer(textOrPointer);
51250
+ const isPointerPath = looksLikePointer2(textOrPointer);
51115
51251
  let rec;
51116
51252
  try {
51117
51253
  rec = await resolveSession(sessionFlag);
@@ -51559,7 +51695,7 @@ var exports_select = {};
51559
51695
  __export(exports_select, {
51560
51696
  handler: () => handler9
51561
51697
  });
51562
- import { randomBytes as randomBytes9, createHash as createHash15 } from "node:crypto";
51698
+ import { randomBytes as randomBytes9, createHash as createHash16 } from "node:crypto";
51563
51699
  function canonicalizeSignedFragment4(body) {
51564
51700
  return JSON.stringify({
51565
51701
  pointer: body.pointer,
@@ -51569,7 +51705,7 @@ function canonicalizeSignedFragment4(body) {
51569
51705
  });
51570
51706
  }
51571
51707
  function sha256Hex5(s) {
51572
- return createHash15("sha256").update(s, "utf8").digest("hex");
51708
+ return createHash16("sha256").update(s, "utf8").digest("hex");
51573
51709
  }
51574
51710
  function bytesToHex7(b) {
51575
51711
  let h = "";
@@ -51678,7 +51814,7 @@ async function handler9(parsed, opts) {
51678
51814
  const byRaw = parsed.flags.by;
51679
51815
  const by = byRaw === "label" || byRaw === "index" ? byRaw : "value";
51680
51816
  const sessionFlag = typeof parsed.flags.session === "string" ? parsed.flags.session : undefined;
51681
- const isPointer = looksLikePointer(pointerArg);
51817
+ const isPointer = looksLikePointer2(pointerArg);
51682
51818
  let rec;
51683
51819
  try {
51684
51820
  rec = await resolveSession(sessionFlag);
@@ -52174,9 +52310,9 @@ var exports_execute = {};
52174
52310
  __export(exports_execute, {
52175
52311
  handler: () => handler12
52176
52312
  });
52177
- import { randomBytes as randomBytes10, createHash as createHash16 } from "node:crypto";
52313
+ import { randomBytes as randomBytes10, createHash as createHash17 } from "node:crypto";
52178
52314
  function sha256Hex6(s) {
52179
- return createHash16("sha256").update(s, "utf8").digest("hex");
52315
+ return createHash17("sha256").update(s, "utf8").digest("hex");
52180
52316
  }
52181
52317
  function bytesToHex8(b) {
52182
52318
  let h = "";
@@ -52190,7 +52326,7 @@ function bytesToBase646(b) {
52190
52326
  function deriveExecContextHash(sessionId, locator, url, nowMs = Date.now()) {
52191
52327
  const bucket = Math.floor(nowMs / FIVE_MINUTES_MS4).toString();
52192
52328
  const payload = `${sessionId}:${locator}:${url}:${bucket}`;
52193
- return createHash16("sha256").update(payload, "utf8").digest("hex");
52329
+ return createHash17("sha256").update(payload, "utf8").digest("hex");
52194
52330
  }
52195
52331
  function parseArgScope4(parsed) {
52196
52332
  const out = {};
@@ -52296,7 +52432,7 @@ function findPointerLeaves(params, prefix = "$") {
52296
52432
  for (const [k, v] of Object.entries(params)) {
52297
52433
  const path11 = `${prefix}.${k}`;
52298
52434
  if (typeof v === "string") {
52299
- if (looksLikePointer(v))
52435
+ if (looksLikePointer2(v))
52300
52436
  out.push({ path: path11, pointer: v });
52301
52437
  } else if (v && typeof v === "object" && !Array.isArray(v)) {
52302
52438
  out.push(...findPointerLeaves(v, path11));
@@ -52434,7 +52570,7 @@ async function handler12(parsed, opts) {
52434
52570
  const outgoingHeaders = { ...descriptor.headers ?? {} };
52435
52571
  try {
52436
52572
  for (const [name, ptrOrValue] of rawHeaders) {
52437
- if (looksLikePointer(ptrOrValue)) {
52573
+ if (looksLikePointer2(ptrOrValue)) {
52438
52574
  const slot = await resolveSlot({
52439
52575
  variant: "header-inject",
52440
52576
  locator: name,
@@ -52608,7 +52744,7 @@ __export(exports_auth_capture, {
52608
52744
  import { existsSync as existsSync19 } from "node:fs";
52609
52745
  import { homedir as homedir19, platform as platform4 } from "node:os";
52610
52746
  import { join as join23 } from "node:path";
52611
- import { randomUUID as randomUUID2, createHash as createHash17 } from "node:crypto";
52747
+ import { randomUUID as randomUUID2, createHash as createHash18 } from "node:crypto";
52612
52748
  import { spawn as spawn7 } from "node:child_process";
52613
52749
  async function writeKeychainJson(account, valuesJson) {
52614
52750
  if (platform4() !== "darwin") {
@@ -52776,7 +52912,7 @@ async function handler13(parsed, opts) {
52776
52912
  cookies: sidecar
52777
52913
  };
52778
52914
  const canonicalInventory = JSON.stringify(inventoryDoc);
52779
- const cookiesInventoryRef = createHash17("sha256").update(canonicalInventory).digest("hex");
52915
+ const cookiesInventoryRef = createHash18("sha256").update(canonicalInventory).digest("hex");
52780
52916
  rec = { ...rec, cookies_inventory_ref: cookiesInventoryRef };
52781
52917
  await writeSessionRecord(rec);
52782
52918
  for (const k of Object.keys(nameToValue))
@@ -53105,9 +53241,9 @@ __export(exports_snap, {
53105
53241
  handler: () => handler16,
53106
53242
  formatAxTree: () => formatAxTree
53107
53243
  });
53108
- import { createHash as createHash18 } from "node:crypto";
53244
+ import { createHash as createHash19 } from "node:crypto";
53109
53245
  function urlHash32(s) {
53110
- return createHash18("sha256").update(s).digest("hex").slice(0, 32);
53246
+ return createHash19("sha256").update(s).digest("hex").slice(0, 32);
53111
53247
  }
53112
53248
  async function getCurrentUrlSafe(conn, sessionId) {
53113
53249
  try {
@@ -53351,7 +53487,10 @@ function sanitizeForPublish(endpoints) {
53351
53487
  clean.body = redactSecrets(clean.body);
53352
53488
  }
53353
53489
  if (clean.query) {
53354
- clean.query = Object.fromEntries(Object.entries(clean.query).map(([key, value]) => [key, typeof value === "string" ? "example" : value]));
53490
+ clean.query = Object.fromEntries(Object.entries(clean.query).map(([key, value]) => [
53491
+ key,
53492
+ typeof value === "string" ? "example" : synthesizePlaceholder(key, value)
53493
+ ]));
53355
53494
  }
53356
53495
  if (clean.path_params) {
53357
53496
  clean.path_params = Object.fromEntries(Object.keys(clean.path_params).map((key) => [key, "example"]));
@@ -53384,18 +53523,17 @@ function sanitizeForPublish(endpoints) {
53384
53523
  delete semantic.sample_request_url;
53385
53524
  }
53386
53525
  }
53387
- if (semantic.requires) {
53388
- semantic.requires = semantic.requires.map((binding) => {
53389
- const { example_value: _exampleValue, ...rest } = binding;
53390
- return rest;
53391
- });
53392
- }
53393
- if (semantic.provides) {
53394
- semantic.provides = semantic.provides.map((binding) => {
53395
- const { example_value: _exampleValue, ...rest } = binding;
53396
- return rest;
53397
- });
53398
- }
53526
+ const stripExample = (binding) => {
53527
+ if (typeof binding.example_value === "string" && binding.example_value.startsWith("sha256:")) {
53528
+ return binding;
53529
+ }
53530
+ const { example_value: _exampleValue, ...rest } = binding;
53531
+ return rest;
53532
+ };
53533
+ if (semantic.requires)
53534
+ semantic.requires = semantic.requires.map(stripExample);
53535
+ if (semantic.provides)
53536
+ semantic.provides = semantic.provides.map(stripExample);
53399
53537
  clean.semantic = semantic;
53400
53538
  }
53401
53539
  return clean;
@@ -53426,11 +53564,11 @@ var init_sanitize = __esm(() => {
53426
53564
  });
53427
53565
 
53428
53566
  // .tmp-runtime-src/capture/wallet-bind.ts
53429
- import { createHash as createHash19 } from "node:crypto";
53567
+ import { createHash as createHash20 } from "node:crypto";
53430
53568
  function bindSecretToWallet(secret, walletPubkey) {
53431
53569
  if (!secret || !walletPubkey)
53432
53570
  throw new Error("bindSecretToWallet: secret and walletPubkey required");
53433
- return createHash19("sha256").update(walletPubkey).update(SEP).update(secret).digest("hex");
53571
+ return createHash20("sha256").update(walletPubkey).update(SEP).update(secret).digest("hex");
53434
53572
  }
53435
53573
  function bindingTag(secret, walletPubkey) {
53436
53574
  return `bound:${bindSecretToWallet(secret, walletPubkey).slice(0, 16)}`;
@@ -53594,7 +53732,7 @@ var exports_resolve = {};
53594
53732
  __export(exports_resolve, {
53595
53733
  handler: () => handler17
53596
53734
  });
53597
- import { createHash as createHash20, randomBytes as randomBytes11 } from "node:crypto";
53735
+ import { createHash as createHash21, randomBytes as randomBytes11 } from "node:crypto";
53598
53736
  function resolveApiBase2() {
53599
53737
  return process.env.UNBROWSE_API_URL ?? process.env.UNBROWSE_BACKEND_URL ?? DEFAULT_BACKEND_URL;
53600
53738
  }
@@ -53665,7 +53803,7 @@ async function handler17(parsed, opts) {
53665
53803
  const canonicalBytes = new TextEncoder().encode(fragment);
53666
53804
  const signed = await signBytes(canonicalBytes);
53667
53805
  const signatureHex = bytesToHex9(signed.signature);
53668
- const cacheKey = createHash20("sha256").update(signed.signature).digest("hex").slice(0, 32);
53806
+ const cacheKey = createHash21("sha256").update(signed.signature).digest("hex").slice(0, 32);
53669
53807
  safeZero(signed.signature);
53670
53808
  const payload = {
53671
53809
  intent,
@@ -54272,7 +54410,7 @@ __export(exports_trace, {
54272
54410
  import { existsSync as existsSync21, writeFileSync as writeFileSync6, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8 } from "node:fs";
54273
54411
  import { join as join27 } from "node:path";
54274
54412
  import { homedir as homedir23 } from "node:os";
54275
- import { createHash as createHash21 } from "node:crypto";
54413
+ import { createHash as createHash22 } from "node:crypto";
54276
54414
  function redactValue(v) {
54277
54415
  if (typeof v === "string") {
54278
54416
  for (const prefix of POINTER_PREFIXES) {
@@ -54326,7 +54464,7 @@ function v7DomainFilePath(domain) {
54326
54464
  }
54327
54465
  function v7TmpPendingPath(domain) {
54328
54466
  const normalized = domain.toLowerCase().replace(/^www\./, "");
54329
- const sigHash = createHash21("sha256").update(normalized).digest("hex").slice(0, 16);
54467
+ const sigHash = createHash22("sha256").update(normalized).digest("hex").slice(0, 16);
54330
54468
  return join27(homedir23(), ".unbrowse", "tmp", sigHash, "trace-pending.jsonl");
54331
54469
  }
54332
54470
  function rmLocalTraceFile(domain) {
@@ -71010,9 +71148,9 @@ __export(exports_markdown, {
71010
71148
  htmlToMarkdown: () => htmlToMarkdown,
71011
71149
  handler: () => handler22
71012
71150
  });
71013
- import { createHash as createHash22 } from "node:crypto";
71151
+ import { createHash as createHash23 } from "node:crypto";
71014
71152
  function urlHash322(s) {
71015
- return createHash22("sha256").update(s).digest("hex").slice(0, 32);
71153
+ return createHash23("sha256").update(s).digest("hex").slice(0, 32);
71016
71154
  }
71017
71155
  function stripPreamble(html) {
71018
71156
  return html.replace(/<!DOCTYPE[^>]*>/gi, "").replace(/<!--[\s\S]*?-->/g, "").replace(/<script[^>]*?>[\s\S]*?<\/script>/gi, "").replace(/<style[^>]*?>[\s\S]*?<\/style>/gi, "").replace(/<noscript[^>]*?>[\s\S]*?<\/noscript>/gi, "");
@@ -71126,7 +71264,7 @@ var exports_screenshot = {};
71126
71264
  __export(exports_screenshot, {
71127
71265
  handler: () => handler23
71128
71266
  });
71129
- import { createHash as createHash23 } from "node:crypto";
71267
+ import { createHash as createHash24 } from "node:crypto";
71130
71268
  import { mkdir as mkdir5, writeFile as writeFile3 } from "node:fs/promises";
71131
71269
  import { homedir as homedir24 } from "node:os";
71132
71270
  import { join as join28 } from "node:path";
@@ -71134,10 +71272,10 @@ function tmpScreenshotDir(sigKey) {
71134
71272
  return join28(homedir24(), ".unbrowse", "tmp", sigKey);
71135
71273
  }
71136
71274
  function sha256HexBytes(bytes) {
71137
- return createHash23("sha256").update(bytes).digest("hex");
71275
+ return createHash24("sha256").update(bytes).digest("hex");
71138
71276
  }
71139
71277
  function urlHash323(url) {
71140
- return createHash23("sha256").update(url).digest("hex").slice(0, 32);
71278
+ return createHash24("sha256").update(url).digest("hex").slice(0, 32);
71141
71279
  }
71142
71280
  async function getCurrentUrlSafe2(conn, sessionId) {
71143
71281
  try {
@@ -71282,12 +71420,12 @@ var exports_text = {};
71282
71420
  __export(exports_text, {
71283
71421
  handler: () => handler24
71284
71422
  });
71285
- import { createHash as createHash24 } from "node:crypto";
71423
+ import { createHash as createHash25 } from "node:crypto";
71286
71424
  function urlHash324(s) {
71287
- return createHash24("sha256").update(s).digest("hex").slice(0, 32);
71425
+ return createHash25("sha256").update(s).digest("hex").slice(0, 32);
71288
71426
  }
71289
71427
  function selectorHashHex(selector) {
71290
- return createHash24("sha256").update(selector).digest("hex");
71428
+ return createHash25("sha256").update(selector).digest("hex");
71291
71429
  }
71292
71430
  async function handler24(parsed, opts) {
71293
71431
  const meta = lookupKindMap("eval", "text");
@@ -71387,9 +71525,9 @@ __export(exports_cookies2, {
71387
71525
  redactCookies: () => redactCookies,
71388
71526
  handler: () => handler25
71389
71527
  });
71390
- import { createHash as createHash25 } from "node:crypto";
71528
+ import { createHash as createHash26 } from "node:crypto";
71391
71529
  function urlHash325(s) {
71392
- return createHash25("sha256").update(s).digest("hex").slice(0, 32);
71530
+ return createHash26("sha256").update(s).digest("hex").slice(0, 32);
71393
71531
  }
71394
71532
  function redactCookies(raw) {
71395
71533
  return raw.map((c) => {
@@ -71603,7 +71741,7 @@ var exports_skills = {};
71603
71741
  __export(exports_skills, {
71604
71742
  handler: () => handler27
71605
71743
  });
71606
- import { createHash as createHash26, randomBytes as randomBytes12 } from "node:crypto";
71744
+ import { createHash as createHash27, randomBytes as randomBytes12 } from "node:crypto";
71607
71745
  function resolveApiBase4() {
71608
71746
  return process.env.UNBROWSE_API_URL ?? process.env.UNBROWSE_BACKEND_URL ?? DEFAULT_BACKEND_URL;
71609
71747
  }
@@ -71701,7 +71839,7 @@ async function handler27(parsed, opts) {
71701
71839
  }, ["op", "domain", "limit", "includeDeprecated", "nonce"]);
71702
71840
  const signed = await signBytes(new TextEncoder().encode(fragment));
71703
71841
  const signatureHex = bytesToHex12(signed.signature);
71704
- const cacheKey = createHash26("sha256").update(signed.signature).digest("hex").slice(0, 32);
71842
+ const cacheKey = createHash27("sha256").update(signed.signature).digest("hex").slice(0, 32);
71705
71843
  safeZero(signed.signature);
71706
71844
  const signedHeaders = {
71707
71845
  "x-wallet-pubkey": walletPubkey,
@@ -71805,7 +71943,7 @@ var exports_skill2 = {};
71805
71943
  __export(exports_skill2, {
71806
71944
  handler: () => handler28
71807
71945
  });
71808
- import { createHash as createHash27, randomBytes as randomBytes13 } from "node:crypto";
71946
+ import { createHash as createHash28, randomBytes as randomBytes13 } from "node:crypto";
71809
71947
  function resolveApiBase5() {
71810
71948
  return process.env.UNBROWSE_API_URL ?? process.env.UNBROWSE_BACKEND_URL ?? DEFAULT_BACKEND_URL;
71811
71949
  }
@@ -71873,7 +72011,7 @@ async function handler28(parsed, opts) {
71873
72011
  const fragment = canonicalizeSignedFragment({ op: "get_skill", skillId, nonce }, ["op", "skillId", "nonce"]);
71874
72012
  const signed = await signBytes(new TextEncoder().encode(fragment));
71875
72013
  const signatureHex = bytesToHex13(signed.signature);
71876
- const cacheKey = createHash27("sha256").update(signed.signature).digest("hex").slice(0, 32);
72014
+ const cacheKey = createHash28("sha256").update(signed.signature).digest("hex").slice(0, 32);
71877
72015
  safeZero(signed.signature);
71878
72016
  const signedHeaders = {
71879
72017
  "x-wallet-pubkey": walletPubkey,
@@ -71984,7 +72122,7 @@ var exports_earnings = {};
71984
72122
  __export(exports_earnings, {
71985
72123
  handler: () => handler29
71986
72124
  });
71987
- import { createHash as createHash28, randomBytes as randomBytes14 } from "node:crypto";
72125
+ import { createHash as createHash29, randomBytes as randomBytes14 } from "node:crypto";
71988
72126
  function resolveApiBase6() {
71989
72127
  return process.env.UNBROWSE_API_URL ?? process.env.UNBROWSE_BACKEND_URL ?? DEFAULT_BACKEND_URL;
71990
72128
  }
@@ -71998,7 +72136,7 @@ function bytesToBase6410(b) {
71998
72136
  return Buffer.from(b).toString("base64");
71999
72137
  }
72000
72138
  function deriveAgentId(walletPubkeyHex) {
72001
- return createHash28("sha256").update(walletPubkeyHex).digest("hex");
72139
+ return createHash29("sha256").update(walletPubkeyHex).digest("hex");
72002
72140
  }
72003
72141
  function domainFromSkillId(skillId, fallback) {
72004
72142
  if (typeof fallback === "string" && fallback.length > 0)
@@ -72052,7 +72190,7 @@ async function handler29(parsed, opts) {
72052
72190
  }, ["op", "agentId", "since", "nonce"]);
72053
72191
  const signed = await signBytes(new TextEncoder().encode(fragment));
72054
72192
  const signatureHex = bytesToHex14(signed.signature);
72055
- const cacheKey = createHash28("sha256").update(signed.signature).digest("hex").slice(0, 32);
72193
+ const cacheKey = createHash29("sha256").update(signed.signature).digest("hex").slice(0, 32);
72056
72194
  safeZero(signed.signature);
72057
72195
  headers["x-wallet-pubkey"] = walletPubkey;
72058
72196
  headers["x-stateless-nonce"] = nonce;
@@ -72176,7 +72314,7 @@ __export(exports_settings, {
72176
72314
  POINTER_PREFIX_REGEX: () => POINTER_PREFIX_REGEX
72177
72315
  });
72178
72316
  import { mkdir as mkdir6, readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
72179
- import { createHash as createHash29 } from "node:crypto";
72317
+ import { createHash as createHash30 } from "node:crypto";
72180
72318
  import { homedir as homedir25 } from "node:os";
72181
72319
  import { join as join29 } from "node:path";
72182
72320
  function resolveHome(override) {
@@ -72200,7 +72338,7 @@ function bytesToHex15(b) {
72200
72338
  return h;
72201
72339
  }
72202
72340
  function deriveSettingKeyHash(settingKey) {
72203
- return createHash29("sha256").update(settingKey, "utf8").digest("hex").slice(0, 32);
72341
+ return createHash30("sha256").update(settingKey, "utf8").digest("hex").slice(0, 32);
72204
72342
  }
72205
72343
  async function readSettings(home) {
72206
72344
  try {
@@ -72230,7 +72368,7 @@ function rejectionReasonStateless(settingKey, rawValue) {
72230
72368
  return null;
72231
72369
  }
72232
72370
  async function writeStash(cacheKey, record, home) {
72233
- const sigHash = cacheKey || createHash29("sha256").update(`${record.settingKey}:${record.settingValuePointer}:${record.written_at}`).digest("hex").slice(0, 32);
72371
+ const sigHash = cacheKey || createHash30("sha256").update(`${record.settingKey}:${record.settingValuePointer}:${record.written_at}`).digest("hex").slice(0, 32);
72234
72372
  const dir = join29(stashRoot(home), sigHash);
72235
72373
  await mkdir6(dir, { recursive: true });
72236
72374
  const path11 = join29(dir, "settings-stash.json");
@@ -74110,7 +74248,7 @@ __export(exports_spec, {
74110
74248
  emitEvalReadAuditSpec: () => emitEvalReadAuditSpec,
74111
74249
  domainHash32: () => domainHash32
74112
74250
  });
74113
- import { createHash as createHash30 } from "node:crypto";
74251
+ import { createHash as createHash31 } from "node:crypto";
74114
74252
  import { existsSync as existsSync25, mkdirSync as mkdirSync9, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "node:fs";
74115
74253
  import { homedir as homedir28 } from "node:os";
74116
74254
  import { join as join32 } from "node:path";
@@ -74248,7 +74386,7 @@ function firstHit(results) {
74248
74386
  return null;
74249
74387
  }
74250
74388
  function domainHash32(domain) {
74251
- return createHash30("sha256").update(domain.toLowerCase()).digest("hex").slice(0, 32);
74389
+ return createHash31("sha256").update(domain.toLowerCase()).digest("hex").slice(0, 32);
74252
74390
  }
74253
74391
  function specCacheDir() {
74254
74392
  return join32(homedir28(), ".unbrowse", "tmp", "spec-cache");
@@ -114544,7 +114682,7 @@ var init_publish_admission = __esm(() => {
114544
114682
  });
114545
114683
 
114546
114684
  // .tmp-runtime-src/telemetry.ts
114547
- import { createHash as createHash32 } from "node:crypto";
114685
+ import { createHash as createHash33 } from "node:crypto";
114548
114686
  import { existsSync as existsSync33, mkdirSync as mkdirSync15, writeFileSync as writeFileSync12 } from "node:fs";
114549
114687
  import { join as join37 } from "node:path";
114550
114688
  function getTraceDir() {
@@ -114554,7 +114692,7 @@ function isTracingEnabled() {
114554
114692
  return process.env.UNBROWSE_DISABLE_TRACES !== "1";
114555
114693
  }
114556
114694
  function hashValue(value) {
114557
- return createHash32("sha256").update(value).digest("hex").slice(0, 16);
114695
+ return createHash33("sha256").update(value).digest("hex").slice(0, 16);
114558
114696
  }
114559
114697
  function isSensitiveName(name) {
114560
114698
  return SENSITIVE_PATTERNS.some((re) => re.test(name));
@@ -114572,7 +114710,7 @@ function anonymizeUrl(url) {
114572
114710
  }
114573
114711
  function hashResponseBody(result) {
114574
114712
  const str = typeof result === "string" ? result : JSON.stringify(result ?? "");
114575
- return createHash32("sha256").update(str).digest("hex").slice(0, 32);
114713
+ return createHash33("sha256").update(str).digest("hex").slice(0, 32);
114576
114714
  }
114577
114715
  function classifyFailure2(error) {
114578
114716
  if (!error)
@@ -161831,6 +161969,78 @@ var init_probe = __esm(() => {
161831
161969
  HTML_LIKE = /text\/html|application\/xhtml\+xml/i;
161832
161970
  });
161833
161971
 
161972
+ // .tmp-runtime-src/proof/commitment.ts
161973
+ import { createHash as createHash34 } from "crypto";
161974
+ function hashResponseBody2(body) {
161975
+ const hash = createHash34("sha256").update(body ?? "").digest("hex");
161976
+ return `sha256:${hash}`;
161977
+ }
161978
+ var init_commitment = () => {};
161979
+
161980
+ // .tmp-runtime-src/lib/write-receipt.ts
161981
+ var exports_write_receipt = {};
161982
+ __export(exports_write_receipt, {
161983
+ yieldsFromResponse: () => yieldsFromResponse,
161984
+ buildWriteReceipt: () => buildWriteReceipt,
161985
+ bindingsFromBody: () => bindingsFromBody
161986
+ });
161987
+ function bindingsFromBody(body) {
161988
+ if (!body || typeof body !== "object" || Array.isArray(body))
161989
+ return [];
161990
+ const out = [];
161991
+ for (const [k, v] of Object.entries(body)) {
161992
+ const sensitive = isSensitiveFieldName(k);
161993
+ out.push({
161994
+ key: k,
161995
+ required: true,
161996
+ source: "body",
161997
+ ...sensitive ? { semantic_type: "secret", example_value: commitValue(String(v)) } : typeof v === "string" || typeof v === "number" || typeof v === "boolean" ? { example_value: String(v) } : {}
161998
+ });
161999
+ }
162000
+ return out;
162001
+ }
162002
+ function yieldsFromResponse(responseBody) {
162003
+ let obj = responseBody;
162004
+ if (typeof responseBody === "string") {
162005
+ try {
162006
+ obj = JSON.parse(responseBody);
162007
+ } catch {
162008
+ return [];
162009
+ }
162010
+ }
162011
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
162012
+ const rec = obj;
162013
+ const inner = rec.data ?? rec.json ?? rec.result;
162014
+ if (inner && typeof inner === "object" && !Array.isArray(inner))
162015
+ obj = inner;
162016
+ }
162017
+ if (!obj || typeof obj !== "object" || Array.isArray(obj))
162018
+ return [];
162019
+ const out = [];
162020
+ for (const [k, v] of Object.entries(obj)) {
162021
+ if (ID_KEY.test(k) && (typeof v === "string" || typeof v === "number")) {
162022
+ out.push({ key: k, source: "response", semantic_type: "resource_id", example_value: String(v) });
162023
+ }
162024
+ }
162025
+ return out;
162026
+ }
162027
+ function buildWriteReceipt(input2) {
162028
+ const { commitments } = censorInputBody(input2.body ?? {});
162029
+ return {
162030
+ claim: input2.intent?.trim() || `${input2.method.toUpperCase()} ${input2.url}`,
162031
+ input_commitments: commitments,
162032
+ response_commitment: hashResponseBody2(typeof input2.responseBody === "string" ? input2.responseBody : input2.responseBody == null ? "" : JSON.stringify(input2.responseBody)),
162033
+ requires: bindingsFromBody(input2.body),
162034
+ provides: yieldsFromResponse(input2.responseBody)
162035
+ };
162036
+ }
162037
+ var ID_KEY;
162038
+ var init_write_receipt = __esm(() => {
162039
+ init_input_censor();
162040
+ init_commitment();
162041
+ ID_KEY = /^(id|uuid|_id|.+_id|.+Id|slug|key|name)$/;
162042
+ });
162043
+
161834
162044
  // .tmp-runtime-src/execution/captcha-solve.ts
161835
162045
  function isCaptchaVendor(vendor) {
161836
162046
  if (!vendor)
@@ -169979,13 +170189,14 @@ __export(exports_execution, {
169979
170189
  buildStructuredReplayHeaders: () => buildStructuredReplayHeaders,
169980
170190
  buildPageFetchEndpoint: () => buildPageFetchEndpoint,
169981
170191
  buildPageArtifactCapture: () => buildPageArtifactCapture,
169982
- buildGraphqlRequestParams: () => buildGraphqlRequestParams
170192
+ buildGraphqlRequestParams: () => buildGraphqlRequestParams,
170193
+ buildAdhocWriteEndpoint: () => buildAdhocWriteEndpoint
169983
170194
  });
169984
- import { createHash as createHash33 } from "node:crypto";
170195
+ import { createHash as createHash35 } from "node:crypto";
169985
170196
  function stableEndpointId(method, urlTemplate) {
169986
170197
  if (!method || !urlTemplate)
169987
170198
  return nanoid();
169988
- return createHash33("sha256").update(`${method}:${urlTemplate}`).digest("base64url").slice(0, 21);
170199
+ return createHash35("sha256").update(`${method}:${urlTemplate}`).digest("base64url").slice(0, 21);
169989
170200
  }
169990
170201
  function stampTrace(trace) {
169991
170202
  trace.trace_version = TRACE_VERSION;
@@ -170556,6 +170767,27 @@ function buildPageFetchEndpoint(url, intent, authRequired = false) {
170556
170767
  }
170557
170768
  };
170558
170769
  }
170770
+ function buildAdhocWriteEndpoint(url, method, body) {
170771
+ const m = method.toUpperCase();
170772
+ return {
170773
+ endpoint_id: stableEndpointId(m, url + "#adhoc_write"),
170774
+ method: m,
170775
+ url_template: url,
170776
+ idempotency: "unsafe",
170777
+ verification_status: "unverified",
170778
+ reliability_score: 0.5,
170779
+ description: `Ad-hoc ${m} to ${url}`,
170780
+ ...body !== undefined && body !== null ? { body } : {},
170781
+ trigger_url: url,
170782
+ semantic: {
170783
+ action_kind: "write",
170784
+ resource_kind: "record",
170785
+ description_in: `Sends a ${m} request to ${url}`,
170786
+ description_out: `Returns the ${url} write response`,
170787
+ ...body && typeof body === "object" && !Array.isArray(body) ? { requires: bindingsFromBody(body) } : {}
170788
+ }
170789
+ };
170790
+ }
170559
170791
  function derivePublicApiEndpointsFromUrl(url, intent, authRequired = false) {
170560
170792
  try {
170561
170793
  const u = new URL(url);
@@ -172721,6 +172953,12 @@ async function executeEndpoint(skill, endpoint, params = {}, projection, options
172721
172953
  workflowChosenStrategy = workflowChosenStrategy ?? "server";
172722
172954
  recipeMatched = true;
172723
172955
  }
172956
+ if (!recipeMatched && endpoint.method !== "GET" && endpoint.method !== "HEAD" && endpoint.method !== "OPTIONS") {
172957
+ result = await serverFetch(workflowBindings?.extraHeaders, workflowBindings?.bodyOverride);
172958
+ decisionTrace.push({ step: "server_fetch", status: result.status, write_method: endpoint.method });
172959
+ workflowChosenStrategy = workflowChosenStrategy ?? "server";
172960
+ recipeMatched = true;
172961
+ }
172724
172962
  if (!recipeMatched) {
172725
172963
  const probeCookies = cookies.map((c) => ({ name: c.name, value: c.value }));
172726
172964
  const probe = await probeUrl(url, {
@@ -173506,7 +173744,8 @@ async function executeEndpoint(skill, endpoint, params = {}, projection, options
173506
173744
  trace.result = data2;
173507
173745
  }
173508
173746
  }
173509
- if (trace.success && effectiveIntent && data2 != null) {
173747
+ const isWriteEndpoint = ["POST", "PUT", "PATCH", "DELETE"].includes(String(endpoint.method ?? "").toUpperCase()) || endpoint.semantic?.action_kind === "write";
173748
+ if (trace.success && effectiveIntent && data2 != null && !isWriteEndpoint) {
173510
173749
  const semanticAssessment = assessIntentResult(data2, effectiveIntent);
173511
173750
  const tinyCheck = semanticAssessment.verdict === "pass" ? { tiny: false } : looksLikeTinyContentReadResult(data2, effectiveIntent);
173512
173751
  if (tinyCheck.tiny) {
@@ -173529,6 +173768,16 @@ async function executeEndpoint(skill, endpoint, params = {}, projection, options
173529
173768
  trace.steps?.push({ step: "extraction_too_thin_gate", reason: tinyCheck.reason });
173530
173769
  }
173531
173770
  }
173771
+ if (trace.success && isWriteEndpoint && data2 != null) {
173772
+ try {
173773
+ const provides = yieldsFromResponse(data2);
173774
+ if (provides.length > 0) {
173775
+ endpoint.semantic = { ...endpoint.semantic ?? { action_kind: "write", resource_kind: "record" }, provides };
173776
+ trace.steps?.push({ step: "write_yields_registered", keys: provides.map((b) => b.key) });
173777
+ cachePublishedSkill(skill, options?.client_scope);
173778
+ }
173779
+ } catch {}
173780
+ }
173532
173781
  if (trace.success && !endpoint.response_schema && data2 != null && typeof data2 !== "string") {
173533
173782
  try {
173534
173783
  const inferred = inferSchema([data2]);
@@ -175229,6 +175478,7 @@ var init_execution = __esm(async () => {
175229
175478
  init_eviction_strikes();
175230
175479
  init_retry();
175231
175480
  init_probe();
175481
+ init_write_receipt();
175232
175482
  init_captcha_solve();
175233
175483
  init_dag_feedback();
175234
175484
  init_nanoid();
@@ -176058,9 +176308,9 @@ var init_pre_resolve_gate = __esm(() => {
176058
176308
  });
176059
176309
 
176060
176310
  // .tmp-runtime-src/routing-telemetry.ts
176061
- import { createHash as createHash34 } from "node:crypto";
176311
+ import { createHash as createHash36 } from "node:crypto";
176062
176312
  function stableHash(value) {
176063
- return createHash34("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 24);
176313
+ return createHash36("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 24);
176064
176314
  }
176065
176315
  function sanitizeScalar(value) {
176066
176316
  if (value == null)
@@ -177481,7 +177731,7 @@ var init_mount = __esm(() => {
177481
177731
  // .tmp-runtime-src/orchestrator/index.ts
177482
177732
  import { existsSync as existsSync38, writeFileSync as writeFileSync18, readFileSync as readFileSync26, mkdirSync as mkdirSync21, readdirSync as readdirSync10 } from "node:fs";
177483
177733
  import { dirname as dirname9, join as join45 } from "node:path";
177484
- import { createHash as createHash35 } from "node:crypto";
177734
+ import { createHash as createHash37 } from "node:crypto";
177485
177735
  function artifactResultWithShortlist(artifact, skillId, triggerUrl) {
177486
177736
  const ep = artifact.endpoint;
177487
177737
  const res = artifact.result;
@@ -177636,7 +177886,7 @@ function scopedResolveCacheKeys(scope, key2) {
177636
177886
  return scope === "global" ? [scopedCacheKey("global", key2)] : [scopedCacheKey(scope, key2), scopedCacheKey("global", key2)];
177637
177887
  }
177638
177888
  function snapshotPathForCacheKey(cacheKey2) {
177639
- const digest = createHash35("sha1").update(cacheKey2).digest("hex");
177889
+ const digest = createHash37("sha1").update(cacheKey2).digest("hex");
177640
177890
  return join45(SKILL_SNAPSHOT_DIR, `${digest}.json`);
177641
177891
  }
177642
177892
  function writeSkillSnapshot(cacheKey2, skill) {
@@ -177663,11 +177913,11 @@ function compositeAddress(domain, target, steps, edges) {
177663
177913
  `steps:${steps.map((s) => s.endpoint_id).join(">")}`,
177664
177914
  `edges:${edges.map((e) => `${e.from}.${e.binding}->${e.to}`).sort().join("|")}`
177665
177915
  ].join("::");
177666
- return `composite:${createHash35("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
177916
+ return `composite:${createHash37("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
177667
177917
  }
177668
177918
  function compositeLookupKey(domain, target) {
177669
177919
  const canonical2 = `domain:${domain}::target:${target}`;
177670
- return `lookup:${createHash35("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
177920
+ return `lookup:${createHash37("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
177671
177921
  }
177672
177922
  function compositeFilePath(lookupKey2) {
177673
177923
  return join45(compositeSnapshotDir(), `${lookupKey2.replace(/[^a-z0-9]/gi, "_")}.json`);
@@ -180076,7 +180326,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
180076
180326
  const persisted = findCompositeInSkill(skill, candidate.endpoint.endpoint_id) ?? readComposite(replayDomain, candidate.endpoint.endpoint_id);
180077
180327
  const decision = planPrereqOrder(prereqOrder, persisted, (id) => {
180078
180328
  const ep = skill.endpoints.find((e) => e.endpoint_id === id);
180079
- return ep != null && canAutoExecuteEndpoint(ep);
180329
+ return ep != null && ep.verification_status !== "disabled" && canAutoExecuteEndpoint(ep);
180080
180330
  });
180081
180331
  prereqOrder = decision.prereqOrder;
180082
180332
  replayedCompositeId = decision.replayedCompositeId;
@@ -184665,12 +184915,12 @@ var init_agent_augment = __esm(() => {
184665
184915
  });
184666
184916
 
184667
184917
  // .tmp-runtime-src/api/browse-index.ts
184668
- import { createHash as createHash36 } from "node:crypto";
184918
+ import { createHash as createHash38 } from "node:crypto";
184669
184919
  import { readFileSync as readFileSync30 } from "node:fs";
184670
184920
  function stableEndpointId2(method, urlTemplate) {
184671
184921
  if (!method || !urlTemplate)
184672
184922
  return nanoid();
184673
- return createHash36("sha256").update(`${method}:${urlTemplate}`).digest("base64url").slice(0, 21);
184923
+ return createHash38("sha256").update(`${method}:${urlTemplate}`).digest("base64url").slice(0, 21);
184674
184924
  }
184675
184925
  function normalizeBrowseUrl(url, baseUrl) {
184676
184926
  if (!url)
@@ -187074,6 +187324,275 @@ var init_skillmd = __esm(() => {
187074
187324
  ];
187075
187325
  });
187076
187326
 
187327
+ // .tmp-runtime-src/runtime/yield-store.ts
187328
+ var exports_yield_store = {};
187329
+ __export(exports_yield_store, {
187330
+ recordYields: () => recordYields,
187331
+ isYieldStale: () => isYieldStale,
187332
+ getYieldCache: () => getYieldCache,
187333
+ fillHolesFromYields: () => fillHolesFromYields,
187334
+ clearSessionYields: () => clearSessionYields
187335
+ });
187336
+ import { existsSync as existsSync43, mkdirSync as mkdirSync25, readFileSync as readFileSync32, writeFileSync as writeFileSync22, unlinkSync as unlinkSync7 } from "node:fs";
187337
+ import os11 from "node:os";
187338
+ import path18 from "node:path";
187339
+ function configDir() {
187340
+ return process.env.UNBROWSE_CONFIG_DIR || path18.join(process.env.HOME || os11.homedir(), ".unbrowse");
187341
+ }
187342
+ function yieldSessionDir() {
187343
+ return path18.join(configDir(), "yield-sessions");
187344
+ }
187345
+ function isSafeSessionId(id) {
187346
+ return typeof id === "string" && id.length > 0 && id.length <= 200 && /^[A-Za-z0-9._@:-]+$/.test(id);
187347
+ }
187348
+ function sessionFile(sessionId) {
187349
+ const safe2 = Buffer.from(sessionId).toString("base64url").slice(0, 120);
187350
+ return path18.join(yieldSessionDir(), `${safe2}.json`);
187351
+ }
187352
+ function persistSession(sessionId, cache) {
187353
+ if (!isSafeSessionId(sessionId))
187354
+ return;
187355
+ try {
187356
+ const dir = yieldSessionDir();
187357
+ if (!existsSync43(dir))
187358
+ mkdirSync25(dir, { recursive: true });
187359
+ const entries = [];
187360
+ for (const [k, y] of cache.entries()) {
187361
+ if (y.sensitive) {
187362
+ entries.push([k, { value: commitValue(String(y.value)), observed_at: y.observed_at, committed: true, ...y.ttl_ms ? { ttl_ms: y.ttl_ms } : {}, ...y.single_use ? { single_use: true } : {} }]);
187363
+ } else {
187364
+ entries.push([k, y]);
187365
+ }
187366
+ }
187367
+ writeFileSync22(sessionFile(sessionId), JSON.stringify({ v: 1, entries }), "utf-8");
187368
+ } catch {}
187369
+ }
187370
+ function loadSession(sessionId) {
187371
+ if (!isSafeSessionId(sessionId))
187372
+ return null;
187373
+ try {
187374
+ const raw = readFileSync32(sessionFile(sessionId), "utf-8");
187375
+ const parsed = JSON.parse(raw);
187376
+ if (!Array.isArray(parsed.entries))
187377
+ return null;
187378
+ return new Map(parsed.entries);
187379
+ } catch {
187380
+ return null;
187381
+ }
187382
+ }
187383
+ function cacheFor(sessionId, store) {
187384
+ let cache = store.get(sessionId);
187385
+ if (!cache) {
187386
+ cache = (store === moduleStore ? loadSession(sessionId) : null) ?? new Map;
187387
+ store.set(sessionId, cache);
187388
+ }
187389
+ return cache;
187390
+ }
187391
+ function scopedKey(key2, scope) {
187392
+ return scope ? `${scope.length}:${scope}:${key2}` : key2;
187393
+ }
187394
+ function isYieldStale(y, nowMs) {
187395
+ if (typeof y.ttl_ms !== "number")
187396
+ return false;
187397
+ const observed = Date.parse(y.observed_at);
187398
+ if (!Number.isFinite(observed))
187399
+ return false;
187400
+ return nowMs - observed > y.ttl_ms;
187401
+ }
187402
+ function recordYields(sessionId, provides, opts) {
187403
+ if (!sessionId || !Array.isArray(provides) || provides.length === 0)
187404
+ return 0;
187405
+ const store = opts?.store ?? moduleStore;
187406
+ const nowIso = opts?.nowIso ?? new Date().toISOString();
187407
+ const cache = cacheFor(sessionId, store);
187408
+ let n = 0;
187409
+ for (const b of provides) {
187410
+ if (!b?.key || b.example_value === undefined)
187411
+ continue;
187412
+ cache.set(scopedKey(b.key, opts?.scope), {
187413
+ value: b.example_value,
187414
+ observed_at: b.observed_at ?? nowIso,
187415
+ ...typeof b.ttl_ms === "number" ? { ttl_ms: b.ttl_ms } : {},
187416
+ ...b.single_use ? { single_use: true } : {},
187417
+ ...isSensitiveFieldName(b.key) ? { sensitive: true } : {}
187418
+ });
187419
+ n++;
187420
+ }
187421
+ if (store === moduleStore && n > 0)
187422
+ persistSession(sessionId, cache);
187423
+ return n;
187424
+ }
187425
+ function getYieldCache(sessionId, opts) {
187426
+ const store = opts?.store ?? moduleStore;
187427
+ const inMem = store.get(sessionId);
187428
+ if (inMem)
187429
+ return inMem;
187430
+ if (store === moduleStore) {
187431
+ const loaded = loadSession(sessionId);
187432
+ if (loaded) {
187433
+ store.set(sessionId, loaded);
187434
+ return loaded;
187435
+ }
187436
+ }
187437
+ return;
187438
+ }
187439
+ function fillHolesFromYields(sessionId, requires, params, opts) {
187440
+ const filled = [];
187441
+ if (!sessionId || !Array.isArray(requires) || requires.length === 0)
187442
+ return { filled, params };
187443
+ const store = opts?.store ?? moduleStore;
187444
+ const cache = store.get(sessionId) ?? (store === moduleStore ? loadSession(sessionId) ?? undefined : undefined);
187445
+ if (!cache)
187446
+ return { filled, params };
187447
+ if (store === moduleStore && !store.get(sessionId))
187448
+ store.set(sessionId, cache);
187449
+ const nowMs = opts?.nowMs ?? Date.now();
187450
+ let consumed = false;
187451
+ for (const b of requires) {
187452
+ if (!b?.key)
187453
+ continue;
187454
+ if (params[b.key] !== undefined && params[b.key] !== null)
187455
+ continue;
187456
+ const ck = scopedKey(b.key, opts?.scope);
187457
+ const y = cache.get(ck);
187458
+ if (!y || isYieldStale(y, nowMs))
187459
+ continue;
187460
+ if (y.committed)
187461
+ continue;
187462
+ params[b.key] = y.value;
187463
+ filled.push(b.key);
187464
+ if (y.single_use) {
187465
+ cache.delete(ck);
187466
+ consumed = true;
187467
+ }
187468
+ }
187469
+ if (consumed && store === moduleStore)
187470
+ persistSession(sessionId, cache);
187471
+ return { filled, params };
187472
+ }
187473
+ function clearSessionYields(sessionId, opts) {
187474
+ const store = opts?.store ?? moduleStore;
187475
+ store.delete(sessionId);
187476
+ if (store === moduleStore && isSafeSessionId(sessionId)) {
187477
+ try {
187478
+ if (existsSync43(sessionFile(sessionId)))
187479
+ unlinkSync7(sessionFile(sessionId));
187480
+ } catch {}
187481
+ }
187482
+ }
187483
+ var moduleStore;
187484
+ var init_yield_store = __esm(() => {
187485
+ init_input_censor();
187486
+ moduleStore = new Map;
187487
+ });
187488
+
187489
+ // .tmp-runtime-src/lib/graph-core/cross-skill-index.ts
187490
+ var exports_cross_skill_index = {};
187491
+ __export(exports_cross_skill_index, {
187492
+ suggestCrossSkillProducers: () => suggestCrossSkillProducers,
187493
+ resolveProducersForHole: () => resolveProducersForHole,
187494
+ buildGlobalProducerIndexFromCache: () => buildGlobalProducerIndexFromCache,
187495
+ buildGlobalProducerIndex: () => buildGlobalProducerIndex,
187496
+ bindingIdentityKey: () => bindingIdentityKey
187497
+ });
187498
+ function normEntity(e) {
187499
+ const k = e.toLowerCase();
187500
+ return ENTITY_ALIASES[k] ?? k;
187501
+ }
187502
+ function bindingIdentityKey(key2, resourceKind) {
187503
+ const raw = String(key2 ?? "").trim();
187504
+ if (!raw)
187505
+ return "::";
187506
+ const m = raw.match(/^([A-Za-z][A-Za-z0-9]*?)[_]?(id|ids|uuid|guid|slug|key)$/i);
187507
+ if (m && m[1] && m[1].toLowerCase() !== m[2].toLowerCase()) {
187508
+ const field = m[2].toLowerCase() === "ids" ? "id" : m[2].toLowerCase();
187509
+ return `${normEntity(m[1])}::${field}`;
187510
+ }
187511
+ if (ID_FIELD.test(raw) && resourceKind) {
187512
+ return `${normEntity(resourceKind)}::${raw.toLowerCase()}`;
187513
+ }
187514
+ return `${resourceKind ? normEntity(resourceKind) : ""}::${raw.toLowerCase()}`;
187515
+ }
187516
+ function endpointResourceKind(ep) {
187517
+ return ep.semantic?.resource_kind;
187518
+ }
187519
+ function buildGlobalProducerIndex(skills) {
187520
+ const byIdentity = new Map;
187521
+ for (const skill of skills ?? []) {
187522
+ if (!skill?.endpoints)
187523
+ continue;
187524
+ for (const ep of skill.endpoints) {
187525
+ const rk = endpointResourceKind(ep);
187526
+ const provides = ep.semantic?.provides ?? [];
187527
+ for (const b of provides) {
187528
+ if (!b?.key)
187529
+ continue;
187530
+ const identity = bindingIdentityKey(b.key, rk);
187531
+ const producer = {
187532
+ skill_id: skill.skill_id,
187533
+ endpoint_id: ep.endpoint_id,
187534
+ binding_key: b.key,
187535
+ identity,
187536
+ semantic_type: b.semantic_type,
187537
+ resource_kind: rk
187538
+ };
187539
+ const list = byIdentity.get(identity) ?? [];
187540
+ list.push(producer);
187541
+ byIdentity.set(identity, list);
187542
+ }
187543
+ }
187544
+ }
187545
+ return { byIdentity };
187546
+ }
187547
+ function resolveProducersForHole(index2, hole, consumerResourceKind, opts) {
187548
+ if (!hole?.key)
187549
+ return [];
187550
+ const identity = bindingIdentityKey(hole.key, consumerResourceKind);
187551
+ const all = index2.byIdentity.get(identity) ?? [];
187552
+ if (opts?.includeSameSkill)
187553
+ return [...all];
187554
+ const exclude = opts?.excludeSkillId;
187555
+ return exclude ? all.filter((p) => p.skill_id !== exclude) : [...all];
187556
+ }
187557
+ async function buildGlobalProducerIndexFromCache() {
187558
+ try {
187559
+ const { listLocalSkills: listLocalSkills2 } = await Promise.resolve().then(() => (init_client(), exports_client));
187560
+ return buildGlobalProducerIndex(listLocalSkills2());
187561
+ } catch {
187562
+ return { byIdentity: new Map };
187563
+ }
187564
+ }
187565
+ function suggestCrossSkillProducers(endpointRequires, filledParams, consumerResourceKind, consumerSkillId, index2) {
187566
+ const out = [];
187567
+ for (const b of endpointRequires ?? []) {
187568
+ if (!b?.key)
187569
+ continue;
187570
+ if (filledParams[b.key] !== undefined && filledParams[b.key] !== null)
187571
+ continue;
187572
+ const producers = resolveProducersForHole(index2, b, consumerResourceKind, { excludeSkillId: consumerSkillId });
187573
+ if (producers.length)
187574
+ out.push({ hole: b.key, producers });
187575
+ }
187576
+ return out;
187577
+ }
187578
+ var ENTITY_ALIASES, ID_FIELD;
187579
+ var init_cross_skill_index = __esm(() => {
187580
+ ENTITY_ALIASES = {
187581
+ repo: "repository",
187582
+ repository: "repository",
187583
+ org: "organization",
187584
+ organisation: "organization",
187585
+ organization: "organization",
187586
+ user: "user",
187587
+ account: "user",
187588
+ post: "post",
187589
+ posts: "post",
187590
+ comment: "comment",
187591
+ comments: "comment"
187592
+ };
187593
+ ID_FIELD = /^(id|uuid|guid|slug|key|number|no)$/i;
187594
+ });
187595
+
187077
187596
  // .tmp-runtime-src/api/routes.ts
187078
187597
  var exports_routes = {};
187079
187598
  __export(exports_routes, {
@@ -187086,10 +187605,10 @@ __export(exports_routes, {
187086
187605
  buildAnalyticsSessionPayload: () => buildAnalyticsSessionPayload,
187087
187606
  __clearBrowseSessionsForTest: () => __clearBrowseSessionsForTest
187088
187607
  });
187089
- import * as os11 from "os";
187090
- import * as path18 from "path";
187091
- import { readdirSync as readdirSync13, readFileSync as readFileSync32 } from "fs";
187092
- import { writeFileSync as writeFileSync22, existsSync as existsSync43, mkdirSync as mkdirSync25 } from "fs";
187608
+ import * as os12 from "os";
187609
+ import * as path19 from "path";
187610
+ import { readdirSync as readdirSync13, readFileSync as readFileSync33 } from "fs";
187611
+ import { writeFileSync as writeFileSync23, existsSync as existsSync44, mkdirSync as mkdirSync26 } from "fs";
187093
187612
  import { join as join54 } from "path";
187094
187613
  function browseBrokerMax() {
187095
187614
  const n = Number(process.env.KURI_MULTI_BROKER_MAX ?? "1");
@@ -187554,12 +188073,12 @@ async function registerRoutes(app) {
187554
188073
  next_step: "Not paired yet. Run `unbrowse setup` to register an agent. Earnings start accruing once you publish a skill that other agents execute."
187555
188074
  });
187556
188075
  }
187557
- const fetchJson = async (path19) => {
188076
+ const fetchJson = async (path20) => {
187558
188077
  try {
187559
188078
  const headers = {};
187560
188079
  if (apiKey)
187561
188080
  headers.Authorization = `Bearer ${apiKey}`;
187562
- const res = await fetch(`${BETA_API_URL}${path19}`, { headers });
188081
+ const res = await fetch(`${BETA_API_URL}${path20}`, { headers });
187563
188082
  if (!res.ok)
187564
188083
  return null;
187565
188084
  return await res.json();
@@ -187814,20 +188333,20 @@ async function registerRoutes(app) {
187814
188333
  });
187815
188334
  app.get("/v1/trace/:trace_id", async (req, reply) => {
187816
188335
  const { trace_id } = req.params;
187817
- const traceDir = path18.join(process.env.UNBROWSE_TRACE_DIR ?? path18.join(os11.homedir(), ".unbrowse", "traces"));
188336
+ const traceDir = path19.join(process.env.UNBROWSE_TRACE_DIR ?? path19.join(os12.homedir(), ".unbrowse", "traces"));
187818
188337
  if (trace_id === "latest") {
187819
188338
  try {
187820
188339
  const files = readdirSync13(traceDir).filter((f) => f.endsWith(".json")).sort().reverse();
187821
188340
  if (files.length === 0)
187822
188341
  return reply.send({ message: "No traces found", trace_id: "latest" });
187823
- const trace = JSON.parse(readFileSync32(join54(traceDir, files[0]), "utf-8"));
188342
+ const trace = JSON.parse(readFileSync33(join54(traceDir, files[0]), "utf-8"));
187824
188343
  return reply.send({ trace_id: "latest", ...trace });
187825
188344
  } catch {
187826
188345
  return reply.send({ message: "No traces found (trace directory may not exist yet)", trace_id: "latest" });
187827
188346
  }
187828
188347
  }
187829
188348
  try {
187830
- const trace = JSON.parse(readFileSync32(join54(traceDir, `${trace_id}.json`), "utf-8"));
188349
+ const trace = JSON.parse(readFileSync33(join54(traceDir, `${trace_id}.json`), "utf-8"));
187831
188350
  return reply.send({ trace_id, ...trace });
187832
188351
  } catch {
187833
188352
  return reply.code(404).send({ error: `Trace ${trace_id} not found` });
@@ -187938,13 +188457,13 @@ async function registerRoutes(app) {
187938
188457
  const ms = Date.now() - t0;
187939
188458
  if (learned && endpoints.length > 0) {
187940
188459
  const cacheKey2 = buildResolveCacheKey(learned.domain, intent, url);
187941
- const scopedKey = scopedCacheKey(clientScope, cacheKey2);
187942
- writeSkillSnapshot(scopedKey, learned);
188460
+ const scopedKey2 = scopedCacheKey(clientScope, cacheKey2);
188461
+ writeSkillSnapshot(scopedKey2, learned);
187943
188462
  const domainKey = getDomainReuseKey(url ?? learned.domain);
187944
188463
  if (domainKey) {
187945
188464
  domainSkillCache.set(domainKey, {
187946
188465
  skillId: learned.skill_id,
187947
- localSkillPath: snapshotPathForCacheKey(scopedKey),
188466
+ localSkillPath: snapshotPathForCacheKey(scopedKey2),
187948
188467
  ts: Date.now()
187949
188468
  });
187950
188469
  persistDomainCache();
@@ -188019,9 +188538,9 @@ async function registerRoutes(app) {
188019
188538
  });
188020
188539
  app.get("/v1/skills", async (req, reply) => {
188021
188540
  const fs7 = __require("fs");
188022
- const path19 = __require("path");
188023
- const os12 = __require("os");
188024
- const cacheDir = process.env.UNBROWSE_SKILL_CACHE_DIR || path19.join(process.env.UNBROWSE_CONFIG_DIR || path19.join(os12.homedir(), ".unbrowse"), "skill-cache");
188541
+ const path20 = __require("path");
188542
+ const os13 = __require("os");
188543
+ const cacheDir = process.env.UNBROWSE_SKILL_CACHE_DIR || path20.join(process.env.UNBROWSE_CONFIG_DIR || path20.join(os13.homedir(), ".unbrowse"), "skill-cache");
188025
188544
  const summaries = [];
188026
188545
  const seen = new Set;
188027
188546
  try {
@@ -188030,7 +188549,7 @@ async function registerRoutes(app) {
188030
188549
  if (!entry.endsWith(".json"))
188031
188550
  continue;
188032
188551
  try {
188033
- const raw = JSON.parse(fs7.readFileSync(path19.join(cacheDir, entry), "utf-8"));
188552
+ const raw = JSON.parse(fs7.readFileSync(path20.join(cacheDir, entry), "utf-8"));
188034
188553
  if (!raw.skill_id || seen.has(raw.skill_id))
188035
188554
  continue;
188036
188555
  seen.add(raw.skill_id);
@@ -188402,21 +188921,21 @@ async function registerRoutes(app) {
188402
188921
  if (!skill_id)
188403
188922
  return reply.code(400).send({ error: "skill_id required" });
188404
188923
  const { join: join55 } = await import("node:path");
188405
- const { existsSync: existsSync44, readFileSync: readFileSync33, readdirSync: readdirSync14 } = await import("node:fs");
188924
+ const { existsSync: existsSync45, readFileSync: readFileSync34, readdirSync: readdirSync14 } = await import("node:fs");
188406
188925
  const { homedir: homedir42 } = await import("node:os");
188407
188926
  let skill = null;
188408
188927
  try {
188409
188928
  const cacheDir = process.env.UNBROWSE_SKILL_CACHE_DIR || join55(process.env.UNBROWSE_CONFIG_DIR || join55(homedir42(), ".unbrowse"), "skill-cache");
188410
- if (existsSync44(cacheDir)) {
188929
+ if (existsSync45(cacheDir)) {
188411
188930
  const direct = join55(cacheDir, `${skill_id}.json`);
188412
- if (existsSync44(direct))
188413
- skill = JSON.parse(readFileSync33(direct, "utf-8"));
188931
+ if (existsSync45(direct))
188932
+ skill = JSON.parse(readFileSync34(direct, "utf-8"));
188414
188933
  if (!skill) {
188415
188934
  for (const f of readdirSync14(cacheDir)) {
188416
188935
  if (!f.endsWith(".json"))
188417
188936
  continue;
188418
188937
  try {
188419
- const s = JSON.parse(readFileSync33(join55(cacheDir, f), "utf-8"));
188938
+ const s = JSON.parse(readFileSync34(join55(cacheDir, f), "utf-8"));
188420
188939
  if (s.skill_id === skill_id) {
188421
188940
  skill = s;
188422
188941
  break;
@@ -188546,7 +189065,7 @@ async function registerRoutes(app) {
188546
189065
  app.post("/v1/skills/:skill_id/execute", { config: { rateLimit: ROUTE_LIMITS["/v1/skills/:skill_id/execute"] } }, async (req, reply) => {
188547
189066
  const clientScope = clientScopeFor(req);
188548
189067
  const { skill_id } = req.params;
188549
- const { params, projection, confirm_unsafe, confirm_third_party_terms, dry_run, intent, context_url } = req.body;
189068
+ const { params, projection, confirm_unsafe, confirm_third_party_terms, dry_run, intent, context_url, session_id } = req.body;
188550
189069
  let skill = getRecentLocalSkill(skill_id, clientScope);
188551
189070
  if (!skill) {
188552
189071
  const { findExistingSkillForDomain: findLocal } = await Promise.resolve().then(() => (init_client(), exports_client));
@@ -188561,16 +189080,92 @@ async function registerRoutes(app) {
188561
189080
  }
188562
189081
  if (!skill)
188563
189082
  skill = await getSkill2(skill_id, clientScope);
189083
+ let adhocWrite = false;
189084
+ let adhocEndpointId;
189085
+ {
189086
+ const reqMethod = typeof req.body?.method === "string" ? String(req.body.method).toUpperCase() : undefined;
189087
+ const adhocUrl = context_url ?? (typeof params?.url === "string" ? params.url : undefined);
189088
+ if (reqMethod && adhocUrl && (reqMethod === "POST" || reqMethod === "PUT" || reqMethod === "PATCH" || reqMethod === "DELETE")) {
189089
+ const { buildAdhocWriteEndpoint: buildAdhocWriteEndpoint2 } = await init_execution().then(() => exports_execution);
189090
+ const reserved = new Set(["url", "endpoint_id", "method", "intent"]);
189091
+ const pBody = params?.body;
189092
+ const rawBody = pBody && typeof pBody === "object" && !Array.isArray(pBody) ? pBody : Object.fromEntries(Object.entries(params ?? {}).filter(([k]) => !reserved.has(k)));
189093
+ const ep = buildAdhocWriteEndpoint2(adhocUrl, reqMethod, rawBody);
189094
+ adhocEndpointId = ep.endpoint_id;
189095
+ const nowIso = new Date().toISOString();
189096
+ skill = {
189097
+ skill_id,
189098
+ version: "1.0.0",
189099
+ schema_version: "1",
189100
+ name: skill_id,
189101
+ intent_signature: intent ?? `write ${adhocUrl}`,
189102
+ domain: (() => {
189103
+ try {
189104
+ return new URL(adhocUrl).hostname;
189105
+ } catch {
189106
+ return skill_id;
189107
+ }
189108
+ })(),
189109
+ description: `Ad-hoc agent write to ${adhocUrl}`,
189110
+ owner_type: "agent",
189111
+ execution_type: "http",
189112
+ lifecycle: "active",
189113
+ created_at: nowIso,
189114
+ updated_at: nowIso,
189115
+ endpoints: [ep]
189116
+ };
189117
+ adhocWrite = true;
189118
+ }
189119
+ }
188564
189120
  if (!skill)
188565
189121
  return reply.code(404).send({ error: "Skill not found" });
188566
189122
  const execParams = {
188567
189123
  ...params ?? {},
188568
- ...context_url && typeof params?.url !== "string" ? { url: context_url } : {}
189124
+ ...context_url && typeof params?.url !== "string" ? { url: context_url } : {},
189125
+ ...adhocEndpointId ? { endpoint_id: adhocEndpointId } : {}
188569
189126
  };
189127
+ const effectiveConfirmUnsafe = confirm_unsafe || adhocWrite;
189128
+ const yieldScope = (() => {
189129
+ const u = context_url ?? (typeof params?.url === "string" ? params.url : undefined) ?? skill.domain;
189130
+ try {
189131
+ return new URL(String(u)).host;
189132
+ } catch {
189133
+ return skill.domain;
189134
+ }
189135
+ })();
189136
+ if (session_id) {
189137
+ try {
189138
+ const { fillHolesFromYields: fillHolesFromYields2 } = await Promise.resolve().then(() => (init_yield_store(), exports_yield_store));
189139
+ const byId = skill.endpoints.find((e) => e.endpoint_id === execParams.endpoint_id);
189140
+ const targetEp = byId ?? (skill.endpoints.length === 1 ? skill.endpoints[0] : undefined);
189141
+ const requires = targetEp?.semantic?.requires;
189142
+ if (requires && requires.length) {
189143
+ const { filled } = fillHolesFromYields2(session_id, requires, execParams, { scope: yieldScope });
189144
+ if (filled.length)
189145
+ console.log(`[pipe-walk] filled holes ${filled.join(",")} from session yields (scope=${yieldScope})`);
189146
+ }
189147
+ } catch (err) {
189148
+ console.warn(`[pipe-walk] fill skipped: ${err?.message}`);
189149
+ }
189150
+ }
189151
+ let crossSkillSuggestions = [];
189152
+ try {
189153
+ const byId = skill.endpoints.find((e) => e.endpoint_id === execParams.endpoint_id);
189154
+ const targetEp = byId ?? (skill.endpoints.length === 1 ? skill.endpoints[0] : undefined);
189155
+ const requires = targetEp?.semantic?.requires;
189156
+ if (requires?.some((r) => r?.key && execParams[r.key] === undefined)) {
189157
+ const { buildGlobalProducerIndexFromCache: buildGlobalProducerIndexFromCache2, suggestCrossSkillProducers: suggestCrossSkillProducers2 } = await Promise.resolve().then(() => (init_cross_skill_index(), exports_cross_skill_index));
189158
+ const index2 = await buildGlobalProducerIndexFromCache2();
189159
+ const rk = targetEp?.semantic?.resource_kind;
189160
+ crossSkillSuggestions = suggestCrossSkillProducers2(requires, execParams, rk, skill.skill_id, index2);
189161
+ }
189162
+ } catch (err) {
189163
+ console.warn(`[cross-skill] suggest skipped: ${err?.message}`);
189164
+ }
188570
189165
  try {
188571
189166
  const executeDeadlineMs = Number(process.env.UNBROWSE_EXECUTE_TIMEOUT_MS) || 60000;
188572
189167
  const endpointIdForTrace = typeof execParams.endpoint_id === "string" ? execParams.endpoint_id : "";
188573
- let execResult = await withExecuteDeadline(executeSkill(skill, execParams, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, intent, contextUrl: context_url, client_scope: clientScope }), executeDeadlineMs, () => {
189168
+ let execResult = await withExecuteDeadline(executeSkill(skill, execParams, projection, { confirm_unsafe: effectiveConfirmUnsafe, confirm_third_party_terms, dry_run, intent, contextUrl: context_url, client_scope: clientScope }), executeDeadlineMs, () => {
188574
189169
  const now = new Date().toISOString();
188575
189170
  return {
188576
189171
  trace: {
@@ -188647,6 +189242,19 @@ async function registerRoutes(app) {
188647
189242
  }
188648
189243
  if (execResult.trace.success) {
188649
189244
  promoteExplicitExecution(clientScope, intent || skill.intent_signature, context_url || (typeof execParams.url === "string" ? execParams.url : undefined), skill, execResult.trace.endpoint_id, execResult.result);
189245
+ if (session_id) {
189246
+ try {
189247
+ const { recordYields: recordYields2 } = await Promise.resolve().then(() => (init_yield_store(), exports_yield_store));
189248
+ const { yieldsFromResponse: yieldsFromResponse2 } = await Promise.resolve().then(() => (init_write_receipt(), exports_write_receipt));
189249
+ const execEp = skill.endpoints.find((e) => e.endpoint_id === execResult.trace.endpoint_id);
189250
+ const provides = execEp?.semantic?.provides ?? yieldsFromResponse2(execResult.result?.data ?? execResult.result);
189251
+ const n = recordYields2(session_id, provides, { scope: yieldScope });
189252
+ if (n)
189253
+ console.log(`[pipe-walk] recorded ${n} yield(s) for session (scope=${yieldScope})`);
189254
+ } catch (err) {
189255
+ console.warn(`[pipe-walk] capture skipped: ${err?.message}`);
189256
+ }
189257
+ }
188650
189258
  }
188651
189259
  if (execResult.trace.status_code === 404 && skill.domain && skill.intent_signature && skill.execution_type !== "browser-capture") {
188652
189260
  try {
@@ -188684,6 +189292,9 @@ async function registerRoutes(app) {
188684
189292
  skill,
188685
189293
  endpointId: execResult.trace.endpoint_id
188686
189294
  });
189295
+ if (Array.isArray(crossSkillSuggestions) && crossSkillSuggestions.length) {
189296
+ response.cross_skill_producers = crossSkillSuggestions;
189297
+ }
188687
189298
  return reply.send(response);
188688
189299
  } catch (err) {
188689
189300
  return reply.code(500).send({ error: err.message });
@@ -188986,8 +189597,8 @@ async function registerRoutes(app) {
188986
189597
  publishAfterIndex: publishDecision.publishQueued
188987
189598
  }
188988
189599
  };
188989
- const path19 = await writeCaptureSpool(getCaptureSpoolDir(), envelope);
188990
- return { written: true, path: path19, request_count: requests.length };
189600
+ const path20 = await writeCaptureSpool(getCaptureSpoolDir(), envelope);
189601
+ return { written: true, path: path20, request_count: requests.length };
188991
189602
  }
188992
189603
  async function lightFlushBrowseCapture(session) {
188993
189604
  let harEntries = [];
@@ -189821,10 +190432,10 @@ ${result.markdown ?? ""}` : result.markdown;
189821
190432
  });
189822
190433
  }
189823
190434
  function saveTrace(trace) {
189824
- if (!existsSync43(TRACES_DIR))
189825
- mkdirSync25(TRACES_DIR, { recursive: true });
190435
+ if (!existsSync44(TRACES_DIR))
190436
+ mkdirSync26(TRACES_DIR, { recursive: true });
189826
190437
  const t = trace;
189827
- writeFileSync22(join54(TRACES_DIR, `${t.trace_id}.json`), JSON.stringify(trace, null, 2));
190438
+ writeFileSync23(join54(TRACES_DIR, `${t.trace_id}.json`), JSON.stringify(trace, null, 2));
189828
190439
  }
189829
190440
  var BETA_API_URL, TRACES_DIR, browseSessions, inspectedHarEntries, perSessionBrokerCursor = 0, statsCache = null, STATS_CACHE_TTL;
189830
190441
  var init_routes = __esm(async () => {
@@ -189893,7 +190504,7 @@ __export(exports_indexer_core, {
189893
190504
  drainPendingIndexJobs: () => drainPendingIndexJobs,
189894
190505
  _processIndexJobForCli: () => processIndexJob2
189895
190506
  });
189896
- import { existsSync as existsSync45, readdirSync as readdirSync14, readFileSync as readFileSync33 } from "node:fs";
190507
+ import { existsSync as existsSync46, readdirSync as readdirSync14, readFileSync as readFileSync34 } from "node:fs";
189897
190508
  import { join as join55 } from "node:path";
189898
190509
  function getQueueDir2() {
189899
190510
  return join55(process.env.HOME ?? "/tmp", ".unbrowse", "queue", "pending");
@@ -189908,7 +190519,7 @@ async function isWorkerActive2(queueDir) {
189908
190519
  }
189909
190520
  function getLocalAgentId2() {
189910
190521
  try {
189911
- const config = JSON.parse(readFileSync33(getUnbrowseConfigPath(), "utf-8"));
190522
+ const config = JSON.parse(readFileSync34(getUnbrowseConfigPath(), "utf-8"));
189912
190523
  return config.agent_id ?? undefined;
189913
190524
  } catch {
189914
190525
  return;
@@ -189943,7 +190554,7 @@ function mergeAgentReview2(endpoints, reviews) {
189943
190554
  });
189944
190555
  }
189945
190556
  function findAndMergeDomainSnapshot2(snapshotDir, domain, incoming) {
189946
- if (!existsSync45(snapshotDir))
190557
+ if (!existsSync46(snapshotDir))
189947
190558
  return null;
189948
190559
  const targetDomain = getRegistrableDomain(domain);
189949
190560
  let bestExisting = null;
@@ -189952,7 +190563,7 @@ function findAndMergeDomainSnapshot2(snapshotDir, domain, incoming) {
189952
190563
  if (!entry.endsWith(".json"))
189953
190564
  continue;
189954
190565
  try {
189955
- const candidate = JSON.parse(readFileSync33(join55(snapshotDir, entry), "utf-8"));
190566
+ const candidate = JSON.parse(readFileSync34(join55(snapshotDir, entry), "utf-8"));
189956
190567
  if (getRegistrableDomain(candidate.domain) !== targetDomain)
189957
190568
  continue;
189958
190569
  if (candidate.execution_type !== "http")
@@ -190066,17 +190677,17 @@ function mergeBackgroundIndexJobs2(current, incoming) {
190066
190677
  publishAfterIndex: incoming.publishAfterIndex ?? current.publishAfterIndex
190067
190678
  };
190068
190679
  }
190069
- function persistIndexedSkillState2(job, skill, scopedKey) {
190680
+ function persistIndexedSkillState2(job, skill, scopedKey2) {
190070
190681
  try {
190071
190682
  cachePublishedSkill(skill, job.clientScope);
190072
190683
  } catch {}
190073
- writeSkillSnapshot(scopedKey, skill);
190684
+ writeSkillSnapshot(scopedKey2, skill);
190074
190685
  writeWorkflowPublishArtifact(buildWorkflowPublishArtifact(skill, readWorkflowArtifact(skill.skill_id), { publishStatus: "indexed" }));
190075
190686
  const domainKey = getDomainReuseKey(job.contextUrl ?? job.domain);
190076
190687
  if (domainKey) {
190077
190688
  domainSkillCache.set(domainKey, {
190078
190689
  skillId: skill.skill_id,
190079
- localSkillPath: snapshotPathForCacheKey(scopedKey),
190690
+ localSkillPath: snapshotPathForCacheKey(scopedKey2),
190080
190691
  ts: Date.now()
190081
190692
  });
190082
190693
  persistDomainCache();
@@ -190085,7 +190696,7 @@ function persistIndexedSkillState2(job, skill, scopedKey) {
190085
190696
  async function indexSkillLocally2(job) {
190086
190697
  let { skill, domain, clientScope } = job;
190087
190698
  const scope = clientScope ?? "global";
190088
- const scopedKey = scopedCacheKey(scope, job.cacheKey);
190699
+ const scopedKey2 = scopedCacheKey(scope, job.cacheKey);
190089
190700
  const merged = findAndMergeDomainSnapshot2(SKILL_SNAPSHOT_DIR3, domain, skill);
190090
190701
  if (merged) {
190091
190702
  console.error(`[capture-pipeline] merged ${skill.endpoints.length} new endpoint(s) into existing ${merged.endpoints.length - skill.endpoints.length} for ${domain}`);
@@ -190097,11 +190708,11 @@ async function indexSkillLocally2(job) {
190097
190708
  ep.description = generateLocalDescription(ep);
190098
190709
  }
190099
190710
  }
190100
- persistIndexedSkillState2(job, skill, scopedKey);
190101
- return { skill, domain, clientScope, scopedKey };
190711
+ persistIndexedSkillState2(job, skill, scopedKey2);
190712
+ return { skill, domain, clientScope, scopedKey: scopedKey2 };
190102
190713
  }
190103
190714
  async function publishIndexedSkill2(indexed) {
190104
- const { skill, domain, clientScope, scopedKey } = indexed;
190715
+ const { skill, domain, clientScope, scopedKey: scopedKey2 } = indexed;
190105
190716
  const selection = selectMarketplacePublishClosure(skill);
190106
190717
  const markBlockedValidation = (errors2) => {
190107
190718
  writeWorkflowPublishArtifact(buildWorkflowPublishArtifact(skill, readWorkflowArtifact(skill.skill_id), {
@@ -190163,7 +190774,7 @@ async function publishIndexedSkill2(indexed) {
190163
190774
  ...skill.auth_profile_ref ? { auth_profile_ref: skill.auth_profile_ref } : {}
190164
190775
  };
190165
190776
  cachePublishedSkill(publishedSkill, clientScope);
190166
- writeSkillSnapshot(scopedKey, publishedSkill);
190777
+ writeSkillSnapshot(scopedKey2, publishedSkill);
190167
190778
  const publishedAt = new Date().toISOString();
190168
190779
  writeWorkflowPublishArtifact(buildWorkflowPublishArtifact(skill, readWorkflowArtifact(skill.skill_id), {
190169
190780
  publishStatus: "published",
@@ -190193,7 +190804,7 @@ async function publishIndexedSkill2(indexed) {
190193
190804
  if (domainKey) {
190194
190805
  domainSkillCache.set(domainKey, {
190195
190806
  skillId: publishedSkill.skill_id,
190196
- localSkillPath: snapshotPathForCacheKey(scopedKey),
190807
+ localSkillPath: snapshotPathForCacheKey(scopedKey2),
190197
190808
  ts: Date.now()
190198
190809
  });
190199
190810
  persistDomainCache();
@@ -190262,9 +190873,9 @@ function isIndexingInFlight(domain) {
190262
190873
  const queueDir = getQueueDir2();
190263
190874
  const cap = sanitizeDomain(domain);
190264
190875
  try {
190265
- if (existsSync45(join55(queueDir, `${cap}.lock`)))
190876
+ if (existsSync46(join55(queueDir, `${cap}.lock`)))
190266
190877
  return true;
190267
- if (!existsSync45(queueDir))
190878
+ if (!existsSync46(queueDir))
190268
190879
  return false;
190269
190880
  for (const name of readdirSync14(queueDir)) {
190270
190881
  if (!name.endsWith(".json"))
@@ -190304,7 +190915,7 @@ async function drainPendingIndexJobs() {
190304
190915
  const jobs = await listJobs(queueDir);
190305
190916
  let deadCount = 0;
190306
190917
  try {
190307
- if (existsSync45(deadDir)) {
190918
+ if (existsSync46(deadDir)) {
190308
190919
  deadCount = readdirSync14(deadDir).filter((n) => n.endsWith(".json") && !n.endsWith(".tmp")).length;
190309
190920
  }
190310
190921
  } catch {
@@ -190372,6 +190983,368 @@ var init_indexer_core2 = __esm(async () => {
190372
190983
  backgroundIndexProcessor2 = processIndexJob2;
190373
190984
  });
190374
190985
 
190986
+ // .tmp-runtime-src/runtime/update-hints.ts
190987
+ var exports_update_hints = {};
190988
+ __export(exports_update_hints, {
190989
+ shouldAutoUpdate: () => shouldAutoUpdate,
190990
+ saveInstallSource: () => saveInstallSource2,
190991
+ resolveInstallSource: () => resolveInstallSource2,
190992
+ recordUpdateHint: () => recordUpdateHint,
190993
+ maybeAutoUpdate: () => maybeAutoUpdate,
190994
+ loadInstallSource: () => loadInstallSource2,
190995
+ getInstalledVersion: () => getInstalledVersion,
190996
+ configureUpdateHintHooks: () => configureUpdateHintHooks2,
190997
+ checkForUpdates: () => checkForUpdates,
190998
+ buildUpgradeCommand: () => buildUpgradeCommand,
190999
+ autoUpdateDisabled: () => autoUpdateDisabled
191000
+ });
191001
+ import { spawn as spawn11 } from "node:child_process";
191002
+ import { existsSync as existsSync49, mkdirSync as mkdirSync30, readFileSync as readFileSync36, writeFileSync as writeFileSync26 } from "node:fs";
191003
+ import os15 from "node:os";
191004
+ import path23 from "node:path";
191005
+ function getHomeDir2() {
191006
+ return process.env.HOME || os15.homedir();
191007
+ }
191008
+ function getConfigDir7() {
191009
+ if (process.env.UNBROWSE_CONFIG_DIR)
191010
+ return process.env.UNBROWSE_CONFIG_DIR;
191011
+ return path23.join(getHomeDir2(), ".unbrowse");
191012
+ }
191013
+ function ensureDir5(dir) {
191014
+ if (!existsSync49(dir))
191015
+ mkdirSync30(dir, { recursive: true });
191016
+ return dir;
191017
+ }
191018
+ function readJsonFile2(file) {
191019
+ try {
191020
+ return JSON.parse(readFileSync36(file, "utf8"));
191021
+ } catch {
191022
+ return null;
191023
+ }
191024
+ }
191025
+ function writeJsonFile2(file, value) {
191026
+ ensureDir5(path23.dirname(file));
191027
+ writeFileSync26(file, `${JSON.stringify(value, null, 2)}
191028
+ `);
191029
+ }
191030
+ function getInstallSourcePath2() {
191031
+ return path23.join(getConfigDir7(), "install-source.json");
191032
+ }
191033
+ function getUpdateCheckStatePath() {
191034
+ return path23.join(getConfigDir7(), "update-check.json");
191035
+ }
191036
+ function detectRepoRoot2(start4) {
191037
+ let dir = path23.resolve(start4);
191038
+ const root2 = path23.parse(dir).root;
191039
+ while (dir !== root2) {
191040
+ if (existsSync49(path23.join(dir, ".git")))
191041
+ return dir;
191042
+ dir = path23.dirname(dir);
191043
+ }
191044
+ return;
191045
+ }
191046
+ function detectInstallMethod2(packageRoot) {
191047
+ if (process.env.UNBROWSE_SETUP_METHOD === "repo-clone")
191048
+ return "repo-clone";
191049
+ if (process.env.UNBROWSE_SETUP_METHOD === "npm-global")
191050
+ return "npm-global";
191051
+ if (packageRoot.includes(`${path23.sep}node_modules${path23.sep}`))
191052
+ return "npm-global";
191053
+ return detectRepoRoot2(packageRoot) ? "repo-clone" : "unknown";
191054
+ }
191055
+ function detectInstallHost2(repoRoot) {
191056
+ const explicit = process.env.UNBROWSE_SETUP_HOST;
191057
+ if (explicit)
191058
+ return explicit;
191059
+ if (!repoRoot)
191060
+ return "unknown";
191061
+ const codexHome = process.env.CODEX_HOME || path23.join(getHomeDir2(), ".codex");
191062
+ if (repoRoot === path23.join(codexHome, "skills", "unbrowse"))
191063
+ return "codex";
191064
+ if (repoRoot === path23.join(getHomeDir2(), "(internal)", "skills", "unbrowse"))
191065
+ return "claude";
191066
+ if (repoRoot === path23.join(getHomeDir2(), "unbrowse"))
191067
+ return "off";
191068
+ return "unknown";
191069
+ }
191070
+ function getInstalledVersion(metaUrl) {
191071
+ const packageRoot = getPackageRoot(metaUrl);
191072
+ try {
191073
+ const pkg = JSON.parse(readFileSync36(path23.join(packageRoot, "package.json"), "utf8"));
191074
+ return pkg.version ?? "unknown";
191075
+ } catch {
191076
+ return "unknown";
191077
+ }
191078
+ }
191079
+ function resolveInstallSource2(metaUrl) {
191080
+ const packageRoot = getPackageRoot(metaUrl);
191081
+ const envRepoRoot = process.env.UNBROWSE_SETUP_ROOT || undefined;
191082
+ const repoRoot = envRepoRoot || detectRepoRoot2(packageRoot);
191083
+ return {
191084
+ method: detectInstallMethod2(packageRoot),
191085
+ host: detectInstallHost2(repoRoot),
191086
+ package_root: packageRoot,
191087
+ repo_root: repoRoot,
191088
+ recorded_at: new Date().toISOString()
191089
+ };
191090
+ }
191091
+ function saveInstallSource2(metaUrl) {
191092
+ const state = resolveInstallSource2(metaUrl);
191093
+ writeJsonFile2(getInstallSourcePath2(), state);
191094
+ return state;
191095
+ }
191096
+ function loadInstallSource2(metaUrl) {
191097
+ return readJsonFile2(getInstallSourcePath2()) ?? resolveInstallSource2(metaUrl);
191098
+ }
191099
+ function compareSemver(a, b) {
191100
+ const parse10 = (value) => value.split("-", 1)[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
191101
+ const left2 = parse10(a);
191102
+ const right2 = parse10(b);
191103
+ const max = Math.max(left2.length, right2.length);
191104
+ for (let i = 0;i < max; i++) {
191105
+ const diff = (left2[i] ?? 0) - (right2[i] ?? 0);
191106
+ if (diff !== 0)
191107
+ return diff;
191108
+ }
191109
+ return 0;
191110
+ }
191111
+ async function fetchLatestVersion() {
191112
+ try {
191113
+ const res = await fetch("https://registry.npmjs.org/unbrowse/latest", {
191114
+ signal: AbortSignal.timeout(8000),
191115
+ headers: { Accept: "application/json" }
191116
+ });
191117
+ if (!res.ok)
191118
+ return null;
191119
+ const body = await res.json();
191120
+ return typeof body.version === "string" && body.version.trim() ? body.version.trim() : null;
191121
+ } catch {
191122
+ return null;
191123
+ }
191124
+ }
191125
+ function getUpdateIntervalMs() {
191126
+ const value = Number.parseInt(process.env.UNBROWSE_UPDATE_CHECK_INTERVAL_MS ?? "", 10);
191127
+ return Number.isFinite(value) && value > 0 ? value : DEFAULT_INTERVAL_MS2;
191128
+ }
191129
+ function buildUpgradeCommand(install2) {
191130
+ if (install2.method === "repo-clone" && install2.repo_root) {
191131
+ const host = install2.host === "unknown" || install2.host === "auto" ? "off" : install2.host;
191132
+ return `cd ${install2.repo_root} && git pull --ff-only && ./setup --host ${host}`;
191133
+ }
191134
+ return `curl -fsSL ${INSTALL_SCRIPT_URL} | bash`;
191135
+ }
191136
+ async function checkForUpdates(metaUrl, options) {
191137
+ const installed = getInstalledVersion(metaUrl);
191138
+ const install2 = loadInstallSource2(metaUrl);
191139
+ const statePath = getUpdateCheckStatePath();
191140
+ const state = readJsonFile2(statePath) ?? {};
191141
+ const checkedAt = new Date().toISOString();
191142
+ const intervalMs = getUpdateIntervalMs();
191143
+ const lastChecked = state.latest_checked_at ? Date.parse(state.latest_checked_at) : Number.NaN;
191144
+ const useCache = !options?.force && !!state.latest_version && Number.isFinite(lastChecked) && Date.now() - lastChecked < intervalMs;
191145
+ const latest = useCache ? state.latest_version ?? null : await fetchLatestVersion();
191146
+ if (!useCache) {
191147
+ writeJsonFile2(statePath, {
191148
+ ...state,
191149
+ checked_at: checkedAt,
191150
+ latest_version: latest ?? undefined,
191151
+ latest_checked_at: checkedAt
191152
+ });
191153
+ }
191154
+ return {
191155
+ installed,
191156
+ latest,
191157
+ has_update: !!latest && compareSemver(latest, installed) > 0,
191158
+ install: install2,
191159
+ command: buildUpgradeCommand(install2),
191160
+ checked_at: checkedAt,
191161
+ cached: useCache
191162
+ };
191163
+ }
191164
+ function recordUpdateHint(latestVersion) {
191165
+ const statePath = getUpdateCheckStatePath();
191166
+ const state = readJsonFile2(statePath) ?? {};
191167
+ writeJsonFile2(statePath, {
191168
+ ...state,
191169
+ notified_version: latestVersion,
191170
+ notified_at: new Date().toISOString()
191171
+ });
191172
+ }
191173
+ function envOn(name) {
191174
+ const v = (process.env[name] ?? "").toLowerCase();
191175
+ return v === "1" || v === "true" || v === "yes";
191176
+ }
191177
+ function shouldAutoUpdate(input2) {
191178
+ if (input2.disabled)
191179
+ return { update: false, reason: "disabled" };
191180
+ if (!input2.hasUpdate)
191181
+ return { update: false, reason: "up-to-date" };
191182
+ if (input2.method !== "npm-global")
191183
+ return { update: false, reason: `method:${input2.method}` };
191184
+ if (input2.lastAttemptAt) {
191185
+ const last2 = Date.parse(input2.lastAttemptAt);
191186
+ if (Number.isFinite(last2) && input2.nowMs - last2 < input2.intervalMs) {
191187
+ return { update: false, reason: "throttled" };
191188
+ }
191189
+ }
191190
+ return { update: true, reason: "applying" };
191191
+ }
191192
+ function autoUpdateDisabled() {
191193
+ return envOn("UNBROWSE_NO_AUTO_UPDATE") || envOn("UNBROWSE_DISABLE_UPDATE_HINTS") || envOn("CI") || !!process.env.GITHUB_ACTIONS;
191194
+ }
191195
+ async function maybeAutoUpdate(metaUrl) {
191196
+ try {
191197
+ const result = await checkForUpdates(metaUrl);
191198
+ const statePath = getUpdateCheckStatePath();
191199
+ const state = readJsonFile2(statePath) ?? {};
191200
+ const decision = shouldAutoUpdate({
191201
+ hasUpdate: result.has_update,
191202
+ method: result.install.method,
191203
+ disabled: autoUpdateDisabled(),
191204
+ lastAttemptAt: state.auto_update_attempted_at,
191205
+ nowMs: Date.now(),
191206
+ intervalMs: getUpdateIntervalMs()
191207
+ });
191208
+ if (!decision.update)
191209
+ return { applied: false, reason: decision.reason };
191210
+ if (!result.latest)
191211
+ return { applied: false, reason: "no-latest" };
191212
+ writeJsonFile2(statePath, {
191213
+ ...state,
191214
+ auto_update_attempted_at: new Date().toISOString(),
191215
+ auto_update_target: result.latest
191216
+ });
191217
+ const logFile = path23.join(ensureDir5(getConfigDir7()), "auto-update.log");
191218
+ const child = spawn11(process.platform === "win32" ? "npm.cmd" : "npm", ["install", "-g", `unbrowse@${result.latest}`], { detached: true, stdio: ["ignore", "ignore", "ignore"], windowsHide: true });
191219
+ try {
191220
+ writeFileSync26(logFile, `${new Date().toISOString()} auto-update ${result.installed} -> ${result.latest} (pid ${child.pid ?? "?"})
191221
+ `, { flag: "a" });
191222
+ } catch {}
191223
+ child.unref();
191224
+ return { applied: true, reason: "spawned", from: result.installed, to: result.latest };
191225
+ } catch (err) {
191226
+ return { applied: false, reason: `error:${err?.message ?? "unknown"}` };
191227
+ }
191228
+ }
191229
+ function commandIncludesHook2(command2, marker) {
191230
+ return typeof command2 === "string" && command2.includes(marker);
191231
+ }
191232
+ function getCodexConfigPath2() {
191233
+ const codexHome = process.env.CODEX_HOME || path23.join(getHomeDir2(), ".codex");
191234
+ return path23.join(codexHome, "config.toml");
191235
+ }
191236
+ function getClaudeSettingsPath2() {
191237
+ return path23.join(getHomeDir2(), "(internal)", "settings.json");
191238
+ }
191239
+ function getHookScriptPath2(metaUrl) {
191240
+ return path23.join(getPackageRoot(metaUrl), "bin", "unbrowse-update-hint.mjs");
191241
+ }
191242
+ function ensureCodexHooksFeature2(content) {
191243
+ if (/\bcodex_hooks\s*=\s*true\b/.test(content))
191244
+ return content;
191245
+ if (/\[features\]/.test(content)) {
191246
+ return content.replace(/\[features\]\r?\n/, (match) => `${match}codex_hooks = true
191247
+ `);
191248
+ }
191249
+ const prefix = content && !content.endsWith(`
191250
+ `) ? `
191251
+ ` : "";
191252
+ return `${content}${prefix}[features]
191253
+ codex_hooks = true
191254
+ `;
191255
+ }
191256
+ function repairManagedCodexHookTable2(content) {
191257
+ const marker = CODEX_MARKER2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
191258
+ return content.replace(new RegExp(`(${marker}\\r?\\n)\\[\\[?hooks\\]?\\]?(?=\\r?\\n)`, "g"), "$1[hooks]");
191259
+ }
191260
+ function writeCodexHook2(metaUrl) {
191261
+ const configPath3 = getCodexConfigPath2();
191262
+ if (!existsSync49(path23.dirname(configPath3))) {
191263
+ return { host: "codex", action: "not-detected", config_file: configPath3 };
191264
+ }
191265
+ try {
191266
+ const hookScript = getHookScriptPath2(metaUrl).replace(/\\/g, "/");
191267
+ const fileExistsBefore = existsSync49(configPath3);
191268
+ let content = fileExistsBefore ? readFileSync36(configPath3, "utf8") : "";
191269
+ const previous = content;
191270
+ content = ensureCodexHooksFeature2(content);
191271
+ content = repairManagedCodexHookTable2(content);
191272
+ if (!content.includes("unbrowse-update-hint.mjs")) {
191273
+ const command2 = `node "${hookScript}"`;
191274
+ const prefix = content && !content.endsWith(`
191275
+ `) ? `
191276
+ ` : "";
191277
+ content += `${prefix}${CODEX_MARKER2}
191278
+ [hooks]
191279
+ event = "SessionStart"
191280
+ command = ${JSON.stringify(command2)}
191281
+ `;
191282
+ }
191283
+ if (content !== previous) {
191284
+ writeFileSync26(configPath3, content, "utf8");
191285
+ return {
191286
+ host: "codex",
191287
+ action: fileExistsBefore ? "updated" : "installed",
191288
+ config_file: configPath3
191289
+ };
191290
+ }
191291
+ return { host: "codex", action: "already-installed", config_file: configPath3 };
191292
+ } catch (error) {
191293
+ return {
191294
+ host: "codex",
191295
+ action: "failed",
191296
+ config_file: configPath3,
191297
+ message: error instanceof Error ? error.message : String(error)
191298
+ };
191299
+ }
191300
+ }
191301
+ function writeClaudeHook2(metaUrl) {
191302
+ const settingsPath = getClaudeSettingsPath2();
191303
+ if (!existsSync49(path23.dirname(settingsPath))) {
191304
+ return { host: "claude", action: "not-detected", config_file: settingsPath };
191305
+ }
191306
+ try {
191307
+ const hookScript = getHookScriptPath2(metaUrl).replace(/\\/g, "/");
191308
+ const command2 = `node "${hookScript}"`;
191309
+ const fileExistsBefore = existsSync49(settingsPath);
191310
+ const settings = readJsonFile2(settingsPath) ?? {};
191311
+ settings.hooks ??= {};
191312
+ settings.hooks.SessionStart ??= [];
191313
+ const existing = settings.hooks.SessionStart.some((entry) => Array.isArray(entry.hooks) && entry.hooks.some((hook) => commandIncludesHook2(hook.command, "unbrowse-update-hint.mjs")));
191314
+ if (!existing) {
191315
+ settings.hooks.SessionStart.push({
191316
+ hooks: [{ type: "command", command: command2 }]
191317
+ });
191318
+ writeJsonFile2(settingsPath, settings);
191319
+ return {
191320
+ host: "claude",
191321
+ action: fileExistsBefore ? "updated" : "installed",
191322
+ config_file: settingsPath
191323
+ };
191324
+ }
191325
+ return { host: "claude", action: "already-installed", config_file: settingsPath };
191326
+ } catch (error) {
191327
+ return {
191328
+ host: "claude",
191329
+ action: "failed",
191330
+ config_file: settingsPath,
191331
+ message: error instanceof Error ? error.message : String(error)
191332
+ };
191333
+ }
191334
+ }
191335
+ function configureUpdateHintHooks2(metaUrl, install2) {
191336
+ if (process.env.UNBROWSE_DISABLE_UPDATE_HINTS === "1")
191337
+ return [];
191338
+ const source = install2 ?? loadInstallSource2(metaUrl);
191339
+ const configuredHosts = source.host === "codex" || source.host === "claude" ? [source.host] : ["codex", "claude"];
191340
+ return configuredHosts.map((host) => host === "codex" ? writeCodexHook2(metaUrl) : writeClaudeHook2(metaUrl));
191341
+ }
191342
+ var INSTALL_SCRIPT_URL = "https://unbrowse.ai/install.sh", DEFAULT_INTERVAL_MS2, CODEX_MARKER2 = "# Unbrowse update hints — managed by unbrowse setup";
191343
+ var init_update_hints = __esm(() => {
191344
+ init_paths();
191345
+ DEFAULT_INTERVAL_MS2 = 12 * 60 * 60 * 1000;
191346
+ });
191347
+
190375
191348
  // .tmp-runtime-src/lib/indexer-core/queue-store.ts
190376
191349
  var exports_queue_store = {};
190377
191350
  __export(exports_queue_store, {
@@ -190411,10 +191384,10 @@ async function writeJob2(queueDir, envelope) {
190411
191384
  await rename3(tmpPath, finalPath);
190412
191385
  return finalPath;
190413
191386
  }
190414
- async function rewriteJobAtPath2(path24, envelope) {
190415
- const tmpPath = `${path24}.tmp`;
191387
+ async function rewriteJobAtPath2(path25, envelope) {
191388
+ const tmpPath = `${path25}.tmp`;
190416
191389
  await writeFile7(tmpPath, JSON.stringify(envelope));
190417
- await rename3(tmpPath, path24);
191390
+ await rename3(tmpPath, path25);
190418
191391
  }
190419
191392
  function isJobEnvelope2(value) {
190420
191393
  if (value === null || typeof value !== "object")
@@ -190450,24 +191423,24 @@ async function listJobs2(queueDir) {
190450
191423
  continue;
190451
191424
  if (entry.name.endsWith(".tmp"))
190452
191425
  continue;
190453
- const path24 = join57(absDir, entry.name);
191426
+ const path25 = join57(absDir, entry.name);
190454
191427
  let parsed;
190455
191428
  try {
190456
- const raw = await readFile9(path24, "utf8");
191429
+ const raw = await readFile9(path25, "utf8");
190457
191430
  parsed = JSON.parse(raw);
190458
191431
  } catch {
190459
191432
  continue;
190460
191433
  }
190461
191434
  if (!isJobEnvelope2(parsed))
190462
191435
  continue;
190463
- results.push({ path: path24, envelope: parsed });
191436
+ results.push({ path: path25, envelope: parsed });
190464
191437
  }
190465
191438
  results.sort((a, b) => a.envelope.queuedAt - b.envelope.queuedAt);
190466
191439
  return results;
190467
191440
  }
190468
- async function deleteJob2(path24) {
191441
+ async function deleteJob2(path25) {
190469
191442
  try {
190470
- await unlink5(path24);
191443
+ await unlink5(path25);
190471
191444
  } catch (err) {
190472
191445
  if (err.code === "ENOENT")
190473
191446
  return;
@@ -190489,11 +191462,11 @@ async function sweepStaleTmp2(queueDir, maxAgeMs = 60000) {
190489
191462
  for (const name of entries) {
190490
191463
  if (!name.endsWith(".tmp"))
190491
191464
  continue;
190492
- const path24 = join57(absDir, name);
191465
+ const path25 = join57(absDir, name);
190493
191466
  try {
190494
- const st = await stat6(path24);
191467
+ const st = await stat6(path25);
190495
191468
  if (now - st.mtimeMs > maxAgeMs) {
190496
- await unlink5(path24);
191469
+ await unlink5(path25);
190497
191470
  unlinked += 1;
190498
191471
  }
190499
191472
  } catch {
@@ -190581,13 +191554,13 @@ async function tryAcquireWorkerSlot2(queueDir) {
190581
191554
  async function touchHeartbeat2(queueDir) {
190582
191555
  const absDir = resolve13(queueDir);
190583
191556
  await mkdir9(absDir, { recursive: true });
190584
- const path24 = join57(absDir, ".heartbeat");
190585
- await writeFile7(path24, String(Date.now()));
191557
+ const path25 = join57(absDir, ".heartbeat");
191558
+ await writeFile7(path25, String(Date.now()));
190586
191559
  }
190587
191560
  async function heartbeatAgeMs2(queueDir) {
190588
- const path24 = join57(resolve13(queueDir), ".heartbeat");
191561
+ const path25 = join57(resolve13(queueDir), ".heartbeat");
190589
191562
  try {
190590
- const st = await stat6(path24);
191563
+ const st = await stat6(path25);
190591
191564
  return Date.now() - st.mtimeMs;
190592
191565
  } catch (err) {
190593
191566
  if (err.code === "ENOENT")
@@ -190614,25 +191587,25 @@ async function listJobsWithRejects2(queueDir) {
190614
191587
  continue;
190615
191588
  if (entry.name.endsWith(".tmp"))
190616
191589
  continue;
190617
- const path24 = join57(absDir, entry.name);
191590
+ const path25 = join57(absDir, entry.name);
190618
191591
  let parsed;
190619
191592
  try {
190620
- const raw = await readFile9(path24, "utf8");
191593
+ const raw = await readFile9(path25, "utf8");
190621
191594
  parsed = JSON.parse(raw);
190622
191595
  } catch {
190623
- rejected.push({ path: path24, reason: "corrupt_json" });
191596
+ rejected.push({ path: path25, reason: "corrupt_json" });
190624
191597
  continue;
190625
191598
  }
190626
191599
  const v = parsed;
190627
191600
  if (v === null || typeof v !== "object" || v.version !== 1) {
190628
- rejected.push({ path: path24, reason: "wrong_version" });
191601
+ rejected.push({ path: path25, reason: "wrong_version" });
190629
191602
  continue;
190630
191603
  }
190631
191604
  if (!isJobEnvelope2(parsed)) {
190632
- rejected.push({ path: path24, reason: "missing_fields" });
191605
+ rejected.push({ path: path25, reason: "missing_fields" });
190633
191606
  continue;
190634
191607
  }
190635
- accepted.push({ path: path24, envelope: parsed });
191608
+ accepted.push({ path: path25, envelope: parsed });
190636
191609
  }
190637
191610
  accepted.sort((a, b) => a.envelope.queuedAt - b.envelope.queuedAt);
190638
191611
  rejected.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -190646,7 +191619,7 @@ __export(exports_wallet, {
190646
191619
  getWalletContext: () => getWalletContext2,
190647
191620
  checkWalletConfigured: () => checkWalletConfigured2
190648
191621
  });
190649
- import { existsSync as existsSync50, readFileSync as readFileSync37 } from "node:fs";
191622
+ import { existsSync as existsSync51, readFileSync as readFileSync38 } from "node:fs";
190650
191623
  import { homedir as homedir43 } from "node:os";
190651
191624
  import { join as join58 } from "node:path";
190652
191625
  function asNonEmptyString2(value) {
@@ -190654,10 +191627,10 @@ function asNonEmptyString2(value) {
190654
191627
  }
190655
191628
  function getLobsterWalletFromLocalConfig2() {
190656
191629
  const agentsPath = join58(process.env.HOME || homedir43(), ".lobster", "agents.json");
190657
- if (!existsSync50(agentsPath))
191630
+ if (!existsSync51(agentsPath))
190658
191631
  return;
190659
191632
  try {
190660
- const raw = JSON.parse(readFileSync37(agentsPath, "utf8"));
191633
+ const raw = JSON.parse(readFileSync38(agentsPath, "utf8"));
190661
191634
  const activeAgentId = asNonEmptyString2(raw.activeAgentId);
190662
191635
  const activeAgent = Array.isArray(raw.agents) ? raw.agents.find((agent) => asNonEmptyString2(agent.id) === activeAgentId) : activeAgentId ? raw.agents?.[activeAgentId] : undefined;
190663
191636
  return asNonEmptyString2(activeAgent?.authorizedWallets?.solana) ?? asNonEmptyString2(activeAgent?.walletAddress) ?? asNonEmptyString2(activeAgent?.wallet_address);
@@ -190704,35 +191677,35 @@ var init_wallet2 = __esm(() => {
190704
191677
  });
190705
191678
 
190706
191679
  // .tmp-runtime-src/telemetry/config.ts
190707
- import { existsSync as existsSync51, mkdirSync as mkdirSync31, readFileSync as readFileSync38, writeFileSync as writeFileSync27 } from "node:fs";
191680
+ import { existsSync as existsSync52, mkdirSync as mkdirSync32, readFileSync as readFileSync39, writeFileSync as writeFileSync28 } from "node:fs";
190708
191681
  import { homedir as homedir44 } from "node:os";
190709
- import path24 from "node:path";
191682
+ import path25 from "node:path";
190710
191683
  import { randomUUID as randomUUID5 } from "node:crypto";
190711
191684
  function getUnbrowseHome2() {
190712
191685
  const home = process.env.HOME || homedir44();
190713
- return path24.join(home, ".unbrowse");
191686
+ return path25.join(home, ".unbrowse");
190714
191687
  }
190715
191688
  function getConfigPath3() {
190716
- return path24.join(getUnbrowseHome2(), "config.json");
191689
+ return path25.join(getUnbrowseHome2(), "config.json");
190717
191690
  }
190718
191691
  function getSessionsDir() {
190719
- return path24.join(getUnbrowseHome2(), "sessions");
191692
+ return path25.join(getUnbrowseHome2(), "sessions");
190720
191693
  }
190721
191694
  function readConfigFile2() {
190722
191695
  const p = getConfigPath3();
190723
- if (!existsSync51(p))
191696
+ if (!existsSync52(p))
190724
191697
  return {};
190725
191698
  try {
190726
- return JSON.parse(readFileSync38(p, "utf8"));
191699
+ return JSON.parse(readFileSync39(p, "utf8"));
190727
191700
  } catch {
190728
191701
  return {};
190729
191702
  }
190730
191703
  }
190731
191704
  function writeConfigFile2(updated) {
190732
191705
  const dir = getUnbrowseHome2();
190733
- if (!existsSync51(dir))
190734
- mkdirSync31(dir, { recursive: true });
190735
- writeFileSync27(getConfigPath3(), JSON.stringify(updated, null, 2), "utf8");
191706
+ if (!existsSync52(dir))
191707
+ mkdirSync32(dir, { recursive: true });
191708
+ writeFileSync28(getConfigPath3(), JSON.stringify(updated, null, 2), "utf8");
190736
191709
  }
190737
191710
  function getTelemetryConfig() {
190738
191711
  const env2 = process.env.UNBROWSE_TELEMETRY;
@@ -190769,18 +191742,18 @@ function writeTelemetryConfig(patch) {
190769
191742
  }
190770
191743
  function ensureSessionsDir() {
190771
191744
  const dir = getSessionsDir();
190772
- if (!existsSync51(dir))
190773
- mkdirSync31(dir, { recursive: true });
191745
+ if (!existsSync52(dir))
191746
+ mkdirSync32(dir, { recursive: true });
190774
191747
  return dir;
190775
191748
  }
190776
191749
  var DEFAULT_UPLOAD_ENDPOINT = "https://beta-api.unbrowse.ai/v1/telemetry/session";
190777
191750
  var init_config = () => {};
190778
191751
 
190779
191752
  // .tmp-runtime-src/telemetry/sanitize.ts
190780
- import { createHash as createHash37 } from "node:crypto";
191753
+ import { createHash as createHash39 } from "node:crypto";
190781
191754
  function shaHex(input2, hexLen) {
190782
191755
  const bytes = Math.ceil(hexLen / SHA_HEX_PER_BYTE);
190783
- return createHash37("sha256").update(input2).digest("hex").slice(0, hexLen);
191756
+ return createHash39("sha256").update(input2).digest("hex").slice(0, hexLen);
190784
191757
  }
190785
191758
  function isEntityShapedSegment(segment) {
190786
191759
  if (!segment)
@@ -190972,21 +191945,21 @@ __export(exports_upload, {
190972
191945
  uploadSessionInBackground: () => uploadSessionInBackground,
190973
191946
  uploadSession: () => uploadSession
190974
191947
  });
190975
- import { readFileSync as readFileSync39, existsSync as existsSync52 } from "node:fs";
190976
- import { createHash as createHash38 } from "node:crypto";
191948
+ import { readFileSync as readFileSync40, existsSync as existsSync53 } from "node:fs";
191949
+ import { createHash as createHash40 } from "node:crypto";
190977
191950
  function deriveAgentFingerprint(meta) {
190978
191951
  const seed = `${meta.mcp_version ?? "?"}|${meta.node_version ?? "?"}|${meta.platform ?? "?"}`;
190979
- return createHash38("sha256").update(seed).digest("hex").slice(0, 16);
191952
+ return createHash40("sha256").update(seed).digest("hex").slice(0, 16);
190980
191953
  }
190981
191954
  async function uploadSession(input2) {
190982
191955
  const cfg = getResolvedTelemetryConfig();
190983
191956
  if (!cfg.enabled)
190984
191957
  return { ok: false, reason: "telemetry_disabled" };
190985
- if (!existsSync52(input2.session_file))
191958
+ if (!existsSync53(input2.session_file))
190986
191959
  return { ok: false, reason: "no_session_file" };
190987
191960
  let raw;
190988
191961
  try {
190989
- raw = readFileSync39(input2.session_file, "utf8");
191962
+ raw = readFileSync40(input2.session_file, "utf8");
190990
191963
  } catch (err) {
190991
191964
  return { ok: false, reason: `read_error: ${err instanceof Error ? err.message : String(err)}` };
190992
191965
  }
@@ -191040,9 +192013,9 @@ var init_upload = __esm(() => {
191040
192013
  });
191041
192014
 
191042
192015
  // .tmp-runtime-src/telemetry/session-log.ts
191043
- import { existsSync as existsSync53, openSync as openSync2, writeSync, closeSync } from "node:fs";
191044
- import path25 from "node:path";
191045
- import { randomUUID as randomUUID6, createHash as createHash39 } from "node:crypto";
192016
+ import { existsSync as existsSync54, openSync as openSync2, writeSync, closeSync } from "node:fs";
192017
+ import path26 from "node:path";
192018
+ import { randomUUID as randomUUID6, createHash as createHash41 } from "node:crypto";
191046
192019
 
191047
192020
  class RealSessionLogger {
191048
192021
  cfg;
@@ -191065,7 +192038,7 @@ class RealSessionLogger {
191065
192038
  if (this.fd !== undefined)
191066
192039
  return;
191067
192040
  const dir = ensureSessionsDir();
191068
- this.filePath = path25.join(dir, `${this.session_id}.jsonl`);
192041
+ this.filePath = path26.join(dir, `${this.session_id}.jsonl`);
191069
192042
  this.fd = openSync2(this.filePath, "a");
191070
192043
  this.startedAtMs = Date.now();
191071
192044
  const event = {
@@ -191205,10 +192178,10 @@ function createSessionLogger(cfg, meta) {
191205
192178
  return new RealSessionLogger(cfg, meta);
191206
192179
  }
191207
192180
  function hashNotes(notes) {
191208
- return createHash39("sha256").update(notes).digest("hex").slice(0, 16);
192181
+ return createHash41("sha256").update(notes).digest("hex").slice(0, 16);
191209
192182
  }
191210
192183
  function sessionFileExists(filePath) {
191211
- return existsSync53(filePath);
192184
+ return existsSync54(filePath);
191212
192185
  }
191213
192186
  var init_session_log = __esm(() => {
191214
192187
  init_config();
@@ -191285,7 +192258,7 @@ __export(exports_skillmd2, {
191285
192258
  credentialHoles: () => credentialHoles2,
191286
192259
  credentialHoleToRuntimeHole: () => credentialHoleToRuntimeHole2
191287
192260
  });
191288
- import { mkdirSync as mkdirSync32, writeFileSync as writeFileSync28 } from "node:fs";
192261
+ import { mkdirSync as mkdirSync33, writeFileSync as writeFileSync29 } from "node:fs";
191289
192262
  import { homedir as homedir45 } from "node:os";
191290
192263
  import { join as join59, resolve as resolve14 } from "node:path";
191291
192264
  function escapeYaml2(s) {
@@ -191631,11 +192604,11 @@ function exportSkillMdLocal2(skill) {
191631
192604
  if (!dir.startsWith(base + "/") && dir !== base) {
191632
192605
  throw new Error("skill_export_path_escape");
191633
192606
  }
191634
- mkdirSync32(dir, { recursive: true });
191635
- const path26 = join59(dir, "SKILL.md");
192607
+ mkdirSync33(dir, { recursive: true });
192608
+ const path27 = join59(dir, "SKILL.md");
191636
192609
  const content = renderSkillMd2(skill);
191637
- writeFileSync28(path26, content);
191638
- return path26;
192610
+ writeFileSync29(path27, content);
192611
+ return path27;
191639
192612
  } catch (e) {
191640
192613
  console.warn(`[skillmd] export failed: ${e.message}`);
191641
192614
  return null;
@@ -191669,13 +192642,13 @@ __export(exports_domain_notes, {
191669
192642
  MAX_NOTES_BYTES: () => MAX_NOTES_BYTES2
191670
192643
  });
191671
192644
  import {
191672
- readFileSync as readFileSync40,
191673
- writeFileSync as writeFileSync29,
191674
- existsSync as existsSync54,
191675
- mkdirSync as mkdirSync33,
192645
+ readFileSync as readFileSync41,
192646
+ writeFileSync as writeFileSync30,
192647
+ existsSync as existsSync55,
192648
+ mkdirSync as mkdirSync34,
191676
192649
  statSync as statSync10,
191677
192650
  renameSync as renameSync4,
191678
- unlinkSync as unlinkSync7
192651
+ unlinkSync as unlinkSync8
191679
192652
  } from "node:fs";
191680
192653
  import { join as join60 } from "node:path";
191681
192654
  import { homedir as homedir46 } from "node:os";
@@ -191723,7 +192696,7 @@ function readDomainNote2(domain) {
191723
192696
  } catch {
191724
192697
  return null;
191725
192698
  }
191726
- if (!existsSync54(p))
192699
+ if (!existsSync55(p))
191727
192700
  return null;
191728
192701
  let size3 = 0;
191729
192702
  try {
@@ -191735,7 +192708,7 @@ function readDomainNote2(domain) {
191735
192708
  return null;
191736
192709
  let body;
191737
192710
  try {
191738
- body = readFileSync40(p, "utf-8");
192711
+ body = readFileSync41(p, "utf-8");
191739
192712
  } catch {
191740
192713
  return null;
191741
192714
  }
@@ -191765,19 +192738,19 @@ function writeDomainNote2(domain, body) {
191765
192738
  const trimmed = body.length > MAX_NOTES_BYTES2 ? body.slice(0, MAX_NOTES_BYTES2) : body;
191766
192739
  const dir = p.slice(0, p.lastIndexOf("/"));
191767
192740
  try {
191768
- if (!existsSync54(dir))
191769
- mkdirSync33(dir, { recursive: true });
192741
+ if (!existsSync55(dir))
192742
+ mkdirSync34(dir, { recursive: true });
191770
192743
  } catch {
191771
192744
  return;
191772
192745
  }
191773
192746
  const tmp = `${p}.tmp.${process.pid}.${Date.now()}`;
191774
192747
  try {
191775
- writeFileSync29(tmp, trimmed, "utf-8");
192748
+ writeFileSync30(tmp, trimmed, "utf-8");
191776
192749
  renameSync4(tmp, p);
191777
192750
  } catch {
191778
192751
  try {
191779
- if (existsSync54(tmp))
191780
- unlinkSync7(tmp);
192752
+ if (existsSync55(tmp))
192753
+ unlinkSync8(tmp);
191781
192754
  } catch {}
191782
192755
  }
191783
192756
  }
@@ -191892,7 +192865,7 @@ __export(exports_claude_mcp_register, {
191892
192865
  applyAllowList: () => applyAllowList,
191893
192866
  UNBROWSE_MCP_TOOL_NAMES: () => UNBROWSE_MCP_TOOL_NAMES
191894
192867
  });
191895
- import { readFileSync as readFileSync41, writeFileSync as writeFileSync30, existsSync as existsSync55, mkdirSync as mkdirSync34 } from "node:fs";
192868
+ import { readFileSync as readFileSync42, writeFileSync as writeFileSync31, existsSync as existsSync56, mkdirSync as mkdirSync35 } from "node:fs";
191896
192869
  import { join as join61, dirname as dirname11 } from "node:path";
191897
192870
  import { homedir as homedir47 } from "node:os";
191898
192871
  import { spawnSync as spawnSync4 } from "node:child_process";
@@ -191928,10 +192901,10 @@ function realClaudeCliAdapter() {
191928
192901
  },
191929
192902
  serverAlreadyRegistered(homeDir, entryName = "unbrowse") {
191930
192903
  const claudeJson = join61(homeDir, "(internal)");
191931
- if (!existsSync55(claudeJson))
192904
+ if (!existsSync56(claudeJson))
191932
192905
  return false;
191933
192906
  try {
191934
- const data2 = JSON.parse(readFileSync41(claudeJson, "utf-8"));
192907
+ const data2 = JSON.parse(readFileSync42(claudeJson, "utf-8"));
191935
192908
  return !!data2?.mcpServers?.[entryName];
191936
192909
  } catch {
191937
192910
  return false;
@@ -192034,9 +193007,9 @@ async function registerWithClaudeCode(opts = { serverCommand: "", serverArgs: []
192034
193007
  };
192035
193008
  }
192036
193009
  const serverAlreadyRegistered = adapter2.serverAlreadyRegistered(home);
192037
- if (serverAlreadyRegistered && existsSync55(settingsPath)) {
193010
+ if (serverAlreadyRegistered && existsSync56(settingsPath)) {
192038
193011
  try {
192039
- const existing = JSON.parse(readFileSync41(settingsPath, "utf-8"));
193012
+ const existing = JSON.parse(readFileSync42(settingsPath, "utf-8"));
192040
193013
  const existingAllow = existing?.permissions?.allow;
192041
193014
  const { added: added2 } = mergeAllowList(existingAllow, allowEntries);
192042
193015
  if (added2 === 0) {
@@ -192058,19 +193031,19 @@ async function registerWithClaudeCode(opts = { serverCommand: "", serverArgs: []
192058
193031
  serverRegistered = adapter2.registerServer(opts.serverCommand, opts.serverArgs, env2);
192059
193032
  }
192060
193033
  const settingsDir = dirname11(settingsPath);
192061
- if (!existsSync55(settingsDir))
192062
- mkdirSync34(settingsDir, { recursive: true });
193034
+ if (!existsSync56(settingsDir))
193035
+ mkdirSync35(settingsDir, { recursive: true });
192063
193036
  let current = {};
192064
- if (existsSync55(settingsPath)) {
193037
+ if (existsSync56(settingsPath)) {
192065
193038
  try {
192066
- current = JSON.parse(readFileSync41(settingsPath, "utf-8"));
193039
+ current = JSON.parse(readFileSync42(settingsPath, "utf-8"));
192067
193040
  } catch {
192068
- writeFileSync30(`${settingsPath}.backup-${Date.now()}`, readFileSync41(settingsPath, "utf-8"));
193041
+ writeFileSync31(`${settingsPath}.backup-${Date.now()}`, readFileSync42(settingsPath, "utf-8"));
192069
193042
  current = {};
192070
193043
  }
192071
193044
  }
192072
193045
  const { settings, added, already } = applyAllowList(current, allowEntries);
192073
- writeFileSync30(settingsPath, `${JSON.stringify(settings, null, 2)}
193046
+ writeFileSync31(settingsPath, `${JSON.stringify(settings, null, 2)}
192074
193047
  `);
192075
193048
  return {
192076
193049
  claude_cli_present: true,
@@ -192138,10 +193111,10 @@ __export(exports_mcp_hosts_register, {
192138
193111
  __testing__: () => __testing__
192139
193112
  });
192140
193113
  import {
192141
- readFileSync as readFileSync42,
192142
- writeFileSync as writeFileSync31,
192143
- existsSync as existsSync56,
192144
- mkdirSync as mkdirSync35,
193114
+ readFileSync as readFileSync43,
193115
+ writeFileSync as writeFileSync32,
193116
+ existsSync as existsSync57,
193117
+ mkdirSync as mkdirSync36,
192145
193118
  copyFileSync as copyFileSync4
192146
193119
  } from "node:fs";
192147
193120
  import { join as join62, dirname as dirname12 } from "node:path";
@@ -192172,32 +193145,32 @@ function configPathFor(host, home) {
192172
193145
  return join62(home, ".codeium", "windsurf", "mcp_config.json");
192173
193146
  }
192174
193147
  }
192175
- function safeReadJson(path26) {
192176
- if (!existsSync56(path26))
193148
+ function safeReadJson(path27) {
193149
+ if (!existsSync57(path27))
192177
193150
  return {};
192178
193151
  try {
192179
- const data2 = JSON.parse(readFileSync42(path26, "utf-8"));
193152
+ const data2 = JSON.parse(readFileSync43(path27, "utf-8"));
192180
193153
  return { data: data2 };
192181
193154
  } catch {
192182
193155
  return { parseError: true };
192183
193156
  }
192184
193157
  }
192185
- function backupAndReset(path26) {
193158
+ function backupAndReset(path27) {
192186
193159
  try {
192187
- copyFileSync4(path26, `${path26}.backup-${Date.now()}`);
193160
+ copyFileSync4(path27, `${path27}.backup-${Date.now()}`);
192188
193161
  } catch {}
192189
193162
  }
192190
- function writeJsonIfChanged(path26, next2, before2) {
193163
+ function writeJsonIfChanged(path27, next2, before2) {
192191
193164
  const nextSerialized = `${JSON.stringify(next2, null, 2)}
192192
193165
  `;
192193
193166
  if (before2 && JSON.stringify(before2) === JSON.stringify(next2))
192194
193167
  return false;
192195
- mkdirSync35(dirname12(path26), { recursive: true });
192196
- writeFileSync31(path26, nextSerialized);
193168
+ mkdirSync36(dirname12(path27), { recursive: true });
193169
+ writeFileSync32(path27, nextSerialized);
192197
193170
  return true;
192198
193171
  }
192199
193172
  function registerSimpleMcpServer(host, configPath4, serverCommand, serverArgs, env2, entryName = "unbrowse") {
192200
- if (!existsSync56(configPath4)) {
193173
+ if (!existsSync57(configPath4)) {
192201
193174
  return { host, config_path: configPath4, action: "not_detected" };
192202
193175
  }
192203
193176
  const { data: data2, parseError } = safeReadJson(configPath4);
@@ -192234,7 +193207,7 @@ function registerSimpleMcpServer(host, configPath4, serverCommand, serverArgs, e
192234
193207
  };
192235
193208
  }
192236
193209
  function registerContinueMcpServer(configPath4, serverCommand, serverArgs, env2, entryName = "unbrowse") {
192237
- if (!existsSync56(configPath4)) {
193210
+ if (!existsSync57(configPath4)) {
192238
193211
  return { host: "continue", config_path: configPath4, action: "not_detected" };
192239
193212
  }
192240
193213
  const { data: data2, parseError } = safeReadJson(configPath4);
@@ -192277,12 +193250,12 @@ function registerContinueMcpServer(configPath4, serverCommand, serverArgs, env2,
192277
193250
  };
192278
193251
  }
192279
193252
  function registerCodexMcpServer(configPath4, serverCommand, serverArgs, env2, entryName = "unbrowse") {
192280
- if (!existsSync56(configPath4)) {
193253
+ if (!existsSync57(configPath4)) {
192281
193254
  return { host: "codex", config_path: configPath4, action: "not_detected" };
192282
193255
  }
192283
193256
  let body;
192284
193257
  try {
192285
- body = readFileSync42(configPath4, "utf-8");
193258
+ body = readFileSync43(configPath4, "utf-8");
192286
193259
  } catch {
192287
193260
  return { host: "codex", config_path: configPath4, action: "parse_error", detail: "could not read file" };
192288
193261
  }
@@ -192311,8 +193284,8 @@ function registerCodexMcpServer(configPath4, serverCommand, serverArgs, env2, en
192311
193284
  const next2 = body.endsWith(`
192312
193285
  `) ? `${body}${proposedStanza}` : `${body}
192313
193286
  ${proposedStanza}`;
192314
- mkdirSync35(dirname12(configPath4), { recursive: true });
192315
- writeFileSync31(configPath4, next2);
193287
+ mkdirSync36(dirname12(configPath4), { recursive: true });
193288
+ writeFileSync32(configPath4, next2);
192316
193289
  return { host: "codex", config_path: configPath4, action: "merged" };
192317
193290
  }
192318
193291
  function registerMcpHosts(opts) {
@@ -192461,10 +193434,10 @@ __export(exports_payment_provider2, {
192461
193434
  _clearPaymentProviderCacheForTests: () => _clearPaymentProviderCacheForTests2
192462
193435
  });
192463
193436
  import fs8 from "node:fs";
192464
- import path26 from "node:path";
192465
- import os16 from "node:os";
193437
+ import path27 from "node:path";
193438
+ import os17 from "node:os";
192466
193439
  function configPath4() {
192467
- return process.env.UNBROWSE_CONFIG_PATH || path26.join(os16.homedir(), ".unbrowse", "config.json");
193440
+ return process.env.UNBROWSE_CONFIG_PATH || path27.join(os17.homedir(), ".unbrowse", "config.json");
192468
193441
  }
192469
193442
  function readConfigFile3() {
192470
193443
  const p = configPath4();
@@ -192478,7 +193451,7 @@ function readConfigFile3() {
192478
193451
  }
192479
193452
  function writeConfigFile3(merged) {
192480
193453
  const p = configPath4();
192481
- fs8.mkdirSync(path26.dirname(p), { recursive: true });
193454
+ fs8.mkdirSync(path27.dirname(p), { recursive: true });
192482
193455
  fs8.writeFileSync(p, JSON.stringify(merged, null, 2));
192483
193456
  }
192484
193457
  function getPaymentProviderConfig2() {
@@ -192761,7 +193734,7 @@ __export(exports_browser_cookies2, {
192761
193734
  });
192762
193735
  import { execFileSync as execFileSync8 } from "node:child_process";
192763
193736
  import { createDecipheriv as createDecipheriv4, pbkdf2Sync as pbkdf2Sync2 } from "node:crypto";
192764
- import { copyFileSync as copyFileSync5, existsSync as existsSync57, mkdtempSync as mkdtempSync5, readdirSync as readdirSync15, rmSync as rmSync4 } from "node:fs";
193737
+ import { copyFileSync as copyFileSync5, existsSync as existsSync58, mkdtempSync as mkdtempSync5, readdirSync as readdirSync15, rmSync as rmSync4 } from "node:fs";
192765
193738
  import { tmpdir as tmpdir5, homedir as homedir49, platform as platform6 } from "node:os";
192766
193739
  import { join as join63 } from "node:path";
192767
193740
  function getChromeUserDataDir2() {
@@ -192787,7 +193760,7 @@ function resolveChromiumCookiesPath2(opts) {
192787
193760
  join63(userDataDir, "Network", "Cookies"),
192788
193761
  join63(userDataDir, "Cookies")
192789
193762
  ];
192790
- return candidates.find((candidate) => existsSync57(candidate)) ?? candidates[0] ?? null;
193763
+ return candidates.find((candidate) => existsSync58(candidate)) ?? candidates[0] ?? null;
192791
193764
  }
192792
193765
  function getFirefoxProfilesRoot2() {
192793
193766
  const home = homedir49();
@@ -192808,7 +193781,7 @@ function getFirefoxProfilesRoot2() {
192808
193781
  function pickFirefoxProfile2(profilesRoot, profile) {
192809
193782
  if (profile) {
192810
193783
  const candidate2 = join63(profilesRoot, profile, "cookies.sqlite");
192811
- return existsSync57(candidate2) ? candidate2 : null;
193784
+ return existsSync58(candidate2) ? candidate2 : null;
192812
193785
  }
192813
193786
  const entries = readdirSync15(profilesRoot, { withFileTypes: true });
192814
193787
  const defaultRelease = entries.find((e) => e.isDirectory() && e.name.includes("default-release"));
@@ -192816,11 +193789,11 @@ function pickFirefoxProfile2(profilesRoot, profile) {
192816
193789
  if (!targetDir)
192817
193790
  return null;
192818
193791
  const candidate = join63(profilesRoot, targetDir, "cookies.sqlite");
192819
- return existsSync57(candidate) ? candidate : null;
193792
+ return existsSync58(candidate) ? candidate : null;
192820
193793
  }
192821
193794
  function getFirefoxCookiesPath2(profile) {
192822
193795
  const profilesRoot = getFirefoxProfilesRoot2();
192823
- if (!profilesRoot || !existsSync57(profilesRoot))
193796
+ if (!profilesRoot || !existsSync58(profilesRoot))
192824
193797
  return null;
192825
193798
  return pickFirefoxProfile2(profilesRoot, profile);
192826
193799
  }
@@ -192895,7 +193868,7 @@ function withTempCopy2(dbPath, fn) {
192895
193868
  copyFileSync5(dbPath, tempDb);
192896
193869
  for (const ext of ["-wal", "-shm"]) {
192897
193870
  const src = dbPath + ext;
192898
- if (existsSync57(src))
193871
+ if (existsSync58(src))
192899
193872
  copyFileSync5(src, tempDb + ext);
192900
193873
  }
192901
193874
  return fn(tempDb);
@@ -192940,7 +193913,7 @@ function extractFromChromium2(domain, opts) {
192940
193913
  const warnings = [];
192941
193914
  const dbPath = resolveChromiumCookiesPath2(opts);
192942
193915
  const sourceLabel = opts?.browserName || "Chromium";
192943
- if (!dbPath || !existsSync57(dbPath)) {
193916
+ if (!dbPath || !existsSync58(dbPath)) {
192944
193917
  warnings.push(`${sourceLabel} cookies DB not found${dbPath ? ` at ${dbPath}` : ""}`);
192945
193918
  return { cookies: [], source: null, warnings };
192946
193919
  }
@@ -193036,7 +194009,7 @@ function extractBrowserCookies2(domain, opts) {
193036
194009
  const __result = _extractBrowserCookiesInner2(domain, opts);
193037
194010
  try {
193038
194011
  const traceDir = join63(homedir49(), ".unbrowse", "traces");
193039
- if (!existsSync57(traceDir))
194012
+ if (!existsSync58(traceDir))
193040
194013
  mkdirSync(traceDir, { recursive: true });
193041
194014
  const entry = JSON.stringify({
193042
194015
  d: domain,
@@ -193090,7 +194063,7 @@ function scanAllBrowserSessions2(domain) {
193090
194063
  const home = homedir49();
193091
194064
  for (const browser of CHROMIUM_BROWSERS2) {
193092
194065
  const userDataDir = platform6() === "darwin" ? join63(home, "Library", "Application Support", browser.macPath) : platform6() === "win32" ? join63(process.env.LOCALAPPDATA ?? join63(home, "AppData", "Local"), browser.macPath, "User Data") : join63(home, ".config", browser.macPath.toLowerCase());
193093
- if (!existsSync57(userDataDir))
194066
+ if (!existsSync58(userDataDir))
193094
194067
  continue;
193095
194068
  try {
193096
194069
  const result = extractFromChromium2(domain, {
@@ -193133,7 +194106,7 @@ function chromiumCookiesPathForUserDataDir2(userDataDir) {
193133
194106
  join63(userDataDir, "Default", "Network", "Cookies")
193134
194107
  ];
193135
194108
  for (const p of candidates)
193136
- if (existsSync57(p))
194109
+ if (existsSync58(p))
193137
194110
  return p;
193138
194111
  return null;
193139
194112
  }
@@ -193167,13 +194140,13 @@ function scanChromiumDomainSummary2(userDataDir, browserName) {
193167
194140
  }
193168
194141
  function scanFirefoxDomainSummary2() {
193169
194142
  const profilesRoot = getFirefoxProfilesRoot2();
193170
- if (!profilesRoot || !existsSync57(profilesRoot))
194143
+ if (!profilesRoot || !existsSync58(profilesRoot))
193171
194144
  return null;
193172
194145
  const profile = pickFirefoxProfile2(profilesRoot);
193173
194146
  if (!profile)
193174
194147
  return null;
193175
194148
  const cookiesPath = getFirefoxCookiesPath2(profile);
193176
- if (!cookiesPath || !existsSync57(cookiesPath))
194149
+ if (!cookiesPath || !existsSync58(cookiesPath))
193177
194150
  return null;
193178
194151
  try {
193179
194152
  return withTempCopy2(cookiesPath, (temp) => {
@@ -193206,7 +194179,7 @@ function listCookieDomains2() {
193206
194179
  const home = homedir49();
193207
194180
  for (const browser of CHROMIUM_BROWSERS2) {
193208
194181
  const userDataDir = platform6() === "darwin" ? join63(home, "Library", "Application Support", browser.macPath) : platform6() === "win32" ? join63(process.env.LOCALAPPDATA ?? join63(home, "AppData", "Local"), browser.macPath, "User Data") : join63(home, ".config", browser.macPath.toLowerCase());
193209
- if (!existsSync57(userDataDir)) {
194182
+ if (!existsSync58(userDataDir)) {
193210
194183
  browsersSkipped.push(`${browser.name} (not installed)`);
193211
194184
  continue;
193212
194185
  }
@@ -194377,7 +195350,7 @@ function extractSPAData2(html3) {
194377
195350
  const MAX_BRANCHES = 12;
194378
195351
  const MIN_BRANCH_LEN = 3;
194379
195352
  const MAX_PATH_DEPTH = 6;
194380
- const visit = (node2, path27, depth) => {
195353
+ const visit = (node2, path28, depth) => {
194381
195354
  if (branchEmissions.length >= MAX_BRANCHES || depth > MAX_PATH_DEPTH)
194382
195355
  return;
194383
195356
  if (Array.isArray(node2)) {
@@ -194392,19 +195365,19 @@ function extractSPAData2(html3) {
194392
195365
  type: "spa-initial-state",
194393
195366
  data: node2,
194394
195367
  element_count: node2.length,
194395
- selector: path27 || "(root)"
195368
+ selector: path28 || "(root)"
194396
195369
  });
194397
195370
  }
194398
195371
  }
194399
195372
  }
194400
195373
  for (let i = 0;i < Math.min(node2.length, 20); i++) {
194401
- visit(node2[i], `${path27}[${i}]`, depth + 1);
195374
+ visit(node2[i], `${path28}[${i}]`, depth + 1);
194402
195375
  }
194403
195376
  return;
194404
195377
  }
194405
195378
  if (node2 && typeof node2 === "object") {
194406
195379
  for (const [key2, value] of Object.entries(node2)) {
194407
- visit(value, path27 ? `${path27}.${key2}` : key2, depth + 1);
195380
+ visit(value, path28 ? `${path28}.${key2}` : key2, depth + 1);
194408
195381
  }
194409
195382
  }
194410
195383
  };
@@ -197288,7 +198261,7 @@ __export(exports_x402_fetch, {
197288
198261
  x402Fetch: () => x402Fetch2,
197289
198262
  resolveWalletConfig: () => resolveWalletConfig2
197290
198263
  });
197291
- import { existsSync as existsSync58, readFileSync as readFileSync43 } from "node:fs";
198264
+ import { existsSync as existsSync59, readFileSync as readFileSync44 } from "node:fs";
197292
198265
  import { homedir as homedir50 } from "node:os";
197293
198266
  import { join as join64 } from "node:path";
197294
198267
  function resolveWalletConfig2(env2 = process.env) {
@@ -197306,10 +198279,10 @@ function resolveWalletConfig2(env2 = process.env) {
197306
198279
  return { adapter: "none", max_cost_usd };
197307
198280
  }
197308
198281
  const home = env2.HOME || homedir50();
197309
- if (existsSync58(join64(home, ".lobster", "agents.json"))) {
198282
+ if (existsSync59(join64(home, ".lobster", "agents.json"))) {
197310
198283
  return { adapter: "lobster", max_cost_usd };
197311
198284
  }
197312
- if (existsSync58(join64(home, ".privy", "session.json"))) {
198285
+ if (existsSync59(join64(home, ".privy", "session.json"))) {
197313
198286
  return { adapter: "privy", max_cost_usd };
197314
198287
  }
197315
198288
  if (env2.UNBROWSE_WALLET_KEY?.trim()) {
@@ -197376,11 +198349,11 @@ async function signViaLobster2(envelope) {
197376
198349
  async function signViaPrivy2(envelope) {
197377
198350
  const home = process.env.HOME || homedir50();
197378
198351
  const sessionPath2 = join64(home, ".privy", "session.json");
197379
- if (!existsSync58(sessionPath2))
198352
+ if (!existsSync59(sessionPath2))
197380
198353
  return { error: "privy session missing" };
197381
198354
  let sessionToken = "";
197382
198355
  try {
197383
- const raw = JSON.parse(readFileSync43(sessionPath2, "utf8"));
198356
+ const raw = JSON.parse(readFileSync44(sessionPath2, "utf8"));
197384
198357
  sessionToken = raw.token ?? raw.access_token ?? "";
197385
198358
  } catch {
197386
198359
  return { error: "privy session unreadable" };
@@ -197439,9 +198412,9 @@ async function signViaGeneric2(envelope, keyRef) {
197439
198412
  if (signer.startsWith("exec:")) {
197440
198413
  const cmd = signer.slice("exec:".length);
197441
198414
  try {
197442
- const { spawn: spawn11 } = await import("node:child_process");
198415
+ const { spawn: spawn12 } = await import("node:child_process");
197443
198416
  return await new Promise((resolve15) => {
197444
- const proc = spawn11(cmd, [keyRef], { stdio: ["pipe", "pipe", "pipe"], shell: true });
198417
+ const proc = spawn12(cmd, [keyRef], { stdio: ["pipe", "pipe", "pipe"], shell: true });
197445
198418
  let out = "";
197446
198419
  let err = "";
197447
198420
  proc.stdout.on("data", (d) => {
@@ -197782,8 +198755,8 @@ __export(exports_version2, {
197782
198755
  DEFAULT_BACKEND_URL: () => DEFAULT_BACKEND_URL2,
197783
198756
  CODE_HASH: () => CODE_HASH2
197784
198757
  });
197785
- import { createHash as createHash40 } from "crypto";
197786
- import { existsSync as existsSync59, readFileSync as readFileSync44, readdirSync as readdirSync16 } from "fs";
198758
+ import { createHash as createHash42 } from "crypto";
198759
+ import { existsSync as existsSync60, readFileSync as readFileSync45, readdirSync as readdirSync16 } from "fs";
197787
198760
  import { dirname as dirname13, join as join65, parse as parse10 } from "path";
197788
198761
  import { fileURLToPath as fileURLToPath7 } from "url";
197789
198762
  import { execSync as execSync7 } from "child_process";
@@ -197807,10 +198780,10 @@ function collectTsFiles2(dir) {
197807
198780
  return results;
197808
198781
  }
197809
198782
  function hashFiles2(srcDir, files) {
197810
- const hash = createHash40("sha256");
198783
+ const hash = createHash42("sha256");
197811
198784
  for (const file of files) {
197812
198785
  hash.update(file.slice(srcDir.length));
197813
- hash.update(readFileSync44(file, "utf-8"));
198786
+ hash.update(readFileSync45(file, "utf-8"));
197814
198787
  }
197815
198788
  return hash.digest("hex").slice(0, 12);
197816
198789
  }
@@ -197824,7 +198797,7 @@ function resolveCodeHashSourceDir2(moduleDir) {
197824
198797
  ];
197825
198798
  for (const candidate of candidates) {
197826
198799
  try {
197827
- if (!existsSync59(candidate))
198800
+ if (!existsSync60(candidate))
197828
198801
  continue;
197829
198802
  const files = collectTsFiles2(candidate);
197830
198803
  if (files.length > 0)
@@ -197847,7 +198820,7 @@ function computeCodeHash2() {
197847
198820
  } catch {}
197848
198821
  const pkgVersion = getPackageVersion2();
197849
198822
  if (pkgVersion !== "unknown") {
197850
- return createHash40("sha256").update(`package:${pkgVersion}`).digest("hex").slice(0, 12);
198823
+ return createHash42("sha256").update(`package:${pkgVersion}`).digest("hex").slice(0, 12);
197851
198824
  }
197852
198825
  return "compiled";
197853
198826
  }
@@ -197874,7 +198847,7 @@ function getPackageVersionForModuleDir2(moduleDir) {
197874
198847
  const root2 = parse10(dir).root;
197875
198848
  while (true) {
197876
198849
  try {
197877
- const pkg = JSON.parse(readFileSync44(join65(dir, "package.json"), "utf-8"));
198850
+ const pkg = JSON.parse(readFileSync45(join65(dir, "package.json"), "utf-8"));
197878
198851
  return typeof pkg.version === "string" ? pkg.version : "unknown";
197879
198852
  } catch {}
197880
198853
  if (dir === root2)
@@ -198072,16 +199045,16 @@ var init_build = __esm(() => {
198072
199045
 
198073
199046
  // .tmp-runtime-src/cli-v7/act/fill-form.ts
198074
199047
  import { spawnSync as spawnSync5 } from "node:child_process";
198075
- import { randomBytes as randomBytes22, createHash as createHash41 } from "node:crypto";
199048
+ import { randomBytes as randomBytes22, createHash as createHash43 } from "node:crypto";
198076
199049
  import { homedir as homedir51 } from "node:os";
198077
199050
  import { join as join66 } from "node:path";
198078
199051
  function sha256Hex8(s) {
198079
- return createHash41("sha256").update(s, "utf8").digest("hex");
199052
+ return createHash43("sha256").update(s, "utf8").digest("hex");
198080
199053
  }
198081
199054
  function deriveFormContextHash(sessionId, formSelector, url, nowMs = Date.now()) {
198082
199055
  const bucket = Math.floor(nowMs / FIVE_MINUTES_MS5).toString();
198083
199056
  const payload = `${sessionId}:form:${formSelector}:${url}:${bucket}`;
198084
- return createHash41("sha256").update(payload, "utf8").digest("hex");
199057
+ return createHash43("sha256").update(payload, "utf8").digest("hex");
198085
199058
  }
198086
199059
  function formSlotEnumExpression(formSelector) {
198087
199060
  const fs9 = JSON.stringify(formSelector);
@@ -198437,7 +199410,7 @@ var init_fill_form = __esm(() => {
198437
199410
  });
198438
199411
 
198439
199412
  // .tmp-runtime-src/cli-v7/act/session-park.ts
198440
- import { createHash as createHash42 } from "node:crypto";
199413
+ import { createHash as createHash44 } from "node:crypto";
198441
199414
  function canonicalizeSignedFragment5(body) {
198442
199415
  const pointersCanonical = body.boundPointers.map((bp) => ({
198443
199416
  l1_pointer: bp.l1_pointer,
@@ -198552,7 +199525,7 @@ async function handler36(parsed, opts) {
198552
199525
  }
198553
199526
  const recForDelete = rec;
198554
199527
  const parkedAt = Date.now();
198555
- const capturedEndpointsHash = createHash42("sha256").update(`${rec.sessionId}:${targetUrl}:v7.2.0-preview.0:empty`).digest("hex");
199528
+ const capturedEndpointsHash = createHash44("sha256").update(`${rec.sessionId}:${targetUrl}:v7.2.0-preview.0:empty`).digest("hex");
198556
199529
  const { signature: sigBytes, walletPubkey: pubBytes } = await signBytes(new TextEncoder().encode(""));
198557
199530
  const walletPubkeyHex = bytesToHex18(pubBytes);
198558
199531
  const bodyWithoutSig = {
@@ -199090,7 +200063,7 @@ async function drainOnce(queueDir, processor, maxAttempts = 3) {
199090
200063
  `);
199091
200064
  }
199092
200065
  }
199093
- for (const { path: path27, envelope } of accepted) {
200066
+ for (const { path: path28, envelope } of accepted) {
199094
200067
  const lockPath = join67(queueDir, sanitizeDomain(envelope.domain) + ".lock");
199095
200068
  const release = await acquireLock(lockPath);
199096
200069
  if (release === null)
@@ -199098,7 +200071,7 @@ async function drainOnce(queueDir, processor, maxAttempts = 3) {
199098
200071
  try {
199099
200072
  try {
199100
200073
  await processor(envelope.job);
199101
- await deleteJob(path27);
200074
+ await deleteJob(path28);
199102
200075
  processed++;
199103
200076
  } catch {
199104
200077
  const newAttempts = envelope.attempts + 1;
@@ -199112,10 +200085,10 @@ async function drainOnce(queueDir, processor, maxAttempts = 3) {
199112
200085
  attempts: newAttempts,
199113
200086
  job: envelope.job
199114
200087
  });
199115
- await deleteJob(path27);
200088
+ await deleteJob(path28);
199116
200089
  deadLettered++;
199117
200090
  } else {
199118
- await rewriteJobAtPath(path27, {
200091
+ await rewriteJobAtPath(path28, {
199119
200092
  version: 1,
199120
200093
  domain: envelope.domain,
199121
200094
  queuedAt: Date.now(),
@@ -199211,10 +200184,10 @@ async function writeCaptureSpool2(spoolDir, envelope) {
199211
200184
  await rename5(tmpPath, finalPath);
199212
200185
  return finalPath;
199213
200186
  }
199214
- async function rewriteCaptureSpoolAtPath(path27, envelope) {
199215
- const tmpPath = `${path27}.tmp`;
200187
+ async function rewriteCaptureSpoolAtPath(path28, envelope) {
200188
+ const tmpPath = `${path28}.tmp`;
199216
200189
  await writeFile8(tmpPath, JSON.stringify(envelope));
199217
- await rename5(tmpPath, path27);
200190
+ await rename5(tmpPath, path28);
199218
200191
  }
199219
200192
  async function listCaptureSpool(spoolDir) {
199220
200193
  const absDir = resolve15(spoolDir);
@@ -199234,23 +200207,23 @@ async function listCaptureSpool(spoolDir) {
199234
200207
  continue;
199235
200208
  if (entry.name.endsWith(".tmp"))
199236
200209
  continue;
199237
- const path27 = join68(absDir, entry.name);
200210
+ const path28 = join68(absDir, entry.name);
199238
200211
  let parsed;
199239
200212
  try {
199240
- parsed = JSON.parse(await readFile10(path27, "utf8"));
200213
+ parsed = JSON.parse(await readFile10(path28, "utf8"));
199241
200214
  } catch {
199242
200215
  continue;
199243
200216
  }
199244
200217
  if (!isCaptureSpoolEnvelope(parsed))
199245
200218
  continue;
199246
- results.push({ path: path27, envelope: parsed });
200219
+ results.push({ path: path28, envelope: parsed });
199247
200220
  }
199248
200221
  results.sort((a, b) => a.envelope.capturedAt - b.envelope.capturedAt);
199249
200222
  return results;
199250
200223
  }
199251
- async function deleteCaptureSpool(path27) {
200224
+ async function deleteCaptureSpool(path28) {
199252
200225
  try {
199253
- await unlink6(path27);
200226
+ await unlink6(path28);
199254
200227
  } catch (err) {
199255
200228
  if (err.code === "ENOENT")
199256
200229
  return;
@@ -199264,7 +200237,7 @@ async function drainCaptureSpoolOnce(spoolDir, processor, maxAttempts = 3) {
199264
200237
  let failed = 0;
199265
200238
  let deadLettered = 0;
199266
200239
  const accepted = await listCaptureSpool(spoolDir);
199267
- for (const { path: path27, envelope } of accepted) {
200240
+ for (const { path: path28, envelope } of accepted) {
199268
200241
  const lockPath = join68(resolve15(spoolDir), sanitizeDomain(envelope.domain) + ".lock");
199269
200242
  const release = await acquireLock(lockPath);
199270
200243
  if (release === null)
@@ -199272,19 +200245,19 @@ async function drainCaptureSpoolOnce(spoolDir, processor, maxAttempts = 3) {
199272
200245
  try {
199273
200246
  try {
199274
200247
  await processor(envelope.capture);
199275
- await deleteCaptureSpool(path27);
200248
+ await deleteCaptureSpool(path28);
199276
200249
  processed++;
199277
200250
  } catch {
199278
200251
  const newAttempts = envelope.attempts + 1;
199279
200252
  if (newAttempts >= maxAttempts) {
199280
200253
  const deadDir = join68(resolve15(spoolDir), "dead");
199281
200254
  await mkdir11(deadDir, { recursive: true });
199282
- await rename5(path27, join68(deadDir, basename4(path27))).catch(async () => {
199283
- await deleteCaptureSpool(path27);
200255
+ await rename5(path28, join68(deadDir, basename4(path28))).catch(async () => {
200256
+ await deleteCaptureSpool(path28);
199284
200257
  });
199285
200258
  deadLettered++;
199286
200259
  } else {
199287
- await rewriteCaptureSpoolAtPath(path27, {
200260
+ await rewriteCaptureSpoolAtPath(path28, {
199288
200261
  ...envelope,
199289
200262
  capturedAt: Date.now(),
199290
200263
  attempts: newAttempts
@@ -199353,18 +200326,18 @@ function hasInlineAuth2(proxyUrl) {
199353
200326
  }
199354
200327
  function spawnAuthForwarder2(upstreamUrl) {
199355
200328
  try {
199356
- const { spawnSync: spawnSync6, spawn: spawn11 } = __require("node:child_process");
199357
- const path27 = __require("node:path");
200329
+ const { spawnSync: spawnSync6, spawn: spawn12 } = __require("node:child_process");
200330
+ const path28 = __require("node:path");
199358
200331
  const fs9 = __require("node:fs");
199359
200332
  let here = __dirname;
199360
200333
  let scriptPath = null;
199361
200334
  for (let i = 0;i < 6; i++) {
199362
- const candidate = path27.join(here, "scripts", "local-proxy-auth-forwarder.py");
200335
+ const candidate = path28.join(here, "scripts", "local-proxy-auth-forwarder.py");
199363
200336
  if (fs9.existsSync(candidate)) {
199364
200337
  scriptPath = candidate;
199365
200338
  break;
199366
200339
  }
199367
- const parent2 = path27.dirname(here);
200340
+ const parent2 = path28.dirname(here);
199368
200341
  if (parent2 === here)
199369
200342
  break;
199370
200343
  here = parent2;
@@ -199374,12 +200347,12 @@ function spawnAuthForwarder2(upstreamUrl) {
199374
200347
  `);
199375
200348
  return null;
199376
200349
  }
199377
- const os17 = __require("node:os");
199378
- const readyFile = path27.join(os17.tmpdir(), `kuri-proxy-forwarder-${process.pid}-${Date.now()}.ready`);
200350
+ const os18 = __require("node:os");
200351
+ const readyFile = path28.join(os18.tmpdir(), `kuri-proxy-forwarder-${process.pid}-${Date.now()}.ready`);
199379
200352
  try {
199380
200353
  fs9.unlinkSync(readyFile);
199381
200354
  } catch {}
199382
- const child = spawn11("python3", [scriptPath, "--upstream", upstreamUrl, "--quiet", "--ready-file", readyFile], {
200355
+ const child = spawn12("python3", [scriptPath, "--upstream", upstreamUrl, "--quiet", "--ready-file", readyFile], {
199383
200356
  stdio: "ignore",
199384
200357
  detached: true
199385
200358
  });
@@ -199807,14 +200780,14 @@ __export(exports_server, {
199807
200780
  getInflightMcpBridgedCount: () => getInflightMcpBridgedCount
199808
200781
  });
199809
200782
  import { execSync as execSync8 } from "node:child_process";
199810
- import { mkdirSync as mkdirSync36, unlinkSync as unlinkSync8, writeFileSync as writeFileSync32 } from "node:fs";
199811
- import path27 from "node:path";
200783
+ import { mkdirSync as mkdirSync37, unlinkSync as unlinkSync9, writeFileSync as writeFileSync33 } from "node:fs";
200784
+ import path28 from "node:path";
199812
200785
  function updatePidFile(pidFile, host = "127.0.0.1", port = 6969) {
199813
200786
  if (!pidFile)
199814
200787
  return;
199815
200788
  try {
199816
- mkdirSync36(path27.dirname(pidFile), { recursive: true });
199817
- writeFileSync32(pidFile, JSON.stringify({
200789
+ mkdirSync37(path28.dirname(pidFile), { recursive: true });
200790
+ writeFileSync33(pidFile, JSON.stringify({
199818
200791
  pid: process.pid,
199819
200792
  base_url: `http://${host}:${port}`,
199820
200793
  started_at: new Date().toISOString(),
@@ -199827,7 +200800,7 @@ function clearPidFile(pidFile) {
199827
200800
  if (!pidFile)
199828
200801
  return;
199829
200802
  try {
199830
- unlinkSync8(pidFile);
200803
+ unlinkSync9(pidFile);
199831
200804
  } catch {}
199832
200805
  }
199833
200806
  function getInflightMcpBridgedCount() {
@@ -199964,7 +200937,35 @@ var init_server = __esm(async () => {
199964
200937
 
199965
200938
  // .tmp-runtime-src/cli.ts
199966
200939
  var import_dotenv = __toESM(require_main(), 1);
199967
- import { spawn as spawn11 } from "child_process";
200940
+ import { spawn as spawn12 } from "child_process";
200941
+ import { createHash as createHash45 } from "crypto";
200942
+
200943
+ // .tmp-runtime-src/lib/infer-write-method.ts
200944
+ var WRITE_METHODS = new Set(["POST", "PUT", "PATCH", "DELETE"]);
200945
+ var READ_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
200946
+ var INTENT_RULES = [
200947
+ ["DELETE", /\b(delete|remove|destroy|cancel|unsubscribe|revoke|deregister)\b/i],
200948
+ ["PUT", /\b(replace|overwrite|put|set\s+the\s+entire)\b/i],
200949
+ ["PATCH", /\b(update|edit|modify|change|rename|patch|adjust|toggle)\b/i],
200950
+ ["POST", /\b(create|post|add|submit|new|register|sign\s*up|send|upload|publish|insert|book|order|comment|reply|like|upvote|vote)\b/i]
200951
+ ];
200952
+ function inferWriteMethod(explicit, intent, hasBody) {
200953
+ if (explicit) {
200954
+ const m = explicit.toUpperCase();
200955
+ if (WRITE_METHODS.has(m))
200956
+ return m;
200957
+ if (READ_METHODS.has(m))
200958
+ return;
200959
+ }
200960
+ const text = intent || "";
200961
+ for (const [verb, re] of INTENT_RULES) {
200962
+ if (re.test(text))
200963
+ return verb;
200964
+ }
200965
+ if (hasBody)
200966
+ return "POST";
200967
+ return;
200968
+ }
199968
200969
 
199969
200970
  // .tmp-runtime-src/env/kuri-proxy-bridge.ts
199970
200971
  init_proxy_fetch();
@@ -201123,7 +202124,7 @@ init_telemetry_attribution();
201123
202124
  import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, existsSync as existsSync26, mkdirSync as mkdirSync10, readdirSync as readdirSync6, unlinkSync as unlinkSync3 } from "fs";
201124
202125
  import { join as join33 } from "path";
201125
202126
  import { homedir as homedir29, hostname as hostname2, release as osRelease2 } from "os";
201126
- import { randomBytes as randomBytes15, createHash as createHash31 } from "crypto";
202127
+ import { randomBytes as randomBytes15, createHash as createHash32 } from "crypto";
201127
202128
  import { createInterface as createInterface3 } from "readline";
201128
202129
  import { execSync as execSync5 } from "child_process";
201129
202130
  var PROFILE_NAME2 = sanitizeProfileName2(process.env.UNBROWSE_PROFILE ?? DEFAULT_PROFILE ?? "");
@@ -202730,19 +203731,19 @@ function getLastVendorBlock(windowMs = 60000) {
202730
203731
  }
202731
203732
 
202732
203733
  // .tmp-runtime-src/runtime/paths.ts
202733
- import { existsSync as existsSync44, mkdirSync as mkdirSync26, realpathSync as realpathSync2 } from "node:fs";
202734
- import path19 from "node:path";
203734
+ import { existsSync as existsSync45, mkdirSync as mkdirSync27, realpathSync as realpathSync2 } from "node:fs";
203735
+ import path20 from "node:path";
202735
203736
  import { createRequire as createRequire4 } from "node:module";
202736
203737
  import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL2 } from "node:url";
202737
203738
  function resolveSiblingEntrypoint2(metaUrl, basename3) {
202738
203739
  const file = fileURLToPath6(metaUrl);
202739
- return path19.join(path19.dirname(file), `${basename3}${path19.extname(file) || ".js"}`);
203740
+ return path20.join(path20.dirname(file), `${basename3}${path20.extname(file) || ".js"}`);
202740
203741
  }
202741
203742
  function isBundledVirtualEntrypoint(entrypoint) {
202742
203743
  return entrypoint.startsWith("/$bunfs/");
202743
203744
  }
202744
203745
  function runtimeArgsForEntrypoint2(metaUrl, entrypoint) {
202745
- if (path19.extname(entrypoint) !== ".ts") {
203746
+ if (path20.extname(entrypoint) !== ".ts") {
202746
203747
  return process.platform === "win32" ? [pathToFileURL2(entrypoint).href] : [entrypoint];
202747
203748
  }
202748
203749
  if (process.versions.bun)
@@ -202750,8 +203751,8 @@ function runtimeArgsForEntrypoint2(metaUrl, entrypoint) {
202750
203751
  try {
202751
203752
  const req = createRequire4(metaUrl);
202752
203753
  const tsxPkg = req.resolve("tsx/package.json");
202753
- const tsxLoader = path19.join(path19.dirname(tsxPkg), "dist", "loader.mjs");
202754
- if (existsSync44(tsxLoader))
203754
+ const tsxLoader = path20.join(path20.dirname(tsxPkg), "dist", "loader.mjs");
203755
+ if (existsSync45(tsxLoader))
202755
203756
  return ["--import", pathToFileURL2(tsxLoader).href, entrypoint];
202756
203757
  } catch {}
202757
203758
  return ["--import", "tsx", entrypoint];
@@ -202769,7 +203770,7 @@ function isMainModule(metaUrl) {
202769
203770
  try {
202770
203771
  return realpathSync2(entry) === realpathSync2(modulePath);
202771
203772
  } catch {
202772
- return path19.resolve(entry) === path19.resolve(modulePath);
203773
+ return path20.resolve(entry) === path20.resolve(modulePath);
202773
203774
  }
202774
203775
  }
202775
203776
 
@@ -202815,52 +203816,52 @@ init_client2();
202815
203816
  init_logger();
202816
203817
  init_wallet();
202817
203818
  import { execFileSync as execFileSync7 } from "node:child_process";
202818
- import { existsSync as existsSync47, mkdirSync as mkdirSync28, writeFileSync as writeFileSync24 } from "node:fs";
202819
- import os13 from "node:os";
202820
- import path21 from "node:path";
203819
+ import { existsSync as existsSync48, mkdirSync as mkdirSync29, writeFileSync as writeFileSync25 } from "node:fs";
203820
+ import os14 from "node:os";
203821
+ import path22 from "node:path";
202821
203822
 
202822
203823
  // .tmp-runtime-src/runtime/update-hints.ts
202823
203824
  init_paths();
202824
- import { existsSync as existsSync46, mkdirSync as mkdirSync27, readFileSync as readFileSync34, writeFileSync as writeFileSync23 } from "node:fs";
202825
- import os12 from "node:os";
202826
- import path20 from "node:path";
203825
+ import { existsSync as existsSync47, mkdirSync as mkdirSync28, readFileSync as readFileSync35, writeFileSync as writeFileSync24 } from "node:fs";
203826
+ import os13 from "node:os";
203827
+ import path21 from "node:path";
202827
203828
  var DEFAULT_INTERVAL_MS = 12 * 60 * 60 * 1000;
202828
203829
  var CODEX_MARKER = "# Unbrowse update hints — managed by unbrowse setup";
202829
203830
  function getHomeDir() {
202830
- return process.env.HOME || os12.homedir();
203831
+ return process.env.HOME || os13.homedir();
202831
203832
  }
202832
203833
  function getConfigDir6() {
202833
203834
  if (process.env.UNBROWSE_CONFIG_DIR)
202834
203835
  return process.env.UNBROWSE_CONFIG_DIR;
202835
- return path20.join(getHomeDir(), ".unbrowse");
203836
+ return path21.join(getHomeDir(), ".unbrowse");
202836
203837
  }
202837
203838
  function ensureDir4(dir) {
202838
- if (!existsSync46(dir))
202839
- mkdirSync27(dir, { recursive: true });
203839
+ if (!existsSync47(dir))
203840
+ mkdirSync28(dir, { recursive: true });
202840
203841
  return dir;
202841
203842
  }
202842
203843
  function readJsonFile(file) {
202843
203844
  try {
202844
- return JSON.parse(readFileSync34(file, "utf8"));
203845
+ return JSON.parse(readFileSync35(file, "utf8"));
202845
203846
  } catch {
202846
203847
  return null;
202847
203848
  }
202848
203849
  }
202849
203850
  function writeJsonFile(file, value) {
202850
- ensureDir4(path20.dirname(file));
202851
- writeFileSync23(file, `${JSON.stringify(value, null, 2)}
203851
+ ensureDir4(path21.dirname(file));
203852
+ writeFileSync24(file, `${JSON.stringify(value, null, 2)}
202852
203853
  `);
202853
203854
  }
202854
203855
  function getInstallSourcePath() {
202855
- return path20.join(getConfigDir6(), "install-source.json");
203856
+ return path21.join(getConfigDir6(), "install-source.json");
202856
203857
  }
202857
203858
  function detectRepoRoot(start4) {
202858
- let dir = path20.resolve(start4);
202859
- const root2 = path20.parse(dir).root;
203859
+ let dir = path21.resolve(start4);
203860
+ const root2 = path21.parse(dir).root;
202860
203861
  while (dir !== root2) {
202861
- if (existsSync46(path20.join(dir, ".git")))
203862
+ if (existsSync47(path21.join(dir, ".git")))
202862
203863
  return dir;
202863
- dir = path20.dirname(dir);
203864
+ dir = path21.dirname(dir);
202864
203865
  }
202865
203866
  return;
202866
203867
  }
@@ -202869,7 +203870,7 @@ function detectInstallMethod(packageRoot) {
202869
203870
  return "repo-clone";
202870
203871
  if (process.env.UNBROWSE_SETUP_METHOD === "npm-global")
202871
203872
  return "npm-global";
202872
- if (packageRoot.includes(`${path20.sep}node_modules${path20.sep}`))
203873
+ if (packageRoot.includes(`${path21.sep}node_modules${path21.sep}`))
202873
203874
  return "npm-global";
202874
203875
  return detectRepoRoot(packageRoot) ? "repo-clone" : "unknown";
202875
203876
  }
@@ -202879,12 +203880,12 @@ function detectInstallHost(repoRoot) {
202879
203880
  return explicit;
202880
203881
  if (!repoRoot)
202881
203882
  return "unknown";
202882
- const codexHome = process.env.CODEX_HOME || path20.join(getHomeDir(), ".codex");
202883
- if (repoRoot === path20.join(codexHome, "skills", "unbrowse"))
203883
+ const codexHome = process.env.CODEX_HOME || path21.join(getHomeDir(), ".codex");
203884
+ if (repoRoot === path21.join(codexHome, "skills", "unbrowse"))
202884
203885
  return "codex";
202885
- if (repoRoot === path20.join(getHomeDir(), "(internal)", "skills", "unbrowse"))
203886
+ if (repoRoot === path21.join(getHomeDir(), "(internal)", "skills", "unbrowse"))
202886
203887
  return "claude";
202887
- if (repoRoot === path20.join(getHomeDir(), "unbrowse"))
203888
+ if (repoRoot === path21.join(getHomeDir(), "unbrowse"))
202888
203889
  return "off";
202889
203890
  return "unknown";
202890
203891
  }
@@ -202912,14 +203913,14 @@ function commandIncludesHook(command2, marker) {
202912
203913
  return typeof command2 === "string" && command2.includes(marker);
202913
203914
  }
202914
203915
  function getCodexConfigPath() {
202915
- const codexHome = process.env.CODEX_HOME || path20.join(getHomeDir(), ".codex");
202916
- return path20.join(codexHome, "config.toml");
203916
+ const codexHome = process.env.CODEX_HOME || path21.join(getHomeDir(), ".codex");
203917
+ return path21.join(codexHome, "config.toml");
202917
203918
  }
202918
203919
  function getClaudeSettingsPath() {
202919
- return path20.join(getHomeDir(), "(internal)", "settings.json");
203920
+ return path21.join(getHomeDir(), "(internal)", "settings.json");
202920
203921
  }
202921
203922
  function getHookScriptPath(metaUrl) {
202922
- return path20.join(getPackageRoot(metaUrl), "bin", "unbrowse-update-hint.mjs");
203923
+ return path21.join(getPackageRoot(metaUrl), "bin", "unbrowse-update-hint.mjs");
202923
203924
  }
202924
203925
  function ensureCodexHooksFeature(content) {
202925
203926
  if (/\bcodex_hooks\s*=\s*true\b/.test(content))
@@ -202941,13 +203942,13 @@ function repairManagedCodexHookTable(content) {
202941
203942
  }
202942
203943
  function writeCodexHook(metaUrl) {
202943
203944
  const configPath3 = getCodexConfigPath();
202944
- if (!existsSync46(path20.dirname(configPath3))) {
203945
+ if (!existsSync47(path21.dirname(configPath3))) {
202945
203946
  return { host: "codex", action: "not-detected", config_file: configPath3 };
202946
203947
  }
202947
203948
  try {
202948
203949
  const hookScript = getHookScriptPath(metaUrl).replace(/\\/g, "/");
202949
- const fileExistsBefore = existsSync46(configPath3);
202950
- let content = fileExistsBefore ? readFileSync34(configPath3, "utf8") : "";
203950
+ const fileExistsBefore = existsSync47(configPath3);
203951
+ let content = fileExistsBefore ? readFileSync35(configPath3, "utf8") : "";
202951
203952
  const previous = content;
202952
203953
  content = ensureCodexHooksFeature(content);
202953
203954
  content = repairManagedCodexHookTable(content);
@@ -202963,7 +203964,7 @@ command = ${JSON.stringify(command2)}
202963
203964
  `;
202964
203965
  }
202965
203966
  if (content !== previous) {
202966
- writeFileSync23(configPath3, content, "utf8");
203967
+ writeFileSync24(configPath3, content, "utf8");
202967
203968
  return {
202968
203969
  host: "codex",
202969
203970
  action: fileExistsBefore ? "updated" : "installed",
@@ -202982,13 +203983,13 @@ command = ${JSON.stringify(command2)}
202982
203983
  }
202983
203984
  function writeClaudeHook(metaUrl) {
202984
203985
  const settingsPath = getClaudeSettingsPath();
202985
- if (!existsSync46(path20.dirname(settingsPath))) {
203986
+ if (!existsSync47(path21.dirname(settingsPath))) {
202986
203987
  return { host: "claude", action: "not-detected", config_file: settingsPath };
202987
203988
  }
202988
203989
  try {
202989
203990
  const hookScript = getHookScriptPath(metaUrl).replace(/\\/g, "/");
202990
203991
  const command2 = `node "${hookScript}"`;
202991
- const fileExistsBefore = existsSync46(settingsPath);
203992
+ const fileExistsBefore = existsSync47(settingsPath);
202992
203993
  const settings = readJsonFile(settingsPath) ?? {};
202993
203994
  settings.hooks ??= {};
202994
203995
  settings.hooks.SessionStart ??= [];
@@ -203042,18 +204043,18 @@ function detectPackageManagers() {
203042
204043
  }
203043
204044
  function resolveConfigHome() {
203044
204045
  if (process.platform === "win32") {
203045
- return process.env.APPDATA || path21.join(os13.homedir(), "AppData", "Roaming");
204046
+ return process.env.APPDATA || path22.join(os14.homedir(), "AppData", "Roaming");
203046
204047
  }
203047
- return process.env.XDG_CONFIG_HOME || path21.join(os13.homedir(), ".config");
204048
+ return process.env.XDG_CONFIG_HOME || path22.join(os14.homedir(), ".config");
203048
204049
  }
203049
204050
  function getOpenCodeGlobalCommandsDir() {
203050
- return path21.join(resolveConfigHome(), "opencode", "commands");
204051
+ return path22.join(resolveConfigHome(), "opencode", "commands");
203051
204052
  }
203052
204053
  function getOpenCodeProjectCommandsDir(cwd) {
203053
- return path21.join(cwd, ".opencode", "commands");
204054
+ return path22.join(cwd, ".opencode", "commands");
203054
204055
  }
203055
204056
  function detectOpenCode(cwd) {
203056
- return hasBinary("opencode") || existsSync47(path21.join(resolveConfigHome(), "opencode")) || existsSync47(path21.join(cwd, ".opencode"));
204057
+ return hasBinary("opencode") || existsSync48(path22.join(resolveConfigHome(), "opencode")) || existsSync48(path22.join(cwd, ".opencode"));
203057
204058
  }
203058
204059
  function renderOpenCodeCommand() {
203059
204060
  return `---
@@ -203081,13 +204082,13 @@ function writeOpenCodeCommand(scope, cwd) {
203081
204082
  if (scope === "auto" && !detected) {
203082
204083
  return { detected: false, action: "not-detected", scope: "off" };
203083
204084
  }
203084
- const resolvedScope = scope === "project" ? "project" : scope === "global" ? "global" : existsSync47(path21.join(cwd, ".opencode")) ? "project" : "global";
204085
+ const resolvedScope = scope === "project" ? "project" : scope === "global" ? "global" : existsSync48(path22.join(cwd, ".opencode")) ? "project" : "global";
203085
204086
  const commandsDir = resolvedScope === "project" ? getOpenCodeProjectCommandsDir(cwd) : getOpenCodeGlobalCommandsDir();
203086
- const commandFile = path21.join(ensureDir2(commandsDir), "unbrowse.md");
204087
+ const commandFile = path22.join(ensureDir2(commandsDir), "unbrowse.md");
203087
204088
  const content = renderOpenCodeCommand();
203088
- const action2 = existsSync47(commandFile) ? "updated" : "installed";
203089
- mkdirSync28(path21.dirname(commandFile), { recursive: true });
203090
- writeFileSync24(commandFile, content);
204089
+ const action2 = existsSync48(commandFile) ? "updated" : "installed";
204090
+ mkdirSync29(path22.dirname(commandFile), { recursive: true });
204091
+ writeFileSync25(commandFile, content);
203091
204092
  return {
203092
204093
  detected: detected || scope !== "auto",
203093
204094
  action: action2,
@@ -203097,10 +204098,10 @@ function writeOpenCodeCommand(scope, cwd) {
203097
204098
  }
203098
204099
  async function ensureBrowserEngineInstalled() {
203099
204100
  const binary = findKuriBinary();
203100
- if (existsSync47(binary)) {
204101
+ if (existsSync48(binary)) {
203101
204102
  return { installed: true, action: "already-installed" };
203102
204103
  }
203103
- const sourceDir = getKuriSourceCandidates().find((candidate) => existsSync47(path21.join(candidate, "build.zig")));
204104
+ const sourceDir = getKuriSourceCandidates().find((candidate) => existsSync48(path22.join(candidate, "build.zig")));
203104
204105
  if (!sourceDir) {
203105
204106
  return {
203106
204107
  installed: false,
@@ -203122,7 +204123,7 @@ async function ensureBrowserEngineInstalled() {
203122
204123
  timeout: 300000
203123
204124
  });
203124
204125
  const builtBinary = findKuriBinary();
203125
- if (existsSync47(builtBinary)) {
204126
+ if (existsSync48(builtBinary)) {
203126
204127
  return {
203127
204128
  installed: true,
203128
204129
  action: "installed",
@@ -203156,7 +204157,7 @@ async function runSetup2(options) {
203156
204157
  }
203157
204158
  const walletCheck = checkWalletConfigured();
203158
204159
  const skipWalletSetup = process.env.UNBROWSE_SKIP_WALLET_SETUP === "1";
203159
- let lobsterInstalled = hasBinary("lobstercash") || existsSync47(path21.join(os13.homedir(), ".agents", "skills", "lobstercash", "SKILL.md"));
204160
+ let lobsterInstalled = hasBinary("lobstercash") || existsSync48(path22.join(os14.homedir(), ".agents", "skills", "lobstercash", "SKILL.md"));
203160
204161
  if (!skipWalletSetup && !walletCheck.configured) {
203161
204162
  const isInteractive = !!process.stdin.isTTY && !!process.stdout.isTTY && process.env.UNBROWSE_NON_INTERACTIVE !== "1";
203162
204163
  let userOptedToSkip = false;
@@ -203246,7 +204247,7 @@ async function runSetup2(options) {
203246
204247
  return {
203247
204248
  os: {
203248
204249
  platform: process.platform,
203249
- release: os13.release(),
204250
+ release: os14.release(),
203250
204251
  arch: process.arch
203251
204252
  },
203252
204253
  host_environment: hostEnv,
@@ -203285,176 +204286,8 @@ async function promptRegisterSessionKey(ctx) {
203285
204286
  return { skipped: true, reason: "deferred_to_sdk_or_web" };
203286
204287
  }
203287
204288
 
203288
- // .tmp-runtime-src/runtime/update-hints.ts
203289
- init_paths();
203290
- import { existsSync as existsSync48, mkdirSync as mkdirSync29, readFileSync as readFileSync35, writeFileSync as writeFileSync25 } from "node:fs";
203291
- import os14 from "node:os";
203292
- import path22 from "node:path";
203293
- var INSTALL_SCRIPT_URL = "https://unbrowse.ai/install.sh";
203294
- var DEFAULT_INTERVAL_MS2 = 12 * 60 * 60 * 1000;
203295
- function getHomeDir2() {
203296
- return process.env.HOME || os14.homedir();
203297
- }
203298
- function getConfigDir7() {
203299
- if (process.env.UNBROWSE_CONFIG_DIR)
203300
- return process.env.UNBROWSE_CONFIG_DIR;
203301
- return path22.join(getHomeDir2(), ".unbrowse");
203302
- }
203303
- function ensureDir5(dir) {
203304
- if (!existsSync48(dir))
203305
- mkdirSync29(dir, { recursive: true });
203306
- return dir;
203307
- }
203308
- function readJsonFile2(file) {
203309
- try {
203310
- return JSON.parse(readFileSync35(file, "utf8"));
203311
- } catch {
203312
- return null;
203313
- }
203314
- }
203315
- function writeJsonFile2(file, value) {
203316
- ensureDir5(path22.dirname(file));
203317
- writeFileSync25(file, `${JSON.stringify(value, null, 2)}
203318
- `);
203319
- }
203320
- function getInstallSourcePath2() {
203321
- return path22.join(getConfigDir7(), "install-source.json");
203322
- }
203323
- function getUpdateCheckStatePath() {
203324
- return path22.join(getConfigDir7(), "update-check.json");
203325
- }
203326
- function detectRepoRoot2(start4) {
203327
- let dir = path22.resolve(start4);
203328
- const root2 = path22.parse(dir).root;
203329
- while (dir !== root2) {
203330
- if (existsSync48(path22.join(dir, ".git")))
203331
- return dir;
203332
- dir = path22.dirname(dir);
203333
- }
203334
- return;
203335
- }
203336
- function detectInstallMethod2(packageRoot) {
203337
- if (process.env.UNBROWSE_SETUP_METHOD === "repo-clone")
203338
- return "repo-clone";
203339
- if (process.env.UNBROWSE_SETUP_METHOD === "npm-global")
203340
- return "npm-global";
203341
- if (packageRoot.includes(`${path22.sep}node_modules${path22.sep}`))
203342
- return "npm-global";
203343
- return detectRepoRoot2(packageRoot) ? "repo-clone" : "unknown";
203344
- }
203345
- function detectInstallHost2(repoRoot) {
203346
- const explicit = process.env.UNBROWSE_SETUP_HOST;
203347
- if (explicit)
203348
- return explicit;
203349
- if (!repoRoot)
203350
- return "unknown";
203351
- const codexHome = process.env.CODEX_HOME || path22.join(getHomeDir2(), ".codex");
203352
- if (repoRoot === path22.join(codexHome, "skills", "unbrowse"))
203353
- return "codex";
203354
- if (repoRoot === path22.join(getHomeDir2(), "(internal)", "skills", "unbrowse"))
203355
- return "claude";
203356
- if (repoRoot === path22.join(getHomeDir2(), "unbrowse"))
203357
- return "off";
203358
- return "unknown";
203359
- }
203360
- function getInstalledVersion(metaUrl) {
203361
- const packageRoot = getPackageRoot(metaUrl);
203362
- try {
203363
- const pkg = JSON.parse(readFileSync35(path22.join(packageRoot, "package.json"), "utf8"));
203364
- return pkg.version ?? "unknown";
203365
- } catch {
203366
- return "unknown";
203367
- }
203368
- }
203369
- function resolveInstallSource2(metaUrl) {
203370
- const packageRoot = getPackageRoot(metaUrl);
203371
- const envRepoRoot = process.env.UNBROWSE_SETUP_ROOT || undefined;
203372
- const repoRoot = envRepoRoot || detectRepoRoot2(packageRoot);
203373
- return {
203374
- method: detectInstallMethod2(packageRoot),
203375
- host: detectInstallHost2(repoRoot),
203376
- package_root: packageRoot,
203377
- repo_root: repoRoot,
203378
- recorded_at: new Date().toISOString()
203379
- };
203380
- }
203381
- function loadInstallSource2(metaUrl) {
203382
- return readJsonFile2(getInstallSourcePath2()) ?? resolveInstallSource2(metaUrl);
203383
- }
203384
- function compareSemver(a, b) {
203385
- const parse10 = (value) => value.split("-", 1)[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
203386
- const left2 = parse10(a);
203387
- const right2 = parse10(b);
203388
- const max = Math.max(left2.length, right2.length);
203389
- for (let i = 0;i < max; i++) {
203390
- const diff = (left2[i] ?? 0) - (right2[i] ?? 0);
203391
- if (diff !== 0)
203392
- return diff;
203393
- }
203394
- return 0;
203395
- }
203396
- async function fetchLatestVersion() {
203397
- try {
203398
- const res = await fetch("https://registry.npmjs.org/unbrowse/latest", {
203399
- signal: AbortSignal.timeout(8000),
203400
- headers: { Accept: "application/json" }
203401
- });
203402
- if (!res.ok)
203403
- return null;
203404
- const body = await res.json();
203405
- return typeof body.version === "string" && body.version.trim() ? body.version.trim() : null;
203406
- } catch {
203407
- return null;
203408
- }
203409
- }
203410
- function getUpdateIntervalMs() {
203411
- const value = Number.parseInt(process.env.UNBROWSE_UPDATE_CHECK_INTERVAL_MS ?? "", 10);
203412
- return Number.isFinite(value) && value > 0 ? value : DEFAULT_INTERVAL_MS2;
203413
- }
203414
- function buildUpgradeCommand(install2) {
203415
- if (install2.method === "repo-clone" && install2.repo_root) {
203416
- const host = install2.host === "unknown" || install2.host === "auto" ? "off" : install2.host;
203417
- return `cd ${install2.repo_root} && git pull --ff-only && ./setup --host ${host}`;
203418
- }
203419
- return `curl -fsSL ${INSTALL_SCRIPT_URL} | bash`;
203420
- }
203421
- async function checkForUpdates(metaUrl, options) {
203422
- const installed = getInstalledVersion(metaUrl);
203423
- const install2 = loadInstallSource2(metaUrl);
203424
- const statePath = getUpdateCheckStatePath();
203425
- const state = readJsonFile2(statePath) ?? {};
203426
- const checkedAt = new Date().toISOString();
203427
- const intervalMs = getUpdateIntervalMs();
203428
- const lastChecked = state.latest_checked_at ? Date.parse(state.latest_checked_at) : Number.NaN;
203429
- const useCache = !options?.force && !!state.latest_version && Number.isFinite(lastChecked) && Date.now() - lastChecked < intervalMs;
203430
- const latest = useCache ? state.latest_version ?? null : await fetchLatestVersion();
203431
- if (!useCache) {
203432
- writeJsonFile2(statePath, {
203433
- ...state,
203434
- checked_at: checkedAt,
203435
- latest_version: latest ?? undefined,
203436
- latest_checked_at: checkedAt
203437
- });
203438
- }
203439
- return {
203440
- installed,
203441
- latest,
203442
- has_update: !!latest && compareSemver(latest, installed) > 0,
203443
- install: install2,
203444
- command: buildUpgradeCommand(install2),
203445
- checked_at: checkedAt,
203446
- cached: useCache
203447
- };
203448
- }
203449
- function recordUpdateHint(latestVersion) {
203450
- const statePath = getUpdateCheckStatePath();
203451
- const state = readJsonFile2(statePath) ?? {};
203452
- writeJsonFile2(statePath, {
203453
- ...state,
203454
- notified_version: latestVersion,
203455
- notified_at: new Date().toISOString()
203456
- });
203457
- }
204289
+ // .tmp-runtime-src/cli.ts
204290
+ init_update_hints();
203458
204291
 
203459
204292
  // .tmp-runtime-src/cli-setup.ts
203460
204293
  init_contribution();
@@ -203541,10 +204374,10 @@ function maybeShowContributionNotice() {
203541
204374
 
203542
204375
  // .tmp-runtime-src/config/contribution.ts
203543
204376
  import fs7 from "node:fs";
203544
- import path23 from "node:path";
203545
- import os15 from "node:os";
204377
+ import path24 from "node:path";
204378
+ import os16 from "node:os";
203546
204379
  function configPath3() {
203547
- return process.env.UNBROWSE_CONFIG_PATH || path23.join(os15.homedir(), ".unbrowse", "config.json");
204380
+ return process.env.UNBROWSE_CONFIG_PATH || path24.join(os16.homedir(), ".unbrowse", "config.json");
203548
204381
  }
203549
204382
  var DEFAULT3 = {
203550
204383
  contribution: { share_pointers: true, auto_review: true, passive_index: true, set_via: "default" },
@@ -203596,7 +204429,7 @@ function getContributionConfig2() {
203596
204429
  if (isExistingUserMigration) {
203597
204430
  try {
203598
204431
  const merged = { ...raw, ...cached4 };
203599
- fs7.mkdirSync(path23.dirname(p), { recursive: true });
204432
+ fs7.mkdirSync(path24.dirname(p), { recursive: true });
203600
204433
  fs7.writeFileSync(p, JSON.stringify(merged, null, 2));
203601
204434
  } catch {}
203602
204435
  }
@@ -203624,14 +204457,14 @@ function setContributionConfig2(updates) {
203624
204457
  existing = JSON.parse(content);
203625
204458
  } catch {}
203626
204459
  const merged = { ...existing, ...next2 };
203627
- fs7.mkdirSync(path23.dirname(p), { recursive: true });
204460
+ fs7.mkdirSync(path24.dirname(p), { recursive: true });
203628
204461
  fs7.writeFileSync(p, JSON.stringify(merged, null, 2));
203629
204462
  cached4 = next2;
203630
204463
  }
203631
204464
 
203632
204465
  // .tmp-runtime-src/settings.ts
203633
204466
  init_domain();
203634
- import { existsSync as existsSync49, mkdirSync as mkdirSync30, readFileSync as readFileSync36, writeFileSync as writeFileSync26 } from "node:fs";
204467
+ import { existsSync as existsSync50, mkdirSync as mkdirSync31, readFileSync as readFileSync37, writeFileSync as writeFileSync27 } from "node:fs";
203635
204468
  import { join as join56 } from "node:path";
203636
204469
  import { homedir as homedir42 } from "node:os";
203637
204470
  function sanitizeProfileName6(value) {
@@ -203649,8 +204482,8 @@ function getUnbrowseConfigPath2() {
203649
204482
  function loadRawConfig2() {
203650
204483
  try {
203651
204484
  const configPath4 = getUnbrowseConfigPath2();
203652
- if (existsSync49(configPath4)) {
203653
- const parsed = JSON.parse(readFileSync36(configPath4, "utf-8"));
204485
+ if (existsSync50(configPath4)) {
204486
+ const parsed = JSON.parse(readFileSync37(configPath4, "utf-8"));
203654
204487
  if (parsed && typeof parsed === "object")
203655
204488
  return parsed;
203656
204489
  }
@@ -203658,10 +204491,10 @@ function loadRawConfig2() {
203658
204491
  return {};
203659
204492
  }
203660
204493
  function saveRawConfig2(config) {
203661
- const configDir = getConfigDir8();
203662
- if (!existsSync49(configDir))
203663
- mkdirSync30(configDir, { recursive: true });
203664
- writeFileSync26(getUnbrowseConfigPath2(), JSON.stringify(config, null, 2), { mode: 384 });
204494
+ const configDir2 = getConfigDir8();
204495
+ if (!existsSync50(configDir2))
204496
+ mkdirSync31(configDir2, { recursive: true });
204497
+ writeFileSync27(getUnbrowseConfigPath2(), JSON.stringify(config, null, 2), { mode: 384 });
203665
204498
  }
203666
204499
  function normalizeDomainRule2(value) {
203667
204500
  let normalized = value.trim().toLowerCase();
@@ -204050,7 +204883,7 @@ async function _spawnDrainWorker() {
204050
204883
  if (slot === null)
204051
204884
  return;
204052
204885
  try {
204053
- const child = spawn11(process.execPath, [entry, "__drain-queue"], {
204886
+ const child = spawn12(process.execPath, [entry, "__drain-queue"], {
204054
204887
  detached: true,
204055
204888
  stdio: "ignore"
204056
204889
  });
@@ -204176,8 +205009,8 @@ function parseArgs(argv) {
204176
205009
  }
204177
205010
  return { command: command2, args: positional, flags, params };
204178
205011
  }
204179
- async function api4(method, path28, body, opts) {
204180
- let url = path28;
205012
+ async function api4(method, path29, body, opts) {
205013
+ let url = path29;
204181
205014
  let payload = body;
204182
205015
  if (method === "GET" && body && typeof body === "object") {
204183
205016
  const params = new URLSearchParams;
@@ -204289,8 +205122,8 @@ async function ensureKuriReachable(kuriBase) {
204289
205122
  };
204290
205123
  if (await probeOnce())
204291
205124
  return;
204292
- const { spawn: spawn12 } = await import("child_process");
204293
- const { existsSync: existsSync60, openSync: openSync3 } = await import("fs");
205125
+ const { spawn: spawn13 } = await import("child_process");
205126
+ const { existsSync: existsSync61, openSync: openSync3 } = await import("fs");
204294
205127
  const { join: join69, dirname: dirname14 } = await import("path");
204295
205128
  const { fileURLToPath: fileURLToPath8 } = await import("url");
204296
205129
  const moduleDir = dirname14(fileURLToPath8(import.meta.url));
@@ -204316,7 +205149,7 @@ async function ensureKuriReachable(kuriBase) {
204316
205149
  kuriTarget ? join69(moduleDir, "../packages/skill/vendor/kuri", kuriTarget, kuriBinName) : undefined,
204317
205150
  "/opt/homebrew/bin/kuri",
204318
205151
  "/usr/local/bin/kuri"
204319
- ].filter((p) => !!p && existsSync60(p));
205152
+ ].filter((p) => !!p && existsSync61(p));
204320
205153
  if (candidates.length === 0) {
204321
205154
  die(`Kuri unreachable at ${kuriBase} and no kuri binary found in standard paths. Set UNBROWSE_KURI_BIN, or run: submodules/kuri/zig-out/bin/kuri`);
204322
205155
  }
@@ -204331,7 +205164,7 @@ async function ensureKuriReachable(kuriBase) {
204331
205164
  })();
204332
205165
  info(`auto-spawning kuri from ${kuriBin} (port ${expectedPort}, logs: /tmp/kuri.log)`);
204333
205166
  const logFd = openSync3("/tmp/kuri.log", "a");
204334
- const child = spawn12(kuriBin, [], {
205167
+ const child = spawn13(kuriBin, [], {
204335
205168
  detached: true,
204336
205169
  stdio: ["ignore", logFd, logFd],
204337
205170
  env: { ...process.env, PORT: expectedPort, HOST: "127.0.0.1" }
@@ -204377,7 +205210,7 @@ function openUrl(url) {
204377
205210
  return;
204378
205211
  try {
204379
205212
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
204380
- spawn11(cmd, [url], { detached: true, stdio: "ignore" }).unref();
205213
+ spawn12(cmd, [url], { detached: true, stdio: "ignore" }).unref();
204381
205214
  } catch {}
204382
205215
  }
204383
205216
  function resolveResultError(result) {
@@ -204639,6 +205472,9 @@ function slimTrace(obj) {
204639
205472
  out.source = obj.source;
204640
205473
  if (obj.skill)
204641
205474
  out.skill = obj.skill;
205475
+ if (Array.isArray(obj.cross_skill_producers) && obj.cross_skill_producers.length) {
205476
+ out.cross_skill_producers = obj.cross_skill_producers;
205477
+ }
204642
205478
  return out;
204643
205479
  }
204644
205480
  function formatSavedDuration(ms) {
@@ -205438,8 +206274,8 @@ async function cmdRun(args, flags) {
205438
206274
  throw error;
205439
206275
  }
205440
206276
  }
205441
- function drillPath(data2, path28) {
205442
- const segments = path28.split(/\./).flatMap((s) => {
206277
+ function drillPath(data2, path29) {
206278
+ const segments = path29.split(/\./).flatMap((s) => {
205443
206279
  const m = s.match(/^(.+)\[\]$/);
205444
206280
  return m ? [m[1], "[]"] : [s];
205445
206281
  });
@@ -205466,9 +206302,9 @@ function drillPath(data2, path28) {
205466
206302
  }
205467
206303
  return values;
205468
206304
  }
205469
- function resolveDotPath(obj, path28) {
206305
+ function resolveDotPath(obj, path29) {
205470
206306
  let cur = obj;
205471
- for (const key2 of path28.split(".")) {
206307
+ for (const key2 of path29.split(".")) {
205472
206308
  if (cur == null || typeof cur !== "object")
205473
206309
  return;
205474
206310
  cur = cur[key2];
@@ -205485,8 +206321,8 @@ function applyExtract(items, extractSpec) {
205485
206321
  return items.map((item) => {
205486
206322
  const row = {};
205487
206323
  let hasValue = false;
205488
- for (const { alias, path: path28 } of fields) {
205489
- const val2 = resolveDotPath(item, path28);
206324
+ for (const { alias, path: path29 } of fields) {
206325
+ const val2 = resolveDotPath(item, path29);
205490
206326
  row[alias] = val2 ?? null;
205491
206327
  if (val2 != null)
205492
206328
  hasValue = true;
@@ -205515,7 +206351,18 @@ function schemaOf(value, depth = 4) {
205515
206351
  }
205516
206352
  var SYNTHETIC_SKILL_IDS = new Set(["exa-web-search"]);
205517
206353
  async function cmdExecute(flags) {
205518
- const skillId = flags.skill ?? flags["skill-id"];
206354
+ const explicitMethod = typeof flags.method === "string" ? flags.method.toUpperCase() : undefined;
206355
+ const intentText = typeof (flags.intent ?? flags.task) === "string" ? String(flags.intent ?? flags.task) : "";
206356
+ const hasBody = !!flags.body || typeof flags.params === "string" && /["']body["']\s*:/.test(flags.params);
206357
+ const effectiveMethod = inferWriteMethod(explicitMethod, intentText, hasBody);
206358
+ const writeMethod = ["POST", "PUT", "PATCH", "DELETE"].includes(effectiveMethod ?? "");
206359
+ if (writeMethod)
206360
+ flags.method = effectiveMethod;
206361
+ let skillId = flags.skill ?? flags["skill-id"];
206362
+ if (!skillId && typeof flags.url === "string" && writeMethod) {
206363
+ const idHash = createHash45("sha256").update(`${effectiveMethod} ${String(flags.url)}`).digest("hex").slice(0, 40);
206364
+ skillId = `adhoc-write-${idHash}`;
206365
+ }
205519
206366
  if (!skillId)
205520
206367
  die("--skill is required. List skills: unbrowse skills. Or run unbrowse resolve --intent '...' first to get a skill_id.");
205521
206368
  if (SYNTHETIC_SKILL_IDS.has(skillId)) {
@@ -205554,6 +206401,13 @@ async function cmdExecute(flags) {
205554
206401
  if (flags.params) {
205555
206402
  body.params = { ...body.params, ...JSON.parse(flags.params) };
205556
206403
  }
206404
+ if (flags.body) {
206405
+ try {
206406
+ body.params.body = JSON.parse(flags.body);
206407
+ } catch {
206408
+ body.params.body = flags.body;
206409
+ }
206410
+ }
205557
206411
  const cliKv = flags._params;
205558
206412
  if (cliKv && Object.keys(cliKv).length > 0) {
205559
206413
  body.params = { ...body.params, ...cliKv };
@@ -205562,6 +206416,10 @@ async function cmdExecute(flags) {
205562
206416
  body.context_url = flags.url;
205563
206417
  body.params.url = flags.url;
205564
206418
  }
206419
+ if (typeof flags.method === "string")
206420
+ body.method = flags.method.toUpperCase();
206421
+ if (typeof flags.session === "string")
206422
+ body.session_id = flags.session;
205565
206423
  if (flags.intent ?? flags.task)
205566
206424
  body.intent = flags.intent ?? flags.task;
205567
206425
  if (flags["dry-run"])
@@ -205898,9 +206756,9 @@ async function cmdSkillPackage(args, flags) {
205898
206756
  const { renderSkillMd: renderSkillMd3, validateSkillPackage: validateSkillPackage3, forbiddenPublicTerms: forbiddenPublicTerms3 } = await Promise.resolve().then(() => (init_skillmd2(), exports_skillmd2));
205899
206757
  const { sanitizeDomain: sanitizeDomain5 } = await Promise.resolve().then(() => (init_domain_notes2(), exports_domain_notes));
205900
206758
  const fs9 = __require("fs");
205901
- const path28 = __require("path");
206759
+ const path29 = __require("path");
205902
206760
  const domain = sanitizeDomain5(String(skill.domain ?? id));
205903
- const outDir = flags.out || path28.join(process.cwd(), `unbrowse-ai-${domain}`);
206761
+ const outDir = flags.out || path29.join(process.cwd(), `unbrowse-ai-${domain}`);
205904
206762
  if (flags.expose)
205905
206763
  skill.exposed = true;
205906
206764
  const md = renderSkillMd3(skill);
@@ -205921,8 +206779,8 @@ Credentials are never embedded \u2014 they are placeholders filled at call time
205921
206779
  if (readmeLeaks.length)
205922
206780
  die(`invalid README for ${domain}: forbidden public term(s) ${readmeLeaks.map((t) => `/${t}/`).join(", ")}`);
205923
206781
  fs9.mkdirSync(outDir, { recursive: true });
205924
- fs9.writeFileSync(path28.join(outDir, "SKILL.md"), md);
205925
- fs9.writeFileSync(path28.join(outDir, "README.md"), readme);
206782
+ fs9.writeFileSync(path29.join(outDir, "SKILL.md"), md);
206783
+ fs9.writeFileSync(path29.join(outDir, "README.md"), readme);
205926
206784
  output2({ ok: true, domain, out: outDir, files: ["SKILL.md", "README.md"], install: `npx skills add unbrowse-ai/${domain}` }, !!flags.pretty);
205927
206785
  }
205928
206786
  async function cmdCleanupStale(flags) {
@@ -206067,10 +206925,10 @@ async function cmdSetup(flags) {
206067
206925
  }
206068
206926
  const hasGcloud = (() => {
206069
206927
  try {
206070
- const { existsSync: existsSync60 } = __require("fs");
206928
+ const { existsSync: existsSync61 } = __require("fs");
206071
206929
  const { homedir: homedir52 } = __require("os");
206072
206930
  const { join: join69 } = __require("path");
206073
- return existsSync60(join69(homedir52(), ".config", "gcloud", "application_default_credentials.json"));
206931
+ return existsSync61(join69(homedir52(), ".config", "gcloud", "application_default_credentials.json"));
206074
206932
  } catch {
206075
206933
  return false;
206076
206934
  }
@@ -206402,10 +207260,10 @@ async function cmdNote(flags, args) {
206402
207260
  if (sub === "list") {
206403
207261
  const { homedir: homedir52 } = await import("os");
206404
207262
  const { join: join69 } = await import("path");
206405
- const { readdirSync: readdirSync17, existsSync: existsSync60 } = await import("fs");
207263
+ const { readdirSync: readdirSync17, existsSync: existsSync61 } = await import("fs");
206406
207264
  const profile = process.env.UNBROWSE_PROFILE ?? "";
206407
207265
  const dir = process.env.UNBROWSE_DOMAIN_NOTES_DIR ?? (profile ? join69(homedir52(), ".unbrowse", "profiles", profile, "domain-notes") : join69(homedir52(), ".unbrowse", "domain-notes"));
206408
- if (!existsSync60(dir)) {
207266
+ if (!existsSync61(dir)) {
206409
207267
  output2({ notes: [], dir }, !!flags.pretty);
206410
207268
  return;
206411
207269
  }
@@ -207246,7 +208104,13 @@ async function cmdUpgrade(flags) {
207246
208104
  return;
207247
208105
  }
207248
208106
  info(`Update available: ${result.installed} -> ${result.latest}`);
207249
- info(`Run: ${result.command}`);
208107
+ const { maybeAutoUpdate: maybeAutoUpdate2 } = await Promise.resolve().then(() => (init_update_hints(), exports_update_hints));
208108
+ const applied = await maybeAutoUpdate2(import.meta.url);
208109
+ if (applied.applied) {
208110
+ info(`Auto-updating in the background: ${applied.from} -> ${applied.to} (takes effect next run).`);
208111
+ } else {
208112
+ info(`Run: ${result.command}`);
208113
+ }
207250
208114
  if (!hintOnly) {
207251
208115
  info("Tip: `unbrowse setup` now installs session-start update hints for Codex and Claude when those hosts are present.");
207252
208116
  }
@@ -207259,7 +208123,7 @@ async function cmdUpgrade(flags) {
207259
208123
  async function cmdMcp(flags) {
207260
208124
  const entrypoint = resolveSiblingEntrypoint2(import.meta.url, "mcp");
207261
208125
  const childArgs = isBundledVirtualEntrypoint(entrypoint) ? ["mcp-serve", ...flags["no-auto-start"] ? ["--no-auto-start"] : []] : [...runtimeArgsForEntrypoint2(import.meta.url, entrypoint), ...flags["no-auto-start"] ? ["--no-auto-start"] : []];
207262
- const child = spawn11(process.execPath, childArgs, {
208126
+ const child = spawn12(process.execPath, childArgs, {
207263
208127
  cwd: process.cwd(),
207264
208128
  stdio: "inherit",
207265
208129
  env: {
@@ -207283,7 +208147,7 @@ async function cmdMcp(flags) {
207283
208147
  async function cmdContractBridge(_flags) {
207284
208148
  const entrypoint = resolveSiblingEntrypoint2(import.meta.url, "contract-bridge");
207285
208149
  const childArgs = isBundledVirtualEntrypoint(entrypoint) ? ["contract-bridge-serve"] : [...runtimeArgsForEntrypoint2(import.meta.url, entrypoint)];
207286
- const child = spawn11(process.execPath, childArgs, {
208150
+ const child = spawn12(process.execPath, childArgs, {
207287
208151
  cwd: process.cwd(),
207288
208152
  stdio: "inherit",
207289
208153
  env: { ...process.env, CONTRACT_BRIDGE_MODE: "1" }
@@ -207611,7 +208475,7 @@ async function cmdRegister(flags) {
207611
208475
  info(`Opening browser: ${url}`);
207612
208476
  try {
207613
208477
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
207614
- spawn11(cmd, [url], { detached: true, stdio: "ignore" }).unref();
208478
+ spawn12(cmd, [url], { detached: true, stdio: "ignore" }).unref();
207615
208479
  } catch {}
207616
208480
  }
207617
208481
  });
@@ -207657,7 +208521,7 @@ async function cmdRegister(flags) {
207657
208521
  async function cmdSessionsScan(flags) {
207658
208522
  const domain = flags.domain;
207659
208523
  const { scanAllBrowserSessions: scanAllBrowserSessions3, findBestBrowserSession: findBestBrowserSession3 } = await Promise.resolve().then(() => (init_browser_cookies2(), exports_browser_cookies2));
207660
- const { execFileSync: execFileSync9, existsSync: existsSync60 } = await import("./cli-imports.js").catch(() => ({ execFileSync: __require("child_process").execFileSync, existsSync: __require("fs").existsSync }));
208524
+ const { execFileSync: execFileSync9, existsSync: existsSync61 } = await import("./cli-imports.js").catch(() => ({ execFileSync: __require("child_process").execFileSync, existsSync: __require("fs").existsSync }));
207661
208525
  if (domain) {
207662
208526
  const sessions = scanAllBrowserSessions3(domain);
207663
208527
  if (sessions.length === 0) {
@@ -207760,7 +208624,7 @@ async function cmdCorpusTest(flags) {
207760
208624
  break;
207761
208625
  if (attempt < retries - 1) {
207762
208626
  try {
207763
- spawn11("pkill", ["-9", "-f", "kuri|chrome-profile"], { stdio: "ignore" });
208627
+ spawn12("pkill", ["-9", "-f", "kuri|chrome-profile"], { stdio: "ignore" });
207764
208628
  } catch {}
207765
208629
  await new Promise((r) => setTimeout(r, 2000));
207766
208630
  }
@@ -207806,7 +208670,7 @@ async function cmdCorpusRun(flags) {
207806
208670
  const caseId = c.id || new URL(c.url).hostname;
207807
208671
  info(`corpus-run [${caseId}] starting`);
207808
208672
  try {
207809
- spawn11("pkill", ["-9", "-f", "kuri|chrome-profile"], { stdio: "ignore" });
208673
+ spawn12("pkill", ["-9", "-f", "kuri|chrome-profile"], { stdio: "ignore" });
207810
208674
  } catch {}
207811
208675
  await new Promise((r) => setTimeout(r, 1500));
207812
208676
  let best = { capture: "error", endpoints: 0, requests: 0 };
@@ -207820,7 +208684,7 @@ async function cmdCorpusRun(flags) {
207820
208684
  break;
207821
208685
  if (attempt < retries - 1) {
207822
208686
  try {
207823
- spawn11("pkill", ["-9", "-f", "kuri|chrome-profile"], { stdio: "ignore" });
208687
+ spawn12("pkill", ["-9", "-f", "kuri|chrome-profile"], { stdio: "ignore" });
207824
208688
  } catch {}
207825
208689
  await new Promise((r) => setTimeout(r, 2000));
207826
208690
  }
@@ -207923,8 +208787,8 @@ async function cmdConnectChrome() {
207923
208787
  async function cmdContract(args, flags) {
207924
208788
  const sub = args[0];
207925
208789
  const baseUrl = ((typeof flags["url"] === "string" ? flags["url"] : undefined) ?? process.env.UNBROWSE_API_URL ?? "https://beta-api.unbrowse.ai").replace(/\/+$/, "");
207926
- async function call2(path28, opts = {}) {
207927
- const url = new URL(`${baseUrl}${path28}`);
208790
+ async function call2(path29, opts = {}) {
208791
+ const url = new URL(`${baseUrl}${path29}`);
207928
208792
  if (opts.query) {
207929
208793
  for (const [k, v] of Object.entries(opts.query))
207930
208794
  url.searchParams.set(k, v);
@@ -208041,8 +208905,8 @@ async function cmdContribute(args, flags) {
208041
208905
  const [method, ...rest] = endpoint.split(" ");
208042
208906
  const target = rest.join(" ");
208043
208907
  const [host, ...pathParts] = target.split("/");
208044
- const path28 = "/" + pathParts.join("/");
208045
- const shape = shapePointer({ method, host, path: path28, paramKeys });
208908
+ const path29 = "/" + pathParts.join("/");
208909
+ const shape = shapePointer({ method, host, path: path29, paramKeys });
208046
208910
  const delta = await signDelta({ op: "add", endpoint, shape, freshness: Date.now() });
208047
208911
  const validity = proveDeltaValidity(delta, count, bound);
208048
208912
  const attestation = await attestExecution({ origin, method, shapeHash: shape });
@@ -208539,6 +209403,7 @@ if (isMainModule(import.meta.url)) {
208539
209403
  });
208540
209404
  }
208541
209405
  export {
209406
+ slimTrace,
208542
209407
  parseCmdRunArgs,
208543
209408
  parseArgs,
208544
209409
  fetchOutcome,