tracer-sh 0.2.0 → 0.2.2

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.
@@ -19,7 +19,7 @@ import {
19
19
  POSTHOG_AUTH_STOP_RULE,
20
20
  POSTHOG_DOMAIN_KNOWLEDGE,
21
21
  POSTHOG_INSIDE_OUT_DEBUGGING
22
- } from "./chunk-ANVLQIEK.js";
22
+ } from "./chunk-OTYSD6PF.js";
23
23
  import {
24
24
  __commonJS,
25
25
  __export,
@@ -170,7 +170,7 @@ var require_dist = __commonJS({
170
170
  }
171
171
  });
172
172
 
173
- // ../../node_modules/.pnpm/@hono+node-server@1.19.14_hono@4.12.14/node_modules/@hono/node-server/dist/index.mjs
173
+ // ../../node_modules/.pnpm/@hono+node-server@1.19.14_hono@4.12.23/node_modules/@hono/node-server/dist/index.mjs
174
174
  import { createServer as createServerHTTP } from "http";
175
175
  import { Http2ServerRequest as Http2ServerRequest2, constants as h2constants } from "http2";
176
176
  import { Http2ServerRequest } from "http2";
@@ -2758,7 +2758,8 @@ var SESSION_PREFIX = {
2758
2758
  MONITORS: "__monitors__"
2759
2759
  };
2760
2760
  var SESSION_KIND = {
2761
- IMPORTED: "imported"
2761
+ IMPORTED: "imported",
2762
+ API: "api"
2762
2763
  };
2763
2764
  function dashboardSessionId(dashboardId) {
2764
2765
  return `${SESSION_PREFIX.DASHBOARD}:${dashboardId}`;
@@ -46135,7 +46136,7 @@ function createDeleteMemoryTool(memoryExecute, opts) {
46135
46136
  var DOMAIN_LOADERS = {
46136
46137
  newrelic: async () => (await import("./domain-knowledge-WHIEZOOH.js")).NR_DOMAIN_KNOWLEDGE,
46137
46138
  gcp: async () => (await import("./domain-knowledge-V6AENXZV.js")).GCP_DOMAIN_KNOWLEDGE,
46138
- posthog: async () => (await import("./domain-knowledge-5JOEEXGN.js")).POSTHOG_DOMAIN_KNOWLEDGE
46139
+ posthog: async () => (await import("./domain-knowledge-5ZUPRLNB.js")).POSTHOG_DOMAIN_KNOWLEDGE
46139
46140
  };
46140
46141
  async function getDomainKnowledge(providerType) {
46141
46142
  const loader = DOMAIN_LOADERS[providerType];
@@ -50090,12 +50091,56 @@ function rowsToObjects(resp) {
50090
50091
  return obj;
50091
50092
  });
50092
50093
  }
50094
+ var CH_DATETIME_RE = /^\d{4}-\d{2}-\d{2}([ T]\d{2}:\d{2}:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?$/;
50095
+ function timeValueToUnixSeconds(v) {
50096
+ if (typeof v !== "string") return null;
50097
+ const trimmed = v.trim();
50098
+ if (!CH_DATETIME_RE.test(trimmed)) return null;
50099
+ const s = /[TZ]|[+-]\d{2}:?\d{2}$/.test(trimmed) ? trimmed : (trimmed.includes(" ") ? trimmed.replace(" ", "T") : `${trimmed}T00:00:00`) + "Z";
50100
+ const ms = Date.parse(s);
50101
+ return Number.isNaN(ms) ? null : Math.floor(ms / 1e3);
50102
+ }
50103
+ function isNumericValue(v) {
50104
+ if (typeof v === "number") return Number.isFinite(v);
50105
+ if (typeof v === "string") return /^-?\d+(\.\d+)?$/.test(v.trim());
50106
+ return false;
50107
+ }
50108
+ function toChartRows(rows) {
50109
+ if (rows.length < 2) return rows;
50110
+ const cols = Object.keys(rows[0]);
50111
+ const timeCol = cols.find(
50112
+ (c) => rows.every((r) => typeof r[c] === "string" && timeValueToUnixSeconds(r[c]) !== null)
50113
+ );
50114
+ if (!timeCol) return rows;
50115
+ const others = cols.filter((c) => c !== timeCol);
50116
+ const metrics = others.filter(
50117
+ (c) => rows.some((r) => r[c] != null) && rows.every((r) => r[c] == null || isNumericValue(r[c]))
50118
+ );
50119
+ if (metrics.length === 0) return rows;
50120
+ const dims = others.filter((c) => !metrics.includes(c) && rows.some((r) => r[c] != null));
50121
+ if (dims.length > 1) return rows;
50122
+ const dimCol = dims[0];
50123
+ return rows.map((r) => {
50124
+ const out = { beginTimeSeconds: timeValueToUnixSeconds(r[timeCol]) };
50125
+ for (const m of metrics) out[m] = r[m] == null ? null : Number(r[m]);
50126
+ if (dimCol !== void 0) {
50127
+ out[dimCol] = r[dimCol];
50128
+ out.facet = r[dimCol];
50129
+ }
50130
+ return out;
50131
+ });
50132
+ }
50133
+ var MAX_CELL_CHARS = 200;
50093
50134
  function fmtVal3(v) {
50094
50135
  if (v == null) return "";
50095
50136
  if (typeof v === "number") return Number.isInteger(v) ? String(v) : v.toFixed(2);
50096
50137
  if (Array.isArray(v)) return v.length <= 5 ? v.join("; ") : `[${v.length} items]`;
50097
- if (typeof v === "object") return JSON.stringify(v);
50098
- return String(v);
50138
+ if (typeof v === "object") {
50139
+ const json3 = JSON.stringify(v);
50140
+ return json3.length <= MAX_CELL_CHARS ? json3 : `{ ${Object.keys(v).join(", ")} }`;
50141
+ }
50142
+ const s = String(v);
50143
+ return s.length <= MAX_CELL_CHARS ? s : `${s.slice(0, MAX_CELL_CHARS)}\u2026 [${s.length} chars]`;
50099
50144
  }
50100
50145
  function csvEscape2(val) {
50101
50146
  if (val.includes(",") || val.includes('"') || val.includes("\n")) {
@@ -50192,13 +50237,14 @@ function buildExecuteHogqlTool(provider, collectedQueries, writer) {
50192
50237
  }),
50193
50238
  execute: async ({ query }, { toolCallId }) => {
50194
50239
  try {
50195
- const rows = await provider.executeRawQuery(query);
50240
+ const raw2 = await provider.executeRawQuery(query);
50241
+ const rows = toChartRows(raw2);
50196
50242
  collectedQueries.push({ query, results: rows });
50197
50243
  writer?.write({
50198
50244
  type: "data-provider-part",
50199
50245
  data: { toolCallId, part: { type: "query", query, results: rows } }
50200
50246
  });
50201
- const csv = formatHogqlCsv(rows);
50247
+ const csv = formatHogqlCsv(raw2);
50202
50248
  return { parts: [{ type: "query", query, results: rows }], analysis: csv };
50203
50249
  } catch (err) {
50204
50250
  const message = err instanceof Error ? err.message : String(err);
@@ -50399,7 +50445,7 @@ function createContext(deps) {
50399
50445
  };
50400
50446
  }
50401
50447
 
50402
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/compose.js
50448
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/compose.js
50403
50449
  var compose = (middleware, onError, onNotFound) => {
50404
50450
  return (context2, next) => {
50405
50451
  let index2 = -1;
@@ -50443,10 +50489,10 @@ var compose = (middleware, onError, onNotFound) => {
50443
50489
  };
50444
50490
  };
50445
50491
 
50446
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/request/constants.js
50492
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/request/constants.js
50447
50493
  var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
50448
50494
 
50449
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/body.js
50495
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/body.js
50450
50496
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
50451
50497
  const { all = false, dot = false } = options;
50452
50498
  const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
@@ -50518,7 +50564,7 @@ var handleParsingNestedValues = (form, key, value) => {
50518
50564
  });
50519
50565
  };
50520
50566
 
50521
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/url.js
50567
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/url.js
50522
50568
  var splitPath = (path) => {
50523
50569
  const paths = path.split("/");
50524
50570
  if (paths[0] === "") {
@@ -50722,7 +50768,7 @@ var getQueryParams = (url2, key) => {
50722
50768
  };
50723
50769
  var decodeURIComponent_ = decodeURIComponent;
50724
50770
 
50725
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/request.js
50771
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/request.js
50726
50772
  var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
50727
50773
  var HonoRequest = class {
50728
50774
  /**
@@ -50867,6 +50913,21 @@ var HonoRequest = class {
50867
50913
  arrayBuffer() {
50868
50914
  return this.#cachedBody("arrayBuffer");
50869
50915
  }
50916
+ /**
50917
+ * `.bytes()` parses the request body as a `Uint8Array`.
50918
+ *
50919
+ * @see {@link https://hono.dev/docs/api/request#bytes}
50920
+ *
50921
+ * @example
50922
+ * ```ts
50923
+ * app.post('/entry', async (c) => {
50924
+ * const body = await c.req.bytes()
50925
+ * })
50926
+ * ```
50927
+ */
50928
+ bytes() {
50929
+ return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
50930
+ }
50870
50931
  /**
50871
50932
  * Parses the request body as a `Blob`.
50872
50933
  * @example
@@ -50990,7 +51051,7 @@ var HonoRequest = class {
50990
51051
  }
50991
51052
  };
50992
51053
 
50993
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/html.js
51054
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/html.js
50994
51055
  var HtmlEscapedCallbackPhase = {
50995
51056
  Stringify: 1,
50996
51057
  BeforeStream: 2,
@@ -51032,7 +51093,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) =>
51032
51093
  }
51033
51094
  };
51034
51095
 
51035
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/context.js
51096
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/context.js
51036
51097
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
51037
51098
  var setDefaultContentType = (contentType, headers) => {
51038
51099
  return {
@@ -51439,7 +51500,7 @@ var Context = class {
51439
51500
  };
51440
51501
  };
51441
51502
 
51442
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router.js
51503
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router.js
51443
51504
  var METHOD_NAME_ALL = "ALL";
51444
51505
  var METHOD_NAME_ALL_LOWERCASE = "all";
51445
51506
  var METHODS = ["get", "post", "put", "delete", "options", "patch"];
@@ -51447,10 +51508,10 @@ var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is
51447
51508
  var UnsupportedPathError = class extends Error {
51448
51509
  };
51449
51510
 
51450
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/constants.js
51511
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/constants.js
51451
51512
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
51452
51513
 
51453
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/hono-base.js
51514
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/hono-base.js
51454
51515
  var notFoundHandler = (c) => {
51455
51516
  return c.text("404 Not Found", 404);
51456
51517
  };
@@ -51565,7 +51626,7 @@ var Hono = class _Hono {
51565
51626
  handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
51566
51627
  handler[COMPOSED_HANDLER] = r.handler;
51567
51628
  }
51568
- subApp.#addRoute(r.method, r.path, handler);
51629
+ subApp.#addRoute(r.method, r.path, handler, r.basePath);
51569
51630
  });
51570
51631
  return this;
51571
51632
  }
@@ -51689,7 +51750,7 @@ var Hono = class _Hono {
51689
51750
  const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
51690
51751
  return (request) => {
51691
51752
  const url2 = new URL(request.url);
51692
- url2.pathname = url2.pathname.slice(pathPrefixLength) || "/";
51753
+ url2.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
51693
51754
  return new Request(url2, request);
51694
51755
  };
51695
51756
  })();
@@ -51703,10 +51764,15 @@ var Hono = class _Hono {
51703
51764
  this.#addRoute(METHOD_NAME_ALL, mergePath(path, "*"), handler);
51704
51765
  return this;
51705
51766
  }
51706
- #addRoute(method, path, handler) {
51767
+ #addRoute(method, path, handler, baseRoutePath) {
51707
51768
  method = method.toUpperCase();
51708
51769
  path = mergePath(this._basePath, path);
51709
- const r = { basePath: this._basePath, path, method, handler };
51770
+ const r = {
51771
+ basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
51772
+ path,
51773
+ method,
51774
+ handler
51775
+ };
51710
51776
  this.router.add(method, path, [handler, r]);
51711
51777
  this.routes.push(r);
51712
51778
  }
@@ -51821,7 +51887,7 @@ var Hono = class _Hono {
51821
51887
  };
51822
51888
  };
51823
51889
 
51824
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/matcher.js
51890
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/matcher.js
51825
51891
  var emptyParam = [];
51826
51892
  function match(method, path) {
51827
51893
  const matchers = this.buildAllMatchers();
@@ -51842,7 +51908,7 @@ function match(method, path) {
51842
51908
  return match2(method, path);
51843
51909
  }
51844
51910
 
51845
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/node.js
51911
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/node.js
51846
51912
  var LABEL_REG_EXP_STR = "[^/]+";
51847
51913
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
51848
51914
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
@@ -51950,7 +52016,7 @@ var Node = class _Node {
51950
52016
  }
51951
52017
  };
51952
52018
 
51953
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/trie.js
52019
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/trie.js
51954
52020
  var Trie = class {
51955
52021
  #context = { varIndex: 0 };
51956
52022
  #root = new Node();
@@ -52006,7 +52072,7 @@ var Trie = class {
52006
52072
  }
52007
52073
  };
52008
52074
 
52009
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/router.js
52075
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/router.js
52010
52076
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
52011
52077
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
52012
52078
  function buildWildcardRegExp(path) {
@@ -52185,7 +52251,7 @@ var RegExpRouter = class {
52185
52251
  }
52186
52252
  };
52187
52253
 
52188
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/smart-router/router.js
52254
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/smart-router/router.js
52189
52255
  var SmartRouter = class {
52190
52256
  name = "SmartRouter";
52191
52257
  #routers = [];
@@ -52240,7 +52306,7 @@ var SmartRouter = class {
52240
52306
  }
52241
52307
  };
52242
52308
 
52243
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/trie-router/node.js
52309
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/trie-router/node.js
52244
52310
  var emptyParams = /* @__PURE__ */ Object.create(null);
52245
52311
  var hasChildren = (children) => {
52246
52312
  for (const _ in children) {
@@ -52415,7 +52481,7 @@ var Node2 = class _Node2 {
52415
52481
  }
52416
52482
  };
52417
52483
 
52418
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/trie-router/router.js
52484
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/trie-router/router.js
52419
52485
  var TrieRouter = class {
52420
52486
  name = "TrieRouter";
52421
52487
  #node;
@@ -52437,7 +52503,7 @@ var TrieRouter = class {
52437
52503
  }
52438
52504
  };
52439
52505
 
52440
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/hono.js
52506
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/hono.js
52441
52507
  var Hono2 = class extends Hono {
52442
52508
  /**
52443
52509
  * Creates an instance of the Hono class.
@@ -52452,14 +52518,262 @@ var Hono2 = class extends Hono {
52452
52518
  }
52453
52519
  };
52454
52520
 
52455
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/compress.js
52456
- var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
52521
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/accept.js
52522
+ var isWhitespace = (char) => char === 32 || char === 9 || char === 10 || char === 13;
52523
+ var consumeWhitespace = (acceptHeader, startIndex) => {
52524
+ while (startIndex < acceptHeader.length) {
52525
+ if (!isWhitespace(acceptHeader.charCodeAt(startIndex))) {
52526
+ break;
52527
+ }
52528
+ startIndex++;
52529
+ }
52530
+ return startIndex;
52531
+ };
52532
+ var ignoreTrailingWhitespace = (acceptHeader, startIndex) => {
52533
+ while (startIndex > 0) {
52534
+ if (!isWhitespace(acceptHeader.charCodeAt(startIndex - 1))) {
52535
+ break;
52536
+ }
52537
+ startIndex--;
52538
+ }
52539
+ return startIndex;
52540
+ };
52541
+ var skipInvalidParam = (acceptHeader, startIndex) => {
52542
+ while (startIndex < acceptHeader.length) {
52543
+ const char = acceptHeader.charCodeAt(startIndex);
52544
+ if (char === 59) {
52545
+ return [startIndex + 1, true];
52546
+ }
52547
+ if (char === 44) {
52548
+ return [startIndex + 1, false];
52549
+ }
52550
+ startIndex++;
52551
+ }
52552
+ return [startIndex, false];
52553
+ };
52554
+ var skipInvalidAcceptValue = (acceptHeader, startIndex) => {
52555
+ let i = startIndex;
52556
+ let inQuotes = false;
52557
+ while (i < acceptHeader.length) {
52558
+ const char = acceptHeader.charCodeAt(i);
52559
+ if (inQuotes && char === 92) {
52560
+ i++;
52561
+ } else if (char === 34) {
52562
+ inQuotes = !inQuotes;
52563
+ } else if (!inQuotes && char === 44) {
52564
+ return i + 1;
52565
+ }
52566
+ i++;
52567
+ }
52568
+ return i;
52569
+ };
52570
+ var getNextParam = (acceptHeader, startIndex) => {
52571
+ startIndex = consumeWhitespace(acceptHeader, startIndex);
52572
+ let i = startIndex;
52573
+ let key;
52574
+ let value;
52575
+ let hasNext = false;
52576
+ while (i < acceptHeader.length) {
52577
+ const char = acceptHeader.charCodeAt(i);
52578
+ if (char === 61) {
52579
+ key = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
52580
+ i++;
52581
+ break;
52582
+ }
52583
+ if (char === 59) {
52584
+ return [i + 1, void 0, void 0, true];
52585
+ }
52586
+ if (char === 44) {
52587
+ return [i + 1, void 0, void 0, false];
52588
+ }
52589
+ i++;
52590
+ }
52591
+ if (key === void 0) {
52592
+ return [i, void 0, void 0, false];
52593
+ }
52594
+ i = consumeWhitespace(acceptHeader, i);
52595
+ if (acceptHeader.charCodeAt(i) === 61) {
52596
+ const skipResult = skipInvalidParam(acceptHeader, i + 1);
52597
+ return [skipResult[0], key, void 0, skipResult[1]];
52598
+ }
52599
+ let inQuotes = false;
52600
+ const paramStartIndex = i;
52601
+ while (i < acceptHeader.length) {
52602
+ const char = acceptHeader.charCodeAt(i);
52603
+ if (inQuotes && char === 92) {
52604
+ i++;
52605
+ } else if (char === 34) {
52606
+ if (inQuotes) {
52607
+ let nextIndex = consumeWhitespace(acceptHeader, i + 1);
52608
+ const nextChar = acceptHeader.charCodeAt(nextIndex);
52609
+ if (nextIndex < acceptHeader.length && !(nextChar === 59 || nextChar === 44)) {
52610
+ const skipResult = skipInvalidParam(acceptHeader, nextIndex);
52611
+ return [skipResult[0], key, void 0, skipResult[1]];
52612
+ }
52613
+ value = acceptHeader.slice(paramStartIndex + 1, i);
52614
+ if (value.includes("\\")) {
52615
+ value = value.replace(/\\(.)/g, "$1");
52616
+ }
52617
+ if (nextChar === 44) {
52618
+ return [nextIndex + 1, key, value, false];
52619
+ }
52620
+ if (nextChar === 59) {
52621
+ hasNext = true;
52622
+ nextIndex++;
52623
+ }
52624
+ i = nextIndex;
52625
+ break;
52626
+ }
52627
+ inQuotes = true;
52628
+ } else if (!inQuotes && (char === 59 || char === 44)) {
52629
+ value = acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i));
52630
+ if (char === 59) {
52631
+ hasNext = true;
52632
+ }
52633
+ i++;
52634
+ break;
52635
+ }
52636
+ i++;
52637
+ }
52638
+ return [
52639
+ i,
52640
+ key,
52641
+ value ?? acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i)),
52642
+ hasNext
52643
+ ];
52644
+ };
52645
+ var getNextAcceptValue = (acceptHeader, startIndex) => {
52646
+ const accept = {
52647
+ type: "",
52648
+ params: {},
52649
+ q: 1
52650
+ };
52651
+ startIndex = consumeWhitespace(acceptHeader, startIndex);
52652
+ let i = startIndex;
52653
+ while (i < acceptHeader.length) {
52654
+ const char = acceptHeader.charCodeAt(i);
52655
+ if (char === 59 || char === 44) {
52656
+ accept.type = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
52657
+ i++;
52658
+ if (char === 44) {
52659
+ return [i, accept.type ? accept : void 0];
52660
+ }
52661
+ if (!accept.type) {
52662
+ return [skipInvalidAcceptValue(acceptHeader, i), void 0];
52663
+ }
52664
+ break;
52665
+ }
52666
+ i++;
52667
+ }
52668
+ if (!accept.type) {
52669
+ accept.type = acceptHeader.slice(
52670
+ startIndex,
52671
+ ignoreTrailingWhitespace(acceptHeader, acceptHeader.length)
52672
+ );
52673
+ return [acceptHeader.length, accept.type ? accept : void 0];
52674
+ }
52675
+ let param;
52676
+ let value;
52677
+ let hasNext;
52678
+ while (i < acceptHeader.length) {
52679
+ ;
52680
+ [i, param, value, hasNext] = getNextParam(acceptHeader, i);
52681
+ if (param && value) {
52682
+ accept.params[param] = value;
52683
+ }
52684
+ if (!hasNext) {
52685
+ break;
52686
+ }
52687
+ }
52688
+ return [i, accept];
52689
+ };
52690
+ var parseAccept = (acceptHeader) => {
52691
+ if (!acceptHeader) {
52692
+ return [];
52693
+ }
52694
+ const values = [];
52695
+ let i = 0;
52696
+ let accept;
52697
+ let requiresSort = false;
52698
+ let lastAccept;
52699
+ while (i < acceptHeader.length) {
52700
+ ;
52701
+ [i, accept] = getNextAcceptValue(acceptHeader, i);
52702
+ if (accept) {
52703
+ accept.q = parseQuality(accept.params.q);
52704
+ values.push(accept);
52705
+ if (lastAccept && lastAccept.q < accept.q) {
52706
+ requiresSort = true;
52707
+ }
52708
+ lastAccept = accept;
52709
+ }
52710
+ }
52711
+ if (requiresSort) {
52712
+ values.sort((a, b) => b.q - a.q);
52713
+ }
52714
+ return values;
52715
+ };
52716
+ var parseQuality = (qVal) => {
52717
+ if (qVal === void 0) {
52718
+ return 1;
52719
+ }
52720
+ if (qVal === "") {
52721
+ return 1;
52722
+ }
52723
+ if (qVal === "NaN") {
52724
+ return 0;
52725
+ }
52726
+ const num = Number(qVal);
52727
+ if (num === Infinity) {
52728
+ return 1;
52729
+ }
52730
+ if (num === -Infinity) {
52731
+ return 0;
52732
+ }
52733
+ if (Number.isNaN(num)) {
52734
+ return 1;
52735
+ }
52736
+ if (num < 0 || num > 1) {
52737
+ return 1;
52738
+ }
52739
+ return num;
52740
+ };
52741
+
52742
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/compress.js
52743
+ var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|msgpack|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|vnd\.msgpack|wasm|x-httpd-php|x-javascript|x-msgpack|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml|msgpack))(?:[;\s]|$)/i;
52457
52744
 
52458
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/middleware/compress/index.js
52745
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/middleware/compress/index.js
52459
52746
  var ENCODING_TYPES = ["gzip", "deflate"];
52460
52747
  var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/i;
52748
+ var selectEncoding = (header, candidates) => {
52749
+ if (header === void 0) {
52750
+ return void 0;
52751
+ }
52752
+ const accepts = parseAccept(header);
52753
+ const wildcardQ = accepts.find((a) => a.type === "*")?.q;
52754
+ let best;
52755
+ for (const enc of candidates) {
52756
+ const explicit = accepts.find((a) => a.type.toLowerCase() === enc);
52757
+ const q = explicit ? explicit.q : wildcardQ ?? 0;
52758
+ if (q === 1) {
52759
+ return enc;
52760
+ } else if (q > 0 && (!best || q > best.q)) {
52761
+ best = { encoding: enc, q };
52762
+ }
52763
+ }
52764
+ return best?.encoding;
52765
+ };
52461
52766
  var compress = (options) => {
52462
52767
  const threshold = options?.threshold ?? 1024;
52768
+ const candidates = options?.encoding ? [options.encoding] : ENCODING_TYPES;
52769
+ const contentTypeFilter = options?.contentTypeFilter ?? COMPRESSIBLE_CONTENT_TYPE_REGEX;
52770
+ const shouldCompress = typeof contentTypeFilter === "function" ? (res) => {
52771
+ const type = res.headers.get("Content-Type");
52772
+ return type && contentTypeFilter(type);
52773
+ } : (res) => {
52774
+ const type = res.headers.get("Content-Type");
52775
+ return type && contentTypeFilter.test(type);
52776
+ };
52463
52777
  return async function compress2(ctx, next) {
52464
52778
  await next();
52465
52779
  const contentLength = ctx.res.headers.get("Content-Length");
@@ -52472,7 +52786,7 @@ var compress = (options) => {
52472
52786
  return;
52473
52787
  }
52474
52788
  const accepted = ctx.req.header("Accept-Encoding");
52475
- const encoding = options?.encoding ?? ENCODING_TYPES.find((encoding2) => accepted?.includes(encoding2));
52789
+ const encoding = selectEncoding(accepted, candidates);
52476
52790
  if (!encoding || !ctx.res.body) {
52477
52791
  return;
52478
52792
  }
@@ -52486,10 +52800,6 @@ var compress = (options) => {
52486
52800
  }
52487
52801
  };
52488
52802
  };
52489
- var shouldCompress = (res) => {
52490
- const type = res.headers.get("Content-Type");
52491
- return type && COMPRESSIBLE_CONTENT_TYPE_REGEX.test(type);
52492
- };
52493
52803
  var shouldTransform = (res) => {
52494
52804
  const cacheControl = res.headers.get("Cache-Control");
52495
52805
  return !cacheControl || !cacheControlNoTransformRegExp.test(cacheControl);
@@ -54824,14 +55134,14 @@ async function fetchRequestHandler(opts) {
54824
55134
  }));
54825
55135
  }
54826
55136
 
54827
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/helper/route/index.js
55137
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/route/index.js
54828
55138
  var matchedRoutes = (c) => (
54829
55139
  // @ts-expect-error c.req[GET_MATCH_RESULT] is not typed
54830
55140
  c.req[GET_MATCH_RESULT][0].map(([[, route]]) => route)
54831
55141
  );
54832
55142
  var routePath = (c, index2) => matchedRoutes(c).at(index2 ?? c.req.routeIndex)?.path ?? "";
54833
55143
 
54834
- // ../../node_modules/.pnpm/@hono+trpc-server@0.4.2_@trpc+server@11.16.0_typescript@5.9.3__hono@4.12.14/node_modules/@hono/trpc-server/dist/index.js
55144
+ // ../../node_modules/.pnpm/@hono+trpc-server@0.4.2_@trpc+server@11.16.0_typescript@5.9.3__hono@4.12.23/node_modules/@hono/trpc-server/dist/index.js
54835
55145
  var trpcServer = ({ endpoint, createContext: createContext2, ...rest }) => {
54836
55146
  const bodyProps = /* @__PURE__ */ new Set([
54837
55147
  "arrayBuffer",
@@ -56457,7 +56767,15 @@ var sessionsRouter = router({
56457
56767
  const rows = ctx.db.select({ status: chatSessions.status, count: sql`count(*)` }).from(chatSessions).where(and(
56458
56768
  notLike(chatSessions.id, `${SESSION_PREFIX.DASHBOARD}%`),
56459
56769
  notLike(chatSessions.id, `${SESSION_PREFIX.MONITORS}%`),
56460
- or(isNull(chatSessions.kind), ne(chatSessions.kind, SESSION_KIND.IMPORTED)),
56770
+ // Imported sessions are read-only and API sessions are driven headlessly by
56771
+ // external agents — neither should drive the "unviewed done" nav badge.
56772
+ or(
56773
+ isNull(chatSessions.kind),
56774
+ and(
56775
+ ne(chatSessions.kind, SESSION_KIND.IMPORTED),
56776
+ ne(chatSessions.kind, SESSION_KIND.API)
56777
+ )
56778
+ ),
56461
56779
  or(
56462
56780
  eq(chatSessions.status, "streaming"),
56463
56781
  eq(chatSessions.status, "done")
@@ -56673,16 +56991,13 @@ var appRouter = router({
56673
56991
  update: updateRouter
56674
56992
  });
56675
56993
 
56676
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/middleware/cors/index.js
56994
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/middleware/cors/index.js
56677
56995
  var cors = (options) => {
56678
- const defaults = {
56996
+ const opts = {
56679
56997
  origin: "*",
56680
56998
  allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
56681
56999
  allowHeaders: [],
56682
- exposeHeaders: []
56683
- };
56684
- const opts = {
56685
- ...defaults,
57000
+ exposeHeaders: [],
56686
57001
  ...options
56687
57002
  };
56688
57003
  const findAllowOrigin = ((optsOrigin) => {
@@ -56761,7 +57076,7 @@ var cors = (options) => {
56761
57076
  };
56762
57077
  };
56763
57078
 
56764
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/color.js
57079
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/color.js
56765
57080
  function getColorEnabled() {
56766
57081
  const { process: process3, Deno } = globalThis;
56767
57082
  const isNoColor = typeof Deno?.noColor === "boolean" ? Deno.noColor : process3 !== void 0 ? (
@@ -56783,7 +57098,7 @@ async function getColorEnabledAsync() {
56783
57098
  return !isNoColor;
56784
57099
  }
56785
57100
 
56786
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/middleware/logger/index.js
57101
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/middleware/logger/index.js
56787
57102
  var humanize = (times) => {
56788
57103
  const [delimiter, separator] = [",", "."];
56789
57104
  const orderTimes = times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + delimiter));
@@ -56832,7 +57147,7 @@ function applyMiddleware(app) {
56832
57147
  app.use("*", cors({ origin: CONFIG.corsOrigin ?? `http://localhost:${CONFIG.port}` }));
56833
57148
  }
56834
57149
 
56835
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/stream.js
57150
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/stream.js
56836
57151
  var StreamingApi = class {
56837
57152
  writer;
56838
57153
  encoder;
@@ -56861,7 +57176,9 @@ var StreamingApi = class {
56861
57176
  done ? controller.close() : controller.enqueue(value);
56862
57177
  },
56863
57178
  cancel: () => {
56864
- this.abort();
57179
+ if (!this.closed) {
57180
+ this.abort();
57181
+ }
56865
57182
  }
56866
57183
  });
56867
57184
  }
@@ -56883,11 +57200,11 @@ var StreamingApi = class {
56883
57200
  return new Promise((res) => setTimeout(res, ms));
56884
57201
  }
56885
57202
  async close() {
57203
+ this.closed = true;
56886
57204
  try {
56887
57205
  await this.writer.close();
56888
57206
  } catch {
56889
57207
  }
56890
- this.closed = true;
56891
57208
  }
56892
57209
  async pipe(body) {
56893
57210
  this.writer.releaseLock();
@@ -56909,7 +57226,7 @@ var StreamingApi = class {
56909
57226
  }
56910
57227
  };
56911
57228
 
56912
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/helper/streaming/utils.js
57229
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/streaming/utils.js
56913
57230
  var isOldBunVersion = () => {
56914
57231
  const version3 = typeof Bun !== "undefined" ? Bun.version : void 0;
56915
57232
  if (version3 === void 0) {
@@ -56920,7 +57237,7 @@ var isOldBunVersion = () => {
56920
57237
  return result;
56921
57238
  };
56922
57239
 
56923
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/helper/streaming/sse.js
57240
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/streaming/sse.js
56924
57241
  var SSEStreamingApi = class extends StreamingApi {
56925
57242
  constructor(writable, readable) {
56926
57243
  super(writable, readable);
@@ -58140,6 +58457,179 @@ function registerChatRoutes(app, context2) {
58140
58457
  });
58141
58458
  }
58142
58459
 
58460
+ // src/http/routes/api.ts
58461
+ var MAX_RESULT_CHARS = 4e3;
58462
+ function renderToolPart(p, queries) {
58463
+ const tool2 = p.type.replace(/^tool-/, "");
58464
+ const queryParts = (p.output?.parts ?? []).filter((x) => typeof x?.query === "string");
58465
+ const blocks = [];
58466
+ for (const qp of queryParts) {
58467
+ const query = qp.query ?? p.input?.query ?? "";
58468
+ queries.push({ tool: tool2, query, results: qp.results });
58469
+ let resultStr;
58470
+ try {
58471
+ resultStr = JSON.stringify(qp.results);
58472
+ } catch {
58473
+ resultStr = String(qp.results);
58474
+ }
58475
+ if (resultStr.length > MAX_RESULT_CHARS) {
58476
+ resultStr = `${resultStr.slice(0, MAX_RESULT_CHARS)} \u2026[truncated, full rows in queries]`;
58477
+ }
58478
+ blocks.push(`Query (${tool2}):
58479
+ \`\`\`
58480
+ ${query}
58481
+ \`\`\`
58482
+ Result:
58483
+ \`\`\`json
58484
+ ${resultStr}
58485
+ \`\`\``);
58486
+ }
58487
+ if (queryParts.length === 0 && p.output?.analysis) {
58488
+ const query = p.input?.query;
58489
+ if (query) queries.push({ tool: tool2, query, results: p.output.analysis });
58490
+ blocks.push(`Query (${tool2}):${query ? `
58491
+ \`\`\`
58492
+ ${query}
58493
+ \`\`\`` : ""}
58494
+ Result:
58495
+ ${p.output.analysis}`);
58496
+ }
58497
+ return blocks.join("\n\n");
58498
+ }
58499
+ function extractAnalysis(messages) {
58500
+ const assistantParts = [];
58501
+ for (const m of messages) {
58502
+ if (m.role !== "assistant") continue;
58503
+ for (const p of m.parts) assistantParts.push(p);
58504
+ }
58505
+ let markerIdx = -1;
58506
+ for (let i = assistantParts.length - 1; i >= 0; i--) {
58507
+ if (assistantParts[i].type === CLIENT_TOOL_NAMES.BEGIN_ANALYSIS) {
58508
+ markerIdx = i;
58509
+ break;
58510
+ }
58511
+ }
58512
+ const queries = [];
58513
+ const segments = [];
58514
+ if (markerIdx >= 0) {
58515
+ for (const p of assistantParts.slice(markerIdx + 1)) {
58516
+ if (p.type === "text") {
58517
+ if (p.text?.trim()) segments.push(p.text);
58518
+ } else if (p.type.startsWith("tool-") && p.type !== CLIENT_TOOL_NAMES.BEGIN_ANALYSIS) {
58519
+ const block = renderToolPart(p, queries);
58520
+ if (block) segments.push(block);
58521
+ }
58522
+ }
58523
+ } else {
58524
+ const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
58525
+ for (const p of lastAssistant?.parts ?? []) {
58526
+ if (p.type === "text" && p.text?.trim()) segments.push(p.text);
58527
+ }
58528
+ }
58529
+ return { analysis: segments.join("\n\n").trim(), queries };
58530
+ }
58531
+ function registerApiRoutes(app, context2) {
58532
+ app.post("/api/v1/analyze", async (c) => {
58533
+ let body;
58534
+ try {
58535
+ body = await c.req.json();
58536
+ } catch {
58537
+ return c.json({ status: "error", error: "invalid JSON body" }, 400);
58538
+ }
58539
+ const message = typeof body.message === "string" ? body.message.trim() : "";
58540
+ if (!message) {
58541
+ return c.json({ status: "error", error: "`message` is required" }, 400);
58542
+ }
58543
+ const sessionId = body.sessionId ?? crypto.randomUUID();
58544
+ const existing = context2.db.select({ id: chatSessions.id }).from(chatSessions).where(eq(chatSessions.id, sessionId)).get();
58545
+ if (!existing) {
58546
+ const now2 = unixNow();
58547
+ context2.db.insert(chatSessions).values({
58548
+ id: sessionId,
58549
+ title: DEFAULT_SESSION_TITLE,
58550
+ messages: "[]",
58551
+ status: "idle",
58552
+ kind: SESSION_KIND.API,
58553
+ createdAt: now2,
58554
+ updatedAt: now2
58555
+ }).run();
58556
+ }
58557
+ const userMessage = {
58558
+ id: crypto.randomUUID(),
58559
+ role: "user",
58560
+ parts: [{ type: "text", text: message }]
58561
+ };
58562
+ const messages = loadSessionMessages(context2.db, sessionId, userMessage);
58563
+ if (messages.length === 1) {
58564
+ generateSessionTitle(context2.db, sessionId, message);
58565
+ }
58566
+ const isUnified = !body.provider || body.provider === UNIFIED_SCOPE;
58567
+ const mode = isUnified ? "unified" : "direct";
58568
+ const scopedProvider = isUnified ? void 0 : body.provider;
58569
+ const modelOverride = mode === "direct" && scopedProvider ? resolveSubAgentModel(context2.db, scopedProvider) : void 0;
58570
+ let resolveDone = () => {
58571
+ };
58572
+ const result = await runChatAgent({
58573
+ sessionId,
58574
+ messages,
58575
+ context: context2,
58576
+ collectTools: (writer) => {
58577
+ const collected = collectChatTools(context2.providers, context2.db, writer, scopedProvider, mode);
58578
+ const orig = collected.afterComplete;
58579
+ return {
58580
+ ...collected,
58581
+ afterComplete: (params) => {
58582
+ orig?.(params);
58583
+ resolveDone();
58584
+ }
58585
+ };
58586
+ },
58587
+ sessionTitle: (updatedMessages) => {
58588
+ const firstUserMsg = updatedMessages.find((m) => m.role === "user");
58589
+ const textPart = firstUserMsg?.parts.find((p) => p.type === "text");
58590
+ return textPart ? textPart.text.slice(0, 60) : DEFAULT_SESSION_TITLE;
58591
+ },
58592
+ modelOverride: modelOverride && !("error" in modelOverride) ? modelOverride : void 0
58593
+ });
58594
+ if ("error" in result) {
58595
+ const status = result.error === "Session is already processing a response" ? 409 : 400;
58596
+ return c.json({ sessionId, status: "error", error: result.error }, status);
58597
+ }
58598
+ const PERSIST_GRACE_MS = 2e3;
58599
+ let pollHandle;
58600
+ let graceHandle;
58601
+ await new Promise((resolve4) => {
58602
+ resolveDone = resolve4;
58603
+ pollHandle = setInterval(() => {
58604
+ if (!context2.activeStreams.has(sessionId)) {
58605
+ clearInterval(pollHandle);
58606
+ graceHandle = setTimeout(resolve4, PERSIST_GRACE_MS);
58607
+ }
58608
+ }, 200);
58609
+ });
58610
+ clearInterval(pollHandle);
58611
+ clearTimeout(graceHandle);
58612
+ const row = context2.db.select().from(chatSessions).where(eq(chatSessions.id, sessionId)).get();
58613
+ let finalMessages = [];
58614
+ try {
58615
+ finalMessages = row ? JSON.parse(row.messages) : [];
58616
+ } catch {
58617
+ }
58618
+ const lastAssistant = [...finalMessages].reverse().find((m) => m.role === "assistant");
58619
+ const usage = lastAssistant?.usage ?? null;
58620
+ const model = usage?.model ?? null;
58621
+ const { analysis, queries } = extractAnalysis(finalMessages);
58622
+ return c.json({
58623
+ sessionId,
58624
+ status: row?.status ?? "done",
58625
+ analysis,
58626
+ queries,
58627
+ usage,
58628
+ model
58629
+ });
58630
+ });
58631
+ }
58632
+
58143
58633
  // src/http/static.ts
58144
58634
  import { readFileSync as readFileSync4, existsSync, statSync } from "fs";
58145
58635
  import { resolve as resolve3, dirname as dirname3, extname } from "path";
@@ -58196,6 +58686,7 @@ function createApp(context2) {
58196
58686
  applyMiddleware(app);
58197
58687
  app.get("/health", (c) => c.json({ status: "ok" }));
58198
58688
  registerChatRoutes(app, context2);
58689
+ registerApiRoutes(app, context2);
58199
58690
  app.use(
58200
58691
  "/api/trpc/*",
58201
58692
  trpcServer({