vibora 1.10.0 → 1.12.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.
Files changed (37) hide show
  1. package/bin/vibora.js +95 -208
  2. package/dist/assets/index-BiapsD8F.css +1 -0
  3. package/dist/assets/{index-DptSra7n.js → index-C4ahV9ZS.js} +62 -62
  4. package/dist/index.html +2 -2
  5. package/package.json +1 -1
  6. package/server/index.js +233 -88
  7. package/dist/assets/index-BMm5AnYN.js +0 -45
  8. package/dist/assets/index-BNhD6i8B.js +0 -45
  9. package/dist/assets/index-BfcOSnqG.css +0 -1
  10. package/dist/assets/index-Bj6X8q5U.js +0 -46
  11. package/dist/assets/index-BrWX1YZT.css +0 -1
  12. package/dist/assets/index-BxOt05pH.css +0 -1
  13. package/dist/assets/index-BxbgLbxS.css +0 -1
  14. package/dist/assets/index-ByL08tgg.js +0 -45
  15. package/dist/assets/index-C7bo3ECQ.css +0 -1
  16. package/dist/assets/index-CCtJOkVu.js +0 -116
  17. package/dist/assets/index-COn-Eyu7.css +0 -1
  18. package/dist/assets/index-ClQ5DUcr.js +0 -46
  19. package/dist/assets/index-Co_u49xL.css +0 -1
  20. package/dist/assets/index-D5T2n3lt.css +0 -1
  21. package/dist/assets/index-DCMXlbkM.css +0 -1
  22. package/dist/assets/index-DDBvX7Ij.css +0 -1
  23. package/dist/assets/index-DJxCuTf-.js +0 -45
  24. package/dist/assets/index-DP-OAlLv.js +0 -116
  25. package/dist/assets/index-DS5B_viR.js +0 -116
  26. package/dist/assets/index-DgP1TgfA.js +0 -45
  27. package/dist/assets/index-DijiKhVm.js +0 -46
  28. package/dist/assets/index-Djf_9c_I.css +0 -1
  29. package/dist/assets/index-Hcd8Y1ma.js +0 -45
  30. package/dist/assets/index-I_FT38E3.css +0 -1
  31. package/dist/assets/index-IdRTHnwv.js +0 -51
  32. package/dist/assets/index-QutiQrzr.js +0 -45
  33. package/dist/assets/index-ViklVZfD.js +0 -51
  34. package/dist/assets/index-Xk8D-HCD.css +0 -1
  35. package/dist/assets/index-f56gTmVJ.css +0 -1
  36. package/dist/assets/index-qBnZOT-E.js +0 -45
  37. package/dist/assets/index-r3_O3Fa_.js +0 -45
package/dist/index.html CHANGED
@@ -6,8 +6,8 @@
6
6
  <link rel="icon" type="image/png" sizes="512x512" href="/vibora-icon.png" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>Vibora</title>
9
- <script type="module" crossorigin src="/assets/index-DptSra7n.js"></script>
10
- <link rel="stylesheet" crossorigin href="/assets/index-D5T2n3lt.css">
9
+ <script type="module" crossorigin src="/assets/index-C4ahV9ZS.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-BiapsD8F.css">
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibora",
3
- "version": "1.10.0",
3
+ "version": "1.12.0",
4
4
  "description": "The Vibe Engineer's Cockpit",
5
5
  "license": "PolyForm-Shield-1.0.0",
6
6
  "repository": {
package/server/index.js CHANGED
@@ -3800,8 +3800,8 @@ var sessionAuthMiddleware = createMiddleware(async (c, next) => {
3800
3800
 
3801
3801
  // server/app.ts
3802
3802
  import { readFile as readFile2 } from "fs/promises";
3803
- import { join as join11 } from "path";
3804
- import { existsSync as existsSync10 } from "fs";
3803
+ import { join as join12 } from "path";
3804
+ import { existsSync as existsSync11 } from "fs";
3805
3805
 
3806
3806
  // server/routes/health.ts
3807
3807
  var app = new Hono2;
@@ -13812,6 +13812,30 @@ class BufferManager {
13812
13812
  }
13813
13813
 
13814
13814
  // server/terminal/terminal-session.ts
13815
+ var ZAI_ENV_VARS = [
13816
+ "ANTHROPIC_AUTH_TOKEN",
13817
+ "ANTHROPIC_BASE_URL",
13818
+ "API_TIMEOUT_MS",
13819
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL",
13820
+ "ANTHROPIC_DEFAULT_SONNET_MODEL",
13821
+ "ANTHROPIC_DEFAULT_OPUS_MODEL",
13822
+ "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"
13823
+ ];
13824
+ function getTerminalEnv() {
13825
+ const { PORT: _PORT, ...envWithoutPort } = process.env;
13826
+ const zaiSettings = getZAiSettings();
13827
+ if (zaiSettings.enabled) {
13828
+ return envWithoutPort;
13829
+ }
13830
+ const filtered = {};
13831
+ for (const [key, value] of Object.entries(envWithoutPort)) {
13832
+ if (!ZAI_ENV_VARS.includes(key) && value !== undefined) {
13833
+ filtered[key] = value;
13834
+ }
13835
+ }
13836
+ return filtered;
13837
+ }
13838
+
13815
13839
  class TerminalSession {
13816
13840
  id;
13817
13841
  _name;
@@ -13864,7 +13888,6 @@ class TerminalSession {
13864
13888
  start() {
13865
13889
  const dtach = getDtachService();
13866
13890
  const [cmd, ...args] = dtach.getCreateCommand(this.id);
13867
- const { PORT: _PORT, ...envWithoutPort } = process.env;
13868
13891
  try {
13869
13892
  this.pty = spawn(cmd, args, {
13870
13893
  name: "xterm-256color",
@@ -13872,7 +13895,7 @@ class TerminalSession {
13872
13895
  rows: this.rows,
13873
13896
  cwd: this.cwd,
13874
13897
  env: {
13875
- ...envWithoutPort,
13898
+ ...getTerminalEnv(),
13876
13899
  TERM: "xterm-256color",
13877
13900
  COLORTERM: "truecolor"
13878
13901
  }
@@ -13899,7 +13922,6 @@ class TerminalSession {
13899
13922
  }
13900
13923
  this.buffer.loadFromDisk();
13901
13924
  const [cmd, ...args] = dtach.getAttachCommand(this.id);
13902
- const { PORT: _PORT, ...envWithoutPort } = process.env;
13903
13925
  try {
13904
13926
  this.pty = spawn(cmd, args, {
13905
13927
  name: "xterm-256color",
@@ -13907,7 +13929,7 @@ class TerminalSession {
13907
13929
  rows: this.rows,
13908
13930
  cwd: this.cwd,
13909
13931
  env: {
13910
- ...envWithoutPort,
13932
+ ...getTerminalEnv(),
13911
13933
  TERM: "xterm-256color",
13912
13934
  COLORTERM: "truecolor"
13913
13935
  }
@@ -137647,24 +137669,6 @@ async function updateLinearTicketStatus(identifier, viboraStatus) {
137647
137669
  }
137648
137670
  }
137649
137671
 
137650
- // server/services/task-status.ts
137651
- async function updateTaskStatus(taskId, newStatus) {
137652
- const existing = db.select().from(tasks).where(eq(tasks.id, taskId)).get();
137653
- if (!existing)
137654
- return;
137655
- const oldStatus = existing.status;
137656
- if (oldStatus === newStatus)
137657
- return;
137658
- const now = new Date().toISOString();
137659
- db.update(tasks).set({ status: newStatus, updatedAt: now }).where(eq(tasks.id, taskId)).run();
137660
- broadcast({ type: "task:updated", payload: { taskId } });
137661
- if (existing.linearTicketId) {
137662
- updateLinearTicketStatus(existing.linearTicketId, newStatus).catch((err) => {
137663
- console.error(`Failed to update Linear ticket ${existing.linearTicketId}:`, err);
137664
- });
137665
- }
137666
- }
137667
-
137668
137672
  // server/services/notification-service.ts
137669
137673
  import { spawn as spawn2 } from "child_process";
137670
137674
  async function sendSoundNotification(config) {
@@ -137838,7 +137842,52 @@ async function testNotificationChannel(channel, settings) {
137838
137842
  }
137839
137843
  }
137840
137844
 
137845
+ // server/services/task-status.ts
137846
+ async function updateTaskStatus(taskId, newStatus, newPosition) {
137847
+ const existing = db.select().from(tasks).where(eq(tasks.id, taskId)).get();
137848
+ if (!existing)
137849
+ return null;
137850
+ const oldStatus = existing.status;
137851
+ const statusChanged = oldStatus !== newStatus;
137852
+ const now = new Date().toISOString();
137853
+ const updateData = {
137854
+ status: newStatus,
137855
+ updatedAt: now
137856
+ };
137857
+ if (newPosition !== undefined) {
137858
+ updateData.position = newPosition;
137859
+ }
137860
+ db.update(tasks).set(updateData).where(eq(tasks.id, taskId)).run();
137861
+ const updated = db.select().from(tasks).where(eq(tasks.id, taskId)).get();
137862
+ broadcast({ type: "task:updated", payload: { taskId } });
137863
+ if (statusChanged && updated) {
137864
+ if (existing.linearTicketId) {
137865
+ updateLinearTicketStatus(existing.linearTicketId, newStatus).catch((err) => {
137866
+ console.error(`Failed to update Linear ticket ${existing.linearTicketId}:`, err);
137867
+ });
137868
+ }
137869
+ if (newStatus === "IN_REVIEW") {
137870
+ sendNotification({
137871
+ title: "Task Ready for Review",
137872
+ message: `Task "${updated.title}" moved to review`,
137873
+ taskId: updated.id,
137874
+ taskTitle: updated.title,
137875
+ type: "task_status_change"
137876
+ });
137877
+ }
137878
+ if ((newStatus === "DONE" || newStatus === "CANCELED") && updated.worktreePath) {
137879
+ try {
137880
+ killClaudeInTerminalsForWorktree(updated.worktreePath);
137881
+ } catch (err) {
137882
+ console.error(`Failed to kill Claude in worktree ${updated.worktreePath}:`, err);
137883
+ }
137884
+ }
137885
+ }
137886
+ return updated ?? null;
137887
+ }
137888
+
137841
137889
  // server/routes/tasks.ts
137890
+ var __dirname = "/home/runner/work/vibora/vibora/server/routes";
137842
137891
  function createGitWorktree(repoPath, worktreePath, branch, baseBranch) {
137843
137892
  try {
137844
137893
  const worktreeParent = path5.dirname(worktreePath);
@@ -137911,29 +137960,8 @@ function copyFilesToWorktree(repoPath, worktreePath, patterns) {
137911
137960
  function initializeWorktreeForVibora(worktreePath) {
137912
137961
  const claudeLocalPath = path5.join(worktreePath, "CLAUDE.local.md");
137913
137962
  const gitignorePath = path5.join(worktreePath, ".gitignore");
137914
- const viboraSection = `
137915
- ## Vibora Task Management
137916
-
137917
- You are working inside a Vibora task worktree. Use the \`vibora\` CLI to manage this task:
137918
-
137919
- \`\`\`bash
137920
- # View current task info
137921
- vibora current-task
137922
-
137923
- # Associate a PR with this task (enables auto-completion when merged)
137924
- vibora current-task pr https://github.com/owner/repo/pull/123
137925
-
137926
- # Associate a Linear ticket with this task
137927
- vibora current-task linear https://linear.app/team/issue/TEAM-123
137928
-
137929
- # Update task status when work is complete
137930
- vibora current-task review # Ready for review
137931
- vibora current-task done # Task complete
137932
- \`\`\`
137933
-
137934
- When you create a PR for this work, run \`vibora current-task pr <url>\` to link it.
137935
- The task will automatically complete when the PR is merged.
137936
- `;
137963
+ const templatePath = path5.join(__dirname, "../templates/CLAUDE.local.template.md");
137964
+ const viboraSection = fs3.readFileSync(templatePath, "utf-8");
137937
137965
  let claudeContent = "";
137938
137966
  if (fs3.existsSync(claudeLocalPath)) {
137939
137967
  claudeContent = fs3.readFileSync(claudeLocalPath, "utf-8");
@@ -138147,37 +138175,7 @@ app2.patch("/:id/status", async (c) => {
138147
138175
  }
138148
138176
  }
138149
138177
  }
138150
- db.update(tasks).set({
138151
- status: newStatus,
138152
- position: newPosition,
138153
- updatedAt: now
138154
- }).where(eq(tasks.id, id)).run();
138155
- const updated = db.select().from(tasks).where(eq(tasks.id, id)).get();
138156
- broadcast({ type: "task:updated", payload: { taskId: id } });
138157
- if (oldStatus !== newStatus && existing.linearTicketId) {
138158
- updateLinearTicketStatus(existing.linearTicketId, newStatus).catch((err) => {
138159
- console.error("Failed to update Linear ticket status:", err);
138160
- });
138161
- }
138162
- if (oldStatus !== newStatus && updated) {
138163
- if (newStatus === "IN_REVIEW") {
138164
- sendNotification({
138165
- title: "Task Ready for Review",
138166
- message: `Task "${updated.title}" moved to review`,
138167
- taskId: updated.id,
138168
- taskTitle: updated.title,
138169
- type: "task_status_change"
138170
- });
138171
- } else if (newStatus === "DONE") {
138172
- sendNotification({
138173
- title: "Task Completed",
138174
- message: `Task "${updated.title}" marked as done`,
138175
- taskId: updated.id,
138176
- taskTitle: updated.title,
138177
- type: "task_status_change"
138178
- });
138179
- }
138180
- }
138178
+ const updated = await updateTaskStatus(id, newStatus, newPosition);
138181
138179
  return c.json(updated ? parseViewState(updated) : null);
138182
138180
  } catch (err) {
138183
138181
  return c.json({ error: err instanceof Error ? err.message : "Failed to update task status" }, 400);
@@ -139096,6 +139094,23 @@ app5.post("/notifications/test/:channel", async (c) => {
139096
139094
  const result = await testNotificationChannel(channel);
139097
139095
  return c.json(result);
139098
139096
  });
139097
+ app5.post("/notifications/send", async (c) => {
139098
+ try {
139099
+ const body = await c.req.json();
139100
+ if (!body.title || !body.message) {
139101
+ return c.json({ error: "title and message are required" }, 400);
139102
+ }
139103
+ const payload = {
139104
+ title: body.title,
139105
+ message: body.message,
139106
+ type: "task_status_change"
139107
+ };
139108
+ const results = await sendNotification(payload);
139109
+ return c.json({ success: true, results });
139110
+ } catch (err) {
139111
+ return c.json({ error: err instanceof Error ? err.message : "Failed to send notification" }, 400);
139112
+ }
139113
+ });
139099
139114
  app5.get("/z-ai", (c) => {
139100
139115
  const settings = getZAiSettings();
139101
139116
  return c.json(settings);
@@ -143580,8 +143595,10 @@ app12.get("/check", async (c) => {
143580
143595
  var auth_default = app12;
143581
143596
 
143582
143597
  // server/routes/monitoring.ts
143583
- import { readdirSync as readdirSync7, readFileSync as readFileSync7, readlinkSync as readlinkSync2 } from "fs";
143598
+ import { readdirSync as readdirSync7, readFileSync as readFileSync7, readlinkSync as readlinkSync2, existsSync as existsSync10 } from "fs";
143584
143599
  import { execSync as execSync5 } from "child_process";
143600
+ import { homedir as homedir5 } from "os";
143601
+ import { join as join11 } from "path";
143585
143602
 
143586
143603
  // server/services/metrics-collector.ts
143587
143604
  import os5 from "os";
@@ -144152,8 +144169,8 @@ function findViboraInstances() {
144152
144169
  const parentPid = getParentPid(pid);
144153
144170
  const cmdParts = cmdline.trim().split(/\s+/);
144154
144171
  const isBunProcess = cmdParts[0]?.includes("bun") ?? false;
144155
- const isDevBackend = isBunProcess && cmdline.includes("server/index.ts");
144156
- const isProdBackend = isBunProcess && !!env.VIBORA_PACKAGE_ROOT;
144172
+ const isDevBackend = isBunProcess && cmdline.includes("server/index.ts") && env.NODE_ENV !== "production";
144173
+ const isProdBackend = isBunProcess && (!!env.VIBORA_PACKAGE_ROOT || cmdline.includes("server/index.ts") && env.NODE_ENV === "production");
144157
144174
  if (isDevBackend || isProdBackend) {
144158
144175
  const port = parseInt(env.PORT || "3333", 10);
144159
144176
  const cwd = getProcessCwd(pid);
@@ -144256,13 +144273,141 @@ monitoringRoutes.post("/vibora-instances/:pid/kill", async (c) => {
144256
144273
  port: group.port
144257
144274
  });
144258
144275
  });
144276
+ var cachedUsage = null;
144277
+ var usageCacheTimestamp = 0;
144278
+ var USAGE_CACHE_MS = 15 * 1000;
144279
+ async function getClaudeOAuthToken() {
144280
+ const primaryPath = join11(homedir5(), ".claude", ".credentials.json");
144281
+ try {
144282
+ if (existsSync10(primaryPath)) {
144283
+ const content = readFileSync7(primaryPath, "utf-8");
144284
+ const config = JSON.parse(content);
144285
+ if (config.claudeAiOauth && typeof config.claudeAiOauth === "object") {
144286
+ const token = config.claudeAiOauth.accessToken;
144287
+ if (token && typeof token === "string" && token.startsWith("sk-ant-oat")) {
144288
+ return token;
144289
+ }
144290
+ }
144291
+ }
144292
+ } catch {}
144293
+ try {
144294
+ const result = execSync5('secret-tool lookup service "Claude Code"', {
144295
+ encoding: "utf-8",
144296
+ timeout: 5000,
144297
+ stdio: ["pipe", "pipe", "pipe"]
144298
+ });
144299
+ const token = result.trim();
144300
+ if (token && token.startsWith("sk-ant-oat")) {
144301
+ return token;
144302
+ }
144303
+ } catch {}
144304
+ return null;
144305
+ }
144306
+ async function fetchClaudeUsage(token) {
144307
+ try {
144308
+ const response = await fetch("https://api.anthropic.com/api/oauth/usage", {
144309
+ method: "GET",
144310
+ headers: {
144311
+ "Content-Type": "application/json",
144312
+ "User-Agent": "vibora/1.0.0",
144313
+ Authorization: `Bearer ${token}`,
144314
+ "anthropic-beta": "oauth-2025-04-20"
144315
+ }
144316
+ });
144317
+ if (!response.ok) {
144318
+ return { available: false, fiveHour: null, sevenDay: null, sevenDayOpus: null, sevenDaySonnet: null, error: `API returned ${response.status}` };
144319
+ }
144320
+ const data = await response.json();
144321
+ const parseBlock = (block) => {
144322
+ if (!block)
144323
+ return null;
144324
+ return {
144325
+ percentUsed: block.utilization ?? 0,
144326
+ resetAt: block.resets_at || new Date().toISOString(),
144327
+ isOverLimit: (block.utilization ?? 0) >= 100
144328
+ };
144329
+ };
144330
+ const fiveHour = parseBlock(data.five_hour);
144331
+ const sevenDay = parseBlock(data.seven_day);
144332
+ let fiveHourWithTime = null;
144333
+ if (fiveHour) {
144334
+ const now = new Date;
144335
+ const resetAt = new Date(fiveHour.resetAt);
144336
+ const timeRemainingMinutes = Math.max(0, Math.round((resetAt.getTime() - now.getTime()) / (1000 * 60)));
144337
+ fiveHourWithTime = { ...fiveHour, timeRemainingMinutes };
144338
+ }
144339
+ let sevenDayWithProgress = null;
144340
+ if (sevenDay) {
144341
+ const now = new Date;
144342
+ const resetAt = new Date(sevenDay.resetAt);
144343
+ const periodStart = new Date(resetAt);
144344
+ periodStart.setDate(periodStart.getDate() - 7);
144345
+ let weekProgressPercent;
144346
+ if (now > resetAt) {
144347
+ const newResetAt = new Date(resetAt);
144348
+ newResetAt.setDate(newResetAt.getDate() + 7);
144349
+ const totalMs = newResetAt.getTime() - resetAt.getTime();
144350
+ const elapsedMs = now.getTime() - resetAt.getTime();
144351
+ weekProgressPercent = Math.round(elapsedMs / totalMs * 100);
144352
+ } else {
144353
+ const totalMs = resetAt.getTime() - periodStart.getTime();
144354
+ const elapsedMs = now.getTime() - periodStart.getTime();
144355
+ weekProgressPercent = Math.max(0, Math.min(100, Math.round(elapsedMs / totalMs * 100)));
144356
+ }
144357
+ sevenDayWithProgress = { ...sevenDay, weekProgressPercent };
144358
+ }
144359
+ return {
144360
+ available: true,
144361
+ fiveHour: fiveHourWithTime,
144362
+ sevenDay: sevenDayWithProgress,
144363
+ sevenDayOpus: parseBlock(data.seven_day_opus ?? undefined),
144364
+ sevenDaySonnet: parseBlock(data.seven_day_sonnet ?? undefined)
144365
+ };
144366
+ } catch (err) {
144367
+ const message = err instanceof Error ? err.message : String(err);
144368
+ return { available: false, fiveHour: null, sevenDay: null, sevenDayOpus: null, sevenDaySonnet: null, error: message };
144369
+ }
144370
+ }
144371
+ monitoringRoutes.get("/claude-usage", async (c) => {
144372
+ const now = Date.now();
144373
+ const zaiSettings = getZAiSettings();
144374
+ if (zaiSettings.enabled && zaiSettings.apiKey) {
144375
+ const response = {
144376
+ available: false,
144377
+ fiveHour: null,
144378
+ sevenDay: null,
144379
+ sevenDayOpus: null,
144380
+ sevenDaySonnet: null,
144381
+ error: "Usage tracking is not available when using z.ai proxy. Check your z.ai dashboard at https://z.ai for usage statistics."
144382
+ };
144383
+ cachedUsage = response;
144384
+ usageCacheTimestamp = now;
144385
+ return c.json(response);
144386
+ }
144387
+ const token = await getClaudeOAuthToken();
144388
+ if (!token) {
144389
+ const response = {
144390
+ available: false,
144391
+ fiveHour: null,
144392
+ sevenDay: null,
144393
+ sevenDayOpus: null,
144394
+ sevenDaySonnet: null,
144395
+ error: "No Claude Code OAuth token found"
144396
+ };
144397
+ return c.json(response);
144398
+ }
144399
+ const usage = await fetchClaudeUsage(token);
144400
+ cachedUsage = usage;
144401
+ usageCacheTimestamp = now;
144402
+ return c.json(usage);
144403
+ });
144259
144404
 
144260
144405
  // server/app.ts
144261
144406
  function getDistPath() {
144262
144407
  if (process.env.VIBORA_PACKAGE_ROOT) {
144263
- return join11(process.env.VIBORA_PACKAGE_ROOT, "dist");
144408
+ return join12(process.env.VIBORA_PACKAGE_ROOT, "dist");
144264
144409
  }
144265
- return join11(process.cwd(), "dist");
144410
+ return join12(process.cwd(), "dist");
144266
144411
  }
144267
144412
  function createApp() {
144268
144413
  const app13 = new Hono2;
@@ -144309,8 +144454,8 @@ function createApp() {
144309
144454
  });
144310
144455
  };
144311
144456
  app13.get("/assets/*", async (c) => {
144312
- const assetPath = join11(distPath, c.req.path);
144313
- if (existsSync10(assetPath)) {
144457
+ const assetPath = join12(distPath, c.req.path);
144458
+ if (existsSync11(assetPath)) {
144314
144459
  return serveFile(assetPath);
144315
144460
  }
144316
144461
  return c.notFound();
@@ -144318,8 +144463,8 @@ function createApp() {
144318
144463
  const staticFiles = ["favicon.ico", "vibora-icon.png", "vibora-logo.jpeg", "vite.svg"];
144319
144464
  for (const file of staticFiles) {
144320
144465
  app13.get(`/${file}`, async () => {
144321
- const filePath = join11(distPath, file);
144322
- if (existsSync10(filePath)) {
144466
+ const filePath = join12(distPath, file);
144467
+ if (existsSync11(filePath)) {
144323
144468
  return serveFile(filePath);
144324
144469
  }
144325
144470
  return new Response("Not Found", { status: 404 });
@@ -144330,7 +144475,7 @@ function createApp() {
144330
144475
  if (path9.startsWith("/api/") || path9.startsWith("/ws/") || path9 === "/health") {
144331
144476
  return next();
144332
144477
  }
144333
- const html = await readFile2(join11(distPath, "index.html"), "utf-8");
144478
+ const html = await readFile2(join12(distPath, "index.html"), "utf-8");
144334
144479
  return c.html(html);
144335
144480
  });
144336
144481
  }