brainfile 0.19.0 → 0.20.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 (82) hide show
  1. package/README.md +18 -24
  2. package/dist/__tests__/helpers/mcp-wire.d.ts +45 -0
  3. package/dist/__tests__/helpers/mcp-wire.d.ts.map +1 -0
  4. package/dist/__tests__/helpers/mcp-wire.js +133 -0
  5. package/dist/__tests__/helpers/mcp-wire.js.map +1 -0
  6. package/dist/{chunk-YTFLC673.mjs → chunk-UOCQBEEW.mjs} +1486 -992
  7. package/dist/cli.mjs +916 -776
  8. package/dist/commands/adr.d.ts +1 -9
  9. package/dist/commands/adr.d.ts.map +1 -1
  10. package/dist/commands/adr.js +11 -88
  11. package/dist/commands/adr.js.map +1 -1
  12. package/dist/commands/archive.d.ts +2 -5
  13. package/dist/commands/archive.d.ts.map +1 -1
  14. package/dist/commands/archive.js +43 -11
  15. package/dist/commands/archive.js.map +1 -1
  16. package/dist/commands/brief.d.ts +31 -0
  17. package/dist/commands/brief.d.ts.map +1 -0
  18. package/dist/commands/brief.js +151 -0
  19. package/dist/commands/brief.js.map +1 -0
  20. package/dist/commands/complete.js +1 -1
  21. package/dist/commands/complete.js.map +1 -1
  22. package/dist/commands/log.js +31 -18
  23. package/dist/commands/log.js.map +1 -1
  24. package/dist/commands/mcp.d.ts +9 -0
  25. package/dist/commands/mcp.d.ts.map +1 -1
  26. package/dist/commands/mcp.js +28 -17
  27. package/dist/commands/mcp.js.map +1 -1
  28. package/dist/commands/migrate.js +10 -12
  29. package/dist/commands/migrate.js.map +1 -1
  30. package/dist/mcp/schemas.d.ts +297 -0
  31. package/dist/mcp/schemas.d.ts.map +1 -0
  32. package/dist/mcp/schemas.js +328 -0
  33. package/dist/mcp/schemas.js.map +1 -0
  34. package/dist/mcp/tools/brief_tool.d.ts +14 -0
  35. package/dist/mcp/tools/brief_tool.d.ts.map +1 -0
  36. package/dist/mcp/tools/brief_tool.js +58 -0
  37. package/dist/mcp/tools/brief_tool.js.map +1 -0
  38. package/dist/mcp/tools/contract_tool.d.ts.map +1 -1
  39. package/dist/mcp/tools/contract_tool.js +37 -13
  40. package/dist/mcp/tools/contract_tool.js.map +1 -1
  41. package/dist/mcp/tools/get_task_tool.d.ts.map +1 -1
  42. package/dist/mcp/tools/get_task_tool.js +7 -2
  43. package/dist/mcp/tools/get_task_tool.js.map +1 -1
  44. package/dist/mcp/tools/list_tasks_tool.d.ts.map +1 -1
  45. package/dist/mcp/tools/list_tasks_tool.js +9 -3
  46. package/dist/mcp/tools/list_tasks_tool.js.map +1 -1
  47. package/dist/mcp/tools/search_tool.d.ts.map +1 -1
  48. package/dist/mcp/tools/search_tool.js +17 -4
  49. package/dist/mcp/tools/search_tool.js.map +1 -1
  50. package/dist/mcp/tools/subtask_tool.d.ts.map +1 -1
  51. package/dist/mcp/tools/subtask_tool.js +47 -13
  52. package/dist/mcp/tools/subtask_tool.js.map +1 -1
  53. package/dist/mcp/tools/task_add_tool.d.ts.map +1 -1
  54. package/dist/mcp/tools/task_add_tool.js +7 -2
  55. package/dist/mcp/tools/task_add_tool.js.map +1 -1
  56. package/dist/mcp/tools/task_complete_tool.d.ts.map +1 -1
  57. package/dist/mcp/tools/task_complete_tool.js +34 -6
  58. package/dist/mcp/tools/task_complete_tool.js.map +1 -1
  59. package/dist/mcp/tools/task_delete_tool.d.ts.map +1 -1
  60. package/dist/mcp/tools/task_delete_tool.js +7 -2
  61. package/dist/mcp/tools/task_delete_tool.js.map +1 -1
  62. package/dist/mcp/tools/task_move_tool.d.ts.map +1 -1
  63. package/dist/mcp/tools/task_move_tool.js +15 -6
  64. package/dist/mcp/tools/task_move_tool.js.map +1 -1
  65. package/dist/mcp/tools/task_patch_tool.d.ts.map +1 -1
  66. package/dist/mcp/tools/task_patch_tool.js +18 -6
  67. package/dist/mcp/tools/task_patch_tool.js.map +1 -1
  68. package/dist/schemas/board.json +1 -1
  69. package/dist/tui/theme.d.ts +98 -0
  70. package/dist/tui/theme.d.ts.map +1 -0
  71. package/dist/tui/theme.js +141 -0
  72. package/dist/tui/theme.js.map +1 -0
  73. package/dist/{tui-P56H4X7N.mjs → tui-H3RI22S4.mjs} +1593 -1934
  74. package/dist/utils/cli-error.d.ts +20 -0
  75. package/dist/utils/cli-error.d.ts.map +1 -1
  76. package/dist/utils/cli-error.js +36 -0
  77. package/dist/utils/cli-error.js.map +1 -1
  78. package/package.json +3 -3
  79. package/dist/commands/rules.d.ts +0 -68
  80. package/dist/commands/rules.d.ts.map +0 -1
  81. package/dist/commands/rules.js +0 -322
  82. package/dist/commands/rules.js.map +0 -1
@@ -1327,14 +1327,14 @@ var require_templates = __commonJS({
1327
1327
  }
1328
1328
  return results;
1329
1329
  }
1330
- function buildStyle(chalk4, styles) {
1330
+ function buildStyle(chalk5, styles) {
1331
1331
  const enabled = {};
1332
1332
  for (const layer of styles) {
1333
1333
  for (const style of layer.styles) {
1334
1334
  enabled[style[0]] = layer.inverse ? null : style.slice(1);
1335
1335
  }
1336
1336
  }
1337
- let current = chalk4;
1337
+ let current = chalk5;
1338
1338
  for (const [styleName, styles2] of Object.entries(enabled)) {
1339
1339
  if (!Array.isArray(styles2)) {
1340
1340
  continue;
@@ -1346,7 +1346,7 @@ var require_templates = __commonJS({
1346
1346
  }
1347
1347
  return current;
1348
1348
  }
1349
- module.exports = (chalk4, temporary) => {
1349
+ module.exports = (chalk5, temporary) => {
1350
1350
  const styles = [];
1351
1351
  const chunks = [];
1352
1352
  let chunk = [];
@@ -1356,13 +1356,13 @@ var require_templates = __commonJS({
1356
1356
  } else if (style) {
1357
1357
  const string = chunk.join("");
1358
1358
  chunk = [];
1359
- chunks.push(styles.length === 0 ? string : buildStyle(chalk4, styles)(string));
1359
+ chunks.push(styles.length === 0 ? string : buildStyle(chalk5, styles)(string));
1360
1360
  styles.push({ inverse, styles: parseStyle(style) });
1361
1361
  } else if (close) {
1362
1362
  if (styles.length === 0) {
1363
1363
  throw new Error("Found extraneous } in Chalk template literal");
1364
1364
  }
1365
- chunks.push(buildStyle(chalk4, styles)(chunk.join("")));
1365
+ chunks.push(buildStyle(chalk5, styles)(chunk.join("")));
1366
1366
  chunk = [];
1367
1367
  styles.pop();
1368
1368
  } else {
@@ -1410,16 +1410,16 @@ var require_source = __commonJS({
1410
1410
  }
1411
1411
  };
1412
1412
  var chalkFactory = (options) => {
1413
- const chalk5 = {};
1414
- applyOptions(chalk5, options);
1415
- chalk5.template = (...arguments_) => chalkTag(chalk5.template, ...arguments_);
1416
- Object.setPrototypeOf(chalk5, Chalk.prototype);
1417
- Object.setPrototypeOf(chalk5.template, chalk5);
1418
- chalk5.template.constructor = () => {
1413
+ const chalk6 = {};
1414
+ applyOptions(chalk6, options);
1415
+ chalk6.template = (...arguments_) => chalkTag(chalk6.template, ...arguments_);
1416
+ Object.setPrototypeOf(chalk6, Chalk.prototype);
1417
+ Object.setPrototypeOf(chalk6.template, chalk6);
1418
+ chalk6.template.constructor = () => {
1419
1419
  throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
1420
1420
  };
1421
- chalk5.template.Instance = ChalkClass;
1422
- return chalk5.template;
1421
+ chalk6.template.Instance = ChalkClass;
1422
+ return chalk6.template;
1423
1423
  };
1424
1424
  function Chalk(options) {
1425
1425
  return chalkFactory(options);
@@ -1530,7 +1530,7 @@ var require_source = __commonJS({
1530
1530
  return openAll + string + closeAll;
1531
1531
  };
1532
1532
  var template;
1533
- var chalkTag = (chalk5, ...strings) => {
1533
+ var chalkTag = (chalk6, ...strings) => {
1534
1534
  const [firstString] = strings;
1535
1535
  if (!isArray(firstString) || !isArray(firstString.raw)) {
1536
1536
  return strings.join(" ");
@@ -1546,14 +1546,14 @@ var require_source = __commonJS({
1546
1546
  if (template === void 0) {
1547
1547
  template = require_templates();
1548
1548
  }
1549
- return template(chalk5, parts.join(""));
1549
+ return template(chalk6, parts.join(""));
1550
1550
  };
1551
1551
  Object.defineProperties(Chalk.prototype, styles);
1552
- var chalk4 = Chalk();
1553
- chalk4.supportsColor = stdoutColor;
1554
- chalk4.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
1555
- chalk4.stderr.supportsColor = stderrColor;
1556
- module.exports = chalk4;
1552
+ var chalk5 = Chalk();
1553
+ chalk5.supportsColor = stdoutColor;
1554
+ chalk5.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
1555
+ chalk5.stderr.supportsColor = stderrColor;
1556
+ module.exports = chalk5;
1557
1557
  }
1558
1558
  });
1559
1559
 
@@ -5421,61 +5421,6 @@ var require_parser = __commonJS({
5421
5421
  }
5422
5422
  return null;
5423
5423
  }
5424
- /**
5425
- * Find the line number of a rule in the YAML frontmatter
5426
- * @param content - The markdown content
5427
- * @param ruleId - The rule ID to find
5428
- * @param ruleType - The type of rule (always, never, prefer, context)
5429
- * @returns Line and column location or null if not found
5430
- */
5431
- static findRuleLocation(content, ruleId, ruleType) {
5432
- const lines = content.split("\n");
5433
- let inFrontmatter = false;
5434
- let inRulesSection = false;
5435
- let inRuleTypeSection = false;
5436
- for (let i = 0; i < lines.length; i++) {
5437
- const line = lines[i];
5438
- const trimmedLine = line.trim();
5439
- if (trimmedLine === "---") {
5440
- if (!inFrontmatter) {
5441
- inFrontmatter = true;
5442
- continue;
5443
- } else {
5444
- break;
5445
- }
5446
- }
5447
- if (!inFrontmatter)
5448
- continue;
5449
- if (trimmedLine === "rules:") {
5450
- inRulesSection = true;
5451
- continue;
5452
- }
5453
- if (inRulesSection && trimmedLine === `${ruleType}:`) {
5454
- inRuleTypeSection = true;
5455
- continue;
5456
- }
5457
- if (inRulesSection && line.match(/^[a-z]+:/) && !line.match(/^\s/)) {
5458
- inRulesSection = false;
5459
- inRuleTypeSection = false;
5460
- }
5461
- if (inRuleTypeSection) {
5462
- if (line.match(/^\s{2}[a-z]+:/) && !line.includes(`${ruleType}:`)) {
5463
- inRuleTypeSection = false;
5464
- continue;
5465
- }
5466
- if (line.includes(`id: ${ruleId}`)) {
5467
- if (line.match(/^\s*-\s+id:\s+/)) {
5468
- return { line: i + 1, column: 0 };
5469
- }
5470
- if (i > 0 && lines[i - 1].match(/^\s*-\s*$/)) {
5471
- return { line: i, column: 0 };
5472
- }
5473
- return { line: i + 1, column: 0 };
5474
- }
5475
- }
5476
- }
5477
- return null;
5478
- }
5479
5424
  };
5480
5425
  exports.BrainfileParser = BrainfileParser;
5481
5426
  }
@@ -5656,10 +5601,6 @@ var require_validator = __commonJS({
5656
5601
  errors.push(...columnErrors);
5657
5602
  });
5658
5603
  }
5659
- if (board.rules !== void 0) {
5660
- const rulesErrors = this.validateRules(board.rules, "rules");
5661
- errors.push(...rulesErrors);
5662
- }
5663
5604
  if (board.archive !== void 0) {
5664
5605
  if (!Array.isArray(board.archive)) {
5665
5606
  errors.push({ path: "archive", message: "Archive must be an array" });
@@ -5788,53 +5729,6 @@ var require_validator = __commonJS({
5788
5729
  }
5789
5730
  return errors;
5790
5731
  }
5791
- /**
5792
- * Validate Rules object
5793
- * @param rules - The rules to validate
5794
- * @param path - The path for error reporting
5795
- * @returns Array of validation errors
5796
- */
5797
- static validateRules(rules, path7) {
5798
- const errors = [];
5799
- if (!rules) {
5800
- errors.push({ path: path7, message: "Rules is null or undefined" });
5801
- return errors;
5802
- }
5803
- const ruleTypes = ["always", "never", "prefer", "context"];
5804
- ruleTypes.forEach((ruleType) => {
5805
- if (rules[ruleType] !== void 0) {
5806
- if (!Array.isArray(rules[ruleType])) {
5807
- errors.push({ path: `${path7}.${ruleType}`, message: `Rules ${ruleType} must be an array` });
5808
- } else {
5809
- rules[ruleType].forEach((rule, index) => {
5810
- const ruleErrors = this.validateRule(rule, `${path7}.${ruleType}[${index}]`);
5811
- errors.push(...ruleErrors);
5812
- });
5813
- }
5814
- }
5815
- });
5816
- return errors;
5817
- }
5818
- /**
5819
- * Validate a Rule object
5820
- * @param rule - The rule to validate
5821
- * @param path - The path for error reporting
5822
- * @returns Array of validation errors
5823
- */
5824
- static validateRule(rule, path7) {
5825
- const errors = [];
5826
- if (!rule) {
5827
- errors.push({ path: path7, message: "Rule is null or undefined" });
5828
- return errors;
5829
- }
5830
- if (typeof rule.id !== "number") {
5831
- errors.push({ path: `${path7}.id`, message: "Rule id must be a number" });
5832
- }
5833
- if (typeof rule.rule !== "string" || rule.rule.trim() === "") {
5834
- errors.push({ path: `${path7}.rule`, message: "Rule rule must be a non-empty string" });
5835
- }
5836
- return errors;
5837
- }
5838
5732
  /**
5839
5733
  * Validate any brainfile object with type detection
5840
5734
  * @param data - The brainfile data to validate
@@ -5886,10 +5780,6 @@ var require_validator = __commonJS({
5886
5780
  errors.push(...entryErrors);
5887
5781
  });
5888
5782
  }
5889
- if (journal.rules !== void 0) {
5890
- const rulesErrors = this.validateRules(journal.rules, "rules");
5891
- errors.push(...rulesErrors);
5892
- }
5893
5783
  return { valid: errors.length === 0, errors };
5894
5784
  }
5895
5785
  /**
@@ -5932,6 +5822,104 @@ var require_validator = __commonJS({
5932
5822
  }
5933
5823
  });
5934
5824
 
5825
+ // ../core/dist/frontmatter.js
5826
+ var require_frontmatter = __commonJS({
5827
+ "../core/dist/frontmatter.js"(exports) {
5828
+ "use strict";
5829
+ var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
5830
+ if (k2 === void 0) k2 = k;
5831
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5832
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
5833
+ desc = { enumerable: true, get: function() {
5834
+ return m[k];
5835
+ } };
5836
+ }
5837
+ Object.defineProperty(o, k2, desc);
5838
+ }) : (function(o, m, k, k2) {
5839
+ if (k2 === void 0) k2 = k;
5840
+ o[k2] = m[k];
5841
+ }));
5842
+ var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
5843
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
5844
+ }) : function(o, v) {
5845
+ o["default"] = v;
5846
+ });
5847
+ var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
5848
+ var ownKeys = function(o) {
5849
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
5850
+ var ar = [];
5851
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
5852
+ return ar;
5853
+ };
5854
+ return ownKeys(o);
5855
+ };
5856
+ return function(mod) {
5857
+ if (mod && mod.__esModule) return mod;
5858
+ var result = {};
5859
+ if (mod != null) {
5860
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
5861
+ }
5862
+ __setModuleDefault(result, mod);
5863
+ return result;
5864
+ };
5865
+ })();
5866
+ Object.defineProperty(exports, "__esModule", { value: true });
5867
+ exports.parseFrontmatter = parseFrontmatter;
5868
+ exports.serializeFrontmatter = serializeFrontmatter;
5869
+ var yaml = __importStar(require_js_yaml());
5870
+ function parseFrontmatter(content) {
5871
+ const lines = content.split("\n");
5872
+ if (!lines[0] || lines[0].trim() !== "---") {
5873
+ return null;
5874
+ }
5875
+ let endIndex = -1;
5876
+ for (let i = 1; i < lines.length; i++) {
5877
+ if (lines[i].trim() === "---") {
5878
+ endIndex = i;
5879
+ break;
5880
+ }
5881
+ }
5882
+ if (endIndex === -1) {
5883
+ return null;
5884
+ }
5885
+ const yamlContent = lines.slice(1, endIndex).join("\n");
5886
+ const bodyContent = lines.slice(endIndex + 1).join("\n");
5887
+ let parsed;
5888
+ try {
5889
+ parsed = yaml.load(yamlContent);
5890
+ } catch {
5891
+ return null;
5892
+ }
5893
+ if (!parsed || typeof parsed !== "object") {
5894
+ return null;
5895
+ }
5896
+ return {
5897
+ data: parsed,
5898
+ body: bodyContent.replace(/^\n/, "")
5899
+ };
5900
+ }
5901
+ function serializeFrontmatter(data, body = "") {
5902
+ const yamlContent = yaml.dump(data, {
5903
+ indent: 2,
5904
+ lineWidth: -1,
5905
+ noRefs: true,
5906
+ sortKeys: false,
5907
+ quotingType: '"',
5908
+ forceQuotes: false
5909
+ });
5910
+ const parts = ["---\n", yamlContent, "---\n"];
5911
+ if (body.length > 0) {
5912
+ parts.push("\n");
5913
+ parts.push(body);
5914
+ if (!body.endsWith("\n")) {
5915
+ parts.push("\n");
5916
+ }
5917
+ }
5918
+ return parts.join("");
5919
+ }
5920
+ }
5921
+ });
5922
+
5935
5923
  // ../core/dist/linter.js
5936
5924
  var require_linter = __commonJS({
5937
5925
  "../core/dist/linter.js"(exports) {
@@ -5974,10 +5962,13 @@ var require_linter = __commonJS({
5974
5962
  };
5975
5963
  })();
5976
5964
  Object.defineProperty(exports, "__esModule", { value: true });
5977
- exports.BrainfileLinter = void 0;
5965
+ exports.BrainfileLinter = exports.LEGACY_RULES_MESSAGE = void 0;
5978
5966
  var yaml = __importStar(require_js_yaml());
5979
5967
  var parser_1 = require_parser();
5980
5968
  var validator_1 = require_validator();
5969
+ var frontmatter_1 = require_frontmatter();
5970
+ exports.LEGACY_RULES_MESSAGE = "rules is removed (adr-2); fold into agent.instructions";
5971
+ var RULE_CATEGORY_ORDER = ["always", "never", "prefer", "context"];
5981
5972
  var BrainfileLinter = class {
5982
5973
  /**
5983
5974
  * Lint a brainfile.md content string
@@ -6004,6 +5995,21 @@ var require_linter = __commonJS({
6004
5995
  fixedContent = this.fixUnquotedStrings(content, quotableStrings);
6005
5996
  }
6006
5997
  }
5998
+ const legacyRules = this.findLegacyRules(fixedContent);
5999
+ if (legacyRules) {
6000
+ issues.push({
6001
+ type: "warning",
6002
+ message: exports.LEGACY_RULES_MESSAGE,
6003
+ line: legacyRules.line,
6004
+ fixable: true,
6005
+ code: "LEGACY_RULES"
6006
+ });
6007
+ if (options.autoFix) {
6008
+ const folded = this.foldLegacyRules(fixedContent);
6009
+ if (folded !== null)
6010
+ fixedContent = folded;
6011
+ }
6012
+ }
6007
6013
  const contentToValidate = options.autoFix && fixedContent !== content ? fixedContent : content;
6008
6014
  const yamlIssues = this.checkYAMLSyntax(contentToValidate);
6009
6015
  if (options.autoFix && fixedContent !== content) {
@@ -6064,6 +6070,62 @@ var require_linter = __commonJS({
6064
6070
  board: board || void 0
6065
6071
  };
6066
6072
  }
6073
+ /**
6074
+ * Locate a legacy top-level `rules:` block in the frontmatter.
6075
+ *
6076
+ * Deliberately textual rather than YAML-object based: this must report a
6077
+ * usable line number, and it must still fire on a file whose frontmatter
6078
+ * fails to `yaml.load` for some unrelated reason.
6079
+ */
6080
+ static findLegacyRules(content) {
6081
+ const lines = content.split("\n");
6082
+ if (!lines[0] || lines[0].trim() !== "---")
6083
+ return null;
6084
+ for (let i = 1; i < lines.length; i++) {
6085
+ if (lines[i].trim() === "---")
6086
+ return null;
6087
+ if (/^rules:\s*$/.test(lines[i]) || /^rules:\s+\S/.test(lines[i])) {
6088
+ return { line: i + 1 };
6089
+ }
6090
+ }
6091
+ return null;
6092
+ }
6093
+ /**
6094
+ * Fold a legacy `rules:` block into `agent.instructions` and remove it.
6095
+ *
6096
+ * Each rule becomes `"<category>: <text>"` (adr-2's stated shape), appended
6097
+ * in category order after any instructions already present. Returns null if
6098
+ * the frontmatter cannot be round-tripped, in which case the caller keeps
6099
+ * the original content and the warning stands unfixed.
6100
+ */
6101
+ static foldLegacyRules(content) {
6102
+ const doc = (0, frontmatter_1.parseFrontmatter)(content);
6103
+ if (!doc)
6104
+ return null;
6105
+ const data = doc.data;
6106
+ const rules = data.rules;
6107
+ if (!rules || typeof rules !== "object" || Array.isArray(rules))
6108
+ return null;
6109
+ const folded = [];
6110
+ for (const category of RULE_CATEGORY_ORDER) {
6111
+ const entries = rules[category];
6112
+ if (!Array.isArray(entries))
6113
+ continue;
6114
+ for (const entry of entries) {
6115
+ const text = typeof entry === "string" ? entry : typeof entry?.rule === "string" ? entry.rule : null;
6116
+ if (text && text.trim())
6117
+ folded.push(`${category}: ${text.trim()}`);
6118
+ }
6119
+ }
6120
+ delete data.rules;
6121
+ if (folded.length > 0) {
6122
+ const agent = data.agent && typeof data.agent === "object" && !Array.isArray(data.agent) ? data.agent : {};
6123
+ const existing = Array.isArray(agent.instructions) ? agent.instructions.filter((i) => typeof i === "string") : [];
6124
+ agent.instructions = [...existing, ...folded];
6125
+ data.agent = agent;
6126
+ }
6127
+ return (0, frontmatter_1.serializeFrontmatter)(data, doc.body);
6128
+ }
6067
6129
  /**
6068
6130
  * Check YAML syntax by attempting to parse
6069
6131
  */
@@ -6212,14 +6274,12 @@ var require_realtimeDiff = __commonJS({
6212
6274
  protocolVersion: previous.protocolVersion,
6213
6275
  schema: previous.schema,
6214
6276
  agent: previous.agent,
6215
- rules: previous.rules,
6216
6277
  statsConfig: previous.statsConfig
6217
6278
  }, {
6218
6279
  title: next.title,
6219
6280
  protocolVersion: next.protocolVersion,
6220
6281
  schema: next.schema,
6221
6282
  agent: next.agent,
6222
- rules: next.rules,
6223
6283
  statsConfig: next.statsConfig
6224
6284
  });
6225
6285
  const columnIdToPrev = indexColumns(previous.columns);
@@ -6678,8 +6738,6 @@ var require_operations = __commonJS({
6678
6738
  exports.updateSubtask = updateSubtask;
6679
6739
  exports.setSubtasksCompleted = setSubtasksCompleted;
6680
6740
  exports.setAllSubtasksCompleted = setAllSubtasksCompleted;
6681
- exports.addRule = addRule;
6682
- exports.deleteRule = deleteRule;
6683
6741
  exports.moveTasks = moveTasks;
6684
6742
  exports.patchTasks = patchTasks;
6685
6743
  exports.deleteTasks = deleteTasks;
@@ -7162,55 +7220,6 @@ var require_operations = __commonJS({
7162
7220
  };
7163
7221
  return { success: true, board: newBoard };
7164
7222
  }
7165
- function addRule(board, ruleType, ruleText) {
7166
- if (!ruleText || ruleText.trim() === "") {
7167
- return { success: false, error: "Rule text is required" };
7168
- }
7169
- const trimmedRule = ruleText.trim();
7170
- const existingRules = board.rules?.[ruleType] ?? [];
7171
- const nextId = existingRules.reduce((maxId, rule) => Math.max(maxId, rule.id), 0) + 1;
7172
- const newRule = {
7173
- id: nextId,
7174
- rule: trimmedRule
7175
- };
7176
- const updatedRulesForType = [...existingRules, newRule];
7177
- const updatedRules = {
7178
- ...board.rules ?? {},
7179
- [ruleType]: updatedRulesForType
7180
- };
7181
- return {
7182
- success: true,
7183
- board: {
7184
- ...board,
7185
- rules: updatedRules
7186
- }
7187
- };
7188
- }
7189
- function deleteRule(board, ruleType, ruleId) {
7190
- const rulesForType = board.rules?.[ruleType];
7191
- if (!rulesForType || rulesForType.length === 0) {
7192
- return { success: false, error: `Rule type ${ruleType} has no entries` };
7193
- }
7194
- const exists = rulesForType.some((rule) => rule.id === ruleId);
7195
- if (!exists) {
7196
- return { success: false, error: `Rule ${ruleId} not found in ${ruleType}` };
7197
- }
7198
- const updatedRulesForType = rulesForType.filter((rule) => rule.id !== ruleId);
7199
- const updatedRules = { ...board.rules ?? {} };
7200
- if (updatedRulesForType.length > 0) {
7201
- updatedRules[ruleType] = updatedRulesForType;
7202
- } else {
7203
- delete updatedRules[ruleType];
7204
- }
7205
- const hasAnyRules = Object.values(updatedRules).some((collection) => collection !== void 0 && collection.length > 0);
7206
- return {
7207
- success: true,
7208
- board: {
7209
- ...board,
7210
- rules: hasAnyRules ? updatedRules : void 0
7211
- }
7212
- };
7213
- }
7214
7223
  function moveTasks(board, taskIds, toColumnId) {
7215
7224
  const results = [];
7216
7225
  let currentBoard = board;
@@ -7797,7 +7806,7 @@ var require_files = __commonJS({
7797
7806
  };
7798
7807
  })();
7799
7808
  Object.defineProperty(exports, "__esModule", { value: true });
7800
- exports.DOT_BRAINFILE_GITIGNORE_BASENAME = exports.BRAINFILE_STATE_BASENAME = exports.BRAINFILE_BASENAME = exports.DOT_BRAINFILE_DIRNAME = void 0;
7809
+ exports.DOT_BRAINFILE_STATE_IGNORE_ENTRY = exports.DOT_BRAINFILE_STATE_DIRNAME = exports.DOT_BRAINFILE_GITIGNORE_BASENAME = exports.BRAINFILE_STATE_BASENAME = exports.BRAINFILE_BASENAME = exports.DOT_BRAINFILE_DIRNAME = void 0;
7801
7810
  exports.findBrainfile = findBrainfile2;
7802
7811
  exports.resolveBrainfilePath = resolveBrainfilePath2;
7803
7812
  exports.getBrainfileStateDir = getBrainfileStateDir;
@@ -7805,12 +7814,15 @@ var require_files = __commonJS({
7805
7814
  exports.getDotBrainfileGitignorePath = getDotBrainfileGitignorePath;
7806
7815
  exports.ensureDotBrainfileDir = ensureDotBrainfileDir;
7807
7816
  exports.ensureDotBrainfileGitignore = ensureDotBrainfileGitignore;
7817
+ exports.atomicWriteFileSync = atomicWriteFileSync;
7808
7818
  var fs7 = __importStar(__require("fs"));
7809
7819
  var path7 = __importStar(__require("path"));
7810
7820
  exports.DOT_BRAINFILE_DIRNAME = ".brainfile";
7811
7821
  exports.BRAINFILE_BASENAME = "brainfile.md";
7812
7822
  exports.BRAINFILE_STATE_BASENAME = "state.json";
7813
7823
  exports.DOT_BRAINFILE_GITIGNORE_BASENAME = ".gitignore";
7824
+ exports.DOT_BRAINFILE_STATE_DIRNAME = "state";
7825
+ exports.DOT_BRAINFILE_STATE_IGNORE_ENTRY = "state/";
7814
7826
  function toAbsolute(p) {
7815
7827
  return path7.isAbsolute(p) ? p : path7.resolve(p);
7816
7828
  }
@@ -7884,159 +7896,66 @@ var require_files = __commonJS({
7884
7896
  ensureDotBrainfileDir(brainfilePath);
7885
7897
  const gitignorePath = getDotBrainfileGitignorePath(brainfilePath);
7886
7898
  const existing = fs7.existsSync(gitignorePath) ? fs7.readFileSync(gitignorePath, "utf-8") : "";
7887
- const filtered = existing.split(/\r?\n/).filter((line) => line.trim() !== exports.BRAINFILE_STATE_BASENAME).join("\n").trimEnd();
7899
+ const lines = existing.split(/\r?\n/).filter((line) => line.trim() !== exports.BRAINFILE_STATE_BASENAME);
7900
+ const hasStateDir = lines.some((line) => line.trim() === exports.DOT_BRAINFILE_STATE_IGNORE_ENTRY);
7901
+ if (!hasStateDir) {
7902
+ lines.push(exports.DOT_BRAINFILE_STATE_IGNORE_ENTRY);
7903
+ }
7904
+ const filtered = lines.join("\n").trim();
7888
7905
  fs7.writeFileSync(gitignorePath, filtered.length > 0 ? `${filtered}
7889
7906
  ` : "", "utf-8");
7890
7907
  }
7908
+ function atomicWriteFileSync(filePath, content) {
7909
+ const abs = toAbsolute(filePath);
7910
+ const dir = path7.dirname(abs);
7911
+ fs7.mkdirSync(dir, { recursive: true });
7912
+ const tmp = path7.join(dir, `.${path7.basename(abs)}.tmp-${process.pid}-${Date.now()}`);
7913
+ try {
7914
+ fs7.writeFileSync(tmp, content, "utf-8");
7915
+ fs7.renameSync(tmp, abs);
7916
+ } catch (err) {
7917
+ try {
7918
+ if (fs7.existsSync(tmp))
7919
+ fs7.unlinkSync(tmp);
7920
+ } catch {
7921
+ }
7922
+ throw err;
7923
+ }
7924
+ }
7891
7925
  }
7892
7926
  });
7893
7927
 
7894
- // ../core/dist/formatters.js
7895
- var require_formatters = __commonJS({
7896
- "../core/dist/formatters.js"(exports) {
7928
+ // ../core/dist/taskContent.js
7929
+ var require_taskContent = __commonJS({
7930
+ "../core/dist/taskContent.js"(exports) {
7897
7931
  "use strict";
7898
7932
  Object.defineProperty(exports, "__esModule", { value: true });
7899
- exports.formatTaskForGitHub = formatTaskForGitHub;
7900
- exports.formatTaskForLinear = formatTaskForLinear;
7901
- function formatTaskForGitHub(task, options = {}) {
7902
- const { includeMeta = true, includeSubtasks = true, includeRelatedFiles = true, resolvedBy, resolvedByPR, fromColumn, boardTitle, extraLabels = [], includeTaskId = true } = options;
7903
- const title = includeTaskId ? `[${task.id}] ${task.title}` : task.title;
7904
- const sections = [];
7905
- if (task.description) {
7906
- sections.push(task.description);
7907
- }
7908
- if (includeSubtasks && task.subtasks && task.subtasks.length > 0) {
7909
- sections.push(formatSubtasksMarkdown(task.subtasks));
7910
- }
7911
- if (includeMeta) {
7912
- const meta = formatMetadataSection(task, { fromColumn, boardTitle });
7913
- if (meta) {
7914
- sections.push(meta);
7915
- }
7916
- }
7917
- if (includeRelatedFiles && task.relatedFiles && task.relatedFiles.length > 0) {
7918
- sections.push(formatRelatedFilesSection(task.relatedFiles));
7919
- }
7920
- if (resolvedBy || resolvedByPR) {
7921
- sections.push(formatResolutionSection(resolvedBy, resolvedByPR));
7922
- }
7923
- sections.push("---\n*Archived from brainfile.md*");
7924
- const labels = [...task.tags || [], ...extraLabels];
7925
- if (task.priority) {
7926
- labels.push(`priority:${task.priority}`);
7933
+ exports.parseTaskContent = parseTaskContent;
7934
+ exports.serializeTaskContent = serializeTaskContent;
7935
+ var frontmatter_1 = require_frontmatter();
7936
+ function parseTaskContent(content) {
7937
+ const parsed = (0, frontmatter_1.parseFrontmatter)(content);
7938
+ if (!parsed) {
7939
+ return null;
7927
7940
  }
7928
- if (task.template) {
7929
- labels.push(task.template);
7941
+ const task = parsed.data;
7942
+ if (!task.id || !task.title) {
7943
+ return null;
7930
7944
  }
7931
7945
  return {
7932
- title,
7933
- body: sections.join("\n\n"),
7934
- labels: labels.length > 0 ? labels : void 0,
7935
- state: "closed"
7936
- };
7937
- }
7938
- function mapPriorityToLinear(priority) {
7939
- switch (priority) {
7940
- case "critical":
7941
- return 1;
7942
- case "high":
7943
- return 2;
7944
- case "medium":
7945
- return 3;
7946
- case "low":
7947
- return 4;
7948
- default:
7949
- return void 0;
7950
- }
7951
- }
7952
- function formatTaskForLinear(task, options = {}) {
7953
- const { includeMeta = true, includeSubtasks = true, includeRelatedFiles = true, resolvedBy, resolvedByPR, fromColumn, boardTitle, stateName = "Done", includeTaskId = false } = options;
7954
- const title = includeTaskId ? `[${task.id}] ${task.title}` : task.title;
7955
- const sections = [];
7956
- if (task.description) {
7957
- sections.push(task.description);
7958
- }
7959
- if (includeSubtasks && task.subtasks && task.subtasks.length > 0) {
7960
- sections.push(formatSubtasksMarkdown(task.subtasks));
7961
- }
7962
- if (includeMeta) {
7963
- const meta = formatMetadataSection(task, { fromColumn, boardTitle });
7964
- if (meta) {
7965
- sections.push(meta);
7966
- }
7967
- }
7968
- if (includeRelatedFiles && task.relatedFiles && task.relatedFiles.length > 0) {
7969
- sections.push(formatRelatedFilesSection(task.relatedFiles));
7970
- }
7971
- if (resolvedBy || resolvedByPR) {
7972
- sections.push(formatResolutionSection(resolvedBy, resolvedByPR));
7973
- }
7974
- sections.push("---\n*Archived from brainfile.md*");
7975
- return {
7976
- title,
7977
- description: sections.join("\n\n"),
7978
- priority: mapPriorityToLinear(task.priority),
7979
- labelNames: task.tags && task.tags.length > 0 ? task.tags : void 0,
7980
- stateName
7946
+ task,
7947
+ body: parsed.body
7981
7948
  };
7982
7949
  }
7983
- function formatSubtasksMarkdown(subtasks) {
7984
- const items = subtasks.map((st) => `- [${st.completed ? "x" : " "}] ${st.title}`);
7985
- return `## Subtasks
7986
-
7987
- ${items.join("\n")}`;
7988
- }
7989
- function formatMetadataSection(task, context) {
7990
- const lines = [];
7991
- if (context.boardTitle) {
7992
- lines.push(`**Board:** ${context.boardTitle}`);
7993
- }
7994
- if (context.fromColumn) {
7995
- lines.push(`**Column:** ${context.fromColumn}`);
7996
- }
7997
- if (task.priority) {
7998
- lines.push(`**Priority:** ${task.priority}`);
7999
- }
8000
- if (task.assignee) {
8001
- lines.push(`**Assignee:** ${task.assignee}`);
8002
- }
8003
- if (task.dueDate) {
8004
- lines.push(`**Due Date:** ${task.dueDate}`);
8005
- }
8006
- if (task.createdAt) {
8007
- lines.push(`**Created:** ${task.createdAt}`);
8008
- }
8009
- if (lines.length === 0) {
8010
- return null;
8011
- }
8012
- return `## Details
8013
-
8014
- ${lines.join("\n")}`;
8015
- }
8016
- function formatRelatedFilesSection(files) {
8017
- const items = files.map((f) => `- \`${f}\``);
8018
- return `## Related Files
8019
-
8020
- ${items.join("\n")}`;
8021
- }
8022
- function formatResolutionSection(resolvedBy, resolvedByPR) {
8023
- const lines = ["## Resolution"];
8024
- if (resolvedByPR) {
8025
- lines.push(`
8026
- **Pull Request:** ${resolvedByPR}`);
8027
- }
8028
- if (resolvedBy) {
8029
- lines.push(`
8030
- **Commit:** ${resolvedBy}`);
8031
- }
8032
- return lines.join("");
7950
+ function serializeTaskContent(task, body = "") {
7951
+ return (0, frontmatter_1.serializeFrontmatter)(task, body);
8033
7952
  }
8034
7953
  }
8035
7954
  });
8036
7955
 
8037
- // ../core/dist/frontmatter.js
8038
- var require_frontmatter = __commonJS({
8039
- "../core/dist/frontmatter.js"(exports) {
7956
+ // ../core/dist/taskFile.js
7957
+ var require_taskFile = __commonJS({
7958
+ "../core/dist/taskFile.js"(exports) {
8040
7959
  "use strict";
8041
7960
  var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
8042
7961
  if (k2 === void 0) k2 = k;
@@ -8076,89 +7995,89 @@ var require_frontmatter = __commonJS({
8076
7995
  };
8077
7996
  })();
8078
7997
  Object.defineProperty(exports, "__esModule", { value: true });
8079
- exports.parseFrontmatter = parseFrontmatter;
8080
- exports.serializeFrontmatter = serializeFrontmatter;
8081
- var yaml = __importStar(require_js_yaml());
8082
- function parseFrontmatter(content) {
8083
- const lines = content.split("\n");
8084
- if (!lines[0] || lines[0].trim() !== "---") {
8085
- return null;
7998
+ exports.serializeTaskContent = exports.parseTaskContent = void 0;
7999
+ exports.readTaskFile = readTaskFile;
8000
+ exports.writeTaskFile = writeTaskFile;
8001
+ exports.readTasksDir = readTasksDir;
8002
+ exports.taskFileName = taskFileName;
8003
+ var fs7 = __importStar(__require("fs"));
8004
+ var path7 = __importStar(__require("path"));
8005
+ var taskContent_1 = require_taskContent();
8006
+ var taskContent_2 = require_taskContent();
8007
+ Object.defineProperty(exports, "parseTaskContent", { enumerable: true, get: function() {
8008
+ return taskContent_2.parseTaskContent;
8009
+ } });
8010
+ Object.defineProperty(exports, "serializeTaskContent", { enumerable: true, get: function() {
8011
+ return taskContent_2.serializeTaskContent;
8012
+ } });
8013
+ function isUnsafeTaskId(taskId) {
8014
+ if (!taskId || taskId.trim() === "") {
8015
+ return true;
8086
8016
  }
8087
- let endIndex = -1;
8088
- for (let i = 1; i < lines.length; i++) {
8089
- if (lines[i].trim() === "---") {
8090
- endIndex = i;
8091
- break;
8092
- }
8017
+ const trimmed = taskId.trim();
8018
+ if (trimmed.includes("/") || trimmed.includes("\\") || trimmed.includes("..")) {
8019
+ return true;
8093
8020
  }
8094
- if (endIndex === -1) {
8095
- return null;
8021
+ if (path7.isAbsolute(trimmed)) {
8022
+ return true;
8096
8023
  }
8097
- const yamlContent = lines.slice(1, endIndex).join("\n");
8098
- const bodyContent = lines.slice(endIndex + 1).join("\n");
8099
- let parsed;
8024
+ return path7.basename(trimmed) !== trimmed;
8025
+ }
8026
+ function readTaskFile(filePath) {
8027
+ let content;
8100
8028
  try {
8101
- parsed = yaml.load(yamlContent);
8029
+ content = fs7.readFileSync(filePath, "utf-8");
8102
8030
  } catch {
8103
8031
  return null;
8104
8032
  }
8105
- if (!parsed || typeof parsed !== "object") {
8033
+ const parsed = (0, taskContent_1.parseTaskContent)(content);
8034
+ if (!parsed) {
8106
8035
  return null;
8107
8036
  }
8108
8037
  return {
8109
- data: parsed,
8110
- body: bodyContent.replace(/^\n/, "")
8038
+ task: parsed.task,
8039
+ body: parsed.body,
8040
+ filePath: path7.resolve(filePath)
8111
8041
  };
8112
8042
  }
8113
- function serializeFrontmatter(data, body = "") {
8114
- const yamlContent = yaml.dump(data, {
8115
- indent: 2,
8116
- lineWidth: -1,
8117
- noRefs: true,
8118
- sortKeys: false,
8119
- quotingType: '"',
8120
- forceQuotes: false
8121
- });
8122
- const parts = ["---\n", yamlContent, "---\n"];
8123
- if (body.length > 0) {
8124
- parts.push("\n");
8125
- parts.push(body);
8126
- if (!body.endsWith("\n")) {
8127
- parts.push("\n");
8043
+ function writeTaskFile(filePath, task, body = "") {
8044
+ const dir = path7.dirname(filePath);
8045
+ fs7.mkdirSync(dir, { recursive: true });
8046
+ const content = (0, taskContent_1.serializeTaskContent)(task, body);
8047
+ fs7.writeFileSync(filePath, content, "utf-8");
8048
+ }
8049
+ function readTasksDir(dirPath) {
8050
+ let entries;
8051
+ try {
8052
+ entries = fs7.readdirSync(dirPath, { withFileTypes: true });
8053
+ } catch {
8054
+ return [];
8055
+ }
8056
+ const docs = [];
8057
+ for (const entry of entries) {
8058
+ if (!entry.isFile() || !entry.name.endsWith(".md")) {
8059
+ continue;
8060
+ }
8061
+ const filePath = path7.join(dirPath, entry.name);
8062
+ const doc = readTaskFile(filePath);
8063
+ if (doc) {
8064
+ docs.push(doc);
8128
8065
  }
8129
8066
  }
8130
- return parts.join("");
8067
+ return docs;
8131
8068
  }
8132
- }
8133
- });
8134
-
8135
- // ../core/dist/boardContent.js
8136
- var require_boardContent = __commonJS({
8137
- "../core/dist/boardContent.js"(exports) {
8138
- "use strict";
8139
- Object.defineProperty(exports, "__esModule", { value: true });
8140
- exports.parseBoardConfig = parseBoardConfig;
8141
- exports.serializeBoardConfig = serializeBoardConfig;
8142
- var frontmatter_1 = require_frontmatter();
8143
- function parseBoardConfig(content) {
8144
- const parsed = (0, frontmatter_1.parseFrontmatter)(content);
8145
- if (!parsed) {
8146
- return null;
8069
+ function taskFileName(taskId) {
8070
+ if (isUnsafeTaskId(taskId)) {
8071
+ throw new Error(`Invalid task ID: ${taskId}`);
8147
8072
  }
8148
- return {
8149
- config: parsed.data,
8150
- body: parsed.body
8151
- };
8152
- }
8153
- function serializeBoardConfig(config, body = "") {
8154
- return (0, frontmatter_1.serializeFrontmatter)(config, body);
8073
+ return `${taskId.trim()}.md`;
8155
8074
  }
8156
8075
  }
8157
8076
  });
8158
8077
 
8159
- // ../core/dist/boardFile.js
8160
- var require_boardFile = __commonJS({
8161
- "../core/dist/boardFile.js"(exports) {
8078
+ // ../core/dist/ledger.js
8079
+ var require_ledger2 = __commonJS({
8080
+ "../core/dist/ledger.js"(exports) {
8162
8081
  "use strict";
8163
8082
  var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
8164
8083
  if (k2 === void 0) k2 = k;
@@ -8198,245 +8117,14 @@ var require_boardFile = __commonJS({
8198
8117
  };
8199
8118
  })();
8200
8119
  Object.defineProperty(exports, "__esModule", { value: true });
8201
- exports.serializeBoardConfig = exports.parseBoardConfig = void 0;
8202
- exports.readBoardConfig = readBoardConfig;
8203
- exports.writeBoardConfig = writeBoardConfig;
8204
- var fs7 = __importStar(__require("fs"));
8205
- var path7 = __importStar(__require("path"));
8206
- var boardContent_1 = require_boardContent();
8207
- var boardContent_2 = require_boardContent();
8208
- Object.defineProperty(exports, "parseBoardConfig", { enumerable: true, get: function() {
8209
- return boardContent_2.parseBoardConfig;
8210
- } });
8211
- Object.defineProperty(exports, "serializeBoardConfig", { enumerable: true, get: function() {
8212
- return boardContent_2.serializeBoardConfig;
8213
- } });
8214
- function readBoardConfig(filePath) {
8215
- let content;
8216
- try {
8217
- content = fs7.readFileSync(filePath, "utf-8");
8218
- } catch {
8219
- return null;
8220
- }
8221
- const parsed = (0, boardContent_1.parseBoardConfig)(content);
8222
- if (!parsed) {
8223
- return null;
8224
- }
8225
- return {
8226
- config: parsed.config,
8227
- body: parsed.body,
8228
- filePath: path7.resolve(filePath)
8229
- };
8230
- }
8231
- function writeBoardConfig(filePath, config, body = "") {
8232
- const dir = path7.dirname(filePath);
8233
- fs7.mkdirSync(dir, { recursive: true });
8234
- const content = (0, boardContent_1.serializeBoardConfig)(config, body);
8235
- fs7.writeFileSync(filePath, content, "utf-8");
8236
- }
8237
- }
8238
- });
8239
-
8240
- // ../core/dist/taskContent.js
8241
- var require_taskContent = __commonJS({
8242
- "../core/dist/taskContent.js"(exports) {
8243
- "use strict";
8244
- Object.defineProperty(exports, "__esModule", { value: true });
8245
- exports.parseTaskContent = parseTaskContent;
8246
- exports.serializeTaskContent = serializeTaskContent;
8247
- var frontmatter_1 = require_frontmatter();
8248
- function parseTaskContent(content) {
8249
- const parsed = (0, frontmatter_1.parseFrontmatter)(content);
8250
- if (!parsed) {
8251
- return null;
8252
- }
8253
- const task = parsed.data;
8254
- if (!task.id || !task.title) {
8255
- return null;
8256
- }
8257
- return {
8258
- task,
8259
- body: parsed.body
8260
- };
8261
- }
8262
- function serializeTaskContent(task, body = "") {
8263
- return (0, frontmatter_1.serializeFrontmatter)(task, body);
8264
- }
8265
- }
8266
- });
8267
-
8268
- // ../core/dist/taskFile.js
8269
- var require_taskFile = __commonJS({
8270
- "../core/dist/taskFile.js"(exports) {
8271
- "use strict";
8272
- var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
8273
- if (k2 === void 0) k2 = k;
8274
- var desc = Object.getOwnPropertyDescriptor(m, k);
8275
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8276
- desc = { enumerable: true, get: function() {
8277
- return m[k];
8278
- } };
8279
- }
8280
- Object.defineProperty(o, k2, desc);
8281
- }) : (function(o, m, k, k2) {
8282
- if (k2 === void 0) k2 = k;
8283
- o[k2] = m[k];
8284
- }));
8285
- var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
8286
- Object.defineProperty(o, "default", { enumerable: true, value: v });
8287
- }) : function(o, v) {
8288
- o["default"] = v;
8289
- });
8290
- var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
8291
- var ownKeys = function(o) {
8292
- ownKeys = Object.getOwnPropertyNames || function(o2) {
8293
- var ar = [];
8294
- for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
8295
- return ar;
8296
- };
8297
- return ownKeys(o);
8298
- };
8299
- return function(mod) {
8300
- if (mod && mod.__esModule) return mod;
8301
- var result = {};
8302
- if (mod != null) {
8303
- for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
8304
- }
8305
- __setModuleDefault(result, mod);
8306
- return result;
8307
- };
8308
- })();
8309
- Object.defineProperty(exports, "__esModule", { value: true });
8310
- exports.serializeTaskContent = exports.parseTaskContent = void 0;
8311
- exports.readTaskFile = readTaskFile;
8312
- exports.writeTaskFile = writeTaskFile;
8313
- exports.readTasksDir = readTasksDir;
8314
- exports.taskFileName = taskFileName;
8315
- var fs7 = __importStar(__require("fs"));
8316
- var path7 = __importStar(__require("path"));
8317
- var taskContent_1 = require_taskContent();
8318
- var taskContent_2 = require_taskContent();
8319
- Object.defineProperty(exports, "parseTaskContent", { enumerable: true, get: function() {
8320
- return taskContent_2.parseTaskContent;
8321
- } });
8322
- Object.defineProperty(exports, "serializeTaskContent", { enumerable: true, get: function() {
8323
- return taskContent_2.serializeTaskContent;
8324
- } });
8325
- function isUnsafeTaskId(taskId) {
8326
- if (!taskId || taskId.trim() === "") {
8327
- return true;
8328
- }
8329
- const trimmed = taskId.trim();
8330
- if (trimmed.includes("/") || trimmed.includes("\\") || trimmed.includes("..")) {
8331
- return true;
8332
- }
8333
- if (path7.isAbsolute(trimmed)) {
8334
- return true;
8335
- }
8336
- return path7.basename(trimmed) !== trimmed;
8337
- }
8338
- function readTaskFile(filePath) {
8339
- let content;
8340
- try {
8341
- content = fs7.readFileSync(filePath, "utf-8");
8342
- } catch {
8343
- return null;
8344
- }
8345
- const parsed = (0, taskContent_1.parseTaskContent)(content);
8346
- if (!parsed) {
8347
- return null;
8348
- }
8349
- return {
8350
- task: parsed.task,
8351
- body: parsed.body,
8352
- filePath: path7.resolve(filePath)
8353
- };
8354
- }
8355
- function writeTaskFile(filePath, task, body = "") {
8356
- const dir = path7.dirname(filePath);
8357
- fs7.mkdirSync(dir, { recursive: true });
8358
- const content = (0, taskContent_1.serializeTaskContent)(task, body);
8359
- fs7.writeFileSync(filePath, content, "utf-8");
8360
- }
8361
- function readTasksDir(dirPath) {
8362
- let entries;
8363
- try {
8364
- entries = fs7.readdirSync(dirPath, { withFileTypes: true });
8365
- } catch {
8366
- return [];
8367
- }
8368
- const docs = [];
8369
- for (const entry of entries) {
8370
- if (!entry.isFile() || !entry.name.endsWith(".md")) {
8371
- continue;
8372
- }
8373
- const filePath = path7.join(dirPath, entry.name);
8374
- const doc = readTaskFile(filePath);
8375
- if (doc) {
8376
- docs.push(doc);
8377
- }
8378
- }
8379
- return docs;
8380
- }
8381
- function taskFileName(taskId) {
8382
- if (isUnsafeTaskId(taskId)) {
8383
- throw new Error(`Invalid task ID: ${taskId}`);
8384
- }
8385
- return `${taskId.trim()}.md`;
8386
- }
8387
- }
8388
- });
8389
-
8390
- // ../core/dist/ledger.js
8391
- var require_ledger2 = __commonJS({
8392
- "../core/dist/ledger.js"(exports) {
8393
- "use strict";
8394
- var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
8395
- if (k2 === void 0) k2 = k;
8396
- var desc = Object.getOwnPropertyDescriptor(m, k);
8397
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8398
- desc = { enumerable: true, get: function() {
8399
- return m[k];
8400
- } };
8401
- }
8402
- Object.defineProperty(o, k2, desc);
8403
- }) : (function(o, m, k, k2) {
8404
- if (k2 === void 0) k2 = k;
8405
- o[k2] = m[k];
8406
- }));
8407
- var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
8408
- Object.defineProperty(o, "default", { enumerable: true, value: v });
8409
- }) : function(o, v) {
8410
- o["default"] = v;
8411
- });
8412
- var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
8413
- var ownKeys = function(o) {
8414
- ownKeys = Object.getOwnPropertyNames || function(o2) {
8415
- var ar = [];
8416
- for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
8417
- return ar;
8418
- };
8419
- return ownKeys(o);
8420
- };
8421
- return function(mod) {
8422
- if (mod && mod.__esModule) return mod;
8423
- var result = {};
8424
- if (mod != null) {
8425
- for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
8426
- }
8427
- __setModuleDefault(result, mod);
8428
- return result;
8429
- };
8430
- })();
8431
- Object.defineProperty(exports, "__esModule", { value: true });
8432
- exports.normalizePathValue = normalizePathValue;
8433
- exports.isLedgerContractStatus = isLedgerContractStatus;
8434
- exports.buildLedgerRecord = buildLedgerRecord;
8435
- exports.appendLedgerRecord = appendLedgerRecord;
8436
- exports.readLedger = readLedger;
8437
- exports.queryLedger = queryLedger;
8438
- exports.getFileHistory = getFileHistory;
8439
- exports.getTaskContext = getTaskContext;
8120
+ exports.normalizePathValue = normalizePathValue;
8121
+ exports.isLedgerContractStatus = isLedgerContractStatus;
8122
+ exports.buildLedgerRecord = buildLedgerRecord;
8123
+ exports.appendLedgerRecord = appendLedgerRecord;
8124
+ exports.readLedger = readLedger;
8125
+ exports.queryLedger = queryLedger;
8126
+ exports.getFileHistory = getFileHistory;
8127
+ exports.getTaskContext = getTaskContext;
8440
8128
  var fs7 = __importStar(__require("fs"));
8441
8129
  var path7 = __importStar(__require("path"));
8442
8130
  var taskFile_1 = require_taskFile();
@@ -8710,127 +8398,1001 @@ var require_ledger2 = __commonJS({
8710
8398
  if (columnHistory.length > 0) {
8711
8399
  record.columnHistory = columnHistory;
8712
8400
  }
8713
- if (task.assignee) {
8714
- record.assignee = task.assignee;
8401
+ if (task.assignee) {
8402
+ record.assignee = task.assignee;
8403
+ }
8404
+ if (task.priority) {
8405
+ record.priority = task.priority;
8406
+ }
8407
+ if (tags.length > 0) {
8408
+ record.tags = tags;
8409
+ }
8410
+ if (task.parentId) {
8411
+ record.parentId = task.parentId;
8412
+ }
8413
+ if (relatedFiles.length > 0) {
8414
+ record.relatedFiles = relatedFiles;
8415
+ }
8416
+ if (deliverables.length > 0) {
8417
+ record.deliverables = deliverables;
8418
+ }
8419
+ if (contractStatus) {
8420
+ record.contractStatus = contractStatus;
8421
+ }
8422
+ if (validationAttempts !== void 0) {
8423
+ record.validationAttempts = validationAttempts;
8424
+ }
8425
+ if (constraints.length > 0) {
8426
+ record.constraints = constraints;
8427
+ }
8428
+ if (subtaskCounts.hasSubtasks) {
8429
+ record.subtasksCompleted = subtaskCounts.completed;
8430
+ record.subtasksTotal = subtaskCounts.total;
8431
+ }
8432
+ const dependsOn = toUniqueStrings(task.dependsOn);
8433
+ if (dependsOn.length > 0) {
8434
+ record.dependsOn = dependsOn;
8435
+ }
8436
+ return record;
8437
+ }
8438
+ function appendLedgerRecord(logsDir, record) {
8439
+ fs7.mkdirSync(logsDir, { recursive: true });
8440
+ const ledgerPath = getLedgerPath(logsDir);
8441
+ fs7.appendFileSync(ledgerPath, `${JSON.stringify(record)}
8442
+ `, "utf-8");
8443
+ return ledgerPath;
8444
+ }
8445
+ function readLedger(logsDir) {
8446
+ const ledgerPath = getLedgerPath(logsDir);
8447
+ if (!fs7.existsSync(ledgerPath)) {
8448
+ return readLegacyMarkdownLedger(logsDir);
8449
+ }
8450
+ const content = fs7.readFileSync(ledgerPath, "utf-8");
8451
+ const lines = content.split("\n");
8452
+ const records = [];
8453
+ for (let index = 0; index < lines.length; index++) {
8454
+ const line = lines[index].trim();
8455
+ if (!line) {
8456
+ continue;
8457
+ }
8458
+ const parsed = parseLedgerLine(line, index + 1, ledgerPath);
8459
+ if (parsed) {
8460
+ records.push(parsed);
8461
+ }
8462
+ }
8463
+ return records;
8464
+ }
8465
+ function queryLedger(logsDir, filters = {}) {
8466
+ const all = readLedger(logsDir);
8467
+ const queryTags = filters.tags?.length ? filters.tags.map((t) => t.toLowerCase()) : null;
8468
+ const statusSet = filters.contractStatus ? new Set(Array.isArray(filters.contractStatus) ? filters.contractStatus : [filters.contractStatus]) : null;
8469
+ const queryFiles = filters.files?.length ? toUniquePaths(filters.files) : null;
8470
+ return all.filter((record) => {
8471
+ if (filters.assignee && record.assignee !== filters.assignee)
8472
+ return false;
8473
+ if (queryTags) {
8474
+ const tags = (record.tags || []).map((t) => t.toLowerCase());
8475
+ if (!queryTags.some((t) => tags.includes(t)))
8476
+ return false;
8477
+ }
8478
+ if (filters.dateRange && !matchesDateRange(record.completedAt, filters.dateRange))
8479
+ return false;
8480
+ if (statusSet && (!record.contractStatus || !statusSet.has(record.contractStatus)))
8481
+ return false;
8482
+ if (queryFiles) {
8483
+ const recordFiles = collectRecordFiles(record);
8484
+ if (!queryFiles.some((qf) => recordFiles.some((rf) => pathMatches(rf, qf))))
8485
+ return false;
8486
+ }
8487
+ return true;
8488
+ });
8489
+ }
8490
+ function getFileHistory(logsDir, filePath, options = {}) {
8491
+ const normalizedTarget = normalizePathValue(filePath);
8492
+ if (!normalizedTarget) {
8493
+ return [];
8494
+ }
8495
+ let records = readLedger(logsDir).filter((record) => (record.filesChanged || []).some((changedFile) => pathMatches(changedFile, normalizedTarget)));
8496
+ if (options.dateRange) {
8497
+ records = records.filter((record) => matchesDateRange(record.completedAt, options.dateRange));
8498
+ }
8499
+ records.sort((a, b) => timestampOr(b.completedAt, 0) - timestampOr(a.completedAt, 0));
8500
+ if (options.limit !== void 0 && options.limit > 0) {
8501
+ return records.slice(0, options.limit);
8502
+ }
8503
+ return records;
8504
+ }
8505
+ function getTaskContext(logsDir, relatedFiles, deliverables, options = {}) {
8506
+ const scopeFiles = toUniquePaths([
8507
+ ...relatedFiles,
8508
+ ...collectDeliverableInputPaths(deliverables)
8509
+ ]);
8510
+ if (scopeFiles.length === 0) {
8511
+ return [];
8512
+ }
8513
+ let entries = readLedger(logsDir).filter((record) => matchesDateRange(record.completedAt, options.dateRange)).map((record) => {
8514
+ const matchedFiles = matchedFilesForScope(scopeFiles, collectRecordFiles(record));
8515
+ return { record, matchedFiles };
8516
+ }).filter((entry) => entry.matchedFiles.length > 0);
8517
+ entries.sort((a, b) => timestampOr(b.record.completedAt, 0) - timestampOr(a.record.completedAt, 0));
8518
+ if (options.limit !== void 0 && options.limit > 0) {
8519
+ entries = entries.slice(0, options.limit);
8520
+ }
8521
+ return entries;
8522
+ }
8523
+ }
8524
+ });
8525
+
8526
+ // ../core/dist/workspace.js
8527
+ var require_workspace = __commonJS({
8528
+ "../core/dist/workspace.js"(exports) {
8529
+ "use strict";
8530
+ var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
8531
+ if (k2 === void 0) k2 = k;
8532
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8533
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8534
+ desc = { enumerable: true, get: function() {
8535
+ return m[k];
8536
+ } };
8537
+ }
8538
+ Object.defineProperty(o, k2, desc);
8539
+ }) : (function(o, m, k, k2) {
8540
+ if (k2 === void 0) k2 = k;
8541
+ o[k2] = m[k];
8542
+ }));
8543
+ var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
8544
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
8545
+ }) : function(o, v) {
8546
+ o["default"] = v;
8547
+ });
8548
+ var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
8549
+ var ownKeys = function(o) {
8550
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
8551
+ var ar = [];
8552
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
8553
+ return ar;
8554
+ };
8555
+ return ownKeys(o);
8556
+ };
8557
+ return function(mod) {
8558
+ if (mod && mod.__esModule) return mod;
8559
+ var result = {};
8560
+ if (mod != null) {
8561
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
8562
+ }
8563
+ __setModuleDefault(result, mod);
8564
+ return result;
8565
+ };
8566
+ })();
8567
+ Object.defineProperty(exports, "__esModule", { value: true });
8568
+ exports.getV2Dirs = getV2Dirs2;
8569
+ exports.isV2 = isV25;
8570
+ exports.ensureV2Dirs = ensureV2Dirs2;
8571
+ exports.getTaskFilePath = getTaskFilePath2;
8572
+ exports.getLogFilePath = getLogFilePath2;
8573
+ exports.findV2Task = findV2Task2;
8574
+ exports.extractDescription = extractDescription2;
8575
+ exports.extractLog = extractLog2;
8576
+ exports.composeBody = composeBody2;
8577
+ exports.readV2BoardConfig = readV2BoardConfig2;
8578
+ exports.buildBoardFromV2 = buildBoardFromV22;
8579
+ var fs7 = __importStar(__require("fs"));
8580
+ var path7 = __importStar(__require("path"));
8581
+ var parser_1 = require_parser();
8582
+ var taskFile_1 = require_taskFile();
8583
+ function getV2Dirs2(brainfilePath) {
8584
+ const resolvedPath = path7.resolve(brainfilePath);
8585
+ const dotDir = path7.dirname(resolvedPath);
8586
+ return {
8587
+ dotDir,
8588
+ boardDir: path7.join(dotDir, "board"),
8589
+ logsDir: path7.join(dotDir, "logs"),
8590
+ brainfilePath: resolvedPath
8591
+ };
8592
+ }
8593
+ function isV25(brainfilePath) {
8594
+ const { boardDir } = getV2Dirs2(brainfilePath);
8595
+ return fs7.existsSync(boardDir);
8596
+ }
8597
+ function ensureV2Dirs2(brainfilePath) {
8598
+ const dirs = getV2Dirs2(brainfilePath);
8599
+ fs7.mkdirSync(dirs.boardDir, { recursive: true });
8600
+ fs7.mkdirSync(dirs.logsDir, { recursive: true });
8601
+ return dirs;
8602
+ }
8603
+ function getTaskFilePath2(boardDir, taskId) {
8604
+ return path7.join(boardDir, (0, taskFile_1.taskFileName)(taskId));
8605
+ }
8606
+ function getLogFilePath2(logsDir, taskId) {
8607
+ return path7.join(logsDir, (0, taskFile_1.taskFileName)(taskId));
8608
+ }
8609
+ function findV2Task2(dirs, taskId, searchLogs = false) {
8610
+ const taskPath = getTaskFilePath2(dirs.boardDir, taskId);
8611
+ const taskDoc = (0, taskFile_1.readTaskFile)(taskPath);
8612
+ if (taskDoc && taskDoc.task.id === taskId) {
8613
+ return { doc: taskDoc, filePath: taskPath, isLog: false };
8614
+ }
8615
+ if (searchLogs) {
8616
+ const logPath = getLogFilePath2(dirs.logsDir, taskId);
8617
+ const logDoc = (0, taskFile_1.readTaskFile)(logPath);
8618
+ if (logDoc && logDoc.task.id === taskId) {
8619
+ return { doc: logDoc, filePath: logPath, isLog: true };
8620
+ }
8621
+ }
8622
+ const boardDocs = (0, taskFile_1.readTasksDir)(dirs.boardDir);
8623
+ const boardMatch = boardDocs.find((d) => d.task.id === taskId);
8624
+ if (boardMatch) {
8625
+ return {
8626
+ doc: boardMatch,
8627
+ filePath: boardMatch.filePath || taskPath,
8628
+ isLog: false
8629
+ };
8630
+ }
8631
+ if (searchLogs) {
8632
+ const logDocs = (0, taskFile_1.readTasksDir)(dirs.logsDir);
8633
+ const logMatch = logDocs.find((d) => d.task.id === taskId);
8634
+ if (logMatch) {
8635
+ return {
8636
+ doc: logMatch,
8637
+ filePath: logMatch.filePath || getLogFilePath2(dirs.logsDir, taskId),
8638
+ isLog: true
8639
+ };
8640
+ }
8641
+ }
8642
+ return null;
8643
+ }
8644
+ function extractDescription2(body) {
8645
+ const match = body.match(/## Description\n([\s\S]*?)(?=\n## |\n*$)/);
8646
+ return match ? match[1].trim() || void 0 : void 0;
8647
+ }
8648
+ function extractLog2(body) {
8649
+ const match = body.match(/## Log\n([\s\S]*?)(?=\n## |\n*$)/);
8650
+ return match ? match[1].trim() || void 0 : void 0;
8651
+ }
8652
+ function composeBody2(description, log) {
8653
+ const sections = [];
8654
+ if (description && description.trim()) {
8655
+ sections.push(`## Description
8656
+ ${description.trim()}`);
8657
+ }
8658
+ if (log && log.trim()) {
8659
+ sections.push(`## Log
8660
+ ${log.trim()}`);
8661
+ }
8662
+ if (sections.length === 0)
8663
+ return "";
8664
+ return `${sections.join("\n\n")}
8665
+ `;
8666
+ }
8667
+ function readV2BoardConfig2(brainfilePath) {
8668
+ const content = fs7.readFileSync(brainfilePath, "utf-8");
8669
+ const result = parser_1.BrainfileParser.parseWithErrors(content);
8670
+ if (!result.board) {
8671
+ throw new Error(`Failed to parse brainfile: ${result.error}`);
8672
+ }
8673
+ const board = result.board;
8674
+ for (const col of board.columns) {
8675
+ if (!col.tasks)
8676
+ col.tasks = [];
8677
+ }
8678
+ return board;
8679
+ }
8680
+ function buildBoardFromV22(brainfilePath) {
8681
+ const dirs = getV2Dirs2(brainfilePath);
8682
+ const board = readV2BoardConfig2(brainfilePath);
8683
+ const taskDocs = (0, taskFile_1.readTasksDir)(dirs.boardDir);
8684
+ const tasksByColumn = /* @__PURE__ */ new Map();
8685
+ for (const doc of taskDocs) {
8686
+ const colId = doc.task.column || "todo";
8687
+ if (!tasksByColumn.has(colId)) {
8688
+ tasksByColumn.set(colId, []);
8689
+ }
8690
+ tasksByColumn.get(colId).push(doc);
8691
+ }
8692
+ for (const col of board.columns) {
8693
+ const colTasks = tasksByColumn.get(col.id) || [];
8694
+ colTasks.sort((a, b) => {
8695
+ const posA = a.task.position ?? Number.MAX_SAFE_INTEGER;
8696
+ const posB = b.task.position ?? Number.MAX_SAFE_INTEGER;
8697
+ if (posA !== posB)
8698
+ return posA - posB;
8699
+ return a.task.id.localeCompare(b.task.id);
8700
+ });
8701
+ col.tasks = colTasks.map((doc) => {
8702
+ const task = { ...doc.task };
8703
+ if (!task.description) {
8704
+ const description = extractDescription2(doc.body);
8705
+ if (description)
8706
+ task.description = description;
8707
+ }
8708
+ return task;
8709
+ });
8710
+ }
8711
+ return board;
8712
+ }
8713
+ }
8714
+ });
8715
+
8716
+ // ../core/dist/brief.js
8717
+ var require_brief = __commonJS({
8718
+ "../core/dist/brief.js"(exports) {
8719
+ "use strict";
8720
+ var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
8721
+ if (k2 === void 0) k2 = k;
8722
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8723
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8724
+ desc = { enumerable: true, get: function() {
8725
+ return m[k];
8726
+ } };
8727
+ }
8728
+ Object.defineProperty(o, k2, desc);
8729
+ }) : (function(o, m, k, k2) {
8730
+ if (k2 === void 0) k2 = k;
8731
+ o[k2] = m[k];
8732
+ }));
8733
+ var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
8734
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
8735
+ }) : function(o, v) {
8736
+ o["default"] = v;
8737
+ });
8738
+ var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
8739
+ var ownKeys = function(o) {
8740
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
8741
+ var ar = [];
8742
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
8743
+ return ar;
8744
+ };
8745
+ return ownKeys(o);
8746
+ };
8747
+ return function(mod) {
8748
+ if (mod && mod.__esModule) return mod;
8749
+ var result = {};
8750
+ if (mod != null) {
8751
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
8752
+ }
8753
+ __setModuleDefault(result, mod);
8754
+ return result;
8755
+ };
8756
+ })();
8757
+ Object.defineProperty(exports, "__esModule", { value: true });
8758
+ exports.parseNoteLine = parseNoteLine;
8759
+ exports.parseNotes = parseNotes;
8760
+ exports.relativeTime = relativeTime;
8761
+ exports.buildBrief = buildBrief;
8762
+ exports.isEmptyBrief = isEmptyBrief;
8763
+ var fs7 = __importStar(__require("fs"));
8764
+ var taskFile_1 = require_taskFile();
8765
+ var ledger_1 = require_ledger2();
8766
+ var workspace_1 = require_workspace();
8767
+ var FULL_MODE_COMPLETION_LIMIT = 10;
8768
+ var ISO_TIMESTAMP_SHAPE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
8769
+ function parseNoteLine(line) {
8770
+ const match = /^-\s+(\S+)/.exec(line);
8771
+ if (!match)
8772
+ return null;
8773
+ let token = match[1];
8774
+ if (token.endsWith(":"))
8775
+ token = token.slice(0, -1);
8776
+ if (!ISO_TIMESTAMP_SHAPE.test(token))
8777
+ return null;
8778
+ const parsed = Date.parse(token);
8779
+ if (Number.isNaN(parsed))
8780
+ return null;
8781
+ let rest = line.slice(match[0].length);
8782
+ let agent;
8783
+ const takeBracket = () => {
8784
+ const bracket = /^\s*\[([^\]]+)\]/.exec(rest);
8785
+ if (bracket) {
8786
+ agent = bracket[1].trim() || void 0;
8787
+ rest = rest.slice(bracket[0].length);
8788
+ }
8789
+ };
8790
+ takeBracket();
8791
+ rest = rest.replace(/^\s*:/, "");
8792
+ if (!agent)
8793
+ takeBracket();
8794
+ return {
8795
+ at: new Date(parsed).toISOString(),
8796
+ text: rest.trim(),
8797
+ agent
8798
+ };
8799
+ }
8800
+ function parseNotes(body) {
8801
+ const log = (0, workspace_1.extractLog)(body);
8802
+ if (!log)
8803
+ return [];
8804
+ const notes = [];
8805
+ for (const line of log.split("\n")) {
8806
+ const parsed = parseNoteLine(line);
8807
+ if (parsed)
8808
+ notes.push(parsed);
8809
+ }
8810
+ return notes.sort((a, b) => Date.parse(b.at) - Date.parse(a.at));
8811
+ }
8812
+ function lastRawLogLine(body) {
8813
+ const log = (0, workspace_1.extractLog)(body);
8814
+ if (!log)
8815
+ return null;
8816
+ const lines = log.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
8817
+ if (lines.length === 0)
8818
+ return null;
8819
+ return lines[lines.length - 1].replace(/^-\s+/, "");
8820
+ }
8821
+ function parseMs(value) {
8822
+ if (!value)
8823
+ return null;
8824
+ const ms = Date.parse(value);
8825
+ return Number.isNaN(ms) ? null : ms;
8826
+ }
8827
+ function isAssignedTo(assignee, agentName) {
8828
+ if (!assignee)
8829
+ return false;
8830
+ return assignee.trim().toLowerCase() === agentName.trim().toLowerCase();
8831
+ }
8832
+ function relativeTime(from, to) {
8833
+ const fromMs = parseMs(from);
8834
+ const toMs = parseMs(to);
8835
+ if (fromMs === null || toMs === null)
8836
+ return "unknown";
8837
+ const deltaSec = Math.max(0, Math.round((toMs - fromMs) / 1e3));
8838
+ if (deltaSec < 60)
8839
+ return "just now";
8840
+ const min = Math.floor(deltaSec / 60);
8841
+ if (min < 60)
8842
+ return `${min}m`;
8843
+ const hours = Math.floor(min / 60);
8844
+ if (hours < 24)
8845
+ return `${hours}h`;
8846
+ const days = Math.floor(hours / 24);
8847
+ return `${days}d`;
8848
+ }
8849
+ function agoPhrase(from, to) {
8850
+ const rel = relativeTime(from, to);
8851
+ return rel === "just now" || rel === "unknown" ? rel : `${rel} ago`;
8852
+ }
8853
+ function taskStateWhy(task) {
8854
+ const parts = [task.column || "unknown"];
8855
+ if (task.priority)
8856
+ parts.push(task.priority);
8857
+ if (task.contract?.status)
8858
+ parts.push(`contract:${task.contract.status}`);
8859
+ return parts.join(" \xB7 ");
8860
+ }
8861
+ function completionWhy(record) {
8862
+ const cycle = typeof record.cycleTimeHours === "number" ? `${record.cycleTimeHours}h cycle` : "cycle unknown";
8863
+ return `completed \xB7 ${cycle}`;
8864
+ }
8865
+ function boardMtimeMs(brainfilePath) {
8866
+ try {
8867
+ return fs7.statSync(brainfilePath).mtimeMs;
8868
+ } catch {
8869
+ return null;
8870
+ }
8871
+ }
8872
+ function completionsFor(dirs, agentName, lastBriefAtMs) {
8873
+ let records;
8874
+ try {
8875
+ records = (0, ledger_1.queryLedger)(dirs.logsDir, {});
8876
+ } catch {
8877
+ return [];
8878
+ }
8879
+ const matching = records.filter((record) => {
8880
+ if (!isAssignedTo(record.assignee, agentName))
8881
+ return false;
8882
+ if (lastBriefAtMs === null)
8883
+ return true;
8884
+ const completedMs = parseMs(record.completedAt);
8885
+ return completedMs !== null && completedMs > lastBriefAtMs;
8886
+ });
8887
+ return matching.sort((a, b) => (parseMs(b.completedAt) ?? 0) - (parseMs(a.completedAt) ?? 0));
8888
+ }
8889
+ function readBoardConfig(brainfilePath) {
8890
+ try {
8891
+ return (0, workspace_1.readV2BoardConfig)(brainfilePath);
8892
+ } catch {
8893
+ return null;
8894
+ }
8895
+ }
8896
+ function buildBrief(dirs, agentName, opts) {
8897
+ const generatedAt = opts.now ?? (/* @__PURE__ */ new Date()).toISOString();
8898
+ const lastBriefAt = opts.lastBriefAt;
8899
+ const lastBriefAtMs = parseMs(lastBriefAt);
8900
+ const mode = lastBriefAtMs === null ? "full" : "delta";
8901
+ const assigned = (0, taskFile_1.readTasksDir)(dirs.boardDir).filter((doc) => isAssignedTo(doc.task.assignee, agentName));
8902
+ const lanes = mode === "full" ? fullLanes(dirs, agentName, assigned, generatedAt) : deltaLanes(dirs, agentName, assigned, generatedAt, lastBriefAtMs);
8903
+ return {
8904
+ agent: agentName,
8905
+ mode,
8906
+ generatedAt,
8907
+ // Normalize away an unparseable stored checkpoint rather than echoing it.
8908
+ lastBriefAt: lastBriefAtMs === null ? null : lastBriefAt,
8909
+ lanes
8910
+ };
8911
+ }
8912
+ function sortAssigned(docs) {
8913
+ return [...docs].sort((a, b) => {
8914
+ const aMs = parseMs(a.task.updatedAt) ?? parseMs(a.task.createdAt) ?? 0;
8915
+ const bMs = parseMs(b.task.updatedAt) ?? parseMs(b.task.createdAt) ?? 0;
8916
+ return bMs - aMs;
8917
+ });
8918
+ }
8919
+ function acceptedAdrs(dirs) {
8920
+ const ACCEPTED = /* @__PURE__ */ new Set(["accepted", "promoted"]);
8921
+ const docs = [];
8922
+ for (const dir of [dirs.boardDir, dirs.logsDir]) {
8923
+ let entries;
8924
+ try {
8925
+ entries = (0, taskFile_1.readTasksDir)(dir);
8926
+ } catch {
8927
+ continue;
8928
+ }
8929
+ for (const doc of entries) {
8930
+ const task = doc.task;
8931
+ if ((task.type || "").toLowerCase() !== "adr")
8932
+ continue;
8933
+ if (!ACCEPTED.has((task.status || "").toLowerCase()))
8934
+ continue;
8935
+ docs.push(doc);
8936
+ }
8937
+ }
8938
+ return docs.sort((a, b) => a.task.id.localeCompare(b.task.id, void 0, { numeric: true }));
8939
+ }
8940
+ function fullLanes(dirs, agentName, assigned, generatedAt) {
8941
+ const orientation = [];
8942
+ const board = readBoardConfig(dirs.brainfilePath);
8943
+ if (board?.title) {
8944
+ orientation.push({ text: board.title, why: "board" });
8945
+ }
8946
+ for (const instruction of board?.agent?.instructions ?? []) {
8947
+ orientation.push({ text: instruction, why: "agent instructions" });
8948
+ }
8949
+ for (const doc of acceptedAdrs(dirs)) {
8950
+ orientation.push({ taskId: doc.task.id, text: doc.task.title, why: "accepted adr" });
8951
+ }
8952
+ const assignedItems = sortAssigned(assigned).map((doc) => ({
8953
+ taskId: doc.task.id,
8954
+ text: doc.task.title,
8955
+ why: taskStateWhy(doc.task),
8956
+ ...doc.task.updatedAt ? { at: doc.task.updatedAt } : {}
8957
+ }));
8958
+ const noteItems = [];
8959
+ for (const doc of assigned) {
8960
+ const notes = parseNotes(doc.body);
8961
+ if (notes.length > 0) {
8962
+ const latest = notes[0];
8963
+ noteItems.push({
8964
+ taskId: doc.task.id,
8965
+ text: latest.text,
8966
+ why: `logged ${agoPhrase(latest.at, generatedAt)}`,
8967
+ at: latest.at
8968
+ });
8969
+ continue;
8970
+ }
8971
+ const raw = lastRawLogLine(doc.body);
8972
+ if (raw) {
8973
+ noteItems.push({ taskId: doc.task.id, text: raw, why: "unstamped entry" });
8974
+ }
8975
+ }
8976
+ noteItems.sort((a, b) => (parseMs(b.at) ?? 0) - (parseMs(a.at) ?? 0));
8977
+ const completionItems = completionsFor(dirs, agentName, null).slice(0, FULL_MODE_COMPLETION_LIMIT).map((record) => ({
8978
+ taskId: record.id,
8979
+ text: record.title,
8980
+ why: completionWhy(record),
8981
+ at: record.completedAt
8982
+ }));
8983
+ return [
8984
+ { id: "orientation", label: "Board & Decisions", items: orientation },
8985
+ { id: "assigned", label: "Your Tasks", items: assignedItems },
8986
+ { id: "notes", label: "Latest Notes", items: noteItems },
8987
+ { id: "completions", label: "Recently Completed (yours)", items: completionItems }
8988
+ ];
8989
+ }
8990
+ function deltaLanes(dirs, agentName, assigned, generatedAt, lastBriefAtMs) {
8991
+ const noteItems = [];
8992
+ for (const doc of assigned) {
8993
+ for (const note of parseNotes(doc.body)) {
8994
+ const noteMs = parseMs(note.at);
8995
+ if (noteMs === null || noteMs <= lastBriefAtMs)
8996
+ continue;
8997
+ noteItems.push({
8998
+ taskId: doc.task.id,
8999
+ text: note.agent ? `[${note.agent}] ${note.text}` : note.text,
9000
+ why: agoPhrase(note.at, generatedAt),
9001
+ at: note.at
9002
+ });
9003
+ }
9004
+ }
9005
+ noteItems.sort((a, b) => (parseMs(b.at) ?? 0) - (parseMs(a.at) ?? 0));
9006
+ const changeItems = [];
9007
+ for (const doc of sortAssigned(assigned)) {
9008
+ const createdMs = parseMs(doc.task.createdAt);
9009
+ const updatedMs = parseMs(doc.task.updatedAt);
9010
+ const isNew = createdMs !== null && createdMs > lastBriefAtMs;
9011
+ const isUpdated = updatedMs !== null && updatedMs > lastBriefAtMs;
9012
+ if (!isNew && !isUpdated)
9013
+ continue;
9014
+ const stamp = isNew ? doc.task.createdAt : doc.task.updatedAt;
9015
+ const verb = isNew ? "created" : "updated";
9016
+ changeItems.push({
9017
+ taskId: doc.task.id,
9018
+ text: doc.task.title,
9019
+ why: `${verb} ${agoPhrase(stamp, generatedAt)} \xB7 ${taskStateWhy(doc.task)}`,
9020
+ ...stamp ? { at: stamp } : {}
9021
+ });
9022
+ }
9023
+ const completionItems = completionsFor(dirs, agentName, lastBriefAtMs).map((record) => ({
9024
+ taskId: record.id,
9025
+ text: record.title,
9026
+ why: completionWhy(record),
9027
+ at: record.completedAt
9028
+ }));
9029
+ const configItems = [];
9030
+ const mtime = boardMtimeMs(dirs.brainfilePath);
9031
+ if (mtime !== null && mtime > lastBriefAtMs) {
9032
+ const at = new Date(mtime).toISOString();
9033
+ configItems.push({
9034
+ text: "Board config changed",
9035
+ why: "brainfile.md changed since last brief",
9036
+ at
9037
+ });
9038
+ }
9039
+ return [
9040
+ { id: "notes", label: "New Notes", items: noteItems },
9041
+ { id: "changes", label: "Task Changes", items: changeItems },
9042
+ { id: "completions", label: "Completed Since Last Brief", items: completionItems },
9043
+ { id: "config", label: "Board Config", items: configItems }
9044
+ ];
9045
+ }
9046
+ function isEmptyBrief(result) {
9047
+ return result.lanes.every((lane) => lane.items.length === 0);
9048
+ }
9049
+ }
9050
+ });
9051
+
9052
+ // ../core/dist/briefState.js
9053
+ var require_briefState = __commonJS({
9054
+ "../core/dist/briefState.js"(exports) {
9055
+ "use strict";
9056
+ var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
9057
+ if (k2 === void 0) k2 = k;
9058
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9059
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9060
+ desc = { enumerable: true, get: function() {
9061
+ return m[k];
9062
+ } };
9063
+ }
9064
+ Object.defineProperty(o, k2, desc);
9065
+ }) : (function(o, m, k, k2) {
9066
+ if (k2 === void 0) k2 = k;
9067
+ o[k2] = m[k];
9068
+ }));
9069
+ var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
9070
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
9071
+ }) : function(o, v) {
9072
+ o["default"] = v;
9073
+ });
9074
+ var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
9075
+ var ownKeys = function(o) {
9076
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
9077
+ var ar = [];
9078
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
9079
+ return ar;
9080
+ };
9081
+ return ownKeys(o);
9082
+ };
9083
+ return function(mod) {
9084
+ if (mod && mod.__esModule) return mod;
9085
+ var result = {};
9086
+ if (mod != null) {
9087
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
9088
+ }
9089
+ __setModuleDefault(result, mod);
9090
+ return result;
9091
+ };
9092
+ })();
9093
+ Object.defineProperty(exports, "__esModule", { value: true });
9094
+ exports.BRIEF_STATE_VERSION = void 0;
9095
+ exports.sanitizeAgentFilename = sanitizeAgentFilename;
9096
+ exports.getBriefStateDir = getBriefStateDir;
9097
+ exports.getBriefStatePath = getBriefStatePath;
9098
+ exports.readBriefState = readBriefState;
9099
+ exports.writeBriefState = writeBriefState;
9100
+ var fs7 = __importStar(__require("fs"));
9101
+ var path7 = __importStar(__require("path"));
9102
+ var files_1 = require_files();
9103
+ exports.BRIEF_STATE_VERSION = 1;
9104
+ function sanitizeAgentFilename(agentName) {
9105
+ const trimmed = agentName.trim().toLowerCase();
9106
+ let cleaned = "";
9107
+ for (const ch of trimmed) {
9108
+ if (/[a-z0-9._-]/.test(ch)) {
9109
+ cleaned += ch;
9110
+ } else {
9111
+ cleaned += `_${ch.charCodeAt(0).toString(16).padStart(2, "0")}`;
9112
+ }
9113
+ }
9114
+ if (cleaned.length === 0 || cleaned === "." || cleaned === "..")
9115
+ return "_";
9116
+ return cleaned;
9117
+ }
9118
+ function getBriefStateDir(brainfilePath) {
9119
+ return path7.join((0, files_1.getBrainfileStateDir)(brainfilePath), files_1.DOT_BRAINFILE_STATE_DIRNAME);
9120
+ }
9121
+ function getBriefStatePath(brainfilePath, agentName) {
9122
+ return path7.join(getBriefStateDir(brainfilePath), `${sanitizeAgentFilename(agentName)}.json`);
9123
+ }
9124
+ function readBriefState(brainfilePath, agentName) {
9125
+ const statePath = getBriefStatePath(brainfilePath, agentName);
9126
+ const fallback = { version: exports.BRIEF_STATE_VERSION, agent: agentName, lastBriefAt: null };
9127
+ if (!fs7.existsSync(statePath))
9128
+ return fallback;
9129
+ try {
9130
+ const parsed = JSON.parse(fs7.readFileSync(statePath, "utf-8"));
9131
+ const lastBriefAt = typeof parsed.lastBriefAt === "string" ? parsed.lastBriefAt : null;
9132
+ return {
9133
+ version: typeof parsed.version === "number" ? parsed.version : exports.BRIEF_STATE_VERSION,
9134
+ agent: typeof parsed.agent === "string" ? parsed.agent : agentName,
9135
+ lastBriefAt
9136
+ };
9137
+ } catch {
9138
+ console.warn(`Warning: unreadable brief state at ${statePath}; treating as first brief`);
9139
+ return fallback;
9140
+ }
9141
+ }
9142
+ function writeBriefState(brainfilePath, agentName, lastBriefAt) {
9143
+ (0, files_1.ensureDotBrainfileGitignore)(brainfilePath);
9144
+ const state = { version: exports.BRIEF_STATE_VERSION, agent: agentName, lastBriefAt };
9145
+ (0, files_1.atomicWriteFileSync)(getBriefStatePath(brainfilePath, agentName), `${JSON.stringify(state, null, 2)}
9146
+ `);
9147
+ return state;
9148
+ }
9149
+ }
9150
+ });
9151
+
9152
+ // ../core/dist/formatters.js
9153
+ var require_formatters = __commonJS({
9154
+ "../core/dist/formatters.js"(exports) {
9155
+ "use strict";
9156
+ Object.defineProperty(exports, "__esModule", { value: true });
9157
+ exports.formatTaskForGitHub = formatTaskForGitHub;
9158
+ exports.formatTaskForLinear = formatTaskForLinear;
9159
+ function formatTaskForGitHub(task, options = {}) {
9160
+ const { includeMeta = true, includeSubtasks = true, includeRelatedFiles = true, resolvedBy, resolvedByPR, fromColumn, boardTitle, extraLabels = [], includeTaskId = true } = options;
9161
+ const title = includeTaskId ? `[${task.id}] ${task.title}` : task.title;
9162
+ const sections = [];
9163
+ if (task.description) {
9164
+ sections.push(task.description);
9165
+ }
9166
+ if (includeSubtasks && task.subtasks && task.subtasks.length > 0) {
9167
+ sections.push(formatSubtasksMarkdown(task.subtasks));
9168
+ }
9169
+ if (includeMeta) {
9170
+ const meta = formatMetadataSection(task, { fromColumn, boardTitle });
9171
+ if (meta) {
9172
+ sections.push(meta);
9173
+ }
9174
+ }
9175
+ if (includeRelatedFiles && task.relatedFiles && task.relatedFiles.length > 0) {
9176
+ sections.push(formatRelatedFilesSection(task.relatedFiles));
9177
+ }
9178
+ if (resolvedBy || resolvedByPR) {
9179
+ sections.push(formatResolutionSection(resolvedBy, resolvedByPR));
9180
+ }
9181
+ sections.push("---\n*Archived from brainfile.md*");
9182
+ const labels = [...task.tags || [], ...extraLabels];
9183
+ if (task.priority) {
9184
+ labels.push(`priority:${task.priority}`);
9185
+ }
9186
+ if (task.template) {
9187
+ labels.push(task.template);
9188
+ }
9189
+ return {
9190
+ title,
9191
+ body: sections.join("\n\n"),
9192
+ labels: labels.length > 0 ? labels : void 0,
9193
+ state: "closed"
9194
+ };
9195
+ }
9196
+ function mapPriorityToLinear(priority) {
9197
+ switch (priority) {
9198
+ case "critical":
9199
+ return 1;
9200
+ case "high":
9201
+ return 2;
9202
+ case "medium":
9203
+ return 3;
9204
+ case "low":
9205
+ return 4;
9206
+ default:
9207
+ return void 0;
9208
+ }
9209
+ }
9210
+ function formatTaskForLinear(task, options = {}) {
9211
+ const { includeMeta = true, includeSubtasks = true, includeRelatedFiles = true, resolvedBy, resolvedByPR, fromColumn, boardTitle, stateName = "Done", includeTaskId = false } = options;
9212
+ const title = includeTaskId ? `[${task.id}] ${task.title}` : task.title;
9213
+ const sections = [];
9214
+ if (task.description) {
9215
+ sections.push(task.description);
9216
+ }
9217
+ if (includeSubtasks && task.subtasks && task.subtasks.length > 0) {
9218
+ sections.push(formatSubtasksMarkdown(task.subtasks));
9219
+ }
9220
+ if (includeMeta) {
9221
+ const meta = formatMetadataSection(task, { fromColumn, boardTitle });
9222
+ if (meta) {
9223
+ sections.push(meta);
9224
+ }
9225
+ }
9226
+ if (includeRelatedFiles && task.relatedFiles && task.relatedFiles.length > 0) {
9227
+ sections.push(formatRelatedFilesSection(task.relatedFiles));
9228
+ }
9229
+ if (resolvedBy || resolvedByPR) {
9230
+ sections.push(formatResolutionSection(resolvedBy, resolvedByPR));
9231
+ }
9232
+ sections.push("---\n*Archived from brainfile.md*");
9233
+ return {
9234
+ title,
9235
+ description: sections.join("\n\n"),
9236
+ priority: mapPriorityToLinear(task.priority),
9237
+ labelNames: task.tags && task.tags.length > 0 ? task.tags : void 0,
9238
+ stateName
9239
+ };
9240
+ }
9241
+ function formatSubtasksMarkdown(subtasks) {
9242
+ const items = subtasks.map((st) => `- [${st.completed ? "x" : " "}] ${st.title}`);
9243
+ return `## Subtasks
9244
+
9245
+ ${items.join("\n")}`;
9246
+ }
9247
+ function formatMetadataSection(task, context) {
9248
+ const lines = [];
9249
+ if (context.boardTitle) {
9250
+ lines.push(`**Board:** ${context.boardTitle}`);
9251
+ }
9252
+ if (context.fromColumn) {
9253
+ lines.push(`**Column:** ${context.fromColumn}`);
8715
9254
  }
8716
9255
  if (task.priority) {
8717
- record.priority = task.priority;
8718
- }
8719
- if (tags.length > 0) {
8720
- record.tags = tags;
8721
- }
8722
- if (task.parentId) {
8723
- record.parentId = task.parentId;
8724
- }
8725
- if (relatedFiles.length > 0) {
8726
- record.relatedFiles = relatedFiles;
8727
- }
8728
- if (deliverables.length > 0) {
8729
- record.deliverables = deliverables;
8730
- }
8731
- if (contractStatus) {
8732
- record.contractStatus = contractStatus;
9256
+ lines.push(`**Priority:** ${task.priority}`);
8733
9257
  }
8734
- if (validationAttempts !== void 0) {
8735
- record.validationAttempts = validationAttempts;
9258
+ if (task.assignee) {
9259
+ lines.push(`**Assignee:** ${task.assignee}`);
8736
9260
  }
8737
- if (constraints.length > 0) {
8738
- record.constraints = constraints;
9261
+ if (task.dueDate) {
9262
+ lines.push(`**Due Date:** ${task.dueDate}`);
8739
9263
  }
8740
- if (subtaskCounts.hasSubtasks) {
8741
- record.subtasksCompleted = subtaskCounts.completed;
8742
- record.subtasksTotal = subtaskCounts.total;
9264
+ if (task.createdAt) {
9265
+ lines.push(`**Created:** ${task.createdAt}`);
8743
9266
  }
8744
- const dependsOn = toUniqueStrings(task.dependsOn);
8745
- if (dependsOn.length > 0) {
8746
- record.dependsOn = dependsOn;
9267
+ if (lines.length === 0) {
9268
+ return null;
8747
9269
  }
8748
- return record;
9270
+ return `## Details
9271
+
9272
+ ${lines.join("\n")}`;
8749
9273
  }
8750
- function appendLedgerRecord(logsDir, record) {
8751
- fs7.mkdirSync(logsDir, { recursive: true });
8752
- const ledgerPath = getLedgerPath(logsDir);
8753
- fs7.appendFileSync(ledgerPath, `${JSON.stringify(record)}
8754
- `, "utf-8");
8755
- return ledgerPath;
9274
+ function formatRelatedFilesSection(files) {
9275
+ const items = files.map((f) => `- \`${f}\``);
9276
+ return `## Related Files
9277
+
9278
+ ${items.join("\n")}`;
8756
9279
  }
8757
- function readLedger(logsDir) {
8758
- const ledgerPath = getLedgerPath(logsDir);
8759
- if (!fs7.existsSync(ledgerPath)) {
8760
- return readLegacyMarkdownLedger(logsDir);
9280
+ function formatResolutionSection(resolvedBy, resolvedByPR) {
9281
+ const lines = ["## Resolution"];
9282
+ if (resolvedByPR) {
9283
+ lines.push(`
9284
+ **Pull Request:** ${resolvedByPR}`);
8761
9285
  }
8762
- const content = fs7.readFileSync(ledgerPath, "utf-8");
8763
- const lines = content.split("\n");
8764
- const records = [];
8765
- for (let index = 0; index < lines.length; index++) {
8766
- const line = lines[index].trim();
8767
- if (!line) {
8768
- continue;
8769
- }
8770
- const parsed = parseLedgerLine(line, index + 1, ledgerPath);
8771
- if (parsed) {
8772
- records.push(parsed);
8773
- }
9286
+ if (resolvedBy) {
9287
+ lines.push(`
9288
+ **Commit:** ${resolvedBy}`);
8774
9289
  }
8775
- return records;
9290
+ return lines.join("");
8776
9291
  }
8777
- function queryLedger(logsDir, filters = {}) {
8778
- const all = readLedger(logsDir);
8779
- const queryTags = filters.tags?.length ? filters.tags.map((t) => t.toLowerCase()) : null;
8780
- const statusSet = filters.contractStatus ? new Set(Array.isArray(filters.contractStatus) ? filters.contractStatus : [filters.contractStatus]) : null;
8781
- const queryFiles = filters.files?.length ? toUniquePaths(filters.files) : null;
8782
- return all.filter((record) => {
8783
- if (filters.assignee && record.assignee !== filters.assignee)
8784
- return false;
8785
- if (queryTags) {
8786
- const tags = (record.tags || []).map((t) => t.toLowerCase());
8787
- if (!queryTags.some((t) => tags.includes(t)))
8788
- return false;
8789
- }
8790
- if (filters.dateRange && !matchesDateRange(record.completedAt, filters.dateRange))
8791
- return false;
8792
- if (statusSet && (!record.contractStatus || !statusSet.has(record.contractStatus)))
8793
- return false;
8794
- if (queryFiles) {
8795
- const recordFiles = collectRecordFiles(record);
8796
- if (!queryFiles.some((qf) => recordFiles.some((rf) => pathMatches(rf, qf))))
8797
- return false;
8798
- }
8799
- return true;
8800
- });
9292
+ }
9293
+ });
9294
+
9295
+ // ../core/dist/boardContent.js
9296
+ var require_boardContent = __commonJS({
9297
+ "../core/dist/boardContent.js"(exports) {
9298
+ "use strict";
9299
+ Object.defineProperty(exports, "__esModule", { value: true });
9300
+ exports.parseBoardConfig = parseBoardConfig;
9301
+ exports.serializeBoardConfig = serializeBoardConfig;
9302
+ var frontmatter_1 = require_frontmatter();
9303
+ function parseBoardConfig(content) {
9304
+ const parsed = (0, frontmatter_1.parseFrontmatter)(content);
9305
+ if (!parsed) {
9306
+ return null;
9307
+ }
9308
+ return {
9309
+ config: parsed.data,
9310
+ body: parsed.body
9311
+ };
8801
9312
  }
8802
- function getFileHistory(logsDir, filePath, options = {}) {
8803
- const normalizedTarget = normalizePathValue(filePath);
8804
- if (!normalizedTarget) {
8805
- return [];
9313
+ function serializeBoardConfig(config, body = "") {
9314
+ return (0, frontmatter_1.serializeFrontmatter)(config, body);
9315
+ }
9316
+ }
9317
+ });
9318
+
9319
+ // ../core/dist/boardFile.js
9320
+ var require_boardFile = __commonJS({
9321
+ "../core/dist/boardFile.js"(exports) {
9322
+ "use strict";
9323
+ var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
9324
+ if (k2 === void 0) k2 = k;
9325
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9326
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9327
+ desc = { enumerable: true, get: function() {
9328
+ return m[k];
9329
+ } };
8806
9330
  }
8807
- let records = readLedger(logsDir).filter((record) => (record.filesChanged || []).some((changedFile) => pathMatches(changedFile, normalizedTarget)));
8808
- if (options.dateRange) {
8809
- records = records.filter((record) => matchesDateRange(record.completedAt, options.dateRange));
9331
+ Object.defineProperty(o, k2, desc);
9332
+ }) : (function(o, m, k, k2) {
9333
+ if (k2 === void 0) k2 = k;
9334
+ o[k2] = m[k];
9335
+ }));
9336
+ var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
9337
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
9338
+ }) : function(o, v) {
9339
+ o["default"] = v;
9340
+ });
9341
+ var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
9342
+ var ownKeys = function(o) {
9343
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
9344
+ var ar = [];
9345
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
9346
+ return ar;
9347
+ };
9348
+ return ownKeys(o);
9349
+ };
9350
+ return function(mod) {
9351
+ if (mod && mod.__esModule) return mod;
9352
+ var result = {};
9353
+ if (mod != null) {
9354
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
9355
+ }
9356
+ __setModuleDefault(result, mod);
9357
+ return result;
9358
+ };
9359
+ })();
9360
+ Object.defineProperty(exports, "__esModule", { value: true });
9361
+ exports.serializeBoardConfig = exports.parseBoardConfig = void 0;
9362
+ exports.readBoardConfig = readBoardConfig;
9363
+ exports.writeBoardConfig = writeBoardConfig;
9364
+ var fs7 = __importStar(__require("fs"));
9365
+ var path7 = __importStar(__require("path"));
9366
+ var boardContent_1 = require_boardContent();
9367
+ var boardContent_2 = require_boardContent();
9368
+ Object.defineProperty(exports, "parseBoardConfig", { enumerable: true, get: function() {
9369
+ return boardContent_2.parseBoardConfig;
9370
+ } });
9371
+ Object.defineProperty(exports, "serializeBoardConfig", { enumerable: true, get: function() {
9372
+ return boardContent_2.serializeBoardConfig;
9373
+ } });
9374
+ function readBoardConfig(filePath) {
9375
+ let content;
9376
+ try {
9377
+ content = fs7.readFileSync(filePath, "utf-8");
9378
+ } catch {
9379
+ return null;
8810
9380
  }
8811
- records.sort((a, b) => timestampOr(b.completedAt, 0) - timestampOr(a.completedAt, 0));
8812
- if (options.limit !== void 0 && options.limit > 0) {
8813
- return records.slice(0, options.limit);
9381
+ const parsed = (0, boardContent_1.parseBoardConfig)(content);
9382
+ if (!parsed) {
9383
+ return null;
8814
9384
  }
8815
- return records;
9385
+ return {
9386
+ config: parsed.config,
9387
+ body: parsed.body,
9388
+ filePath: path7.resolve(filePath)
9389
+ };
8816
9390
  }
8817
- function getTaskContext(logsDir, relatedFiles, deliverables, options = {}) {
8818
- const scopeFiles = toUniquePaths([
8819
- ...relatedFiles,
8820
- ...collectDeliverableInputPaths(deliverables)
8821
- ]);
8822
- if (scopeFiles.length === 0) {
8823
- return [];
8824
- }
8825
- let entries = readLedger(logsDir).filter((record) => matchesDateRange(record.completedAt, options.dateRange)).map((record) => {
8826
- const matchedFiles = matchedFilesForScope(scopeFiles, collectRecordFiles(record));
8827
- return { record, matchedFiles };
8828
- }).filter((entry) => entry.matchedFiles.length > 0);
8829
- entries.sort((a, b) => timestampOr(b.record.completedAt, 0) - timestampOr(a.record.completedAt, 0));
8830
- if (options.limit !== void 0 && options.limit > 0) {
8831
- entries = entries.slice(0, options.limit);
8832
- }
8833
- return entries;
9391
+ function writeBoardConfig(filePath, config, body = "") {
9392
+ const dir = path7.dirname(filePath);
9393
+ fs7.mkdirSync(dir, { recursive: true });
9394
+ const content = (0, boardContent_1.serializeBoardConfig)(config, body);
9395
+ fs7.writeFileSync(filePath, content, "utf-8");
8834
9396
  }
8835
9397
  }
8836
9398
  });
@@ -9018,40 +9580,17 @@ ${section}
9018
9580
  try {
9019
9581
  const stat = fs7.statSync(ledgerPath);
9020
9582
  const newSize = stat.size - appendedBytes;
9021
- if (newSize >= 0) {
9022
- fs7.truncateSync(ledgerPath, newSize);
9023
- }
9024
- } catch {
9025
- }
9026
- }
9027
- function completeTaskFileLegacy(taskPath, logsDir, doc, completedTask, childStates) {
9028
- const baseName = path7.basename(taskPath);
9029
- const destPath = path7.join(logsDir, baseName);
9030
- let completedBody = doc.body;
9031
- if (doc.task.type === "epic") {
9032
- const childTasksSection = buildChildTasksSection(childStates ?? []);
9033
- completedBody = appendBodySection(doc.body, childTasksSection);
9034
- }
9035
- if (fs7.existsSync(destPath)) {
9036
- return { success: false, error: `Task already exists in logs: ${doc.task.id}` };
9037
- }
9038
- try {
9039
- fs7.mkdirSync(logsDir, { recursive: true });
9040
- writeTaskFileExclusive(destPath, completedTask, completedBody);
9041
- } catch (err) {
9042
- return { success: false, error: `Failed to complete task: ${err}` };
9043
- }
9044
- try {
9045
- fs7.unlinkSync(taskPath);
9046
- return { success: true, task: completedTask, filePath: destPath };
9047
- } catch (err) {
9048
- try {
9049
- fs7.unlinkSync(destPath);
9050
- } catch {
9583
+ if (newSize >= 0) {
9584
+ fs7.truncateSync(ledgerPath, newSize);
9051
9585
  }
9052
- return { success: false, error: `Failed to finalize completion: ${err}` };
9586
+ } catch {
9053
9587
  }
9054
9588
  }
9589
+ function archivedBody(doc, childStates) {
9590
+ if (doc.task.type !== "epic")
9591
+ return doc.body;
9592
+ return appendBodySection(doc.body, buildChildTasksSection(childStates ?? []));
9593
+ }
9055
9594
  function generateNextFileTaskId(boardDir, logsDir, typePrefix = "task") {
9056
9595
  let maxNum = 0;
9057
9596
  const escaped = typePrefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -9198,7 +9737,7 @@ ${section}
9198
9737
  if (!shouldAutoComplete) {
9199
9738
  return { success: true, task, filePath, column: resolvedColumn };
9200
9739
  }
9201
- const completeResult = completeTaskFile(filePath, dirs.logsDir, { legacyMode: true });
9740
+ const completeResult = completeTaskFile(filePath, dirs.logsDir);
9202
9741
  if (!completeResult.success || !completeResult.task) {
9203
9742
  return {
9204
9743
  success: false,
@@ -9415,32 +9954,43 @@ ${section}
9415
9954
  completedAt: now,
9416
9955
  updatedAt: now
9417
9956
  };
9418
- if (options.legacyMode) {
9419
- const legacyResult = completeTaskFileLegacy(taskPath, logsDir, doc, completedTask, childStates);
9420
- return incompleteChildren && legacyResult.success ? { ...legacyResult, incompleteChildren } : legacyResult;
9957
+ const destPath = path7.join(logsDir, path7.basename(taskPath));
9958
+ if (fs7.existsSync(destPath)) {
9959
+ return { success: false, error: `Task already exists in logs: ${doc.task.id}` };
9421
9960
  }
9422
- const record = (0, ledger_2.buildLedgerRecord)(completedTask, doc.body, {
9961
+ const completedBody = archivedBody(doc, childStates);
9962
+ const record = (0, ledger_2.buildLedgerRecord)(completedTask, completedBody, {
9423
9963
  summary: options.summary,
9424
9964
  filesChanged: options.filesChanged,
9425
9965
  completedAt: now,
9426
9966
  columnHistory: options.columnHistory,
9427
9967
  validationAttempts: options.validationAttempts
9428
9968
  });
9429
- let ledgerPath;
9430
9969
  try {
9431
- ledgerPath = (0, ledger_2.appendLedgerRecord)(logsDir, record);
9970
+ (0, ledger_2.appendLedgerRecord)(logsDir, record);
9432
9971
  } catch (err) {
9433
9972
  return { success: false, error: `Failed to append ledger record: ${err}` };
9434
9973
  }
9974
+ try {
9975
+ fs7.mkdirSync(logsDir, { recursive: true });
9976
+ writeTaskFileExclusive(destPath, completedTask, completedBody);
9977
+ } catch (err) {
9978
+ rollbackLedgerAppend(logsDir, record);
9979
+ return { success: false, error: `Failed to complete task: ${err}` };
9980
+ }
9435
9981
  try {
9436
9982
  fs7.unlinkSync(taskPath);
9437
9983
  return {
9438
9984
  success: true,
9439
9985
  task: completedTask,
9440
- filePath: ledgerPath,
9986
+ filePath: destPath,
9441
9987
  ...incompleteChildren && { incompleteChildren }
9442
9988
  };
9443
9989
  } catch (err) {
9990
+ try {
9991
+ fs7.unlinkSync(destPath);
9992
+ } catch {
9993
+ }
9444
9994
  rollbackLedgerAppend(logsDir, record);
9445
9995
  return { success: false, error: `Failed to finalize completion: ${err}` };
9446
9996
  }
@@ -9775,196 +10325,6 @@ ${section}
9775
10325
  }
9776
10326
  });
9777
10327
 
9778
- // ../core/dist/workspace.js
9779
- var require_workspace = __commonJS({
9780
- "../core/dist/workspace.js"(exports) {
9781
- "use strict";
9782
- var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
9783
- if (k2 === void 0) k2 = k;
9784
- var desc = Object.getOwnPropertyDescriptor(m, k);
9785
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9786
- desc = { enumerable: true, get: function() {
9787
- return m[k];
9788
- } };
9789
- }
9790
- Object.defineProperty(o, k2, desc);
9791
- }) : (function(o, m, k, k2) {
9792
- if (k2 === void 0) k2 = k;
9793
- o[k2] = m[k];
9794
- }));
9795
- var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
9796
- Object.defineProperty(o, "default", { enumerable: true, value: v });
9797
- }) : function(o, v) {
9798
- o["default"] = v;
9799
- });
9800
- var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
9801
- var ownKeys = function(o) {
9802
- ownKeys = Object.getOwnPropertyNames || function(o2) {
9803
- var ar = [];
9804
- for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
9805
- return ar;
9806
- };
9807
- return ownKeys(o);
9808
- };
9809
- return function(mod) {
9810
- if (mod && mod.__esModule) return mod;
9811
- var result = {};
9812
- if (mod != null) {
9813
- for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
9814
- }
9815
- __setModuleDefault(result, mod);
9816
- return result;
9817
- };
9818
- })();
9819
- Object.defineProperty(exports, "__esModule", { value: true });
9820
- exports.getV2Dirs = getV2Dirs2;
9821
- exports.isV2 = isV25;
9822
- exports.ensureV2Dirs = ensureV2Dirs2;
9823
- exports.getTaskFilePath = getTaskFilePath2;
9824
- exports.getLogFilePath = getLogFilePath2;
9825
- exports.findV2Task = findV2Task2;
9826
- exports.extractDescription = extractDescription2;
9827
- exports.extractLog = extractLog2;
9828
- exports.composeBody = composeBody2;
9829
- exports.readV2BoardConfig = readV2BoardConfig2;
9830
- exports.buildBoardFromV2 = buildBoardFromV22;
9831
- var fs7 = __importStar(__require("fs"));
9832
- var path7 = __importStar(__require("path"));
9833
- var parser_1 = require_parser();
9834
- var taskFile_1 = require_taskFile();
9835
- function getV2Dirs2(brainfilePath) {
9836
- const resolvedPath = path7.resolve(brainfilePath);
9837
- const dotDir = path7.dirname(resolvedPath);
9838
- return {
9839
- dotDir,
9840
- boardDir: path7.join(dotDir, "board"),
9841
- logsDir: path7.join(dotDir, "logs"),
9842
- brainfilePath: resolvedPath
9843
- };
9844
- }
9845
- function isV25(brainfilePath) {
9846
- const { boardDir } = getV2Dirs2(brainfilePath);
9847
- return fs7.existsSync(boardDir);
9848
- }
9849
- function ensureV2Dirs2(brainfilePath) {
9850
- const dirs = getV2Dirs2(brainfilePath);
9851
- fs7.mkdirSync(dirs.boardDir, { recursive: true });
9852
- fs7.mkdirSync(dirs.logsDir, { recursive: true });
9853
- return dirs;
9854
- }
9855
- function getTaskFilePath2(boardDir, taskId) {
9856
- return path7.join(boardDir, (0, taskFile_1.taskFileName)(taskId));
9857
- }
9858
- function getLogFilePath2(logsDir, taskId) {
9859
- return path7.join(logsDir, (0, taskFile_1.taskFileName)(taskId));
9860
- }
9861
- function findV2Task2(dirs, taskId, searchLogs = false) {
9862
- const taskPath = getTaskFilePath2(dirs.boardDir, taskId);
9863
- const taskDoc = (0, taskFile_1.readTaskFile)(taskPath);
9864
- if (taskDoc && taskDoc.task.id === taskId) {
9865
- return { doc: taskDoc, filePath: taskPath, isLog: false };
9866
- }
9867
- if (searchLogs) {
9868
- const logPath = getLogFilePath2(dirs.logsDir, taskId);
9869
- const logDoc = (0, taskFile_1.readTaskFile)(logPath);
9870
- if (logDoc && logDoc.task.id === taskId) {
9871
- return { doc: logDoc, filePath: logPath, isLog: true };
9872
- }
9873
- }
9874
- const boardDocs = (0, taskFile_1.readTasksDir)(dirs.boardDir);
9875
- const boardMatch = boardDocs.find((d) => d.task.id === taskId);
9876
- if (boardMatch) {
9877
- return {
9878
- doc: boardMatch,
9879
- filePath: boardMatch.filePath || taskPath,
9880
- isLog: false
9881
- };
9882
- }
9883
- if (searchLogs) {
9884
- const logDocs = (0, taskFile_1.readTasksDir)(dirs.logsDir);
9885
- const logMatch = logDocs.find((d) => d.task.id === taskId);
9886
- if (logMatch) {
9887
- return {
9888
- doc: logMatch,
9889
- filePath: logMatch.filePath || getLogFilePath2(dirs.logsDir, taskId),
9890
- isLog: true
9891
- };
9892
- }
9893
- }
9894
- return null;
9895
- }
9896
- function extractDescription2(body) {
9897
- const match = body.match(/## Description\n([\s\S]*?)(?=\n## |\n*$)/);
9898
- return match ? match[1].trim() || void 0 : void 0;
9899
- }
9900
- function extractLog2(body) {
9901
- const match = body.match(/## Log\n([\s\S]*?)(?=\n## |\n*$)/);
9902
- return match ? match[1].trim() || void 0 : void 0;
9903
- }
9904
- function composeBody2(description, log) {
9905
- const sections = [];
9906
- if (description && description.trim()) {
9907
- sections.push(`## Description
9908
- ${description.trim()}`);
9909
- }
9910
- if (log && log.trim()) {
9911
- sections.push(`## Log
9912
- ${log.trim()}`);
9913
- }
9914
- if (sections.length === 0)
9915
- return "";
9916
- return `${sections.join("\n\n")}
9917
- `;
9918
- }
9919
- function readV2BoardConfig2(brainfilePath) {
9920
- const content = fs7.readFileSync(brainfilePath, "utf-8");
9921
- const result = parser_1.BrainfileParser.parseWithErrors(content);
9922
- if (!result.board) {
9923
- throw new Error(`Failed to parse brainfile: ${result.error}`);
9924
- }
9925
- const board = result.board;
9926
- for (const col of board.columns) {
9927
- if (!col.tasks)
9928
- col.tasks = [];
9929
- }
9930
- return board;
9931
- }
9932
- function buildBoardFromV22(brainfilePath) {
9933
- const dirs = getV2Dirs2(brainfilePath);
9934
- const board = readV2BoardConfig2(brainfilePath);
9935
- const taskDocs = (0, taskFile_1.readTasksDir)(dirs.boardDir);
9936
- const tasksByColumn = /* @__PURE__ */ new Map();
9937
- for (const doc of taskDocs) {
9938
- const colId = doc.task.column || "todo";
9939
- if (!tasksByColumn.has(colId)) {
9940
- tasksByColumn.set(colId, []);
9941
- }
9942
- tasksByColumn.get(colId).push(doc);
9943
- }
9944
- for (const col of board.columns) {
9945
- const colTasks = tasksByColumn.get(col.id) || [];
9946
- colTasks.sort((a, b) => {
9947
- const posA = a.task.position ?? Number.MAX_SAFE_INTEGER;
9948
- const posB = b.task.position ?? Number.MAX_SAFE_INTEGER;
9949
- if (posA !== posB)
9950
- return posA - posB;
9951
- return a.task.id.localeCompare(b.task.id);
9952
- });
9953
- col.tasks = colTasks.map((doc) => {
9954
- const task = { ...doc.task };
9955
- if (!task.description) {
9956
- const description = extractDescription2(doc.body);
9957
- if (description)
9958
- task.description = description;
9959
- }
9960
- return task;
9961
- });
9962
- }
9963
- return board;
9964
- }
9965
- }
9966
- });
9967
-
9968
10328
  // ../core/dist/search.js
9969
10329
  var require_search = __commonJS({
9970
10330
  "../core/dist/search.js"(exports) {
@@ -10310,9 +10670,9 @@ var require_dist = __commonJS({
10310
10670
  };
10311
10671
  Object.defineProperty(exports, "__esModule", { value: true });
10312
10672
  exports.archiveTasks = exports.deleteTasks = exports.patchTasks = exports.moveTasks = exports.setAllSubtasksCompleted = exports.setSubtasksCompleted = exports.updateSubtask = exports.deleteSubtask = exports.addSubtask = exports.patchTask = exports.restoreTask = exports.archiveTask = exports.updateStatsConfig = exports.updateBoardTitle = exports.toggleSubtask = exports.deleteTask = exports.updateTask = exports.addTask = exports.moveTask = exports.getAllTemplateIds = exports.getTemplateById = exports.processTemplate = exports.generateSubtaskId = exports.generateTaskId = exports.BUILT_IN_TEMPLATES = exports.hashBoardContent = exports.hashBoard = exports.diffBoards = exports.BrainfileLinter = exports.BrainfileValidator = exports.BrainfileSerializer = exports.loadSchemaHints = exports.parseSchemaHints = exports.inferRenderer = exports.inferType = exports.BrainfileParser = exports.buildContract = exports.parseDeliverableSpec = exports.normalizeToArray = exports.ALLOWED_DELIVERABLE_TYPES = exports.removeTaskContractConstraint = exports.addTaskContractConstraint = exports.removeTaskContractValidationCommand = exports.addTaskContractValidationCommand = exports.removeTaskContractDeliverable = exports.addTaskContractDeliverable = exports.patchTaskContract = exports.setTaskContractStatus = exports.clearTaskContract = exports.setTaskContract = void 0;
10313
- exports.BRAINFILE_STATE_BASENAME = exports.BRAINFILE_BASENAME = exports.DOT_BRAINFILE_DIRNAME = exports.ensureDotBrainfileGitignore = exports.ensureDotBrainfileDir = exports.getDotBrainfileGitignorePath = exports.getBrainfileStatePath = exports.getBrainfileStateDir = exports.resolveBrainfilePath = exports.findBrainfile = exports.EXCLUDE_DIRS = exports.BRAINFILE_GLOBS = exports.BRAINFILE_PATTERNS = exports.extractBrainfileSuffix = exports.isBrainfileName = exports.watchBrainfiles = exports.findNearestBrainfile = exports.findPrimaryBrainfile = exports.discover = exports.getParentTaskId = exports.isValidSubtaskId = exports.isValidTaskId = exports.generateNextSubtaskId = exports.generateSubtaskIdFromIndex = exports.generateNextTaskId = exports.getMaxTaskIdNumber = exports.extractTaskIdNumber = exports.getOverdueTasks = exports.getIncompleteSubtasksSummary = exports.getTasksWithIncompleteSubtasks = exports.isCompletionColumn = exports.findCompletionColumn = exports.columnExists = exports.getTotalTaskCount = exports.getColumnTaskCount = exports.searchTasks = exports.getTasksByAssignee = exports.getTasksByPriority = exports.getTasksByTag = exports.getAllTasks = exports.taskIdExists = exports.findTaskById = exports.findColumnByName = exports.findColumnById = exports.validateColumn = exports.validateType = exports.isTypeCompletable = exports.getBoardTypes = exports.deleteRule = exports.addRule = void 0;
10314
- exports.isLedgerContractStatus = exports.normalizePathValue = exports.getTaskContext = exports.getFileHistory = exports.queryLedger = exports.readLedger = exports.appendLedgerRecord = exports.buildLedgerRecord = exports.searchTasksRanked = exports.scoreTaskDocument = exports.taskMatchesFilters = exports.parseSearchQuery = exports.getEffectiveState = exports.activateTaskContractsByParent = exports.activateTaskContract = exports.attachTaskContract = exports.failTaskContract = exports.completeTaskContract = exports.deliverTaskContract = exports.pickupTaskContract = exports.updateSubtasksInFile = exports.toggleSubtasksInFile = exports.deleteSubtasksFromFile = exports.addSubtasksToFile = exports.searchLogs = exports.searchTaskFiles = exports.findTask = exports.listTasks = exports.appendLog = exports.deleteTaskFile = exports.completeTaskFile = exports.patchTaskFile = exports.moveTaskFileToColumn = exports.moveTaskFile = exports.addTaskFile = exports.generateNextFileTaskId = exports.DEFAULT_CONTRACT_COLUMN_MAP = exports.taskFileName = exports.readTasksDir = exports.writeTaskFile = exports.readTaskFile = exports.serializeTaskContent = exports.parseTaskContent = exports.writeBoardConfig = exports.readBoardConfig = exports.serializeBoardConfig = exports.parseBoardConfig = exports.formatTaskForLinear = exports.formatTaskForGitHub = exports.DOT_BRAINFILE_GITIGNORE_BASENAME = void 0;
10315
- exports.Brainfile = exports.buildBoardFromV2 = exports.readV2BoardConfig = exports.composeBody = exports.extractLog = exports.extractDescription = exports.findV2Task = exports.getLogFilePath = exports.getTaskFilePath = exports.ensureV2Dirs = exports.isV2 = exports.getV2Dirs = exports.topologicalSort = exports.DependencyCycleError = exports.MissingDependencyError = exports.ledgerRecordToCompletedRef = exports.taskToCompletedRef = void 0;
10673
+ exports.DOT_BRAINFILE_GITIGNORE_BASENAME = exports.BRAINFILE_STATE_BASENAME = exports.BRAINFILE_BASENAME = exports.DOT_BRAINFILE_DIRNAME = exports.atomicWriteFileSync = exports.ensureDotBrainfileGitignore = exports.ensureDotBrainfileDir = exports.getDotBrainfileGitignorePath = exports.getBrainfileStatePath = exports.getBrainfileStateDir = exports.resolveBrainfilePath = exports.findBrainfile = exports.EXCLUDE_DIRS = exports.BRAINFILE_GLOBS = exports.BRAINFILE_PATTERNS = exports.extractBrainfileSuffix = exports.isBrainfileName = exports.watchBrainfiles = exports.findNearestBrainfile = exports.findPrimaryBrainfile = exports.discover = exports.getParentTaskId = exports.isValidSubtaskId = exports.isValidTaskId = exports.generateNextSubtaskId = exports.generateSubtaskIdFromIndex = exports.generateNextTaskId = exports.getMaxTaskIdNumber = exports.extractTaskIdNumber = exports.getOverdueTasks = exports.getIncompleteSubtasksSummary = exports.getTasksWithIncompleteSubtasks = exports.isCompletionColumn = exports.findCompletionColumn = exports.columnExists = exports.getTotalTaskCount = exports.getColumnTaskCount = exports.searchTasks = exports.getTasksByAssignee = exports.getTasksByPriority = exports.getTasksByTag = exports.getAllTasks = exports.taskIdExists = exports.findTaskById = exports.findColumnByName = exports.findColumnById = exports.validateColumn = exports.validateType = exports.isTypeCompletable = exports.getBoardTypes = void 0;
10674
+ exports.getEffectiveState = exports.activateTaskContractsByParent = exports.activateTaskContract = exports.attachTaskContract = exports.failTaskContract = exports.completeTaskContract = exports.deliverTaskContract = exports.pickupTaskContract = exports.updateSubtasksInFile = exports.toggleSubtasksInFile = exports.deleteSubtasksFromFile = exports.addSubtasksToFile = exports.searchLogs = exports.searchTaskFiles = exports.findTask = exports.listTasks = exports.appendLog = exports.deleteTaskFile = exports.completeTaskFile = exports.patchTaskFile = exports.moveTaskFileToColumn = exports.moveTaskFile = exports.addTaskFile = exports.generateNextFileTaskId = exports.DEFAULT_CONTRACT_COLUMN_MAP = exports.taskFileName = exports.readTasksDir = exports.writeTaskFile = exports.readTaskFile = exports.serializeTaskContent = exports.parseTaskContent = exports.writeBoardConfig = exports.readBoardConfig = exports.serializeBoardConfig = exports.parseBoardConfig = exports.formatTaskForLinear = exports.formatTaskForGitHub = exports.BRIEF_STATE_VERSION = exports.sanitizeAgentFilename = exports.getBriefStatePath = exports.getBriefStateDir = exports.writeBriefState = exports.readBriefState = exports.relativeTime = exports.parseNotes = exports.parseNoteLine = exports.isEmptyBrief = exports.buildBrief = exports.DOT_BRAINFILE_STATE_IGNORE_ENTRY = exports.DOT_BRAINFILE_STATE_DIRNAME = void 0;
10675
+ exports.Brainfile = exports.buildBoardFromV2 = exports.readV2BoardConfig = exports.composeBody = exports.extractLog = exports.extractDescription = exports.findV2Task = exports.getLogFilePath = exports.getTaskFilePath = exports.ensureV2Dirs = exports.isV2 = exports.getV2Dirs = exports.topologicalSort = exports.DependencyCycleError = exports.MissingDependencyError = exports.ledgerRecordToCompletedRef = exports.taskToCompletedRef = exports.isLedgerContractStatus = exports.normalizePathValue = exports.getTaskContext = exports.getFileHistory = exports.queryLedger = exports.readLedger = exports.appendLedgerRecord = exports.buildLedgerRecord = exports.searchTasksRanked = exports.scoreTaskDocument = exports.taskMatchesFilters = exports.parseSearchQuery = void 0;
10316
10676
  __exportStar(require_types2(), exports);
10317
10677
  __exportStar(require_contract(), exports);
10318
10678
  var contract_1 = require_contract2();
@@ -10476,12 +10836,6 @@ var require_dist = __commonJS({
10476
10836
  Object.defineProperty(exports, "archiveTasks", { enumerable: true, get: function() {
10477
10837
  return operations_1.archiveTasks;
10478
10838
  } });
10479
- Object.defineProperty(exports, "addRule", { enumerable: true, get: function() {
10480
- return operations_1.addRule;
10481
- } });
10482
- Object.defineProperty(exports, "deleteRule", { enumerable: true, get: function() {
10483
- return operations_1.deleteRule;
10484
- } });
10485
10839
  var boardValidation_1 = require_boardValidation();
10486
10840
  Object.defineProperty(exports, "getBoardTypes", { enumerable: true, get: function() {
10487
10841
  return boardValidation_1.getBoardTypes;
@@ -10622,6 +10976,9 @@ var require_dist = __commonJS({
10622
10976
  Object.defineProperty(exports, "ensureDotBrainfileGitignore", { enumerable: true, get: function() {
10623
10977
  return files_1.ensureDotBrainfileGitignore;
10624
10978
  } });
10979
+ Object.defineProperty(exports, "atomicWriteFileSync", { enumerable: true, get: function() {
10980
+ return files_1.atomicWriteFileSync;
10981
+ } });
10625
10982
  Object.defineProperty(exports, "DOT_BRAINFILE_DIRNAME", { enumerable: true, get: function() {
10626
10983
  return files_1.DOT_BRAINFILE_DIRNAME;
10627
10984
  } });
@@ -10634,6 +10991,47 @@ var require_dist = __commonJS({
10634
10991
  Object.defineProperty(exports, "DOT_BRAINFILE_GITIGNORE_BASENAME", { enumerable: true, get: function() {
10635
10992
  return files_1.DOT_BRAINFILE_GITIGNORE_BASENAME;
10636
10993
  } });
10994
+ Object.defineProperty(exports, "DOT_BRAINFILE_STATE_DIRNAME", { enumerable: true, get: function() {
10995
+ return files_1.DOT_BRAINFILE_STATE_DIRNAME;
10996
+ } });
10997
+ Object.defineProperty(exports, "DOT_BRAINFILE_STATE_IGNORE_ENTRY", { enumerable: true, get: function() {
10998
+ return files_1.DOT_BRAINFILE_STATE_IGNORE_ENTRY;
10999
+ } });
11000
+ var brief_1 = require_brief();
11001
+ Object.defineProperty(exports, "buildBrief", { enumerable: true, get: function() {
11002
+ return brief_1.buildBrief;
11003
+ } });
11004
+ Object.defineProperty(exports, "isEmptyBrief", { enumerable: true, get: function() {
11005
+ return brief_1.isEmptyBrief;
11006
+ } });
11007
+ Object.defineProperty(exports, "parseNoteLine", { enumerable: true, get: function() {
11008
+ return brief_1.parseNoteLine;
11009
+ } });
11010
+ Object.defineProperty(exports, "parseNotes", { enumerable: true, get: function() {
11011
+ return brief_1.parseNotes;
11012
+ } });
11013
+ Object.defineProperty(exports, "relativeTime", { enumerable: true, get: function() {
11014
+ return brief_1.relativeTime;
11015
+ } });
11016
+ var briefState_1 = require_briefState();
11017
+ Object.defineProperty(exports, "readBriefState", { enumerable: true, get: function() {
11018
+ return briefState_1.readBriefState;
11019
+ } });
11020
+ Object.defineProperty(exports, "writeBriefState", { enumerable: true, get: function() {
11021
+ return briefState_1.writeBriefState;
11022
+ } });
11023
+ Object.defineProperty(exports, "getBriefStateDir", { enumerable: true, get: function() {
11024
+ return briefState_1.getBriefStateDir;
11025
+ } });
11026
+ Object.defineProperty(exports, "getBriefStatePath", { enumerable: true, get: function() {
11027
+ return briefState_1.getBriefStatePath;
11028
+ } });
11029
+ Object.defineProperty(exports, "sanitizeAgentFilename", { enumerable: true, get: function() {
11030
+ return briefState_1.sanitizeAgentFilename;
11031
+ } });
11032
+ Object.defineProperty(exports, "BRIEF_STATE_VERSION", { enumerable: true, get: function() {
11033
+ return briefState_1.BRIEF_STATE_VERSION;
11034
+ } });
10637
11035
  var formatters_1 = require_formatters();
10638
11036
  Object.defineProperty(exports, "formatTaskForGitHub", { enumerable: true, get: function() {
10639
11037
  return formatters_1.formatTaskForGitHub;
@@ -10918,16 +11316,6 @@ var require_dist = __commonJS({
10918
11316
  static findTaskLocation(content, taskId) {
10919
11317
  return parser_2.BrainfileParser.findTaskLocation(content, taskId);
10920
11318
  }
10921
- /**
10922
- * Find the location of a rule in the file content
10923
- * @param content - The markdown content
10924
- * @param ruleId - The rule ID to find
10925
- * @param ruleType - The type of rule
10926
- * @returns Line and column location or null if not found
10927
- */
10928
- static findRuleLocation(content, ruleId, ruleType) {
10929
- return parser_2.BrainfileParser.findRuleLocation(content, ruleId, ruleType);
10930
- }
10931
11319
  };
10932
11320
  exports.Brainfile = Brainfile2;
10933
11321
  var parser_2 = require_parser();
@@ -10938,10 +11326,8 @@ var require_dist = __commonJS({
10938
11326
  }
10939
11327
  });
10940
11328
 
10941
- // src/utils/brainfile-path.ts
10942
- var import_core3 = __toESM(require_dist());
10943
- import * as fs2 from "fs";
10944
- import * as path2 from "path";
11329
+ // src/utils/cli-error.ts
11330
+ var import_chalk2 = __toESM(require_source());
10945
11331
 
10946
11332
  // src/utils/errorHandler.ts
10947
11333
  var import_chalk = __toESM(require_source());
@@ -11107,6 +11493,23 @@ ${availableTasks.map((t) => ` - ${t}`).join("\n")}`;
11107
11493
  function validationError2(message) {
11108
11494
  return new CLIError(`Validation error: ${message}`, ExitCode.USER_ERROR);
11109
11495
  }
11496
+ function renderCliError(error) {
11497
+ if (error instanceof CLIError) {
11498
+ console.error(import_chalk2.default.red(`Error: ${error.message}`));
11499
+ if (error.details) {
11500
+ console.error("");
11501
+ console.error(import_chalk2.default.gray(error.details));
11502
+ }
11503
+ process.exit(error.exitCode);
11504
+ }
11505
+ console.error(error instanceof Error ? error.stack : String(error));
11506
+ process.exit(ExitCode.USER_ERROR);
11507
+ }
11508
+
11509
+ // src/utils/brainfile-path.ts
11510
+ var import_core3 = __toESM(require_dist());
11511
+ import * as fs2 from "fs";
11512
+ import * as path2 from "path";
11110
11513
 
11111
11514
  // src/utils/v2-only.ts
11112
11515
  var import_core2 = __toESM(require_dist());
@@ -11578,7 +11981,7 @@ var AuthStore = class {
11578
11981
  var authStore = new AuthStore();
11579
11982
 
11580
11983
  // src/utils/github-auth.ts
11581
- var import_chalk2 = __toESM(require_source());
11984
+ var import_chalk3 = __toESM(require_source());
11582
11985
  var GITHUB_CLIENT_ID = process.env.BRAINFILE_GITHUB_CLIENT_ID || "Ov23liYourClientId";
11583
11986
  var GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
11584
11987
  var GITHUB_TOKEN_URL = "https://github.com/login/oauth/access_token";
@@ -11601,13 +12004,13 @@ async function authenticateGitHub(options) {
11601
12004
  const ghToken = getGitHubCLIToken();
11602
12005
  if (ghToken) {
11603
12006
  if (!silent) {
11604
- console.log(import_chalk2.default.green("\u2713") + " Found existing GitHub CLI authentication");
12007
+ console.log(import_chalk3.default.green("\u2713") + " Found existing GitHub CLI authentication");
11605
12008
  }
11606
12009
  const user = await getGitHubUser(ghToken);
11607
12010
  if (user) {
11608
12011
  await authStore.set("github", ghToken, { username: user.login });
11609
12012
  if (!silent) {
11610
- console.log(import_chalk2.default.green("\u2713") + ` Authenticated as ${import_chalk2.default.cyan("@" + user.login)}`);
12013
+ console.log(import_chalk3.default.green("\u2713") + ` Authenticated as ${import_chalk3.default.cyan("@" + user.login)}`);
11611
12014
  }
11612
12015
  return { success: true, username: user.login };
11613
12016
  }
@@ -11622,8 +12025,8 @@ async function verifyAndStoreToken(token, silent) {
11622
12025
  }
11623
12026
  await authStore.set("github", token, { username: user.login });
11624
12027
  if (!silent) {
11625
- console.log(import_chalk2.default.green("\u2713") + " Token verified");
11626
- console.log(import_chalk2.default.green("\u2713") + ` Authenticated as ${import_chalk2.default.cyan("@" + user.login)}`);
12028
+ console.log(import_chalk3.default.green("\u2713") + " Token verified");
12029
+ console.log(import_chalk3.default.green("\u2713") + ` Authenticated as ${import_chalk3.default.cyan("@" + user.login)}`);
11627
12030
  }
11628
12031
  return { success: true, username: user.login };
11629
12032
  }
@@ -11636,16 +12039,16 @@ async function deviceFlowAuth(silent) {
11636
12039
  try {
11637
12040
  const deviceCode = await requestDeviceCode();
11638
12041
  if (!silent) {
11639
- console.log(import_chalk2.default.yellow("!") + ` First, copy your one-time code: ${import_chalk2.default.bold.cyan(deviceCode.user_code)}`);
12042
+ console.log(import_chalk3.default.yellow("!") + ` First, copy your one-time code: ${import_chalk3.default.bold.cyan(deviceCode.user_code)}`);
11640
12043
  console.log("");
11641
- console.log(`Then visit: ${import_chalk2.default.underline(deviceCode.verification_uri)}`);
12044
+ console.log(`Then visit: ${import_chalk3.default.underline(deviceCode.verification_uri)}`);
11642
12045
  console.log("");
11643
12046
  }
11644
12047
  try {
11645
12048
  const open = await import("./open-ZGSQIGEH.mjs");
11646
12049
  await open.default(deviceCode.verification_uri);
11647
12050
  if (!silent) {
11648
- console.log(import_chalk2.default.gray("(Opening browser...)"));
12051
+ console.log(import_chalk3.default.gray("(Opening browser...)"));
11649
12052
  }
11650
12053
  } catch {
11651
12054
  }
@@ -11806,7 +12209,7 @@ function sleep(ms) {
11806
12209
  }
11807
12210
 
11808
12211
  // src/utils/linear-auth.ts
11809
- var import_chalk3 = __toESM(require_source());
12212
+ var import_chalk4 = __toESM(require_source());
11810
12213
  var LINEAR_API_URL = "https://api.linear.app/graphql";
11811
12214
  async function isLinearAuthenticated() {
11812
12215
  return await authStore.isAuthenticated("linear");
@@ -11821,7 +12224,7 @@ async function authenticateLinear(options) {
11821
12224
  console.log("");
11822
12225
  console.log("To authenticate with Linear, you need an API key.");
11823
12226
  console.log("");
11824
- console.log(`Get your API key from: ${import_chalk3.default.underline("https://linear.app/settings/api")}`);
12227
+ console.log(`Get your API key from: ${import_chalk4.default.underline("https://linear.app/settings/api")}`);
11825
12228
  console.log("");
11826
12229
  }
11827
12230
  return { success: false, error: "Linear API key required. Use --token flag." };
@@ -11837,8 +12240,8 @@ async function authenticateLinear(options) {
11837
12240
  workspace
11838
12241
  });
11839
12242
  if (!silent) {
11840
- console.log(import_chalk3.default.green("\u2713") + " API key verified");
11841
- console.log(import_chalk3.default.green("\u2713") + ` Authenticated as ${import_chalk3.default.cyan(viewer.name)} in ${import_chalk3.default.cyan(workspace)}`);
12243
+ console.log(import_chalk4.default.green("\u2713") + " API key verified");
12244
+ console.log(import_chalk4.default.green("\u2713") + ` Authenticated as ${import_chalk4.default.cyan(viewer.name)} in ${import_chalk4.default.cyan(workspace)}`);
11842
12245
  }
11843
12246
  return { success: true, workspace };
11844
12247
  }
@@ -12039,6 +12442,91 @@ async function logoutLinear() {
12039
12442
  await authStore.clear("linear");
12040
12443
  }
12041
12444
 
12445
+ // src/tui/theme.ts
12446
+ var RAW_PALETTE = {
12447
+ // Text hierarchy
12448
+ text: "#ffffff",
12449
+ textSecondary: "#a0a0a0",
12450
+ textMuted: "#606060",
12451
+ textDim: "#404040",
12452
+ // Priority signal
12453
+ critical: "#ef4444",
12454
+ high: "#f59e0b",
12455
+ medium: "#3b82f6",
12456
+ low: "#6b7280",
12457
+ // Contract-state signal (design §3: draft dim · ready cyan · in_progress
12458
+ // yellow · delivered magenta · done green · failed/blocked red)
12459
+ contractDraft: "#606060",
12460
+ contractReady: "#06b6d4",
12461
+ contractInProgress: "#eab308",
12462
+ contractDelivered: "#c026d3",
12463
+ contractDone: "#22c55e",
12464
+ contractFailed: "#ef4444",
12465
+ // Feedback
12466
+ success: "#22c55e",
12467
+ warning: "#eab308",
12468
+ error: "#ef4444",
12469
+ info: "#3b82f6",
12470
+ accent: "#7c3aed"
12471
+ };
12472
+ function isNoColor(env = process.env) {
12473
+ return Boolean(env.NO_COLOR);
12474
+ }
12475
+ function makePalette(noColor) {
12476
+ if (!noColor) return RAW_PALETTE;
12477
+ return new Proxy(RAW_PALETTE, { get: () => void 0 });
12478
+ }
12479
+ var NO_COLOR = isNoColor();
12480
+ var PALETTE = makePalette(NO_COLOR);
12481
+ var RULE = "\u2500";
12482
+ var TYPE_GLYPHS = {
12483
+ epic: "\u25B8",
12484
+ spec: "\u25C6",
12485
+ adr: "\u25CF",
12486
+ plan: "\u2398",
12487
+ task: ""
12488
+ };
12489
+ function getTypeGlyph(type) {
12490
+ if (!type) return "";
12491
+ return TYPE_GLYPHS[type.toLowerCase()] ?? "";
12492
+ }
12493
+ var GLYPHS = {
12494
+ pointer: "\u25B8",
12495
+ cursor: "\u258C",
12496
+ collapsed: "\u25B6",
12497
+ success: "\u2713",
12498
+ error: "\u2717",
12499
+ warning: "\u26A0",
12500
+ live: "\u25CF",
12501
+ subtaskOpen: "\u25FB",
12502
+ subtaskDone: "\u2611",
12503
+ orphanParent: "\u2190",
12504
+ /** Board-list row glyph for a parent-with-children that is expanded (§A1). */
12505
+ parentExpanded: "\u25BE",
12506
+ /** Board-list row glyph for a parent-with-children that is collapsed (§A1). */
12507
+ parentCollapsed: "\u25B8",
12508
+ /** Detail body scroll indicator (§B2), e.g. `↕ 2/9`. */
12509
+ scroll: "\u2195"
12510
+ };
12511
+ function getContractStateColor(state) {
12512
+ switch (state?.toLowerCase()) {
12513
+ case "ready":
12514
+ return PALETTE.contractReady;
12515
+ case "in_progress":
12516
+ return PALETTE.contractInProgress;
12517
+ case "delivered":
12518
+ return PALETTE.contractDelivered;
12519
+ case "done":
12520
+ return PALETTE.contractDone;
12521
+ case "failed":
12522
+ case "blocked":
12523
+ return PALETTE.contractFailed;
12524
+ case "draft":
12525
+ default:
12526
+ return PALETTE.contractDraft;
12527
+ }
12528
+ }
12529
+
12042
12530
  export {
12043
12531
  require_source,
12044
12532
  require_dist,
@@ -12061,6 +12549,7 @@ export {
12061
12549
  columnNotFound,
12062
12550
  taskNotFound,
12063
12551
  validationError2,
12552
+ renderCliError,
12064
12553
  V1_UNSUPPORTED_MESSAGE,
12065
12554
  assertV2Brainfile,
12066
12555
  resolveCliBrainfilePath,
@@ -12085,5 +12574,10 @@ export {
12085
12574
  authenticateLinear,
12086
12575
  getLinearTeams,
12087
12576
  createLinearIssue,
12088
- logoutLinear
12577
+ logoutLinear,
12578
+ PALETTE,
12579
+ RULE,
12580
+ getTypeGlyph,
12581
+ GLYPHS,
12582
+ getContractStateColor
12089
12583
  };