tarsk 0.5.50 → 0.5.51

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 (90) hide show
  1. package/README.md +85 -3
  2. package/dist/index.js +298 -140
  3. package/dist/public/assets/{account-view-orctnHTc.js → account-view-CGokQA1o.js} +1 -1
  4. package/dist/public/assets/api-BRrGio-B.js +1 -0
  5. package/dist/public/assets/browser-tab-B3BybVD0.js +1 -0
  6. package/dist/public/assets/commit-dialog-BLzHl6oN.js +1 -0
  7. package/dist/public/assets/context-menu-yKNgVtVk.js +1 -0
  8. package/dist/public/assets/create-repo-dialog-DHFloJc3.js +1 -0
  9. package/dist/public/assets/{dialogs-config-COzptu1b.js → dialogs-config-BF_RyK5j.js} +14 -14
  10. package/dist/public/assets/diff-view-DONeogdk.js +3 -0
  11. package/dist/public/assets/explorer-tab-view-C1Dex751.js +2 -0
  12. package/dist/public/assets/explorer-tree-BmsrsMXJ.js +1 -0
  13. package/dist/public/assets/explorer-view-1fAca9It.js +1 -0
  14. package/dist/public/assets/git-history-dialog-DXsSt3e0.js +1 -0
  15. package/dist/public/assets/git-ops-button-Cj3j4bvy.js +2 -0
  16. package/dist/public/assets/history-view-COEFPP2U.js +9 -0
  17. package/dist/public/assets/index-Dsj5zHdU.js +73 -0
  18. package/dist/public/assets/mcp-server-card-3bFOnHFO.js +1 -0
  19. package/dist/public/assets/merged-pr-dialog-C5vgSXwq.js +1 -0
  20. package/dist/public/assets/model-star-rating-GWRgO9pY.js +1 -0
  21. package/dist/public/assets/onboarding-B_n7I3ri.js +1 -0
  22. package/dist/public/assets/project-settings-view-DsVEiQM_.js +1 -0
  23. package/dist/public/assets/providers-list-view-BT5XZP-F.js +1 -0
  24. package/dist/public/assets/pull-request-dialog-BO_7fALs.js +1 -0
  25. package/dist/public/assets/pull-with-changes-dialog-DQSC-HUH.js +1 -0
  26. package/dist/public/assets/push-before-pr-dialog-B9evx_c7.js +1 -0
  27. package/dist/public/assets/radio-group-CNuRXtN5.js +1 -0
  28. package/dist/public/assets/react-vendor-D-z0br-z.js +16 -0
  29. package/dist/public/assets/settings-general-view-BaTUBgdM.js +1 -0
  30. package/dist/public/assets/{settings-instructions-view-CB-cGPIr.js → settings-instructions-view-Bit7tYRh.js} +1 -1
  31. package/dist/public/assets/settings-list-Cc_0YmxB.js +1 -0
  32. package/dist/public/assets/settings-mcp-servers-view-BcuuyWhI.js +5 -0
  33. package/dist/public/assets/{settings-models-skeleton-ZtGznNlV.js → settings-models-skeleton-BfIx9XDs.js} +1 -1
  34. package/dist/public/assets/settings-models-view-CNFB1Iqn.js +1 -0
  35. package/dist/public/assets/settings-rules-view-BvelCH4j.js +8 -0
  36. package/dist/public/assets/settings-skills-view-DV-cA6cj.js +3 -0
  37. package/dist/public/assets/settings-slash-commands-view-CKxQnzse.js +1 -0
  38. package/dist/public/assets/settings-subagents-view-DAl5Db-p.js +2 -0
  39. package/dist/public/assets/{settings-system-prompt-view-BLkM6rN5.js → settings-system-prompt-view-BdwsxqMo.js} +1 -1
  40. package/dist/public/assets/settings-view-BxiazdKG.js +2 -0
  41. package/dist/public/assets/{skeleton-CxK1dTki.js → skeleton-DJZ5x6e0.js} +1 -1
  42. package/dist/public/assets/slug-utils-D4uxO5qv.js +1 -0
  43. package/dist/public/assets/{tabs-Tmfp1NOE.js → tabs-TGCt-ze0.js} +1 -1
  44. package/dist/public/assets/{terminal-panel-DKkr68gm.js → terminal-panel-Bh_CKydu.js} +2 -2
  45. package/dist/public/assets/todos-view-DDSSplmi.js +17 -0
  46. package/dist/public/assets/{ui-components-BhYSDqpD.js → ui-components-JEH8JAJ7.js} +1 -1
  47. package/dist/public/assets/{use-deferred-search-DXiiWEeH.js → use-deferred-search-BZg7Bt7W.js} +1 -1
  48. package/dist/public/assets/{utils-DDUhUTLy.js → utils-H-1x3dmp.js} +1 -1
  49. package/dist/public/assets/{vosk-speech-BHa2mKnm.js → vosk-speech-FJiKHPe4.js} +1 -1
  50. package/dist/public/assets/{web-BYoghlKk.js → web-B4cuelyi.js} +1 -1
  51. package/dist/public/assets/{web-6JeYEnKU.js → web-CQpWcSn8.js} +1 -1
  52. package/dist/public/assets/{web-3Ems3Koj.js → web-Cq4yC7dg.js} +1 -1
  53. package/dist/public/assets/{web-Dgmyivst.js → web-DOZOaJlj.js} +1 -1
  54. package/dist/public/index.html +7 -7
  55. package/package.json +1 -1
  56. package/dist/public/assets/api-_tZksLaY.js +0 -1
  57. package/dist/public/assets/browser-tab-bfjSH9LH.js +0 -1
  58. package/dist/public/assets/commit-dialog-BAFsxiuw.js +0 -1
  59. package/dist/public/assets/context-menu-CeBh_Q21.js +0 -1
  60. package/dist/public/assets/create-repo-dialog-D6cKAxMh.js +0 -1
  61. package/dist/public/assets/diff-view-CFu5DBIy.js +0 -3
  62. package/dist/public/assets/explorer-tab-view-yR_3TyF7.js +0 -2
  63. package/dist/public/assets/explorer-tree-DKrWFiee.js +0 -1
  64. package/dist/public/assets/explorer-view-DYbdTXTm.js +0 -1
  65. package/dist/public/assets/git-history-dialog-CTJwMGDA.js +0 -1
  66. package/dist/public/assets/git-ops-button-DM9h9L8O.js +0 -2
  67. package/dist/public/assets/history-view-BJ65FVAN.js +0 -9
  68. package/dist/public/assets/index-BMgOr4si.js +0 -73
  69. package/dist/public/assets/mcp-server-card-7DWtYR7B.js +0 -1
  70. package/dist/public/assets/merged-pr-dialog-D6ReZlV4.js +0 -1
  71. package/dist/public/assets/model-star-rating-DmWIerry.js +0 -1
  72. package/dist/public/assets/onboarding-pVfMmu_a.js +0 -1
  73. package/dist/public/assets/project-settings-view-CvPC_OvN.js +0 -1
  74. package/dist/public/assets/providers-list-view-BEBGDXvF.js +0 -1
  75. package/dist/public/assets/pull-request-dialog-DD9Yxl2t.js +0 -1
  76. package/dist/public/assets/pull-with-changes-dialog-yEIyN-rw.js +0 -1
  77. package/dist/public/assets/push-before-pr-dialog-09SWB4nh.js +0 -1
  78. package/dist/public/assets/radio-group-DAndqwXy.js +0 -1
  79. package/dist/public/assets/react-vendor-CEpXTE2b.js +0 -16
  80. package/dist/public/assets/settings-general-view-Crc9BTRv.js +0 -1
  81. package/dist/public/assets/settings-list-C5XuK_4u.js +0 -1
  82. package/dist/public/assets/settings-mcp-servers-view-CZR7I1h2.js +0 -5
  83. package/dist/public/assets/settings-models-view-CB0rRPNa.js +0 -1
  84. package/dist/public/assets/settings-rules-view-BnoxoZfX.js +0 -8
  85. package/dist/public/assets/settings-skills-view-DKXDiK3e.js +0 -3
  86. package/dist/public/assets/settings-slash-commands-view-DtTuDEFe.js +0 -1
  87. package/dist/public/assets/settings-subagents-view-DNcPuqd5.js +0 -2
  88. package/dist/public/assets/settings-view-BX2dUb7a.js +0 -2
  89. package/dist/public/assets/slug-utils-D3-onmIf.js +0 -1
  90. package/dist/public/assets/todos-view-_rD_cv7x.js +0 -17
package/dist/index.js CHANGED
@@ -765,42 +765,125 @@ var init_tool_display = __esm({
765
765
  "../shared/dist/tool-display.js"() {
766
766
  "use strict";
767
767
  toolDisplayRegistry = [
768
- { name: "agent", displayName: "Subagent", activeDisplayName: "Subagent" },
769
- { name: "ask_user", displayName: "Ask", activeDisplayName: "Asking" },
770
- { name: "bash", displayName: "Ran", activeDisplayName: "Running" },
771
- { name: "browser", displayName: "Browser", activeDisplayName: "Browsing" },
772
- { name: "code_search", displayName: "Code Search", activeDisplayName: "Searching" },
773
- { name: "edit", displayName: "Edit", activeDisplayName: "Editing" },
774
- { name: "execute_skill_script", displayName: "Run Script", activeDisplayName: "Running Script" },
775
- { name: "fetch", displayName: "Fetch", activeDisplayName: "Fetching" },
776
- { name: "find", displayName: "Find", activeDisplayName: "Finding" },
777
- { name: "find_images", displayName: "Find Images", activeDisplayName: "Finding Images" },
778
- { name: "generate_image", displayName: "Make Image", activeDisplayName: "Making Image" },
779
- { name: "grep", displayName: "Search", activeDisplayName: "Searching" },
780
- { name: "ls", displayName: "List", activeDisplayName: "Listing" },
781
- { name: "mcp", displayName: "Tool", activeDisplayName: "Tool" },
782
- { name: "read", displayName: "Read", activeDisplayName: "Reading" },
768
+ { name: "agent", enabled: true, displayName: "Subagent", activeDisplayName: "Subagent" },
769
+ { name: "ask_user", enabled: true, displayName: "Ask", activeDisplayName: "Asking" },
770
+ { name: "bash", enabled: true, displayName: "Ran", activeDisplayName: "Running" },
771
+ { name: "browser", enabled: true, displayName: "Browser", activeDisplayName: "Browsing" },
772
+ {
773
+ name: "code_search",
774
+ enabled: false,
775
+ displayName: "Code Search",
776
+ activeDisplayName: "Searching"
777
+ },
778
+ { name: "edit", enabled: true, displayName: "Edit", activeDisplayName: "Editing" },
779
+ {
780
+ name: "execute_skill_script",
781
+ enabled: true,
782
+ displayName: "Run Skill Script",
783
+ activeDisplayName: "Running Script"
784
+ },
785
+ { name: "fetch", enabled: true, displayName: "Fetch", activeDisplayName: "Fetching" },
786
+ { name: "find", enabled: true, displayName: "Find", activeDisplayName: "Finding" },
787
+ {
788
+ name: "find_images",
789
+ enabled: true,
790
+ displayName: "Find Images",
791
+ activeDisplayName: "Finding Images"
792
+ },
793
+ {
794
+ name: "generate_image",
795
+ enabled: true,
796
+ displayName: "Make Image",
797
+ activeDisplayName: "Making Image"
798
+ },
799
+ { name: "grep", enabled: true, displayName: "Search", activeDisplayName: "Searching" },
800
+ { name: "ls", enabled: false, displayName: "List", activeDisplayName: "Listing" },
801
+ { name: "mcp", enabled: true, displayName: "MCP Tool", activeDisplayName: "Tool" },
802
+ { name: "read", enabled: true, displayName: "Read", activeDisplayName: "Reading" },
783
803
  {
784
804
  name: "read_skill_reference",
805
+ enabled: true,
785
806
  displayName: "Read Reference",
786
807
  activeDisplayName: "Reading Reference"
787
808
  },
788
- { name: "run_js", displayName: "Run JS", activeDisplayName: "Running JS" },
789
- { name: "simple_grep", displayName: "Search", activeDisplayName: "Searching" },
790
- { name: "todo", displayName: "Todo", activeDisplayName: "Updating" },
791
- { name: "tasks", displayName: "Tasks", activeDisplayName: "Managing Tasks" },
792
- { name: "tool_search", displayName: "Find Tools", activeDisplayName: "Finding Tools" },
809
+ { name: "run_js", enabled: true, displayName: "Run JS", activeDisplayName: "Running JS" },
810
+ {
811
+ name: "simple_grep",
812
+ enabled: false,
813
+ displayName: "Search",
814
+ activeDisplayName: "Searching"
815
+ },
816
+ { name: "todo", enabled: true, displayName: "Todo", activeDisplayName: "Updating" },
817
+ { name: "tasks", enabled: true, displayName: "Tasks", activeDisplayName: "Managing Tasks" },
818
+ {
819
+ name: "tool_search",
820
+ enabled: true,
821
+ displayName: "Find Tools",
822
+ activeDisplayName: "Finding Tools"
823
+ },
793
824
  {
794
825
  name: "web_search",
826
+ enabled: true,
795
827
  displayName: "Web Search",
796
828
  activeDisplayName: "Searching Web"
797
829
  },
798
- { name: "write", displayName: "Write", activeDisplayName: "Writing" }
830
+ { name: "write", enabled: true, displayName: "Write", activeDisplayName: "Writing" }
799
831
  ];
800
832
  displayByName = new Map(toolDisplayRegistry.map((entry) => [entry.name, entry]));
801
833
  }
802
834
  });
803
835
 
836
+ // ../shared/dist/project-tools.js
837
+ function normalizeDisabledTools(names) {
838
+ if (!Array.isArray(names)) {
839
+ return [];
840
+ }
841
+ const seen = /* @__PURE__ */ new Set();
842
+ const normalized = [];
843
+ for (const name of names) {
844
+ if (typeof name !== "string") {
845
+ continue;
846
+ }
847
+ const lowerName = name.trim().toLowerCase();
848
+ if (!lowerName || !configurableToolNames.has(lowerName) || seen.has(lowerName)) {
849
+ continue;
850
+ }
851
+ seen.add(lowerName);
852
+ normalized.push(lowerName);
853
+ }
854
+ return normalized.sort();
855
+ }
856
+ function resolveProjectToolName(toolName) {
857
+ const lowerName = toolName.toLowerCase();
858
+ if (lowerName.startsWith("mcp_") || lowerName.startsWith("mcp__")) {
859
+ return "mcp";
860
+ }
861
+ return lowerName;
862
+ }
863
+ function isProjectToolEnabled(toolName, disabledTools) {
864
+ if (!disabledTools?.length) {
865
+ return true;
866
+ }
867
+ const disabled = new Set(disabledTools.map((name) => name.toLowerCase()));
868
+ return !disabled.has(resolveProjectToolName(toolName));
869
+ }
870
+ function filterProjectTools(tools, disabledTools) {
871
+ if (!disabledTools?.length) {
872
+ return tools;
873
+ }
874
+ return tools.filter((tool) => isProjectToolEnabled(tool.name, disabledTools));
875
+ }
876
+ var PROJECT_SETTINGS_EXCLUDED_TOOL_NAMES, PROJECT_CONFIGURABLE_TOOL_NAMES, configurableToolNames;
877
+ var init_project_tools = __esm({
878
+ "../shared/dist/project-tools.js"() {
879
+ "use strict";
880
+ init_tool_display();
881
+ PROJECT_SETTINGS_EXCLUDED_TOOL_NAMES = /* @__PURE__ */ new Set(["tool_search"]);
882
+ PROJECT_CONFIGURABLE_TOOL_NAMES = toolDisplayRegistry.filter((entry) => entry.enabled && !PROJECT_SETTINGS_EXCLUDED_TOOL_NAMES.has(entry.name)).map((entry) => entry.name);
883
+ configurableToolNames = new Set(PROJECT_CONFIGURABLE_TOOL_NAMES);
884
+ }
885
+ });
886
+
804
887
  // ../shared/dist/providers.js
805
888
  function resolveLocalProviderApiUrl(envValues) {
806
889
  const override = envValues[LOCAL_API_URL_ENV]?.trim();
@@ -1135,6 +1218,7 @@ var init_dist = __esm({
1135
1218
  init_typography();
1136
1219
  init_font_scale();
1137
1220
  init_tool_display();
1221
+ init_project_tools();
1138
1222
  init_providers();
1139
1223
  init_web_fetch();
1140
1224
  init_explorer_media();
@@ -2405,6 +2489,14 @@ async function runMigrations(db) {
2405
2489
  tarskDebugLog("[db] Running migration: Adding modelAliases column to projects");
2406
2490
  await db.execute(`ALTER TABLE projects ADD COLUMN modelAliases TEXT`);
2407
2491
  }
2492
+ const disabledToolsProjectsInfo = await db.execute(`PRAGMA table_info(projects)`);
2493
+ const hasDisabledTools = disabledToolsProjectsInfo.rows.some(
2494
+ (col) => col.name === "disabledTools"
2495
+ );
2496
+ if (!hasDisabledTools) {
2497
+ tarskDebugLog("[db] Running migration: Adding disabledTools column to projects");
2498
+ await db.execute(`ALTER TABLE projects ADD COLUMN disabledTools TEXT`);
2499
+ }
2408
2500
  const projectScriptsExists = await db.execute(
2409
2501
  `SELECT name FROM sqlite_master WHERE type='table' AND name='project_scripts'`
2410
2502
  );
@@ -11413,71 +11505,8 @@ var toolRegistry, registryByName;
11413
11505
  var init_tool_registry = __esm({
11414
11506
  "src/tools/tool-registry.ts"() {
11415
11507
  "use strict";
11416
- toolRegistry = [
11417
- { name: "agent", enabled: true, displayName: "Subagent", activeDisplayName: "Subagent" },
11418
- { name: "ask_user", enabled: true, displayName: "Ask", activeDisplayName: "Asking" },
11419
- { name: "bash", enabled: true, displayName: "Ran", activeDisplayName: "Running" },
11420
- { name: "browser", enabled: true, displayName: "Browser", activeDisplayName: "Browsing" },
11421
- {
11422
- name: "code_search",
11423
- enabled: false,
11424
- displayName: "Code Search",
11425
- activeDisplayName: "Searching"
11426
- },
11427
- { name: "edit", enabled: true, displayName: "Edit", activeDisplayName: "Editing" },
11428
- {
11429
- name: "execute_skill_script",
11430
- enabled: true,
11431
- displayName: "Run Script",
11432
- activeDisplayName: "Running Script"
11433
- },
11434
- { name: "fetch", enabled: true, displayName: "Fetch", activeDisplayName: "Fetching" },
11435
- { name: "find", enabled: true, displayName: "Find", activeDisplayName: "Finding" },
11436
- {
11437
- name: "find_images",
11438
- enabled: true,
11439
- displayName: "Find Images",
11440
- activeDisplayName: "Finding Images"
11441
- },
11442
- {
11443
- name: "generate_image",
11444
- enabled: true,
11445
- displayName: "Make Image",
11446
- activeDisplayName: "Making Image"
11447
- },
11448
- { name: "grep", enabled: true, displayName: "Search", activeDisplayName: "Searching" },
11449
- { name: "ls", enabled: false, displayName: "List", activeDisplayName: "Listing" },
11450
- { name: "mcp", enabled: true, displayName: "Tool", activeDisplayName: "Tool" },
11451
- { name: "read", enabled: true, displayName: "Read", activeDisplayName: "Reading" },
11452
- {
11453
- name: "read_skill_reference",
11454
- enabled: true,
11455
- displayName: "Read Reference",
11456
- activeDisplayName: "Reading Reference"
11457
- },
11458
- { name: "run_js", enabled: true, displayName: "Run JS", activeDisplayName: "Running JS" },
11459
- {
11460
- name: "simple_grep",
11461
- enabled: false,
11462
- displayName: "Search",
11463
- activeDisplayName: "Searching"
11464
- },
11465
- { name: "todo", enabled: true, displayName: "Todo", activeDisplayName: "Updating" },
11466
- { name: "tasks", enabled: true, displayName: "Tasks", activeDisplayName: "Managing Tasks" },
11467
- {
11468
- name: "tool_search",
11469
- enabled: true,
11470
- displayName: "Find Tools",
11471
- activeDisplayName: "Finding Tools"
11472
- },
11473
- {
11474
- name: "web_search",
11475
- enabled: true,
11476
- displayName: "Web Search",
11477
- activeDisplayName: "Searching Web"
11478
- },
11479
- { name: "write", enabled: true, displayName: "Write", activeDisplayName: "Writing" }
11480
- ];
11508
+ init_dist();
11509
+ toolRegistry = toolDisplayRegistry;
11481
11510
  registryByName = new Map(toolRegistry.map((entry) => [entry.name, entry]));
11482
11511
  }
11483
11512
  });
@@ -11828,54 +11857,68 @@ function wrapToolWithCodeSearchInvalidation(tool, threadId) {
11828
11857
  function applyCodeSearchInvalidationHooks(tools, threadId) {
11829
11858
  return tools.map((tool) => wrapToolWithCodeSearchInvalidation(tool, threadId));
11830
11859
  }
11860
+ function filterAvailableTools(tools, disabledTools) {
11861
+ return filterProjectTools(filterEnabledTools(tools), disabledTools);
11862
+ }
11831
11863
  async function createCodingTools(cwd, options) {
11832
11864
  const deferOption = options?.deferTools ?? true;
11865
+ const disabledTools = options?.disabledTools;
11833
11866
  const shellPermissionGate = options?.shellPermissionGate;
11834
11867
  const bashOptions = shellPermissionGate || options?.projectId ? { ...options?.bash, shellPermissionGate, projectId: options?.projectId } : options?.bash;
11835
- const coreTools = filterEnabledTools([
11836
- createReadTool(cwd, options?.read),
11837
- createBashTool(cwd, bashOptions),
11838
- createEditTool(cwd),
11839
- createWriteTool(cwd),
11840
- createAskUserTool(),
11841
- createTodoTool(options?.threadId ?? "", options?.threadPath),
11842
- createFindTool(cwd),
11843
- createRipGrepTool(cwd),
11844
- createSimpleGrepTool(cwd),
11845
- createCodeSearchTool(cwd, options?.threadId ?? ""),
11846
- createRunWebWorkerTool(),
11847
- createFetchTool({
11848
- metadataManager: options?.metadataManager,
11849
- webFetchPermissionGate: options?.webFetchPermissionGate
11850
- }),
11851
- createWebSearchTool()
11852
- ]);
11853
- if (options?.projectId && options.threadId && isToolEnabled("tasks")) {
11868
+ const coreTools = filterAvailableTools(
11869
+ [
11870
+ createReadTool(cwd, options?.read),
11871
+ createBashTool(cwd, bashOptions),
11872
+ createEditTool(cwd),
11873
+ createWriteTool(cwd),
11874
+ createAskUserTool(),
11875
+ createTodoTool(options?.threadId ?? "", options?.threadPath),
11876
+ createFindTool(cwd),
11877
+ createRipGrepTool(cwd),
11878
+ createSimpleGrepTool(cwd),
11879
+ createCodeSearchTool(cwd, options?.threadId ?? ""),
11880
+ createRunWebWorkerTool(),
11881
+ createFetchTool({
11882
+ metadataManager: options?.metadataManager,
11883
+ webFetchPermissionGate: options?.webFetchPermissionGate
11884
+ }),
11885
+ createWebSearchTool()
11886
+ ],
11887
+ disabledTools
11888
+ );
11889
+ if (options?.projectId && options.threadId && isToolEnabled("tasks") && isProjectToolEnabled("tasks", disabledTools)) {
11854
11890
  coreTools.push(createTasksTool(options.projectId, options.threadId, options.metadataManager));
11855
11891
  }
11856
- if (options?.metadataManager && isToolEnabled("generate_image")) {
11892
+ if (options?.metadataManager && isToolEnabled("generate_image") && isProjectToolEnabled("generate_image", disabledTools)) {
11857
11893
  coreTools.push(createGenerateImageTool({ metadataManager: options.metadataManager, cwd }));
11858
11894
  }
11859
- const optionalTools = filterEnabledTools([
11860
- createFindImagesTool({ cwd, threadId: options?.threadId }),
11861
- createBrowserTool({ cwd, threadId: options?.threadId })
11862
- ]);
11895
+ const optionalTools = filterAvailableTools(
11896
+ [
11897
+ createFindImagesTool({ cwd, threadId: options?.threadId }),
11898
+ createBrowserTool({ cwd, threadId: options?.threadId })
11899
+ ],
11900
+ disabledTools
11901
+ );
11863
11902
  if (options?.skills && options.skills.length > 0) {
11864
11903
  optionalTools.push(
11865
- ...filterEnabledTools([
11866
- createSkillScriptTool(options.skills, cwd, shellPermissionGate, options?.projectId),
11867
- createSkillReferenceTool(options.skills)
11868
- ])
11904
+ ...filterAvailableTools(
11905
+ [
11906
+ createSkillScriptTool(options.skills, cwd, shellPermissionGate, options?.projectId),
11907
+ createSkillReferenceTool(options.skills)
11908
+ ],
11909
+ disabledTools
11910
+ )
11869
11911
  );
11870
11912
  }
11871
11913
  let mcpTools = [];
11872
- if (options?.loadMcpTools !== false && isToolEnabled("mcp")) {
11914
+ if (options?.loadMcpTools !== false && isToolEnabled("mcp") && isProjectToolEnabled("mcp", disabledTools)) {
11873
11915
  try {
11874
- mcpTools = filterEnabledTools(
11916
+ mcpTools = filterAvailableTools(
11875
11917
  await createMCPTools(cwd, {
11876
11918
  onMcpStatus: options?.onMcpStatus,
11877
11919
  projectId: options?.projectId
11878
- })
11920
+ }),
11921
+ disabledTools
11879
11922
  );
11880
11923
  } catch (error) {
11881
11924
  console.warn(`[Tools] Failed to load MCP tools for ${cwd}:`, error);
@@ -11922,6 +11965,7 @@ async function createCodingTools(cwd, options) {
11922
11965
  function createAllTools(cwd, options) {
11923
11966
  const shellPermissionGate = options?.shellPermissionGate;
11924
11967
  const bashOptions = shellPermissionGate ? { ...options?.bash, shellPermissionGate } : options?.bash;
11968
+ const disabledTools = options?.disabledTools;
11925
11969
  const tools = {};
11926
11970
  const candidates = {
11927
11971
  read: createReadTool(cwd, options?.read),
@@ -11937,17 +11981,17 @@ function createAllTools(cwd, options) {
11937
11981
  run_js: createRunWebWorkerTool()
11938
11982
  };
11939
11983
  for (const [name, tool] of Object.entries(candidates)) {
11940
- if (isToolEnabled(name)) {
11984
+ if (isToolEnabled(name) && isProjectToolEnabled(name, disabledTools)) {
11941
11985
  tools[name] = tool;
11942
11986
  }
11943
11987
  }
11944
- if (options?.metadataManager && isToolEnabled("generate_image")) {
11988
+ if (options?.metadataManager && isToolEnabled("generate_image") && isProjectToolEnabled("generate_image", disabledTools)) {
11945
11989
  tools.generate_image = createGenerateImageTool({
11946
11990
  metadataManager: options.metadataManager,
11947
11991
  cwd
11948
11992
  });
11949
11993
  }
11950
- if (isToolEnabled("find_images")) {
11994
+ if (isToolEnabled("find_images") && isProjectToolEnabled("find_images", disabledTools)) {
11951
11995
  tools.find_images = createFindImagesTool({ cwd, threadId: options?.threadId });
11952
11996
  }
11953
11997
  if (options?.threadId) {
@@ -11961,6 +12005,7 @@ var codingTools, readOnlyTools, allToolsByName, allTools, INDEX_INVALIDATING_TOO
11961
12005
  var init_tools = __esm({
11962
12006
  "src/tools/index.ts"() {
11963
12007
  "use strict";
12008
+ init_dist();
11964
12009
  init_bash();
11965
12010
  init_edit();
11966
12011
  init_find();
@@ -14084,7 +14129,8 @@ var init_agent_executor = __esm({
14084
14129
  projectId: context.projectId,
14085
14130
  metadataManager: this.metadataManager,
14086
14131
  shellPermissionGate,
14087
- webFetchPermissionGate
14132
+ webFetchPermissionGate,
14133
+ disabledTools: context.disabledTools
14088
14134
  });
14089
14135
  let toolsResult = await toolsLoader.next();
14090
14136
  while (!toolsResult.done) {
@@ -14116,7 +14162,7 @@ var init_agent_executor = __esm({
14116
14162
  });
14117
14163
  log3.debug("System prompt content", systemPrompt);
14118
14164
  const invocableAgents = (context.agents ?? []).filter((a) => !a.disableModelInvocation);
14119
- if (invocableAgents.length > 0 && isToolEnabled("agent")) {
14165
+ if (invocableAgents.length > 0 && isToolEnabled("agent") && isProjectToolEnabled("agent", context.disabledTools)) {
14120
14166
  const agentToolInstance = createAgentTool({
14121
14167
  agents: invocableAgents,
14122
14168
  baseTools: tools,
@@ -16012,8 +16058,8 @@ async function insertProject(db, project) {
16012
16058
  try {
16013
16059
  await db.execute(
16014
16060
  `
16015
- INSERT INTO projects (id, name, gitUrl, path, createdAt, openWith, commands, setupScript, validationScript, runCommand, commitMethod, planPrompt, testPrompt, reviewPrompt, customSystemPrompt, useCustomSystemPrompt, allowAllCommands, allowedCommandPatterns, allowedFetchDomains, modelAliases)
16016
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
16061
+ INSERT INTO projects (id, name, gitUrl, path, createdAt, openWith, commands, setupScript, validationScript, runCommand, commitMethod, planPrompt, testPrompt, reviewPrompt, customSystemPrompt, useCustomSystemPrompt, allowAllCommands, allowedCommandPatterns, allowedFetchDomains, modelAliases, disabledTools)
16062
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
16017
16063
  `,
16018
16064
  [
16019
16065
  project.id,
@@ -16035,7 +16081,8 @@ async function insertProject(db, project) {
16035
16081
  project.allowAllCommands === false ? 0 : 1,
16036
16082
  project.allowedCommandPatterns ? JSON.stringify(project.allowedCommandPatterns) : null,
16037
16083
  project.allowedFetchDomains ? JSON.stringify(project.allowedFetchDomains) : null,
16038
- project.modelAliases ? JSON.stringify(project.modelAliases) : null
16084
+ project.modelAliases ? JSON.stringify(project.modelAliases) : null,
16085
+ project.disabledTools?.length ? JSON.stringify(project.disabledTools) : null
16039
16086
  ]
16040
16087
  );
16041
16088
  } catch (error) {
@@ -16123,6 +16170,10 @@ async function updateProject(db, id, updates) {
16123
16170
  fields.push("modelAliases = ?");
16124
16171
  values.push(updates.modelAliases ? JSON.stringify(updates.modelAliases) : null);
16125
16172
  }
16173
+ if (updates.disabledTools !== void 0) {
16174
+ fields.push("disabledTools = ?");
16175
+ values.push(updates.disabledTools?.length ? JSON.stringify(updates.disabledTools) : null);
16176
+ }
16126
16177
  if (fields.length === 0) {
16127
16178
  return;
16128
16179
  }
@@ -16231,7 +16282,8 @@ function deserializeProjectWithThreads(row, threadIds) {
16231
16282
  allowAllCommands: row.allowAllCommands === null ? true : Boolean(row.allowAllCommands),
16232
16283
  allowedCommandPatterns: row.allowedCommandPatterns ? JSON.parse(row.allowedCommandPatterns) : void 0,
16233
16284
  allowedFetchDomains: row.allowedFetchDomains ? JSON.parse(row.allowedFetchDomains) : void 0,
16234
- modelAliases: row.modelAliases ? JSON.parse(row.modelAliases) : void 0
16285
+ modelAliases: row.modelAliases ? JSON.parse(row.modelAliases) : void 0,
16286
+ disabledTools: row.disabledTools ? JSON.parse(row.disabledTools) : void 0
16235
16287
  };
16236
16288
  }
16237
16289
  async function deserializeProject(db, row) {
@@ -16436,7 +16488,8 @@ async function postChatMessage(c, threadManager, agentExecutor, conversationMana
16436
16488
  allowedFetchDomains: domains
16437
16489
  });
16438
16490
  },
16439
- modelAliases: project?.modelAliases
16491
+ modelAliases: project?.modelAliases,
16492
+ disabledTools: project?.disabledTools
16440
16493
  };
16441
16494
  console.log("[ChatRoute] Execution context:", {
16442
16495
  threadId,
@@ -18506,6 +18559,12 @@ function serializeToolsForEstimate(tools) {
18506
18559
  }))
18507
18560
  );
18508
18561
  }
18562
+ function filterToolsForDefinitionEstimate(tools, disabledTools) {
18563
+ return filterProjectTools(
18564
+ tools.filter((tool) => isToolEnabled(tool.name)),
18565
+ disabledTools
18566
+ );
18567
+ }
18509
18568
  function serializeConversationContent(messages) {
18510
18569
  const parts = [];
18511
18570
  for (const message of messages) {
@@ -18623,15 +18682,17 @@ async function computeContextBreakdown(threadId, conversationId, conversationMan
18623
18682
  );
18624
18683
  const agentsManager = new AgentsManager();
18625
18684
  const agents = await agentsManager.loadAgents(threadPath);
18685
+ const db = await getDatabase();
18686
+ const project = await getProject(db, thread.projectId);
18626
18687
  const { tools, deferredToolNames } = await createCodingTools(threadPath, {
18627
18688
  skills: activatedSkills,
18628
18689
  threadId,
18629
18690
  threadPath,
18691
+ projectId: thread.projectId,
18630
18692
  metadataManager,
18631
- loadMcpTools: false
18693
+ loadMcpTools: false,
18694
+ disabledTools: project?.disabledTools
18632
18695
  });
18633
- const db = await getDatabase();
18634
- const project = await getProject(db, thread.projectId);
18635
18696
  const promptSections = await loadPromptSections(
18636
18697
  threadPath,
18637
18698
  tools,
@@ -18646,7 +18707,7 @@ async function computeContextBreakdown(threadId, conversationId, conversationMan
18646
18707
  }
18647
18708
  );
18648
18709
  const invocableAgents = agents.filter((agent) => !agent.disableModelInvocation);
18649
- if (invocableAgents.length > 0) {
18710
+ if (invocableAgents.length > 0 && isToolEnabled("agent") && isProjectToolEnabled("agent", project?.disabledTools)) {
18650
18711
  const agentToolInstance = createAgentTool({
18651
18712
  agents: invocableAgents,
18652
18713
  baseTools: tools,
@@ -18660,9 +18721,13 @@ async function computeContextBreakdown(threadId, conversationId, conversationMan
18660
18721
  });
18661
18722
  tools.push(agentToolInstance);
18662
18723
  }
18724
+ const toolsForDefinitionEstimate = filterToolsForDefinitionEstimate(
18725
+ tools,
18726
+ project?.disabledTools
18727
+ );
18663
18728
  const categories = {
18664
18729
  systemPrompt: estimateTokenCount(promptSections.systemPrompt),
18665
- toolDefinitions: estimateTokenCount(serializeToolsForEstimate(tools)),
18730
+ toolDefinitions: estimateTokenCount(serializeToolsForEstimate(toolsForDefinitionEstimate)),
18666
18731
  rules: estimateTokenCount(promptSections.rules),
18667
18732
  skills: estimateTokenCount(promptSections.skills),
18668
18733
  subagentDefinitions: estimateTokenCount(promptSections.subagentDefinitions),
@@ -20113,6 +20178,7 @@ async function handleListProjects(c, projectManager, threadManager, db) {
20113
20178
  allowAllCommands: project.allowAllCommands !== false,
20114
20179
  allowedCommandPatterns: project.allowedCommandPatterns ?? [],
20115
20180
  modelAliases: project.modelAliases,
20181
+ disabledTools: project.disabledTools ?? [],
20116
20182
  threads: threads.map((thread) => {
20117
20183
  const cached = statusCache.get(thread.id);
20118
20184
  const gitStatusDot = cached ? computeGitStatusDot(cached) : false;
@@ -20433,7 +20499,8 @@ async function handleUpdateProject(c, projectManager, metadataManager) {
20433
20499
  useCustomSystemPrompt,
20434
20500
  allowAllCommands,
20435
20501
  allowedCommandPatterns,
20436
- modelAliases
20502
+ modelAliases,
20503
+ disabledTools
20437
20504
  } = body;
20438
20505
  if (!projectId) {
20439
20506
  return errorResponse(c, ErrorCodes.INVALID_REQUEST, "Project ID is required", 400);
@@ -20508,6 +20575,10 @@ async function handleUpdateProject(c, projectManager, metadataManager) {
20508
20575
  }
20509
20576
  await projectManager.updateModelAliases(projectId, normalizedAliases);
20510
20577
  }
20578
+ if (disabledTools !== void 0) {
20579
+ const normalizedDisabledTools = normalizeDisabledTools(disabledTools);
20580
+ await projectManager.updateDisabledTools(projectId, normalizedDisabledTools);
20581
+ }
20511
20582
  if (name !== void 0) {
20512
20583
  if (!name?.trim()) {
20513
20584
  return errorResponse(c, ErrorCodes.INVALID_REQUEST, "Project name is required", 400);
@@ -24148,6 +24219,15 @@ ___CWD___%s
24148
24219
  project.modelAliases = modelAliases;
24149
24220
  await this.metadataManager.saveProjects(projects);
24150
24221
  }
24222
+ async updateDisabledTools(projectId, disabledTools) {
24223
+ const projects = await this.metadataManager.loadProjects();
24224
+ const project = projects.find((p) => p.id === projectId);
24225
+ if (!project) {
24226
+ throw new Error(`Project not found: ${projectId}`);
24227
+ }
24228
+ project.disabledTools = disabledTools.length > 0 ? disabledTools : [];
24229
+ await this.metadataManager.saveProjects(projects);
24230
+ }
24151
24231
  /**
24152
24232
  * Starts running a dev server process for a project
24153
24233
  * @param projectId - The project ID
@@ -32935,10 +33015,11 @@ var init_server_bind_mode_store = __esm({
32935
33015
  });
32936
33016
 
32937
33017
  // src/features/account/account-settings.route.ts
32938
- function buildAccountSettingsResponse(rawMaximumTurnCount, rawUseToolsThroughCode, serverBindMode) {
33018
+ function buildAccountSettingsResponse(rawMaximumTurnCount, rawUseToolsThroughCode, rawVoiceAiProcessing, serverBindMode) {
32939
33019
  return {
32940
33020
  maximumTurnCount: normalizeMaximumTurnCount(rawMaximumTurnCount),
32941
33021
  useToolsThroughCode: rawUseToolsThroughCode !== false,
33022
+ voiceAiProcessing: rawVoiceAiProcessing !== false,
32942
33023
  serverBindMode,
32943
33024
  networkAddresses: serverBindMode === "network" ? getLocalNetworkAddresses() : []
32944
33025
  };
@@ -32969,10 +33050,16 @@ async function getServerBindModeSetting() {
32969
33050
  async function getAccountSettings(c) {
32970
33051
  const db = await getDatabase();
32971
33052
  const rawUseToolsThroughCode = await getState(db, KEY_USE_TOOLS_THROUGH_CODE);
33053
+ const rawVoiceAiProcessing = await getState(db, KEY_VOICE_AI_PROCESSING);
32972
33054
  const rawMaximumTurnCount = await getState(db, KEY_MAXIMUM_TURN_COUNT);
32973
33055
  const serverBindMode = await getServerBindModeSetting();
32974
33056
  return c.json(
32975
- buildAccountSettingsResponse(rawMaximumTurnCount, rawUseToolsThroughCode, serverBindMode)
33057
+ buildAccountSettingsResponse(
33058
+ rawMaximumTurnCount,
33059
+ rawUseToolsThroughCode,
33060
+ rawVoiceAiProcessing,
33061
+ serverBindMode
33062
+ )
32976
33063
  );
32977
33064
  }
32978
33065
  async function updateAccountSettings(c) {
@@ -32981,6 +33068,9 @@ async function updateAccountSettings(c) {
32981
33068
  if (typeof body.useToolsThroughCode === "boolean") {
32982
33069
  await setState(db, KEY_USE_TOOLS_THROUGH_CODE, body.useToolsThroughCode);
32983
33070
  }
33071
+ if (typeof body.voiceAiProcessing === "boolean") {
33072
+ await setState(db, KEY_VOICE_AI_PROCESSING, body.voiceAiProcessing);
33073
+ }
32984
33074
  if (body.maximumTurnCount !== void 0) {
32985
33075
  await setState(db, KEY_MAXIMUM_TURN_COUNT, normalizeMaximumTurnCount(body.maximumTurnCount));
32986
33076
  }
@@ -32988,13 +33078,19 @@ async function updateAccountSettings(c) {
32988
33078
  writeServerBindMode(normalizeServerBindMode(body.serverBindMode));
32989
33079
  }
32990
33080
  const rawUseToolsThroughCode = await getState(db, KEY_USE_TOOLS_THROUGH_CODE);
33081
+ const rawVoiceAiProcessing = await getState(db, KEY_VOICE_AI_PROCESSING);
32991
33082
  const rawMaximumTurnCount = await getState(db, KEY_MAXIMUM_TURN_COUNT);
32992
33083
  const serverBindMode = readServerBindMode();
32993
33084
  return c.json(
32994
- buildAccountSettingsResponse(rawMaximumTurnCount, rawUseToolsThroughCode, serverBindMode)
33085
+ buildAccountSettingsResponse(
33086
+ rawMaximumTurnCount,
33087
+ rawUseToolsThroughCode,
33088
+ rawVoiceAiProcessing,
33089
+ serverBindMode
33090
+ )
32995
33091
  );
32996
33092
  }
32997
- var DEFAULT_MAXIMUM_TURN_COUNT, KEY_MAXIMUM_TURN_COUNT, KEY_USE_TOOLS_THROUGH_CODE, LEGACY_KEY_SERVER_BIND_MODE;
33093
+ var DEFAULT_MAXIMUM_TURN_COUNT, KEY_MAXIMUM_TURN_COUNT, KEY_USE_TOOLS_THROUGH_CODE, KEY_VOICE_AI_PROCESSING, LEGACY_KEY_SERVER_BIND_MODE;
32998
33094
  var init_account_settings_route = __esm({
32999
33095
  "src/features/account/account-settings.route.ts"() {
33000
33096
  "use strict";
@@ -33006,6 +33102,7 @@ var init_account_settings_route = __esm({
33006
33102
  DEFAULT_MAXIMUM_TURN_COUNT = 50;
33007
33103
  KEY_MAXIMUM_TURN_COUNT = "MaximumTurnCount";
33008
33104
  KEY_USE_TOOLS_THROUGH_CODE = "UseToolsThroughCode";
33105
+ KEY_VOICE_AI_PROCESSING = "VoiceAiProcessing";
33009
33106
  LEGACY_KEY_SERVER_BIND_MODE = "ServerBindMode";
33010
33107
  }
33011
33108
  });
@@ -33439,7 +33536,11 @@ function createBrowserJsRoutes(threadManager, projectManager, processingStateMan
33439
33536
  });
33440
33537
  }
33441
33538
  }) : void 0;
33442
- const tools = createAllTools(thread.path, { shellPermissionGate, threadId });
33539
+ const tools = createAllTools(thread.path, {
33540
+ shellPermissionGate,
33541
+ threadId,
33542
+ disabledTools: project?.disabledTools
33543
+ });
33443
33544
  const tool = tools[toolName];
33444
33545
  if (!tool) {
33445
33546
  return errorResponse(c, ErrorCodes.INVALID_REQUEST, `Tool ${toolName} not found`, 404);
@@ -33546,9 +33647,64 @@ var init_browser_routes = __esm({
33546
33647
  }
33547
33648
  });
33548
33649
 
33650
+ // src/features/voice-model/voice-transcript.route.ts
33651
+ import { completeSimple as completeSimple5 } from "@earendil-works/pi-ai";
33652
+ async function resolveProcessorModel2(metadataManager) {
33653
+ for (const [slug, defaultModel] of Object.entries(DEFAULT_PROCESSOR_MODELS2)) {
33654
+ const resolved = await resolveModelAndKey(slug, defaultModel, metadataManager);
33655
+ if (resolved) {
33656
+ return resolved;
33657
+ }
33658
+ }
33659
+ return null;
33660
+ }
33661
+ async function processVoiceTranscript(c, metadataManager) {
33662
+ const body = await c.req.json();
33663
+ const text = typeof body.text === "string" ? body.text.trim() : "";
33664
+ if (!text) {
33665
+ return c.json({ text: "" });
33666
+ }
33667
+ const resolved = await resolveProcessorModel2(metadataManager);
33668
+ if (!resolved) {
33669
+ return c.json({ text });
33670
+ }
33671
+ try {
33672
+ const userMessage = `${VOICE_CLEANUP_SYSTEM_PROMPT}
33673
+
33674
+ Transcription to clean up:
33675
+ ${text}`;
33676
+ const response = await completeSimple5(
33677
+ resolved.model,
33678
+ {
33679
+ messages: [{ role: "user", content: userMessage, timestamp: Date.now() }]
33680
+ },
33681
+ { apiKey: resolved.apiKey }
33682
+ );
33683
+ const cleaned = response.content.filter((block) => block.type === "text").map((block) => block.text).join("").trim();
33684
+ return c.json({ text: cleaned || text });
33685
+ } catch {
33686
+ return c.json({ text });
33687
+ }
33688
+ }
33689
+ var DEFAULT_PROCESSOR_MODELS2, VOICE_CLEANUP_SYSTEM_PROMPT;
33690
+ var init_voice_transcript_route = __esm({
33691
+ "src/features/voice-model/voice-transcript.route.ts"() {
33692
+ "use strict";
33693
+ init_git_utils();
33694
+ DEFAULT_PROCESSOR_MODELS2 = {
33695
+ anthropic: "claude-haiku-4-5-20251001",
33696
+ openai: "gpt-4o-mini",
33697
+ openrouter: "openai/gpt-4o-mini",
33698
+ groq: "llama-3.3-70b-versatile",
33699
+ deepseek: "deepseek-chat"
33700
+ };
33701
+ VOICE_CLEANUP_SYSTEM_PROMPT = `You are a voice transcription cleanup assistant. The text you receive was transcribed from live speech and may contain filler words (um, uh, ah, er), false starts, repetitions, and other spoken language artifacts. Clean it up into clear, readable text that preserves the original meaning and intent. Remove filler words, fix false starts, and eliminate unnecessary repetitions. Return only the cleaned text \u2014 no explanation, no commentary, no quotes.`;
33702
+ }
33703
+ });
33704
+
33549
33705
  // src/features/voice-model/voice-model.routes.ts
33550
33706
  import { Hono as Hono24 } from "hono";
33551
- function createVoiceModelRoutes() {
33707
+ function createVoiceModelRoutes(metadataManager) {
33552
33708
  const router = new Hono24();
33553
33709
  router.get("/download", async (c) => {
33554
33710
  try {
@@ -33583,6 +33739,7 @@ function createVoiceModelRoutes() {
33583
33739
  );
33584
33740
  }
33585
33741
  });
33742
+ router.post("/process-transcript", (c) => processVoiceTranscript(c, metadataManager));
33586
33743
  return router;
33587
33744
  }
33588
33745
  var VOICE_MODEL_URL;
@@ -33591,6 +33748,7 @@ var init_voice_model_routes = __esm({
33591
33748
  "use strict";
33592
33749
  init_route_helpers();
33593
33750
  init_error_responses();
33751
+ init_voice_transcript_route();
33594
33752
  VOICE_MODEL_URL = "https://install.tarsk.io/voice-models/vosk-model-small-en-us-0.15.tar.gz";
33595
33753
  }
33596
33754
  });
@@ -33951,7 +34109,7 @@ async function startTarskServerInternal(options) {
33951
34109
  createBrowserJsRoutes(threadManager, projectManager, processingStateManager)
33952
34110
  );
33953
34111
  app.route("/api/browser", createBrowserRoutes());
33954
- app.route("/api/voice-model", createVoiceModelRoutes());
34112
+ app.route("/api/voice-model", createVoiceModelRoutes(metadataManager));
33955
34113
  app.route("/api/logs", createLogsRoutes());
33956
34114
  app.route("/api/system-permissions", createSystemPermissionsRoutes());
33957
34115
  app.route("/api/update", createUpdateRoutes(options.updater));