tarsk 0.4.7 → 0.4.9

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 (48) hide show
  1. package/dist/index.js +254 -129
  2. package/dist/public/assets/account-view-D2dv34vY.js +1 -0
  3. package/dist/public/assets/{add-agent-view-B9IQjAwU.js → add-agent-view-DM__lVyy.js} +1 -1
  4. package/dist/public/assets/add-rule-view-BomwxNHB.js +7 -0
  5. package/dist/public/assets/{add-skill-view-Cuu6Z0fr.js → add-skill-view-JiUioTS0.js} +1 -1
  6. package/dist/public/assets/{add-slash-command-view-uW75Jvbh.js → add-slash-command-view--JU5d22L.js} +1 -1
  7. package/dist/public/assets/conversation-history-view-C2i3vP6t.js +1 -0
  8. package/dist/public/assets/{dialogs-config-DiFQjCeA.js → dialogs-config-CdogKQE6.js} +13 -13
  9. package/dist/public/assets/diff-view-BOokQeYx.js +3 -0
  10. package/dist/public/assets/file-tree-sidebar-BXedO8ZD.js +1 -0
  11. package/dist/public/assets/{files-view-CUZn7G0o.js → files-view-BK-J3s66.js} +1 -1
  12. package/dist/public/assets/history-view-DtTMEZIl.js +1 -0
  13. package/dist/public/assets/index-BR4u03pf.js +17 -0
  14. package/dist/public/assets/index-LCD_R39p.css +1 -0
  15. package/dist/public/assets/mcp-manager-BNA3V6Cy.js +1 -0
  16. package/dist/public/assets/{mcp-server-edit-view-BAwMNOAH.js → mcp-server-edit-view-B_xPUXV1.js} +3 -3
  17. package/dist/public/assets/mcp-servers-sidebar-Cv-D6sy7.js +1 -0
  18. package/dist/public/assets/{mcp-view-Cz7nelGQ.js → mcp-view-TSM0sRuR.js} +1 -1
  19. package/dist/public/assets/onboarding-dialog-C3veuByQ.js +1 -0
  20. package/dist/public/assets/onboarding-gO0dp5Em.js +1 -0
  21. package/dist/public/assets/project-settings-view-CwvIMmXu.js +1 -0
  22. package/dist/public/assets/provider-details-view-Dcm9ZdOm.js +1 -0
  23. package/dist/public/assets/{providers-sidebar-C4MF6i9d.js → providers-sidebar-B5hxgXyK.js} +1 -1
  24. package/dist/public/assets/radio-group-BQ7i054U.js +1 -0
  25. package/dist/public/assets/react-vendor-BNQTbRKd.js +17 -0
  26. package/dist/public/assets/settings-view-Di5K8IgA.js +2 -0
  27. package/dist/public/assets/{store-BVVGurzl.js → store-CB5vVIg-.js} +2 -2
  28. package/dist/public/assets/{use-toast-DEJkXPN4.js → use-toast-DCmq-wgl.js} +1 -1
  29. package/dist/public/assets/{utils-DY_quHB8.js → utils-B7eoN2Bj.js} +1 -1
  30. package/dist/public/index.html +10 -10
  31. package/package.json +1 -1
  32. package/dist/public/assets/add-rule-view-BdZHurB3.js +0 -7
  33. package/dist/public/assets/conversation-history-view-D0OBxJMC.js +0 -1
  34. package/dist/public/assets/diff-view-B5XBM5UZ.js +0 -3
  35. package/dist/public/assets/file-tree-sidebar-DMX7fHi7.js +0 -1
  36. package/dist/public/assets/history-view-B8HM78Wa.js +0 -1
  37. package/dist/public/assets/index-C-p81QYw.js +0 -17
  38. package/dist/public/assets/index-DhVMb7D6.css +0 -1
  39. package/dist/public/assets/mcp-manager-CEm1L3dn.js +0 -1
  40. package/dist/public/assets/mcp-servers-sidebar-Ncxq9Oj5.js +0 -1
  41. package/dist/public/assets/onboarding-CvpvkF3X.js +0 -1
  42. package/dist/public/assets/onboarding-dialog-CKJw0ULj.js +0 -1
  43. package/dist/public/assets/project-settings-view-DJ1uvrTL.js +0 -1
  44. package/dist/public/assets/provider-details-view-CkS6WbnK.js +0 -1
  45. package/dist/public/assets/radio-group-BItFbSTw.js +0 -1
  46. package/dist/public/assets/react-vendor-DkKo9QGO.js +0 -17
  47. package/dist/public/assets/settings-view-C45kmAGH.js +0 -2
  48. /package/dist/public/assets/{monaco-DvsnxTfD.js → monaco-DKN4dKR5.js} +0 -0
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
4
  var __esm = (fn, res) => function __init() {
@@ -643,7 +642,7 @@ function isValidPackageManager(value) {
643
642
 
644
643
  // src/server.ts
645
644
  import fs3 from "fs";
646
- import { Hono as Hono15 } from "hono";
645
+ import { Hono as Hono16 } from "hono";
647
646
  import { cors } from "hono/cors";
648
647
  import open3 from "open";
649
648
  import path5 from "path";
@@ -3426,6 +3425,10 @@ async function resolveProviderKeyName(providerName) {
3426
3425
 
3427
3426
  // src/agent/agent.model-resolver.ts
3428
3427
  import { getModel } from "@mariozechner/pi-ai";
3428
+ var DEFAULT_HEADERS = {
3429
+ "HTTP-Referer": "https://tarsk.io",
3430
+ "X-Title": "Tarsk.io"
3431
+ };
3429
3432
  var PROVIDER_NAME_TO_PI = {
3430
3433
  anthropic: "anthropic",
3431
3434
  openai: "openai",
@@ -3450,7 +3453,8 @@ function resolveModel(providerName, modelId, providerConfig) {
3450
3453
  const piProvider = PROVIDER_NAME_TO_PI[providerName.toLowerCase()];
3451
3454
  if (piProvider) {
3452
3455
  try {
3453
- return getModel(piProvider, modelId);
3456
+ const model = getModel(piProvider, modelId);
3457
+ return { ...model, headers: { ...model.headers, ...DEFAULT_HEADERS } };
3454
3458
  } catch {
3455
3459
  }
3456
3460
  }
@@ -3465,11 +3469,12 @@ function resolveModel(providerName, modelId, providerConfig) {
3465
3469
  api: apiType,
3466
3470
  provider: providerName.toLowerCase(),
3467
3471
  baseUrl,
3468
- reasoning: false,
3472
+ reasoning: true,
3469
3473
  input: ["text"],
3470
3474
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
3471
3475
  contextWindow: 128e3,
3472
- maxTokens: 16384
3476
+ maxTokens: 16384,
3477
+ headers: DEFAULT_HEADERS
3473
3478
  };
3474
3479
  }
3475
3480
 
@@ -5004,7 +5009,7 @@ function createAskUserRoutes() {
5004
5009
  import { Hono as Hono2 } from "hono";
5005
5010
 
5006
5011
  // src/features/chat/chat-post.route.ts
5007
- import { randomUUID as randomUUID3 } from "crypto";
5012
+ import { randomUUID as randomUUID4 } from "crypto";
5008
5013
 
5009
5014
  // src/features/skills/skills.manager.ts
5010
5015
  import { readdir as readdir4, readFile as readFile4 } from "fs/promises";
@@ -5723,6 +5728,214 @@ async function invalidateGitStatusCache(db, threadId) {
5723
5728
  await db.execute("DELETE FROM git_status_cache WHERE threadId = ?", [threadId]);
5724
5729
  }
5725
5730
 
5731
+ // src/features/account/account-get-info.route.ts
5732
+ init_database();
5733
+ import { randomUUID as randomUUID3 } from "crypto";
5734
+
5735
+ // src/core/crypto.ts
5736
+ init_database();
5737
+ import { createCipheriv, createDecipheriv, randomBytes as randomBytes2, createHash } from "crypto";
5738
+ import { networkInterfaces, hostname } from "os";
5739
+ var ALGORITHM = "aes-256-gcm";
5740
+ var IV_LENGTH = 16;
5741
+ function getMachineKey() {
5742
+ try {
5743
+ const interfaces = networkInterfaces();
5744
+ let macAddress = "";
5745
+ for (const name of Object.keys(interfaces)) {
5746
+ const iface = interfaces[name];
5747
+ if (iface) {
5748
+ for (const addr of iface) {
5749
+ if (addr.mac && addr.mac !== "00:00:00:00:00:00" && !addr.internal) {
5750
+ macAddress = addr.mac;
5751
+ break;
5752
+ }
5753
+ }
5754
+ if (macAddress) break;
5755
+ }
5756
+ }
5757
+ const host = hostname();
5758
+ const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "";
5759
+ const machineId = `${macAddress}-${host}-${homeDir}`;
5760
+ return createHash("sha256").update(machineId).digest();
5761
+ } catch {
5762
+ return Buffer.from("Invalid", "utf8");
5763
+ }
5764
+ }
5765
+ async function getEncryptionKey() {
5766
+ try {
5767
+ const db = await getDatabase();
5768
+ const result = await db.execute({
5769
+ sql: "SELECT value FROM state WHERE key = ?",
5770
+ args: ["encryption_key"]
5771
+ });
5772
+ if (result.rows.length > 0 && result.rows[0].value) {
5773
+ const storedValue = result.rows[0].value;
5774
+ try {
5775
+ const parsed = JSON.parse(storedValue);
5776
+ return Buffer.from(parsed, "base64");
5777
+ } catch {
5778
+ return Buffer.from(storedValue, "base64");
5779
+ }
5780
+ }
5781
+ const machineKey = getMachineKey();
5782
+ await db.execute({
5783
+ sql: "INSERT OR REPLACE INTO state (key, value) VALUES (?, ?)",
5784
+ args: ["encryption_key", machineKey.toString("base64")]
5785
+ });
5786
+ return machineKey;
5787
+ } catch {
5788
+ return getMachineKey();
5789
+ }
5790
+ }
5791
+ async function encrypt(plaintext) {
5792
+ if (!plaintext) {
5793
+ return "";
5794
+ }
5795
+ const key = await getEncryptionKey();
5796
+ const iv = randomBytes2(IV_LENGTH);
5797
+ const cipher = createCipheriv(ALGORITHM, key, iv);
5798
+ let encrypted = cipher.update(plaintext, "utf8", "base64");
5799
+ encrypted += cipher.final("base64");
5800
+ const authTag = cipher.getAuthTag();
5801
+ const result = `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted}`;
5802
+ return result;
5803
+ }
5804
+ async function decrypt(encryptedData) {
5805
+ if (!encryptedData) {
5806
+ return "";
5807
+ }
5808
+ try {
5809
+ const parts = encryptedData.split(":");
5810
+ if (parts.length !== 3) {
5811
+ throw new Error("Invalid encrypted data format");
5812
+ }
5813
+ const [ivBase64, authTagBase64, encrypted] = parts;
5814
+ const key = await getEncryptionKey();
5815
+ const iv = Buffer.from(ivBase64, "base64");
5816
+ const authTag = Buffer.from(authTagBase64, "base64");
5817
+ const decipher = createDecipheriv(ALGORITHM, key, iv);
5818
+ decipher.setAuthTag(authTag);
5819
+ let decrypted = decipher.update(encrypted, "base64", "utf8");
5820
+ decrypted += decipher.final("utf8");
5821
+ return decrypted;
5822
+ } catch (error) {
5823
+ throw new Error(
5824
+ `Decryption failed: ${error instanceof Error ? error.message : "Unknown error"}`
5825
+ );
5826
+ }
5827
+ }
5828
+ function isEncrypted(value) {
5829
+ if (!value) {
5830
+ return false;
5831
+ }
5832
+ const parts = value.split(":");
5833
+ if (parts.length !== 3) {
5834
+ return false;
5835
+ }
5836
+ const base64Regex = /^[A-Za-z0-9+/]+=*$/;
5837
+ return parts.every((part) => base64Regex.test(part));
5838
+ }
5839
+
5840
+ // src/features/account/account-get-info.route.ts
5841
+ var KEY_BALANCE = "PromptBalance";
5842
+ var KEY_VERIFICATION = "PromptBalanceVerification";
5843
+ var KEY_PLAN = "Plan";
5844
+ var KEY_CLIENT_REFERENCE_ID = "clientReferenceId";
5845
+ var DEFAULT_BALANCE = 1e3;
5846
+ async function writeBalance(balance) {
5847
+ const db = await getDatabase();
5848
+ const verification = await encrypt(String(balance));
5849
+ await db.batch([
5850
+ {
5851
+ sql: "INSERT OR REPLACE INTO state (key, value) VALUES (?, ?)",
5852
+ args: [KEY_BALANCE, JSON.stringify(balance)]
5853
+ },
5854
+ {
5855
+ sql: "INSERT OR REPLACE INTO state (key, value) VALUES (?, ?)",
5856
+ args: [KEY_VERIFICATION, JSON.stringify(verification)]
5857
+ }
5858
+ ]);
5859
+ }
5860
+ async function readVerifiedBalance() {
5861
+ const db = await getDatabase();
5862
+ const rawBalance = await getState(db, KEY_BALANCE);
5863
+ if (rawBalance === null || rawBalance === void 0) {
5864
+ await writeBalance(DEFAULT_BALANCE);
5865
+ return DEFAULT_BALANCE;
5866
+ }
5867
+ const balance = rawBalance;
5868
+ const rawVerification = await getState(db, KEY_VERIFICATION);
5869
+ if (rawVerification === null || rawVerification === void 0) {
5870
+ throw new Error("PromptBalanceVerification is missing \u2014 balance integrity cannot be confirmed");
5871
+ }
5872
+ const decrypted = await decrypt(rawVerification);
5873
+ if (decrypted !== String(balance)) {
5874
+ throw new Error(
5875
+ "PromptBalance integrity check failed: verification does not match stored balance"
5876
+ );
5877
+ }
5878
+ return balance;
5879
+ }
5880
+ async function getOrCreateClientReferenceId() {
5881
+ const db = await getDatabase();
5882
+ const existing = await getState(db, KEY_CLIENT_REFERENCE_ID);
5883
+ if (existing !== null && existing !== void 0) {
5884
+ return existing;
5885
+ }
5886
+ const id = randomUUID3();
5887
+ await setState(db, KEY_CLIENT_REFERENCE_ID, id);
5888
+ return id;
5889
+ }
5890
+ async function decrementBalance() {
5891
+ const current = await readVerifiedBalance();
5892
+ if (current <= 0) return;
5893
+ await writeBalance(current - 1);
5894
+ }
5895
+ async function processPayments(clientReferenceId) {
5896
+ const controller = new AbortController();
5897
+ const timeoutId = setTimeout(() => controller.abort(), 5e3);
5898
+ try {
5899
+ const res = await fetch(`https://payments.webnative.dev/account/${clientReferenceId}`, {
5900
+ method: "POST",
5901
+ signal: controller.signal
5902
+ });
5903
+ if (!res.ok) return;
5904
+ const data = await res.json();
5905
+ if (!data.success || !data.lineItems?.length) return;
5906
+ const db = await getDatabase();
5907
+ for (const item of data.lineItems) {
5908
+ if (item === "top-up-1000") {
5909
+ const current = await readVerifiedBalance();
5910
+ await writeBalance(current + 1e3);
5911
+ } else if (item === "pro-plan") {
5912
+ await setState(db, KEY_PLAN, "unlimited-pro");
5913
+ }
5914
+ }
5915
+ } catch {
5916
+ return;
5917
+ } finally {
5918
+ clearTimeout(timeoutId);
5919
+ }
5920
+ }
5921
+ async function getAccountInfo(c) {
5922
+ try {
5923
+ const db = await getDatabase();
5924
+ const clientReferenceId = await getOrCreateClientReferenceId();
5925
+ await processPayments(clientReferenceId);
5926
+ const promptsRemaining = await readVerifiedBalance();
5927
+ const rawPlan = await getState(db, KEY_PLAN);
5928
+ const plan = rawPlan === "unlimited-pro" ? "unlimited-pro" : "pay-as-you-go";
5929
+ return c.json({ promptsRemaining, plan, clientReferenceId });
5930
+ } catch (error) {
5931
+ console.error("Failed to get account info:", error);
5932
+ return c.json(
5933
+ { error: error instanceof Error ? error.message : "Failed to get account info" },
5934
+ 500
5935
+ );
5936
+ }
5937
+ }
5938
+
5726
5939
  // src/features/chat/chat-post.route.ts
5727
5940
  async function postChatMessage(c, threadManager, agentExecutor, conversationManager, processingStateManager) {
5728
5941
  try {
@@ -5825,7 +6038,7 @@ async function postChatMessage(c, threadManager, agentExecutor, conversationMana
5825
6038
  }
5826
6039
  let conversationId = thread.currentConversationId;
5827
6040
  if (!conversationId) {
5828
- conversationId = randomUUID3();
6041
+ conversationId = randomUUID4();
5829
6042
  const db = await getDatabase();
5830
6043
  await db.execute({
5831
6044
  sql: "DELETE FROM todos WHERE threadId = ?",
@@ -5955,6 +6168,14 @@ User: ${content}` : content;
5955
6168
  }
5956
6169
  } finally {
5957
6170
  processingStateManager.clearProcessing(threadId);
6171
+ const noResponse = capturedEvents.some(
6172
+ (e) => e.type === "error" && e.error?.code === "NO_CONTENT_NO_TOOLS"
6173
+ );
6174
+ if (!noResponse) {
6175
+ decrementBalance().catch((err) => {
6176
+ console.error("[ChatRoute] Failed to decrement balance:", err);
6177
+ });
6178
+ }
5958
6179
  try {
5959
6180
  const db = await getDatabase();
5960
6181
  await invalidateGitStatusCache(db, threadId);
@@ -5995,7 +6216,7 @@ User: ${content}` : content;
5995
6216
  }
5996
6217
 
5997
6218
  // src/features/chat/chat-delete.route.ts
5998
- import { randomUUID as randomUUID4 } from "crypto";
6219
+ import { randomUUID as randomUUID5 } from "crypto";
5999
6220
  init_database();
6000
6221
  async function deleteChat(c, threadManager) {
6001
6222
  try {
@@ -6017,7 +6238,7 @@ async function deleteChat(c, threadManager) {
6017
6238
  sql: "DELETE FROM todos WHERE threadId = ?",
6018
6239
  args: [threadId]
6019
6240
  });
6020
- const newConversationId = randomUUID4();
6241
+ const newConversationId = randomUUID5();
6021
6242
  await threadManager.updateThread(threadId, { currentConversationId: newConversationId });
6022
6243
  return successResponse(
6023
6244
  c,
@@ -6129,10 +6350,10 @@ function createChatRoutes(threadManager, agentExecutor, conversationManager, pro
6129
6350
  init_database();
6130
6351
 
6131
6352
  // src/features/conversations/conversations.database.ts
6132
- import { randomUUID as randomUUID5 } from "crypto";
6353
+ import { randomUUID as randomUUID6 } from "crypto";
6133
6354
  async function insertMessage(db, threadId, conversationId, message, model, attachments, planMode) {
6134
6355
  try {
6135
- const messageId = randomUUID5();
6356
+ const messageId = randomUUID6();
6136
6357
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
6137
6358
  await db.execute(
6138
6359
  `
@@ -7477,111 +7698,6 @@ function deserializeThread(row) {
7477
7698
  };
7478
7699
  }
7479
7700
 
7480
- // src/core/crypto.ts
7481
- init_database();
7482
- import { createCipheriv, createDecipheriv, randomBytes as randomBytes2, createHash } from "crypto";
7483
- import { networkInterfaces, hostname } from "os";
7484
- var ALGORITHM = "aes-256-gcm";
7485
- var IV_LENGTH = 16;
7486
- function getMachineKey() {
7487
- try {
7488
- const interfaces = networkInterfaces();
7489
- let macAddress = "";
7490
- for (const name of Object.keys(interfaces)) {
7491
- const iface = interfaces[name];
7492
- if (iface) {
7493
- for (const addr of iface) {
7494
- if (addr.mac && addr.mac !== "00:00:00:00:00:00" && !addr.internal) {
7495
- macAddress = addr.mac;
7496
- break;
7497
- }
7498
- }
7499
- if (macAddress) break;
7500
- }
7501
- }
7502
- const host = hostname();
7503
- const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "";
7504
- const machineId = `${macAddress}-${host}-${homeDir}`;
7505
- return createHash("sha256").update(machineId).digest();
7506
- } catch {
7507
- return Buffer.from("Invalid", "utf8");
7508
- }
7509
- }
7510
- async function getEncryptionKey() {
7511
- try {
7512
- const db = await getDatabase();
7513
- const result = await db.execute({
7514
- sql: "SELECT value FROM state WHERE key = ?",
7515
- args: ["encryption_key"]
7516
- });
7517
- if (result.rows.length > 0 && result.rows[0].value) {
7518
- const storedValue = result.rows[0].value;
7519
- try {
7520
- const parsed = JSON.parse(storedValue);
7521
- return Buffer.from(parsed, "base64");
7522
- } catch {
7523
- return Buffer.from(storedValue, "base64");
7524
- }
7525
- }
7526
- const machineKey = getMachineKey();
7527
- await db.execute({
7528
- sql: "INSERT OR REPLACE INTO state (key, value) VALUES (?, ?)",
7529
- args: ["encryption_key", machineKey.toString("base64")]
7530
- });
7531
- return machineKey;
7532
- } catch {
7533
- return getMachineKey();
7534
- }
7535
- }
7536
- async function encrypt(plaintext) {
7537
- if (!plaintext) {
7538
- return "";
7539
- }
7540
- const key = await getEncryptionKey();
7541
- const iv = randomBytes2(IV_LENGTH);
7542
- const cipher = createCipheriv(ALGORITHM, key, iv);
7543
- let encrypted = cipher.update(plaintext, "utf8", "base64");
7544
- encrypted += cipher.final("base64");
7545
- const authTag = cipher.getAuthTag();
7546
- const result = `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted}`;
7547
- return result;
7548
- }
7549
- async function decrypt(encryptedData) {
7550
- if (!encryptedData) {
7551
- return "";
7552
- }
7553
- try {
7554
- const parts = encryptedData.split(":");
7555
- if (parts.length !== 3) {
7556
- throw new Error("Invalid encrypted data format");
7557
- }
7558
- const [ivBase64, authTagBase64, encrypted] = parts;
7559
- const key = await getEncryptionKey();
7560
- const iv = Buffer.from(ivBase64, "base64");
7561
- const authTag = Buffer.from(authTagBase64, "base64");
7562
- const decipher = createDecipheriv(ALGORITHM, key, iv);
7563
- decipher.setAuthTag(authTag);
7564
- let decrypted = decipher.update(encrypted, "base64", "utf8");
7565
- decrypted += decipher.final("utf8");
7566
- return decrypted;
7567
- } catch (error) {
7568
- throw new Error(
7569
- `Decryption failed: ${error instanceof Error ? error.message : "Unknown error"}`
7570
- );
7571
- }
7572
- }
7573
- function isEncrypted(value) {
7574
- if (!value) {
7575
- return false;
7576
- }
7577
- const parts = value.split(":");
7578
- if (parts.length !== 3) {
7579
- return false;
7580
- }
7581
- const base64Regex = /^[A-Za-z0-9+/]+=*$/;
7582
- return parts.every((part) => base64Regex.test(part));
7583
- }
7584
-
7585
7701
  // src/database/database.encryption.ts
7586
7702
  async function encryptProviderKey(key) {
7587
7703
  if (!key) {
@@ -9758,7 +9874,7 @@ var ProcessManager = class extends EventEmitter {
9758
9874
 
9759
9875
  // src/features/projects/projects.creator.ts
9760
9876
  init_utils();
9761
- import { randomUUID as randomUUID6 } from "crypto";
9877
+ import { randomUUID as randomUUID7 } from "crypto";
9762
9878
  import { basename as basename2, join as join16, relative as relative4 } from "path";
9763
9879
  import { access as access3, stat as stat3, readdir as readdir8 } from "fs/promises";
9764
9880
 
@@ -10767,14 +10883,14 @@ var ProjectCreator = class {
10767
10883
  }
10768
10884
  let initialThreadId;
10769
10885
  try {
10770
- const projectId = randomUUID6();
10886
+ const projectId = randomUUID7();
10771
10887
  const existingProjects = await this.metadataManager.loadProjects();
10772
10888
  const existingNames = existingProjects.map((p) => p.name);
10773
10889
  const projectName = this.ensureUniqueProjectName(
10774
10890
  this.deriveProjectName(gitUrl),
10775
10891
  existingNames
10776
10892
  );
10777
- initialThreadId = randomUUID6();
10893
+ initialThreadId = randomUUID7();
10778
10894
  const initialThreadTitle = generateRandomThreadName();
10779
10895
  const firstThreadPath = this.generateThreadPath(projectId, initialThreadId);
10780
10896
  this.processingStateManager?.setProcessing(initialThreadId);
@@ -10914,8 +11030,8 @@ var ProjectCreator = class {
10914
11030
  };
10915
11031
  return;
10916
11032
  }
10917
- const projectId = randomUUID6();
10918
- const initialThreadId = randomUUID6();
11033
+ const projectId = randomUUID7();
11034
+ const initialThreadId = randomUUID7();
10919
11035
  const initialThreadTitle = generateRandomThreadName();
10920
11036
  this.processingStateManager?.setProcessing(initialThreadId);
10921
11037
  try {
@@ -11065,8 +11181,8 @@ var ProjectCreator = class {
11065
11181
  yield { type: "error", message: `Cannot access folder: ${folderPath}` };
11066
11182
  return;
11067
11183
  }
11068
- const projectId = randomUUID6();
11069
- const initialThreadId = randomUUID6();
11184
+ const projectId = randomUUID7();
11185
+ const initialThreadId = randomUUID7();
11070
11186
  const initialThreadTitle = generateRandomThreadName();
11071
11187
  this.processingStateManager?.setProcessing(initialThreadId);
11072
11188
  try {
@@ -12697,7 +12813,7 @@ function createRuleRoutes(router, projectManager) {
12697
12813
 
12698
12814
  // src/features/threads/threads.manager.ts
12699
12815
  init_utils();
12700
- import { randomUUID as randomUUID7 } from "crypto";
12816
+ import { randomUUID as randomUUID8 } from "crypto";
12701
12817
  import { join as join20 } from "path";
12702
12818
  import { execSync as execSync3 } from "child_process";
12703
12819
  import { rm as rm4, stat as stat4, mkdir as mkdir4 } from "fs/promises";
@@ -12764,7 +12880,7 @@ var ThreadManagerImpl = class {
12764
12880
  } catch {
12765
12881
  await mkdir4(project.path, { recursive: true });
12766
12882
  }
12767
- threadId = randomUUID7();
12883
+ threadId = randomUUID8();
12768
12884
  const threadPath = this.generateThreadPath(projectId, threadId);
12769
12885
  const existingThreads = await this.metadataManager.loadThreads();
12770
12886
  const existingTitles = new Set(
@@ -14445,7 +14561,7 @@ DESCRIPTION: <description here>`;
14445
14561
  try {
14446
14562
  const providerKeys = await metadataManager.getProviderKeys();
14447
14563
  const resolved = await resolveProviderAndKey(providerKeys, provider);
14448
- if (!resolved?.provider?.api) {
14564
+ if (!resolved) {
14449
14565
  const errorMsg = provider ? `AI provider "${provider}" is specified but no API key is configured. Please add the API key in settings.` : `No AI provider configured. Please configure a provider in settings.`;
14450
14566
  console.log(`[pr-generation] ${errorMsg}`);
14451
14567
  return { title: "Update", description: "" };
@@ -14500,7 +14616,7 @@ Generate only the commit message, nothing else:`;
14500
14616
  try {
14501
14617
  const providerKeys = await metadataManager.getProviderKeys();
14502
14618
  const resolved = await resolveProviderAndKey(providerKeys, provider);
14503
- if (!resolved?.provider?.api) {
14619
+ if (!resolved) {
14504
14620
  const errorMsg = provider ? `AI provider "${provider}" is specified but no API key is configured. Please add the API key in settings.` : `No AI provider configured. Please configure a provider in settings.`;
14505
14621
  process.stdout.write(`[generate-commit-message] ${errorMsg}
14506
14622
  `);
@@ -16900,7 +17016,7 @@ Todo description: ${description}`;
16900
17016
  try {
16901
17017
  const providerKeys = await metadataManager.getProviderKeys();
16902
17018
  const resolved = await resolveProviderAndKey(providerKeys);
16903
- if (!resolved?.provider.api) return description.slice(0, 60);
17019
+ if (!resolved) return description.slice(0, 60);
16904
17020
  const selectedModel = DEFAULT_MODEL_MAP[resolved.provider.name] || "default";
16905
17021
  const resolvedModel = resolveModelForGit(
16906
17022
  resolved.provider.name,
@@ -16974,13 +17090,21 @@ function createProjectTodosRoutes(metadataManager) {
16974
17090
  return router;
16975
17091
  }
16976
17092
 
17093
+ // src/features/account/account.routes.ts
17094
+ import { Hono as Hono15 } from "hono";
17095
+ function createAccountRoutes() {
17096
+ const router = new Hono15();
17097
+ router.get("/info", (c) => getAccountInfo(c));
17098
+ return router;
17099
+ }
17100
+
16977
17101
  // src/server.ts
16978
17102
  var __filename = fileURLToPath2(import.meta.url);
16979
17103
  var __dirname = path5.dirname(__filename);
16980
17104
  async function startTarskServer(options) {
16981
17105
  const { isDebug: isDebug2, publicDir: publicDirOverride } = options;
16982
17106
  const port = isDebug2 ? 462 : process.env.PORT ? parseInt(process.env.PORT) : 641;
16983
- const app = new Hono15();
17107
+ const app = new Hono16();
16984
17108
  app.use("/*", cors());
16985
17109
  app.use("/*", async (c, next) => {
16986
17110
  if (c.req.path.startsWith("/api/")) {
@@ -17044,6 +17168,7 @@ async function startTarskServer(options) {
17044
17168
  app.route("/api/mcp", createMCPRoutes());
17045
17169
  app.route("/api/git", createGitRoutes(metadataManager));
17046
17170
  app.route("/api/onboarding", createOnboardingRoutes(metadataManager));
17171
+ app.route("/api/account", createAccountRoutes());
17047
17172
  app.route("/api/scaffold", createScaffoldRoutes(projectManager));
17048
17173
  app.route("/api/ask-user", createAskUserRoutes());
17049
17174
  app.route("/api/update", createUpdateRoutes(options.updater));
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{Fi as t,Ir as n,Kn as r,Nt as i,X as a,Xn as o,li as s,wi as c,zr as l}from"./dialogs-config-CdogKQE6.js";import{t as u}from"./use-toast-DCmq-wgl.js";var d=e(t(),1),f=o();function p(){let[e,t]=(0,d.useState)(null),[o,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 a())}catch(e){u({title:`Error`,description:e instanceof Error?e.message:`Failed to load account info`,variant:`destructive`})}finally{p(!1)}}function h(){i(`https://buy.stripe.com/14AcN6feK0Jjbheb2H3Nm03?client_reference_id=${e?.clientReferenceId??``}`)}function g(){i(`https://buy.stripe.com/9B67sMd6CgIh70Y0o33Nm04?client_reference_id=${e?.clientReferenceId??``}`)}if(o)return(0,f.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,f.jsx)(l,{className:`h-5 w-5 animate-spin text-muted-foreground`})});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)(n,{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)(s,{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)(r,{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)(s,{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)(c,{className:`h-3 w-3 text-primary`}),`Unlimited prompts`]}),(0,f.jsxs)(`li`,{className:`flex items-center gap-1.5`,children:[(0,f.jsx)(c,{className:`h-3 w-3 text-primary`}),`Priority access`]})]})]}),(0,f.jsx)(r,{onClick:g,className:`shrink-0`,children:`Purchase`})]})]})]})]})}export{p as default};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{F as t,Jn as n,Lr as r,Mi as i,Wn as a,c as o,l as s,vi as c}from"./dialogs-config-DiFQjCeA.js";import"./react-vendor-DkKo9QGO.js";import"./history-view-B8HM78Wa.js";import{t as l}from"./use-toast-DEJkXPN4.js";import{d as u}from"./index-C-p81QYw.js";import{n as d,t as f}from"./radio-group-BItFbSTw.js";var p=e(i(),1),m=n();function h({threadId:e,onAgentCreated:n}){let[i,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(``),[v,y]=(0,p.useState)(``),[b,x]=(0,p.useState)(`local`),[S,C]=(0,p.useState)(!1),w=i.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``),T=w.length>0&&w.length<=64;return e?(0,m.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,m.jsxs)(`div`,{className:`mb-6`,children:[(0,m.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Add Agent`}),(0,m.jsx)(`p`,{className:`text-muted-foreground`,children:`Create a new subagent. The agent will be saved as an AGENT.md file in the .agents/agents folder.`})]}),(0,m.jsxs)(`div`,{className:`space-y-6`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(s,{htmlFor:`agentName`,children:`Agent Name`}),(0,m.jsx)(o,{id:`agentName`,value:i,onChange:e=>h(e.target.value),placeholder:`e.g. Security Reviewer`,disabled:S}),i&&(0,m.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Folder name: `,(0,m.jsx)(`span`,{className:`font-mono`,children:w||`...`})]})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(s,{htmlFor:`agentDescription`,children:`Description`}),(0,m.jsx)(u,{id:`agentDescription`,value:g,onChange:e=>_(e.target.value),placeholder:`Describe what this agent does and when it should be invoked`,className:`resize-none min-h-[120px]`,disabled:S})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(s,{htmlFor:`agentTools`,children:`Allowed Tools (optional)`}),(0,m.jsx)(o,{id:`agentTools`,value:v,onChange:e=>y(e.target.value),placeholder:`e.g. read grep glob`,disabled:S}),(0,m.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Space-separated list of tools this agent can use. Leave empty to allow all coding tools.`})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(s,{children:`Scope`}),(0,m.jsxs)(f,{value:b,onValueChange:e=>x(e),className:`flex gap-4`,disabled:S,children:[(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`local`,id:`scope-local`}),(0,m.jsx)(s,{htmlFor:`scope-local`,className:`font-normal cursor-pointer`,children:`Local (this project)`})]}),(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`global`,id:`scope-global`,disabled:!0}),(0,m.jsx)(s,{htmlFor:`scope-global`,className:`font-normal cursor-pointer text-muted-foreground`,children:`Global (coming soon)`})]})]}),(0,m.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:b===`local`?`This agent will only be available for this project.`:`This agent will be available across all projects (coming soon).`})]}),(0,m.jsx)(`div`,{className:`border-t pt-4 flex justify-end`,children:(0,m.jsx)(a,{onClick:async()=>{if(!(!T||!g.trim()||!e)){C(!0);try{let r=await t(e,w,g.trim(),v.trim()||void 0);l({title:`Agent created`,description:`Agent '${w}' was created successfully.`}),h(``),_(``),y(``),x(`local`),n?.(r.path,`AGENT.md`)}catch(e){l({title:`Error`,description:e instanceof Error?e.message:`Failed to create agent`,variant:`destructive`})}finally{C(!1)}}},disabled:!T||!g.trim()||S,children:S?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(r,{className:`mr-2 h-4 w-4 animate-spin`}),`Creating...`]}):(0,m.jsxs)(m.Fragment,{children:[`Continue`,(0,m.jsx)(c,{className:`ml-2 h-4 w-4`})]})})})]})]}):(0,m.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,m.jsxs)(`div`,{className:`text-center`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-semibold text-muted-foreground mb-2`,children:`No Thread Selected`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Please select a thread to add an agent.`})]})})}export{h as default};
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{Fi as t,I as n,Kn as r,Xn as i,c as a,l as o,xi as s,zr as c}from"./dialogs-config-CdogKQE6.js";import"./react-vendor-BNQTbRKd.js";import"./history-view-DtTMEZIl.js";import{t as l}from"./use-toast-DCmq-wgl.js";import{a as u}from"./index-BR4u03pf.js";import{n as d,t as f}from"./radio-group-BQ7i054U.js";var p=e(t(),1),m=i();function h({threadId:e,onAgentCreated:t}){let[i,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(``),[v,y]=(0,p.useState)(``),[b,x]=(0,p.useState)(`local`),[S,C]=(0,p.useState)(!1),w=i.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``),T=w.length>0&&w.length<=64;return e?(0,m.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,m.jsxs)(`div`,{className:`mb-6`,children:[(0,m.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Add Agent`}),(0,m.jsx)(`p`,{className:`text-muted-foreground`,children:`Create a new subagent. The agent will be saved as an AGENT.md file in the .agents/agents folder.`})]}),(0,m.jsxs)(`div`,{className:`space-y-6`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(o,{htmlFor:`agentName`,children:`Agent Name`}),(0,m.jsx)(a,{id:`agentName`,value:i,onChange:e=>h(e.target.value),placeholder:`e.g. Security Reviewer`,disabled:S}),i&&(0,m.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Folder name: `,(0,m.jsx)(`span`,{className:`font-mono`,children:w||`...`})]})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(o,{htmlFor:`agentDescription`,children:`Description`}),(0,m.jsx)(u,{id:`agentDescription`,value:g,onChange:e=>_(e.target.value),placeholder:`Describe what this agent does and when it should be invoked`,className:`resize-none min-h-[120px]`,disabled:S})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(o,{htmlFor:`agentTools`,children:`Allowed Tools (optional)`}),(0,m.jsx)(a,{id:`agentTools`,value:v,onChange:e=>y(e.target.value),placeholder:`e.g. read grep glob`,disabled:S}),(0,m.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Space-separated list of tools this agent can use. Leave empty to allow all coding tools.`})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(o,{children:`Scope`}),(0,m.jsxs)(f,{value:b,onValueChange:e=>x(e),className:`flex gap-4`,disabled:S,children:[(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`local`,id:`scope-local`}),(0,m.jsx)(o,{htmlFor:`scope-local`,className:`font-normal cursor-pointer`,children:`Local (this project)`})]}),(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`global`,id:`scope-global`,disabled:!0}),(0,m.jsx)(o,{htmlFor:`scope-global`,className:`font-normal cursor-pointer text-muted-foreground`,children:`Global (coming soon)`})]})]}),(0,m.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:b===`local`?`This agent will only be available for this project.`:`This agent will be available across all projects (coming soon).`})]}),(0,m.jsx)(`div`,{className:`border-t pt-4 flex justify-end`,children:(0,m.jsx)(r,{onClick:async()=>{if(!(!T||!g.trim()||!e)){C(!0);try{let r=await n(e,w,g.trim(),v.trim()||void 0);l({title:`Agent created`,description:`Agent '${w}' was created successfully.`}),h(``),_(``),y(``),x(`local`),t?.(r.path,`AGENT.md`)}catch(e){l({title:`Error`,description:e instanceof Error?e.message:`Failed to create agent`,variant:`destructive`})}finally{C(!1)}}},disabled:!T||!g.trim()||S,children:S?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(c,{className:`mr-2 h-4 w-4 animate-spin`}),`Creating...`]}):(0,m.jsxs)(m.Fragment,{children:[`Continue`,(0,m.jsx)(s,{className:`ml-2 h-4 w-4`})]})})})]})]}):(0,m.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,m.jsxs)(`div`,{className:`text-center`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-semibold text-muted-foreground mb-2`,children:`No Thread Selected`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Please select a thread to add an agent.`})]})})}export{h as default};
@@ -0,0 +1,7 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{$n as t,Fi as n,Kn as r,Ni as i,Ut as a,Xn as o,c as s,l as c,xi as l,zr as u}from"./dialogs-config-CdogKQE6.js";import{i as d,r as f}from"./react-vendor-BNQTbRKd.js";import"./history-view-DtTMEZIl.js";import{t as p}from"./use-toast-DCmq-wgl.js";import{a as m}from"./index-BR4u03pf.js";import{n as h,t as g}from"./radio-group-BQ7i054U.js";var _=i(),v=e(n(),1),y=o(),b=v.forwardRef((e,n)=>{let r=(0,_.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]===i?o=r[4]:(o=t(`peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input`,i),r[3]=i,r[4]=o);let s;r[5]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,y.jsx)(d,{className:t(`pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0`)}),r[5]=s):s=r[5];let c;return r[6]!==a||r[7]!==n||r[8]!==o?(c=(0,y.jsx)(f,{className:o,...a,ref:n,children:s}),r[6]=a,r[7]=n,r[8]=o,r[9]=c):c=r[9],c});b.displayName=f.displayName;function x({threadId:e,onRuleCreated:t}){let[n,i]=(0,v.useState)(``),[o,d]=(0,v.useState)(``),[f,_]=(0,v.useState)(!1),[x,S]=(0,v.useState)(`local`),[C,w]=(0,v.useState)(!1),T=n.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``),E=T.length>0&&T.length<=64;return e?(0,y.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,y.jsxs)(`div`,{className:`mb-6`,children:[(0,y.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Add Rule`}),(0,y.jsx)(`p`,{className:`text-muted-foreground`,children:`Create a new agent rule. The rule will be saved as a .md file in the .agents/rules folder.`})]}),(0,y.jsxs)(`div`,{className:`space-y-6`,children:[(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsx)(c,{htmlFor:`ruleName`,children:`Rule Name`}),(0,y.jsx)(s,{id:`ruleName`,value:n,onChange:e=>i(e.target.value),placeholder:`e.g. Code Style Guide`,disabled:C}),n&&(0,y.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`File name: `,(0,y.jsxs)(`span`,{className:`font-mono`,children:[T||`...`,`.md`]})]})]}),(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsx)(c,{htmlFor:`ruleDescription`,children:`Description`}),(0,y.jsx)(m,{id:`ruleDescription`,value:o,onChange:e=>d(e.target.value),placeholder:`Describe when Tarsk should apply this rule...`,className:`resize-none min-h-[120px]`,disabled:C})]}),(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,y.jsx)(c,{htmlFor:`alwaysApply`,children:`Always Apply`}),(0,y.jsx)(b,{id:`alwaysApply`,checked:f,onCheckedChange:_,disabled:C})]}),(0,y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:f?`This rule will be automatically added to context for all conversations.`:`Only the rule description will be added to context, allowing the agent to read the rule file when needed.`})]}),(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsx)(c,{children:`Scope`}),(0,y.jsxs)(g,{value:x,onValueChange:e=>S(e),className:`flex gap-4`,disabled:C,children:[(0,y.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,y.jsx)(h,{value:`local`,id:`scope-local`}),(0,y.jsx)(c,{htmlFor:`scope-local`,className:`font-normal cursor-pointer`,children:`Local (this project)`})]}),(0,y.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,y.jsx)(h,{value:`global`,id:`scope-global`,disabled:!0}),(0,y.jsx)(c,{htmlFor:`scope-global`,className:`font-normal cursor-pointer text-muted-foreground`,children:`Global (coming soon)`})]})]}),(0,y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:x===`local`?`This rule will only be available for this project.`:`This rule will be available across all projects (coming soon).`})]}),(0,y.jsx)(`div`,{className:`border-t pt-4 flex justify-end`,children:(0,y.jsx)(r,{onClick:async()=>{if(!(!E||!e)){w(!0);try{let n=`---
2
+ description: ${o.trim()}
3
+ alwaysApply: ${f}
4
+ ---
5
+
6
+ Place your rule instructions here as markdown.
7
+ `;await a(e,`.agents/rules/${T}.md`,n),p({title:`Rule created`,description:`Rule '${T}' was created successfully.`}),i(``),d(``),_(!1),S(`local`),t?.(T)}catch(e){p({title:`Error`,description:e instanceof Error?e.message:`Failed to create rule`,variant:`destructive`})}finally{w(!1)}}},disabled:!E||!o.trim()||C,children:C?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(u,{className:`mr-2 h-4 w-4 animate-spin`}),`Creating...`]}):(0,y.jsxs)(y.Fragment,{children:[`Continue`,(0,y.jsx)(l,{className:`ml-2 h-4 w-4`})]})})})]})]}):(0,y.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,y.jsxs)(`div`,{className:`text-center`,children:[(0,y.jsx)(`h2`,{className:`text-lg font-semibold text-muted-foreground mb-2`,children:`No Thread Selected`}),(0,y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Please select a thread to add a rule.`})]})})}export{x as default};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{I as t,Jn as n,Lr as r,Mi as i,Wn as a,c as o,l as s,vi as c}from"./dialogs-config-DiFQjCeA.js";import"./react-vendor-DkKo9QGO.js";import"./history-view-B8HM78Wa.js";import{t as l}from"./use-toast-DEJkXPN4.js";import{d as u}from"./index-C-p81QYw.js";import{n as d,t as f}from"./radio-group-BItFbSTw.js";var p=e(i(),1),m=n();function h({threadId:e,onSkillCreated:n}){let[i,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(``),[v,y]=(0,p.useState)(`local`),[b,x]=(0,p.useState)(!1),S=i.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``),C=S.length>0&&S.length<=64;return e?(0,m.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,m.jsxs)(`div`,{className:`mb-6`,children:[(0,m.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Add Skill`}),(0,m.jsx)(`p`,{className:`text-muted-foreground`,children:`Create a new agent skill. The skill will be saved as a SKILL.md file in the .agents/skills folder.`})]}),(0,m.jsxs)(`div`,{className:`space-y-6`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(s,{htmlFor:`skillName`,children:`Skill Name`}),(0,m.jsx)(o,{id:`skillName`,value:i,onChange:e=>h(e.target.value),placeholder:`e.g. Code Review`,disabled:b}),i&&(0,m.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Folder name: `,(0,m.jsx)(`span`,{className:`font-mono`,children:S||`...`})]})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(s,{htmlFor:`skillDescription`,children:`Description`}),(0,m.jsx)(u,{id:`skillDescription`,value:g,onChange:e=>_(e.target.value),placeholder:`Describe when Tarsk should apply this skill`,className:`resize-none min-h-[120px]`,disabled:b})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(s,{children:`Scope`}),(0,m.jsxs)(f,{value:v,onValueChange:e=>y(e),className:`flex gap-4`,disabled:b,children:[(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`local`,id:`scope-local`}),(0,m.jsx)(s,{htmlFor:`scope-local`,className:`font-normal cursor-pointer`,children:`Local (this project)`})]}),(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`global`,id:`scope-global`,disabled:!0}),(0,m.jsx)(s,{htmlFor:`scope-global`,className:`font-normal cursor-pointer text-muted-foreground`,children:`Global (coming soon)`})]})]}),(0,m.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:v===`local`?`This skill will only be available for this project.`:`This skill will be available across all projects (coming soon).`})]}),(0,m.jsx)(`div`,{className:`border-t pt-4 flex justify-end`,children:(0,m.jsx)(a,{onClick:async()=>{if(!(!C||!g.trim()||!e)){x(!0);try{let r=await t(e,S,g.trim());l({title:`Skill created`,description:`Skill '${S}' was created successfully.`}),h(``),_(``),y(`local`),n?.(r.path,`SKILL.md`)}catch(e){l({title:`Error`,description:e instanceof Error?e.message:`Failed to create skill`,variant:`destructive`})}finally{x(!1)}}},disabled:!C||!g.trim()||b,children:b?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(r,{className:`mr-2 h-4 w-4 animate-spin`}),`Creating...`]}):(0,m.jsxs)(m.Fragment,{children:[`Continue`,(0,m.jsx)(c,{className:`ml-2 h-4 w-4`})]})})})]})]}):(0,m.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,m.jsxs)(`div`,{className:`text-center`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-semibold text-muted-foreground mb-2`,children:`No Thread Selected`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Please select a thread to add a skill.`})]})})}export{h as default};
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{Fi as t,Kn as n,L as r,Xn as i,c as a,l as o,xi as s,zr as c}from"./dialogs-config-CdogKQE6.js";import"./react-vendor-BNQTbRKd.js";import"./history-view-DtTMEZIl.js";import{t as l}from"./use-toast-DCmq-wgl.js";import{a as u}from"./index-BR4u03pf.js";import{n as d,t as f}from"./radio-group-BQ7i054U.js";var p=e(t(),1),m=i();function h({threadId:e,onSkillCreated:t}){let[i,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(``),[v,y]=(0,p.useState)(`local`),[b,x]=(0,p.useState)(!1),S=i.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``),C=S.length>0&&S.length<=64;return e?(0,m.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,m.jsxs)(`div`,{className:`mb-6`,children:[(0,m.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Add Skill`}),(0,m.jsx)(`p`,{className:`text-muted-foreground`,children:`Create a new agent skill. The skill will be saved as a SKILL.md file in the .agents/skills folder.`})]}),(0,m.jsxs)(`div`,{className:`space-y-6`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(o,{htmlFor:`skillName`,children:`Skill Name`}),(0,m.jsx)(a,{id:`skillName`,value:i,onChange:e=>h(e.target.value),placeholder:`e.g. Code Review`,disabled:b}),i&&(0,m.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Folder name: `,(0,m.jsx)(`span`,{className:`font-mono`,children:S||`...`})]})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(o,{htmlFor:`skillDescription`,children:`Description`}),(0,m.jsx)(u,{id:`skillDescription`,value:g,onChange:e=>_(e.target.value),placeholder:`Describe when Tarsk should apply this skill`,className:`resize-none min-h-[120px]`,disabled:b})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(o,{children:`Scope`}),(0,m.jsxs)(f,{value:v,onValueChange:e=>y(e),className:`flex gap-4`,disabled:b,children:[(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`local`,id:`scope-local`}),(0,m.jsx)(o,{htmlFor:`scope-local`,className:`font-normal cursor-pointer`,children:`Local (this project)`})]}),(0,m.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,m.jsx)(d,{value:`global`,id:`scope-global`,disabled:!0}),(0,m.jsx)(o,{htmlFor:`scope-global`,className:`font-normal cursor-pointer text-muted-foreground`,children:`Global (coming soon)`})]})]}),(0,m.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:v===`local`?`This skill will only be available for this project.`:`This skill will be available across all projects (coming soon).`})]}),(0,m.jsx)(`div`,{className:`border-t pt-4 flex justify-end`,children:(0,m.jsx)(n,{onClick:async()=>{if(!(!C||!g.trim()||!e)){x(!0);try{let n=await r(e,S,g.trim());l({title:`Skill created`,description:`Skill '${S}' was created successfully.`}),h(``),_(``),y(`local`),t?.(n.path,`SKILL.md`)}catch(e){l({title:`Error`,description:e instanceof Error?e.message:`Failed to create skill`,variant:`destructive`})}finally{x(!1)}}},disabled:!C||!g.trim()||b,children:b?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(c,{className:`mr-2 h-4 w-4 animate-spin`}),`Creating...`]}):(0,m.jsxs)(m.Fragment,{children:[`Continue`,(0,m.jsx)(s,{className:`ml-2 h-4 w-4`})]})})})]})]}):(0,m.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,m.jsxs)(`div`,{className:`text-center`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-semibold text-muted-foreground mb-2`,children:`No Thread Selected`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Please select a thread to add a skill.`})]})})}export{h as default};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{Jn as t,Lr as n,Mi as r,N as i,Wn as a,c as o,l as s,vi as c}from"./dialogs-config-DiFQjCeA.js";import"./react-vendor-DkKo9QGO.js";import"./history-view-B8HM78Wa.js";import{t as l}from"./use-toast-DEJkXPN4.js";import{n as u,t as d}from"./radio-group-BItFbSTw.js";var f=e(r(),1),p=t();function m({projectId:e,threadId:t,onCommandCreated:r}){let[m,h]=(0,f.useState)(``),[g,_]=(0,f.useState)(``),[v,y]=(0,f.useState)(``),[b,x]=(0,f.useState)(`default`),[S,C]=(0,f.useState)(`local`),[w,T]=(0,f.useState)(!1),E=m.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``),D=E.length>0&&E.length<=64;return e?(0,p.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,p.jsxs)(`div`,{className:`mb-6`,children:[(0,p.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Add Slash Command`}),(0,p.jsx)(`p`,{className:`text-muted-foreground`,children:`Create a new slash command. The command will be saved as a .md file in the ~/.agents/commands folder.`})]}),(0,p.jsxs)(`div`,{className:`space-y-6`,children:[(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(s,{htmlFor:`commandName`,children:`Command Name`}),(0,p.jsx)(o,{id:`commandName`,value:m,onChange:e=>h(e.target.value),placeholder:`e.g. review`,disabled:w}),m&&(0,p.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Command: `,(0,p.jsxs)(`span`,{className:`font-mono`,children:[`/`,E||`...`]})]})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(s,{htmlFor:`commandDescription`,children:`Description`}),(0,p.jsx)(o,{id:`commandDescription`,value:g,onChange:e=>_(e.target.value),placeholder:`Brief description shown in autocomplete`,disabled:w})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(s,{htmlFor:`argumentHint`,children:`Argument Hint (optional)`}),(0,p.jsx)(o,{id:`argumentHint`,value:v,onChange:e=>y(e.target.value),placeholder:`e.g. <focus-area> or <branch-name>`,disabled:w}),(0,p.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Shows after the command name to guide users what to type`})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(s,{children:`Mode`}),(0,p.jsxs)(d,{value:b,onValueChange:e=>x(e),className:`flex gap-4`,disabled:w,children:[(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`default`,id:`mode-default`}),(0,p.jsx)(s,{htmlFor:`mode-default`,className:`font-normal cursor-pointer`,children:`Default`})]}),(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`plan`,id:`mode-plan`}),(0,p.jsx)(s,{htmlFor:`mode-plan`,className:`font-normal cursor-pointer`,children:`Plan`})]})]}),(0,p.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:b===`default`?`Standard chat mode`:`Activates plan mode when this command is used`})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(s,{children:`Scope`}),(0,p.jsxs)(d,{value:S,onValueChange:e=>C(e),className:`flex gap-4`,disabled:w,children:[(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`local`,id:`scope-local`}),(0,p.jsx)(s,{htmlFor:`scope-local`,className:`font-normal cursor-pointer`,children:`Local (this project)`})]}),(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`global`,id:`scope-global`,disabled:!0}),(0,p.jsx)(s,{htmlFor:`scope-global`,className:`font-normal cursor-pointer text-muted-foreground`,children:`Global (coming soon)`})]})]}),(0,p.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:S===`local`?`This command will only be available for this project.`:`This command will be available across all projects (coming soon).`})]}),(0,p.jsx)(`div`,{className:`border-t pt-4 flex justify-end`,children:(0,p.jsx)(a,{onClick:async()=>{if(!(!D||!e)){T(!0);try{await i(E,``,{description:g.trim()||void 0,argumentHint:v.trim()||void 0,mode:b===`plan`?`plan`:void 0},S===`global`?`global`:`project`,t??void 0),l({title:`Command created`,description:`Command '/${E}' was created successfully.`}),h(``),_(``),y(``),x(`default`),C(`local`),r?.(E)}catch(e){l({title:`Error`,description:e instanceof Error?e.message:`Failed to create command`,variant:`destructive`})}finally{T(!1)}}},disabled:!D||w,children:w?(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(n,{className:`mr-2 h-4 w-4 animate-spin`}),`Creating...`]}):(0,p.jsxs)(p.Fragment,{children:[`Continue`,(0,p.jsx)(c,{className:`ml-2 h-4 w-4`})]})})})]})]}):(0,p.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,p.jsxs)(`div`,{className:`text-center`,children:[(0,p.jsx)(`h2`,{className:`text-lg font-semibold text-muted-foreground mb-2`,children:`No Project Selected`}),(0,p.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Please select a project to add a slash command.`})]})})}export{m as default};
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{Fi as t,Kn as n,P as r,Xn as i,c as a,l as o,xi as s,zr as c}from"./dialogs-config-CdogKQE6.js";import"./react-vendor-BNQTbRKd.js";import"./history-view-DtTMEZIl.js";import{t as l}from"./use-toast-DCmq-wgl.js";import{n as u,t as d}from"./radio-group-BQ7i054U.js";var f=e(t(),1),p=i();function m({projectId:e,threadId:t,onCommandCreated:i}){let[m,h]=(0,f.useState)(``),[g,_]=(0,f.useState)(``),[v,y]=(0,f.useState)(``),[b,x]=(0,f.useState)(`default`),[S,C]=(0,f.useState)(`local`),[w,T]=(0,f.useState)(!1),E=m.toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``),D=E.length>0&&E.length<=64;return e?(0,p.jsxs)(`div`,{className:`max-w-2xl mx-auto p-6`,children:[(0,p.jsxs)(`div`,{className:`mb-6`,children:[(0,p.jsx)(`h1`,{className:`text-2xl font-bold`,children:`Add Slash Command`}),(0,p.jsx)(`p`,{className:`text-muted-foreground`,children:`Create a new slash command. The command will be saved as a .md file in the ~/.agents/commands folder.`})]}),(0,p.jsxs)(`div`,{className:`space-y-6`,children:[(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(o,{htmlFor:`commandName`,children:`Command Name`}),(0,p.jsx)(a,{id:`commandName`,value:m,onChange:e=>h(e.target.value),placeholder:`e.g. review`,disabled:w}),m&&(0,p.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Command: `,(0,p.jsxs)(`span`,{className:`font-mono`,children:[`/`,E||`...`]})]})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(o,{htmlFor:`commandDescription`,children:`Description`}),(0,p.jsx)(a,{id:`commandDescription`,value:g,onChange:e=>_(e.target.value),placeholder:`Brief description shown in autocomplete`,disabled:w})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(o,{htmlFor:`argumentHint`,children:`Argument Hint (optional)`}),(0,p.jsx)(a,{id:`argumentHint`,value:v,onChange:e=>y(e.target.value),placeholder:`e.g. <focus-area> or <branch-name>`,disabled:w}),(0,p.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Shows after the command name to guide users what to type`})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(o,{children:`Mode`}),(0,p.jsxs)(d,{value:b,onValueChange:e=>x(e),className:`flex gap-4`,disabled:w,children:[(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`default`,id:`mode-default`}),(0,p.jsx)(o,{htmlFor:`mode-default`,className:`font-normal cursor-pointer`,children:`Default`})]}),(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`plan`,id:`mode-plan`}),(0,p.jsx)(o,{htmlFor:`mode-plan`,className:`font-normal cursor-pointer`,children:`Plan`})]})]}),(0,p.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:b===`default`?`Standard chat mode`:`Activates plan mode when this command is used`})]}),(0,p.jsxs)(`div`,{className:`space-y-2`,children:[(0,p.jsx)(o,{children:`Scope`}),(0,p.jsxs)(d,{value:S,onValueChange:e=>C(e),className:`flex gap-4`,disabled:w,children:[(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`local`,id:`scope-local`}),(0,p.jsx)(o,{htmlFor:`scope-local`,className:`font-normal cursor-pointer`,children:`Local (this project)`})]}),(0,p.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,p.jsx)(u,{value:`global`,id:`scope-global`,disabled:!0}),(0,p.jsx)(o,{htmlFor:`scope-global`,className:`font-normal cursor-pointer text-muted-foreground`,children:`Global (coming soon)`})]})]}),(0,p.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:S===`local`?`This command will only be available for this project.`:`This command will be available across all projects (coming soon).`})]}),(0,p.jsx)(`div`,{className:`border-t pt-4 flex justify-end`,children:(0,p.jsx)(n,{onClick:async()=>{if(!(!D||!e)){T(!0);try{await r(E,``,{description:g.trim()||void 0,argumentHint:v.trim()||void 0,mode:b===`plan`?`plan`:void 0},S===`global`?`global`:`project`,t??void 0),l({title:`Command created`,description:`Command '/${E}' was created successfully.`}),h(``),_(``),y(``),x(`default`),C(`local`),i?.(E)}catch(e){l({title:`Error`,description:e instanceof Error?e.message:`Failed to create command`,variant:`destructive`})}finally{T(!1)}}},disabled:!D||w,children:w?(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(c,{className:`mr-2 h-4 w-4 animate-spin`}),`Creating...`]}):(0,p.jsxs)(p.Fragment,{children:[`Continue`,(0,p.jsx)(s,{className:`ml-2 h-4 w-4`})]})})})]})]}):(0,p.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,p.jsxs)(`div`,{className:`text-center`,children:[(0,p.jsx)(`h2`,{className:`text-lg font-semibold text-muted-foreground mb-2`,children:`No Project Selected`}),(0,p.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Please select a project to add a slash command.`})]})})}export{m as default};
@@ -0,0 +1 @@
1
+ import"./dialogs-config-CdogKQE6.js";import{t as e}from"./history-view-DtTMEZIl.js";export{e as ConversationHistoryView,e as default};