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
package/dist/index.js CHANGED
@@ -2435,7 +2435,11 @@ var init_fields = __esm({
2435
2435
  tags: { kind: "list" },
2436
2436
  archived: { kind: "bool" },
2437
2437
  title: { kind: "substring" },
2438
- search: { kind: "substring", get: (i) => i["title"] },
2438
+ // `search` reads a dedicated `searchText` haystack when the item provides one
2439
+ // (so the dashboard can match title + slug + project like its filter box),
2440
+ // falling back to `title` when absent. Backward-compatible: title-only when no
2441
+ // searchText. The `title` field stays title-only.
2442
+ search: { kind: "substring", get: (i) => i["searchText"] ?? i["title"] },
2439
2443
  created: { kind: "timestamp" },
2440
2444
  updated: { kind: "timestamp" },
2441
2445
  completedat: { kind: "timestamp", get: (i) => i["completedAt"] },
@@ -3069,6 +3073,9 @@ function compileQuery(input4, registry = ASSIGNMENT_FIELDS) {
3069
3073
  throw err2;
3070
3074
  }
3071
3075
  }
3076
+ function validateQuery(input4, registry = ASSIGNMENT_FIELDS) {
3077
+ return compileQuery(input4, registry).errors;
3078
+ }
3072
3079
  var init_query = __esm({
3073
3080
  "src/utils/query/index.ts"() {
3074
3081
  "use strict";
@@ -3081,17 +3088,7 @@ var init_query = __esm({
3081
3088
  }
3082
3089
  });
3083
3090
 
3084
- // src/lifecycle/derive.ts
3085
- var derive_exports = {};
3086
- __export(derive_exports, {
3087
- DERIVE_FIELDS: () => DERIVE_FIELDS,
3088
- acceptFactDeclarations: () => acceptFactDeclarations,
3089
- buildDeriveRegistry: () => buildDeriveRegistry,
3090
- buildQueryRegistry: () => buildQueryRegistry,
3091
- deriveDimensions: () => deriveDimensions,
3092
- factFieldNames: () => factFieldNames,
3093
- validateDeriveCondition: () => validateDeriveCondition
3094
- });
3091
+ // src/utils/fact-registry.ts
3095
3092
  function factFieldNames(decl) {
3096
3093
  const name = decl.name;
3097
3094
  const exportNames = {
@@ -3158,85 +3155,63 @@ function buildQueryRegistry(accepted) {
3158
3155
  for (const decl of accepted) addFactFields(registry, decl);
3159
3156
  return registry;
3160
3157
  }
3161
- function validateDeriveCondition(when, registry = DERIVE_FIELDS) {
3162
- if (when === "*") return null;
3163
- const parsed = parseQuery(when);
3164
- if (!parsed.ast) return parsed.errors[0]?.message ?? "unparseable condition";
3165
- try {
3166
- compileNode(parsed.ast, registry);
3167
- return null;
3168
- } catch (err2) {
3169
- if (err2 instanceof CompileError) return err2.errors[0]?.message ?? "invalid condition";
3170
- throw err2;
3171
- }
3172
- }
3173
- function compiledWhen(registry, when) {
3174
- let cache2 = conditionCache.get(registry);
3175
- if (!cache2) {
3176
- cache2 = /* @__PURE__ */ new Map();
3177
- conditionCache.set(registry, cache2);
3178
- }
3179
- let pred = cache2.get(when);
3180
- if (!pred) {
3181
- if (when === "*") {
3182
- pred = () => true;
3158
+ function queryFieldNames(declarations) {
3159
+ const builtins = [
3160
+ "status",
3161
+ "priority",
3162
+ "type",
3163
+ "assignee",
3164
+ "project",
3165
+ "tag",
3166
+ "tags",
3167
+ "archived",
3168
+ "title",
3169
+ "search",
3170
+ "created",
3171
+ "updated",
3172
+ "completedAt",
3173
+ "statusAge",
3174
+ "phase",
3175
+ "disposition",
3176
+ "phaseAge",
3177
+ "hasRealObjective",
3178
+ "acRealTotal",
3179
+ "acRealChecked",
3180
+ "acAllChecked",
3181
+ "planExists",
3182
+ "planApproved",
3183
+ "workspaceSet",
3184
+ "implementationStarted",
3185
+ "depsSatisfied",
3186
+ "unresolvedQuestions",
3187
+ "progressStaleDays",
3188
+ "blocked",
3189
+ "parked",
3190
+ "reviewRequested",
3191
+ "pinned"
3192
+ ];
3193
+ const custom = [];
3194
+ for (const decl of declarations) {
3195
+ const names = factFieldNames(decl);
3196
+ if (decl.type === "attestation") {
3197
+ custom.push(
3198
+ names.exports.fact,
3199
+ names.exports.approved,
3200
+ names.exports.changesRequested,
3201
+ names.exports.by,
3202
+ names.exports.approvedBy
3203
+ );
3183
3204
  } else {
3184
- const parsed = parseQuery(when);
3185
- if (!parsed.ast) {
3186
- throw new CompileError(parsed.errors);
3187
- }
3188
- pred = compileNode(parsed.ast, registry);
3205
+ custom.push(names.exports.fact);
3189
3206
  }
3190
- cache2.set(when, pred);
3191
3207
  }
3192
- return pred;
3208
+ return [...builtins, ...custom];
3193
3209
  }
3194
- function deriveDimensions(input4) {
3195
- const { facts, derive, currentStatus, terminalStatuses: terminalStatuses3, knownStatusIds, override } = input4;
3196
- const registry = input4.registry ?? DERIVE_FIELDS;
3197
- if (terminalStatuses3.has(currentStatus)) return null;
3198
- const ctx = { now: 0 };
3199
- const item = facts;
3200
- let phase = derive.phaseLadder[0]?.phase ?? currentStatus;
3201
- let nextAction = derive.phaseLadder[0]?.next ?? null;
3202
- for (let i = derive.phaseLadder.length - 1; i >= 0; i--) {
3203
- const rung = derive.phaseLadder[i];
3204
- if (compiledWhen(registry, rung.when)(item, ctx)) {
3205
- phase = rung.phase;
3206
- nextAction = rung.next ?? null;
3207
- break;
3208
- }
3209
- }
3210
- let disposition = "active";
3211
- for (const rule of derive.disposition) {
3212
- if (rule.when === null || compiledWhen(registry, rule.when)(item, ctx)) {
3213
- disposition = rule.is;
3214
- break;
3215
- }
3216
- }
3217
- let derivedStatus;
3218
- switch (disposition) {
3219
- case "parked":
3220
- derivedStatus = knownStatusIds.has(derive.headline.parked) ? derive.headline.parked : phase;
3221
- break;
3222
- case "blocked":
3223
- derivedStatus = knownStatusIds.has(derive.headline.blocked) ? derive.headline.blocked : phase;
3224
- break;
3225
- default:
3226
- derivedStatus = phase;
3227
- }
3228
- let status = derivedStatus;
3229
- if (override && override.status && !terminalStatuses3.has(override.status) && knownStatusIds.has(override.status)) {
3230
- status = override.status;
3231
- }
3232
- return { phase, disposition, derivedStatus, status, nextAction };
3233
- }
3234
- var DERIVE_FIELDS, conditionCache;
3235
- var init_derive = __esm({
3236
- "src/lifecycle/derive.ts"() {
3210
+ var DERIVE_FIELDS;
3211
+ var init_fact_registry = __esm({
3212
+ "src/utils/fact-registry.ts"() {
3237
3213
  "use strict";
3238
3214
  init_query();
3239
- init_query();
3240
3215
  DERIVE_FIELDS = {
3241
3216
  hasrealobjective: { kind: "bool", get: (i) => i["hasRealObjective"] },
3242
3217
  acrealtotal: { kind: "number", get: (i) => i["acRealTotal"] },
@@ -3253,7 +3228,6 @@ var init_derive = __esm({
3253
3228
  reviewrequested: { kind: "bool", get: (i) => i["reviewRequested"] },
3254
3229
  pinned: { kind: "bool" }
3255
3230
  };
3256
- conditionCache = /* @__PURE__ */ new WeakMap();
3257
3231
  }
3258
3232
  });
3259
3233
 
@@ -4913,7 +4887,7 @@ var init_config2 = __esm({
4913
4887
  init_hotkeysCatalog();
4914
4888
  init_agents_schema();
4915
4889
  init_slug();
4916
- init_derive();
4890
+ init_fact_registry();
4917
4891
  init_query();
4918
4892
  init_terminal_schema();
4919
4893
  init_workspace_visibility_schema();
@@ -6383,6 +6357,103 @@ var init_create_assignment = __esm({
6383
6357
  }
6384
6358
  });
6385
6359
 
6360
+ // src/lifecycle/derive.ts
6361
+ var derive_exports = {};
6362
+ __export(derive_exports, {
6363
+ DERIVE_FIELDS: () => DERIVE_FIELDS,
6364
+ acceptFactDeclarations: () => acceptFactDeclarations,
6365
+ addFactFields: () => addFactFields,
6366
+ buildDeriveRegistry: () => buildDeriveRegistry,
6367
+ buildQueryRegistry: () => buildQueryRegistry,
6368
+ deriveDimensions: () => deriveDimensions,
6369
+ factFieldNames: () => factFieldNames,
6370
+ queryFieldNames: () => queryFieldNames,
6371
+ validateDeriveCondition: () => validateDeriveCondition
6372
+ });
6373
+ function validateDeriveCondition(when, registry = DERIVE_FIELDS) {
6374
+ if (when === "*") return null;
6375
+ const parsed = parseQuery(when);
6376
+ if (!parsed.ast) return parsed.errors[0]?.message ?? "unparseable condition";
6377
+ try {
6378
+ compileNode(parsed.ast, registry);
6379
+ return null;
6380
+ } catch (err2) {
6381
+ if (err2 instanceof CompileError) return err2.errors[0]?.message ?? "invalid condition";
6382
+ throw err2;
6383
+ }
6384
+ }
6385
+ function compiledWhen(registry, when) {
6386
+ let cache2 = conditionCache.get(registry);
6387
+ if (!cache2) {
6388
+ cache2 = /* @__PURE__ */ new Map();
6389
+ conditionCache.set(registry, cache2);
6390
+ }
6391
+ let pred = cache2.get(when);
6392
+ if (!pred) {
6393
+ if (when === "*") {
6394
+ pred = () => true;
6395
+ } else {
6396
+ const parsed = parseQuery(when);
6397
+ if (!parsed.ast) {
6398
+ throw new CompileError(parsed.errors);
6399
+ }
6400
+ pred = compileNode(parsed.ast, registry);
6401
+ }
6402
+ cache2.set(when, pred);
6403
+ }
6404
+ return pred;
6405
+ }
6406
+ function deriveDimensions(input4) {
6407
+ const { facts, derive, currentStatus, terminalStatuses: terminalStatuses3, knownStatusIds, override } = input4;
6408
+ const registry = input4.registry ?? DERIVE_FIELDS;
6409
+ if (terminalStatuses3.has(currentStatus)) return null;
6410
+ const ctx = { now: 0 };
6411
+ const item = facts;
6412
+ let phase = derive.phaseLadder[0]?.phase ?? currentStatus;
6413
+ let nextAction = derive.phaseLadder[0]?.next ?? null;
6414
+ for (let i = derive.phaseLadder.length - 1; i >= 0; i--) {
6415
+ const rung = derive.phaseLadder[i];
6416
+ if (compiledWhen(registry, rung.when)(item, ctx)) {
6417
+ phase = rung.phase;
6418
+ nextAction = rung.next ?? null;
6419
+ break;
6420
+ }
6421
+ }
6422
+ let disposition = "active";
6423
+ for (const rule of derive.disposition) {
6424
+ if (rule.when === null || compiledWhen(registry, rule.when)(item, ctx)) {
6425
+ disposition = rule.is;
6426
+ break;
6427
+ }
6428
+ }
6429
+ let derivedStatus;
6430
+ switch (disposition) {
6431
+ case "parked":
6432
+ derivedStatus = knownStatusIds.has(derive.headline.parked) ? derive.headline.parked : phase;
6433
+ break;
6434
+ case "blocked":
6435
+ derivedStatus = knownStatusIds.has(derive.headline.blocked) ? derive.headline.blocked : phase;
6436
+ break;
6437
+ default:
6438
+ derivedStatus = phase;
6439
+ }
6440
+ let status = derivedStatus;
6441
+ if (override && override.status && !terminalStatuses3.has(override.status) && knownStatusIds.has(override.status)) {
6442
+ status = override.status;
6443
+ }
6444
+ return { phase, disposition, derivedStatus, status, nextAction };
6445
+ }
6446
+ var conditionCache;
6447
+ var init_derive = __esm({
6448
+ "src/lifecycle/derive.ts"() {
6449
+ "use strict";
6450
+ init_query();
6451
+ init_fact_registry();
6452
+ init_fact_registry();
6453
+ conditionCache = /* @__PURE__ */ new WeakMap();
6454
+ }
6455
+ });
6456
+
6386
6457
  // src/utils/assignment-resolver.ts
6387
6458
  import { resolve as resolve11 } from "path";
6388
6459
  import { readdir as readdir5, readFile as readFile8 } from "fs/promises";
@@ -8666,7 +8737,8 @@ async function getStatusConfig() {
8666
8737
  derive: config.statuses.derive ?? null,
8667
8738
  facts: config.statuses.facts ?? null,
8668
8739
  factDeclarations: accepted,
8669
- deriveRegistry: buildDeriveRegistry(accepted)
8740
+ deriveRegistry: buildDeriveRegistry(accepted),
8741
+ queryRegistry: buildQueryRegistry(accepted)
8670
8742
  };
8671
8743
  } else {
8672
8744
  const def = buildDefaultStatusConfig();
@@ -8680,7 +8752,8 @@ async function getStatusConfig() {
8680
8752
  derive: null,
8681
8753
  facts: null,
8682
8754
  factDeclarations: [],
8683
- deriveRegistry: buildDeriveRegistry([])
8755
+ deriveRegistry: buildDeriveRegistry([]),
8756
+ queryRegistry: buildQueryRegistry([])
8684
8757
  };
8685
8758
  }
8686
8759
  return _cachedConfig;
@@ -8989,14 +9062,30 @@ async function listArchived(projectsDir2, assignmentsDir2) {
8989
9062
  return { projects, assignments: individuallyArchived };
8990
9063
  }
8991
9064
  async function toStandaloneBoardItem(sr) {
8992
- const { terminalStatuses: terminalStatuses3 } = await getStatusConfig();
9065
+ const config = await getStatusConfig();
9066
+ const { terminalStatuses: terminalStatuses3 } = config;
9067
+ let facts;
9068
+ try {
9069
+ const { computeFacts: computeFacts2 } = await Promise.resolve().then(() => (init_facts(), facts_exports));
9070
+ facts = await computeFacts2({
9071
+ assignmentDir: sr.assignmentDir,
9072
+ frontmatter: sr.record,
9073
+ body: sr.record.body,
9074
+ projectDir: null,
9075
+ terminalStatuses: terminalStatuses3,
9076
+ declarations: config.factDeclarations
9077
+ });
9078
+ } catch (err2) {
9079
+ console.warn(`toStandaloneBoardItem: computeFacts failed for ${sr.assignmentDir}:`, err2);
9080
+ }
8993
9081
  return {
8994
9082
  ...toAssignmentSummary(sr.record, terminalStatuses3),
8995
9083
  projectSlug: null,
8996
9084
  projectTitle: null,
8997
9085
  blockedReason: sr.record.blockedReason,
8998
9086
  projectWorkspace: sr.record.workspaceGroup ?? null,
8999
- availableTransitions: await getStandaloneAvailableTransitions(sr.record)
9087
+ availableTransitions: await getStandaloneAvailableTransitions(sr.record),
9088
+ facts
9000
9089
  };
9001
9090
  }
9002
9091
  async function getStandaloneAvailableTransitions(assignment) {
@@ -9883,7 +9972,24 @@ function toAssignmentSummary(assignment, terminalStatuses3) {
9883
9972
  };
9884
9973
  }
9885
9974
  async function toAssignmentBoardItem(projectsDir2, projectRecord, assignment) {
9886
- const { terminalStatuses: terminalStatuses3 } = await getStatusConfig();
9975
+ const config = await getStatusConfig();
9976
+ const { terminalStatuses: terminalStatuses3 } = config;
9977
+ const assignmentDir = resolve17(projectRecord.projectPath, "assignments", assignment.slug);
9978
+ const projectDir = projectRecord.projectPath;
9979
+ let facts;
9980
+ try {
9981
+ const { computeFacts: computeFacts2 } = await Promise.resolve().then(() => (init_facts(), facts_exports));
9982
+ facts = await computeFacts2({
9983
+ assignmentDir,
9984
+ frontmatter: assignment,
9985
+ body: assignment.body,
9986
+ projectDir,
9987
+ terminalStatuses: terminalStatuses3,
9988
+ declarations: config.factDeclarations
9989
+ });
9990
+ } catch (err2) {
9991
+ console.warn(`toAssignmentBoardItem: computeFacts failed for ${assignmentDir}:`, err2);
9992
+ }
9887
9993
  return {
9888
9994
  ...toAssignmentSummary(assignment, terminalStatuses3),
9889
9995
  projectSlug: projectRecord.summary.slug,
@@ -9895,7 +10001,8 @@ async function toAssignmentBoardItem(projectsDir2, projectRecord, assignment) {
9895
10001
  projectRecord.summary.slug,
9896
10002
  assignment.slug,
9897
10003
  assignment
9898
- )
10004
+ ),
10005
+ facts
9899
10006
  };
9900
10007
  }
9901
10008
  function buildDependencyGraph(assignments) {
@@ -12858,6 +12965,9 @@ function isViewPrefsDefaults(file) {
12858
12965
  // src/dashboard/api-saved-views.ts
12859
12966
  import { Router } from "express";
12860
12967
 
12968
+ // src/utils/view-filters-query.ts
12969
+ init_query();
12970
+
12861
12971
  // src/utils/saved-views-schema.ts
12862
12972
  var TABLE_COLUMN_IDS = [
12863
12973
  "title",
@@ -12951,6 +13061,7 @@ function isViewFilters(value) {
12951
13061
  if (obj.activity !== void 0 && !isActivity(obj.activity)) return false;
12952
13062
  if (obj.dateRange !== void 0 && !isDateRange(obj.dateRange)) return false;
12953
13063
  if (obj.search !== void 0 && typeof obj.search !== "string") return false;
13064
+ if (obj.query !== void 0 && typeof obj.query !== "string") return false;
12954
13065
  return true;
12955
13066
  }
12956
13067
  function isSavedViewConfig(value) {
@@ -13136,6 +13247,8 @@ function withTwoLocks(keyA, keyB, fn) {
13136
13247
  }
13137
13248
 
13138
13249
  // src/dashboard/api-saved-views.ts
13250
+ init_api();
13251
+ init_query();
13139
13252
  var SAVED_VIEWS_LOCK = "sv:global";
13140
13253
  function validateCreateBody(body) {
13141
13254
  if (!body || typeof body !== "object" || Array.isArray(body)) {
@@ -13222,6 +13335,15 @@ function createSavedViewsRouter() {
13222
13335
  res.status(400).json({ error: result.error });
13223
13336
  return;
13224
13337
  }
13338
+ const queryStr = result.value.config.filters.query;
13339
+ if (typeof queryStr === "string" && queryStr.length > 0) {
13340
+ const statusConfig = await getStatusConfig();
13341
+ const queryErrors = validateQuery(queryStr, statusConfig.queryRegistry);
13342
+ if (queryErrors.length > 0) {
13343
+ res.status(400).json({ errors: queryErrors });
13344
+ return;
13345
+ }
13346
+ }
13225
13347
  try {
13226
13348
  const file = await withLock(SAVED_VIEWS_LOCK, async () => {
13227
13349
  const current = await readSavedViewsFile();
@@ -13246,6 +13368,15 @@ function createSavedViewsRouter() {
13246
13368
  res.status(400).json({ error: result.error });
13247
13369
  return;
13248
13370
  }
13371
+ const patchQueryStr = result.value.config?.filters.query;
13372
+ if (typeof patchQueryStr === "string" && patchQueryStr.length > 0) {
13373
+ const statusConfig = await getStatusConfig();
13374
+ const queryErrors = validateQuery(patchQueryStr, statusConfig.queryRegistry);
13375
+ if (queryErrors.length > 0) {
13376
+ res.status(400).json({ errors: queryErrors });
13377
+ return;
13378
+ }
13379
+ }
13249
13380
  try {
13250
13381
  const outcome = await withLock(SAVED_VIEWS_LOCK, async () => {
13251
13382
  const current = await readSavedViewsFile();
@@ -17204,12 +17335,6 @@ function parseOpenUrl(input4) {
17204
17335
  let prompt;
17205
17336
  if (promptVals.length === 1) {
17206
17337
  const value = promptVals[0];
17207
- if (/[\r\n]/.test(value)) {
17208
- throw new OpenUrlError(
17209
- "invalid-prompt",
17210
- "`prompt` query param must be a single line (no newlines)"
17211
- );
17212
- }
17213
17338
  if (value.length > MAX_OPEN_PROMPT_LENGTH) {
17214
17339
  throw new OpenUrlError(
17215
17340
  "invalid-prompt",
@@ -18523,7 +18648,8 @@ function createStatusConfigRouter(projectsDir2, assignmentsDir2) {
18523
18648
  statuses: config.statuses,
18524
18649
  order: config.order,
18525
18650
  transitions: config.transitions,
18526
- custom: config.custom
18651
+ custom: config.custom,
18652
+ factDeclarations: config.factDeclarations
18527
18653
  });
18528
18654
  } catch (error) {
18529
18655
  console.error("Error getting status config:", error);
@@ -37599,7 +37725,11 @@ async function loadQueryItem(item, terminalStatuses3, now, declarations) {
37599
37725
  updated: fm.updated,
37600
37726
  completedAt,
37601
37727
  statusAge,
37602
- phaseAge
37728
+ phaseAge,
37729
+ // Mirror the dashboard haystack (queryFilter.ts boardItemToQueryItem) so
37730
+ // `search:` behaves identically on the CLI and the dashboard. The shared
37731
+ // `search` field reads `searchText ?? title`; `title:` stays title-only.
37732
+ searchText: `${item.title ?? ""} ${item.slug ?? ""} ${item.projectTitle ?? "standalone"} ${item.projectSlug ?? ""}`
37603
37733
  };
37604
37734
  } catch {
37605
37735
  return null;
@@ -37659,7 +37789,8 @@ var KNOWN_FILTER_KEYS = /* @__PURE__ */ new Set([
37659
37789
  "tags",
37660
37790
  "activity",
37661
37791
  "dateRange",
37662
- "search"
37792
+ "search",
37793
+ "query"
37663
37794
  ]);
37664
37795
  function preserveUnknownFilterKeys(existing, built) {
37665
37796
  const out = {};
@@ -37702,6 +37833,8 @@ function minimizeFilters(filters, forcedProject) {
37702
37833
  if (filters.dateRange) minimal.dateRange = filters.dateRange;
37703
37834
  const search = filters.search?.trim();
37704
37835
  if (search) minimal.search = search;
37836
+ const query = filters.query?.trim();
37837
+ if (query) minimal.query = query;
37705
37838
  return minimal;
37706
37839
  }
37707
37840
  function captureCurrentView(input4) {
@@ -37728,6 +37861,9 @@ var DEFAULT_CREATE_VIEW_STATE = {
37728
37861
  };
37729
37862
 
37730
37863
  // src/commands/views.ts
37864
+ init_derive();
37865
+ init_recompute();
37866
+ init_query();
37731
37867
  var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
37732
37868
  function fail2(error) {
37733
37869
  console.error("Error:", error instanceof Error ? error.message : String(error));
@@ -37797,7 +37933,7 @@ function buildDateRange(opts) {
37797
37933
  return dr;
37798
37934
  }
37799
37935
  function hasConfigFlag(opts) {
37800
- return opts.viewMode !== void 0 || opts.sortField !== void 0 || opts.sortDirection !== void 0 || opts.status !== void 0 || opts.type !== void 0 || opts.priority !== void 0 || opts.assignee !== void 0 || opts.projectFilter !== void 0 || opts.tags !== void 0 || opts.activity !== void 0 || opts.search !== void 0 || opts.dateRangeField !== void 0 || opts.dateRangePreset !== void 0 || opts.dateFrom !== void 0 || opts.dateTo !== void 0 || opts.clearDateRange === true || opts.collapsed !== void 0 || opts.kanbanHidden !== void 0 || opts.tableHidden !== void 0;
37936
+ return opts.viewMode !== void 0 || opts.sortField !== void 0 || opts.sortDirection !== void 0 || opts.status !== void 0 || opts.type !== void 0 || opts.priority !== void 0 || opts.assignee !== void 0 || opts.projectFilter !== void 0 || opts.tags !== void 0 || opts.activity !== void 0 || opts.search !== void 0 || opts.dateRangeField !== void 0 || opts.dateRangePreset !== void 0 || opts.dateFrom !== void 0 || opts.dateTo !== void 0 || opts.clearDateRange === true || opts.collapsed !== void 0 || opts.kanbanHidden !== void 0 || opts.tableHidden !== void 0 || opts.query !== void 0;
37801
37937
  }
37802
37938
  function emptyVisibilityState() {
37803
37939
  return {
@@ -37826,7 +37962,7 @@ function baseStateFromConfig(config) {
37826
37962
  tableColumnVisibility: { hidden: [...config.tableColumnVisibility.hidden] }
37827
37963
  };
37828
37964
  }
37829
- function applyFlagsToState(state, opts) {
37965
+ async function applyFlagsToState(state, opts) {
37830
37966
  if (opts.viewMode !== void 0) state.viewMode = validateEnum(opts.viewMode, VIEW_MODES, "--view-mode");
37831
37967
  if (opts.sortField !== void 0) state.sortField = validateEnum(opts.sortField, SORT_FIELDS, "--sort-field");
37832
37968
  if (opts.sortDirection !== void 0) {
@@ -37862,13 +37998,28 @@ function applyFlagsToState(state, opts) {
37862
37998
  }
37863
37999
  state.tableColumnVisibility = { hidden: ids };
37864
38000
  }
38001
+ if (opts.query !== void 0) {
38002
+ if (opts.query === "") {
38003
+ delete state.filters.query;
38004
+ } else {
38005
+ const context = await resolveDeriveContext();
38006
+ const { query, errors } = compileQuery(opts.query, buildQueryRegistry(context.factDeclarations));
38007
+ if (!query) {
38008
+ throw new Error(
38009
+ `Invalid --query:
38010
+ ${errors.map((e) => ` at ${e.pos}: ${e.message}`).join("\n")}`
38011
+ );
38012
+ }
38013
+ state.filters.query = opts.query;
38014
+ }
38015
+ }
37865
38016
  }
37866
38017
  async function runViewsAdd(opts) {
37867
38018
  if (opts.name === void 0) throw new Error("--name is required");
37868
38019
  const name = validateName(opts.name);
37869
38020
  const { value: workspace } = resolveWorkspaceFlag(opts);
37870
38021
  const state = baseStateForAdd();
37871
- applyFlagsToState(state, opts);
38022
+ await applyFlagsToState(state, opts);
37872
38023
  const { config } = captureCurrentView({ name, context: { workspace, projectSlug: null }, state });
37873
38024
  if (!isSavedViewConfig(config)) throw new Error("assembled an invalid SavedViewConfig");
37874
38025
  const file = await readSavedViewsFile();
@@ -37916,7 +38067,7 @@ async function runViewsUpdate(id, opts) {
37916
38067
  if (ws.provided) patch.workspace = ws.value;
37917
38068
  if (hasConfigFlag(opts)) {
37918
38069
  const state = baseStateFromConfig(existing.config);
37919
- applyFlagsToState(state, opts);
38070
+ await applyFlagsToState(state, opts);
37920
38071
  const built = captureCurrentView({ name: "", context: { workspace: null, projectSlug: null }, state }).config;
37921
38072
  const merged = mergeUpdatedConfig(existing.config, built, {
37922
38073
  listSectionVisibility: state.listSectionVisibility,
@@ -37941,7 +38092,7 @@ async function runViewsDelete(id) {
37941
38092
  await writeSavedViewsFile(result.file);
37942
38093
  }
37943
38094
  function addConfigFlags(cmd) {
37944
- return cmd.option("--workspace <ws>", "Scope the view to a workspace (default: global)").option("--global", "Make the view global (workspace = null)").option("--view-mode <mode>", `View mode (${VIEW_MODES.join("|")})`).option("--sort-field <field>", `Sort field (${SORT_FIELDS.join("|")})`).option("--sort-direction <dir>", `Sort direction (${SORT_DIRECTIONS.join("|")})`).option("--status <vals>", 'Status filter, comma-separated ("all"/"" clears)').option("--type <vals>", 'Type filter, comma-separated ("all"/"" clears)').option("--priority <vals>", 'Priority filter, comma-separated ("all"/"" clears)').option("--assignee <vals>", 'Assignee filter, comma-separated ("all"/"" clears)').option("--project-filter <vals>", 'Project filter, comma-separated ("all"/"" clears)').option("--tags <vals>", 'Tags filter, comma-separated ("all"/"" clears)').option("--activity <val>", `Activity filter (${ACTIVITIES.join("|")}; "all" clears)`).option("--date-range-field <field>", `Date range field (${DATE_RANGE_FIELDS.join("|")})`).option("--date-range-preset <preset>", `Date range preset (${DATE_RANGE_PRESETS.join("|")})`).option("--date-from <YYYY-MM-DD>", "Date range start (exclusive with --date-range-preset)").option("--date-to <YYYY-MM-DD>", "Date range end (exclusive with --date-range-preset)").option("--clear-date-range", "Remove the date-range filter").option("--search <text>", 'Search text filter ("" clears)').option("--collapsed <vals>", "List-view collapsed section ids, comma-separated").option("--kanban-hidden <vals>", "Kanban hidden column ids, comma-separated").option("--table-hidden <vals>", `Table hidden column ids (${TABLE_COLUMN_IDS.join("|")}), comma-separated`).option("--json", "Output the resulting view as JSON");
38095
+ return cmd.option("--workspace <ws>", "Scope the view to a workspace (default: global)").option("--global", "Make the view global (workspace = null)").option("--view-mode <mode>", `View mode (${VIEW_MODES.join("|")})`).option("--sort-field <field>", `Sort field (${SORT_FIELDS.join("|")})`).option("--sort-direction <dir>", `Sort direction (${SORT_DIRECTIONS.join("|")})`).option("--status <vals>", 'Status filter, comma-separated ("all"/"" clears)').option("--type <vals>", 'Type filter, comma-separated ("all"/"" clears)').option("--priority <vals>", 'Priority filter, comma-separated ("all"/"" clears)').option("--assignee <vals>", 'Assignee filter, comma-separated ("all"/"" clears)').option("--project-filter <vals>", 'Project filter, comma-separated ("all"/"" clears)').option("--tags <vals>", 'Tags filter, comma-separated ("all"/"" clears)').option("--activity <val>", `Activity filter (${ACTIVITIES.join("|")}; "all" clears)`).option("--date-range-field <field>", `Date range field (${DATE_RANGE_FIELDS.join("|")})`).option("--date-range-preset <preset>", `Date range preset (${DATE_RANGE_PRESETS.join("|")})`).option("--date-from <YYYY-MM-DD>", "Date range start (exclusive with --date-range-preset)").option("--date-to <YYYY-MM-DD>", "Date range end (exclusive with --date-range-preset)").option("--clear-date-range", "Remove the date-range filter").option("--search <text>", 'Search text filter ("" clears)').option("--query <expr>", 'AQL filter query ("" clears)').option("--collapsed <vals>", "List-view collapsed section ids, comma-separated").option("--kanban-hidden <vals>", "Kanban hidden column ids, comma-separated").option("--table-hidden <vals>", `Table hidden column ids (${TABLE_COLUMN_IDS.join("|")}), comma-separated`).option("--json", "Output the resulting view as JSON");
37945
38096
  }
37946
38097
  var viewsCommand = new Command15("views").description(
37947
38098
  "Manage saved views (~/.syntaur/saved-views.json)"