tracer-sh 0.2.1 → 0.2.3

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.
Files changed (23) hide show
  1. package/README.md +11 -1
  2. package/bin/tracer.mjs +58 -0
  3. package/package.json +7 -2
  4. package/packages/server/dist/{chunk-6QUU7TGZ.js → chunk-IKD3ICQK.js} +2 -0
  5. package/packages/server/dist/{chunk-OTYSD6PF.js → chunk-L7TO4UJ4.js} +2 -0
  6. package/packages/server/dist/{chunk-4VNS5WPM.js → chunk-WOL2ZWU7.js} +1 -0
  7. package/packages/server/dist/{chunk-7J2BYJNR.js → chunk-WUFQGSGW.js} +2 -1
  8. package/packages/server/dist/{chunk-5IQ4TST5.js → chunk-XFJVNMJI.js} +2 -0
  9. package/packages/server/dist/{domain-knowledge-WHIEZOOH.js → domain-knowledge-4AAER546.js} +3 -2
  10. package/packages/server/dist/{domain-knowledge-V6AENXZV.js → domain-knowledge-A3WXZ55R.js} +3 -2
  11. package/packages/server/dist/{domain-knowledge-5ZUPRLNB.js → domain-knowledge-CAD7MDFJ.js} +3 -2
  12. package/packages/server/dist/index.js +601 -77
  13. package/packages/server/dist/{token-4WRACUIQ.js → token-QV5VOVJ4.js} +3 -2
  14. package/packages/server/dist/token-util-DLXYCJR4.js +6 -0
  15. package/packages/web/dist/assets/{SearchableSelect-DGHfwNeM.js → SearchableSelect-DwcqGvga.js} +1 -1
  16. package/packages/web/dist/assets/{Settings-CM7N7YVW.js → Settings-V6P0atyS.js} +1 -1
  17. package/packages/web/dist/assets/{highlighted-body-OFNGDK62-CbmcR8p5.js → highlighted-body-OFNGDK62-BI81QblF.js} +1 -1
  18. package/packages/web/dist/assets/{index-DLQaH2AJ.css → index-CxrnanDH.css} +1 -1
  19. package/packages/web/dist/assets/index-XO-cs6YP.js +48 -0
  20. package/packages/web/dist/assets/{mermaid-GHXKKRXX-BCl4cq6r.js → mermaid-GHXKKRXX-mO3J4JDi.js} +3 -3
  21. package/packages/web/dist/index.html +2 -2
  22. package/packages/server/dist/token-util-NKFL6ZOU.js +0 -5
  23. package/packages/web/dist/assets/index-Chm2Gi5F.js +0 -48
@@ -1,30 +1,31 @@
1
+ import { createRequire as __createRequire } from 'module'; const require = __createRequire(import.meta.url);
1
2
  import {
2
3
  require_auth_errors,
3
4
  require_token_error,
4
5
  require_token_util
5
- } from "./chunk-7J2BYJNR.js";
6
+ } from "./chunk-WUFQGSGW.js";
6
7
  import {
7
8
  NR_AUTH_STOP_RULE,
8
9
  NR_DOMAIN_KNOWLEDGE,
9
10
  NR_INSIDE_OUT_DEBUGGING
10
- } from "./chunk-5IQ4TST5.js";
11
+ } from "./chunk-XFJVNMJI.js";
11
12
  import {
12
13
  GCP_AUTH_STOP_RULE,
13
14
  GCP_CROSS_SIGNAL,
14
15
  GCP_DOMAIN_KNOWLEDGE,
15
16
  GCP_INSIDE_OUT_DEBUGGING,
16
17
  GCP_PAGE_SIZE_RULE
17
- } from "./chunk-6QUU7TGZ.js";
18
+ } from "./chunk-IKD3ICQK.js";
18
19
  import {
19
20
  POSTHOG_AUTH_STOP_RULE,
20
21
  POSTHOG_DOMAIN_KNOWLEDGE,
21
22
  POSTHOG_INSIDE_OUT_DEBUGGING
22
- } from "./chunk-OTYSD6PF.js";
23
+ } from "./chunk-L7TO4UJ4.js";
23
24
  import {
24
25
  __commonJS,
25
26
  __export,
26
27
  __toESM
27
- } from "./chunk-4VNS5WPM.js";
28
+ } from "./chunk-WOL2ZWU7.js";
28
29
 
29
30
  // ../../node_modules/.pnpm/@vercel+oidc@3.2.0/node_modules/@vercel/oidc/dist/get-context.js
30
31
  var require_get_context = __commonJS({
@@ -100,8 +101,8 @@ var require_get_vercel_oidc_token = __commonJS({
100
101
  }
101
102
  try {
102
103
  const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([
103
- await import("./token-util-NKFL6ZOU.js"),
104
- await import("./token-4WRACUIQ.js")
104
+ await import("./token-util-DLXYCJR4.js"),
105
+ await import("./token-QV5VOVJ4.js")
105
106
  ]);
106
107
  if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
107
108
  await refreshToken(options);
@@ -170,7 +171,7 @@ var require_dist = __commonJS({
170
171
  }
171
172
  });
172
173
 
173
- // ../../node_modules/.pnpm/@hono+node-server@1.19.14_hono@4.12.14/node_modules/@hono/node-server/dist/index.mjs
174
+ // ../../node_modules/.pnpm/@hono+node-server@1.19.14_hono@4.12.23/node_modules/@hono/node-server/dist/index.mjs
174
175
  import { createServer as createServerHTTP } from "http";
175
176
  import { Http2ServerRequest as Http2ServerRequest2, constants as h2constants } from "http2";
176
177
  import { Http2ServerRequest } from "http2";
@@ -2758,7 +2759,8 @@ var SESSION_PREFIX = {
2758
2759
  MONITORS: "__monitors__"
2759
2760
  };
2760
2761
  var SESSION_KIND = {
2761
- IMPORTED: "imported"
2762
+ IMPORTED: "imported",
2763
+ API: "api"
2762
2764
  };
2763
2765
  function dashboardSessionId(dashboardId) {
2764
2766
  return `${SESSION_PREFIX.DASHBOARD}:${dashboardId}`;
@@ -16590,6 +16592,11 @@ var CONFIG = {
16590
16592
  restartExitCode: 75,
16591
16593
  // ── Updater ──
16592
16594
  npmViewTimeoutMs: 1e4,
16595
+ /** `npm install -g` can take a while (network + native rebuilds), so allow more headroom. */
16596
+ npmInstallTimeoutMs: 12e4,
16597
+ /** Buffer cap for `npm install -g` output; well above the 1MB default so a noisy
16598
+ * but successful install (native rebuild logs) isn't misreported as a failure. */
16599
+ npmInstallMaxBufferBytes: 16 * 1024 * 1024,
16593
16600
  // ── Dashboard defaults ──
16594
16601
  widgetDefaultWidth: 6,
16595
16602
  widgetDefaultHeight: 6,
@@ -16617,11 +16624,14 @@ function subAgentModelKey(providerType) {
16617
16624
  // src/updater.ts
16618
16625
  import { exec } from "child_process";
16619
16626
  import { readFileSync } from "fs";
16620
- import { join, dirname } from "path";
16627
+ import { join, dirname, sep } from "path";
16621
16628
  import { fileURLToPath } from "url";
16622
16629
  var RESTART_EXIT_CODE = CONFIG.restartExitCode;
16623
16630
  var cachedStatus = null;
16624
- function readCurrentVersion() {
16631
+ var cachedPackageInfo = null;
16632
+ function resolvePackage() {
16633
+ if (cachedPackageInfo) return cachedPackageInfo;
16634
+ let info = { root: null, version: "unknown" };
16625
16635
  try {
16626
16636
  const __dirname = dirname(fileURLToPath(import.meta.url));
16627
16637
  for (const candidate of [
@@ -16631,13 +16641,29 @@ function readCurrentVersion() {
16631
16641
  ]) {
16632
16642
  try {
16633
16643
  const pkg = JSON.parse(readFileSync(candidate, "utf-8"));
16634
- if (pkg.name === "tracer-sh" && pkg.version) return pkg.version;
16644
+ if (pkg.name === "tracer-sh" && pkg.version) {
16645
+ info = { root: dirname(candidate), version: pkg.version };
16646
+ break;
16647
+ }
16635
16648
  } catch {
16636
16649
  }
16637
16650
  }
16638
16651
  } catch {
16639
16652
  }
16640
- return "unknown";
16653
+ cachedPackageInfo = info;
16654
+ return info;
16655
+ }
16656
+ function readCurrentVersion() {
16657
+ return resolvePackage().version;
16658
+ }
16659
+ function detectInstallMethod(root) {
16660
+ if (!root) return "dev";
16661
+ if (root.includes(`${sep}_npx${sep}`)) return "npx";
16662
+ if (root.includes(`${sep}node_modules${sep}tracer-sh`)) return "global";
16663
+ return "dev";
16664
+ }
16665
+ function getInstallMethod() {
16666
+ return detectInstallMethod(resolvePackage().root);
16641
16667
  }
16642
16668
  function isNewerVersion(latest, current) {
16643
16669
  const parse4 = (v) => v.replace(/^v/, "").split(".").map(Number);
@@ -16664,29 +16690,66 @@ function getUpdateStatus() {
16664
16690
  return {
16665
16691
  available: false,
16666
16692
  currentVersion: readCurrentVersion(),
16667
- latestVersion: null
16693
+ latestVersion: null,
16694
+ method: getInstallMethod()
16668
16695
  };
16669
16696
  }
16670
16697
  function checkForUpdateBackground() {
16671
16698
  const current = readCurrentVersion();
16699
+ const method = getInstallMethod();
16700
+ const unavailable = () => ({ available: false, currentVersion: current, latestVersion: null, method });
16672
16701
  if (current === "unknown") {
16673
- cachedStatus = { available: false, currentVersion: current, latestVersion: null };
16702
+ cachedStatus = unavailable();
16674
16703
  return;
16675
16704
  }
16676
16705
  fetchLatestNpmVersion().then((latest) => {
16677
16706
  if (!latest) {
16678
- cachedStatus = { available: false, currentVersion: current, latestVersion: null };
16707
+ cachedStatus = unavailable();
16679
16708
  return;
16680
16709
  }
16681
16710
  const available = isNewerVersion(latest, current);
16682
- cachedStatus = { available, currentVersion: current, latestVersion: latest };
16711
+ cachedStatus = { available, currentVersion: current, latestVersion: latest, method };
16683
16712
  if (available) {
16684
- console.log(`Update available: v${current} \u2192 v${latest} (run: npm update -g tracer-sh)`);
16713
+ const hint = method === "global" ? "click the version in the sidebar to update from the app" : method === "npx" ? "re-run: npx tracer-sh@latest" : "git pull && pnpm install && pnpm build";
16714
+ console.log(`Update available: v${current} \u2192 v${latest} (${hint})`);
16685
16715
  }
16686
16716
  }).catch(() => {
16687
- cachedStatus = { available: false, currentVersion: current, latestVersion: null };
16717
+ cachedStatus = unavailable();
16718
+ });
16719
+ }
16720
+ function performSelfUpdate() {
16721
+ const method = getInstallMethod();
16722
+ if (method !== "global") {
16723
+ return Promise.resolve({
16724
+ ok: false,
16725
+ method,
16726
+ error: method === "npx" ? "Running via npx, which can't be updated in place. Re-run `npx tracer-sh@latest` to get the latest version." : "Running from a local source checkout, so in-app update is disabled."
16727
+ });
16728
+ }
16729
+ return new Promise((resolve4) => {
16730
+ exec(
16731
+ // Quiet flags keep output small (a verbose install can otherwise overflow
16732
+ // the stdout buffer and look like a failure); maxBuffer adds headroom for
16733
+ // native rebuild logs so a successful install is never misreported.
16734
+ "npm install -g tracer-sh@latest --no-fund --no-audit --loglevel=error",
16735
+ { encoding: "utf-8", timeout: CONFIG.npmInstallTimeoutMs, maxBuffer: CONFIG.npmInstallMaxBufferBytes },
16736
+ (err, _stdout, stderr) => {
16737
+ if (err) {
16738
+ resolve4({ ok: false, method, error: (stderr || "").trim() || err.message });
16739
+ return;
16740
+ }
16741
+ resolve4({ ok: true, method });
16742
+ }
16743
+ );
16688
16744
  });
16689
16745
  }
16746
+ var restartHandler = null;
16747
+ function setRestartHandler(fn) {
16748
+ restartHandler = fn;
16749
+ }
16750
+ function requestRestart() {
16751
+ restartHandler?.();
16752
+ }
16690
16753
 
16691
16754
  // src/db/client.ts
16692
16755
  import { homedir } from "os";
@@ -46133,9 +46196,9 @@ function createDeleteMemoryTool(memoryExecute, opts) {
46133
46196
 
46134
46197
  // src/agents/utility/memory-domain-knowledge.ts
46135
46198
  var DOMAIN_LOADERS = {
46136
- newrelic: async () => (await import("./domain-knowledge-WHIEZOOH.js")).NR_DOMAIN_KNOWLEDGE,
46137
- gcp: async () => (await import("./domain-knowledge-V6AENXZV.js")).GCP_DOMAIN_KNOWLEDGE,
46138
- posthog: async () => (await import("./domain-knowledge-5ZUPRLNB.js")).POSTHOG_DOMAIN_KNOWLEDGE
46199
+ newrelic: async () => (await import("./domain-knowledge-4AAER546.js")).NR_DOMAIN_KNOWLEDGE,
46200
+ gcp: async () => (await import("./domain-knowledge-A3WXZ55R.js")).GCP_DOMAIN_KNOWLEDGE,
46201
+ posthog: async () => (await import("./domain-knowledge-CAD7MDFJ.js")).POSTHOG_DOMAIN_KNOWLEDGE
46139
46202
  };
46140
46203
  async function getDomainKnowledge(providerType) {
46141
46204
  const loader = DOMAIN_LOADERS[providerType];
@@ -49594,14 +49657,14 @@ function fmtVal2(v) {
49594
49657
  function mdTable(headers, rows) {
49595
49658
  if (rows.length === 0) return "(empty)";
49596
49659
  const hdr = `| ${headers.join(" | ")} |`;
49597
- const sep = `| ${headers.map(() => "---").join(" | ")} |`;
49660
+ const sep2 = `| ${headers.map(() => "---").join(" | ")} |`;
49598
49661
  const body = rows.map(
49599
49662
  (r) => `| ${r.map(
49600
49663
  (c) => String(c).replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\n/g, " ")
49601
49664
  ).join(" | ")} |`
49602
49665
  ).join("\n");
49603
49666
  return `${hdr}
49604
- ${sep}
49667
+ ${sep2}
49605
49668
  ${body}`;
49606
49669
  }
49607
49670
  function trunc(s, max = 100) {
@@ -50444,7 +50507,7 @@ function createContext(deps) {
50444
50507
  };
50445
50508
  }
50446
50509
 
50447
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/compose.js
50510
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/compose.js
50448
50511
  var compose = (middleware, onError, onNotFound) => {
50449
50512
  return (context2, next) => {
50450
50513
  let index2 = -1;
@@ -50488,10 +50551,10 @@ var compose = (middleware, onError, onNotFound) => {
50488
50551
  };
50489
50552
  };
50490
50553
 
50491
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/request/constants.js
50554
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/request/constants.js
50492
50555
  var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
50493
50556
 
50494
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/body.js
50557
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/body.js
50495
50558
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
50496
50559
  const { all = false, dot = false } = options;
50497
50560
  const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
@@ -50563,7 +50626,7 @@ var handleParsingNestedValues = (form, key, value) => {
50563
50626
  });
50564
50627
  };
50565
50628
 
50566
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/url.js
50629
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/url.js
50567
50630
  var splitPath = (path) => {
50568
50631
  const paths = path.split("/");
50569
50632
  if (paths[0] === "") {
@@ -50767,7 +50830,7 @@ var getQueryParams = (url2, key) => {
50767
50830
  };
50768
50831
  var decodeURIComponent_ = decodeURIComponent;
50769
50832
 
50770
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/request.js
50833
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/request.js
50771
50834
  var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
50772
50835
  var HonoRequest = class {
50773
50836
  /**
@@ -50912,6 +50975,21 @@ var HonoRequest = class {
50912
50975
  arrayBuffer() {
50913
50976
  return this.#cachedBody("arrayBuffer");
50914
50977
  }
50978
+ /**
50979
+ * `.bytes()` parses the request body as a `Uint8Array`.
50980
+ *
50981
+ * @see {@link https://hono.dev/docs/api/request#bytes}
50982
+ *
50983
+ * @example
50984
+ * ```ts
50985
+ * app.post('/entry', async (c) => {
50986
+ * const body = await c.req.bytes()
50987
+ * })
50988
+ * ```
50989
+ */
50990
+ bytes() {
50991
+ return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
50992
+ }
50915
50993
  /**
50916
50994
  * Parses the request body as a `Blob`.
50917
50995
  * @example
@@ -51035,7 +51113,7 @@ var HonoRequest = class {
51035
51113
  }
51036
51114
  };
51037
51115
 
51038
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/html.js
51116
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/html.js
51039
51117
  var HtmlEscapedCallbackPhase = {
51040
51118
  Stringify: 1,
51041
51119
  BeforeStream: 2,
@@ -51077,7 +51155,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) =>
51077
51155
  }
51078
51156
  };
51079
51157
 
51080
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/context.js
51158
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/context.js
51081
51159
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
51082
51160
  var setDefaultContentType = (contentType, headers) => {
51083
51161
  return {
@@ -51484,7 +51562,7 @@ var Context = class {
51484
51562
  };
51485
51563
  };
51486
51564
 
51487
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router.js
51565
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router.js
51488
51566
  var METHOD_NAME_ALL = "ALL";
51489
51567
  var METHOD_NAME_ALL_LOWERCASE = "all";
51490
51568
  var METHODS = ["get", "post", "put", "delete", "options", "patch"];
@@ -51492,10 +51570,10 @@ var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is
51492
51570
  var UnsupportedPathError = class extends Error {
51493
51571
  };
51494
51572
 
51495
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/constants.js
51573
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/constants.js
51496
51574
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
51497
51575
 
51498
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/hono-base.js
51576
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/hono-base.js
51499
51577
  var notFoundHandler = (c) => {
51500
51578
  return c.text("404 Not Found", 404);
51501
51579
  };
@@ -51610,7 +51688,7 @@ var Hono = class _Hono {
51610
51688
  handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
51611
51689
  handler[COMPOSED_HANDLER] = r.handler;
51612
51690
  }
51613
- subApp.#addRoute(r.method, r.path, handler);
51691
+ subApp.#addRoute(r.method, r.path, handler, r.basePath);
51614
51692
  });
51615
51693
  return this;
51616
51694
  }
@@ -51734,7 +51812,7 @@ var Hono = class _Hono {
51734
51812
  const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
51735
51813
  return (request) => {
51736
51814
  const url2 = new URL(request.url);
51737
- url2.pathname = url2.pathname.slice(pathPrefixLength) || "/";
51815
+ url2.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
51738
51816
  return new Request(url2, request);
51739
51817
  };
51740
51818
  })();
@@ -51748,10 +51826,15 @@ var Hono = class _Hono {
51748
51826
  this.#addRoute(METHOD_NAME_ALL, mergePath(path, "*"), handler);
51749
51827
  return this;
51750
51828
  }
51751
- #addRoute(method, path, handler) {
51829
+ #addRoute(method, path, handler, baseRoutePath) {
51752
51830
  method = method.toUpperCase();
51753
51831
  path = mergePath(this._basePath, path);
51754
- const r = { basePath: this._basePath, path, method, handler };
51832
+ const r = {
51833
+ basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
51834
+ path,
51835
+ method,
51836
+ handler
51837
+ };
51755
51838
  this.router.add(method, path, [handler, r]);
51756
51839
  this.routes.push(r);
51757
51840
  }
@@ -51866,7 +51949,7 @@ var Hono = class _Hono {
51866
51949
  };
51867
51950
  };
51868
51951
 
51869
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/matcher.js
51952
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/matcher.js
51870
51953
  var emptyParam = [];
51871
51954
  function match(method, path) {
51872
51955
  const matchers = this.buildAllMatchers();
@@ -51887,7 +51970,7 @@ function match(method, path) {
51887
51970
  return match2(method, path);
51888
51971
  }
51889
51972
 
51890
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/node.js
51973
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/node.js
51891
51974
  var LABEL_REG_EXP_STR = "[^/]+";
51892
51975
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
51893
51976
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
@@ -51995,7 +52078,7 @@ var Node = class _Node {
51995
52078
  }
51996
52079
  };
51997
52080
 
51998
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/trie.js
52081
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/trie.js
51999
52082
  var Trie = class {
52000
52083
  #context = { varIndex: 0 };
52001
52084
  #root = new Node();
@@ -52051,7 +52134,7 @@ var Trie = class {
52051
52134
  }
52052
52135
  };
52053
52136
 
52054
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/reg-exp-router/router.js
52137
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/router.js
52055
52138
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
52056
52139
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
52057
52140
  function buildWildcardRegExp(path) {
@@ -52230,7 +52313,7 @@ var RegExpRouter = class {
52230
52313
  }
52231
52314
  };
52232
52315
 
52233
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/smart-router/router.js
52316
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/smart-router/router.js
52234
52317
  var SmartRouter = class {
52235
52318
  name = "SmartRouter";
52236
52319
  #routers = [];
@@ -52285,7 +52368,7 @@ var SmartRouter = class {
52285
52368
  }
52286
52369
  };
52287
52370
 
52288
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/trie-router/node.js
52371
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/trie-router/node.js
52289
52372
  var emptyParams = /* @__PURE__ */ Object.create(null);
52290
52373
  var hasChildren = (children) => {
52291
52374
  for (const _ in children) {
@@ -52460,7 +52543,7 @@ var Node2 = class _Node2 {
52460
52543
  }
52461
52544
  };
52462
52545
 
52463
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/router/trie-router/router.js
52546
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/trie-router/router.js
52464
52547
  var TrieRouter = class {
52465
52548
  name = "TrieRouter";
52466
52549
  #node;
@@ -52482,7 +52565,7 @@ var TrieRouter = class {
52482
52565
  }
52483
52566
  };
52484
52567
 
52485
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/hono.js
52568
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/hono.js
52486
52569
  var Hono2 = class extends Hono {
52487
52570
  /**
52488
52571
  * Creates an instance of the Hono class.
@@ -52497,14 +52580,262 @@ var Hono2 = class extends Hono {
52497
52580
  }
52498
52581
  };
52499
52582
 
52500
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/compress.js
52501
- 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;
52583
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/accept.js
52584
+ var isWhitespace = (char) => char === 32 || char === 9 || char === 10 || char === 13;
52585
+ var consumeWhitespace = (acceptHeader, startIndex) => {
52586
+ while (startIndex < acceptHeader.length) {
52587
+ if (!isWhitespace(acceptHeader.charCodeAt(startIndex))) {
52588
+ break;
52589
+ }
52590
+ startIndex++;
52591
+ }
52592
+ return startIndex;
52593
+ };
52594
+ var ignoreTrailingWhitespace = (acceptHeader, startIndex) => {
52595
+ while (startIndex > 0) {
52596
+ if (!isWhitespace(acceptHeader.charCodeAt(startIndex - 1))) {
52597
+ break;
52598
+ }
52599
+ startIndex--;
52600
+ }
52601
+ return startIndex;
52602
+ };
52603
+ var skipInvalidParam = (acceptHeader, startIndex) => {
52604
+ while (startIndex < acceptHeader.length) {
52605
+ const char = acceptHeader.charCodeAt(startIndex);
52606
+ if (char === 59) {
52607
+ return [startIndex + 1, true];
52608
+ }
52609
+ if (char === 44) {
52610
+ return [startIndex + 1, false];
52611
+ }
52612
+ startIndex++;
52613
+ }
52614
+ return [startIndex, false];
52615
+ };
52616
+ var skipInvalidAcceptValue = (acceptHeader, startIndex) => {
52617
+ let i = startIndex;
52618
+ let inQuotes = false;
52619
+ while (i < acceptHeader.length) {
52620
+ const char = acceptHeader.charCodeAt(i);
52621
+ if (inQuotes && char === 92) {
52622
+ i++;
52623
+ } else if (char === 34) {
52624
+ inQuotes = !inQuotes;
52625
+ } else if (!inQuotes && char === 44) {
52626
+ return i + 1;
52627
+ }
52628
+ i++;
52629
+ }
52630
+ return i;
52631
+ };
52632
+ var getNextParam = (acceptHeader, startIndex) => {
52633
+ startIndex = consumeWhitespace(acceptHeader, startIndex);
52634
+ let i = startIndex;
52635
+ let key;
52636
+ let value;
52637
+ let hasNext = false;
52638
+ while (i < acceptHeader.length) {
52639
+ const char = acceptHeader.charCodeAt(i);
52640
+ if (char === 61) {
52641
+ key = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
52642
+ i++;
52643
+ break;
52644
+ }
52645
+ if (char === 59) {
52646
+ return [i + 1, void 0, void 0, true];
52647
+ }
52648
+ if (char === 44) {
52649
+ return [i + 1, void 0, void 0, false];
52650
+ }
52651
+ i++;
52652
+ }
52653
+ if (key === void 0) {
52654
+ return [i, void 0, void 0, false];
52655
+ }
52656
+ i = consumeWhitespace(acceptHeader, i);
52657
+ if (acceptHeader.charCodeAt(i) === 61) {
52658
+ const skipResult = skipInvalidParam(acceptHeader, i + 1);
52659
+ return [skipResult[0], key, void 0, skipResult[1]];
52660
+ }
52661
+ let inQuotes = false;
52662
+ const paramStartIndex = i;
52663
+ while (i < acceptHeader.length) {
52664
+ const char = acceptHeader.charCodeAt(i);
52665
+ if (inQuotes && char === 92) {
52666
+ i++;
52667
+ } else if (char === 34) {
52668
+ if (inQuotes) {
52669
+ let nextIndex = consumeWhitespace(acceptHeader, i + 1);
52670
+ const nextChar = acceptHeader.charCodeAt(nextIndex);
52671
+ if (nextIndex < acceptHeader.length && !(nextChar === 59 || nextChar === 44)) {
52672
+ const skipResult = skipInvalidParam(acceptHeader, nextIndex);
52673
+ return [skipResult[0], key, void 0, skipResult[1]];
52674
+ }
52675
+ value = acceptHeader.slice(paramStartIndex + 1, i);
52676
+ if (value.includes("\\")) {
52677
+ value = value.replace(/\\(.)/g, "$1");
52678
+ }
52679
+ if (nextChar === 44) {
52680
+ return [nextIndex + 1, key, value, false];
52681
+ }
52682
+ if (nextChar === 59) {
52683
+ hasNext = true;
52684
+ nextIndex++;
52685
+ }
52686
+ i = nextIndex;
52687
+ break;
52688
+ }
52689
+ inQuotes = true;
52690
+ } else if (!inQuotes && (char === 59 || char === 44)) {
52691
+ value = acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i));
52692
+ if (char === 59) {
52693
+ hasNext = true;
52694
+ }
52695
+ i++;
52696
+ break;
52697
+ }
52698
+ i++;
52699
+ }
52700
+ return [
52701
+ i,
52702
+ key,
52703
+ value ?? acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i)),
52704
+ hasNext
52705
+ ];
52706
+ };
52707
+ var getNextAcceptValue = (acceptHeader, startIndex) => {
52708
+ const accept = {
52709
+ type: "",
52710
+ params: {},
52711
+ q: 1
52712
+ };
52713
+ startIndex = consumeWhitespace(acceptHeader, startIndex);
52714
+ let i = startIndex;
52715
+ while (i < acceptHeader.length) {
52716
+ const char = acceptHeader.charCodeAt(i);
52717
+ if (char === 59 || char === 44) {
52718
+ accept.type = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
52719
+ i++;
52720
+ if (char === 44) {
52721
+ return [i, accept.type ? accept : void 0];
52722
+ }
52723
+ if (!accept.type) {
52724
+ return [skipInvalidAcceptValue(acceptHeader, i), void 0];
52725
+ }
52726
+ break;
52727
+ }
52728
+ i++;
52729
+ }
52730
+ if (!accept.type) {
52731
+ accept.type = acceptHeader.slice(
52732
+ startIndex,
52733
+ ignoreTrailingWhitespace(acceptHeader, acceptHeader.length)
52734
+ );
52735
+ return [acceptHeader.length, accept.type ? accept : void 0];
52736
+ }
52737
+ let param;
52738
+ let value;
52739
+ let hasNext;
52740
+ while (i < acceptHeader.length) {
52741
+ ;
52742
+ [i, param, value, hasNext] = getNextParam(acceptHeader, i);
52743
+ if (param && value) {
52744
+ accept.params[param] = value;
52745
+ }
52746
+ if (!hasNext) {
52747
+ break;
52748
+ }
52749
+ }
52750
+ return [i, accept];
52751
+ };
52752
+ var parseAccept = (acceptHeader) => {
52753
+ if (!acceptHeader) {
52754
+ return [];
52755
+ }
52756
+ const values = [];
52757
+ let i = 0;
52758
+ let accept;
52759
+ let requiresSort = false;
52760
+ let lastAccept;
52761
+ while (i < acceptHeader.length) {
52762
+ ;
52763
+ [i, accept] = getNextAcceptValue(acceptHeader, i);
52764
+ if (accept) {
52765
+ accept.q = parseQuality(accept.params.q);
52766
+ values.push(accept);
52767
+ if (lastAccept && lastAccept.q < accept.q) {
52768
+ requiresSort = true;
52769
+ }
52770
+ lastAccept = accept;
52771
+ }
52772
+ }
52773
+ if (requiresSort) {
52774
+ values.sort((a, b) => b.q - a.q);
52775
+ }
52776
+ return values;
52777
+ };
52778
+ var parseQuality = (qVal) => {
52779
+ if (qVal === void 0) {
52780
+ return 1;
52781
+ }
52782
+ if (qVal === "") {
52783
+ return 1;
52784
+ }
52785
+ if (qVal === "NaN") {
52786
+ return 0;
52787
+ }
52788
+ const num = Number(qVal);
52789
+ if (num === Infinity) {
52790
+ return 1;
52791
+ }
52792
+ if (num === -Infinity) {
52793
+ return 0;
52794
+ }
52795
+ if (Number.isNaN(num)) {
52796
+ return 1;
52797
+ }
52798
+ if (num < 0 || num > 1) {
52799
+ return 1;
52800
+ }
52801
+ return num;
52802
+ };
52803
+
52804
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/compress.js
52805
+ 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;
52502
52806
 
52503
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/middleware/compress/index.js
52807
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/middleware/compress/index.js
52504
52808
  var ENCODING_TYPES = ["gzip", "deflate"];
52505
52809
  var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/i;
52810
+ var selectEncoding = (header, candidates) => {
52811
+ if (header === void 0) {
52812
+ return void 0;
52813
+ }
52814
+ const accepts = parseAccept(header);
52815
+ const wildcardQ = accepts.find((a) => a.type === "*")?.q;
52816
+ let best;
52817
+ for (const enc of candidates) {
52818
+ const explicit = accepts.find((a) => a.type.toLowerCase() === enc);
52819
+ const q = explicit ? explicit.q : wildcardQ ?? 0;
52820
+ if (q === 1) {
52821
+ return enc;
52822
+ } else if (q > 0 && (!best || q > best.q)) {
52823
+ best = { encoding: enc, q };
52824
+ }
52825
+ }
52826
+ return best?.encoding;
52827
+ };
52506
52828
  var compress = (options) => {
52507
52829
  const threshold = options?.threshold ?? 1024;
52830
+ const candidates = options?.encoding ? [options.encoding] : ENCODING_TYPES;
52831
+ const contentTypeFilter = options?.contentTypeFilter ?? COMPRESSIBLE_CONTENT_TYPE_REGEX;
52832
+ const shouldCompress = typeof contentTypeFilter === "function" ? (res) => {
52833
+ const type = res.headers.get("Content-Type");
52834
+ return type && contentTypeFilter(type);
52835
+ } : (res) => {
52836
+ const type = res.headers.get("Content-Type");
52837
+ return type && contentTypeFilter.test(type);
52838
+ };
52508
52839
  return async function compress2(ctx, next) {
52509
52840
  await next();
52510
52841
  const contentLength = ctx.res.headers.get("Content-Length");
@@ -52517,7 +52848,7 @@ var compress = (options) => {
52517
52848
  return;
52518
52849
  }
52519
52850
  const accepted = ctx.req.header("Accept-Encoding");
52520
- const encoding = options?.encoding ?? ENCODING_TYPES.find((encoding2) => accepted?.includes(encoding2));
52851
+ const encoding = selectEncoding(accepted, candidates);
52521
52852
  if (!encoding || !ctx.res.body) {
52522
52853
  return;
52523
52854
  }
@@ -52531,10 +52862,6 @@ var compress = (options) => {
52531
52862
  }
52532
52863
  };
52533
52864
  };
52534
- var shouldCompress = (res) => {
52535
- const type = res.headers.get("Content-Type");
52536
- return type && COMPRESSIBLE_CONTENT_TYPE_REGEX.test(type);
52537
- };
52538
52865
  var shouldTransform = (res) => {
52539
52866
  const cacheControl = res.headers.get("Cache-Control");
52540
52867
  return !cacheControl || !cacheControlNoTransformRegExp.test(cacheControl);
@@ -54869,14 +55196,14 @@ async function fetchRequestHandler(opts) {
54869
55196
  }));
54870
55197
  }
54871
55198
 
54872
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/helper/route/index.js
55199
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/route/index.js
54873
55200
  var matchedRoutes = (c) => (
54874
55201
  // @ts-expect-error c.req[GET_MATCH_RESULT] is not typed
54875
55202
  c.req[GET_MATCH_RESULT][0].map(([[, route]]) => route)
54876
55203
  );
54877
55204
  var routePath = (c, index2) => matchedRoutes(c).at(index2 ?? c.req.routeIndex)?.path ?? "";
54878
55205
 
54879
- // ../../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
55206
+ // ../../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
54880
55207
  var trpcServer = ({ endpoint, createContext: createContext2, ...rest }) => {
54881
55208
  const bodyProps = /* @__PURE__ */ new Set([
54882
55209
  "arrayBuffer",
@@ -56502,7 +56829,15 @@ var sessionsRouter = router({
56502
56829
  const rows = ctx.db.select({ status: chatSessions.status, count: sql`count(*)` }).from(chatSessions).where(and(
56503
56830
  notLike(chatSessions.id, `${SESSION_PREFIX.DASHBOARD}%`),
56504
56831
  notLike(chatSessions.id, `${SESSION_PREFIX.MONITORS}%`),
56505
- or(isNull(chatSessions.kind), ne(chatSessions.kind, SESSION_KIND.IMPORTED)),
56832
+ // Imported sessions are read-only and API sessions are driven headlessly by
56833
+ // external agents — neither should drive the "unviewed done" nav badge.
56834
+ or(
56835
+ isNull(chatSessions.kind),
56836
+ and(
56837
+ ne(chatSessions.kind, SESSION_KIND.IMPORTED),
56838
+ ne(chatSessions.kind, SESSION_KIND.API)
56839
+ )
56840
+ ),
56506
56841
  or(
56507
56842
  eq(chatSessions.status, "streaming"),
56508
56843
  eq(chatSessions.status, "done")
@@ -56700,8 +57035,21 @@ var updateRouter = router({
56700
57035
  return {
56701
57036
  available: status.available,
56702
57037
  currentVersion: status.currentVersion,
56703
- latestVersion: status.latestVersion
57038
+ latestVersion: status.latestVersion,
57039
+ method: status.method,
57040
+ // Only a global install can be upgraded in place from the app.
57041
+ canSelfUpdate: status.method === "global"
56704
57042
  };
57043
+ }),
57044
+ // Upgrade a global install in place, then trigger a graceful restart so the
57045
+ // launcher re-spawns the new server. The restart is deferred to the next tick
57046
+ // so this response flushes to the client before shutdown begins.
57047
+ perform: publicProcedure.mutation(async () => {
57048
+ const result = await performSelfUpdate();
57049
+ if (result.ok) {
57050
+ setImmediate(() => requestRestart());
57051
+ }
57052
+ return result;
56705
57053
  })
56706
57054
  });
56707
57055
 
@@ -56718,16 +57066,13 @@ var appRouter = router({
56718
57066
  update: updateRouter
56719
57067
  });
56720
57068
 
56721
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/middleware/cors/index.js
57069
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/middleware/cors/index.js
56722
57070
  var cors = (options) => {
56723
- const defaults = {
57071
+ const opts = {
56724
57072
  origin: "*",
56725
57073
  allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
56726
57074
  allowHeaders: [],
56727
- exposeHeaders: []
56728
- };
56729
- const opts = {
56730
- ...defaults,
57075
+ exposeHeaders: [],
56731
57076
  ...options
56732
57077
  };
56733
57078
  const findAllowOrigin = ((optsOrigin) => {
@@ -56806,7 +57151,7 @@ var cors = (options) => {
56806
57151
  };
56807
57152
  };
56808
57153
 
56809
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/color.js
57154
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/color.js
56810
57155
  function getColorEnabled() {
56811
57156
  const { process: process3, Deno } = globalThis;
56812
57157
  const isNoColor = typeof Deno?.noColor === "boolean" ? Deno.noColor : process3 !== void 0 ? (
@@ -56828,7 +57173,7 @@ async function getColorEnabledAsync() {
56828
57173
  return !isNoColor;
56829
57174
  }
56830
57175
 
56831
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/middleware/logger/index.js
57176
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/middleware/logger/index.js
56832
57177
  var humanize = (times) => {
56833
57178
  const [delimiter, separator] = [",", "."];
56834
57179
  const orderTimes = times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + delimiter));
@@ -56877,7 +57222,7 @@ function applyMiddleware(app) {
56877
57222
  app.use("*", cors({ origin: CONFIG.corsOrigin ?? `http://localhost:${CONFIG.port}` }));
56878
57223
  }
56879
57224
 
56880
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/stream.js
57225
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/stream.js
56881
57226
  var StreamingApi = class {
56882
57227
  writer;
56883
57228
  encoder;
@@ -56906,7 +57251,9 @@ var StreamingApi = class {
56906
57251
  done ? controller.close() : controller.enqueue(value);
56907
57252
  },
56908
57253
  cancel: () => {
56909
- this.abort();
57254
+ if (!this.closed) {
57255
+ this.abort();
57256
+ }
56910
57257
  }
56911
57258
  });
56912
57259
  }
@@ -56928,11 +57275,11 @@ var StreamingApi = class {
56928
57275
  return new Promise((res) => setTimeout(res, ms));
56929
57276
  }
56930
57277
  async close() {
57278
+ this.closed = true;
56931
57279
  try {
56932
57280
  await this.writer.close();
56933
57281
  } catch {
56934
57282
  }
56935
- this.closed = true;
56936
57283
  }
56937
57284
  async pipe(body) {
56938
57285
  this.writer.releaseLock();
@@ -56954,7 +57301,7 @@ var StreamingApi = class {
56954
57301
  }
56955
57302
  };
56956
57303
 
56957
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/helper/streaming/utils.js
57304
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/streaming/utils.js
56958
57305
  var isOldBunVersion = () => {
56959
57306
  const version3 = typeof Bun !== "undefined" ? Bun.version : void 0;
56960
57307
  if (version3 === void 0) {
@@ -56965,7 +57312,7 @@ var isOldBunVersion = () => {
56965
57312
  return result;
56966
57313
  };
56967
57314
 
56968
- // ../../node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/helper/streaming/sse.js
57315
+ // ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/streaming/sse.js
56969
57316
  var SSEStreamingApi = class extends StreamingApi {
56970
57317
  constructor(writable, readable) {
56971
57318
  super(writable, readable);
@@ -58185,6 +58532,179 @@ function registerChatRoutes(app, context2) {
58185
58532
  });
58186
58533
  }
58187
58534
 
58535
+ // src/http/routes/api.ts
58536
+ var MAX_RESULT_CHARS = 4e3;
58537
+ function renderToolPart(p, queries) {
58538
+ const tool2 = p.type.replace(/^tool-/, "");
58539
+ const queryParts = (p.output?.parts ?? []).filter((x) => typeof x?.query === "string");
58540
+ const blocks = [];
58541
+ for (const qp of queryParts) {
58542
+ const query = qp.query ?? p.input?.query ?? "";
58543
+ queries.push({ tool: tool2, query, results: qp.results });
58544
+ let resultStr;
58545
+ try {
58546
+ resultStr = JSON.stringify(qp.results);
58547
+ } catch {
58548
+ resultStr = String(qp.results);
58549
+ }
58550
+ if (resultStr.length > MAX_RESULT_CHARS) {
58551
+ resultStr = `${resultStr.slice(0, MAX_RESULT_CHARS)} \u2026[truncated, full rows in queries]`;
58552
+ }
58553
+ blocks.push(`Query (${tool2}):
58554
+ \`\`\`
58555
+ ${query}
58556
+ \`\`\`
58557
+ Result:
58558
+ \`\`\`json
58559
+ ${resultStr}
58560
+ \`\`\``);
58561
+ }
58562
+ if (queryParts.length === 0 && p.output?.analysis) {
58563
+ const query = p.input?.query;
58564
+ if (query) queries.push({ tool: tool2, query, results: p.output.analysis });
58565
+ blocks.push(`Query (${tool2}):${query ? `
58566
+ \`\`\`
58567
+ ${query}
58568
+ \`\`\`` : ""}
58569
+ Result:
58570
+ ${p.output.analysis}`);
58571
+ }
58572
+ return blocks.join("\n\n");
58573
+ }
58574
+ function extractAnalysis(messages) {
58575
+ const assistantParts = [];
58576
+ for (const m of messages) {
58577
+ if (m.role !== "assistant") continue;
58578
+ for (const p of m.parts) assistantParts.push(p);
58579
+ }
58580
+ let markerIdx = -1;
58581
+ for (let i = assistantParts.length - 1; i >= 0; i--) {
58582
+ if (assistantParts[i].type === CLIENT_TOOL_NAMES.BEGIN_ANALYSIS) {
58583
+ markerIdx = i;
58584
+ break;
58585
+ }
58586
+ }
58587
+ const queries = [];
58588
+ const segments = [];
58589
+ if (markerIdx >= 0) {
58590
+ for (const p of assistantParts.slice(markerIdx + 1)) {
58591
+ if (p.type === "text") {
58592
+ if (p.text?.trim()) segments.push(p.text);
58593
+ } else if (p.type.startsWith("tool-") && p.type !== CLIENT_TOOL_NAMES.BEGIN_ANALYSIS) {
58594
+ const block = renderToolPart(p, queries);
58595
+ if (block) segments.push(block);
58596
+ }
58597
+ }
58598
+ } else {
58599
+ const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
58600
+ for (const p of lastAssistant?.parts ?? []) {
58601
+ if (p.type === "text" && p.text?.trim()) segments.push(p.text);
58602
+ }
58603
+ }
58604
+ return { analysis: segments.join("\n\n").trim(), queries };
58605
+ }
58606
+ function registerApiRoutes(app, context2) {
58607
+ app.post("/api/v1/analyze", async (c) => {
58608
+ let body;
58609
+ try {
58610
+ body = await c.req.json();
58611
+ } catch {
58612
+ return c.json({ status: "error", error: "invalid JSON body" }, 400);
58613
+ }
58614
+ const message = typeof body.message === "string" ? body.message.trim() : "";
58615
+ if (!message) {
58616
+ return c.json({ status: "error", error: "`message` is required" }, 400);
58617
+ }
58618
+ const sessionId = body.sessionId ?? crypto.randomUUID();
58619
+ const existing = context2.db.select({ id: chatSessions.id }).from(chatSessions).where(eq(chatSessions.id, sessionId)).get();
58620
+ if (!existing) {
58621
+ const now2 = unixNow();
58622
+ context2.db.insert(chatSessions).values({
58623
+ id: sessionId,
58624
+ title: DEFAULT_SESSION_TITLE,
58625
+ messages: "[]",
58626
+ status: "idle",
58627
+ kind: SESSION_KIND.API,
58628
+ createdAt: now2,
58629
+ updatedAt: now2
58630
+ }).run();
58631
+ }
58632
+ const userMessage = {
58633
+ id: crypto.randomUUID(),
58634
+ role: "user",
58635
+ parts: [{ type: "text", text: message }]
58636
+ };
58637
+ const messages = loadSessionMessages(context2.db, sessionId, userMessage);
58638
+ if (messages.length === 1) {
58639
+ generateSessionTitle(context2.db, sessionId, message);
58640
+ }
58641
+ const isUnified = !body.provider || body.provider === UNIFIED_SCOPE;
58642
+ const mode = isUnified ? "unified" : "direct";
58643
+ const scopedProvider = isUnified ? void 0 : body.provider;
58644
+ const modelOverride = mode === "direct" && scopedProvider ? resolveSubAgentModel(context2.db, scopedProvider) : void 0;
58645
+ let resolveDone = () => {
58646
+ };
58647
+ const result = await runChatAgent({
58648
+ sessionId,
58649
+ messages,
58650
+ context: context2,
58651
+ collectTools: (writer) => {
58652
+ const collected = collectChatTools(context2.providers, context2.db, writer, scopedProvider, mode);
58653
+ const orig = collected.afterComplete;
58654
+ return {
58655
+ ...collected,
58656
+ afterComplete: (params) => {
58657
+ orig?.(params);
58658
+ resolveDone();
58659
+ }
58660
+ };
58661
+ },
58662
+ sessionTitle: (updatedMessages) => {
58663
+ const firstUserMsg = updatedMessages.find((m) => m.role === "user");
58664
+ const textPart = firstUserMsg?.parts.find((p) => p.type === "text");
58665
+ return textPart ? textPart.text.slice(0, 60) : DEFAULT_SESSION_TITLE;
58666
+ },
58667
+ modelOverride: modelOverride && !("error" in modelOverride) ? modelOverride : void 0
58668
+ });
58669
+ if ("error" in result) {
58670
+ const status = result.error === "Session is already processing a response" ? 409 : 400;
58671
+ return c.json({ sessionId, status: "error", error: result.error }, status);
58672
+ }
58673
+ const PERSIST_GRACE_MS = 2e3;
58674
+ let pollHandle;
58675
+ let graceHandle;
58676
+ await new Promise((resolve4) => {
58677
+ resolveDone = resolve4;
58678
+ pollHandle = setInterval(() => {
58679
+ if (!context2.activeStreams.has(sessionId)) {
58680
+ clearInterval(pollHandle);
58681
+ graceHandle = setTimeout(resolve4, PERSIST_GRACE_MS);
58682
+ }
58683
+ }, 200);
58684
+ });
58685
+ clearInterval(pollHandle);
58686
+ clearTimeout(graceHandle);
58687
+ const row = context2.db.select().from(chatSessions).where(eq(chatSessions.id, sessionId)).get();
58688
+ let finalMessages = [];
58689
+ try {
58690
+ finalMessages = row ? JSON.parse(row.messages) : [];
58691
+ } catch {
58692
+ }
58693
+ const lastAssistant = [...finalMessages].reverse().find((m) => m.role === "assistant");
58694
+ const usage = lastAssistant?.usage ?? null;
58695
+ const model = usage?.model ?? null;
58696
+ const { analysis, queries } = extractAnalysis(finalMessages);
58697
+ return c.json({
58698
+ sessionId,
58699
+ status: row?.status ?? "done",
58700
+ analysis,
58701
+ queries,
58702
+ usage,
58703
+ model
58704
+ });
58705
+ });
58706
+ }
58707
+
58188
58708
  // src/http/static.ts
58189
58709
  import { readFileSync as readFileSync4, existsSync, statSync } from "fs";
58190
58710
  import { resolve as resolve3, dirname as dirname3, extname } from "path";
@@ -58241,6 +58761,7 @@ function createApp(context2) {
58241
58761
  applyMiddleware(app);
58242
58762
  app.get("/health", (c) => c.json({ status: "ok" }));
58243
58763
  registerChatRoutes(app, context2);
58764
+ registerApiRoutes(app, context2);
58244
58765
  app.use(
58245
58766
  "/api/trpc/*",
58246
58767
  trpcServer({
@@ -58384,19 +58905,22 @@ Port ${CONFIG.port} is already in use. Run: lsof -ti :${CONFIG.port} | xargs kil
58384
58905
  }
58385
58906
  process.exit(1);
58386
58907
  });
58387
- const shutdown = async () => {
58388
- const timeout = setTimeout(() => process.exit(1), CONFIG.shutdownGracePeriodMs);
58908
+ const shutdown = async (code = 0) => {
58909
+ const timeout = setTimeout(() => process.exit(code === 0 ? 1 : code), CONFIG.shutdownGracePeriodMs);
58389
58910
  await scheduler.stop();
58390
58911
  for (const p of providers.getAllProviders()) {
58391
58912
  await p.dispose().catch(() => {
58392
58913
  });
58393
58914
  }
58394
58915
  clearTimeout(timeout);
58395
- process.exit(0);
58916
+ process.exit(code);
58396
58917
  };
58397
- process.on("SIGINT", shutdown);
58398
- process.on("SIGTERM", shutdown);
58399
- process.on("SIGHUP", shutdown);
58918
+ process.on("SIGINT", () => shutdown());
58919
+ process.on("SIGTERM", () => shutdown());
58920
+ process.on("SIGHUP", () => shutdown());
58921
+ setRestartHandler(() => {
58922
+ void shutdown(CONFIG.restartExitCode);
58923
+ });
58400
58924
  }
58401
58925
  main().catch((err) => {
58402
58926
  console.error("Failed to start Tracer server:", err);