@kmugalkhod/lightcode 0.15.0 → 0.17.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/server.js CHANGED
@@ -428,6 +428,9 @@ import {
428
428
  } from "fs";
429
429
  import path4 from "path";
430
430
  import { z } from "zod";
431
+ function isAuthenticatedWebRequest(request) {
432
+ return authenticatedWebRequests.has(request);
433
+ }
431
434
  function defaultExpectedOrigin(env = Bun.env) {
432
435
  const configuredPort = env.PORT?.trim() || "4983";
433
436
  return new URL(`http://127.0.0.1:${configuredPort}`).origin;
@@ -603,6 +606,9 @@ function createWebSecurityMiddleware(options = {}) {
603
606
  if (!hasValidBearerToken(request, authState.token)) {
604
607
  return jsonSecurityError(c, 401, "web_auth_required", "A valid Lightcode browser token is required.");
605
608
  }
609
+ if (browserRequest) {
610
+ authenticatedWebRequests.add(request);
611
+ }
606
612
  } else if (browserRequest || authState.configured) {
607
613
  return jsonSecurityError(c, 503, "web_auth_unavailable", "Browser access is unavailable. Start Lightcode with `lightcode web`.");
608
614
  } else if (!allowUnauthenticatedCli) {
@@ -615,7 +621,7 @@ function createWebSecurityMiddleware(options = {}) {
615
621
  await next();
616
622
  };
617
623
  }
618
- var webAuthFileEnvironmentVariable = "LIGHTCODE_WEB_AUTH_FILE", webAuthHandoffSchema, maximumHandoffBytes = 4096, maximumHandoffAgeMs, maximumHandoffClockSkewMs, defaultAuthState;
624
+ var webAuthFileEnvironmentVariable = "LIGHTCODE_WEB_AUTH_FILE", webAuthHandoffSchema, maximumHandoffBytes = 4096, maximumHandoffAgeMs, maximumHandoffClockSkewMs, authenticatedWebRequests, defaultAuthState;
619
625
  var init_web_auth = __esm(() => {
620
626
  webAuthHandoffSchema = z.object({
621
627
  version: z.literal(1),
@@ -624,6 +630,7 @@ var init_web_auth = __esm(() => {
624
630
  }).strict();
625
631
  maximumHandoffAgeMs = 5 * 60 * 1000;
626
632
  maximumHandoffClockSkewMs = 30 * 1000;
633
+ authenticatedWebRequests = new WeakSet;
627
634
  defaultAuthState = loadWebAuthStateFromEnvironment();
628
635
  });
629
636
 
@@ -2054,10 +2061,11 @@ var init_schema10 = __esm(() => {
2054
2061
 
2055
2062
  // packages/ai/src/skills/schema.ts
2056
2063
  import { z as z21 } from "zod";
2057
- var skillDescription = "Load a local Lightcode skill by name and return its instructions and metadata.", skillInputSchema, skillProviderInputSchema, skillSummarySchema, skillOutputSchema, skillListOutputSchema;
2064
+ var skillDescription = "Load an installed skill by name before following its instructions. Use resource to read a supporting file relative to that skill's directory.", skillInputSchema, skillProviderInputSchema, skillSummarySchema, skillOutputSchema, skillListOutputSchema;
2058
2065
  var init_schema11 = __esm(() => {
2059
2066
  skillInputSchema = z21.object({
2060
- name: z21.string().min(1).max(160)
2067
+ name: z21.string().min(1).max(160),
2068
+ resource: z21.string().min(1).max(1024).optional()
2061
2069
  });
2062
2070
  skillProviderInputSchema = skillInputSchema;
2063
2071
  skillSummarySchema = z21.object({
@@ -2407,7 +2415,7 @@ var init_tool_registry = __esm(() => {
2407
2415
  permissionMode: "read-only",
2408
2416
  execution: "server",
2409
2417
  availability: "skills",
2410
- activation: "specialized",
2418
+ activation: "core",
2411
2419
  outputPolicy: "artifact-if-large"
2412
2420
  },
2413
2421
  list_mcp_resources: {
@@ -3060,7 +3068,7 @@ ${environmentContext.trim()}` : "");
3060
3068
  var cwdPromptPlaceholder = "{cwd}", defaultCodingAgentSystemPrompt, toolCallingDisciplineAddendum;
3061
3069
  var init_coding_agent_prompt = __esm(() => {
3062
3070
  init_coding_agent_modes();
3063
- defaultCodingAgentSystemPrompt = "You are a coding agent working inside the user's project at this working directory: {cwd}. " + 'You can already see the project \u2014 proactively read it. When the user asks you to review, explain, or work on "my code"/"this", inspect the working directory yourself with list_files, glob_search, grep, and read_file; NEVER ask the user to paste or share code that lives in this directory \u2014 open it. ' + "Use tools for filesystem and codebase tasks instead of guessing, and only interact with files under the working directory. " + "Prefer dedicated tools \u2014 glob_search for paths, grep for text search, structured git tools for repository inspection \u2014 and bash only when those are not enough. " + `Inspect context before risky operations. Progress notes: before a major tool action you may emit ONE short note (one sentence, ~15 words) saying what you are about to do. After a tool returns, mention a finding only if it changes your plan, and state it as fact grounded in what the tool actually returned \u2014 cite the file/line/symbol. NEVER claim you found, changed, or fixed something before a tool result confirms it. Skip notes for routine reads, and do not restate the todo list in prose.
3071
+ defaultCodingAgentSystemPrompt = "You are a coding agent working inside the user's project at this working directory: {cwd}. " + 'You can already see the project \u2014 proactively read it. When the user asks you to review, explain, or work on "my code"/"this", inspect the working directory yourself with list_files, glob_search, grep, and read_file; NEVER ask the user to paste or share code that lives in this directory \u2014 open it. ' + "Use tools for filesystem and codebase tasks instead of guessing, and only interact with files under the working directory. " + "Prefer dedicated tools \u2014 glob_search for paths, grep for text search, structured git tools for repository inspection \u2014 and bash only when those are not enough. " + "Check the available skill descriptions for every task. When a skill is explicitly named or clearly matches the task, load it with the skill tool before acting and follow its instructions within the user's scope and tool permissions. Skill files may be installed outside the workspace; use the skill tool to read their relative supporting resources. Never claim to have used a skill you have not loaded. " + `Inspect context before risky operations. Progress notes: before a major tool action you may emit ONE short note (one sentence, ~15 words) saying what you are about to do. After a tool returns, mention a finding only if it changes your plan, and state it as fact grounded in what the tool actually returned \u2014 cite the file/line/symbol. NEVER claim you found, changed, or fixed something before a tool result confirms it. Skip notes for routine reads, and do not restate the todo list in prose.
3064
3072
 
3065
3073
  ` + `Task list discipline \u2014 use the todo_write tool to keep a visible, evolving checklist:
3066
3074
  ` + `- Create the list FIRST. For any task with roughly three or more distinct steps, or any multi-file or multi-stage work, call todo_write as your very first action \u2014 before reading or editing \u2014 with every step listed and all of them set to pending.
@@ -5309,103 +5317,145 @@ var init_runtime10 = __esm(() => {
5309
5317
  });
5310
5318
 
5311
5319
  // packages/ai/src/skills/runtime.ts
5312
- import { existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
5320
+ import { readFileSync as readFileSync2, readdirSync as readdirSync2, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
5313
5321
  import os from "os";
5314
5322
  import path11 from "path";
5315
- function defaultSkillRoots(cwd) {
5323
+ function defaultSkillRoots(cwd, home, env) {
5316
5324
  return [
5317
5325
  { source: "project", path: path11.join(cwd, ".lightcode", "skills") },
5318
5326
  { source: "project", path: path11.join(cwd, ".agents", "skills") },
5319
- { source: "user", path: path11.join(os.homedir(), ".lightcode", "skills") }
5327
+ ...[".claude", ".codex", ".opencode"].map((dir) => ({
5328
+ source: "project",
5329
+ path: path11.join(cwd, dir, "skills")
5330
+ })),
5331
+ ...[".lightcode", ".agents", ".claude"].map((dir) => ({
5332
+ source: "user",
5333
+ path: path11.join(home, dir, "skills")
5334
+ })),
5335
+ {
5336
+ source: "user",
5337
+ path: path11.join(env.CODEX_HOME || path11.join(home, ".codex"), "skills")
5338
+ },
5339
+ {
5340
+ source: "user",
5341
+ path: path11.join(env.XDG_CONFIG_HOME || path11.join(home, ".config"), "opencode", "skills")
5342
+ },
5343
+ ...(env.LIGHTCODE_SKILL_PATHS ?? "").split(path11.delimiter).filter(Boolean).map((root) => ({
5344
+ source: "user",
5345
+ path: path11.resolve(cwd, root)
5346
+ }))
5320
5347
  ];
5321
5348
  }
5322
5349
  function normalizeSkillName(value) {
5323
5350
  return value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-");
5324
5351
  }
5325
5352
  function parseBasicFrontmatter(content) {
5326
- if (!content.startsWith("---")) {
5353
+ const match = /^\uFEFF?---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(content);
5354
+ if (!match)
5327
5355
  return {};
5328
- }
5329
- const endIndex = content.indexOf(`
5330
- ---`, 3);
5331
- if (endIndex === -1) {
5356
+ const parsed = Bun.YAML.parse(match[1]);
5357
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
5332
5358
  return {};
5333
- }
5334
- const frontmatter = content.slice(3, endIndex).trim();
5335
- return Object.fromEntries(frontmatter.split(/\r?\n/).map((line) => line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/)).filter((match) => match !== null).map((match) => [
5336
- match[1],
5337
- match[2].replace(/^["']|["']$/g, "").trim()
5338
- ]));
5359
+ return Object.fromEntries(Object.entries(parsed).filter((entry) => typeof entry[1] === "string"));
5339
5360
  }
5340
5361
  function findSkillFiles(root) {
5341
- if (!existsSync4(root.path)) {
5342
- return [];
5343
- }
5344
5362
  const files = [];
5363
+ const visited = new Set;
5345
5364
  const visit = (directory, depth) => {
5346
- if (depth > 4) {
5365
+ if (depth > 8 || visited.size >= 2000) {
5366
+ return;
5367
+ }
5368
+ let entries;
5369
+ try {
5370
+ const real = realpathSync2(directory);
5371
+ if (visited.has(real))
5372
+ return;
5373
+ visited.add(real);
5374
+ entries = readdirSync2(directory).sort();
5375
+ } catch {
5347
5376
  return;
5348
5377
  }
5349
- for (const entry of readdirSync2(directory)) {
5378
+ for (const entry of entries) {
5350
5379
  const entryPath = path11.join(directory, entry);
5351
- const stat3 = statSync2(entryPath);
5352
- if (stat3.isDirectory()) {
5353
- visit(entryPath, depth + 1);
5354
- } else if (entry.toLowerCase() === "skill.md") {
5355
- files.push(entryPath);
5356
- }
5380
+ try {
5381
+ const stat3 = statSync2(entryPath);
5382
+ if (stat3.isDirectory()) {
5383
+ visit(entryPath, depth + 1);
5384
+ } else if (stat3.isFile() && stat3.size <= 1048576 && entry.toLowerCase() === "skill.md") {
5385
+ files.push(entryPath);
5386
+ }
5387
+ } catch {}
5357
5388
  }
5358
5389
  };
5359
5390
  visit(root.path, 0);
5360
5391
  return files;
5361
5392
  }
5362
5393
  function listSkills({
5363
- cwd = process.cwd()
5394
+ cwd = process.cwd(),
5395
+ home = os.homedir(),
5396
+ env = process.env
5364
5397
  } = {}) {
5365
- const cached = skillsCache.get(cwd);
5398
+ const roots = defaultSkillRoots(path11.resolve(cwd), home, env);
5399
+ const cacheKey = JSON.stringify(roots);
5400
+ const cached = skillsCache.get(cacheKey);
5366
5401
  if (cached && cached.expiresAt > Date.now()) {
5367
5402
  return cached.skills;
5368
5403
  }
5369
- const skills = listSkillsUncached(cwd);
5370
- skillsCache.set(cwd, {
5404
+ const skills = listSkillsUncached(roots);
5405
+ if (skillsCache.size >= 100)
5406
+ skillsCache.delete(skillsCache.keys().next().value);
5407
+ skillsCache.set(cacheKey, {
5371
5408
  expiresAt: Date.now() + skillsCacheTtlMs,
5372
5409
  skills
5373
5410
  });
5374
5411
  return skills;
5375
5412
  }
5376
- function listSkillsUncached(cwd) {
5413
+ function listSkillsUncached(roots) {
5377
5414
  const seen = new Set;
5378
5415
  const summaries = [];
5379
- for (const root of defaultSkillRoots(cwd)) {
5416
+ for (const root of roots) {
5380
5417
  for (const skillPath of findSkillFiles(root)) {
5381
- const content = readFileSync2(skillPath, "utf8");
5382
- const frontmatter = parseBasicFrontmatter(content);
5383
- const fallbackName = path11.basename(path11.dirname(skillPath));
5384
- const name = normalizeSkillName(frontmatter.name ?? fallbackName);
5385
- if (!name || seen.has(name)) {
5386
- continue;
5387
- }
5388
- seen.add(name);
5389
- summaries.push({
5390
- name,
5391
- description: frontmatter.description || null,
5392
- path: skillPath,
5393
- source: root.source
5394
- });
5418
+ try {
5419
+ const content = readFileSync2(skillPath, "utf8");
5420
+ const frontmatter = parseBasicFrontmatter(content);
5421
+ const fallbackName = path11.basename(path11.dirname(skillPath));
5422
+ const name = normalizeSkillName(frontmatter.name ?? fallbackName);
5423
+ if (!name || name.length > 160 || seen.has(name)) {
5424
+ continue;
5425
+ }
5426
+ seen.add(name);
5427
+ summaries.push({
5428
+ name,
5429
+ description: frontmatter.description || null,
5430
+ path: skillPath,
5431
+ source: root.source
5432
+ });
5433
+ } catch {}
5395
5434
  }
5396
5435
  }
5397
5436
  return summaries.sort((left, right) => left.name.localeCompare(right.name));
5398
5437
  }
5399
- function loadSkill(input, { cwd = process.cwd() } = {}) {
5438
+ function loadSkill(input, options = {}) {
5400
5439
  const parsedInput = skillInputSchema.parse(input);
5401
5440
  const normalizedName = normalizeSkillName(parsedInput.name);
5402
- const skill = listSkills({ cwd }).find((candidate) => normalizeSkillName(candidate.name) === normalizedName);
5441
+ const skill = listSkills(options).find((candidate) => normalizeSkillName(candidate.name) === normalizedName);
5403
5442
  if (!skill) {
5404
5443
  throw new Error(`Skill not found: ${parsedInput.name}`);
5405
5444
  }
5445
+ const root = realpathSync2(path11.dirname(skill.path));
5446
+ const target = parsedInput.resource ? realpathSync2(path11.resolve(root, parsedInput.resource)) : skill.path;
5447
+ if (parsedInput.resource) {
5448
+ const relative = path11.relative(root, target);
5449
+ if (relative === ".." || relative.startsWith(`..${path11.sep}`) || path11.isAbsolute(relative)) {
5450
+ throw new Error("Skill resources must stay inside the installed skill directory.");
5451
+ }
5452
+ }
5453
+ const stat3 = statSync2(target);
5454
+ if (!stat3.isFile() || stat3.size > 1048576)
5455
+ throw new Error("Skill resource must be a file smaller than 1 MiB.");
5406
5456
  return skillOutputSchema.parse({
5407
5457
  skill,
5408
- content: readFileSync2(skill.path, "utf8")
5458
+ content: readFileSync2(target, "utf8")
5409
5459
  });
5410
5460
  }
5411
5461
  var skillsCacheTtlMs = 30000, skillsCache;
@@ -7079,7 +7129,7 @@ var init_context = __esm(() => {
7079
7129
  });
7080
7130
 
7081
7131
  // packages/ai/src/config/lightcode-config.ts
7082
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync } from "fs";
7132
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync } from "fs";
7083
7133
  import os2 from "os";
7084
7134
  import path13 from "path";
7085
7135
  import { z as z34 } from "zod";
@@ -7090,7 +7140,7 @@ function getDefaultUserConfigPath(env) {
7090
7140
  return path13.join(os2.homedir(), ".lightcode", "settings.json");
7091
7141
  }
7092
7142
  function readConfigFile(scope, configPath) {
7093
- if (!existsSync5(configPath)) {
7143
+ if (!existsSync4(configPath)) {
7094
7144
  return {
7095
7145
  config: {},
7096
7146
  file: {
@@ -7552,17 +7602,101 @@ var init_runtime12 = __esm(() => {
7552
7602
  init_schema8();
7553
7603
  });
7554
7604
 
7605
+ // packages/shared/src/network-fetch.ts
7606
+ import { readFileSync as readFileSync4, statSync as statSync3 } from "fs";
7607
+ import { X509Certificate } from "crypto";
7608
+ import * as tls from "tls";
7609
+ function isCertificateError(error) {
7610
+ const seen = new Set;
7611
+ let current = error;
7612
+ while (current && typeof current === "object" && !seen.has(current) && seen.size < 12) {
7613
+ seen.add(current);
7614
+ const record = current;
7615
+ if (certificateErrorPattern.test(`${record.code ?? ""} ${record.message ?? ""}`))
7616
+ return true;
7617
+ current = record.cause;
7618
+ }
7619
+ return false;
7620
+ }
7621
+ function createNetworkFetch({
7622
+ env = process.env,
7623
+ fetchImpl
7624
+ } = {}) {
7625
+ let cachedKey = "";
7626
+ let cachedCa;
7627
+ let checkedAt = 0;
7628
+ const resolveCa = () => {
7629
+ const paths = [
7630
+ ...new Set([env.LIGHTCODE_CA_CERTS, env.NODE_EXTRA_CA_CERTS, env.SSL_CERT_FILE].map((value) => value?.trim()).filter((value) => Boolean(value)))
7631
+ ];
7632
+ const key = JSON.stringify(paths);
7633
+ if (key === cachedKey && Date.now() - checkedAt < 30000)
7634
+ return cachedCa;
7635
+ const extra = [];
7636
+ for (const file of paths) {
7637
+ try {
7638
+ if (statSync3(file).size > 4 * 1024 * 1024)
7639
+ throw new Error("CA bundle exceeds 4 MiB");
7640
+ const certificates = readFileSync4(file, "utf8").match(certificatePattern);
7641
+ if (!certificates?.length)
7642
+ throw new Error("No PEM certificates found");
7643
+ for (const cert of certificates)
7644
+ new X509Certificate(cert);
7645
+ extra.push(...certificates);
7646
+ } catch (cause) {
7647
+ throw new Error("Cannot load configured TLS CA certificate bundle. Check LIGHTCODE_CA_CERTS, NODE_EXTRA_CA_CERTS and SSL_CERT_FILE for readable PEM files.", { cause });
7648
+ }
7649
+ }
7650
+ let defaults = [...tls.rootCertificates];
7651
+ try {
7652
+ defaults.push(...tls.getCACertificates("default"), ...tls.getCACertificates("system"));
7653
+ } catch {}
7654
+ cachedCa = extra.length ? [...new Set([...defaults, ...extra])] : undefined;
7655
+ cachedKey = key;
7656
+ checkedAt = Date.now();
7657
+ return cachedCa;
7658
+ };
7659
+ return async (input, init) => {
7660
+ const url = new URL(input instanceof Request ? input.url : String(input));
7661
+ const ca = url.protocol === "https:" ? resolveCa() : undefined;
7662
+ const local = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
7663
+ try {
7664
+ return await (fetchImpl ?? globalThis.fetch)(input, {
7665
+ ...init,
7666
+ ...local && init?.proxy === undefined ? { proxy: "" } : {},
7667
+ ...ca ? {
7668
+ tls: {
7669
+ ...init?.tls,
7670
+ ca: init?.tls?.ca ?? ca,
7671
+ rejectUnauthorized: true
7672
+ }
7673
+ } : {}
7674
+ });
7675
+ } catch (cause) {
7676
+ if (isCertificateError(cause))
7677
+ throw new Error(certificateErrorHint, { cause });
7678
+ throw cause;
7679
+ }
7680
+ };
7681
+ }
7682
+ var certificatePattern, certificateErrorPattern, certificateErrorHint = "TLS certificate verification failed. Configure your company CA PEM with NODE_EXTRA_CA_CERTS or LIGHTCODE_CA_CERTS, then restart Lightcode. If a CA is already configured, check the server certificate hostname, expiry, and chain.", networkFetch;
7683
+ var init_network_fetch = __esm(() => {
7684
+ certificatePattern = /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g;
7685
+ certificateErrorPattern = /CERT_(?:HAS_EXPIRED|NOT_YET_VALID|REVOKED|UNTRUSTED|SIGNATURE_FAILURE)|CERTIFICATE_VERIFY_FAILED|UNABLE_TO_(?:GET_ISSUER_CERT(?:_LOCALLY)?|VERIFY_LEAF_SIGNATURE)|DEPTH_ZERO_SELF_SIGNED_CERT|SELF_SIGNED_CERT_IN_CHAIN|ERR_TLS_CERT_ALTNAME_INVALID|certificate|self.signed|unable to (?:get local issuer|verify the first)/i;
7686
+ networkFetch = createNetworkFetch();
7687
+ });
7688
+
7555
7689
  // packages/ai/src/web-fetch/runtime.ts
7556
7690
  function decodeHtmlEntities(value) {
7557
7691
  return value.replace(/&(#x?[0-9a-f]+|[a-z]+);/gi, (match, entity) => {
7558
7692
  const normalized = entity.toLowerCase();
7559
7693
  if (normalized.startsWith("#x")) {
7560
7694
  const codePoint = Number.parseInt(normalized.slice(2), 16);
7561
- return Number.isFinite(codePoint) ? String.fromCodePoint(codePoint) : match;
7695
+ return Number.isInteger(codePoint) && codePoint >= 0 && codePoint <= 1114111 ? String.fromCodePoint(codePoint) : match;
7562
7696
  }
7563
7697
  if (normalized.startsWith("#")) {
7564
7698
  const codePoint = Number.parseInt(normalized.slice(1), 10);
7565
- return Number.isFinite(codePoint) ? String.fromCodePoint(codePoint) : match;
7699
+ return Number.isInteger(codePoint) && codePoint >= 0 && codePoint <= 1114111 ? String.fromCodePoint(codePoint) : match;
7566
7700
  }
7567
7701
  return htmlEntityMap[normalized] ?? match;
7568
7702
  });
@@ -7589,6 +7723,34 @@ function normalizeContentToText(content, contentType) {
7589
7723
  return content.replace(/\r\n/g, `
7590
7724
  `).trim();
7591
7725
  }
7726
+ async function readBoundedBody(response) {
7727
+ if (!response.body)
7728
+ return { text: "", truncated: false };
7729
+ const reader = response.body.getReader();
7730
+ const decoder = new TextDecoder;
7731
+ let bytes = 0;
7732
+ let text = "";
7733
+ let truncated = false;
7734
+ try {
7735
+ for (;; ) {
7736
+ const { done, value } = await reader.read();
7737
+ if (done)
7738
+ break;
7739
+ const available = maxDownloadBytes - bytes;
7740
+ text += decoder.decode(value.subarray(0, available), { stream: true });
7741
+ bytes += value.byteLength;
7742
+ if (bytes >= maxDownloadBytes) {
7743
+ truncated = true;
7744
+ await reader.cancel();
7745
+ break;
7746
+ }
7747
+ }
7748
+ text += decoder.decode();
7749
+ return { text, truncated };
7750
+ } finally {
7751
+ reader.releaseLock();
7752
+ }
7753
+ }
7592
7754
  function errorOutput({
7593
7755
  parsedInput,
7594
7756
  code,
@@ -7616,7 +7778,7 @@ async function executeWebFetch(input, options = {}) {
7616
7778
  const timeoutSignal = AbortSignal.timeout(parsedInput.timeoutMs);
7617
7779
  const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
7618
7780
  try {
7619
- const response = await (options.fetch ?? globalThis.fetch)(parsedInput.url, {
7781
+ const response = await (options.fetch ?? networkFetch)(parsedInput.url, {
7620
7782
  redirect: "follow",
7621
7783
  signal,
7622
7784
  headers: {
@@ -7625,7 +7787,8 @@ async function executeWebFetch(input, options = {}) {
7625
7787
  }
7626
7788
  });
7627
7789
  const contentType = response.headers.get("content-type");
7628
- const rawText = await response.text();
7790
+ const downloaded = await readBoundedBody(response);
7791
+ const rawText = downloaded.text;
7629
7792
  const normalizedText = normalizeContentToText(rawText, contentType);
7630
7793
  const truncated = truncateText(normalizedText, parsedInput.maxChars);
7631
7794
  return webFetchOutputSchema.parse({
@@ -7637,7 +7800,7 @@ async function executeWebFetch(input, options = {}) {
7637
7800
  contentType,
7638
7801
  title: contentType?.toLowerCase().includes("html") ? extractTitle(rawText) : null,
7639
7802
  text: truncated.text,
7640
- truncated: truncated.truncated,
7803
+ truncated: truncated.truncated || downloaded.truncated,
7641
7804
  fetchedAt: new Date().toISOString(),
7642
7805
  error: response.ok ? null : {
7643
7806
  code: "http_error",
@@ -7652,8 +7815,9 @@ async function executeWebFetch(input, options = {}) {
7652
7815
  });
7653
7816
  }
7654
7817
  }
7655
- var htmlEntityMap;
7818
+ var htmlEntityMap, maxDownloadBytes;
7656
7819
  var init_runtime13 = __esm(() => {
7820
+ init_network_fetch();
7657
7821
  init_output_utils();
7658
7822
  init_schema14();
7659
7823
  htmlEntityMap = {
@@ -7664,10 +7828,11 @@ var init_runtime13 = __esm(() => {
7664
7828
  apos: "'",
7665
7829
  nbsp: " "
7666
7830
  };
7831
+ maxDownloadBytes = 2 * 1024 * 1024;
7667
7832
  });
7668
7833
 
7669
7834
  // packages/ai/src/config/credentials.ts
7670
- import { chmodSync, existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
7835
+ import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
7671
7836
  import os3 from "os";
7672
7837
  import path14 from "path";
7673
7838
  import { z as z35 } from "zod";
@@ -7680,11 +7845,11 @@ function getCredentialsPath(env = process.env) {
7680
7845
  }
7681
7846
  function readStoredCredentials(env = process.env) {
7682
7847
  const credentialsPath = getCredentialsPath(env);
7683
- if (!existsSync6(credentialsPath)) {
7848
+ if (!existsSync5(credentialsPath)) {
7684
7849
  return {};
7685
7850
  }
7686
7851
  try {
7687
- const parsed = storedCredentialsSchema.safeParse(JSON.parse(readFileSync4(credentialsPath, "utf8")));
7852
+ const parsed = storedCredentialsSchema.safeParse(JSON.parse(readFileSync5(credentialsPath, "utf8")));
7688
7853
  return parsed.success ? parsed.data : {};
7689
7854
  } catch {
7690
7855
  return {};
@@ -7896,7 +8061,7 @@ async function executeWebSearch(input, options = {}) {
7896
8061
  }
7897
8062
  return await searchBrave(parsedInput, {
7898
8063
  apiKey: keys.brave,
7899
- fetch: options.fetch ?? globalThis.fetch,
8064
+ fetch: options.fetch ?? networkFetch,
7900
8065
  signal,
7901
8066
  maxCharactersPerResult: config2.maxCharactersPerResult
7902
8067
  });
@@ -7912,7 +8077,7 @@ async function executeWebSearch(input, options = {}) {
7912
8077
  }
7913
8078
  return await searchTavily(parsedInput, {
7914
8079
  apiKey: keys.tavily,
7915
- fetch: options.fetch ?? globalThis.fetch,
8080
+ fetch: options.fetch ?? networkFetch,
7916
8081
  signal,
7917
8082
  maxCharactersPerResult: config2.maxCharactersPerResult
7918
8083
  });
@@ -7953,6 +8118,7 @@ async function executeWebSearch(input, options = {}) {
7953
8118
  }
7954
8119
  var localUsesByTurn;
7955
8120
  var init_runtime14 = __esm(() => {
8121
+ init_network_fetch();
7956
8122
  init_lightcode_config();
7957
8123
  init_credentials();
7958
8124
  init_config2();
@@ -9479,7 +9645,7 @@ var init_schema18 = __esm(() => {
9479
9645
  });
9480
9646
 
9481
9647
  // packages/ai/src/plugins/runtime.ts
9482
- import { existsSync as existsSync7, readFileSync as readFileSync5, readdirSync as readdirSync3 } from "fs";
9648
+ import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync3 } from "fs";
9483
9649
  import os4 from "os";
9484
9650
  import path16 from "path";
9485
9651
  function pluginRoots(cwd) {
@@ -9491,7 +9657,7 @@ function pluginRoots(cwd) {
9491
9657
  function listPlugins({ cwd = process.cwd() } = {}) {
9492
9658
  const plugins = [];
9493
9659
  for (const root of pluginRoots(cwd)) {
9494
- if (!existsSync7(root)) {
9660
+ if (!existsSync6(root)) {
9495
9661
  continue;
9496
9662
  }
9497
9663
  for (const entry of readdirSync3(root, { withFileTypes: true })) {
@@ -9499,10 +9665,10 @@ function listPlugins({ cwd = process.cwd() } = {}) {
9499
9665
  continue;
9500
9666
  }
9501
9667
  const manifestPath = path16.join(root, entry.name, "plugin.json");
9502
- if (!existsSync7(manifestPath)) {
9668
+ if (!existsSync6(manifestPath)) {
9503
9669
  continue;
9504
9670
  }
9505
- const manifest = pluginManifestSchema.parse(JSON.parse(readFileSync5(manifestPath, "utf8")));
9671
+ const manifest = pluginManifestSchema.parse(JSON.parse(readFileSync6(manifestPath, "utf8")));
9506
9672
  plugins.push({
9507
9673
  id: manifest.id,
9508
9674
  name: manifest.name,
@@ -9522,7 +9688,7 @@ var init_runtime16 = __esm(() => {
9522
9688
 
9523
9689
  // packages/ai/src/workspace-browser.ts
9524
9690
  import { z as z38 } from "zod";
9525
- var workspaceLocationIdSchema, workspaceLocationStateSchema, workspaceLocationSchema, workspaceLocationsResponseSchema, workspaceBrowserOpenRequestSchema, workspaceBrowserIdSchema, workspaceBrowserOpenResponseSchema, workspacePathSegmentSchema, workspacePathSegmentsSchema, workspaceBrowserCursorSchema, workspaceBrowserEntriesRequestSchema, workspaceBrowserEntryKindSchema, workspaceBrowserSymlinkStateSchema, workspaceBrowserEntrySchema, workspaceBrowserEntriesResponseSchema, workspaceBrowserSelectRequestSchema, workspaceGrantIdSchema, workspaceGrantSchema, workspaceBrowserSelectResponseSchema, workspaceSessionPathParamsSchema, workspaceSessionCreateRequestSchema, workspaceBrowserPathParamsSchema, workspaceApiErrorCodeSchema, workspaceApiErrorResponseSchema;
9691
+ var workspaceLocationIdSchema, workspaceLocationStateSchema, workspaceLocationSchema, workspaceLocationsResponseSchema, workspaceBrowserOpenRequestSchema, workspaceBrowserIdSchema, workspaceBrowserOpenResponseSchema, workspacePathSegmentSchema, workspacePathSegmentsSchema, workspaceBrowserCursorSchema, workspaceBrowserEntriesRequestSchema, workspaceBrowserEntryKindSchema, workspaceBrowserSymlinkStateSchema, workspaceBrowserEntrySchema, workspaceBrowserEntriesResponseSchema, workspaceBrowserSelectRequestSchema, workspaceGrantIdSchema, workspaceGrantSchema, workspaceNativePickerRequestSchema, workspaceNativePickerResponseSchema, workspaceBrowserSelectResponseSchema, workspaceSessionPathParamsSchema, workspaceSessionCreateRequestSchema, workspaceBrowserPathParamsSchema, workspaceApiErrorCodeSchema, workspaceApiErrorResponseSchema;
9526
9692
  var init_workspace_browser = __esm(() => {
9527
9693
  init_coding_agent_modes();
9528
9694
  init_permissions();
@@ -9604,6 +9770,16 @@ var init_workspace_browser = __esm(() => {
9604
9770
  pathLabel: z38.string().min(1).max(4096),
9605
9771
  createdAt: z38.string().min(1)
9606
9772
  }).strict();
9773
+ workspaceNativePickerRequestSchema = z38.object({}).strict();
9774
+ workspaceNativePickerResponseSchema = z38.discriminatedUnion("outcome", [
9775
+ z38.object({
9776
+ outcome: z38.literal("selected"),
9777
+ workspace: workspaceGrantSchema
9778
+ }).strict(),
9779
+ z38.object({
9780
+ outcome: z38.literal("cancelled")
9781
+ }).strict()
9782
+ ]);
9607
9783
  workspaceBrowserSelectResponseSchema = z38.object({
9608
9784
  workspace: workspaceGrantSchema
9609
9785
  }).strict();
@@ -9631,7 +9807,10 @@ var init_workspace_browser = __esm(() => {
9631
9807
  "browser_capability_expired",
9632
9808
  "workspace_grant_not_found",
9633
9809
  "invalid_cursor",
9634
- "workspace_unavailable"
9810
+ "workspace_unavailable",
9811
+ "native_picker_busy",
9812
+ "native_picker_unavailable",
9813
+ "native_picker_failed"
9635
9814
  ]);
9636
9815
  workspaceApiErrorResponseSchema = z38.object({
9637
9816
  error: z38.string().min(1),
@@ -9988,6 +10167,9 @@ function classifyChatError(error) {
9988
10167
  if (RetryError.isInstance(error) && error.lastError) {
9989
10168
  return classifyChatError(error.lastError);
9990
10169
  }
10170
+ if (!(APICallError.isInstance(error) && typeof error.statusCode === "number") && isCertificateError(error)) {
10171
+ return { kind: "network", retryable: false, message: certificateErrorHint };
10172
+ }
9991
10173
  if (APICallError.isInstance(error)) {
9992
10174
  const responseBody = error.responseBody ?? "";
9993
10175
  const message2 = responseBody.length > 0 ? responseBody : error.message;
@@ -10086,6 +10268,7 @@ function logChatDisconnectEvent({
10086
10268
  var chatFailureCounters, logger2, retryableStatusCodes, contextOverflowPattern, contextLimitPattern;
10087
10269
  var init_chat_observability = __esm(() => {
10088
10270
  init_src();
10271
+ init_network_fetch();
10089
10272
  chatFailureCounters = {
10090
10273
  provider_schema_rejection: 0,
10091
10274
  provider_billing_quota: 0,
@@ -10301,8 +10484,8 @@ var config5;
10301
10484
  var init_class = __esm(() => {
10302
10485
  config5 = {
10303
10486
  previewFeatures: [],
10304
- clientVersion: "7.8.0",
10305
- engineVersion: "3c6e192761c0362d496ed980de936e2f3cebcd3a",
10487
+ clientVersion: "7.10.0",
10488
+ engineVersion: "0edf323efd1d98336f3f0a68684b56f689b900d3",
10306
10489
  activeProvider: "sqlite",
10307
10490
  inlineSchema: `generator client {
10308
10491
  provider = "prisma-client"
@@ -10545,7 +10728,7 @@ model SubagentTask {
10545
10728
  graph: ""
10546
10729
  }
10547
10730
  };
10548
- config5.runtimeDataModel = JSON.parse('{"models":{"ChatSession":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"title","kind":"scalar","type":"String"},{"name":"autoTitled","kind":"scalar","type":"Boolean","dbName":"auto_titled"},{"name":"cwd","kind":"scalar","type":"String"},{"name":"workspaceDevice","kind":"scalar","type":"String","dbName":"workspace_device"},{"name":"workspaceInode","kind":"scalar","type":"String","dbName":"workspace_inode"},{"name":"mode","kind":"scalar","type":"String"},{"name":"permissionMode","kind":"scalar","type":"String","dbName":"permission_mode"},{"name":"model","kind":"scalar","type":"String"},{"name":"revision","kind":"scalar","type":"Int"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"messages","kind":"object","type":"ChatMessage","relationName":"ChatMessageToChatSession"},{"name":"interactions","kind":"object","type":"ChatInteraction","relationName":"ChatInteractionToChatSession"},{"name":"subagentTasks","kind":"object","type":"SubagentTask","relationName":"ChatSessionToSubagentTask"},{"name":"contextState","kind":"object","type":"SessionContextState","relationName":"ChatSessionToSessionContextState"},{"name":"runs","kind":"object","type":"ChatRun","relationName":"ChatRunToChatSession"},{"name":"turnReverts","kind":"object","type":"ChatTurnRevert","relationName":"ChatSessionToChatTurnRevert"}],"dbName":"sessions"},"SessionContextState":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"summary","kind":"scalar","type":"String"},{"name":"anchorMessageId","kind":"scalar","type":"String","dbName":"anchor_message_id"},{"name":"coveredMessageCount","kind":"scalar","type":"Int","dbName":"covered_message_count"},{"name":"estimatedTokens","kind":"scalar","type":"Int","dbName":"estimated_tokens"},{"name":"tier","kind":"scalar","type":"String"},{"name":"model","kind":"scalar","type":"String"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatSessionToSessionContextState"}],"dbName":"session_context_states"},"ChatMessage":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"messageId","kind":"scalar","type":"String","dbName":"message_id"},{"name":"role","kind":"enum","type":"MessageRole"},{"name":"model","kind":"scalar","type":"String"},{"name":"sequence","kind":"scalar","type":"Int"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatMessageToChatSession"},{"name":"parts","kind":"object","type":"ChatMessagePart","relationName":"ChatMessageToChatMessagePart"}],"dbName":"messages"},"ChatMessagePart":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"messageId","kind":"scalar","type":"String","dbName":"message_id"},{"name":"partIndex","kind":"scalar","type":"Int","dbName":"part_index"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"message","kind":"object","type":"ChatMessage","relationName":"ChatMessageToChatMessagePart"}],"dbName":"message_parts"},"ChatRun":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"clientTurnId","kind":"scalar","type":"String","dbName":"client_turn_id"},{"name":"status","kind":"enum","type":"ChatRunStatus"},{"name":"baseRevision","kind":"scalar","type":"Int","dbName":"base_revision"},{"name":"finalRevision","kind":"scalar","type":"Int","dbName":"final_revision"},{"name":"error","kind":"scalar","type":"String"},{"name":"startedAt","kind":"scalar","type":"DateTime","dbName":"started_at"},{"name":"finishedAt","kind":"scalar","type":"DateTime","dbName":"finished_at"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatRunToChatSession"},{"name":"events","kind":"object","type":"ChatRunEvent","relationName":"ChatRunToChatRunEvent"}],"dbName":"chat_runs"},"ChatRunEvent":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"runId","kind":"scalar","type":"String","dbName":"run_id"},{"name":"cursor","kind":"scalar","type":"Int"},{"name":"kind","kind":"scalar","type":"String"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"run","kind":"object","type":"ChatRun","relationName":"ChatRunToChatRunEvent"}],"dbName":"chat_run_events"},"ChatTurnRevert":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"turnKey","kind":"scalar","type":"String","dbName":"turn_key"},{"name":"messages","kind":"scalar","type":"Json"},{"name":"state","kind":"scalar","type":"String"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"reappliedAt","kind":"scalar","type":"DateTime","dbName":"reapplied_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatSessionToChatTurnRevert"}],"dbName":"chat_turn_reverts"},"ChatInteraction":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"toolCallId","kind":"scalar","type":"String","dbName":"tool_call_id"},{"name":"kind","kind":"enum","type":"ChatInteractionKind"},{"name":"status","kind":"enum","type":"ChatInteractionStatus"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"response","kind":"scalar","type":"Json"},{"name":"resolvedAt","kind":"scalar","type":"DateTime","dbName":"resolved_at"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatInteractionToChatSession"}],"dbName":"chat_interactions"},"SubagentTask":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"parentSessionId","kind":"scalar","type":"String","dbName":"parent_session_id"},{"name":"prompt","kind":"scalar","type":"String"},{"name":"status","kind":"enum","type":"SubagentTaskStatus"},{"name":"mode","kind":"scalar","type":"String"},{"name":"model","kind":"scalar","type":"String"},{"name":"allowedTools","kind":"scalar","type":"Json","dbName":"allowed_tools"},{"name":"output","kind":"scalar","type":"Json"},{"name":"error","kind":"scalar","type":"String"},{"name":"startedAt","kind":"scalar","type":"DateTime","dbName":"started_at"},{"name":"finishedAt","kind":"scalar","type":"DateTime","dbName":"finished_at"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"parentSession","kind":"object","type":"ChatSession","relationName":"ChatSessionToSubagentTask"}],"dbName":"subagent_tasks"}},"enums":{},"types":{}}');
10731
+ config5.runtimeDataModel = JSON.parse('{"models":{"ChatSession":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"title","kind":"scalar","type":"String"},{"name":"autoTitled","kind":"scalar","type":"Boolean","dbName":"auto_titled"},{"name":"cwd","kind":"scalar","type":"String"},{"name":"workspaceDevice","kind":"scalar","type":"String","dbName":"workspace_device"},{"name":"workspaceInode","kind":"scalar","type":"String","dbName":"workspace_inode"},{"name":"mode","kind":"scalar","type":"String"},{"name":"permissionMode","kind":"scalar","type":"String","dbName":"permission_mode"},{"name":"model","kind":"scalar","type":"String"},{"name":"revision","kind":"scalar","type":"Int"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"messages","kind":"object","type":"ChatMessage","relationName":"ChatMessageToChatSession"},{"name":"interactions","kind":"object","type":"ChatInteraction","relationName":"ChatInteractionToChatSession"},{"name":"subagentTasks","kind":"object","type":"SubagentTask","relationName":"ChatSessionToSubagentTask"},{"name":"contextState","kind":"object","type":"SessionContextState","relationName":"ChatSessionToSessionContextState"},{"name":"runs","kind":"object","type":"ChatRun","relationName":"ChatRunToChatSession"},{"name":"turnReverts","kind":"object","type":"ChatTurnRevert","relationName":"ChatSessionToChatTurnRevert"}],"dbName":"sessions","schema":null},"SessionContextState":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"summary","kind":"scalar","type":"String"},{"name":"anchorMessageId","kind":"scalar","type":"String","dbName":"anchor_message_id"},{"name":"coveredMessageCount","kind":"scalar","type":"Int","dbName":"covered_message_count"},{"name":"estimatedTokens","kind":"scalar","type":"Int","dbName":"estimated_tokens"},{"name":"tier","kind":"scalar","type":"String"},{"name":"model","kind":"scalar","type":"String"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatSessionToSessionContextState"}],"dbName":"session_context_states","schema":null},"ChatMessage":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"messageId","kind":"scalar","type":"String","dbName":"message_id"},{"name":"role","kind":"enum","type":"MessageRole"},{"name":"model","kind":"scalar","type":"String"},{"name":"sequence","kind":"scalar","type":"Int"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatMessageToChatSession"},{"name":"parts","kind":"object","type":"ChatMessagePart","relationName":"ChatMessageToChatMessagePart"}],"dbName":"messages","schema":null},"ChatMessagePart":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"messageId","kind":"scalar","type":"String","dbName":"message_id"},{"name":"partIndex","kind":"scalar","type":"Int","dbName":"part_index"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"message","kind":"object","type":"ChatMessage","relationName":"ChatMessageToChatMessagePart"}],"dbName":"message_parts","schema":null},"ChatRun":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"clientTurnId","kind":"scalar","type":"String","dbName":"client_turn_id"},{"name":"status","kind":"enum","type":"ChatRunStatus"},{"name":"baseRevision","kind":"scalar","type":"Int","dbName":"base_revision"},{"name":"finalRevision","kind":"scalar","type":"Int","dbName":"final_revision"},{"name":"error","kind":"scalar","type":"String"},{"name":"startedAt","kind":"scalar","type":"DateTime","dbName":"started_at"},{"name":"finishedAt","kind":"scalar","type":"DateTime","dbName":"finished_at"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatRunToChatSession"},{"name":"events","kind":"object","type":"ChatRunEvent","relationName":"ChatRunToChatRunEvent"}],"dbName":"chat_runs","schema":null},"ChatRunEvent":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"runId","kind":"scalar","type":"String","dbName":"run_id"},{"name":"cursor","kind":"scalar","type":"Int"},{"name":"kind","kind":"scalar","type":"String"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"run","kind":"object","type":"ChatRun","relationName":"ChatRunToChatRunEvent"}],"dbName":"chat_run_events","schema":null},"ChatTurnRevert":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"turnKey","kind":"scalar","type":"String","dbName":"turn_key"},{"name":"messages","kind":"scalar","type":"Json"},{"name":"state","kind":"scalar","type":"String"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"reappliedAt","kind":"scalar","type":"DateTime","dbName":"reapplied_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatSessionToChatTurnRevert"}],"dbName":"chat_turn_reverts","schema":null},"ChatInteraction":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"sessionId","kind":"scalar","type":"String","dbName":"session_id"},{"name":"toolCallId","kind":"scalar","type":"String","dbName":"tool_call_id"},{"name":"kind","kind":"enum","type":"ChatInteractionKind"},{"name":"status","kind":"enum","type":"ChatInteractionStatus"},{"name":"payload","kind":"scalar","type":"Json"},{"name":"response","kind":"scalar","type":"Json"},{"name":"resolvedAt","kind":"scalar","type":"DateTime","dbName":"resolved_at"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"session","kind":"object","type":"ChatSession","relationName":"ChatInteractionToChatSession"}],"dbName":"chat_interactions","schema":null},"SubagentTask":{"fields":[{"name":"id","kind":"scalar","type":"String"},{"name":"parentSessionId","kind":"scalar","type":"String","dbName":"parent_session_id"},{"name":"prompt","kind":"scalar","type":"String"},{"name":"status","kind":"enum","type":"SubagentTaskStatus"},{"name":"mode","kind":"scalar","type":"String"},{"name":"model","kind":"scalar","type":"String"},{"name":"allowedTools","kind":"scalar","type":"Json","dbName":"allowed_tools"},{"name":"output","kind":"scalar","type":"Json"},{"name":"error","kind":"scalar","type":"String"},{"name":"startedAt","kind":"scalar","type":"DateTime","dbName":"started_at"},{"name":"finishedAt","kind":"scalar","type":"DateTime","dbName":"finished_at"},{"name":"createdAt","kind":"scalar","type":"DateTime","dbName":"created_at"},{"name":"updatedAt","kind":"scalar","type":"DateTime","dbName":"updated_at"},{"name":"parentSession","kind":"object","type":"ChatSession","relationName":"ChatSessionToSubagentTask"}],"dbName":"subagent_tasks","schema":null}},"enums":{},"types":{}}');
10549
10732
  config5.parameterizationSchema = {
10550
10733
  strings: JSON.parse('["where","orderBy","cursor","session","message","parts","_count","messages","interactions","parentSession","subagentTasks","contextState","run","events","runs","turnReverts","ChatSession.findUnique","ChatSession.findUniqueOrThrow","ChatSession.findFirst","ChatSession.findFirstOrThrow","ChatSession.findMany","data","ChatSession.createOne","ChatSession.createMany","ChatSession.createManyAndReturn","ChatSession.updateOne","ChatSession.updateMany","ChatSession.updateManyAndReturn","create","update","ChatSession.upsertOne","ChatSession.deleteOne","ChatSession.deleteMany","having","_avg","_sum","_min","_max","ChatSession.groupBy","ChatSession.aggregate","SessionContextState.findUnique","SessionContextState.findUniqueOrThrow","SessionContextState.findFirst","SessionContextState.findFirstOrThrow","SessionContextState.findMany","SessionContextState.createOne","SessionContextState.createMany","SessionContextState.createManyAndReturn","SessionContextState.updateOne","SessionContextState.updateMany","SessionContextState.updateManyAndReturn","SessionContextState.upsertOne","SessionContextState.deleteOne","SessionContextState.deleteMany","SessionContextState.groupBy","SessionContextState.aggregate","ChatMessage.findUnique","ChatMessage.findUniqueOrThrow","ChatMessage.findFirst","ChatMessage.findFirstOrThrow","ChatMessage.findMany","ChatMessage.createOne","ChatMessage.createMany","ChatMessage.createManyAndReturn","ChatMessage.updateOne","ChatMessage.updateMany","ChatMessage.updateManyAndReturn","ChatMessage.upsertOne","ChatMessage.deleteOne","ChatMessage.deleteMany","ChatMessage.groupBy","ChatMessage.aggregate","ChatMessagePart.findUnique","ChatMessagePart.findUniqueOrThrow","ChatMessagePart.findFirst","ChatMessagePart.findFirstOrThrow","ChatMessagePart.findMany","ChatMessagePart.createOne","ChatMessagePart.createMany","ChatMessagePart.createManyAndReturn","ChatMessagePart.updateOne","ChatMessagePart.updateMany","ChatMessagePart.updateManyAndReturn","ChatMessagePart.upsertOne","ChatMessagePart.deleteOne","ChatMessagePart.deleteMany","ChatMessagePart.groupBy","ChatMessagePart.aggregate","ChatRun.findUnique","ChatRun.findUniqueOrThrow","ChatRun.findFirst","ChatRun.findFirstOrThrow","ChatRun.findMany","ChatRun.createOne","ChatRun.createMany","ChatRun.createManyAndReturn","ChatRun.updateOne","ChatRun.updateMany","ChatRun.updateManyAndReturn","ChatRun.upsertOne","ChatRun.deleteOne","ChatRun.deleteMany","ChatRun.groupBy","ChatRun.aggregate","ChatRunEvent.findUnique","ChatRunEvent.findUniqueOrThrow","ChatRunEvent.findFirst","ChatRunEvent.findFirstOrThrow","ChatRunEvent.findMany","ChatRunEvent.createOne","ChatRunEvent.createMany","ChatRunEvent.createManyAndReturn","ChatRunEvent.updateOne","ChatRunEvent.updateMany","ChatRunEvent.updateManyAndReturn","ChatRunEvent.upsertOne","ChatRunEvent.deleteOne","ChatRunEvent.deleteMany","ChatRunEvent.groupBy","ChatRunEvent.aggregate","ChatTurnRevert.findUnique","ChatTurnRevert.findUniqueOrThrow","ChatTurnRevert.findFirst","ChatTurnRevert.findFirstOrThrow","ChatTurnRevert.findMany","ChatTurnRevert.createOne","ChatTurnRevert.createMany","ChatTurnRevert.createManyAndReturn","ChatTurnRevert.updateOne","ChatTurnRevert.updateMany","ChatTurnRevert.updateManyAndReturn","ChatTurnRevert.upsertOne","ChatTurnRevert.deleteOne","ChatTurnRevert.deleteMany","ChatTurnRevert.groupBy","ChatTurnRevert.aggregate","ChatInteraction.findUnique","ChatInteraction.findUniqueOrThrow","ChatInteraction.findFirst","ChatInteraction.findFirstOrThrow","ChatInteraction.findMany","ChatInteraction.createOne","ChatInteraction.createMany","ChatInteraction.createManyAndReturn","ChatInteraction.updateOne","ChatInteraction.updateMany","ChatInteraction.updateManyAndReturn","ChatInteraction.upsertOne","ChatInteraction.deleteOne","ChatInteraction.deleteMany","ChatInteraction.groupBy","ChatInteraction.aggregate","SubagentTask.findUnique","SubagentTask.findUniqueOrThrow","SubagentTask.findFirst","SubagentTask.findFirstOrThrow","SubagentTask.findMany","SubagentTask.createOne","SubagentTask.createMany","SubagentTask.createManyAndReturn","SubagentTask.updateOne","SubagentTask.updateMany","SubagentTask.updateManyAndReturn","SubagentTask.upsertOne","SubagentTask.deleteOne","SubagentTask.deleteMany","SubagentTask.groupBy","SubagentTask.aggregate","AND","OR","NOT","id","parentSessionId","prompt","SubagentTaskStatus","status","mode","model","allowedTools","output","error","startedAt","finishedAt","createdAt","updatedAt","equals","in","notIn","lt","lte","gt","gte","not","string_contains","string_starts_with","string_ends_with","array_starts_with","array_ends_with","contains","startsWith","endsWith","sessionId","toolCallId","ChatInteractionKind","kind","ChatInteractionStatus","payload","response","resolvedAt","turnKey","state","reappliedAt","runId","clientTurnId","ChatRunStatus","baseRevision","finalRevision","messageId","partIndex","MessageRole","role","sequence","summary","anchorMessageId","coveredMessageCount","estimatedTokens","tier","title","autoTitled","cwd","workspaceDevice","workspaceInode","permissionMode","revision","every","some","none","runId_cursor","sessionId_clientTurnId","sessionId_toolCallId","messageId_partIndex","sessionId_messageId","sessionId_sequence","is","isNot","connectOrCreate","upsert","createMany","set","disconnect","delete","connect","updateMany","deleteMany","increment","decrement","multiply","divide"]'),
10551
10734
  graph: "sgRYkAEVBwAArAIAIAgAAK0CACAKAACuAgAgCwAArwIAIA4AALACACAPAACxAgAgqAEAAKoCADCpAQAAKQAQqgEAAKoCADCrAQEAAAABsAEBAKECACGxAQEAowIAIbcBQACkAgAhuAFAAKQCACHjAQEAowIAIeQBIACrAgAh5QEBAKMCACHmAQEAowIAIecBAQCjAgAh6AEBAKMCACHpAQIAogIAIQEAAAABACAOAwAApQIAIAUAAMsCACCoAQAAyQIAMKkBAAADABCqAQAAyQIAMKsBAQChAgAhsQEBAKMCACG3AUAApAIAIbgBQACkAgAhyQEBAKECACHOAQAAswIAINkBAQChAgAh3AEAAMoC3AEi3QECAKICACEDAwAApgMAIAUAAIMEACCxAQAAzAIAIBADAAClAgAgBQAAywIAIKgBAADJAgAwqQEAAAMAEKoBAADJAgAwqwEBAAAAAbEBAQCjAgAhtwFAAKQCACG4AUAApAIAIckBAQChAgAhzgEAALMCACDZAQEAoQIAIdwBAADKAtwBIt0BAgCiAgAh8QEAAMcCACDyAQAAyAIAIAMAAAADACABAAAEADACAAAFACAJBAAAxgIAIKgBAADFAgAwqQEAAAcAEKoBAADFAgAwqwEBAKECACG3AUAApAIAIc4BAACzAgAg2QEBAKECACHaAQIAogIAIQEEAACCBAAgCgQAAMYCACCoAQAAxQIAMKkBAAAHABCqAQAAxQIAMKsBAQAAAAG3AUAApAIAIc4BAACzAgAg2QEBAKECACHaAQIAogIAIfABAADEAgAgAwAAAAcAIAEAAAgAMAIAAAkAIAEAAAAHACAOAwAApQIAIKgBAADBAgAwqQEAAAwAEKoBAADBAgAwqwEBAKECACGvAQAAwwLOASK3AUAApAIAIbgBQACkAgAhyQEBAKECACHKAQEAoQIAIcwBAADCAswBIs4BAACzAgAgzwEAAL8CACDQAUAAtAIAIQMDAACmAwAgzwEAAMwCACDQAQAAzAIAIA8DAAClAgAgqAEAAMECADCpAQAADAAQqgEAAMECADCrAQEAAAABrwEAAMMCzgEitwFAAKQCACG4AUAApAIAIckBAQChAgAhygEBAKECACHMAQAAwgLMASLOAQAAswIAIM8BAAC_AgAg0AFAALQCACHvAQAAwAIAIAMAAAAMACABAAANADACAAAOACARCQAApQIAIKgBAAC9AgAwqQEAABAAEKoBAAC9AgAwqwEBAKECACGsAQEAoQIAIa0BAQChAgAhrwEAAL4CrwEisAEBAKECACGxAQEAowIAIbIBAACzAgAgswEAAL8CACC0AQEAowIAIbUBQAC0AgAhtgFAALQCACG3AUAApAIAIbgBQACkAgAhBgkAAKYDACCxAQAAzAIAILMBAADMAgAgtAEAAMwCACC1AQAAzAIAILYBAADMAgAgEQkAAKUCACCoAQAAvQIAMKkBAAAQABCqAQAAvQIAMKsBAQAAAAGsAQEAoQIAIa0BAQChAgAhrwEAAL4CrwEisAEBAKECACGxAQEAowIAIbIBAACzAgAgswEAAL8CACC0AQEAowIAIbUBQAC0AgAhtgFAALQCACG3AUAApAIAIbgBQACkAgAhAwAAABAAIAEAABEAMAIAABIAIA4DAAClAgAgqAEAAKACADCpAQAAFAAQqgEAAKACADCrAQEAoQIAIbEBAQCjAgAhtwFAAKQCACG4AUAApAIAIckBAQChAgAh3gEBAKECACHfAQEAoQIAIeABAgCiAgAh4QECAKICACHiAQEAoQIAIQEAAAAUACAQAwAApQIAIA0AALwCACCoAQAAuQIAMKkBAAAWABCqAQAAuQIAMKsBAQChAgAhrwEAALoC1wEitAEBAKMCACG1AUAAtAIAIbYBQAC0AgAhtwFAAKQCACG4AUAApAIAIckBAQChAgAh1QEBAKECACHXAQIAogIAIdgBAgC7AgAhBgMAAKYDACANAACBBAAgtAEAAMwCACC1AQAAzAIAILYBAADMAgAg2AEAAMwCACARAwAApQIAIA0AALwCACCoAQAAuQIAMKkBAAAWABCqAQAAuQIAMKsBAQAAAAGvAQAAugLXASK0AQEAowIAIbUBQAC0AgAhtgFAALQCACG3AUAApAIAIbgBQACkAgAhyQEBAKECACHVAQEAoQIAIdcBAgCiAgAh2AECALsCACHuAQAAuAIAIAMAAAAWACABAAAXADACAAAYACAKAgIAogIAIQwAALcCACCoAQAAtgIAMKkBAAAaABCqAQAAtgIAMKsBAQChAgAhtwFAAKQCACHMAQEAoQIAIc4BAACzAgAg1AEBAKECACEBDAAAgAQAIAsCAgCiAgAhDAAAtwIAIKgBAAC2AgAwqQEAABoAEKoBAAC2AgAwqwEBAAAAAbcBQACkAgAhzAEBAKECACHOAQAAswIAINQBAQChAgAh7QEAALUCACADAAAAGgAgAQAAGwAwAgAAHAAgAQAAABoAIAsDAAClAgAgBwAAswIAIKgBAACyAgAwqQEAAB8AEKoBAACyAgAwqwEBAKECACG3AUAApAIAIckBAQChAgAh0QEBAKECACHSAQEAoQIAIdMBQAC0AgAhAgMAAKYDACDTAQAAzAIAIAsDAAClAgAgBwAAswIAIKgBAACyAgAwqQEAAB8AEKoBAACyAgAwqwEBAAAAAbcBQACkAgAhyQEBAKECACHRAQEAoQIAIdIBAQChAgAh0wFAALQCACEDAAAAHwAgAQAAIAAwAgAAIQAgAQAAAAMAIAEAAAAMACABAAAAEAAgAQAAABYAIAEAAAAfACABAAAAAQAgFQcAAKwCACAIAACtAgAgCgAArgIAIAsAAK8CACAOAACwAgAgDwAAsQIAIKgBAACqAgAwqQEAACkAEKoBAACqAgAwqwEBAKECACGwAQEAoQIAIbEBAQCjAgAhtwFAAKQCACG4AUAApAIAIeMBAQCjAgAh5AEgAKsCACHlAQEAowIAIeYBAQCjAgAh5wEBAKMCACHoAQEAowIAIekBAgCiAgAhDAcAAPoDACAIAAD7AwAgCgAA_AMAIAsAAP0DACAOAAD-AwAgDwAA_wMAILEBAADMAgAg4wEAAMwCACDlAQAAzAIAIOYBAADMAgAg5wEAAMwCACDoAQAAzAIAIAMAAAApACABAAAqADACAAABACADAAAAKQAgAQAAKgAwAgAAAQAgAwAAACkAIAEAACoAMAIAAAEAIBIHAAD0AwAgCAAA9QMAIAoAAPYDACALAAD3AwAgDgAA-AMAIA8AAPkDACCrAQEAAAABsAEBAAAAAbEBAQAAAAG3AUAAAAABuAFAAAAAAeMBAQAAAAHkASAAAAAB5QEBAAAAAeYBAQAAAAHnAQEAAAAB6AEBAAAAAekBAgAAAAEBFQAALgAgDKsBAQAAAAGwAQEAAAABsQEBAAAAAbcBQAAAAAG4AUAAAAAB4wEBAAAAAeQBIAAAAAHlAQEAAAAB5gEBAAAAAecBAQAAAAHoAQEAAAAB6QECAAAAAQEVAAAwADABFQAAMAAwEgcAAK0DACAIAACuAwAgCgAArwMAIAsAALADACAOAACxAwAgDwAAsgMAIKsBAQDQAgAhsAEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHjAQEA0gIAIeQBIACsAwAh5QEBANICACHmAQEA0gIAIecBAQDSAgAh6AEBANICACHpAQIA6AIAIQIAAAABACAVAAAzACAMqwEBANACACGwAQEA0AIAIbEBAQDSAgAhtwFAANQCACG4AUAA1AIAIeMBAQDSAgAh5AEgAKwDACHlAQEA0gIAIeYBAQDSAgAh5wEBANICACHoAQEA0gIAIekBAgDoAgAhAgAAACkAIBUAADUAIAIAAAApACAVAAA1ACADAAAAAQAgHAAALgAgHQAAMwAgAQAAAAEAIAEAAAApACALBgAApwMAICIAAKgDACAjAACrAwAgJAAAqgMAICUAAKkDACCxAQAAzAIAIOMBAADMAgAg5QEAAMwCACDmAQAAzAIAIOcBAADMAgAg6AEAAMwCACAPqAEAAKYCADCpAQAAPAAQqgEAAKYCADCrAQEA8gEAIbABAQDyAQAhsQEBAPQBACG3AUAA-AEAIbgBQAD4AQAh4wEBAPQBACHkASAApwIAIeUBAQD0AQAh5gEBAPQBACHnAQEA9AEAIegBAQD0AQAh6QECAJACACEDAAAAKQAgAQAAOwAwIQAAPAAgAwAAACkAIAEAACoAMAIAAAEAIA4DAAClAgAgqAEAAKACADCpAQAAFAAQqgEAAKACADCrAQEAAAABsQEBAKMCACG3AUAApAIAIbgBQACkAgAhyQEBAAAAAd4BAQChAgAh3wEBAKECACHgAQIAogIAIeEBAgCiAgAh4gEBAKECACEBAAAAPwAgAQAAAD8AIAIDAACmAwAgsQEAAMwCACADAAAAFAAgAQAAQgAwAgAAPwAgAwAAABQAIAEAAEIAMAIAAD8AIAMAAAAUACABAABCADACAAA_ACALAwAApQMAIKsBAQAAAAGxAQEAAAABtwFAAAAAAbgBQAAAAAHJAQEAAAAB3gEBAAAAAd8BAQAAAAHgAQIAAAAB4QECAAAAAeIBAQAAAAEBFQAARgAgCqsBAQAAAAGxAQEAAAABtwFAAAAAAbgBQAAAAAHJAQEAAAAB3gEBAAAAAd8BAQAAAAHgAQIAAAAB4QECAAAAAeIBAQAAAAEBFQAASAAwARUAAEgAMAsDAACkAwAgqwEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHJAQEA0AIAId4BAQDQAgAh3wEBANACACHgAQIA6AIAIeEBAgDoAgAh4gEBANACACECAAAAPwAgFQAASwAgCqsBAQDQAgAhsQEBANICACG3AUAA1AIAIbgBQADUAgAhyQEBANACACHeAQEA0AIAId8BAQDQAgAh4AECAOgCACHhAQIA6AIAIeIBAQDQAgAhAgAAABQAIBUAAE0AIAIAAAAUACAVAABNACADAAAAPwAgHAAARgAgHQAASwAgAQAAAD8AIAEAAAAUACAGBgAAnwMAICIAAKADACAjAACjAwAgJAAAogMAICUAAKEDACCxAQAAzAIAIA2oAQAAnwIAMKkBAABUABCqAQAAnwIAMKsBAQDyAQAhsQEBAPQBACG3AUAA-AEAIbgBQAD4AQAhyQEBAPIBACHeAQEA8gEAId8BAQDyAQAh4AECAJACACHhAQIAkAIAIeIBAQDyAQAhAwAAABQAIAEAAFMAMCEAAFQAIAMAAAAUACABAABCADACAAA_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_AQEAAAABwAEBAIECACHGAQEAAAABxwEBAAAAAcgBAQAAAAEKBgAA-gEAICQAAIACACAlAACAAgAguQGAAAAAAcABgAAAAAHBAQEAAAABwgEBAAAAAcMBAQAAAAHEAYAAAAABxQGAAAAAAQoGAAD9AQAgJAAA_wEAICUAAP8BACC5AYAAAAABwAGAAAAAAcEBAQAAAAHCAQEAAAABwwEBAAAAAcQBgAAAAAHFAYAAAAABCwYAAP0BACAkAAD-AQAgJQAA_gEAILkBQAAAAAG6AUAAAAAFuwFAAAAABbwBQAAAAAG9AUAAAAABvgFAAAAAAb8BQAAAAAHAAUAA_AEAIQsGAAD6AQAgJAAA-wEAICUAAPsBACC5AUAAAAABugFAAAAABLsBQAAAAAS8AUAAAAABvQFAAAAAAb4BQAAAAAG_AUAAAAABwAFAAPkBACELBgAA-gEAICQAAPsBACAlAAD7AQAguQFAAAAAAboBQAAAAAS7AUAAAAAEvAFAAAAAAb0BQAAAAAG-AUAAAAABvwFAAAAAAcABQAD5AQAhCLkBAgAAAAG6AQIAAAAEuwECAAAABLwBAgAAAAG9AQIAAAABvgECAAAAAb8BAgAAAAHAAQIA-gEAIQi5AUAAAAABugFAAAAABLsBQAAAAAS8AUAAAAABvQFAAAAAAb4BQAAAAAG_AUAAAAABwAFAAPsBACELBgAA_QEAICQAAP4BACAlAAD-AQAguQFAAAAAAboBQAAAAAW7AUAAAAAFvAFAAAAAAb0BQAAAAAG-AUAAAAABvwFAAAAAAcABQAD8AQAhCLkBAgAAAAG6AQIAAAAFuwECAAAABbwBAgAAAAG9AQIAAAABvgECAAAAAb8BAgAAAAHAAQIA_QEAIQi5AUAAAAABugFAAAAABbsBQAAAAAW8AUAAAAABvQFAAAAAAb4BQAAAAAG_AUAAAAABwAFAAP4BACEHuQGAAAAAAcABgAAAAAHBAQEAAAABwgEBAAAAAcMBAQAAAAHEAYAAAAABxQGAAAAAAQe5AYAAAAABwAGAAAAAAcEBAQAAAAHCAQEAAAABwwEBAAAAAcQBgAAAAAHFAYAAAAABDgYAAP0BACAkAACCAgAgJQAAggIAILkBAQAAAAG6AQEAAAAFuwEBAAAABbwBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAgQIAIcYBAQAAAAHHAQEAAAAByAEBAAAAAQu5AQEAAAABugEBAAAABbsBAQAAAAW8AQEAAAABvQEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAIICACHGAQEAAAABxwEBAAAAAcgBAQAAAAEHBgAA-gEAICQAAIQCACAlAACEAgAguQEAAACvAQK6AQAAAK8BCLsBAAAArwEIwAEAAIMCrwEiBLkBAAAArwECugEAAACvAQi7AQAAAK8BCMABAACEAq8BIg4GAAD6AQAgJAAAhgIAICUAAIYCACC5AQEAAAABugEBAAAABLsBAQAAAAS8AQEAAAABvQEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAIUCACHGAQEAAAABxwEBAAAAAcgBAQAAAAELuQEBAAAAAboBAQAAAAS7AQEAAAAEvAEBAAAAAb0BAQAAAAG-AQEAAAABvwEBAAAAAcABAQCGAgAhxgEBAAAAAccBAQAAAAHIAQEAAAABDagBAACHAgAwqQEAANgBABCqAQAAhwIAMKsBAQDyAQAhrwEAAIkCzgEitwFAAPgBACG4AUAA-AEAIckBAQDyAQAhygEBAPIBACHMAQAAiALMASLOAQAA9QEAIM8BAAD2AQAg0AFAAPcBACEHBgAA-gEAICQAAI0CACAlAACNAgAguQEAAADMAQK6AQAAAMwBCLsBAAAAzAEIwAEAAIwCzAEiBwYAAPoBACAkAACLAgAgJQAAiwIAILkBAAAAzgECugEAAADOAQi7AQAAAM4BCMABAACKAs4BIgcGAAD6AQAgJAAAiwIAICUAAIsCACC5AQAAAM4BAroBAAAAzgEIuwEAAADOAQjAAQAAigLOASIEuQEAAADOAQK6AQAAAM4BCLsBAAAAzgEIwAEAAIsCzgEiBwYAAPoBACAkAACNAgAgJQAAjQIAILkBAAAAzAECugEAAADMAQi7AQAAAMwBCMABAACMAswBIgS5AQAAAMwBAroBAAAAzAEIuwEAAADMAQjAAQAAjQLMASIKBwAA9QEAIKgBAACOAgAwqQEAAMIBABCqAQAAjgIAMKsBAQDyAQAhtwFAAPgBACHJAQEA8gEAIdEBAQDyAQAh0gEBAPIBACHTAUAA9wEAIQkCAgCQAgAhqAEAAI8CADCpAQAArAEAEKoBAACPAgAwqwEBAPIBACG3AUAA-AEAIcwBAQDyAQAhzgEAAPUBACDUAQEA8gEAIQ0GAAD6AQAgIgAAkgIAICMAAPoBACAkAAD6AQAgJQAA-gEAILkBAgAAAAG6AQIAAAAEuwECAAAABLwBAgAAAAG9AQIAAAABvgECAAAAAb8BAgAAAAHAAQIAkQIAIQ0GAAD6AQAgIgAAkgIAICMAAPoBACAkAAD6AQAgJQAA-gEAILkBAgAAAAG6AQIAAAAEuwECAAAABLwBAgAAAAG9AQIAAAABvgECAAAAAb8BAgAAAAHAAQIAkQIAIQi5AQgAAAABugEIAAAABLsBCAAAAAS8AQgAAAABvQEIAAAAAb4BCAAAAAG_AQgAAAABwAEIAJICACEOqAEAAJMCADCpAQAAlgEAEKoBAACTAgAwqwEBAPIBACGvAQAAlALXASK0AQEA9AEAIbUBQAD3AQAhtgFAAPcBACG3AUAA-AEAIbgBQAD4AQAhyQEBAPIBACHVAQEA8gEAIdcBAgCQAgAh2AECAJUCACEHBgAA-gEAICQAAJkCACAlAACZAgAguQEAAADXAQK6AQAAANcBCLsBAAAA1wEIwAEAAJgC1wEiDQYAAP0BACAiAACXAgAgIwAA_QEAICQAAP0BACAlAAD9AQAguQECAAAAAboBAgAAAAW7AQIAAAAFvAECAAAAAb0BAgAAAAG-AQIAAAABvwECAAAAAcABAgCWAgAhDQYAAP0BACAiAACXAgAgIwAA_QEAICQAAP0BACAlAAD9AQAguQECAAAAAboBAgAAAAW7AQIAAAAFvAECAAAAAb0BAgAAAAG-AQIAAAABvwECAAAAAcABAgCWAgAhCLkBCAAAAAG6AQgAAAAFuwEIAAAABbwBCAAAAAG9AQgAAAABvgEIAAAAAb8BCAAAAAHAAQgAlwIAIQcGAAD6AQAgJAAAmQIAICUAAJkCACC5AQAAANcBAroBAAAA1wEIuwEAAADXAQjAAQAAmALXASIEuQEAAADXAQK6AQAAANcBCLsBAAAA1wEIwAEAAJkC1wEiCKgBAACaAgAwqQEAAIABABCqAQAAmgIAMKsBAQDyAQAhtwFAAPgBACHOAQAA9QEAINkBAQDyAQAh2gECAJACACEMqAEAAJsCADCpAQAAagAQqgEAAJsCADCrAQEA8gEAIbEBAQD0AQAhtwFAAPgBACG4AUAA-AEAIckBAQDyAQAhzgEAAPUBACDZAQEA8gEAIdwBAACcAtwBIt0BAgCQAgAhBwYAAPoBACAkAACeAgAgJQAAngIAILkBAAAA3AECugEAAADcAQi7AQAAANwBCMABAACdAtwBIgcGAAD6AQAgJAAAngIAICUAAJ4CACC5AQAAANwBAroBAAAA3AEIuwEAAADcAQjAAQAAnQLcASIEuQEAAADcAQK6AQAAANwBCLsBAAAA3AEIwAEAAJ4C3AEiDagBAACfAgAwqQEAAFQAEKoBAACfAgAwqwEBAPIBACGxAQEA9AEAIbcBQAD4AQAhuAFAAPgBACHJAQEA8gEAId4BAQDyAQAh3wEBAPIBACHgAQIAkAIAIeEBAgCQAgAh4gEBAPIBACEOAwAApQIAIKgBAACgAgAwqQEAABQAEKoBAACgAgAwqwEBAKECACGxAQEAowIAIbcBQACkAgAhuAFAAKQCACHJAQEAoQIAId4BAQChAgAh3wEBAKECACHgAQIAogIAIeEBAgCiAgAh4gEBAKECACELuQEBAAAAAboBAQAAAAS7AQEAAAAEvAEBAAAAAb0BAQAAAAG-AQEAAAABvwEBAAAAAcABAQCGAgAhxgEBAAAAAccBAQAAAAHIAQEAAAABCLkBAgAAAAG6AQIAAAAEuwECAAAABLwBAgAAAAG9AQIAAAABvgECAAAAAb8BAgAAAAHAAQIA-gEAIQu5AQEAAAABugEBAAAABbsBAQAAAAW8AQEAAAABvQEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAIICACHGAQEAAAABxwEBAAAAAcgBAQAAAAEIuQFAAAAAAboBQAAAAAS7AUAAAAAEvAFAAAAAAb0BQAAAAAG-AUAAAAABvwFAAAAAAcABQAD7AQAhFwcAAKwCACAIAACtAgAgCgAArgIAIAsAAK8CACAOAACwAgAgDwAAsQIAIKgBAACqAgAwqQEAACkAEKoBAACqAgAwqwEBAKECACGwAQEAoQIAIbEBAQCjAgAhtwFAAKQCACG4AUAApAIAIeMBAQCjAgAh5AEgAKsCACHlAQEAowIAIeYBAQCjAgAh5wEBAKMCACHoAQEAowIAIekBAgCiAgAh8wEAACkAIPQBAAApACAPqAEAAKYCADCpAQAAPAAQqgEAAKYCADCrAQEA8gEAIbABAQDyAQAhsQEBAPQBACG3AUAA-AEAIbgBQAD4AQAh4wEBAPQBACHkASAApwIAIeUBAQD0AQAh5gEBAPQBACHnAQEA9AEAIegBAQD0AQAh6QECAJACACEFBgAA-gEAICQAAKkCACAlAACpAgAguQEgAAAAAcABIACoAgAhBQYAAPoBACAkAACpAgAgJQAAqQIAILkBIAAAAAHAASAAqAIAIQK5ASAAAAABwAEgAKkCACEVBwAArAIAIAgAAK0CACAKAACuAgAgCwAArwIAIA4AALACACAPAACxAgAgqAEAAKoCADCpAQAAKQAQqgEAAKoCADCrAQEAoQIAIbABAQChAgAhsQEBAKMCACG3AUAApAIAIbgBQACkAgAh4wEBAKMCACHkASAAqwIAIeUBAQCjAgAh5gEBAKMCACHnAQEAowIAIegBAQCjAgAh6QECAKICACECuQEgAAAAAcABIACpAgAhA-oBAAADACDrAQAAAwAg7AEAAAMAIAPqAQAADAAg6wEAAAwAIOwBAAAMACAD6gEAABAAIOsBAAAQACDsAQAAEAAgEAMAAKUCACCoAQAAoAIAMKkBAAAUABCqAQAAoAIAMKsBAQChAgAhsQEBAKMCACG3AUAApAIAIbgBQACkAgAhyQEBAKECACHeAQEAoQIAId8BAQChAgAh4AECAKICACHhAQIAogIAIeIBAQChAgAh8wEAABQAIPQBAAAUACAD6gEAABYAIOsBAAAWACDsAQAAFgAgA-oBAAAfACDrAQAAHwAg7AEAAB8AIAsDAAClAgAgBwAAswIAIKgBAACyAgAwqQEAAB8AEKoBAACyAgAwqwEBAKECACG3AUAApAIAIckBAQChAgAh0QEBAKECACHSAQEAoQIAIdMBQAC0AgAhB7kBgAAAAAHAAYAAAAABwQEBAAAAAcIBAQAAAAHDAQEAAAABxAGAAAAAAcUBgAAAAAEIuQFAAAAAAboBQAAAAAW7AUAAAAAFvAFAAAAAAb0BQAAAAAG-AUAAAAABvwFAAAAAAcABQAD-AQAhAgICAAAAAdQBAQAAAAEKAgIAogIAIQwAALcCACCoAQAAtgIAMKkBAAAaABCqAQAAtgIAMKsBAQChAgAhtwFAAKQCACHMAQEAoQIAIc4BAACzAgAg1AEBAKECACESAwAApQIAIA0AALwCACCoAQAAuQIAMKkBAAAWABCqAQAAuQIAMKsBAQChAgAhrwEAALoC1wEitAEBAKMCACG1AUAAtAIAIbYBQAC0AgAhtwFAAKQCACG4AUAApAIAIckBAQChAgAh1QEBAKECACHXAQIAogIAIdgBAgC7AgAh8wEAABYAIPQBAAAWACACyQEBAAAAAdUBAQAAAAEQAwAApQIAIA0AALwCACCoAQAAuQIAMKkBAAAWABCqAQAAuQIAMKsBAQChAgAhrwEAALoC1wEitAEBAKMCACG1AUAAtAIAIbYBQAC0AgAhtwFAAKQCACG4AUAApAIAIckBAQChAgAh1QEBAKECACHXAQIAogIAIdgBAgC7AgAhBLkBAAAA1wECugEAAADXAQi7AQAAANcBCMABAACZAtcBIgi5AQIAAAABugECAAAABbsBAgAAAAW8AQIAAAABvQECAAAAAb4BAgAAAAG_AQIAAAABwAECAP0BACED6gEAABoAIOsBAAAaACDsAQAAGgAgEQkAAKUCACCoAQAAvQIAMKkBAAAQABCqAQAAvQIAMKsBAQChAgAhrAEBAKECACGtAQEAoQIAIa8BAAC-Aq8BIrABAQChAgAhsQEBAKMCACGyAQAAswIAILMBAAC_AgAgtAEBAKMCACG1AUAAtAIAIbYBQAC0AgAhtwFAAKQCACG4AUAApAIAIQS5AQAAAK8BAroBAAAArwEIuwEAAACvAQjAAQAAhAKvASIHuQGAAAAAAcABgAAAAAHBAQEAAAABwgEBAAAAAcMBAQAAAAHEAYAAAAABxQGAAAAAAQLJAQEAAAABygEBAAAAAQ4DAAClAgAgqAEAAMECADCpAQAADAAQqgEAAMECADCrAQEAoQIAIa8BAADDAs4BIrcBQACkAgAhuAFAAKQCACHJAQEAoQIAIcoBAQChAgAhzAEAAMICzAEizgEAALMCACDPAQAAvwIAINABQAC0AgAhBLkBAAAAzAECugEAAADMAQi7AQAAAMwBCMABAACNAswBIgS5AQAAAM4BAroBAAAAzgEIuwEAAADOAQjAAQAAiwLOASIC2QEBAAAAAdoBAgAAAAEJBAAAxgIAIKgBAADFAgAwqQEAAAcAEKoBAADFAgAwqwEBAKECACG3AUAApAIAIc4BAACzAgAg2QEBAKECACHaAQIAogIAIRADAAClAgAgBQAAywIAIKgBAADJAgAwqQEAAAMAEKoBAADJAgAwqwEBAKECACGxAQEAowIAIbcBQACkAgAhuAFAAKQCACHJAQEAoQIAIc4BAACzAgAg2QEBAKECACHcAQAAygLcASLdAQIAogIAIfMBAAADACD0AQAAAwAgAskBAQAAAAHZAQEAAAABAskBAQAAAAHdAQIAAAABDgMAAKUCACAFAADLAgAgqAEAAMkCADCpAQAAAwAQqgEAAMkCADCrAQEAoQIAIbEBAQCjAgAhtwFAAKQCACG4AUAApAIAIckBAQChAgAhzgEAALMCACDZAQEAoQIAIdwBAADKAtwBIt0BAgCiAgAhBLkBAAAA3AECugEAAADcAQi7AQAAANwBCMABAACeAtwBIgPqAQAABwAg6wEAAAcAIOwBAAAHACAAAAAAAfgBAQAAAAEB-AEAAACvAQIB-AEBAAAAAQH4AUAAAAABAfgBQAAAAAEFHAAArgQAIB0AALEEACD1AQAArwQAIPYBAACwBAAg-wEAAAEAIAMcAACuBAAg9QEAAK8EACD7AQAAAQAgAAAAAfgBAAAAzAECAfgBAAAAzgECBRwAAKkEACAdAACsBAAg9QEAAKoEACD2AQAAqwQAIPsBAAABACADHAAAqQQAIPUBAACqBAAg-wEAAAEAIAAAAAUcAACkBAAgHQAApwQAIPUBAAClBAAg9gEAAKYEACD7AQAAAQAgAxwAAKQEACD1AQAApQQAIPsBAAABACAAAAAAAAX4AQIAAAAB_gECAAAAAf8BAgAAAAGAAgIAAAABgQICAAAAAQUcAACfBAAgHQAAogQAIPUBAACgBAAg9gEAAKEEACD7AQAAGAAgAxwAAJ8EACD1AQAAoAQAIPsBAAAYACAAAAAAAAH4AQAAANcBAgX4AQIAAAAB_gECAAAAAf8BAgAAAAGAAgIAAAABgQICAAAAAQUcAACZBAAgHQAAnQQAIPUBAACaBAAg9gEAAJwEACD7AQAAAQAgCxwAAPQCADAdAAD5AgAw9QEAAPUCADD2AQAA9gIAMPcBAAD3AgAg-AEAAPgCADD5AQAA-AIAMPoBAAD4AgAw-wEAAPgCADD8AQAA-gIAMP0BAAD7AgAwBQICAAAAAasBAQAAAAG3AUAAAAABzAEBAAAAAc4BgAAAAAECAAAAHAAgHAAA_wIAIAMAAAAcACAcAAD_AgAgHQAA_gIAIAEVAACbBAAwCwICAKICACEMAAC3AgAgqAEAALYCADCpAQAAGgAQqgEAALYCADCrAQEAAAABtwFAAKQCACHMAQEAoQIAIc4BAACzAgAg1AEBAKECACHtAQAAtQIAIAIAAAAcACAVAAD-AgAgAgAAAPwCACAVAAD9AgAgCQICAKICACGoAQAA-wIAMKkBAAD8AgAQqgEAAPsCADCrAQEAoQIAIbcBQACkAgAhzAEBAKECACHOAQAAswIAINQBAQChAgAhCQICAKICACGoAQAA-wIAMKkBAAD8AgAQqgEAAPsCADCrAQEAoQIAIbcBQACkAgAhzAEBAKECACHOAQAAswIAINQBAQChAgAhBQICAOgCACGrAQEA0AIAIbcBQADUAgAhzAEBANACACHOAYAAAAABBQICAOgCACGrAQEA0AIAIbcBQADUAgAhzAEBANACACHOAYAAAAABBQICAAAAAasBAQAAAAG3AUAAAAABzAEBAAAAAc4BgAAAAAEDHAAAmQQAIPUBAACaBAAg-wEAAAEAIAQcAAD0AgAw9QEAAPUCADD3AQAA9wIAIPsBAAD4AgAwAAAAAAAFHAAAlAQAIB0AAJcEACD1AQAAlQQAIPYBAACWBAAg-wEAAAUAIAMcAACUBAAg9QEAAJUEACD7AQAABQAgAAAAAAAB-AEAAADcAQIFHAAAjgQAIB0AAJIEACD1AQAAjwQAIPYBAACRBAAg-wEAAAEAIAscAACRAwAwHQAAlgMAMPUBAACSAwAw9gEAAJMDADD3AQAAlAMAIPgBAACVAwAw-QEAAJUDADD6AQAAlQMAMPsBAACVAwAw_AEAAJcDADD9AQAAmAMAMASrAQEAAAABtwFAAAAAAc4BgAAAAAHaAQIAAAABAgAAAAkAIBwAAJwDACADAAAACQAgHAAAnAMAIB0AAJsDACABFQAAkAQAMAoEAADGAgAgqAEAAMUCADCpAQAABwAQqgEAAMUCADCrAQEAAAABtwFAAKQCACHOAQAAswIAINkBAQChAgAh2gECAKICACHwAQAAxAIAIAIAAAAJACAVAACbAwAgAgAAAJkDACAVAACaAwAgCKgBAACYAwAwqQEAAJkDABCqAQAAmAMAMKsBAQChAgAhtwFAAKQCACHOAQAAswIAINkBAQChAgAh2gECAKICACEIqAEAAJgDADCpAQAAmQMAEKoBAACYAwAwqwEBAKECACG3AUAApAIAIc4BAACzAgAg2QEBAKECACHaAQIAogIAIQSrAQEA0AIAIbcBQADUAgAhzgGAAAAAAdoBAgDoAgAhBKsBAQDQAgAhtwFAANQCACHOAYAAAAAB2gECAOgCACEEqwEBAAAAAbcBQAAAAAHOAYAAAAAB2gECAAAAAQMcAACOBAAg9QEAAI8EACD7AQAAAQAgBBwAAJEDADD1AQAAkgMAMPcBAACUAwAg-wEAAJUDADAAAAAAAAUcAACJBAAgHQAAjAQAIPUBAACKBAAg9gEAAIsEACD7AQAAAQAgAxwAAIkEACD1AQAAigQAIPsBAAABACAMBwAA-gMAIAgAAPsDACAKAAD8AwAgCwAA_QMAIA4AAP4DACAPAAD_AwAgsQEAAMwCACDjAQAAzAIAIOUBAADMAgAg5gEAAMwCACDnAQAAzAIAIOgBAADMAgAgAAAAAAAB-AEgAAAAAQscAADoAwAwHQAA7QMAMPUBAADpAwAw9gEAAOoDADD3AQAA6wMAIPgBAADsAwAw-QEAAOwDADD6AQAA7AMAMPsBAADsAwAw_AEAAO4DADD9AQAA7wMAMAscAADcAwAwHQAA4QMAMPUBAADdAwAw9gEAAN4DADD3AQAA3wMAIPgBAADgAwAw-QEAAOADADD6AQAA4AMAMPsBAADgAwAw_AEAAOIDADD9AQAA4wMAMAscAADQAwAwHQAA1QMAMPUBAADRAwAw9gEAANIDADD3AQAA0wMAIPgBAADUAwAw-QEAANQDADD6AQAA1AMAMPsBAADUAwAw_AEAANYDADD9AQAA1wMAMAccAADLAwAgHQAAzgMAIPUBAADMAwAg9gEAAM0DACD5AQAAFAAg-gEAABQAIPsBAAA_ACALHAAAvwMAMB0AAMQDADD1AQAAwAMAMPYBAADBAwAw9wEAAMIDACD4AQAAwwMAMPkBAADDAwAw-gEAAMMDADD7AQAAwwMAMPwBAADFAwAw_QEAAMYDADALHAAAswMAMB0AALgDADD1AQAAtAMAMPYBAAC1AwAw9wEAALYDACD4AQAAtwMAMPkBAAC3AwAw-gEAALcDADD7AQAAtwMAMPwBAAC5AwAw_QEAALoDADAGB4AAAAABqwEBAAAAAbcBQAAAAAHRAQEAAAAB0gEBAAAAAdMBQAAAAAECAAAAIQAgHAAAvgMAIAMAAAAhACAcAAC-AwAgHQAAvQMAIAEVAACIBAAwCwMAAKUCACAHAACzAgAgqAEAALICADCpAQAAHwAQqgEAALICADCrAQEAAAABtwFAAKQCACHJAQEAoQIAIdEBAQChAgAh0gEBAKECACHTAUAAtAIAIQIAAAAhACAVAAC9AwAgAgAAALsDACAVAAC8AwAgCgcAALMCACCoAQAAugMAMKkBAAC7AwAQqgEAALoDADCrAQEAoQIAIbcBQACkAgAhyQEBAKECACHRAQEAoQIAIdIBAQChAgAh0wFAALQCACEKBwAAswIAIKgBAAC6AwAwqQEAALsDABCqAQAAugMAMKsBAQChAgAhtwFAAKQCACHJAQEAoQIAIdEBAQChAgAh0gEBAKECACHTAUAAtAIAIQYHgAAAAAGrAQEA0AIAIbcBQADUAgAh0QEBANACACHSAQEA0AIAIdMBQADTAgAhBgeAAAAAAasBAQDQAgAhtwFAANQCACHRAQEA0AIAIdIBAQDQAgAh0wFAANMCACEGB4AAAAABqwEBAAAAAbcBQAAAAAHRAQEAAAAB0gEBAAAAAdMBQAAAAAELDQAAgQMAIKsBAQAAAAGvAQAAANcBArQBAQAAAAG1AUAAAAABtgFAAAAAAbcBQAAAAAG4AUAAAAAB1QEBAAAAAdcBAgAAAAHYAQIAAAABAgAAABgAIBwAAMoDACADAAAAGAAgHAAAygMAIB0AAMkDACABFQAAhwQAMBEDAAClAgAgDQAAvAIAIKgBAAC5AgAwqQEAABYAEKoBAAC5AgAwqwEBAAAAAa8BAAC6AtcBIrQBAQCjAgAhtQFAALQCACG2AUAAtAIAIbcBQACkAgAhuAFAAKQCACHJAQEAoQIAIdUBAQChAgAh1wECAKICACHYAQIAuwIAIe4BAAC4AgAgAgAAABgAIBUAAMkDACACAAAAxwMAIBUAAMgDACAOqAEAAMYDADCpAQAAxwMAEKoBAADGAwAwqwEBAKECACGvAQAAugLXASK0AQEAowIAIbUBQAC0AgAhtgFAALQCACG3AUAApAIAIbgBQACkAgAhyQEBAKECACHVAQEAoQIAIdcBAgCiAgAh2AECALsCACEOqAEAAMYDADCpAQAAxwMAEKoBAADGAwAwqwEBAKECACGvAQAAugLXASK0AQEAowIAIbUBQAC0AgAhtgFAALQCACG3AUAApAIAIbgBQACkAgAhyQEBAKECACHVAQEAoQIAIdcBAgCiAgAh2AECALsCACEKqwEBANACACGvAQAA8ALXASK0AQEA0gIAIbUBQADTAgAhtgFAANMCACG3AUAA1AIAIbgBQADUAgAh1QEBANACACHXAQIA6AIAIdgBAgDxAgAhCw0AAPMCACCrAQEA0AIAIa8BAADwAtcBIrQBAQDSAgAhtQFAANMCACG2AUAA0wIAIbcBQADUAgAhuAFAANQCACHVAQEA0AIAIdcBAgDoAgAh2AECAPECACELDQAAgQMAIKsBAQAAAAGvAQAAANcBArQBAQAAAAG1AUAAAAABtgFAAAAAAbcBQAAAAAG4AUAAAAAB1QEBAAAAAdcBAgAAAAHYAQIAAAABCasBAQAAAAGxAQEAAAABtwFAAAAAAbgBQAAAAAHeAQEAAAAB3wEBAAAAAeABAgAAAAHhAQIAAAAB4gEBAAAAAQIAAAA_ACAcAADLAwAgAwAAABQAIBwAAMsDACAdAADPAwAgCwAAABQAIBUAAM8DACCrAQEA0AIAIbEBAQDSAgAhtwFAANQCACG4AUAA1AIAId4BAQDQAgAh3wEBANACACHgAQIA6AIAIeEBAgDoAgAh4gEBANACACEJqwEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHeAQEA0AIAId8BAQDQAgAh4AECAOgCACHhAQIA6AIAIeIBAQDQAgAhDKsBAQAAAAGtAQEAAAABrwEAAACvAQKwAQEAAAABsQEBAAAAAbIBgAAAAAGzAYAAAAABtAEBAAAAAbUBQAAAAAG2AUAAAAABtwFAAAAAAbgBQAAAAAECAAAAEgAgHAAA2wMAIAMAAAASACAcAADbAwAgHQAA2gMAIAEVAACGBAAwEQkAAKUCACCoAQAAvQIAMKkBAAAQABCqAQAAvQIAMKsBAQAAAAGsAQEAoQIAIa0BAQChAgAhrwEAAL4CrwEisAEBAKECACGxAQEAowIAIbIBAACzAgAgswEAAL8CACC0AQEAowIAIbUBQAC0AgAhtgFAALQCACG3AUAApAIAIbgBQACkAgAhAgAAABIAIBUAANoDACACAAAA2AMAIBUAANkDACAQqAEAANcDADCpAQAA2AMAEKoBAADXAwAwqwEBAKECACGsAQEAoQIAIa0BAQChAgAhrwEAAL4CrwEisAEBAKECACGxAQEAowIAIbIBAACzAgAgswEAAL8CACC0AQEAowIAIbUBQAC0AgAhtgFAALQCACG3AUAApAIAIbgBQACkAgAhEKgBAADXAwAwqQEAANgDABCqAQAA1wMAMKsBAQChAgAhrAEBAKECACGtAQEAoQIAIa8BAAC-Aq8BIrABAQChAgAhsQEBAKMCACGyAQAAswIAILMBAAC_AgAgtAEBAKMCACG1AUAAtAIAIbYBQAC0AgAhtwFAAKQCACG4AUAApAIAIQyrAQEA0AIAIa0BAQDQAgAhrwEAANECrwEisAEBANACACGxAQEA0gIAIbIBgAAAAAGzAYAAAAABtAEBANICACG1AUAA0wIAIbYBQADTAgAhtwFAANQCACG4AUAA1AIAIQyrAQEA0AIAIa0BAQDQAgAhrwEAANECrwEisAEBANACACGxAQEA0gIAIbIBgAAAAAGzAYAAAAABtAEBANICACG1AUAA0wIAIbYBQADTAgAhtwFAANQCACG4AUAA1AIAIQyrAQEAAAABrQEBAAAAAa8BAAAArwECsAEBAAAAAbEBAQAAAAGyAYAAAAABswGAAAAAAbQBAQAAAAG1AUAAAAABtgFAAAAAAbcBQAAAAAG4AUAAAAABCasBAQAAAAGvAQAAAM4BArcBQAAAAAG4AUAAAAABygEBAAAAAcwBAAAAzAECzgGAAAAAAc8BgAAAAAHQAUAAAAABAgAAAA4AIBwAAOcDACADAAAADgAgHAAA5wMAIB0AAOYDACABFQAAhQQAMA8DAAClAgAgqAEAAMECADCpAQAADAAQqgEAAMECADCrAQEAAAABrwEAAMMCzgEitwFAAKQCACG4AUAApAIAIckBAQChAgAhygEBAKECACHMAQAAwgLMASLOAQAAswIAIM8BAAC_AgAg0AFAALQCACHvAQAAwAIAIAIAAAAOACAVAADmAwAgAgAAAOQDACAVAADlAwAgDagBAADjAwAwqQEAAOQDABCqAQAA4wMAMKsBAQChAgAhrwEAAMMCzgEitwFAAKQCACG4AUAApAIAIckBAQChAgAhygEBAKECACHMAQAAwgLMASLOAQAAswIAIM8BAAC_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-AMAIKsBAQAAAAGwAQEAAAABsQEBAAAAAbcBQAAAAAG4AUAAAAAB4wEBAAAAAeQBIAAAAAHlAQEAAAAB5gEBAAAAAecBAQAAAAHoAQEAAAAB6QECAAAAAQIAAAABACAcAACkBAAgAwAAACkAIBwAAKQEACAdAACoBAAgEwAAACkAIAcAAK0DACAIAACuAwAgCgAArwMAIAsAALADACAOAACxAwAgFQAAqAQAIKsBAQDQAgAhsAEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHjAQEA0gIAIeQBIACsAwAh5QEBANICACHmAQEA0gIAIecBAQDSAgAh6AEBANICACHpAQIA6AIAIREHAACtAwAgCAAArgMAIAoAAK8DACALAACwAwAgDgAAsQMAIKsBAQDQAgAhsAEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHjAQEA0gIAIeQBIACsAwAh5QEBANICACHmAQEA0gIAIecBAQDSAgAh6AEBANICACHpAQIA6AIAIREHAAD0AwAgCgAA9gMAIAsAAPcDACAOAAD4AwAgDwAA-QMAIKsBAQAAAAGwAQEAAAABsQEBAAAAAbcBQAAAAAG4AUAAAAAB4wEBAAAAAeQBIAAAAAHlAQEAAAAB5gEBAAAAAecBAQAAAAHoAQEAAAAB6QECAAAAAQIAAAABACAcAACpBAAgAwAAACkAIBwAAKkEACAdAACtBAAgEwAAACkAIAcAAK0DACAKAACvAwAgCwAAsAMAIA4AALEDACAPAACyAwAgFQAArQQAIKsBAQDQAgAhsAEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHjAQEA0gIAIeQBIACsAwAh5QEBANICACHmAQEA0gIAIecBAQDSAgAh6AEBANICACHpAQIA6AIAIREHAACtAwAgCgAArwMAIAsAALADACAOAACxAwAgDwAAsgMAIKsBAQDQAgAhsAEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHjAQEA0gIAIeQBIACsAwAh5QEBANICACHmAQEA0gIAIecBAQDSAgAh6AEBANICACHpAQIA6AIAIREHAAD0AwAgCAAA9QMAIAsAAPcDACAOAAD4AwAgDwAA-QMAIKsBAQAAAAGwAQEAAAABsQEBAAAAAbcBQAAAAAG4AUAAAAAB4wEBAAAAAeQBIAAAAAHlAQEAAAAB5gEBAAAAAecBAQAAAAHoAQEAAAAB6QECAAAAAQIAAAABACAcAACuBAAgAwAAACkAIBwAAK4EACAdAACyBAAgEwAAACkAIAcAAK0DACAIAACuAwAgCwAAsAMAIA4AALEDACAPAACyAwAgFQAAsgQAIKsBAQDQAgAhsAEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHjAQEA0gIAIeQBIACsAwAh5QEBANICACHmAQEA0gIAIecBAQDSAgAh6AEBANICACHpAQIA6AIAIREHAACtAwAgCAAArgMAIAsAALADACAOAACxAwAgDwAAsgMAIKsBAQDQAgAhsAEBANACACGxAQEA0gIAIbcBQADUAgAhuAFAANQCACHjAQEA0gIAIeQBIACsAwAh5QEBANICACHmAQEA0gIAIecBAQDSAgAh6AEBANICACHpAQIA6AIAIQcGAAwHBgIIDwUKEwYLFQcOGQgPIgsDAwABBQoDBgAEAQQAAgEFCwABAwABAQkAAQEDAAEDAwABBgAKDR0JAQwACAENHgABAwABBQcjAAgkAAolAA4mAA8nAAAAAAUGABEiABIjABMkABQlABUAAAAAAAUGABEiABIjABMkABQlABUBAwABAQMAAQUGABoiABsjABwkAB0lAB4AAAAAAAUGABoiABsjABwkAB0lAB4BAwABAQMAAQUGACMiACQjACUkACYlACcAAAAAAAUGACMiACQjACUkACYlACcBBAACAQQAAgUGACwiAC0jAC4kAC8lADAAAAAAAAUGACwiAC0jAC4kAC8lADABAwABAQMAAQUGADUiADYjADckADglADkAAAAAAAUGADUiADYjADckADglADkBDAAIAQwACAUGAD4iAD8jAEAkAEElAEIAAAAAAAUGAD4iAD8jAEAkAEElAEIBAwABAQMAAQMGAEckAEglAEkAAAADBgBHJABIJQBJAQMAAQEDAAEDBgBOJABPJQBQAAAAAwYATiQATyUAUAEJAAEBCQABAwYAVSQAViUAVwAAAAMGAFUkAFYlAFcQAgERKAESKwETLAEULQEWLwEXMQ0YMg4ZNAEaNg0bNw8eOAEfOQEgOg0mPRAnPhYoQAcpQQcqQwcrRAcsRQctRwcuSQ0vShcwTAcxTg0yTxgzUAc0UQc1Ug02VRk3Vh84VwI5WAI6WQI7WgI8WwI9XQI-Xw0_YCBAYgJBZA1CZSFDZgJEZwJFaA1GayJHbChIbQNJbgNKbwNLcANMcQNNcwNOdQ1PdilQeANReg1SeypTfANUfQNVfg1WgQErV4IBMViDAQhZhAEIWoUBCFuGAQhchwEIXYkBCF6LAQ1fjAEyYI4BCGGQAQ1ikQEzY5IBCGSTAQhllAENZpcBNGeYATpomQEJaZoBCWqbAQlrnAEJbJ0BCW2fAQluoQENb6IBO3CkAQlxpgENcqcBPHOoAQl0qQEJdaoBDXatAT13rgFDeK8BC3mwAQt6sQELe7IBC3yzAQt9tQELfrcBDX-4AUSAAboBC4EBvAENggG9AUWDAb4BC4QBvwELhQHAAQ2GAcMBRocBxAFKiAHFAQWJAcYBBYoBxwEFiwHIAQWMAckBBY0BywEFjgHNAQ2PAc4BS5AB0AEFkQHSAQ2SAdMBTJMB1AEFlAHVAQWVAdYBDZYB2QFNlwHaAVGYAdsBBpkB3AEGmgHdAQabAd4BBpwB3wEGnQHhAQaeAeMBDZ8B5AFSoAHmAQahAegBDaIB6QFTowHqAQakAesBBqUB7AENpgHvAVSnAfABWA"
@@ -10615,8 +10798,8 @@ var init_prismaNamespace = __esm(() => {
10615
10798
  Decimal2 = runtime18.Decimal;
10616
10799
  getExtensionContext = runtime18.Extensions.getExtensionContext;
10617
10800
  prismaVersion = {
10618
- client: "7.8.0",
10619
- engine: "3c6e192761c0362d496ed980de936e2f3cebcd3a"
10801
+ client: "7.10.0",
10802
+ engine: "0edf323efd1d98336f3f0a68684b56f689b900d3"
10620
10803
  };
10621
10804
  NullTypes2 = {
10622
10805
  DbNull: runtime18.NullTypes.DbNull,
@@ -12970,7 +13153,7 @@ var init_sse_heartbeat = __esm(() => {
12970
13153
  });
12971
13154
 
12972
13155
  // apps/server/src/lib/openrouter-models.ts
12973
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
13156
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
12974
13157
  import path20 from "path";
12975
13158
  import { z as z39 } from "zod";
12976
13159
  function getCacheFilePath() {
@@ -12979,10 +13162,10 @@ function getCacheFilePath() {
12979
13162
  function readCache() {
12980
13163
  try {
12981
13164
  const cachePath = getCacheFilePath();
12982
- if (!existsSync8(cachePath)) {
13165
+ if (!existsSync7(cachePath)) {
12983
13166
  return null;
12984
13167
  }
12985
- return modelsCacheSchema.parse(JSON.parse(readFileSync6(cachePath, "utf8")));
13168
+ return modelsCacheSchema.parse(JSON.parse(readFileSync7(cachePath, "utf8")));
12986
13169
  } catch {
12987
13170
  return null;
12988
13171
  }
@@ -13029,14 +13212,14 @@ function summarizeRawModel(raw3) {
13029
13212
  };
13030
13213
  }
13031
13214
  async function fetchModelsFromApi() {
13032
- const response = await fetch(openRouterModelsUrl, {
13215
+ const response = await networkFetch(openRouterModelsUrl, {
13033
13216
  signal: AbortSignal.timeout(fetchTimeoutMs)
13034
13217
  });
13035
13218
  if (!response.ok) {
13036
13219
  throw new Error(`OpenRouter models API returned HTTP ${response.status}.`);
13037
13220
  }
13038
- const payload = await response.json();
13039
- const models = (payload.data ?? []).map(summarizeRawModel).filter((model) => model !== null);
13221
+ const payload = z39.object({ data: z39.array(z39.unknown()) }).parse(await response.json());
13222
+ const models = payload.data.map(summarizeRawModel).filter((model) => model !== null);
13040
13223
  if (models.length === 0) {
13041
13224
  throw new Error("OpenRouter models API returned no models.");
13042
13225
  }
@@ -13097,6 +13280,7 @@ function toCapabilityPricing(pricing) {
13097
13280
  var logger5, openRouterModelsUrl = "https://openrouter.ai/api/v1/models", cacheTtlMs, fetchTimeoutMs = 15000, openRouterModelSummarySchema, modelsCacheSchema;
13098
13281
  var init_openrouter_models = __esm(() => {
13099
13282
  init_src();
13283
+ init_network_fetch();
13100
13284
  logger5 = createLogger("openrouter-models");
13101
13285
  cacheTtlMs = 24 * 60 * 60 * 1000;
13102
13286
  openRouterModelSummarySchema = z39.object({
@@ -13145,7 +13329,7 @@ function createIdleTimeoutFetch({
13145
13329
  }
13146
13330
  const idleTimeoutFetch = async (input, init) => {
13147
13331
  const controller = new AbortController;
13148
- const callerSignal = init?.signal ?? undefined;
13332
+ const callerSignal = init?.signal ?? (input instanceof Request ? input.signal : undefined);
13149
13333
  const forwardCallerAbort = () => controller.abort(callerSignal?.reason);
13150
13334
  if (callerSignal) {
13151
13335
  if (callerSignal.aborted) {
@@ -13169,13 +13353,16 @@ function createIdleTimeoutFetch({
13169
13353
  let response;
13170
13354
  try {
13171
13355
  response = await fetchImpl(input, { ...init, signal: controller.signal });
13356
+ } catch (error) {
13357
+ callerSignal?.removeEventListener("abort", forwardCallerAbort);
13358
+ throw controller.signal.aborted ? controller.signal.reason : error;
13172
13359
  } finally {
13173
13360
  if (headersTimer) {
13174
13361
  clearTimeout(headersTimer);
13175
13362
  }
13176
13363
  }
13177
13364
  const body = response.body;
13178
- if (idleTimeoutMs <= 0 || !body) {
13365
+ if (!body) {
13179
13366
  if (callerSignal) {
13180
13367
  callerSignal.removeEventListener("abort", forwardCallerAbort);
13181
13368
  }
@@ -13191,16 +13378,30 @@ function createIdleTimeoutFetch({
13191
13378
  callerSignal.removeEventListener("abort", forwardCallerAbort);
13192
13379
  }
13193
13380
  };
13381
+ const reader = body.getReader();
13194
13382
  let rearm = () => {};
13195
- const transform = new TransformStream({
13383
+ let onAbort = () => {};
13384
+ const cleanup = () => {
13385
+ stopIdleTimer();
13386
+ controller.signal.removeEventListener("abort", onAbort);
13387
+ };
13388
+ const stream = new ReadableStream({
13196
13389
  start(streamController) {
13390
+ onAbort = () => {
13391
+ cleanup();
13392
+ streamController.error(controller.signal.reason);
13393
+ reader.cancel(controller.signal.reason).catch(() => {});
13394
+ };
13395
+ controller.signal.addEventListener("abort", onAbort, { once: true });
13396
+ if (controller.signal.aborted) {
13397
+ onAbort();
13398
+ return;
13399
+ }
13197
13400
  const arm = () => {
13401
+ if (idleTimeoutMs <= 0)
13402
+ return;
13198
13403
  idleTimer = setTimeout(() => {
13199
13404
  const error = new HttpIdleTimeoutError(`Provider stream timed out: no bytes received for ${idleTimeoutMs}ms`);
13200
- stopIdleTimer();
13201
- try {
13202
- streamController.error(error);
13203
- } catch {}
13204
13405
  abortWithTimeout(error);
13205
13406
  }, idleTimeoutMs);
13206
13407
  };
@@ -13212,15 +13413,30 @@ function createIdleTimeoutFetch({
13212
13413
  arm();
13213
13414
  };
13214
13415
  },
13215
- transform(chunk, streamController) {
13216
- rearm();
13217
- streamController.enqueue(chunk);
13416
+ async pull(streamController) {
13417
+ try {
13418
+ const result = await reader.read();
13419
+ if (controller.signal.aborted)
13420
+ return;
13421
+ if (result.done) {
13422
+ cleanup();
13423
+ streamController.close();
13424
+ } else {
13425
+ rearm();
13426
+ streamController.enqueue(result.value);
13427
+ }
13428
+ } catch (error) {
13429
+ cleanup();
13430
+ streamController.error(error);
13431
+ }
13218
13432
  },
13219
- flush() {
13220
- stopIdleTimer();
13433
+ async cancel(reason) {
13434
+ cleanup();
13435
+ controller.abort(reason);
13436
+ await reader.cancel(reason);
13221
13437
  }
13222
13438
  });
13223
- return new Response(body.pipeThrough(transform), {
13439
+ return new Response(stream, {
13224
13440
  status: response.status,
13225
13441
  statusText: response.statusText,
13226
13442
  headers: response.headers
@@ -13438,9 +13654,7 @@ function resolveOpenAITransportModel({
13438
13654
  needsToolCallDiscipline: true,
13439
13655
  providerOptions: isOpenRouter ? getOpenRouterProviderOptions(configuredModel) : undefined,
13440
13656
  contextWindow: capabilities?.contextLength ?? getModelContextWindow(config6.provider, configuredModel),
13441
- missingCredentialHints: apiKey ? [] : isOpenCodeZen ? ["Set OPENCODE_API_KEY to call OpenCode Zen models."] : isOpenRouter ? ["Set OPENROUTER_API_KEY to call OpenRouter models."] : [
13442
- "Set LIGHTCODE_OPENAI_COMPATIBLE_API_KEY or OPENAI_API_KEY if your OpenAI-compatible endpoint requires authentication."
13443
- ],
13657
+ missingCredentialHints: apiKey ? [] : isOpenCodeZen ? ["Set OPENCODE_API_KEY to call OpenCode Zen models."] : isOpenRouter ? ["Set OPENROUTER_API_KEY to call OpenRouter models."] : [],
13444
13658
  maxCompletionTokens: capabilities?.maxCompletionTokens ?? null,
13445
13659
  supportsPromptCaching: isOpenRouter && isOpenRouterAnthropicFamilyModel(configuredModel),
13446
13660
  pricing: resolveCapabilityPricing(capabilities, isOpenRouter && isOpenRouterAnthropicFamilyModel(configuredModel) ? 0.1 : null),
@@ -13506,9 +13720,10 @@ function createConfigStatus({
13506
13720
  }
13507
13721
  var providerFetch, anthropicModelAliases, opencodeZenDefaultBaseUrl = "https://opencode.ai/zen/v1", openRouterDefaultBaseUrl = "https://openrouter.ai/api/v1";
13508
13722
  var init_provider_registry = __esm(() => {
13723
+ init_network_fetch();
13509
13724
  init_src2();
13510
13725
  init_idle_timeout_fetch();
13511
- providerFetch = createIdleTimeoutFetch(resolveIdleTimeoutsFromEnv());
13726
+ providerFetch = createIdleTimeoutFetch({ ...resolveIdleTimeoutsFromEnv(), fetchImpl: networkFetch });
13512
13727
  anthropicModelAliases = {
13513
13728
  haiku: "claude-haiku-4-5",
13514
13729
  sonnet: "claude-sonnet-4-6",
@@ -13968,13 +14183,11 @@ function formatAvailableSkills(skills) {
13968
14183
  if (skills.length === 0) {
13969
14184
  return "";
13970
14185
  }
13971
- const shown = skills.slice(0, maxListedSkills);
13972
- const lines = shown.map((skill) => `- ${skill.name}${skill.description ? `: ${skill.description}` : ""}`);
13973
- const more = skills.length > shown.length ? `
13974
- \u2026 and ${skills.length - shown.length} more` : "";
14186
+ const shown = skills;
14187
+ const lines = shown.map((skill) => `- ${skill.name}${skill.description ? `: ${skill.description.replace(/\s+/g, " ").slice(0, 300)}` : ""}`);
13975
14188
  return `Available skills (load by name with the skill tool):
13976
14189
  ${lines.join(`
13977
- `)}${more}`;
14190
+ `)}`;
13978
14191
  }
13979
14192
  function buildAvailableSkills(cwd) {
13980
14193
  try {
@@ -14166,7 +14379,7 @@ ${skills}` : "",
14166
14379
  ].join(`
14167
14380
  `);
14168
14381
  }
14169
- var logger7, projectInstructionNames, maxListedEntries = 40, maxListedSkills = 20, maxInstructionChars = 6000, maxNestedInstructionChars = 6000, maxNestedInstructionFileChars = 1600, maxBlockChars = 18000, instructionEpochSchema, instructionEpochStateSchema, gitSummaryCacheTtlMs = 5000, gitSummaryCache;
14382
+ var logger7, projectInstructionNames, maxListedEntries = 40, maxInstructionChars = 6000, maxNestedInstructionChars = 6000, maxNestedInstructionFileChars = 1600, maxBlockChars = 18000, instructionEpochSchema, instructionEpochStateSchema, gitSummaryCacheTtlMs = 5000, gitSummaryCache;
14170
14383
  var init_workspace_context = __esm(() => {
14171
14384
  init_runtime17();
14172
14385
  init_src2();
@@ -16247,7 +16460,7 @@ var init_extension_runtime = __esm(() => {
16247
16460
  });
16248
16461
 
16249
16462
  // apps/server/src/routes/diagnostics-routes.ts
16250
- import { existsSync as existsSync9, readdirSync as readdirSync4 } from "fs";
16463
+ import { existsSync as existsSync8, readdirSync as readdirSync4 } from "fs";
16251
16464
  import path22 from "path";
16252
16465
  import { Hono as Hono3 } from "hono";
16253
16466
  function combineStatuses(statuses) {
@@ -16388,8 +16601,8 @@ function checkWorkspace() {
16388
16601
  return {
16389
16602
  id: "workspace",
16390
16603
  label: "Workspace",
16391
- status: existsSync9(cwd) ? "ok" : "error",
16392
- summary: existsSync9(cwd) ? `Workspace is accessible: ${cwd}` : `Workspace is missing: ${cwd}`,
16604
+ status: existsSync8(cwd) ? "ok" : "error",
16605
+ summary: existsSync8(cwd) ? `Workspace is accessible: ${cwd}` : `Workspace is missing: ${cwd}`,
16393
16606
  details: []
16394
16607
  };
16395
16608
  }
@@ -16529,7 +16742,7 @@ async function buildConnectivityPayload() {
16529
16742
  httpsProxy: Boolean(Bun.env.HTTPS_PROXY ?? Bun.env.https_proxy),
16530
16743
  httpProxy: Boolean(Bun.env.HTTP_PROXY ?? Bun.env.http_proxy),
16531
16744
  noProxy: Boolean(Bun.env.NO_PROXY ?? Bun.env.no_proxy),
16532
- extraCaCerts: Boolean(Bun.env.NODE_EXTRA_CA_CERTS)
16745
+ extraCaCerts: Boolean(Bun.env.NODE_EXTRA_CA_CERTS || Bun.env.LIGHTCODE_CA_CERTS || Bun.env.SSL_CERT_FILE)
16533
16746
  };
16534
16747
  if (!baseUrl) {
16535
16748
  return {
@@ -16546,7 +16759,7 @@ async function buildConnectivityPayload() {
16546
16759
  const target = new URL("models", baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
16547
16760
  const startedAt = performance.now();
16548
16761
  try {
16549
- const response = await fetch(target, {
16762
+ const response = await networkFetch(target, {
16550
16763
  signal: AbortSignal.timeout(connectivityProbeTimeoutMs)
16551
16764
  });
16552
16765
  return {
@@ -16601,6 +16814,7 @@ async function buildLogsTailPayload(requestedLines) {
16601
16814
  }
16602
16815
  var connectivityProbeTimeoutMs = 1e4, maxLogTailLines = 1000, diagnosticsRoutes;
16603
16816
  var init_diagnostics_routes = __esm(() => {
16817
+ init_network_fetch();
16604
16818
  init_src2();
16605
16819
  init_src();
16606
16820
  init_chat_store();
@@ -16689,7 +16903,7 @@ var init_root_routes = __esm(() => {
16689
16903
  });
16690
16904
 
16691
16905
  // apps/server/src/routes/web-routes.ts
16692
- import { lstatSync as lstatSync3, realpathSync as realpathSync2 } from "fs";
16906
+ import { lstatSync as lstatSync3, realpathSync as realpathSync3 } from "fs";
16693
16907
  import { lstat as lstat4, realpath as realpath4 } from "fs/promises";
16694
16908
  import path23 from "path";
16695
16909
  import { fileURLToPath as fileURLToPath3 } from "url";
@@ -16708,7 +16922,7 @@ function resolveWebAssetsRoot() {
16708
16922
  try {
16709
16923
  const metadata = lstatSync3(candidate);
16710
16924
  if (metadata.isDirectory() && !metadata.isSymbolicLink()) {
16711
- return realpathSync2(candidate);
16925
+ return realpathSync3(candidate);
16712
16926
  }
16713
16927
  } catch {}
16714
16928
  }
@@ -16799,6 +17013,320 @@ var init_web_routes = __esm(() => {
16799
17013
  }).get("/app/*", serveWebAsset);
16800
17014
  });
16801
17015
 
17016
+ // apps/server/src/lib/native-directory-picker.ts
17017
+ import path24 from "path";
17018
+ import { accessSync, constants as fsConstants2 } from "fs";
17019
+ import { homedir as homedir4 } from "os";
17020
+ async function readBoundedStream(stream, maximumBytes) {
17021
+ const reader = stream.getReader();
17022
+ const chunks = [];
17023
+ let totalBytes = 0;
17024
+ try {
17025
+ while (true) {
17026
+ const { done, value } = await reader.read();
17027
+ if (done)
17028
+ break;
17029
+ totalBytes += value.byteLength;
17030
+ if (totalBytes > maximumBytes) {
17031
+ throw new PickerOutputTooLargeError;
17032
+ }
17033
+ chunks.push(value);
17034
+ }
17035
+ } finally {
17036
+ reader.releaseLock();
17037
+ }
17038
+ const output = new Uint8Array(totalBytes);
17039
+ let offset = 0;
17040
+ for (const chunk of chunks) {
17041
+ output.set(chunk, offset);
17042
+ offset += chunk.byteLength;
17043
+ }
17044
+ return new TextDecoder().decode(output);
17045
+ }
17046
+ function stripToolLineEnding(value) {
17047
+ return value.endsWith(`\r
17048
+ `) ? value.slice(0, -2) : value.endsWith(`
17049
+ `) ? value.slice(0, -1) : value;
17050
+ }
17051
+ function assertPickerPath(value, pathApi) {
17052
+ const windowsRoot = pathApi === path24.win32 ? path24.win32.parse(value).root : null;
17053
+ const isFullyQualifiedWindowsPath = windowsRoot === null || /^[A-Za-z]:[\\/]$/.test(windowsRoot) || /^\\\\(?![?.][\\/])[^\\/]+[\\/][^\\/]+[\\/]$/.test(windowsRoot);
17054
+ if (value.length === 0 || value.length > 4096 || value.includes("\x00") || !pathApi.isAbsolute(value) || !isFullyQualifiedWindowsPath) {
17055
+ throw new NativeDirectoryPickerError("native_picker_failed", "The system folder picker returned an invalid folder.");
17056
+ }
17057
+ return value;
17058
+ }
17059
+ function parseWindowsResult(result) {
17060
+ const output = stripToolLineEnding(result.stdout);
17061
+ if (result.exitCode !== 0) {
17062
+ throw new NativeDirectoryPickerError("native_picker_failed", "The Windows folder picker could not be opened.");
17063
+ }
17064
+ if (output === "cancelled")
17065
+ return { outcome: "cancelled" };
17066
+ if (!output.startsWith("selected:")) {
17067
+ throw new NativeDirectoryPickerError("native_picker_failed", "The Windows folder picker returned an invalid response.");
17068
+ }
17069
+ const encoded = output.slice("selected:".length);
17070
+ if (!encoded || !/^[A-Za-z0-9+/]+={0,2}$/.test(encoded)) {
17071
+ throw new NativeDirectoryPickerError("native_picker_failed", "The Windows folder picker returned an invalid response.");
17072
+ }
17073
+ try {
17074
+ const directory = new TextDecoder("utf-8", { fatal: true }).decode(Buffer.from(encoded, "base64"));
17075
+ if (Buffer.from(directory, "utf8").toString("base64").replace(/=+$/, "") !== encoded.replace(/=+$/, "")) {
17076
+ throw new Error("invalid base64");
17077
+ }
17078
+ return {
17079
+ outcome: "selected",
17080
+ directory: assertPickerPath(directory, path24.win32)
17081
+ };
17082
+ } catch (error) {
17083
+ if (error instanceof NativeDirectoryPickerError)
17084
+ throw error;
17085
+ throw new NativeDirectoryPickerError("native_picker_failed", "The Windows folder picker returned an invalid response.");
17086
+ }
17087
+ }
17088
+ function parseMacosResult(result) {
17089
+ if (result.exitCode !== 0) {
17090
+ if (/\(-128\)|user canceled/i.test(result.stderr)) {
17091
+ return { outcome: "cancelled" };
17092
+ }
17093
+ throw new NativeDirectoryPickerError("native_picker_failed", "The macOS folder picker could not be opened.");
17094
+ }
17095
+ return {
17096
+ outcome: "selected",
17097
+ directory: assertPickerPath(stripToolLineEnding(result.stdout), path24.posix)
17098
+ };
17099
+ }
17100
+ function parseLinuxResult(result) {
17101
+ if (result.exitCode === 1)
17102
+ return { outcome: "cancelled" };
17103
+ if (result.exitCode !== 0) {
17104
+ throw new NativeDirectoryPickerError("native_picker_failed", "The Linux folder picker could not be opened.");
17105
+ }
17106
+ return {
17107
+ outcome: "selected",
17108
+ directory: assertPickerPath(stripToolLineEnding(result.stdout), path24.posix)
17109
+ };
17110
+ }
17111
+ function resolvePickerCommand({
17112
+ platform: platform4,
17113
+ environment,
17114
+ which
17115
+ }) {
17116
+ if (platform4 === "win32") {
17117
+ const configuredRoot = environment.SystemRoot?.trim();
17118
+ const systemRoot = configuredRoot && path24.win32.isAbsolute(configuredRoot) ? configuredRoot : "C:\\Windows";
17119
+ const candidate = path24.win32.join(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
17120
+ const executable = which(candidate);
17121
+ if (!executable || !path24.win32.isAbsolute(executable))
17122
+ return null;
17123
+ return {
17124
+ kind: "windows",
17125
+ argv: [
17126
+ executable,
17127
+ "-NoLogo",
17128
+ "-NoProfile",
17129
+ "-NonInteractive",
17130
+ "-STA",
17131
+ "-EncodedCommand",
17132
+ Buffer.from(windowsPickerScript, "utf16le").toString("base64")
17133
+ ]
17134
+ };
17135
+ }
17136
+ if (platform4 === "darwin") {
17137
+ const executable = which("/usr/bin/osascript");
17138
+ if (!executable || !path24.posix.isAbsolute(executable))
17139
+ return null;
17140
+ return {
17141
+ kind: "macos",
17142
+ argv: [executable, "-e", macosPickerScript]
17143
+ };
17144
+ }
17145
+ if (platform4 === "linux") {
17146
+ if (!environment.DISPLAY?.trim() && !environment.WAYLAND_DISPLAY?.trim()) {
17147
+ return null;
17148
+ }
17149
+ const desktop = environment.XDG_CURRENT_DESKTOP?.toLowerCase() ?? "";
17150
+ const candidates = desktop.includes("kde") ? ["kdialog", "zenity"] : ["zenity", "kdialog"];
17151
+ for (const command of candidates) {
17152
+ let executable = null;
17153
+ for (const directory of trustedLinuxExecutableDirectories) {
17154
+ const candidate = path24.posix.join(directory, command);
17155
+ const resolved = which(candidate);
17156
+ if (resolved === candidate) {
17157
+ executable = resolved;
17158
+ break;
17159
+ }
17160
+ }
17161
+ if (!executable)
17162
+ continue;
17163
+ if (command === "zenity") {
17164
+ return {
17165
+ kind: "zenity",
17166
+ argv: [
17167
+ executable,
17168
+ "--file-selection",
17169
+ "--directory",
17170
+ "--title=Choose a project folder"
17171
+ ]
17172
+ };
17173
+ }
17174
+ return {
17175
+ kind: "kdialog",
17176
+ argv: [
17177
+ executable,
17178
+ "--title",
17179
+ "Choose a project folder",
17180
+ "--getexistingdirectory",
17181
+ path24.posix.isAbsolute(homedir4()) ? homedir4() : "/"
17182
+ ]
17183
+ };
17184
+ }
17185
+ }
17186
+ return null;
17187
+ }
17188
+ function createNativeDirectoryPicker(options = {}) {
17189
+ const platform4 = options.platform ?? process.platform;
17190
+ const environment = options.environment ?? Bun.env;
17191
+ const which = options.which ?? ((candidate) => {
17192
+ try {
17193
+ accessSync(candidate, fsConstants2.X_OK);
17194
+ return candidate;
17195
+ } catch {
17196
+ return null;
17197
+ }
17198
+ });
17199
+ const runProcess = options.runProcess ?? runNativePickerProcess;
17200
+ let active = false;
17201
+ return {
17202
+ async pick(signal) {
17203
+ if (active) {
17204
+ throw new NativeDirectoryPickerError("native_picker_busy", "A folder picker is already open.");
17205
+ }
17206
+ if (signal?.aborted)
17207
+ return { outcome: "cancelled" };
17208
+ const command = resolvePickerCommand({ platform: platform4, environment, which });
17209
+ if (!command) {
17210
+ throw new NativeDirectoryPickerError("native_picker_unavailable", "No supported system folder picker is available.");
17211
+ }
17212
+ active = true;
17213
+ try {
17214
+ const result = await runProcess(command.argv, signal);
17215
+ if (signal?.aborted)
17216
+ return { outcome: "cancelled" };
17217
+ if (command.kind === "windows")
17218
+ return parseWindowsResult(result);
17219
+ if (command.kind === "macos")
17220
+ return parseMacosResult(result);
17221
+ return parseLinuxResult(result);
17222
+ } catch (error) {
17223
+ if (error instanceof NativeDirectoryPickerError)
17224
+ throw error;
17225
+ throw new NativeDirectoryPickerError("native_picker_failed", "The system folder picker could not be opened.");
17226
+ } finally {
17227
+ active = false;
17228
+ }
17229
+ }
17230
+ };
17231
+ }
17232
+ var maximumPickerOutputBytes, NativeDirectoryPickerError, trustedLinuxExecutableDirectories, PickerOutputTooLargeError, runNativePickerProcess = async (command, signal) => {
17233
+ if (signal?.aborted) {
17234
+ return { exitCode: 1, stdout: "", stderr: "" };
17235
+ }
17236
+ const child = Bun.spawn([...command], {
17237
+ stdin: "ignore",
17238
+ stdout: "pipe",
17239
+ stderr: "pipe",
17240
+ windowsHide: true
17241
+ });
17242
+ let aborted = false;
17243
+ const abort = () => {
17244
+ aborted = true;
17245
+ try {
17246
+ child.kill();
17247
+ } catch {}
17248
+ };
17249
+ signal?.addEventListener("abort", abort, { once: true });
17250
+ if (signal?.aborted)
17251
+ abort();
17252
+ try {
17253
+ const [stdout, stderr, exitCode] = await Promise.all([
17254
+ readBoundedStream(child.stdout, maximumPickerOutputBytes),
17255
+ readBoundedStream(child.stderr, maximumPickerOutputBytes),
17256
+ child.exited
17257
+ ]);
17258
+ return {
17259
+ exitCode: aborted ? 1 : exitCode,
17260
+ stdout: aborted ? "" : stdout,
17261
+ stderr: aborted ? "" : stderr
17262
+ };
17263
+ } catch (error) {
17264
+ abort();
17265
+ if (error instanceof PickerOutputTooLargeError) {
17266
+ throw new NativeDirectoryPickerError("native_picker_failed", "The system folder picker returned an invalid response.");
17267
+ }
17268
+ throw error;
17269
+ } finally {
17270
+ signal?.removeEventListener("abort", abort);
17271
+ }
17272
+ }, windowsPickerScript, macosPickerScript;
17273
+ var init_native_directory_picker = __esm(() => {
17274
+ maximumPickerOutputBytes = 16 * 1024;
17275
+ NativeDirectoryPickerError = class NativeDirectoryPickerError extends Error {
17276
+ code;
17277
+ constructor(code, message) {
17278
+ super(message);
17279
+ this.code = code;
17280
+ this.name = "NativeDirectoryPickerError";
17281
+ }
17282
+ };
17283
+ trustedLinuxExecutableDirectories = [
17284
+ "/usr/bin",
17285
+ "/bin",
17286
+ "/run/current-system/sw/bin"
17287
+ ];
17288
+ PickerOutputTooLargeError = class PickerOutputTooLargeError extends Error {
17289
+ };
17290
+ windowsPickerScript = String.raw`
17291
+ $ErrorActionPreference = 'Stop'
17292
+ [Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
17293
+ Add-Type -AssemblyName System.Windows.Forms
17294
+ $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
17295
+ $dialog.Description = 'Choose a project folder'
17296
+ $dialog.ShowNewFolderButton = $true
17297
+ $dialog.AutoUpgradeEnabled = $true
17298
+ $owner = New-Object System.Windows.Forms.Form
17299
+ $owner.TopMost = $true
17300
+ $owner.ShowInTaskbar = $false
17301
+ $owner.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual
17302
+ $owner.Location = New-Object System.Drawing.Point(-32000, -32000)
17303
+ $owner.Size = New-Object System.Drawing.Size(1, 1)
17304
+ $owner.Opacity = 0
17305
+ try {
17306
+ $owner.Show()
17307
+ $owner.Activate()
17308
+ $result = $dialog.ShowDialog($owner)
17309
+ if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
17310
+ $bytes = [Text.Encoding]::UTF8.GetBytes($dialog.SelectedPath)
17311
+ [Console]::Out.Write('selected:' + [Convert]::ToBase64String($bytes))
17312
+ } else {
17313
+ [Console]::Out.Write('cancelled')
17314
+ }
17315
+ } finally {
17316
+ $dialog.Dispose()
17317
+ $owner.Dispose()
17318
+ }
17319
+ `;
17320
+ macosPickerScript = String.raw`
17321
+ try
17322
+ set chosenFolder to choose folder with prompt "Choose a project folder"
17323
+ return POSIX path of chosenFolder
17324
+ on error number -128
17325
+ error number -128
17326
+ end try
17327
+ `;
17328
+ });
17329
+
16802
17330
  // apps/server/src/routes/workspace-routes.ts
16803
17331
  import { zValidator as zValidator3 } from "@hono/zod-validator";
16804
17332
  import {
@@ -16807,12 +17335,17 @@ import {
16807
17335
  randomBytes,
16808
17336
  timingSafeEqual as timingSafeEqual2
16809
17337
  } from "crypto";
16810
- import { constants as fsConstants2, promises as fs8 } from "fs";
16811
- import { homedir as homedir4 } from "os";
16812
- import path24 from "path";
17338
+ import { constants as fsConstants3, promises as fs8 } from "fs";
17339
+ import { homedir as homedir5 } from "os";
17340
+ import path25 from "path";
16813
17341
  import { Hono as Hono7 } from "hono";
16814
17342
  function pathImplementation(platform4) {
16815
- return platform4 === "win32" ? path24.win32 : path24.posix;
17343
+ return platform4 === "win32" ? path25.win32 : path25.posix;
17344
+ }
17345
+ function isFilesystemRootPath(candidate, platform4 = process.platform) {
17346
+ const pathApi = pathImplementation(platform4);
17347
+ const normalized = pathApi.normalize(candidate);
17348
+ return normalized === pathApi.parse(normalized).root;
16816
17349
  }
16817
17350
  function normalizeKnownFolderCandidate(candidate, platform4) {
16818
17351
  if (candidate.includes("\x00")) {
@@ -16823,7 +17356,7 @@ function normalizeKnownFolderCandidate(candidate, platform4) {
16823
17356
  return null;
16824
17357
  }
16825
17358
  const normalized = pathApi.normalize(candidate);
16826
- if (normalized === pathApi.parse(normalized).root) {
17359
+ if (isFilesystemRootPath(normalized, platform4)) {
16827
17360
  return null;
16828
17361
  }
16829
17362
  return normalized;
@@ -16841,10 +17374,10 @@ async function probeDirectory(candidate) {
16841
17374
  }
16842
17375
  }
16843
17376
  async function readSmallUserDirsConfiguration(filePath) {
16844
- const noFollowFlag = typeof fsConstants2.O_NOFOLLOW === "number" ? fsConstants2.O_NOFOLLOW : 0;
17377
+ const noFollowFlag = typeof fsConstants3.O_NOFOLLOW === "number" ? fsConstants3.O_NOFOLLOW : 0;
16845
17378
  let handle;
16846
17379
  try {
16847
- handle = await fs8.open(filePath, fsConstants2.O_RDONLY | noFollowFlag);
17380
+ handle = await fs8.open(filePath, fsConstants3.O_RDONLY | noFollowFlag);
16848
17381
  const metadata = await handle.stat();
16849
17382
  if (!metadata.isFile() || metadata.size <= 0 || metadata.size > maximumUserDirsConfigurationBytes) {
16850
17383
  return null;
@@ -16865,8 +17398,8 @@ async function resolveWindowsKnownFolder(environment, folder) {
16865
17398
  if (!windowsRoot) {
16866
17399
  return null;
16867
17400
  }
16868
- const systemDirectory = path24.win32.join(windowsRoot, "System32");
16869
- const executable = path24.win32.join(systemDirectory, "WindowsPowerShell", "v1.0", "powershell.exe");
17401
+ const systemDirectory = path25.win32.join(windowsRoot, "System32");
17402
+ const executable = path25.win32.join(systemDirectory, "WindowsPowerShell", "v1.0", "powershell.exe");
16870
17403
  const folderExpression = folder === "desktop" ? "[Environment]::GetFolderPath([Environment+SpecialFolder]::DesktopDirectory)" : folder === "documents" ? "[Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments)" : "[Environment]::ExpandEnvironmentVariables([string](Get-ItemProperty -LiteralPath 'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders' -Name '{374DE290-123F-4565-9164-39C4925E467B}' -ErrorAction Stop).'{374DE290-123F-4565-9164-39C4925E467B}')";
16871
17404
  const child = Bun.spawn([
16872
17405
  executable,
@@ -16925,15 +17458,15 @@ function parseXdgUserDirectory(contents, homeDirectory, variableName) {
16925
17458
  return null;
16926
17459
  }
16927
17460
  if (configured.startsWith("$HOME/")) {
16928
- return path24.posix.resolve(homeDirectory, configured.slice(6));
17461
+ return path25.posix.resolve(homeDirectory, configured.slice(6));
16929
17462
  }
16930
17463
  if (configured.startsWith("${HOME}/")) {
16931
- return path24.posix.resolve(homeDirectory, configured.slice(8));
17464
+ return path25.posix.resolve(homeDirectory, configured.slice(8));
16932
17465
  }
16933
17466
  if (configured.includes("$")) {
16934
17467
  return null;
16935
17468
  }
16936
- return path24.posix.isAbsolute(configured) ? path24.posix.normalize(configured) : null;
17469
+ return path25.posix.isAbsolute(configured) ? path25.posix.normalize(configured) : null;
16937
17470
  }
16938
17471
  return null;
16939
17472
  }
@@ -16963,7 +17496,7 @@ async function resolveDesktopDirectoryPath(options = {}) {
16963
17496
  const platform4 = options.platform ?? process.platform;
16964
17497
  const pathApi = pathImplementation(platform4);
16965
17498
  const environment = options.environment ?? Bun.env;
16966
- const homeDirectory = pathApi.normalize(options.homeDirectory ?? homedir4());
17499
+ const homeDirectory = pathApi.normalize(options.homeDirectory ?? homedir5());
16967
17500
  const explicit = environment.LIGHTCODE_DESKTOP_PATH?.trim();
16968
17501
  if (explicit) {
16969
17502
  const normalized = normalizeKnownFolderCandidate(explicit, platform4);
@@ -16987,17 +17520,17 @@ async function resolveDesktopDirectoryPath(options = {}) {
16987
17520
  return [];
16988
17521
  }
16989
17522
  return [
16990
- index === 0 ? trimmed : path24.win32.join(trimmed, "Desktop")
17523
+ index === 0 ? trimmed : path25.win32.join(trimmed, "Desktop")
16991
17524
  ];
16992
17525
  });
16993
- candidates.push(path24.win32.join(userProfile, "Desktop"));
16994
- return await firstUsableKnownFolder(candidates, platform4, probe) ?? path24.win32.join(homeDirectory, "Desktop");
17526
+ candidates.push(path25.win32.join(userProfile, "Desktop"));
17527
+ return await firstUsableKnownFolder(candidates, platform4, probe) ?? path25.win32.join(homeDirectory, "Desktop");
16995
17528
  }
16996
17529
  if (platform4 === "linux") {
16997
17530
  const configHome = environment.XDG_CONFIG_HOME?.trim();
16998
- const safeConfigHome = configHome && path24.posix.isAbsolute(configHome) ? path24.posix.normalize(configHome) : path24.posix.join(homeDirectory, ".config");
17531
+ const safeConfigHome = configHome && path25.posix.isAbsolute(configHome) ? path25.posix.normalize(configHome) : path25.posix.join(homeDirectory, ".config");
16999
17532
  const readConfiguration = options.readUserDirsConfiguration ?? readSmallUserDirsConfiguration;
17000
- const contents = await readConfiguration(path24.posix.join(safeConfigHome, "user-dirs.dirs"));
17533
+ const contents = await readConfiguration(path25.posix.join(safeConfigHome, "user-dirs.dirs"));
17001
17534
  const configured = contents ? parseXdgUserDirectory(contents, homeDirectory, "XDG_DESKTOP_DIR") : null;
17002
17535
  if (configured) {
17003
17536
  const selected = await firstUsableKnownFolder([configured], platform4, probe);
@@ -17012,7 +17545,7 @@ async function resolveUserDirectoryPath(folder, options) {
17012
17545
  const platform4 = options.platform ?? process.platform;
17013
17546
  const pathApi = pathImplementation(platform4);
17014
17547
  const environment = options.environment ?? Bun.env;
17015
- const homeDirectory = pathApi.normalize(options.homeDirectory ?? homedir4());
17548
+ const homeDirectory = pathApi.normalize(options.homeDirectory ?? homedir5());
17016
17549
  const displayName = folder === "documents" ? "Documents" : "Downloads";
17017
17550
  const overrideName = folder === "documents" ? "LIGHTCODE_DOCUMENTS_PATH" : "LIGHTCODE_DOWNLOADS_PATH";
17018
17551
  const explicit = environment[overrideName]?.trim();
@@ -17034,17 +17567,17 @@ async function resolveUserDirectoryPath(folder, options) {
17034
17567
  ];
17035
17568
  const candidates = [
17036
17569
  knownFolder,
17037
- ...cloudRoots.map((root) => root?.trim() ? path24.win32.join(root.trim(), displayName) : null),
17038
- path24.win32.join(userProfile, displayName),
17039
- path24.win32.join(homeDirectory, displayName)
17570
+ ...cloudRoots.map((root) => root?.trim() ? path25.win32.join(root.trim(), displayName) : null),
17571
+ path25.win32.join(userProfile, displayName),
17572
+ path25.win32.join(homeDirectory, displayName)
17040
17573
  ];
17041
- return await firstUsableKnownFolder(candidates, platform4, probe) ?? path24.win32.join(homeDirectory, displayName);
17574
+ return await firstUsableKnownFolder(candidates, platform4, probe) ?? path25.win32.join(homeDirectory, displayName);
17042
17575
  }
17043
17576
  if (platform4 === "linux") {
17044
17577
  const configHome = environment.XDG_CONFIG_HOME?.trim();
17045
- const safeConfigHome = configHome && path24.posix.isAbsolute(configHome) ? path24.posix.normalize(configHome) : path24.posix.join(homeDirectory, ".config");
17578
+ const safeConfigHome = configHome && path25.posix.isAbsolute(configHome) ? path25.posix.normalize(configHome) : path25.posix.join(homeDirectory, ".config");
17046
17579
  const readConfiguration = options.readUserDirsConfiguration ?? readSmallUserDirsConfiguration;
17047
- const contents = await readConfiguration(path24.posix.join(safeConfigHome, "user-dirs.dirs"));
17580
+ const contents = await readConfiguration(path25.posix.join(safeConfigHome, "user-dirs.dirs"));
17048
17581
  const configured = contents ? parseXdgUserDirectory(contents, homeDirectory, folder === "documents" ? "XDG_DOCUMENTS_DIR" : "XDG_DOWNLOAD_DIR") : null;
17049
17582
  const selected = await firstUsableKnownFolder([configured], platform4, probe);
17050
17583
  if (selected) {
@@ -17063,7 +17596,7 @@ async function resolveProjectsDirectoryPath(options = {}) {
17063
17596
  const platform4 = options.platform ?? process.platform;
17064
17597
  const pathApi = pathImplementation(platform4);
17065
17598
  const environment = options.environment ?? Bun.env;
17066
- const homeDirectory = pathApi.normalize(options.homeDirectory ?? homedir4());
17599
+ const homeDirectory = pathApi.normalize(options.homeDirectory ?? homedir5());
17067
17600
  const explicit = environment.LIGHTCODE_PROJECTS_PATH?.trim();
17068
17601
  if (explicit) {
17069
17602
  const normalized = normalizeKnownFolderCandidate(explicit, platform4);
@@ -17114,11 +17647,23 @@ function mapFilesystemError(error) {
17114
17647
  }
17115
17648
  return new WorkspaceRouteError("workspace_unavailable", "Unable to access the selected workspace.", 500, true);
17116
17649
  }
17650
+ function mapNativePickerError(error) {
17651
+ if (!(error instanceof NativeDirectoryPickerError)) {
17652
+ return new WorkspaceRouteError("native_picker_failed", "The system folder picker could not be opened.", 500, true);
17653
+ }
17654
+ if (error.code === "native_picker_busy") {
17655
+ return new WorkspaceRouteError(error.code, "A folder picker is already open.", 409, true);
17656
+ }
17657
+ if (error.code === "native_picker_unavailable") {
17658
+ return new WorkspaceRouteError(error.code, "No supported system folder picker is available.", 503, false);
17659
+ }
17660
+ return new WorkspaceRouteError(error.code, "The system folder picker could not be opened.", 500, true);
17661
+ }
17117
17662
  function workspaceErrorResponse(c, error) {
17118
17663
  const mapped = error instanceof WorkspaceRouteError ? error : mapFilesystemError(error);
17119
17664
  if (mapped.status === 500) {
17120
17665
  logger13.error("workspace_request_failed", {
17121
- error: getErrorMessage(error)
17666
+ error: getErrorMessage(mapped)
17122
17667
  });
17123
17668
  }
17124
17669
  return c.json({
@@ -17144,13 +17689,13 @@ function identitiesMatch(left, right) {
17144
17689
  return left.device === right.device && left.inode === right.inode;
17145
17690
  }
17146
17691
  function isContainedPath2(root, candidate) {
17147
- const relative = path24.relative(root, candidate);
17148
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path24.sep}`) && !path24.isAbsolute(relative);
17692
+ const relative = path25.relative(root, candidate);
17693
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path25.sep}`) && !path25.isAbsolute(relative);
17149
17694
  }
17150
17695
  async function resolveKnownDirectory(directory) {
17151
17696
  try {
17152
- const root = await fs8.realpath(path24.resolve(directory));
17153
- if (root === path24.parse(root).root) {
17697
+ const root = await fs8.realpath(path25.resolve(directory));
17698
+ if (isFilesystemRootPath(root)) {
17154
17699
  throw new WorkspaceRouteError("workspace_unavailable", "A filesystem root cannot be opened as a workspace location.", 500, false);
17155
17700
  }
17156
17701
  const stats = await fs8.stat(root, { bigint: true });
@@ -17199,7 +17744,7 @@ async function symlinkFailure(root, candidate, locationName) {
17199
17744
  async function resolveDirectoryFromSegments(root, segments, locationName) {
17200
17745
  let current = root;
17201
17746
  for (const segment of segments) {
17202
- const candidate = path24.join(current, segment);
17747
+ const candidate = path25.join(current, segment);
17203
17748
  if (!isContainedPath2(root, candidate)) {
17204
17749
  throw new WorkspaceRouteError("workspace_symlink_escape", `The requested path is outside the allowed ${locationName} location.`, 403, false);
17205
17750
  }
@@ -17302,7 +17847,7 @@ function decodeCursor(secret, cursor, binding) {
17302
17847
  }
17303
17848
  }
17304
17849
  async function describeEntry(root, directory, name) {
17305
- const candidate = path24.join(directory, name);
17850
+ const candidate = path25.join(directory, name);
17306
17851
  try {
17307
17852
  const stats = await fs8.lstat(candidate);
17308
17853
  if (stats.isSymbolicLink()) {
@@ -17326,7 +17871,7 @@ async function describeEntry(root, directory, name) {
17326
17871
  }
17327
17872
  }
17328
17873
  const kind = stats.isDirectory() ? "directory" : stats.isFile() ? "file" : "other";
17329
- const requiredAccess = stats.isDirectory() ? fsConstants2.R_OK | fsConstants2.X_OK : fsConstants2.R_OK;
17874
+ const requiredAccess = stats.isDirectory() ? fsConstants3.R_OK | fsConstants3.X_OK : fsConstants3.R_OK;
17330
17875
  const readable = await fs8.access(candidate, requiredAccess).then(() => true).catch(() => false);
17331
17876
  return {
17332
17877
  name,
@@ -17382,7 +17927,7 @@ function createWorkspaceRoutes(options = {}) {
17382
17927
  return normalized;
17383
17928
  } : () => resolveDesktopDirectoryPath());
17384
17929
  const desktopPathLabel = options.desktopPathLabel ?? "Desktop";
17385
- const defaultHomePath = async () => homedir4();
17930
+ const defaultHomePath = async () => homedir5();
17386
17931
  const defaultDocumentsPath = () => resolveDocumentsDirectoryPath();
17387
17932
  const defaultDownloadsPath = () => resolveDownloadsDirectoryPath();
17388
17933
  const definitions = [
@@ -17424,6 +17969,8 @@ function createWorkspaceRoutes(options = {}) {
17424
17969
  ];
17425
17970
  const definitionsById = new Map(definitions.map((definition) => [definition.id, definition]));
17426
17971
  const createSession = options.createSession ?? createChatSession;
17972
+ const nativeDirectoryPicker = options.nativeDirectoryPicker ?? createNativeDirectoryPicker();
17973
+ const authorizeNativePickerRequest = options.authorizeNativePickerRequest ?? isAuthenticatedWebRequest;
17427
17974
  const cursorSecret = randomBytes(32);
17428
17975
  const browserCapabilities = new Map;
17429
17976
  const workspaceGrants = new Map;
@@ -17442,7 +17989,70 @@ function createWorkspaceRoutes(options = {}) {
17442
17989
  }
17443
17990
  return grant;
17444
17991
  };
17445
- return new Hono7().get("/locations", (c) => c.json(workspaceLocationsResponseSchema.parse({
17992
+ const storeWorkspaceGrant = async ({
17993
+ root,
17994
+ identity,
17995
+ name,
17996
+ pathLabel
17997
+ }) => {
17998
+ await fs8.access(root, fsConstants3.R_OK | fsConstants3.X_OK);
17999
+ const createdAt = new Date(now()).toISOString();
18000
+ const id = crypto.randomUUID();
18001
+ const grant = {
18002
+ id,
18003
+ name,
18004
+ pathLabel,
18005
+ createdAt,
18006
+ root,
18007
+ identity
18008
+ };
18009
+ workspaceGrants.set(id, grant);
18010
+ trimOldestEntries(workspaceGrants, maximumWorkspaceGrants);
18011
+ try {
18012
+ await assertRootIdentity(grant);
18013
+ } catch (error) {
18014
+ workspaceGrants.delete(id);
18015
+ throw error;
18016
+ }
18017
+ return workspaceGrantSchema.parse({ id, name, pathLabel, createdAt });
18018
+ };
18019
+ return new Hono7().post("/picker/open", zValidator3("json", workspaceNativePickerRequestSchema, (result, c) => {
18020
+ if (!result.success) {
18021
+ return invalidRequestResponse(c);
18022
+ }
18023
+ }), async (c) => {
18024
+ if (!authorizeNativePickerRequest(c.req.raw)) {
18025
+ return c.json({
18026
+ error: "The system folder picker is available only to an authenticated Lightcode web session.",
18027
+ code: "web_browser_required"
18028
+ }, 403);
18029
+ }
18030
+ try {
18031
+ let picked;
18032
+ try {
18033
+ picked = await nativeDirectoryPicker.pick(c.req.raw.signal);
18034
+ } catch (error) {
18035
+ throw mapNativePickerError(error);
18036
+ }
18037
+ if (picked.outcome === "cancelled") {
18038
+ return c.json(workspaceNativePickerResponseSchema.parse({
18039
+ outcome: "cancelled"
18040
+ }), 200);
18041
+ }
18042
+ const directory = await resolveKnownDirectory(picked.directory);
18043
+ const workspace = await storeWorkspaceGrant({
18044
+ ...directory,
18045
+ name: path25.basename(directory.root),
18046
+ pathLabel: directory.root
18047
+ });
18048
+ return c.json(workspaceNativePickerResponseSchema.parse({
18049
+ outcome: "selected",
18050
+ workspace
18051
+ }), 201);
18052
+ } catch (error) {
18053
+ return workspaceErrorResponse(c, error);
18054
+ }
18055
+ }).get("/locations", (c) => c.json(workspaceLocationsResponseSchema.parse({
17446
18056
  locations: definitions.map((definition) => knownLocation(definition, "unprobed"))
17447
18057
  }))).post("/browser/open", zValidator3("json", workspaceBrowserOpenRequestSchema, (result, c) => {
17448
18058
  if (!result.success) {
@@ -17578,37 +18188,19 @@ function createWorkspaceRoutes(options = {}) {
17578
18188
  operation: "select",
17579
18189
  directory: directory.path
17580
18190
  });
17581
- await fs8.access(directory.path, fsConstants2.R_OK | fsConstants2.X_OK);
17582
- const createdAt = new Date(now()).toISOString();
17583
- const id = crypto.randomUUID();
17584
18191
  const name = segments.at(-1) ?? capability2.rootName;
17585
18192
  const pathLabel = [
17586
18193
  capability2.location.pathLabel,
17587
18194
  ...segments
17588
18195
  ].join("/");
17589
- const grant = {
17590
- id,
17591
- name,
17592
- pathLabel,
17593
- createdAt,
18196
+ const workspace = await storeWorkspaceGrant({
17594
18197
  root: directory.path,
17595
- identity: directory.identity
17596
- };
17597
- workspaceGrants.set(id, grant);
17598
- trimOldestEntries(workspaceGrants, maximumWorkspaceGrants);
17599
- try {
17600
- await assertRootIdentity(grant);
17601
- } catch (error) {
17602
- workspaceGrants.delete(id);
17603
- throw error;
17604
- }
18198
+ identity: directory.identity,
18199
+ name,
18200
+ pathLabel
18201
+ });
17605
18202
  return c.json(workspaceBrowserSelectResponseSchema.parse({
17606
- workspace: workspaceGrantSchema.parse({
17607
- id,
17608
- name,
17609
- pathLabel,
17610
- createdAt
17611
- })
18203
+ workspace
17612
18204
  }), 201);
17613
18205
  } catch (error) {
17614
18206
  return workspaceErrorResponse(c, error);
@@ -17646,6 +18238,8 @@ var init_workspace_routes = __esm(() => {
17646
18238
  init_src();
17647
18239
  init_chat_store();
17648
18240
  init_runtime_config();
18241
+ init_native_directory_picker();
18242
+ init_web_auth();
17649
18243
  logger13 = createLogger("workspace-routes");
17650
18244
  defaultBrowserCapabilityTtlMs = 10 * 60 * 1000;
17651
18245
  maximumUserDirsConfigurationBytes = 16 * 1024;