syntaur 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dashboard/dist/assets/{_basePickBy-DmVNJO8J.js → _basePickBy-BboQhTYn.js} +1 -1
  3. package/dashboard/dist/assets/{_baseUniq-BtWQDHxm.js → _baseUniq-C6ARYdEJ.js} +1 -1
  4. package/dashboard/dist/assets/{arc-BDZ8fFmA.js → arc-D76wUYJ-.js} +1 -1
  5. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-DmE3bMva.js → architectureDiagram-2XIMDMQ5-eoW8_dbN.js} +1 -1
  6. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-BUpzLbve.js → blockDiagram-WCTKOSBZ--XxaNbBK.js} +1 -1
  7. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-5lB7kxgt.js → c4Diagram-IC4MRINW-D2B-NJq6.js} +1 -1
  8. package/dashboard/dist/assets/channel-BPykMjmL.js +1 -0
  9. package/dashboard/dist/assets/{chunk-4BX2VUAB-DdRqNqOP.js → chunk-4BX2VUAB-CY34rkdT.js} +1 -1
  10. package/dashboard/dist/assets/{chunk-55IACEB6-D_qI2OxO.js → chunk-55IACEB6-CLXE1Ejn.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-FMBD7UC4-BMtQHZt3.js → chunk-FMBD7UC4-D00VtmIk.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-JSJVCQXG-CeCGSMMb.js → chunk-JSJVCQXG-_EITJTaI.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-KX2RTZJC-Biv2a0MB.js → chunk-KX2RTZJC-DrqZI_kX.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-NQ4KR5QH-CbkEQT8f.js → chunk-NQ4KR5QH-DnYhUmZY.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-QZHKN3VN-BU54yyBK.js → chunk-QZHKN3VN-CqCcFoFI.js} +1 -1
  16. package/dashboard/dist/assets/{chunk-WL4C6EOR-ypzKdtzY.js → chunk-WL4C6EOR-Bwx5h46l.js} +1 -1
  17. package/dashboard/dist/assets/classDiagram-VBA2DB6C-z8L393gl.js +1 -0
  18. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-z8L393gl.js +1 -0
  19. package/dashboard/dist/assets/clone--rMJOGpf.js +1 -0
  20. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-Cfexs6Pq.js → cose-bilkent-S5V4N54A-QUZroYuH.js} +1 -1
  21. package/dashboard/dist/assets/{dagre-KLK3FWXG-BjdeaK5Z.js → dagre-KLK3FWXG-D8hYiZ7i.js} +1 -1
  22. package/dashboard/dist/assets/{diagram-E7M64L7V-BVZRb5bD.js → diagram-E7M64L7V-Cl_n980P.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-IFDJBPK2-6fnO4hw1.js → diagram-IFDJBPK2-01DdmzmS.js} +1 -1
  24. package/dashboard/dist/assets/{diagram-P4PSJMXO-DX_fbvo0.js → diagram-P4PSJMXO-GcqkAPB2.js} +1 -1
  25. package/dashboard/dist/assets/{erDiagram-INFDFZHY-Dc-Ult_U.js → erDiagram-INFDFZHY-DQnXbhhn.js} +1 -1
  26. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-nrIBfe3g.js → flowDiagram-PKNHOUZH-DSmXtiZK.js} +1 -1
  27. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-7zt_k1Nl.js → ganttDiagram-A5KZAMGK-BLyt9LDp.js} +1 -1
  28. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-2yK7iOPo.js → gitGraphDiagram-K3NZZRJ6-FWlr0I_j.js} +1 -1
  29. package/dashboard/dist/assets/{graph-DD0OOYtL.js → graph-Czw8ZNXY.js} +1 -1
  30. package/dashboard/dist/assets/index-EntCfH3I.css +1 -0
  31. package/dashboard/dist/assets/index-zHNBGpC7.js +602 -0
  32. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-7nottSf8.js → infoDiagram-LFFYTUFH-CygGWMzd.js} +1 -1
  33. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-DHd9lm-i.js → ishikawaDiagram-PHBUUO56-39XaFufR.js} +1 -1
  34. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-BS86Ecdy.js → journeyDiagram-4ABVD52K-DCMzi84v.js} +1 -1
  35. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-B9uccuva.js → kanban-definition-K7BYSVSG-RSNF4GmM.js} +1 -1
  36. package/dashboard/dist/assets/{layout-Bq6MeguZ.js → layout-AOYFASCy.js} +1 -1
  37. package/dashboard/dist/assets/{linear-XkyDYAy6.js → linear-Bf-cRRMe.js} +1 -1
  38. package/dashboard/dist/assets/{mermaid.core-BH9rlHr4.js → mermaid.core-7QJzPWTu.js} +4 -4
  39. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-Cc-hDkvW.js → mindmap-definition-YRQLILUH-Ck4L1K7y.js} +1 -1
  40. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-BFIPTP1F.js → pieDiagram-SKSYHLDU-BHEH_9Yh.js} +1 -1
  41. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-yVL8WrSz.js → quadrantDiagram-337W2JSQ-DScQHhsU.js} +1 -1
  42. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-DxWjrQut.js → requirementDiagram-Z7DCOOCP-DLmxwUdt.js} +1 -1
  43. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-BPkz1Yl7.js → sankeyDiagram-WA2Y5GQK-B6OZtKmg.js} +1 -1
  44. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-DlgeS-S7.js → sequenceDiagram-2WXFIKYE-woFPqQIY.js} +1 -1
  45. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-DBpOK-Ql.js → stateDiagram-RAJIS63D-Db9HV_HG.js} +1 -1
  46. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-DZsj07hg.js +1 -0
  47. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-abDjZ0W-.js → timeline-definition-YZTLITO2-CGVOTXAD.js} +1 -1
  48. package/dashboard/dist/assets/{treemap-KZPCXAKY-bF6AoBlY.js → treemap-KZPCXAKY-CGmqtjaL.js} +1 -1
  49. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-lUeCE7KT.js → vennDiagram-LZ73GAT5-DAuyqqKn.js} +1 -1
  50. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-ByECFP6v.js → xychartDiagram-JWTSCODW--uOFgr6-.js} +1 -1
  51. package/dashboard/dist/index.html +2 -2
  52. package/dist/dashboard/server.js +290 -23
  53. package/dist/dashboard/server.js.map +1 -1
  54. package/dist/index.js +290 -23
  55. package/dist/index.js.map +1 -1
  56. package/dist/launch/index.d.ts +25 -0
  57. package/dist/launch/index.js +187 -1
  58. package/dist/launch/index.js.map +1 -1
  59. package/package.json +1 -1
  60. package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
  61. package/platforms/codex/.codex-plugin/plugin.json +1 -1
  62. package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
  63. package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
  64. package/dashboard/dist/assets/channel-SCYGGwh4.js +0 -1
  65. package/dashboard/dist/assets/classDiagram-VBA2DB6C-DDovN08E.js +0 -1
  66. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-DDovN08E.js +0 -1
  67. package/dashboard/dist/assets/clone-DjHcKoH3.js +0 -1
  68. package/dashboard/dist/assets/index-BKfPPYKw.js +0 -602
  69. package/dashboard/dist/assets/index-C8THdvxD.css +0 -1
  70. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-CS61beS7.js +0 -1
package/dist/index.js CHANGED
@@ -3439,6 +3439,98 @@ var init_terminal_schema = __esm({
3439
3439
  }
3440
3440
  });
3441
3441
 
3442
+ // src/utils/search-schema.ts
3443
+ function isEntityKind(value) {
3444
+ return typeof value === "string" && ENTITY_KINDS.includes(value);
3445
+ }
3446
+ function isDefaultScope(value) {
3447
+ return value === "all" || isEntityKind(value);
3448
+ }
3449
+ function normalizeSearchConfig(raw2) {
3450
+ if (!raw2 || typeof raw2 !== "object") {
3451
+ return cloneDefaultSearchConfig();
3452
+ }
3453
+ const r = raw2;
3454
+ const defaultScope = isDefaultScope(r["defaultScope"]) ? r["defaultScope"] : DEFAULT_SEARCH_CONFIG.defaultScope;
3455
+ const externalIds = typeof r["externalIds"] === "boolean" ? r["externalIds"] : DEFAULT_SEARCH_CONFIG.externalIds;
3456
+ let aliases;
3457
+ if (r["aliases"] && typeof r["aliases"] === "object") {
3458
+ aliases = {};
3459
+ for (const [key, value] of Object.entries(r["aliases"])) {
3460
+ if (ALIAS_KEY_RE.test(key) && key !== RESERVED_ALIAS && !SEARCH_FIELD_NAMES.includes(key) && isEntityKind(value)) {
3461
+ aliases[key] = value;
3462
+ }
3463
+ }
3464
+ } else {
3465
+ aliases = { ...DEFAULT_SEARCH_CONFIG.aliases };
3466
+ }
3467
+ return { defaultScope, aliases, externalIds };
3468
+ }
3469
+ function validateAliases(aliases) {
3470
+ if (!aliases || typeof aliases !== "object") {
3471
+ return { ok: false, errors: ["aliases must be an object"] };
3472
+ }
3473
+ const errors = [];
3474
+ for (const [key, value] of Object.entries(aliases)) {
3475
+ if (!ALIAS_KEY_RE.test(key)) {
3476
+ errors.push(`alias key "${key}" must be lowercase and match [a-z][a-z0-9]*`);
3477
+ }
3478
+ if (key === RESERVED_ALIAS) {
3479
+ errors.push(`alias key "${RESERVED_ALIAS}" is reserved (the "search everything" escape)`);
3480
+ }
3481
+ if (SEARCH_FIELD_NAMES.includes(key)) {
3482
+ errors.push(`alias key "${key}" collides with the reserved field name "${key}"`);
3483
+ }
3484
+ if (!isEntityKind(value)) {
3485
+ errors.push(`alias "${key}" must map to one of: ${ENTITY_KINDS.join(", ")}`);
3486
+ }
3487
+ }
3488
+ return errors.length === 0 ? { ok: true } : { ok: false, errors };
3489
+ }
3490
+ function isValidDefaultScope(value) {
3491
+ return isDefaultScope(value);
3492
+ }
3493
+ function cloneDefaultSearchConfig() {
3494
+ return {
3495
+ defaultScope: DEFAULT_SEARCH_CONFIG.defaultScope,
3496
+ aliases: { ...DEFAULT_SEARCH_CONFIG.aliases },
3497
+ externalIds: DEFAULT_SEARCH_CONFIG.externalIds
3498
+ };
3499
+ }
3500
+ var ENTITY_KINDS, DEFAULT_SEARCH_CONFIG, SEARCH_FIELD_NAMES, RESERVED_ALIAS, ALIAS_KEY_RE;
3501
+ var init_search_schema = __esm({
3502
+ "src/utils/search-schema.ts"() {
3503
+ "use strict";
3504
+ ENTITY_KINDS = [
3505
+ "assignment",
3506
+ "project",
3507
+ "todo",
3508
+ "server",
3509
+ "playbook"
3510
+ ];
3511
+ DEFAULT_SEARCH_CONFIG = {
3512
+ defaultScope: "all",
3513
+ aliases: { a: "assignment", p: "project", t: "todo", s: "server", pb: "playbook" },
3514
+ externalIds: true
3515
+ };
3516
+ SEARCH_FIELD_NAMES = [
3517
+ "kind",
3518
+ "status",
3519
+ "tag",
3520
+ "tags",
3521
+ "assignee",
3522
+ "type",
3523
+ "project",
3524
+ "externalid",
3525
+ "jira",
3526
+ "title",
3527
+ "search"
3528
+ ];
3529
+ RESERVED_ALIAS = "all";
3530
+ ALIAS_KEY_RE = /^[a-z][a-z0-9]*$/;
3531
+ }
3532
+ });
3533
+
3442
3534
  // src/utils/workspace-visibility-schema.ts
3443
3535
  function normalizeHiddenList(input4) {
3444
3536
  if (!Array.isArray(input4)) return [];
@@ -3479,18 +3571,22 @@ __export(config_exports, {
3479
3571
  buildDefaultStatusConfig: () => buildDefaultStatusConfig,
3480
3572
  deleteAgentsConfig: () => deleteAgentsConfig,
3481
3573
  deleteHotkeyBindingsConfig: () => deleteHotkeyBindingsConfig,
3574
+ deleteSearchConfig: () => deleteSearchConfig,
3482
3575
  deleteStatusConfig: () => deleteStatusConfig,
3483
3576
  deleteTerminalConfig: () => deleteTerminalConfig,
3484
3577
  deleteThemeConfig: () => deleteThemeConfig,
3485
3578
  deleteWorkspaceVisibilityConfig: () => deleteWorkspaceVisibilityConfig,
3486
3579
  getAgents: () => getAgents,
3487
3580
  getAssignmentTypes: () => getAssignmentTypes,
3581
+ getSearchConfig: () => getSearchConfig,
3488
3582
  getTerminal: () => getTerminal,
3489
3583
  normalizeFactDeclarations: () => normalizeFactDeclarations,
3490
3584
  parseAgentCommand: () => parseAgentCommand,
3585
+ parseSearchConfig: () => parseSearchConfig,
3491
3586
  parseStatusConfig: () => parseStatusConfig,
3492
3587
  parseTerminalConfig: () => parseTerminalConfig,
3493
3588
  readConfig: () => readConfig,
3589
+ serializeSearchConfig: () => serializeSearchConfig,
3494
3590
  serializeStatusConfig: () => serializeStatusConfig,
3495
3591
  toTitleCase: () => toTitleCase,
3496
3592
  updateAgentsConfig: () => updateAgentsConfig,
@@ -3504,6 +3600,7 @@ __export(config_exports, {
3504
3600
  validateFactDeclarations: () => validateFactDeclarations,
3505
3601
  writeAgentsConfig: () => writeAgentsConfig,
3506
3602
  writeHotkeyBindingsConfig: () => writeHotkeyBindingsConfig,
3603
+ writeSearchConfig: () => writeSearchConfig,
3507
3604
  writeStatusConfig: () => writeStatusConfig,
3508
3605
  writeTerminalConfig: () => writeTerminalConfig,
3509
3606
  writeThemeConfig: () => writeThemeConfig,
@@ -4311,7 +4408,7 @@ function stripTopLevelBlock(fmBlock, key) {
4311
4408
  if (!blockStart) {
4312
4409
  return fmBlock.replace(/\n+$/, "");
4313
4410
  }
4314
- const startIdx = fmBlock.indexOf(blockStart[0]);
4411
+ const startIdx = blockStart.index ?? 0;
4315
4412
  const before = fmBlock.slice(0, startIdx);
4316
4413
  const after = fmBlock.slice(startIdx + blockStart[0].length);
4317
4414
  const remaining = after.split("\n");
@@ -4737,6 +4834,116 @@ ${cleanedFm}
4737
4834
  ---${afterFrontmatter}`;
4738
4835
  await writeFileForce(configPath2, newContent);
4739
4836
  }
4837
+ function parseSearchConfig(content) {
4838
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
4839
+ if (!match) return null;
4840
+ const fmBlock = match[1];
4841
+ const blockStart = fmBlock.match(/^search:\s*$/m);
4842
+ if (!blockStart) return null;
4843
+ const startIdx = (blockStart.index ?? 0) + blockStart[0].length;
4844
+ const lines = fmBlock.slice(startIdx).split("\n");
4845
+ const unquote = (v) => {
4846
+ const t = v.trim();
4847
+ if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) {
4848
+ return t.slice(1, -1);
4849
+ }
4850
+ return t;
4851
+ };
4852
+ const raw2 = {};
4853
+ let inAliases = false;
4854
+ for (const line of lines) {
4855
+ if (line.trim() === "") continue;
4856
+ const trimmed = line.trimStart();
4857
+ const indent = line.length - trimmed.length;
4858
+ if (indent === 0) break;
4859
+ if (indent <= 2) {
4860
+ inAliases = false;
4861
+ if (trimmed === "aliases:") {
4862
+ inAliases = true;
4863
+ raw2.aliases = {};
4864
+ continue;
4865
+ }
4866
+ const ci = trimmed.indexOf(":");
4867
+ if (ci <= 0) continue;
4868
+ const key = trimmed.slice(0, ci).trim();
4869
+ const value = unquote(trimmed.slice(ci + 1).trim());
4870
+ if (key === "defaultScope") {
4871
+ raw2.defaultScope = value;
4872
+ } else if (key === "externalIds") {
4873
+ const v = value.toLowerCase();
4874
+ if (v === "true") raw2.externalIds = true;
4875
+ else if (v === "false") raw2.externalIds = false;
4876
+ }
4877
+ } else if (inAliases) {
4878
+ const ci = trimmed.indexOf(":");
4879
+ if (ci <= 0) continue;
4880
+ raw2.aliases ??= {};
4881
+ raw2.aliases[trimmed.slice(0, ci).trim()] = unquote(trimmed.slice(ci + 1).trim());
4882
+ }
4883
+ }
4884
+ return normalizeSearchConfig(raw2);
4885
+ }
4886
+ function serializeSearchConfig(search) {
4887
+ const cfg = normalizeSearchConfig(search);
4888
+ const lines = ["search:"];
4889
+ lines.push(` defaultScope: ${cfg.defaultScope}`);
4890
+ lines.push(" aliases:");
4891
+ for (const [prefix, kind] of Object.entries(cfg.aliases)) {
4892
+ lines.push(` ${prefix}: ${kind}`);
4893
+ }
4894
+ lines.push(` externalIds: ${cfg.externalIds ? "true" : "false"}`);
4895
+ return lines.join("\n");
4896
+ }
4897
+ async function writeSearchConfig(search) {
4898
+ const configPath2 = resolve6(syntaurRoot(), "config.md");
4899
+ const searchBlock = serializeSearchConfig(search);
4900
+ if (!await fileExists(configPath2)) {
4901
+ const content = `---
4902
+ version: "2.0"
4903
+ defaultProjectDir: ~/projects
4904
+ ${searchBlock}
4905
+ ---
4906
+ `;
4907
+ await writeFileForce(configPath2, content);
4908
+ return;
4909
+ }
4910
+ const existing = await readFile5(configPath2, "utf-8");
4911
+ const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
4912
+ if (!fmMatch) {
4913
+ const content = `---
4914
+ version: "2.0"
4915
+ ${searchBlock}
4916
+ ---
4917
+ ${existing}`;
4918
+ await writeFileForce(configPath2, content);
4919
+ return;
4920
+ }
4921
+ const fmBlock = fmMatch[2];
4922
+ const afterFrontmatter = existing.slice(fmMatch[0].length);
4923
+ const cleanedFm = stripTopLevelBlock(fmBlock, "search");
4924
+ const newContent = `---
4925
+ ${cleanedFm}
4926
+ ${searchBlock}
4927
+ ---${afterFrontmatter}`;
4928
+ await writeFileForce(configPath2, newContent);
4929
+ }
4930
+ async function deleteSearchConfig() {
4931
+ const configPath2 = resolve6(syntaurRoot(), "config.md");
4932
+ if (!await fileExists(configPath2)) return;
4933
+ const existing = await readFile5(configPath2, "utf-8");
4934
+ const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
4935
+ if (!fmMatch) return;
4936
+ const fmBlock = fmMatch[2];
4937
+ const afterFrontmatter = existing.slice(fmMatch[0].length);
4938
+ const cleanedFm = stripTopLevelBlock(fmBlock, "search");
4939
+ const newContent = `---
4940
+ ${cleanedFm}
4941
+ ---${afterFrontmatter}`;
4942
+ await writeFileForce(configPath2, newContent);
4943
+ }
4944
+ function getSearchConfig(config) {
4945
+ return config.searchConfig ?? DEFAULT_SEARCH_CONFIG;
4946
+ }
4740
4947
  async function updateIntegrationConfig(integrations) {
4741
4948
  const configPath2 = resolve6(syntaurRoot(), "config.md");
4742
4949
  const nextIntegrations = {
@@ -4908,6 +5115,7 @@ async function readConfig() {
4908
5115
  return null;
4909
5116
  }
4910
5117
  })(),
5118
+ searchConfig: parseSearchConfig(content),
4911
5119
  workspaceVisibility: parseWorkspaceVisibilityConfig(fmBlock)
4912
5120
  };
4913
5121
  }
@@ -4986,6 +5194,7 @@ var init_config2 = __esm({
4986
5194
  init_derive_config();
4987
5195
  init_fact_registry();
4988
5196
  init_terminal_schema();
5197
+ init_search_schema();
4989
5198
  init_workspace_visibility_schema();
4990
5199
  DEFAULT_ASSIGNMENT_TYPES = {
4991
5200
  definitions: [
@@ -5026,6 +5235,7 @@ var init_config2 = __esm({
5026
5235
  theme: null,
5027
5236
  hotkeys: null,
5028
5237
  terminal: null,
5238
+ searchConfig: null,
5029
5239
  workspaceVisibility: {
5030
5240
  hidden: []
5031
5241
  }
@@ -19557,12 +19767,68 @@ function createTerminalConfigRouter() {
19557
19767
  return router;
19558
19768
  }
19559
19769
 
19770
+ // src/dashboard/api-search-config.ts
19771
+ init_config2();
19772
+ init_search_schema();
19773
+ import { Router as Router8 } from "express";
19774
+ function createSearchConfigRouter() {
19775
+ const router = Router8();
19776
+ router.get("/", async (_req, res) => {
19777
+ try {
19778
+ const config = await readConfig();
19779
+ res.json({
19780
+ search: getSearchConfig(config),
19781
+ custom: config.searchConfig !== null
19782
+ });
19783
+ } catch (error) {
19784
+ console.error("Error getting search config:", error);
19785
+ res.status(500).json({ error: "Failed to get search config" });
19786
+ }
19787
+ });
19788
+ router.post("/", async (req2, res) => {
19789
+ try {
19790
+ const body = req2.body ?? {};
19791
+ if (body["defaultScope"] !== void 0 && !isValidDefaultScope(body["defaultScope"])) {
19792
+ res.status(400).json({
19793
+ error: `defaultScope must be one of: all, ${ENTITY_KINDS.join(", ")}`
19794
+ });
19795
+ return;
19796
+ }
19797
+ const aliasCheck = validateAliases(body["aliases"] ?? {});
19798
+ if (!aliasCheck.ok) {
19799
+ res.status(400).json({ error: "Invalid aliases", errors: aliasCheck.errors });
19800
+ return;
19801
+ }
19802
+ const search = normalizeSearchConfig(body);
19803
+ await writeSearchConfig(search);
19804
+ res.json({ search, custom: true });
19805
+ } catch (error) {
19806
+ console.error("Error saving search config:", error);
19807
+ res.status(500).json({ error: "Failed to save search config" });
19808
+ }
19809
+ });
19810
+ router.delete("/", async (_req, res) => {
19811
+ try {
19812
+ await deleteSearchConfig();
19813
+ const config = await readConfig();
19814
+ res.json({
19815
+ search: getSearchConfig(config),
19816
+ custom: config.searchConfig !== null
19817
+ });
19818
+ } catch (error) {
19819
+ console.error("Error resetting search config:", error);
19820
+ res.status(500).json({ error: "Failed to reset search config" });
19821
+ }
19822
+ });
19823
+ return router;
19824
+ }
19825
+
19560
19826
  // src/dashboard/api-workspace-visibility-config.ts
19561
19827
  init_config2();
19562
19828
  init_workspace_visibility_schema();
19563
- import { Router as Router8 } from "express";
19829
+ import { Router as Router9 } from "express";
19564
19830
  function createWorkspaceVisibilityConfigRouter() {
19565
- const router = Router8();
19831
+ const router = Router9();
19566
19832
  router.get("/", async (_req, res) => {
19567
19833
  try {
19568
19834
  const config = await readConfig();
@@ -19608,7 +19874,7 @@ init_fact_registry();
19608
19874
  init_state_machine();
19609
19875
  init_api();
19610
19876
  init_derive();
19611
- import { Router as Router9 } from "express";
19877
+ import { Router as Router10 } from "express";
19612
19878
 
19613
19879
  // src/utils/status-config-resolution.ts
19614
19880
  init_frontmatter();
@@ -20024,7 +20290,7 @@ function mapResolutionErrorToHttp(err2, applied) {
20024
20290
  }
20025
20291
  }
20026
20292
  function createStatusConfigRouter(projectsDir2, assignmentsDir2) {
20027
- const router = Router9();
20293
+ const router = Router10();
20028
20294
  installRecordsInvalidation(router);
20029
20295
  router.get("/", async (_req, res) => {
20030
20296
  try {
@@ -20344,7 +20610,7 @@ function createStatusConfigRouter(projectsDir2, assignmentsDir2) {
20344
20610
  }
20345
20611
 
20346
20612
  // src/dashboard/api-leases.ts
20347
- import { Router as Router10 } from "express";
20613
+ import { Router as Router11 } from "express";
20348
20614
 
20349
20615
  // src/db/leases-db.ts
20350
20616
  init_paths();
@@ -20975,7 +21241,7 @@ function releaseLeasesByRequestedFor(tag) {
20975
21241
 
20976
21242
  // src/dashboard/api-leases.ts
20977
21243
  function createLeasesRouter(broadcast) {
20978
- const router = Router10();
21244
+ const router = Router11();
20979
21245
  router.get("/", (_req, res) => {
20980
21246
  try {
20981
21247
  initLeasesDb();
@@ -21031,7 +21297,7 @@ function createLeasesRouter(broadcast) {
21031
21297
 
21032
21298
  // src/dashboard/api-schedules.ts
21033
21299
  init_timestamp();
21034
- import { Router as Router11 } from "express";
21300
+ import { Router as Router12 } from "express";
21035
21301
 
21036
21302
  // src/schedules/store.ts
21037
21303
  init_fs();
@@ -21592,7 +21858,7 @@ function canFire(job, deps) {
21592
21858
  init_agent_sessions();
21593
21859
  init_session_db();
21594
21860
  function createSchedulesRouter(broadcast) {
21595
- const router = Router11();
21861
+ const router = Router12();
21596
21862
  const notify = () => broadcast?.({ type: "schedules-updated", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
21597
21863
  router.get("/", async (_req, res) => {
21598
21864
  try {
@@ -21975,7 +22241,7 @@ async function runTick(deps = {}) {
21975
22241
  }
21976
22242
 
21977
22243
  // src/dashboard/api-usage.ts
21978
- import { Router as Router12 } from "express";
22244
+ import { Router as Router13 } from "express";
21979
22245
 
21980
22246
  // src/db/usage-db.ts
21981
22247
  init_paths();
@@ -22232,7 +22498,7 @@ function listDistinctTools() {
22232
22498
  // src/dashboard/api-usage.ts
22233
22499
  init_api();
22234
22500
  function createUsageRouter(projectsDir2, assignmentsDir2) {
22235
- const router = Router12();
22501
+ const router = Router13();
22236
22502
  router.get("/facets", (_req, res) => {
22237
22503
  try {
22238
22504
  initUsageDb();
@@ -22417,7 +22683,7 @@ init_timestamp();
22417
22683
  init_fs();
22418
22684
  init_playbook();
22419
22685
  init_playbooks();
22420
- import { Router as Router13 } from "express";
22686
+ import { Router as Router14 } from "express";
22421
22687
  import { resolve as resolve36 } from "path";
22422
22688
  import { readFile as readFile24 } from "fs/promises";
22423
22689
  function statusForPlaybookError(code) {
@@ -22433,7 +22699,7 @@ function statusForPlaybookError(code) {
22433
22699
  }
22434
22700
  }
22435
22701
  function createPlaybooksRouter(playbooksDir3) {
22436
- const router = Router13();
22702
+ const router = Router14();
22437
22703
  router.get("/", async (_req, res) => {
22438
22704
  try {
22439
22705
  const playbooks = await listPlaybooks(playbooksDir3);
@@ -22597,7 +22863,7 @@ init_fs_migration();
22597
22863
  init_parser2();
22598
22864
  init_fs();
22599
22865
  init_paths();
22600
- import { Router as Router15 } from "express";
22866
+ import { Router as Router16 } from "express";
22601
22867
  import { readdir as readdir16 } from "fs/promises";
22602
22868
  import { resolve as resolvePath, dirname as dirname11 } from "path";
22603
22869
  import { rename as rename6, mkdir as mkdir5 } from "fs/promises";
@@ -22966,7 +23232,7 @@ function touchItem3(item) {
22966
23232
  item.updatedAt = now;
22967
23233
  }
22968
23234
  function createTodosRouter(todosDir2, broadcast, projectsDir2) {
22969
- const router = Router15();
23235
+ const router = Router16();
22970
23236
  installRecordsInvalidation(router);
22971
23237
  function broadcastUpdate() {
22972
23238
  broadcast({ type: "todos-updated", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
@@ -23740,7 +24006,7 @@ init_parser2();
23740
24006
  init_fs();
23741
24007
  init_paths();
23742
24008
  init_slug();
23743
- import { Router as Router16 } from "express";
24009
+ import { Router as Router17 } from "express";
23744
24010
  import { mkdir as mkdir6, readFile as readFile25, rename as rename7 } from "fs/promises";
23745
24011
  import { resolve as resolve38, dirname as dirname12 } from "path";
23746
24012
  init_promote_todos();
@@ -23792,7 +24058,7 @@ function notFound(res, slug) {
23792
24058
  res.status(404).json({ error: `Project "${slug}" not found` });
23793
24059
  }
23794
24060
  function createProjectTodosRouter(projectsDir2, broadcast, workspaceTodosDir) {
23795
- const router = Router16({ mergeParams: true });
24061
+ const router = Router17({ mergeParams: true });
23796
24062
  installRecordsInvalidation(router);
23797
24063
  function broadcastUpdate(projectSlug) {
23798
24064
  broadcast({ type: "todos-updated", projectSlug, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
@@ -24651,7 +24917,7 @@ workspace: ${slug}
24651
24917
  }
24652
24918
 
24653
24919
  // src/dashboard/api-bundles.ts
24654
- import { Router as Router17 } from "express";
24920
+ import { Router as Router18 } from "express";
24655
24921
  import { readdir as readdir17 } from "fs/promises";
24656
24922
 
24657
24923
  // src/todos/bundle-parser.ts
@@ -24802,7 +25068,7 @@ function annotate(bundle, items) {
24802
25068
  }
24803
25069
  function createBundlesRouter(todosDir2, broadcast) {
24804
25070
  void broadcast;
24805
- const router = Router17();
25071
+ const router = Router18();
24806
25072
  function validateWorkspace(req2, res, next) {
24807
25073
  const workspace = getWorkspaceParam2(req2.params.workspace);
24808
25074
  if (workspace && !WORKSPACE_REGEX3.test(workspace)) {
@@ -24868,7 +25134,7 @@ function createBundlesRouter(todosDir2, broadcast) {
24868
25134
  init_fs();
24869
25135
  init_paths();
24870
25136
  init_slug();
24871
- import { Router as Router18 } from "express";
25137
+ import { Router as Router19 } from "express";
24872
25138
  import { resolve as resolve39 } from "path";
24873
25139
  init_parser2();
24874
25140
  function deriveStatus2(bundle, items) {
@@ -24898,7 +25164,7 @@ function notFound2(res, slug) {
24898
25164
  }
24899
25165
  function createProjectBundlesRouter(projectsDir2, broadcast) {
24900
25166
  void broadcast;
24901
- const router = Router18({ mergeParams: true });
25167
+ const router = Router19({ mergeParams: true });
24902
25168
  function validateProjectId(req2, res, next) {
24903
25169
  const slug = getProjectIdParam2(req2.params.projectId);
24904
25170
  if (!slug || !isValidSlug(slug)) {
@@ -24932,7 +25198,7 @@ function createProjectBundlesRouter(projectsDir2, broadcast) {
24932
25198
  init_config2();
24933
25199
  init_api();
24934
25200
  init_scanner();
24935
- import { Router as Router19 } from "express";
25201
+ import { Router as Router20 } from "express";
24936
25202
 
24937
25203
  // src/utils/github-backup.ts
24938
25204
  init_paths();
@@ -25255,7 +25521,7 @@ async function getBackupStatus() {
25255
25521
 
25256
25522
  // src/dashboard/api-backup.ts
25257
25523
  function createBackupRouter() {
25258
- const router = Router19();
25524
+ const router = Router20();
25259
25525
  router.get("/", async (_req, res) => {
25260
25526
  try {
25261
25527
  const status = await getBackupStatus();
@@ -26114,6 +26380,7 @@ function createDashboardServer(options) {
26114
26380
  }
26115
26381
  });
26116
26382
  app.use("/api/config/terminal", createTerminalConfigRouter());
26383
+ app.use("/api/config/search", createSearchConfigRouter());
26117
26384
  app.use("/api/config/workspace-visibility", createWorkspaceVisibilityConfigRouter());
26118
26385
  app.get("/api/config/hotkeys", async (_req, res) => {
26119
26386
  try {