tarsk 0.4.26 → 0.4.27

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 (71) hide show
  1. package/dist/index.js +197 -51
  2. package/dist/public/assets/account-view-BFhjAYmz.js +1 -0
  3. package/dist/public/assets/alert-dialog--tUzAWFm.js +1 -0
  4. package/dist/public/assets/api-BBbysRIh.js +1 -0
  5. package/dist/public/assets/{browser-tab-BNkQAd5u.js → browser-tab-DlzO5cMP.js} +1 -1
  6. package/dist/public/assets/chat-input-container-B_qVOGzW.js +21 -0
  7. package/dist/public/assets/context-menu-D5slxFcc.js +1 -0
  8. package/dist/public/assets/conversation-history-view-B4zHwyrw.js +1 -0
  9. package/dist/public/assets/{dialogs-config-BEsTbY1C.js → dialogs-config-DZFG2IQM.js} +3 -3
  10. package/dist/public/assets/diff-view-fOVqrHQW.js +3 -0
  11. package/dist/public/assets/explorer-tab-view-MLrWJ1Y0.js +2 -0
  12. package/dist/public/assets/{explorer-tree-KuYjR6r9.js → explorer-tree-8TyBYuC7.js} +1 -1
  13. package/dist/public/assets/{explorer-view-Cj6fyxMP.js → explorer-view-5U70mfAJ.js} +1 -1
  14. package/dist/public/assets/history-view-BR8scGnM.js +1 -0
  15. package/dist/public/assets/index-0BuHfewk.css +1 -0
  16. package/dist/public/assets/index-BTbiyooe.js +37 -0
  17. package/dist/public/assets/mcp-server-card-DupwHcKT.js +1 -0
  18. package/dist/public/assets/onboarding-Cn5RqOCa.js +1 -0
  19. package/dist/public/assets/onboarding-dialog-BXsvjU1t.js +1 -0
  20. package/dist/public/assets/{page-toolbar-DM-x5q1_.js → page-toolbar-TvYsDwUY.js} +1 -1
  21. package/dist/public/assets/{project-settings-view-wkrbmymL.js → project-settings-view-C7GW_R0m.js} +1 -1
  22. package/dist/public/assets/providers-list-view-AVt5I1WB.js +1 -0
  23. package/dist/public/assets/radio-group-Mifbn8sU.js +1 -0
  24. package/dist/public/assets/react-vendor-Bao-KYKs.js +22 -0
  25. package/dist/public/assets/resizable-DzrIos_Y.js +1 -0
  26. package/dist/public/assets/{run-stop-button-CZ62jJDn.js → run-stop-button-k1LeM0M-.js} +2 -2
  27. package/dist/public/assets/settings-instructions-view-CgfWSPmK.js +1 -0
  28. package/dist/public/assets/settings-mcp-servers-view-Becs_RxN.js +5 -0
  29. package/dist/public/assets/settings-models-view-BqdD_7GR.js +1 -0
  30. package/dist/public/assets/settings-rules-view-D7j5OHUi.js +8 -0
  31. package/dist/public/assets/settings-skills-view-aPv03-bO.js +2 -0
  32. package/dist/public/assets/settings-slash-commands-view-DLMWXQXA.js +1 -0
  33. package/dist/public/assets/settings-subagents-view-DBYzNE4W.js +2 -0
  34. package/dist/public/assets/settings-view-CccwUKkf.js +2 -0
  35. package/dist/public/assets/{side-panel-container-DVnN8vFb.js → side-panel-container-oMcXib2A.js} +2 -2
  36. package/dist/public/assets/skeleton-Bc0U0oGc.js +1 -0
  37. package/dist/public/assets/{standard-list-item-ByRgCvKd.js → standard-list-item-D2lbPXa1.js} +1 -1
  38. package/dist/public/assets/{store-Dyy2UFdD.js → store-CwvBC-YP.js} +1 -1
  39. package/dist/public/assets/{tab-context-DBrXMyNd.js → tab-context-CCvlrC0o.js} +1 -1
  40. package/dist/public/assets/{tabs-DxQZhlZp.js → tabs-Mb_cjIfE.js} +1 -1
  41. package/dist/public/assets/{terminal-panel-COYGYBV5.js → terminal-panel-GuO2XygM.js} +2 -2
  42. package/dist/public/assets/{textarea-CUYwgm5q.js → textarea-DpXOZLt8.js} +1 -1
  43. package/dist/public/assets/todos-view-C4GMi1Np.js +1 -0
  44. package/dist/public/assets/{use-toast-BqYP6xbg.js → use-toast-DqmC-mB5.js} +1 -1
  45. package/dist/public/assets/{utils-BavofGRh.js → utils-Cy2s2TEb.js} +1 -1
  46. package/dist/public/assets/whisper-wasm-Clnf-l-9.js +2 -0
  47. package/dist/public/index.html +21 -20
  48. package/dist/public/wasm/libmain-CWYJvMY5.js +3318 -0
  49. package/dist/public/wasm/libmain-D9-QM3iM.mjs +3301 -0
  50. package/package.json +4 -3
  51. package/dist/public/assets/account-view-g3bIVa-z.js +0 -1
  52. package/dist/public/assets/alert-dialog-DXEB8gMn.js +0 -1
  53. package/dist/public/assets/api-DQLZE-zX.js +0 -1
  54. package/dist/public/assets/chat-input-container-C8o4YcJZ.js +0 -1
  55. package/dist/public/assets/context-menu-CThafUml.js +0 -1
  56. package/dist/public/assets/conversation-history-view-64T6FDPb.js +0 -1
  57. package/dist/public/assets/diff-view-DgR-WEkB.js +0 -3
  58. package/dist/public/assets/explorer-tab-view-B53xe5xM.js +0 -2
  59. package/dist/public/assets/history-view-_L50vkTM.js +0 -1
  60. package/dist/public/assets/index-CAoVFXj2.css +0 -1
  61. package/dist/public/assets/index-Q5OqmtNF.js +0 -50
  62. package/dist/public/assets/onboarding-C_q_uRK0.js +0 -1
  63. package/dist/public/assets/onboarding-dialog-Cum5S2wE.js +0 -1
  64. package/dist/public/assets/provider-details-view-jc3yYdzr.js +0 -1
  65. package/dist/public/assets/providers-sidebar-B796hXzU.js +0 -1
  66. package/dist/public/assets/react-vendor-QkuITxN7.js +0 -17
  67. package/dist/public/assets/resizable-GT3fWOfA.js +0 -1
  68. package/dist/public/assets/settings-view-BbL7i34u.js +0 -2
  69. package/dist/public/assets/todos-view-DB99PEKH.js +0 -1
  70. /package/dist/public/assets/{dist-CIGnaqp2.js → dist-BI23Ei33.js} +0 -0
  71. /package/dist/public/assets/{monaco-c-HyCuEi.js → monaco-DDfTQM3i.js} +0 -0
package/dist/index.js CHANGED
@@ -249,7 +249,7 @@ async function initializeSchema(db) {
249
249
  friendlyName TEXT NOT NULL,
250
250
  updatedAt TEXT NOT NULL,
251
251
  FOREIGN KEY (projectId) REFERENCES projects(id) ON DELETE CASCADE,
252
- UNIQUE(projectId, name)
252
+ UNIQUE(projectId, workspace, name)
253
253
  )
254
254
  `);
255
255
  await db.execute(`
@@ -364,8 +364,8 @@ async function runMigrations(db) {
364
364
  WHERE type='table' AND name='conversation_history'
365
365
  `);
366
366
  if (tableInfo.rows.length > 0) {
367
- const tableSql = tableInfo.rows[0].sql;
368
- if (!tableSql.includes("ON DELETE CASCADE")) {
367
+ const tableSql2 = tableInfo.rows[0].sql;
368
+ if (!tableSql2.includes("ON DELETE CASCADE")) {
369
369
  console.log(
370
370
  "[db] Running migration: Adding ON DELETE CASCADE to conversation_history.threadId foreign key"
371
371
  );
@@ -444,8 +444,8 @@ async function runMigrations(db) {
444
444
  WHERE type='table' AND name='threads'
445
445
  `);
446
446
  if (threadsTableInfo.rows.length > 0) {
447
- const tableSql = threadsTableInfo.rows[0].sql;
448
- if (!tableSql.includes("ON DELETE CASCADE")) {
447
+ const tableSql2 = threadsTableInfo.rows[0].sql;
448
+ if (!tableSql2.includes("ON DELETE CASCADE")) {
449
449
  console.log(
450
450
  "[db] Running migration: Adding ON DELETE CASCADE to threads.projectId foreign key"
451
451
  );
@@ -680,7 +680,31 @@ async function runMigrations(db) {
680
680
  friendlyName TEXT NOT NULL,
681
681
  updatedAt TEXT NOT NULL,
682
682
  FOREIGN KEY (projectId) REFERENCES projects(id) ON DELETE CASCADE,
683
- UNIQUE(projectId, name)
683
+ UNIQUE(projectId, workspace, name)
684
+ )
685
+ `);
686
+ await db.execute(`
687
+ CREATE INDEX idx_project_scripts_projectId ON project_scripts(projectId)
688
+ `);
689
+ }
690
+ const projectScriptsInfo = await db.execute(
691
+ `SELECT sql FROM sqlite_master WHERE type='table' AND name='project_scripts'`
692
+ );
693
+ const tableSql = projectScriptsInfo.rows[0];
694
+ if (projectScriptsInfo.rows.length > 0 && typeof tableSql["sql"] === "string" && tableSql["sql"].includes('UNIQUE("projectId", "name")')) {
695
+ console.log("[db] Running migration: Fixing project_scripts UNIQUE constraint");
696
+ await db.execute(`DROP TABLE IF EXISTS project_scripts`);
697
+ await db.execute(`
698
+ CREATE TABLE project_scripts (
699
+ id TEXT PRIMARY KEY,
700
+ projectId TEXT NOT NULL,
701
+ workspace TEXT NOT NULL,
702
+ name TEXT NOT NULL,
703
+ command TEXT NOT NULL,
704
+ friendlyName TEXT NOT NULL,
705
+ updatedAt TEXT NOT NULL,
706
+ FOREIGN KEY (projectId) REFERENCES projects(id) ON DELETE CASCADE,
707
+ UNIQUE(projectId, workspace, name)
684
708
  )
685
709
  `);
686
710
  await db.execute(`
@@ -792,7 +816,7 @@ function isValidPackageManager(value) {
792
816
 
793
817
  // src/server.ts
794
818
  import fs3 from "fs";
795
- import { Hono as Hono21 } from "hono";
819
+ import { Hono as Hono23 } from "hono";
796
820
  import { cors } from "hono/cors";
797
821
  import open3 from "open";
798
822
  import path4 from "path";
@@ -6577,7 +6601,8 @@ var ErrorCodes = {
6577
6601
  // Git operation errors
6578
6602
  DUPLICATE_BRANCH: "DUPLICATE_BRANCH",
6579
6603
  // General server errors
6580
- INTERNAL_ERROR: "INTERNAL_ERROR"
6604
+ INTERNAL_ERROR: "INTERNAL_ERROR",
6605
+ EXTERNAL_API_ERROR: "EXTERNAL_API_ERROR"
6581
6606
  };
6582
6607
 
6583
6608
  // src/features/ask-user/ask-user.routes.ts
@@ -13617,12 +13642,15 @@ var ProjectManagerImpl = class {
13617
13642
  const threads = await this.metadataManager.loadThreads();
13618
13643
  const remainingThreads = threads.filter((t) => t.projectId !== projectId);
13619
13644
  await this.metadataManager.saveThreads(remainingThreads);
13620
- try {
13621
- await rm3(project.path, { recursive: true, force: true });
13622
- } catch (error) {
13623
- throw new Error(
13624
- `Failed to remove project directory: ${error instanceof Error ? error.message : String(error)}`
13625
- );
13645
+ const isInsideDataDir = project.path.startsWith(this.rootFolder + "/");
13646
+ if (isInsideDataDir) {
13647
+ try {
13648
+ await rm3(project.path, { recursive: true, force: true });
13649
+ } catch (error) {
13650
+ throw new Error(
13651
+ `Failed to remove project directory: ${error instanceof Error ? error.message : String(error)}`
13652
+ );
13653
+ }
13626
13654
  }
13627
13655
  projects.splice(projectIndex, 1);
13628
13656
  await this.metadataManager.saveProjects(projects);
@@ -14013,6 +14041,9 @@ async function getProviders(c, metadataManager) {
14013
14041
  const envFileKey = keyName ? envFileKeys[keyName] : "";
14014
14042
  const processEnvKey = keyName ? process.env[keyName] : "";
14015
14043
  const storedKey = keys[catalogProvider.name] || keys[catalogId];
14044
+ const hasEnvKey = Boolean(envFileKey || processEnvKey);
14045
+ const resolvedKey = storedKey ?? envFileKey ?? processEnvKey ?? "";
14046
+ const isEnv = !storedKey && hasEnvKey && resolvedKey !== "";
14016
14047
  providersWithKeys.push({
14017
14048
  name: catalogProvider.name ?? catalogId,
14018
14049
  slug: catalogId,
@@ -14020,7 +14051,8 @@ async function getProviders(c, metadataManager) {
14020
14051
  keyName,
14021
14052
  authType: "APIKey",
14022
14053
  api: catalogProvider.api ?? "",
14023
- apiKey: storedKey ?? envFileKey ?? processEnvKey ?? ""
14054
+ apiKey: resolvedKey,
14055
+ isEnv
14024
14056
  });
14025
14057
  }
14026
14058
  }
@@ -14161,6 +14193,32 @@ async function getProviderCredits(c, metadataManager) {
14161
14193
  return c.json({ balance: null, status: "unknown" });
14162
14194
  }
14163
14195
 
14196
+ // src/features/providers/providers-get-logo.route.ts
14197
+ var LOGO_BASE_URL = "https://models.tarsk.io/svg";
14198
+ var SLUG_PATTERN = /^[a-z0-9._-]+$/i;
14199
+ async function getProviderLogo(c) {
14200
+ const slug = c.req.param("slug");
14201
+ if (!slug || !SLUG_PATTERN.test(slug)) {
14202
+ return c.body(null, 404);
14203
+ }
14204
+ try {
14205
+ const response = await fetch(`${LOGO_BASE_URL}/${slug}.svg`, { signal: AbortSignal.timeout(5e3) });
14206
+ if (!response.ok) {
14207
+ return c.body(null, 404);
14208
+ }
14209
+ const svg = await response.text();
14210
+ if (!svg.includes("<svg")) {
14211
+ return c.body(null, 404);
14212
+ }
14213
+ return c.body(svg, 200, {
14214
+ "Content-Type": "image/svg+xml",
14215
+ "Cache-Control": "public, max-age=86400"
14216
+ });
14217
+ } catch {
14218
+ return c.body(null, 404);
14219
+ }
14220
+ }
14221
+
14164
14222
  // src/features/providers/providers-open-external.route.ts
14165
14223
  var Utils2 = null;
14166
14224
  var utilsLoaded2 = false;
@@ -14205,6 +14263,7 @@ function createProviderRoutes(metadataManager) {
14205
14263
  router.post("/keys", (c) => postProviderKeys(c, metadataManager));
14206
14264
  router.post("/bulk-keys", (c) => postProviderBulkKeys(c, metadataManager));
14207
14265
  router.get("/:name/credits", (c) => getProviderCredits(c, metadataManager));
14266
+ router.get("/:slug/logo", (c) => getProviderLogo(c));
14208
14267
  router.post("/open-external", (c) => openExternalUrl(c));
14209
14268
  return router;
14210
14269
  }
@@ -15462,12 +15521,15 @@ var ThreadManagerImpl = class {
15462
15521
  throw new Error(`Thread not found: ${threadId}`);
15463
15522
  }
15464
15523
  const thread = threads[threadIndex];
15465
- try {
15466
- await rm4(thread.path, { recursive: true, force: true });
15467
- } catch (error) {
15468
- throw new Error(
15469
- `Failed to remove thread directory: ${error instanceof Error ? error.message : String(error)}`
15470
- );
15524
+ const isInsideDataDir = thread.path.startsWith(this.rootFolder + "/");
15525
+ if (isInsideDataDir) {
15526
+ try {
15527
+ await rm4(thread.path, { recursive: true, force: true });
15528
+ } catch (error) {
15529
+ throw new Error(
15530
+ `Failed to remove thread directory: ${error instanceof Error ? error.message : String(error)}`
15531
+ );
15532
+ }
15471
15533
  }
15472
15534
  threads.splice(threadIndex, 1);
15473
15535
  await this.metadataManager.saveThreads(threads);
@@ -16804,15 +16866,17 @@ async function handleOpenThread(c, threadManager) {
16804
16866
  }
16805
16867
 
16806
16868
  // src/features/threads/threads-conversation-folder-path.route.ts
16807
- import { join as join25 } from "path";
16808
- async function handleGetConversationFolderPath(c) {
16869
+ async function handleGetConversationFolderPath(c, threadManager) {
16809
16870
  try {
16810
16871
  const threadId = c.req.param("id");
16811
16872
  if (!threadId) {
16812
16873
  return errorResponse(c, ErrorCodes.INVALID_REQUEST, "Thread ID is required", 400);
16813
16874
  }
16814
- const path6 = join25(getDataDir(), threadId);
16815
- return successResponse(c, { path: path6 });
16875
+ const thread = await threadManager.getThread(threadId);
16876
+ if (!thread) {
16877
+ return errorResponse(c, ErrorCodes.THREAD_NOT_FOUND, `Thread not found: ${threadId}`, 404);
16878
+ }
16879
+ return successResponse(c, { path: thread.path });
16816
16880
  } catch (error) {
16817
16881
  const errorMessage = error instanceof Error ? error.message : String(error);
16818
16882
  return errorResponse(
@@ -16866,12 +16930,12 @@ async function handleFixComments(c, threadManager) {
16866
16930
 
16867
16931
  // src/features/threads/threads-ai-files.route.ts
16868
16932
  import { readFile as readFile15, writeFile as writeFile7, mkdir as mkdir7, access as access5, rm as rm6 } from "fs/promises";
16869
- import { join as join27 } from "path";
16933
+ import { join as join26 } from "path";
16870
16934
  import { existsSync as existsSync15 } from "fs";
16871
16935
 
16872
16936
  // src/features/git/git-download-folder.ts
16873
16937
  import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
16874
- import { join as join26, dirname as dirname4 } from "path";
16938
+ import { join as join25, dirname as dirname4 } from "path";
16875
16939
  async function downloadGithubFolder(repoUrl, srcPath, destPath, options = {}) {
16876
16940
  const { token, ref } = options;
16877
16941
  const match = repoUrl.replace(/\.git$/, "").match(/github\.com\/([^/]+)\/([^/]+)/);
@@ -16907,7 +16971,7 @@ async function downloadGithubFolder(repoUrl, srcPath, destPath, options = {}) {
16907
16971
  await Promise.all(
16908
16972
  files.map(async (file) => {
16909
16973
  const relativePath = file.path.slice(prefix.length);
16910
- const localPath = join26(destPath, relativePath);
16974
+ const localPath = join25(destPath, relativePath);
16911
16975
  await mkdir6(dirname4(localPath), { recursive: true });
16912
16976
  const rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${refParam}/${file.path}`;
16913
16977
  const fileRes = await fetch(rawUrl, { headers });
@@ -17049,7 +17113,7 @@ async function handleSaveThreadAIFile(c, threadManager) {
17049
17113
  if (!absPath) {
17050
17114
  return c.json({ error: { code: "BAD_REQUEST", message: "Invalid file path" } }, 400);
17051
17115
  }
17052
- const parentDir = join27(absPath, "..");
17116
+ const parentDir = join26(absPath, "..");
17053
17117
  await mkdir7(parentDir, { recursive: true });
17054
17118
  await writeFile7(absPath, content, "utf-8");
17055
17119
  return c.json({ success: true, path: filePath });
@@ -17138,10 +17202,10 @@ async function handleCreateThreadAgent(c, threadManager) {
17138
17202
  if (!thread) {
17139
17203
  return errorResponse(c, ErrorCodes.THREAD_NOT_FOUND, `Thread not found: ${threadId}`, 404);
17140
17204
  }
17141
- const agentRelPath = join27(".agents", "agents", name);
17142
- const agentAbsPath = join27(thread.path, agentRelPath);
17143
- const agentFileRelPath = join27(agentRelPath, "AGENT.md");
17144
- const agentFileAbsPath = join27(agentAbsPath, "AGENT.md");
17205
+ const agentRelPath = join26(".agents", "agents", name);
17206
+ const agentAbsPath = join26(thread.path, agentRelPath);
17207
+ const agentFileRelPath = join26(agentRelPath, "AGENT.md");
17208
+ const agentFileAbsPath = join26(agentAbsPath, "AGENT.md");
17145
17209
  if (existsSync15(agentAbsPath)) {
17146
17210
  return c.json(
17147
17211
  { error: { code: "CONFLICT", message: `Agent '${name}' already exists` } },
@@ -17208,10 +17272,10 @@ async function handleCreateThreadSkill(c, threadManager) {
17208
17272
  if (!thread) {
17209
17273
  return errorResponse(c, ErrorCodes.THREAD_NOT_FOUND, `Thread not found: ${threadId}`, 404);
17210
17274
  }
17211
- const skillRelPath = join27(".agents", "skills", name);
17212
- const skillAbsPath = join27(thread.path, skillRelPath);
17213
- const skillFileRelPath = join27(skillRelPath, "SKILL.md");
17214
- const skillFileAbsPath = join27(skillAbsPath, "SKILL.md");
17275
+ const skillRelPath = join26(".agents", "skills", name);
17276
+ const skillAbsPath = join26(thread.path, skillRelPath);
17277
+ const skillFileRelPath = join26(skillRelPath, "SKILL.md");
17278
+ const skillFileAbsPath = join26(skillAbsPath, "SKILL.md");
17215
17279
  if (existsSync15(skillAbsPath)) {
17216
17280
  return c.json(
17217
17281
  { error: { code: "CONFLICT", message: `Skill '${name}' already exists` } },
@@ -17525,7 +17589,7 @@ function createThreadRoutes(threadManager, gitManager, conversationManager) {
17525
17589
  return handleOpenThread(c, threadManager);
17526
17590
  });
17527
17591
  router.get("/:id/conversation-folder-path", async (c) => {
17528
- return handleGetConversationFolderPath(c);
17592
+ return handleGetConversationFolderPath(c, threadManager);
17529
17593
  });
17530
17594
  router.post("/:id/fix-comments", async (c) => {
17531
17595
  return handleFixComments(c, threadManager);
@@ -17895,7 +17959,7 @@ import { existsSync as existsSync17 } from "fs";
17895
17959
  // src/features/git/git.utils.ts
17896
17960
  init_utils();
17897
17961
  import { existsSync as existsSync16, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
17898
- import { isAbsolute as isAbsolute3, normalize as normalize2, resolve as resolve3, join as join28 } from "path";
17962
+ import { isAbsolute as isAbsolute3, normalize as normalize2, resolve as resolve3, join as join27 } from "path";
17899
17963
  import { completeSimple } from "@mariozechner/pi-ai";
17900
17964
  async function resolveModelAndKey(provider, modelId, metadataManager) {
17901
17965
  const providerConfig = await resolveProviderConfig(provider);
@@ -18152,7 +18216,7 @@ async function getUntrackedFilesDiff(gitRoot) {
18152
18216
  const parts = [];
18153
18217
  const maxFileSize = 1e5;
18154
18218
  for (const relPath of untrackedPaths) {
18155
- const fullPath = join28(gitRoot, relPath);
18219
+ const fullPath = join27(gitRoot, relPath);
18156
18220
  if (!existsSync16(fullPath)) continue;
18157
18221
  try {
18158
18222
  if (statSync4(fullPath).isDirectory()) continue;
@@ -20522,7 +20586,7 @@ function createUpdateRoutes(updater) {
20522
20586
  // src/features/mcp/mcp.routes.ts
20523
20587
  import { Hono as Hono13 } from "hono";
20524
20588
  import { readFile as readFile16, writeFile as writeFile8, mkdir as mkdir9, access as access6 } from "fs/promises";
20525
- import { join as join29, dirname as dirname6 } from "path";
20589
+ import { join as join28, dirname as dirname6 } from "path";
20526
20590
 
20527
20591
  // src/features/mcp/mcp.popular.json
20528
20592
  var mcp_popular_default = [
@@ -20633,7 +20697,7 @@ var mcp_popular_default = [
20633
20697
  var MCP_CONFIG_PATHS2 = [".agents/mcp.json", "mcp.json"];
20634
20698
  async function readMCPConfig(projectPath) {
20635
20699
  for (const configPath of MCP_CONFIG_PATHS2) {
20636
- const fullPath = join29(projectPath, configPath);
20700
+ const fullPath = join28(projectPath, configPath);
20637
20701
  try {
20638
20702
  await access6(fullPath);
20639
20703
  const content = await readFile16(fullPath, "utf-8");
@@ -20647,7 +20711,7 @@ async function readMCPConfig(projectPath) {
20647
20711
  }
20648
20712
  async function writeMCPConfig(projectPath, config) {
20649
20713
  const existing = await readMCPConfig(projectPath);
20650
- const targetPath = existing?.filePath ?? join29(projectPath, ".agents/mcp.json");
20714
+ const targetPath = existing?.filePath ?? join28(projectPath, ".agents/mcp.json");
20651
20715
  await mkdir9(dirname6(targetPath), { recursive: true });
20652
20716
  await writeFile8(targetPath, JSON.stringify(config, null, 2), "utf-8");
20653
20717
  }
@@ -21321,7 +21385,7 @@ async function clipboardWriteImage(c) {
21321
21385
  }
21322
21386
 
21323
21387
  // src/features/image/image-save.route.ts
21324
- import { join as join30 } from "path";
21388
+ import { join as join29 } from "path";
21325
21389
  var Utils5 = null;
21326
21390
  var utilsLoaded5 = false;
21327
21391
  async function loadUtils5() {
@@ -21358,7 +21422,7 @@ async function saveImage(c) {
21358
21422
  return c.json({ error: "imageUrl or imageData is required" }, 400);
21359
21423
  }
21360
21424
  const name = filename ?? `generated-image-${Date.now()}.png`;
21361
- const savePath = join30(Utils5.paths.downloads, name);
21425
+ const savePath = join29(Utils5.paths.downloads, name);
21362
21426
  await Bun.write(savePath, data);
21363
21427
  return c.json({ success: true, path: savePath });
21364
21428
  } catch (error) {
@@ -21447,20 +21511,102 @@ function createBrowserJsRoutes(threadManager) {
21447
21511
  return router;
21448
21512
  }
21449
21513
 
21514
+ // src/features/voice-model/voice-model.routes.ts
21515
+ import { Hono as Hono21 } from "hono";
21516
+ var MODEL_URL = "https://install.tarsk.io/voice-models/ggml-tiny.en.bin";
21517
+ function createVoiceModelRoutes() {
21518
+ const router = new Hono21();
21519
+ router.get("/download", async (c) => {
21520
+ try {
21521
+ const response = await fetch(MODEL_URL);
21522
+ if (!response.ok) {
21523
+ return errorResponse(
21524
+ c,
21525
+ ErrorCodes.EXTERNAL_API_ERROR,
21526
+ `Download server returned ${response.status} ${response.statusText}`,
21527
+ 502
21528
+ );
21529
+ }
21530
+ const contentLength = response.headers.get("content-length");
21531
+ const headers = {
21532
+ "Content-Type": "application/octet-stream"
21533
+ };
21534
+ if (contentLength) {
21535
+ headers["Content-Length"] = contentLength;
21536
+ }
21537
+ return new Response(response.body, {
21538
+ status: 200,
21539
+ headers
21540
+ });
21541
+ } catch (error) {
21542
+ const message = error instanceof Error ? error.message : String(error);
21543
+ return errorResponse(
21544
+ c,
21545
+ ErrorCodes.EXTERNAL_API_ERROR,
21546
+ `Failed to download voice model: ${message}`,
21547
+ 502,
21548
+ message
21549
+ );
21550
+ }
21551
+ });
21552
+ return router;
21553
+ }
21554
+
21555
+ // src/features/logs/logs.routes.ts
21556
+ import { Hono as Hono22 } from "hono";
21557
+ function createLogsRoutes() {
21558
+ const router = new Hono22();
21559
+ router.post("/", async (c) => {
21560
+ let body = {};
21561
+ try {
21562
+ body = await c.req.json();
21563
+ } catch {
21564
+ return c.json({ ok: false, error: "invalid json" }, 400);
21565
+ }
21566
+ const { level = "INFO", context = "app", message = "", data } = body;
21567
+ let line = `[VOICE] [${level}] [${context}] ${message}`;
21568
+ if (data !== void 0 && data !== "") {
21569
+ try {
21570
+ line += ` | ${JSON.stringify(data)}`;
21571
+ } catch {
21572
+ line += ` | [non-serializable]`;
21573
+ }
21574
+ }
21575
+ if (level === "ERROR") {
21576
+ console.error(line);
21577
+ } else if (level === "WARN") {
21578
+ console.warn(line);
21579
+ } else {
21580
+ console.log(line);
21581
+ }
21582
+ return c.json({ ok: true });
21583
+ });
21584
+ router.delete("/", (c) => {
21585
+ console.log("[VOICE] Log cleared by client request");
21586
+ return c.json({ ok: true });
21587
+ });
21588
+ return router;
21589
+ }
21590
+
21450
21591
  // src/server.ts
21451
21592
  var __filename = fileURLToPath(import.meta.url);
21452
21593
  var __dirname = path4.dirname(__filename);
21453
21594
  async function startTarskServer(options) {
21454
21595
  const { isDebug: isDebug2, publicDir: publicDirOverride } = options;
21455
21596
  const port = isDebug2 ? 462 : process.env.PORT ? parseInt(process.env.PORT) : 641;
21456
- const app = new Hono21();
21597
+ const app = new Hono23();
21457
21598
  app.use("/*", cors());
21599
+ app.use("/*", async (c, next) => {
21600
+ c.header("Cross-Origin-Opener-Policy", "same-origin");
21601
+ c.header("Cross-Origin-Embedder-Policy", "require-corp");
21602
+ return next();
21603
+ });
21458
21604
  app.use("/*", async (c, next) => {
21459
21605
  if (c.req.path.startsWith("/api/")) {
21460
21606
  const method = c.req.method;
21461
21607
  const reqPath = c.req.path;
21462
21608
  const fullUrl = `http://localhost:${port}${reqPath}`;
21463
- if (!fullUrl.includes("processing")) {
21609
+ if (!fullUrl.includes("processing") && !reqPath.startsWith("/api/logs")) {
21464
21610
  console.log(`${method} ${fullUrl}`);
21465
21611
  }
21466
21612
  }
@@ -21525,6 +21671,8 @@ async function startTarskServer(options) {
21525
21671
  app.route("/api/scaffold", createScaffoldRoutes(projectManager));
21526
21672
  app.route("/api/ask-user", createAskUserRoutes());
21527
21673
  app.route("/api/browser-js", createBrowserJsRoutes(threadManager));
21674
+ app.route("/api/voice-model", createVoiceModelRoutes());
21675
+ app.route("/api/logs", createLogsRoutes());
21528
21676
  app.route("/api/update", createUpdateRoutes(options.updater));
21529
21677
  createSlashCommandRoutes(app, threadManager);
21530
21678
  createRuleRoutes(app, projectManager);
@@ -21583,7 +21731,6 @@ async function startTarskServer(options) {
21583
21731
  // src/index.ts
21584
21732
  import fs4 from "fs";
21585
21733
  import path5 from "path";
21586
- import { fileURLToPath as fileURLToPath2 } from "url";
21587
21734
  var args = process.argv.slice(2);
21588
21735
  var isDebug = args.includes("--debug");
21589
21736
  var shouldOpenBrowser = args.includes("--open");
@@ -21591,10 +21738,9 @@ if (!isDebug) {
21591
21738
  console.log = () => {
21592
21739
  };
21593
21740
  } else {
21594
- const __filename2 = fileURLToPath2(import.meta.url);
21595
- const cliDir = path5.resolve(path5.dirname(__filename2), "..");
21596
- const logFilePath = path5.join(cliDir, "logs.txt");
21741
+ const logFilePath = path5.join(APP_SUPPORT_DIR, "debug-logs.txt");
21597
21742
  try {
21743
+ fs4.mkdirSync(path5.dirname(logFilePath), { recursive: true });
21598
21744
  fs4.writeFileSync(logFilePath, "");
21599
21745
  } catch {
21600
21746
  }
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{Dr as t,Ji as n,Jt as r,Q as i,Rn as a,ca as o,ya as s,yi as c}from"./dialogs-config-DZFG2IQM.js";import{t as l}from"./use-toast-DqmC-mB5.js";import{t as u}from"./skeleton-Bc0U0oGc.js";var d=e(s(),1),f=t();function p(){let[e,t]=(0,d.useState)(null),[s,p]=(0,d.useState)(!0);(0,d.useEffect)(()=>{m();let e=()=>{document.visibilityState===`visible`&&m()};return document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[]);async function m(){p(!0);try{t(await i())}catch(e){l({title:`Error`,description:e instanceof Error?e.message:`Failed to load account info`,variant:`destructive`})}finally{p(!1)}}function h(){r(`https://buy.stripe.com/14AcN6feK0Jjbheb2H3Nm03?client_reference_id=${e?.clientReferenceId??``}`)}function g(){r(`https://buy.stripe.com/9B67sMd6CgIh70Y0o33Nm04?client_reference_id=${e?.clientReferenceId??``}`)}if(s)return(0,f.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,f.jsxs)(`div`,{className:`mb-6`,children:[(0,f.jsx)(u,{className:`h-8 w-32 mb-2`}),(0,f.jsx)(u,{className:`h-4 w-64`})]}),(0,f.jsxs)(`div`,{className:`space-y-6`,children:[(0,f.jsxs)(`div`,{className:`flex gap-4`,children:[(0,f.jsxs)(`div`,{className:`flex-1 rounded-xl border bg-card p-5 space-y-2`,children:[(0,f.jsx)(u,{className:`h-4 w-20`}),(0,f.jsx)(u,{className:`h-9 w-28`})]}),(0,f.jsxs)(`div`,{className:`flex-1 rounded-xl border bg-card p-5 space-y-3`,children:[(0,f.jsx)(u,{className:`h-4 w-24`}),(0,f.jsx)(u,{className:`h-6 w-32`}),(0,f.jsx)(u,{className:`h-4 w-full`})]})]}),(0,f.jsxs)(`div`,{className:`space-y-3`,children:[(0,f.jsx)(u,{className:`h-4 w-24`}),(0,f.jsxs)(`div`,{className:`rounded-xl border bg-card p-5 flex items-center justify-between gap-4`,children:[(0,f.jsxs)(`div`,{className:`space-y-1 flex-1`,children:[(0,f.jsx)(u,{className:`h-5 w-28`}),(0,f.jsx)(u,{className:`h-4 w-64`})]}),(0,f.jsx)(u,{className:`h-9 w-28 shrink-0`})]}),(0,f.jsxs)(`div`,{className:`rounded-xl border bg-card p-5 flex items-center justify-between gap-4`,children:[(0,f.jsxs)(`div`,{className:`space-y-1 flex-1`,children:[(0,f.jsx)(u,{className:`h-5 w-36`}),(0,f.jsx)(u,{className:`h-4 w-56`}),(0,f.jsx)(u,{className:`h-4 w-32`})]}),(0,f.jsx)(u,{className:`h-9 w-24 shrink-0`})]})]})]})]});let _=e?.plan===`unlimited-pro`;return(0,f.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,f.jsxs)(`div`,{className:`mb-6`,children:[(0,f.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Account`}),(0,f.jsx)(`p`,{className:`text-muted-foreground`,children:`Manage your Tarsk plan and prompt balance.`})]}),(0,f.jsxs)(`div`,{className:`space-y-6`,children:[(0,f.jsxs)(`div`,{className:`flex gap-4`,children:[(0,f.jsxs)(`div`,{className:`flex-1 rounded-xl border bg-card p-5 space-y-2`,children:[(0,f.jsxs)(`div`,{className:`flex items-center gap-2 text-sm font-medium text-muted-foreground`,children:[(0,f.jsx)(c,{className:`h-4 w-4`}),`Balance`]}),(0,f.jsx)(`div`,{className:`flex items-end gap-2`,children:_?(0,f.jsx)(`span`,{className:`text-3xl font-bold`,children:`Unlimited`}):(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`span`,{className:`text-3xl font-bold`,children:e?.promptsRemaining.toLocaleString()??0}),(0,f.jsx)(`span`,{className:`text-muted-foreground mb-1 text-sm`,children:`prompts remaining`})]})})]}),(0,f.jsxs)(`div`,{className:`flex-1 rounded-xl border bg-card p-5 space-y-3`,children:[(0,f.jsxs)(`div`,{className:`flex items-center gap-2 text-sm font-medium text-muted-foreground`,children:[(0,f.jsx)(n,{className:`h-4 w-4`}),`Current Plan`]}),(0,f.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,f.jsx)(`span`,{className:`text-lg font-semibold`,children:_?`Unlimited Pro`:`Pay as you go`}),_&&(0,f.jsx)(`span`,{className:`rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary`,children:`Active`})]}),(0,f.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:_?`You have unlimited prompts with no restrictions.`:`Purchase prompts as needed. Upgrade to Pro for unlimited access.`})]})]}),!_&&(0,f.jsxs)(`div`,{className:`space-y-3`,children:[(0,f.jsx)(`h2`,{className:`text-sm font-semibold text-muted-foreground uppercase tracking-wide`,children:`Add Prompts`}),(0,f.jsxs)(`div`,{className:`rounded-xl border bg-card p-5 flex items-center justify-between gap-4`,children:[(0,f.jsxs)(`div`,{className:`space-y-1`,children:[(0,f.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,f.jsx)(`span`,{className:`font-semibold`,children:`1,000 Prompts`})}),(0,f.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Top up your balance with 1,000 additional prompts for $5.`})]}),(0,f.jsx)(a,{onClick:h,className:`shrink-0`,children:`Top Up Balance`})]}),(0,f.jsxs)(`div`,{className:`rounded-xl border bg-card p-5 flex items-center justify-between gap-4`,children:[(0,f.jsxs)(`div`,{className:`space-y-1`,children:[(0,f.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,f.jsx)(n,{className:`h-4 w-4 text-primary`}),(0,f.jsx)(`span`,{className:`font-semibold`,children:`Unlimited Pro Plan`})]}),(0,f.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Unlimited prompts for $100 and lifetime access to Tarsk.`}),(0,f.jsxs)(`ul`,{className:`text-sm text-muted-foreground space-y-0.5`,children:[(0,f.jsxs)(`li`,{className:`flex items-center gap-1.5`,children:[(0,f.jsx)(o,{className:`h-3 w-3 text-primary`}),`Unlimited prompts`]}),(0,f.jsxs)(`li`,{className:`flex items-center gap-1.5`,children:[(0,f.jsx)(o,{className:`h-3 w-3 text-primary`}),`Priority access`]})]})]}),(0,f.jsx)(a,{onClick:g,className:`shrink-0`,children:`Purchase`})]})]})]})]})}export{p as default};
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{Dr as t,Jn as n,_a as r,ya as i,zn as a}from"./dialogs-config-DZFG2IQM.js";import{at as o,ct as s,dt as c,ft as l,lt as u,ot as d,st as f,ut as p}from"./react-vendor-Bao-KYKs.js";var m=r(),h=e(i(),1),g=t(),_=c,v=p,y=h.forwardRef((e,t)=>{let r=(0,m.c)(9),i,a;r[0]===e?(i=r[1],a=r[2]):({className:i,...a}=e,r[0]=e,r[1]=i,r[2]=a);let o;r[3]===i?o=r[4]:(o=n(`fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`,i),r[3]=i,r[4]=o);let s;return r[5]!==a||r[6]!==t||r[7]!==o?(s=(0,g.jsx)(u,{className:o,...a,ref:t}),r[5]=a,r[6]=t,r[7]=o,r[8]=s):s=r[8],s});y.displayName=u.displayName;var b=h.forwardRef((e,t)=>{let r=(0,m.c)(10),i,a;r[0]===e?(i=r[1],a=r[2]):({className:i,...a}=e,r[0]=e,r[1]=i,r[2]=a);let o;r[3]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,g.jsx)(y,{}),r[3]=o):o=r[3];let s;r[4]===i?s=r[5]:(s=n(`fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg`,i),r[4]=i,r[5]=s);let c;return r[6]!==a||r[7]!==t||r[8]!==s?(c=(0,g.jsxs)(v,{children:[o,(0,g.jsx)(f,{ref:t,className:s,...a})]}),r[6]=a,r[7]=t,r[8]=s,r[9]=c):c=r[9],c});b.displayName=f.displayName;var x=e=>{let t=(0,m.c)(8),r,i;t[0]===e?(r=t[1],i=t[2]):({className:r,...i}=e,t[0]=e,t[1]=r,t[2]=i);let a;t[3]===r?a=t[4]:(a=n(`flex flex-col space-y-2 text-center sm:text-left`,r),t[3]=r,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,g.jsx)(`div`,{className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o};x.displayName=`AlertDialogHeader`;var S=e=>{let t=(0,m.c)(8),r,i;t[0]===e?(r=t[1],i=t[2]):({className:r,...i}=e,t[0]=e,t[1]=r,t[2]=i);let a;t[3]===r?a=t[4]:(a=n(`flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2`,r),t[3]=r,t[4]=a);let o;return t[5]!==i||t[6]!==a?(o=(0,g.jsx)(`div`,{className:a,...i}),t[5]=i,t[6]=a,t[7]=o):o=t[7],o};S.displayName=`AlertDialogFooter`;var C=h.forwardRef((e,t)=>{let r=(0,m.c)(9),i,a;r[0]===e?(i=r[1],a=r[2]):({className:i,...a}=e,r[0]=e,r[1]=i,r[2]=a);let o;r[3]===i?o=r[4]:(o=n(`text-lg font-semibold`,i),r[3]=i,r[4]=o);let s;return r[5]!==a||r[6]!==t||r[7]!==o?(s=(0,g.jsx)(l,{ref:t,className:o,...a}),r[5]=a,r[6]=t,r[7]=o,r[8]=s):s=r[8],s});C.displayName=l.displayName;var w=h.forwardRef((e,t)=>{let r=(0,m.c)(9),i,a;r[0]===e?(i=r[1],a=r[2]):({className:i,...a}=e,r[0]=e,r[1]=i,r[2]=a);let o;r[3]===i?o=r[4]:(o=n(`text-sm text-muted-foreground`,i),r[3]=i,r[4]=o);let c;return r[5]!==a||r[6]!==t||r[7]!==o?(c=(0,g.jsx)(s,{ref:t,className:o,...a}),r[5]=a,r[6]=t,r[7]=o,r[8]=c):c=r[8],c});w.displayName=s.displayName;var T=h.forwardRef((e,t)=>{let r=(0,m.c)(9),i,s;r[0]===e?(i=r[1],s=r[2]):({className:i,...s}=e,r[0]=e,r[1]=i,r[2]=s);let c;r[3]===i?c=r[4]:(c=n(a(),i),r[3]=i,r[4]=c);let l;return r[5]!==s||r[6]!==t||r[7]!==c?(l=(0,g.jsx)(o,{ref:t,className:c,...s}),r[5]=s,r[6]=t,r[7]=c,r[8]=l):l=r[8],l});T.displayName=o.displayName;var E=h.forwardRef((e,t)=>{let r=(0,m.c)(9),i,o;r[0]===e?(i=r[1],o=r[2]):({className:i,...o}=e,r[0]=e,r[1]=i,r[2]=o);let s;r[3]===i?s=r[4]:(s=n(a({variant:`outline`}),`mt-2 sm:mt-0`,i),r[3]=i,r[4]=s);let c;return r[5]!==o||r[6]!==t||r[7]!==s?(c=(0,g.jsx)(d,{ref:t,className:s,...o}),r[5]=o,r[6]=t,r[7]=s,r[8]=c):c=r[8],c});E.displayName=d.displayName;export{w as a,C as c,b as i,T as n,S as o,E as r,x as s,_ as t};
@@ -0,0 +1 @@
1
+ import{An as e,Dn as t,En as n,On as r,Tn as i,jn as a,kn as o}from"./dialogs-config-DZFG2IQM.js";async function s(e,r){return t(`api/threads/${n(e)}/explorer?path=${encodeURIComponent(r)}`)}async function c(e,r){return t(`api/threads/${n(e)}/ai-file?path=${encodeURIComponent(r)}`)}async function l(e,t,r){return a(`api/threads/${n(e)}/ai-file`,{path:t,content:r})}async function u(e,t){return i(`api/threads/${n(e)}/explorer?path=${encodeURIComponent(t)}`)}async function d(e,t,r){return o(`api/threads/${n(e)}/explorer`,{path:t,newName:r})}async function f(t,r,i){return e(`api/threads/${n(t)}/explorer/file`,{dirPath:r,name:i})}function p(e,t){return`${r()}/api/threads/${n(e)}/explorer/media?path=${encodeURIComponent(t)}`}async function m(t,r,i){return e(`api/threads/${n(t)}/explorer/folder`,{dirPath:r,name:i})}export{p as a,l as c,c as i,m as n,s as o,u as r,d as s,f as t};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{Cr as t,Gt as n,Ri as r,Rr as i,Wr as a,Xr as o,ci as s,da as c,la as l}from"./dialogs-config-BEsTbY1C.js";import{a as u}from"./store-Dyy2UFdD.js";import{n as d}from"./tab-context-DBrXMyNd.js";import{t as f}from"./run-stop-button-CZ62jJDn.js";var p=l(),m=e(c(),1),h=t();function g(){let e=(0,p.c)(41),{devServerUrl:t,browserResetTrigger:c}=d(),{state:l}=u(),{selectedProjectId:g,projects:_}=l,v;if(e[0]!==_||e[1]!==g){let t;e[3]===g?t=e[4]:(t=e=>e.projectId===g,e[3]=g,e[4]=t),v=_.find(t),e[0]=_,e[1]=g,e[2]=v}else v=e[2];let y=v,[b,x]=(0,m.useState)(``),[S,C]=(0,m.useState)(``),[w,T]=(0,m.useState)(`desktop`),E=(0,m.useRef)(null),D;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(D=()=>{C(``),x(``),E.current&&(E.current.src=``)},e[5]=D):D=e[5];let O;e[6]===c?O=e[7]:(O=[c],e[6]=c,e[7]=O),(0,m.useEffect)(D,O);let k,A;e[8]===t?(k=e[9],A=e[10]):(k=()=>{t&&(x(t),C(t))},A=[t],e[8]=t,e[9]=k,e[10]=A),(0,m.useEffect)(k,A);let j;e[11]===Symbol.for(`react.memo_cache_sentinel`)?(j=e=>{let t=e.trim();t&&(!t.startsWith(`http://`)&&!t.startsWith(`https://`)&&(t=`http://`+t),x(t),C(t))},e[11]=j):j=e[11];let M=j,N;e[12]===b?N=e[13]:(N=e=>{e.key===`Enter`&&M(b)},e[12]=b,e[13]=N);let P=N,F;e[14]===Symbol.for(`react.memo_cache_sentinel`)?(F=()=>{if(E.current){let e=E.current.src;E.current.src=``,setTimeout(()=>{E.current&&(E.current.src=e)},0)}},e[14]=F):F=e[14];let I=F,L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L={desktop:{width:`100%`,height:`100%`},tablet:{width:`768px`,height:`1024px`},mobile:{width:`375px`,height:`667px`}},e[15]=L):L=e[15];let R=L[w],z;e[16]===Symbol.for(`react.memo_cache_sentinel`)?(z=e=>x(e.target.value),e[16]=z):z=e[16];let B;e[17]!==P||e[18]!==b?(B=(0,h.jsx)(`input`,{type:`text`,value:b,onChange:z,onKeyDown:P,placeholder:`Enter URL...`,className:`flex-1 px-4 py-1.5 text-sm bg-muted rounded-full border border-border outline-none focus:ring-1 focus:ring-ring font-mono`,spellCheck:!1}),e[17]=P,e[18]=b,e[19]=B):B=e[19];let V;e[20]===S?V=e[21]:(V=S&&(0,h.jsx)(`button`,{onClick:I,title:`Refresh page`,className:`p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`,children:(0,h.jsx)(o,{size:15})}),e[20]=S,e[21]=V);let H;e[22]!==w||e[23]!==S?(H=S&&(0,h.jsxs)(`div`,{className:`flex items-center bg-muted rounded-md p-0.5`,children:[(0,h.jsx)(`button`,{onClick:()=>T(`desktop`),title:`Desktop view`,className:`p-1.5 rounded transition-colors ${w===`desktop`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground hover:bg-background/50`}`,children:(0,h.jsx)(s,{size:15})}),(0,h.jsx)(`button`,{onClick:()=>T(`tablet`),title:`Tablet view`,className:`p-1.5 rounded transition-colors ${w===`tablet`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground hover:bg-background/50`}`,children:(0,h.jsx)(i,{size:15})}),(0,h.jsx)(`button`,{onClick:()=>T(`mobile`),title:`Mobile view`,className:`p-1.5 rounded transition-colors ${w===`mobile`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground hover:bg-background/50`}`,children:(0,h.jsx)(a,{size:15})})]}),e[22]=w,e[23]=S,e[24]=H):H=e[24];let U;e[25]===S?U=e[26]:(U=S&&(0,h.jsx)(`button`,{onClick:()=>void n(S),title:`Open in external browser`,className:`p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`,children:(0,h.jsx)(r,{size:15})}),e[25]=S,e[26]=U);let W;e[27]!==B||e[28]!==V||e[29]!==H||e[30]!==U?(W=(0,h.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-2 border-b border-border shrink-0`,children:[B,V,H,U]}),e[27]=B,e[28]=V,e[29]=H,e[30]=U,e[31]=W):W=e[31];let G;e[32]!==R||e[33]!==w||e[34]!==S||e[35]!==y||e[36]!==g?(G=S?(0,h.jsx)(`div`,{className:`flex-1 flex items-center justify-center bg-background`,children:w===`desktop`?(0,h.jsx)(`iframe`,{ref:E,src:S,className:`flex-1 w-full h-full border-none`,title:`Browser`}):(0,h.jsx)(`div`,{className:`bg-white border border-border rounded-lg shadow-lg overflow-hidden transition-all duration-200`,style:{width:R.width,height:R.height,maxWidth:`100%`,maxHeight:`100%`},children:(0,h.jsx)(`iframe`,{ref:E,src:S,className:`w-full h-full border-none`,title:`Browser`})})}):(0,h.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center gap-6 text-muted-foreground`,children:g&&y?.runCommand?(0,h.jsx)(f,{projectId:g,runCommand:y.runCommand,large:!0}):(0,h.jsx)(`p`,{className:`text-sm`,children:`Enter a URL to browse`})}),e[32]=R,e[33]=w,e[34]=S,e[35]=y,e[36]=g,e[37]=G):G=e[37];let K;return e[38]!==W||e[39]!==G?(K=(0,h.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[W,G]}),e[38]=W,e[39]=G,e[40]=K):K=e[40],K}export{g as BrowserTab};
1
+ import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{Dr as t,Gi as n,Jt as r,Wr as i,Xr as a,_a as o,hi as s,ni as c,ya as l}from"./dialogs-config-DZFG2IQM.js";import{a as u}from"./store-CwvBC-YP.js";import{n as d}from"./tab-context-CCvlrC0o.js";import{t as f}from"./run-stop-button-k1LeM0M-.js";var p=o(),m=e(l(),1),h=t();function g(){let e=(0,p.c)(41),{devServerUrl:t,browserResetTrigger:o}=d(),{state:l}=u(),{selectedProjectId:g,projects:_}=l,v;if(e[0]!==_||e[1]!==g){let t;e[3]===g?t=e[4]:(t=e=>e.projectId===g,e[3]=g,e[4]=t),v=_.find(t),e[0]=_,e[1]=g,e[2]=v}else v=e[2];let y=v,[b,x]=(0,m.useState)(``),[S,C]=(0,m.useState)(``),[w,T]=(0,m.useState)(`desktop`),E=(0,m.useRef)(null),D;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(D=()=>{C(``),x(``),E.current&&(E.current.src=``)},e[5]=D):D=e[5];let O;e[6]===o?O=e[7]:(O=[o],e[6]=o,e[7]=O),(0,m.useEffect)(D,O);let k,A;e[8]===t?(k=e[9],A=e[10]):(k=()=>{t&&(x(t),C(t))},A=[t],e[8]=t,e[9]=k,e[10]=A),(0,m.useEffect)(k,A);let j;e[11]===Symbol.for(`react.memo_cache_sentinel`)?(j=e=>{let t=e.trim();t&&(!t.startsWith(`http://`)&&!t.startsWith(`https://`)&&(t=`http://`+t),x(t),C(t))},e[11]=j):j=e[11];let M=j,N;e[12]===b?N=e[13]:(N=e=>{e.key===`Enter`&&M(b)},e[12]=b,e[13]=N);let P=N,F;e[14]===Symbol.for(`react.memo_cache_sentinel`)?(F=()=>{if(E.current){let e=E.current.src;E.current.src=``,setTimeout(()=>{E.current&&(E.current.src=e)},0)}},e[14]=F):F=e[14];let I=F,L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L={desktop:{width:`100%`,height:`100%`},tablet:{width:`768px`,height:`1024px`},mobile:{width:`375px`,height:`667px`}},e[15]=L):L=e[15];let R=L[w],z;e[16]===Symbol.for(`react.memo_cache_sentinel`)?(z=e=>x(e.target.value),e[16]=z):z=e[16];let B;e[17]!==P||e[18]!==b?(B=(0,h.jsx)(`input`,{type:`text`,value:b,onChange:z,onKeyDown:P,placeholder:`Enter URL...`,className:`flex-1 px-4 py-1.5 text-sm bg-muted rounded-full border border-border outline-none focus:ring-1 focus:ring-ring font-mono`,spellCheck:!1}),e[17]=P,e[18]=b,e[19]=B):B=e[19];let V;e[20]===S?V=e[21]:(V=S&&(0,h.jsx)(`button`,{onClick:I,title:`Refresh page`,className:`p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`,children:(0,h.jsx)(c,{size:15})}),e[20]=S,e[21]=V);let H;e[22]!==w||e[23]!==S?(H=S&&(0,h.jsxs)(`div`,{className:`flex items-center bg-muted rounded-md p-0.5`,children:[(0,h.jsx)(`button`,{onClick:()=>T(`desktop`),title:`Desktop view`,className:`p-1.5 rounded transition-colors ${w===`desktop`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground hover:bg-background/50`}`,children:(0,h.jsx)(s,{size:15})}),(0,h.jsx)(`button`,{onClick:()=>T(`tablet`),title:`Tablet view`,className:`p-1.5 rounded transition-colors ${w===`tablet`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground hover:bg-background/50`}`,children:(0,h.jsx)(i,{size:15})}),(0,h.jsx)(`button`,{onClick:()=>T(`mobile`),title:`Mobile view`,className:`p-1.5 rounded transition-colors ${w===`mobile`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground hover:bg-background/50`}`,children:(0,h.jsx)(a,{size:15})})]}),e[22]=w,e[23]=S,e[24]=H):H=e[24];let U;e[25]===S?U=e[26]:(U=S&&(0,h.jsx)(`button`,{onClick:()=>void r(S),title:`Open in external browser`,className:`p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`,children:(0,h.jsx)(n,{size:15})}),e[25]=S,e[26]=U);let W;e[27]!==B||e[28]!==V||e[29]!==H||e[30]!==U?(W=(0,h.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-2 border-b border-border shrink-0`,children:[B,V,H,U]}),e[27]=B,e[28]=V,e[29]=H,e[30]=U,e[31]=W):W=e[31];let G;e[32]!==R||e[33]!==w||e[34]!==S||e[35]!==y||e[36]!==g?(G=S?(0,h.jsx)(`div`,{className:`flex-1 flex items-center justify-center bg-background`,children:w===`desktop`?(0,h.jsx)(`iframe`,{ref:E,src:S,className:`flex-1 w-full h-full border-none`,title:`Browser`}):(0,h.jsx)(`div`,{className:`bg-white border border-border rounded-lg shadow-lg overflow-hidden transition-all duration-200`,style:{width:R.width,height:R.height,maxWidth:`100%`,maxHeight:`100%`},children:(0,h.jsx)(`iframe`,{ref:E,src:S,className:`w-full h-full border-none`,title:`Browser`})})}):(0,h.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center gap-6 text-muted-foreground`,children:g&&y?.runCommand?(0,h.jsx)(f,{projectId:g,runCommand:y.runCommand,large:!0}):(0,h.jsx)(`p`,{className:`text-sm`,children:`Enter a URL to browse`})}),e[32]=R,e[33]=w,e[34]=S,e[35]=y,e[36]=g,e[37]=G):G=e[37];let K;return e[38]!==W||e[39]!==G?(K=(0,h.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[W,G]}),e[38]=W,e[39]=G,e[40]=K):K=e[40],K}export{g as BrowserTab};