syntaur 0.44.1 → 0.45.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-n0wU3YiR.js → _basePickBy-RQBuJKcX.js} +1 -1
  3. package/dashboard/dist/assets/{_baseUniq-CZE21ua2.js → _baseUniq-_J7s4kD3.js} +1 -1
  4. package/dashboard/dist/assets/{arc-Dd_UCPQq.js → arc-_9SyUgKQ.js} +1 -1
  5. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-mgIxQnzX.js → architectureDiagram-2XIMDMQ5-C8LeFMgr.js} +1 -1
  6. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-DhlycMw2.js → blockDiagram-WCTKOSBZ-gMh0EPEh.js} +1 -1
  7. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-CuWqqKYM.js → c4Diagram-IC4MRINW-cHwecwLI.js} +1 -1
  8. package/dashboard/dist/assets/channel-C36dnl_e.js +1 -0
  9. package/dashboard/dist/assets/{chunk-4BX2VUAB-CTP72FfB.js → chunk-4BX2VUAB-Bb2anYuQ.js} +1 -1
  10. package/dashboard/dist/assets/{chunk-55IACEB6-CE7fO2_0.js → chunk-55IACEB6-DYIRGzA1.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-FMBD7UC4-DBsJdRy7.js → chunk-FMBD7UC4-sgRWBbaF.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-JSJVCQXG-1dES-fUJ.js → chunk-JSJVCQXG-DlYKMl_j.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-KX2RTZJC-U98s2l2I.js → chunk-KX2RTZJC-D0YDLAOF.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-NQ4KR5QH-DAy7YeTS.js → chunk-NQ4KR5QH-D-Y-CUx6.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-QZHKN3VN-BeQRHiY8.js → chunk-QZHKN3VN-D7FpSvb5.js} +1 -1
  16. package/dashboard/dist/assets/{chunk-WL4C6EOR-Bt94wrMs.js → chunk-WL4C6EOR-CtXgQLdS.js} +1 -1
  17. package/dashboard/dist/assets/classDiagram-VBA2DB6C-BsoGa6_a.js +1 -0
  18. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BsoGa6_a.js +1 -0
  19. package/dashboard/dist/assets/clone-Bz6jW3OY.js +1 -0
  20. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-CdQh3kdW.js → cose-bilkent-S5V4N54A-YbTaohoJ.js} +1 -1
  21. package/dashboard/dist/assets/{dagre-KLK3FWXG-CKWb9fD7.js → dagre-KLK3FWXG-CMtwGAnP.js} +1 -1
  22. package/dashboard/dist/assets/{diagram-E7M64L7V-Dlkqi8ga.js → diagram-E7M64L7V-D8wBMBAX.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-IFDJBPK2-HhRKBN6J.js → diagram-IFDJBPK2-DfudLpiJ.js} +1 -1
  24. package/dashboard/dist/assets/{diagram-P4PSJMXO-B70t50AJ.js → diagram-P4PSJMXO-CyMy61wE.js} +1 -1
  25. package/dashboard/dist/assets/{erDiagram-INFDFZHY-Cc6Lz8R-.js → erDiagram-INFDFZHY-BlB4ZQl9.js} +1 -1
  26. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-UfEconjz.js → flowDiagram-PKNHOUZH-DbhDQJM3.js} +1 -1
  27. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-B13deOQz.js → ganttDiagram-A5KZAMGK-DJFqteNi.js} +1 -1
  28. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-CHRxKecy.js → gitGraphDiagram-K3NZZRJ6-D8etA_mm.js} +1 -1
  29. package/dashboard/dist/assets/{graph-BO4rYEQo.js → graph-Ce86jeZn.js} +1 -1
  30. package/dashboard/dist/assets/index-DRng26Jg.js +567 -0
  31. package/dashboard/dist/assets/index-DzHQIE2n.css +1 -0
  32. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-DYhPRnW_.js → infoDiagram-LFFYTUFH-Cx35U-h8.js} +1 -1
  33. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-uCkY17Z8.js → ishikawaDiagram-PHBUUO56-C04Y2nj8.js} +1 -1
  34. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-DT3-91Dx.js → journeyDiagram-4ABVD52K-D8-cxbxE.js} +1 -1
  35. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-CbNSU1jT.js → kanban-definition-K7BYSVSG-DVKqMylP.js} +1 -1
  36. package/dashboard/dist/assets/{layout-wdZYENqD.js → layout-98xZDpgu.js} +1 -1
  37. package/dashboard/dist/assets/{linear-DP2LUzjc.js → linear-0jk_IwAc.js} +1 -1
  38. package/dashboard/dist/assets/{mermaid.core-glRfe02B.js → mermaid.core-C337VWfr.js} +4 -4
  39. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-Bq2Qe7iv.js → mindmap-definition-YRQLILUH-8sNYGYEP.js} +1 -1
  40. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-BnG8dbQb.js → pieDiagram-SKSYHLDU-afcmzHxf.js} +1 -1
  41. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-CBvIkuCW.js → quadrantDiagram-337W2JSQ-B4RjcpOq.js} +1 -1
  42. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-CsHJZ9D_.js → requirementDiagram-Z7DCOOCP-CRavU6cI.js} +1 -1
  43. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-DioS3JH6.js → sankeyDiagram-WA2Y5GQK-DFomU3z-.js} +1 -1
  44. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-_noTQrZH.js → sequenceDiagram-2WXFIKYE-CGKO7nmK.js} +1 -1
  45. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-K3R1Eh9N.js → stateDiagram-RAJIS63D-BjFI1K8h.js} +1 -1
  46. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-BtxefYKD.js +1 -0
  47. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-Bb3u4Ahz.js → timeline-definition-YZTLITO2-BBo8XJFG.js} +1 -1
  48. package/dashboard/dist/assets/{treemap-KZPCXAKY-BLiQz7AY.js → treemap-KZPCXAKY-COd6i6TE.js} +1 -1
  49. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-BLsoQIAw.js → vennDiagram-LZ73GAT5-CGQweQ36.js} +1 -1
  50. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-Dm1juAkc.js → xychartDiagram-JWTSCODW-mfJ5So7N.js} +1 -1
  51. package/dashboard/dist/index.html +2 -2
  52. package/dist/dashboard/server.js +237 -94
  53. package/dist/dashboard/server.js.map +1 -1
  54. package/dist/index.js +258 -107
  55. package/dist/index.js.map +1 -1
  56. package/dist/launch/index.d.ts +2 -1
  57. package/dist/launch/index.js +159 -95
  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-BLQNOcNZ.js +0 -1
  65. package/dashboard/dist/assets/classDiagram-VBA2DB6C-Mx6la8yG.js +0 -1
  66. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-Mx6la8yG.js +0 -1
  67. package/dashboard/dist/assets/clone-58HOBY7h.js +0 -1
  68. package/dashboard/dist/assets/index-BKdHsXLj.js +0 -566
  69. package/dashboard/dist/assets/index-D1f1wB-7.css +0 -1
  70. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-BJes_eiS.js +0 -1
@@ -2374,7 +2374,11 @@ var init_fields = __esm({
2374
2374
  tags: { kind: "list" },
2375
2375
  archived: { kind: "bool" },
2376
2376
  title: { kind: "substring" },
2377
- search: { kind: "substring", get: (i) => i["title"] },
2377
+ // `search` reads a dedicated `searchText` haystack when the item provides one
2378
+ // (so the dashboard can match title + slug + project like its filter box),
2379
+ // falling back to `title` when absent. Backward-compatible: title-only when no
2380
+ // searchText. The `title` field stays title-only.
2381
+ search: { kind: "substring", get: (i) => i["searchText"] ?? i["title"] },
2378
2382
  created: { kind: "timestamp" },
2379
2383
  updated: { kind: "timestamp" },
2380
2384
  completedat: { kind: "timestamp", get: (i) => i["completedAt"] },
@@ -2997,6 +3001,20 @@ var init_parser3 = __esm({
2997
3001
  });
2998
3002
 
2999
3003
  // src/utils/query/index.ts
3004
+ function compileQuery(input, registry = ASSIGNMENT_FIELDS) {
3005
+ const parsed = parseQuery(input);
3006
+ if (!parsed.ast) return { query: null, errors: parsed.errors };
3007
+ try {
3008
+ const predicate = compileNode(parsed.ast, registry);
3009
+ return { query: { predicate, ast: parsed.ast }, errors: [] };
3010
+ } catch (err) {
3011
+ if (err instanceof CompileError) return { query: null, errors: err.errors };
3012
+ throw err;
3013
+ }
3014
+ }
3015
+ function validateQuery(input, registry = ASSIGNMENT_FIELDS) {
3016
+ return compileQuery(input, registry).errors;
3017
+ }
3000
3018
  var init_query = __esm({
3001
3019
  "src/utils/query/index.ts"() {
3002
3020
  "use strict";
@@ -3009,17 +3027,7 @@ var init_query = __esm({
3009
3027
  }
3010
3028
  });
3011
3029
 
3012
- // src/lifecycle/derive.ts
3013
- var derive_exports = {};
3014
- __export(derive_exports, {
3015
- DERIVE_FIELDS: () => DERIVE_FIELDS,
3016
- acceptFactDeclarations: () => acceptFactDeclarations,
3017
- buildDeriveRegistry: () => buildDeriveRegistry,
3018
- buildQueryRegistry: () => buildQueryRegistry,
3019
- deriveDimensions: () => deriveDimensions,
3020
- factFieldNames: () => factFieldNames,
3021
- validateDeriveCondition: () => validateDeriveCondition
3022
- });
3030
+ // src/utils/fact-registry.ts
3023
3031
  function factFieldNames(decl) {
3024
3032
  const name = decl.name;
3025
3033
  const exportNames = {
@@ -3086,85 +3094,63 @@ function buildQueryRegistry(accepted) {
3086
3094
  for (const decl of accepted) addFactFields(registry, decl);
3087
3095
  return registry;
3088
3096
  }
3089
- function validateDeriveCondition(when, registry = DERIVE_FIELDS) {
3090
- if (when === "*") return null;
3091
- const parsed = parseQuery(when);
3092
- if (!parsed.ast) return parsed.errors[0]?.message ?? "unparseable condition";
3093
- try {
3094
- compileNode(parsed.ast, registry);
3095
- return null;
3096
- } catch (err) {
3097
- if (err instanceof CompileError) return err.errors[0]?.message ?? "invalid condition";
3098
- throw err;
3099
- }
3100
- }
3101
- function compiledWhen(registry, when) {
3102
- let cache2 = conditionCache.get(registry);
3103
- if (!cache2) {
3104
- cache2 = /* @__PURE__ */ new Map();
3105
- conditionCache.set(registry, cache2);
3106
- }
3107
- let pred = cache2.get(when);
3108
- if (!pred) {
3109
- if (when === "*") {
3110
- pred = () => true;
3097
+ function queryFieldNames(declarations) {
3098
+ const builtins = [
3099
+ "status",
3100
+ "priority",
3101
+ "type",
3102
+ "assignee",
3103
+ "project",
3104
+ "tag",
3105
+ "tags",
3106
+ "archived",
3107
+ "title",
3108
+ "search",
3109
+ "created",
3110
+ "updated",
3111
+ "completedAt",
3112
+ "statusAge",
3113
+ "phase",
3114
+ "disposition",
3115
+ "phaseAge",
3116
+ "hasRealObjective",
3117
+ "acRealTotal",
3118
+ "acRealChecked",
3119
+ "acAllChecked",
3120
+ "planExists",
3121
+ "planApproved",
3122
+ "workspaceSet",
3123
+ "implementationStarted",
3124
+ "depsSatisfied",
3125
+ "unresolvedQuestions",
3126
+ "progressStaleDays",
3127
+ "blocked",
3128
+ "parked",
3129
+ "reviewRequested",
3130
+ "pinned"
3131
+ ];
3132
+ const custom = [];
3133
+ for (const decl of declarations) {
3134
+ const names = factFieldNames(decl);
3135
+ if (decl.type === "attestation") {
3136
+ custom.push(
3137
+ names.exports.fact,
3138
+ names.exports.approved,
3139
+ names.exports.changesRequested,
3140
+ names.exports.by,
3141
+ names.exports.approvedBy
3142
+ );
3111
3143
  } else {
3112
- const parsed = parseQuery(when);
3113
- if (!parsed.ast) {
3114
- throw new CompileError(parsed.errors);
3115
- }
3116
- pred = compileNode(parsed.ast, registry);
3144
+ custom.push(names.exports.fact);
3117
3145
  }
3118
- cache2.set(when, pred);
3119
3146
  }
3120
- return pred;
3147
+ return [...builtins, ...custom];
3121
3148
  }
3122
- function deriveDimensions(input) {
3123
- const { facts, derive, currentStatus, terminalStatuses, knownStatusIds, override } = input;
3124
- const registry = input.registry ?? DERIVE_FIELDS;
3125
- if (terminalStatuses.has(currentStatus)) return null;
3126
- const ctx = { now: 0 };
3127
- const item = facts;
3128
- let phase = derive.phaseLadder[0]?.phase ?? currentStatus;
3129
- let nextAction = derive.phaseLadder[0]?.next ?? null;
3130
- for (let i = derive.phaseLadder.length - 1; i >= 0; i--) {
3131
- const rung = derive.phaseLadder[i];
3132
- if (compiledWhen(registry, rung.when)(item, ctx)) {
3133
- phase = rung.phase;
3134
- nextAction = rung.next ?? null;
3135
- break;
3136
- }
3137
- }
3138
- let disposition = "active";
3139
- for (const rule of derive.disposition) {
3140
- if (rule.when === null || compiledWhen(registry, rule.when)(item, ctx)) {
3141
- disposition = rule.is;
3142
- break;
3143
- }
3144
- }
3145
- let derivedStatus;
3146
- switch (disposition) {
3147
- case "parked":
3148
- derivedStatus = knownStatusIds.has(derive.headline.parked) ? derive.headline.parked : phase;
3149
- break;
3150
- case "blocked":
3151
- derivedStatus = knownStatusIds.has(derive.headline.blocked) ? derive.headline.blocked : phase;
3152
- break;
3153
- default:
3154
- derivedStatus = phase;
3155
- }
3156
- let status = derivedStatus;
3157
- if (override && override.status && !terminalStatuses.has(override.status) && knownStatusIds.has(override.status)) {
3158
- status = override.status;
3159
- }
3160
- return { phase, disposition, derivedStatus, status, nextAction };
3161
- }
3162
- var DERIVE_FIELDS, conditionCache;
3163
- var init_derive = __esm({
3164
- "src/lifecycle/derive.ts"() {
3149
+ var DERIVE_FIELDS;
3150
+ var init_fact_registry = __esm({
3151
+ "src/utils/fact-registry.ts"() {
3165
3152
  "use strict";
3166
3153
  init_query();
3167
- init_query();
3168
3154
  DERIVE_FIELDS = {
3169
3155
  hasrealobjective: { kind: "bool", get: (i) => i["hasRealObjective"] },
3170
3156
  acrealtotal: { kind: "number", get: (i) => i["acRealTotal"] },
@@ -3181,7 +3167,6 @@ var init_derive = __esm({
3181
3167
  reviewrequested: { kind: "bool", get: (i) => i["reviewRequested"] },
3182
3168
  pinned: { kind: "bool" }
3183
3169
  };
3184
- conditionCache = /* @__PURE__ */ new WeakMap();
3185
3170
  }
3186
3171
  });
3187
3172
 
@@ -4841,7 +4826,7 @@ var init_config2 = __esm({
4841
4826
  init_hotkeysCatalog();
4842
4827
  init_agents_schema();
4843
4828
  init_slug();
4844
- init_derive();
4829
+ init_fact_registry();
4845
4830
  init_query();
4846
4831
  init_terminal_schema();
4847
4832
  init_workspace_visibility_schema();
@@ -4942,6 +4927,103 @@ var init_config2 = __esm({
4942
4927
  }
4943
4928
  });
4944
4929
 
4930
+ // src/lifecycle/derive.ts
4931
+ var derive_exports = {};
4932
+ __export(derive_exports, {
4933
+ DERIVE_FIELDS: () => DERIVE_FIELDS,
4934
+ acceptFactDeclarations: () => acceptFactDeclarations,
4935
+ addFactFields: () => addFactFields,
4936
+ buildDeriveRegistry: () => buildDeriveRegistry,
4937
+ buildQueryRegistry: () => buildQueryRegistry,
4938
+ deriveDimensions: () => deriveDimensions,
4939
+ factFieldNames: () => factFieldNames,
4940
+ queryFieldNames: () => queryFieldNames,
4941
+ validateDeriveCondition: () => validateDeriveCondition
4942
+ });
4943
+ function validateDeriveCondition(when, registry = DERIVE_FIELDS) {
4944
+ if (when === "*") return null;
4945
+ const parsed = parseQuery(when);
4946
+ if (!parsed.ast) return parsed.errors[0]?.message ?? "unparseable condition";
4947
+ try {
4948
+ compileNode(parsed.ast, registry);
4949
+ return null;
4950
+ } catch (err) {
4951
+ if (err instanceof CompileError) return err.errors[0]?.message ?? "invalid condition";
4952
+ throw err;
4953
+ }
4954
+ }
4955
+ function compiledWhen(registry, when) {
4956
+ let cache2 = conditionCache.get(registry);
4957
+ if (!cache2) {
4958
+ cache2 = /* @__PURE__ */ new Map();
4959
+ conditionCache.set(registry, cache2);
4960
+ }
4961
+ let pred = cache2.get(when);
4962
+ if (!pred) {
4963
+ if (when === "*") {
4964
+ pred = () => true;
4965
+ } else {
4966
+ const parsed = parseQuery(when);
4967
+ if (!parsed.ast) {
4968
+ throw new CompileError(parsed.errors);
4969
+ }
4970
+ pred = compileNode(parsed.ast, registry);
4971
+ }
4972
+ cache2.set(when, pred);
4973
+ }
4974
+ return pred;
4975
+ }
4976
+ function deriveDimensions(input) {
4977
+ const { facts, derive, currentStatus, terminalStatuses, knownStatusIds, override } = input;
4978
+ const registry = input.registry ?? DERIVE_FIELDS;
4979
+ if (terminalStatuses.has(currentStatus)) return null;
4980
+ const ctx = { now: 0 };
4981
+ const item = facts;
4982
+ let phase = derive.phaseLadder[0]?.phase ?? currentStatus;
4983
+ let nextAction = derive.phaseLadder[0]?.next ?? null;
4984
+ for (let i = derive.phaseLadder.length - 1; i >= 0; i--) {
4985
+ const rung = derive.phaseLadder[i];
4986
+ if (compiledWhen(registry, rung.when)(item, ctx)) {
4987
+ phase = rung.phase;
4988
+ nextAction = rung.next ?? null;
4989
+ break;
4990
+ }
4991
+ }
4992
+ let disposition = "active";
4993
+ for (const rule of derive.disposition) {
4994
+ if (rule.when === null || compiledWhen(registry, rule.when)(item, ctx)) {
4995
+ disposition = rule.is;
4996
+ break;
4997
+ }
4998
+ }
4999
+ let derivedStatus;
5000
+ switch (disposition) {
5001
+ case "parked":
5002
+ derivedStatus = knownStatusIds.has(derive.headline.parked) ? derive.headline.parked : phase;
5003
+ break;
5004
+ case "blocked":
5005
+ derivedStatus = knownStatusIds.has(derive.headline.blocked) ? derive.headline.blocked : phase;
5006
+ break;
5007
+ default:
5008
+ derivedStatus = phase;
5009
+ }
5010
+ let status = derivedStatus;
5011
+ if (override && override.status && !terminalStatuses.has(override.status) && knownStatusIds.has(override.status)) {
5012
+ status = override.status;
5013
+ }
5014
+ return { phase, disposition, derivedStatus, status, nextAction };
5015
+ }
5016
+ var conditionCache;
5017
+ var init_derive = __esm({
5018
+ "src/lifecycle/derive.ts"() {
5019
+ "use strict";
5020
+ init_query();
5021
+ init_fact_registry();
5022
+ init_fact_registry();
5023
+ conditionCache = /* @__PURE__ */ new WeakMap();
5024
+ }
5025
+ });
5026
+
4945
5027
  // src/utils/playbooks.ts
4946
5028
  import { resolve as resolve7 } from "path";
4947
5029
  import { readdir as readdir3, readFile as readFile6, unlink } from "fs/promises";
@@ -7359,7 +7441,8 @@ async function getStatusConfig() {
7359
7441
  derive: config.statuses.derive ?? null,
7360
7442
  facts: config.statuses.facts ?? null,
7361
7443
  factDeclarations: accepted,
7362
- deriveRegistry: buildDeriveRegistry(accepted)
7444
+ deriveRegistry: buildDeriveRegistry(accepted),
7445
+ queryRegistry: buildQueryRegistry(accepted)
7363
7446
  };
7364
7447
  } else {
7365
7448
  const def = buildDefaultStatusConfig();
@@ -7373,7 +7456,8 @@ async function getStatusConfig() {
7373
7456
  derive: null,
7374
7457
  facts: null,
7375
7458
  factDeclarations: [],
7376
- deriveRegistry: buildDeriveRegistry([])
7459
+ deriveRegistry: buildDeriveRegistry([]),
7460
+ queryRegistry: buildQueryRegistry([])
7377
7461
  };
7378
7462
  }
7379
7463
  return _cachedConfig;
@@ -7682,14 +7766,30 @@ async function listArchived(projectsDir, assignmentsDir2) {
7682
7766
  return { projects, assignments: individuallyArchived };
7683
7767
  }
7684
7768
  async function toStandaloneBoardItem(sr) {
7685
- const { terminalStatuses } = await getStatusConfig();
7769
+ const config = await getStatusConfig();
7770
+ const { terminalStatuses } = config;
7771
+ let facts;
7772
+ try {
7773
+ const { computeFacts: computeFacts2 } = await Promise.resolve().then(() => (init_facts(), facts_exports));
7774
+ facts = await computeFacts2({
7775
+ assignmentDir: sr.assignmentDir,
7776
+ frontmatter: sr.record,
7777
+ body: sr.record.body,
7778
+ projectDir: null,
7779
+ terminalStatuses,
7780
+ declarations: config.factDeclarations
7781
+ });
7782
+ } catch (err) {
7783
+ console.warn(`toStandaloneBoardItem: computeFacts failed for ${sr.assignmentDir}:`, err);
7784
+ }
7686
7785
  return {
7687
7786
  ...toAssignmentSummary(sr.record, terminalStatuses),
7688
7787
  projectSlug: null,
7689
7788
  projectTitle: null,
7690
7789
  blockedReason: sr.record.blockedReason,
7691
7790
  projectWorkspace: sr.record.workspaceGroup ?? null,
7692
- availableTransitions: await getStandaloneAvailableTransitions(sr.record)
7791
+ availableTransitions: await getStandaloneAvailableTransitions(sr.record),
7792
+ facts
7693
7793
  };
7694
7794
  }
7695
7795
  async function getStandaloneAvailableTransitions(assignment) {
@@ -8576,7 +8676,24 @@ function toAssignmentSummary(assignment, terminalStatuses) {
8576
8676
  };
8577
8677
  }
8578
8678
  async function toAssignmentBoardItem(projectsDir, projectRecord, assignment) {
8579
- const { terminalStatuses } = await getStatusConfig();
8679
+ const config = await getStatusConfig();
8680
+ const { terminalStatuses } = config;
8681
+ const assignmentDir = resolve14(projectRecord.projectPath, "assignments", assignment.slug);
8682
+ const projectDir = projectRecord.projectPath;
8683
+ let facts;
8684
+ try {
8685
+ const { computeFacts: computeFacts2 } = await Promise.resolve().then(() => (init_facts(), facts_exports));
8686
+ facts = await computeFacts2({
8687
+ assignmentDir,
8688
+ frontmatter: assignment,
8689
+ body: assignment.body,
8690
+ projectDir,
8691
+ terminalStatuses,
8692
+ declarations: config.factDeclarations
8693
+ });
8694
+ } catch (err) {
8695
+ console.warn(`toAssignmentBoardItem: computeFacts failed for ${assignmentDir}:`, err);
8696
+ }
8580
8697
  return {
8581
8698
  ...toAssignmentSummary(assignment, terminalStatuses),
8582
8699
  projectSlug: projectRecord.summary.slug,
@@ -8588,7 +8705,8 @@ async function toAssignmentBoardItem(projectsDir, projectRecord, assignment) {
8588
8705
  projectRecord.summary.slug,
8589
8706
  assignment.slug,
8590
8707
  assignment
8591
- )
8708
+ ),
8709
+ facts
8592
8710
  };
8593
8711
  }
8594
8712
  function buildDependencyGraph(assignments) {
@@ -10115,6 +10233,9 @@ function isViewPrefsDefaults(file) {
10115
10233
  // src/dashboard/api-saved-views.ts
10116
10234
  import { Router } from "express";
10117
10235
 
10236
+ // src/utils/view-filters-query.ts
10237
+ init_query();
10238
+
10118
10239
  // src/utils/saved-views-schema.ts
10119
10240
  var TABLE_COLUMN_IDS = [
10120
10241
  "title",
@@ -10208,6 +10329,7 @@ function isViewFilters(value) {
10208
10329
  if (obj.activity !== void 0 && !isActivity(obj.activity)) return false;
10209
10330
  if (obj.dateRange !== void 0 && !isDateRange(obj.dateRange)) return false;
10210
10331
  if (obj.search !== void 0 && typeof obj.search !== "string") return false;
10332
+ if (obj.query !== void 0 && typeof obj.query !== "string") return false;
10211
10333
  return true;
10212
10334
  }
10213
10335
  function isSavedViewConfig(value) {
@@ -10393,6 +10515,8 @@ function withTwoLocks(keyA, keyB, fn) {
10393
10515
  }
10394
10516
 
10395
10517
  // src/dashboard/api-saved-views.ts
10518
+ init_api();
10519
+ init_query();
10396
10520
  var SAVED_VIEWS_LOCK = "sv:global";
10397
10521
  function validateCreateBody(body) {
10398
10522
  if (!body || typeof body !== "object" || Array.isArray(body)) {
@@ -10479,6 +10603,15 @@ function createSavedViewsRouter() {
10479
10603
  res.status(400).json({ error: result.error });
10480
10604
  return;
10481
10605
  }
10606
+ const queryStr = result.value.config.filters.query;
10607
+ if (typeof queryStr === "string" && queryStr.length > 0) {
10608
+ const statusConfig = await getStatusConfig();
10609
+ const queryErrors = validateQuery(queryStr, statusConfig.queryRegistry);
10610
+ if (queryErrors.length > 0) {
10611
+ res.status(400).json({ errors: queryErrors });
10612
+ return;
10613
+ }
10614
+ }
10482
10615
  try {
10483
10616
  const file = await withLock(SAVED_VIEWS_LOCK, async () => {
10484
10617
  const current = await readSavedViewsFile();
@@ -10503,6 +10636,15 @@ function createSavedViewsRouter() {
10503
10636
  res.status(400).json({ error: result.error });
10504
10637
  return;
10505
10638
  }
10639
+ const patchQueryStr = result.value.config?.filters.query;
10640
+ if (typeof patchQueryStr === "string" && patchQueryStr.length > 0) {
10641
+ const statusConfig = await getStatusConfig();
10642
+ const queryErrors = validateQuery(patchQueryStr, statusConfig.queryRegistry);
10643
+ if (queryErrors.length > 0) {
10644
+ res.status(400).json({ errors: queryErrors });
10645
+ return;
10646
+ }
10647
+ }
10506
10648
  try {
10507
10649
  const outcome = await withLock(SAVED_VIEWS_LOCK, async () => {
10508
10650
  const current = await readSavedViewsFile();
@@ -15771,7 +15913,8 @@ function createStatusConfigRouter(projectsDir, assignmentsDir2) {
15771
15913
  statuses: config.statuses,
15772
15914
  order: config.order,
15773
15915
  transitions: config.transitions,
15774
- custom: config.custom
15916
+ custom: config.custom,
15917
+ factDeclarations: config.factDeclarations
15775
15918
  });
15776
15919
  } catch (error) {
15777
15920
  console.error("Error getting status config:", error);