@jayjiang/byoao 1.1.2 → 2.0.1

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 (156) hide show
  1. package/dist/__tests__/plugin-config.test.js +7 -10
  2. package/dist/__tests__/plugin-config.test.js.map +1 -1
  3. package/dist/assets/obsidian-skills/byoao-conventions.md +30 -54
  4. package/dist/assets/obsidian-skills/vault-thinking.md +6 -5
  5. package/dist/assets/presets/common/AGENTS.md.hbs +29 -46
  6. package/dist/assets/presets/common/SCHEMA.md.hbs +57 -0
  7. package/dist/assets/presets/common/Start Here.md.hbs +29 -40
  8. package/dist/assets/presets/minimal/preset.json +3 -3
  9. package/dist/assets/presets/pm-tpm/preset.json +2 -2
  10. package/{src/skills/ask.md → dist/assets/skills/ask/SKILL.md} +30 -27
  11. package/dist/assets/skills/ask.md +28 -27
  12. package/dist/assets/skills/challenge/SKILL.md +134 -0
  13. package/dist/assets/skills/challenge.md +79 -121
  14. package/dist/assets/skills/connect/SKILL.md +126 -0
  15. package/dist/assets/skills/connect.md +75 -163
  16. package/dist/assets/skills/cook/SKILL.md +170 -0
  17. package/dist/assets/skills/cook.md +167 -0
  18. package/dist/assets/skills/diagnose/SKILL.md +134 -0
  19. package/dist/assets/skills/diagnose.md +102 -43
  20. package/dist/assets/skills/drift/SKILL.md +123 -0
  21. package/dist/assets/skills/drift.md +64 -165
  22. package/dist/assets/skills/health/SKILL.md +65 -0
  23. package/dist/assets/skills/health.md +63 -0
  24. package/{src/skills/ideas.md → dist/assets/skills/ideas/SKILL.md} +11 -10
  25. package/dist/assets/skills/ideas.md +11 -10
  26. package/dist/assets/skills/organize/SKILL.md +109 -0
  27. package/dist/assets/skills/organize.md +56 -155
  28. package/dist/assets/skills/prep/SKILL.md +65 -0
  29. package/dist/assets/skills/prep.md +63 -0
  30. package/dist/assets/skills/trace/SKILL.md +143 -0
  31. package/dist/assets/skills/trace.md +75 -90
  32. package/dist/assets/skills/wiki/SKILL.md +127 -0
  33. package/dist/assets/skills/wiki.md +77 -178
  34. package/dist/cli/cli-program.js +18 -15
  35. package/dist/cli/cli-program.js.map +1 -1
  36. package/dist/cli/installer.js +54 -29
  37. package/dist/cli/installer.js.map +1 -1
  38. package/dist/hooks/idle-suggestions.js +4 -4
  39. package/dist/hooks/idle-suggestions.js.map +1 -1
  40. package/dist/hooks/system-transform.js +35 -1
  41. package/dist/hooks/system-transform.js.map +1 -1
  42. package/dist/index.js +455 -636
  43. package/dist/index.js.map +1 -1
  44. package/dist/plugin-config.js +6 -32
  45. package/dist/plugin-config.js.map +1 -1
  46. package/dist/tools/init-vault.js +8 -38
  47. package/dist/tools/init-vault.js.map +1 -1
  48. package/dist/tools/vault-doctor.js +1 -1
  49. package/dist/tools/vault-doctor.js.map +1 -1
  50. package/dist/tools/vault-status.js +1 -1
  51. package/dist/tools/vault-status.js.map +1 -1
  52. package/dist/vault/__tests__/create.test.js +48 -116
  53. package/dist/vault/__tests__/create.test.js.map +1 -1
  54. package/dist/vault/__tests__/doctor.test.js +14 -2
  55. package/dist/vault/__tests__/doctor.test.js.map +1 -1
  56. package/dist/vault/__tests__/manifest.test.js +2 -2
  57. package/dist/vault/__tests__/manifest.test.js.map +1 -1
  58. package/dist/vault/__tests__/status.test.js +12 -0
  59. package/dist/vault/__tests__/status.test.js.map +1 -1
  60. package/dist/vault/__tests__/upgrade.test.js +3 -3
  61. package/dist/vault/__tests__/upgrade.test.js.map +1 -1
  62. package/dist/vault/create.js +86 -196
  63. package/dist/vault/create.js.map +1 -1
  64. package/dist/vault/doctor.js +49 -0
  65. package/dist/vault/doctor.js.map +1 -1
  66. package/dist/vault/manifest.js +2 -2
  67. package/dist/vault/manifest.js.map +1 -1
  68. package/dist/vault/preset.js +10 -4
  69. package/dist/vault/preset.js.map +1 -1
  70. package/dist/vault/self-update.js +1 -1
  71. package/dist/vault/status.js +24 -0
  72. package/dist/vault/status.js.map +1 -1
  73. package/dist/vault/upgrade.js +165 -23
  74. package/dist/vault/upgrade.js.map +1 -1
  75. package/package.json +1 -1
  76. package/src/assets/obsidian-skills/byoao-conventions.md +9 -6
  77. package/src/assets/obsidian-skills/vault-thinking.md +6 -5
  78. package/src/assets/presets/common/AGENTS.md.hbs +23 -19
  79. package/src/assets/presets/common/SCHEMA.md.hbs +57 -0
  80. package/src/assets/presets/common/Start Here.md.hbs +29 -40
  81. package/src/assets/presets/minimal/preset.json +3 -3
  82. package/src/assets/presets/pm-tpm/preset.json +2 -2
  83. package/src/skills/ask/SKILL.md +135 -0
  84. package/src/skills/challenge/SKILL.md +134 -0
  85. package/src/skills/connect/SKILL.md +126 -0
  86. package/src/skills/cook/SKILL.md +170 -0
  87. package/src/skills/diagnose/SKILL.md +134 -0
  88. package/src/skills/drift/SKILL.md +123 -0
  89. package/src/skills/health/SKILL.md +65 -0
  90. package/src/skills/ideas/SKILL.md +173 -0
  91. package/src/skills/organize/SKILL.md +109 -0
  92. package/src/skills/prep/SKILL.md +65 -0
  93. package/src/skills/trace/SKILL.md +143 -0
  94. package/src/skills/wiki/SKILL.md +127 -0
  95. package/dist/assets/presets/common/Glossary.md.hbs +0 -16
  96. package/dist/assets/presets/common/obsidian/daily-notes.json +0 -5
  97. package/dist/assets/presets/common/obsidian/templates.json +0 -3
  98. package/dist/assets/presets/common/templates/Daily Note.md +0 -19
  99. package/dist/assets/presets/common/templates/Decision Record.md +0 -32
  100. package/dist/assets/presets/common/templates/Investigation.md +0 -34
  101. package/dist/assets/presets/common/templates/Meeting Notes.md +0 -25
  102. package/dist/assets/skills/emerge.md +0 -168
  103. package/dist/assets/skills/weave.md +0 -287
  104. package/dist/tools/add-glossary-term.js +0 -21
  105. package/dist/tools/add-glossary-term.js.map +0 -1
  106. package/dist/tools/add-person.js +0 -21
  107. package/dist/tools/add-person.js.map +0 -1
  108. package/dist/tools/add-project.js +0 -24
  109. package/dist/tools/add-project.js.map +0 -1
  110. package/dist/tools/graph-health.js +0 -25
  111. package/dist/tools/graph-health.js.map +0 -1
  112. package/dist/tools/note-read.js +0 -19
  113. package/dist/tools/note-read.js.map +0 -1
  114. package/dist/tools/search-vault.js +0 -22
  115. package/dist/tools/search-vault.js.map +0 -1
  116. package/dist/vault/__tests__/glossary.test.js +0 -68
  117. package/dist/vault/__tests__/glossary.test.js.map +0 -1
  118. package/dist/vault/__tests__/graph-health.test.js +0 -102
  119. package/dist/vault/__tests__/graph-health.test.js.map +0 -1
  120. package/dist/vault/__tests__/member.test.js +0 -85
  121. package/dist/vault/__tests__/member.test.js.map +0 -1
  122. package/dist/vault/__tests__/note-read.test.js +0 -71
  123. package/dist/vault/__tests__/note-read.test.js.map +0 -1
  124. package/dist/vault/__tests__/obsidian-cli.test.js +0 -108
  125. package/dist/vault/__tests__/obsidian-cli.test.js.map +0 -1
  126. package/dist/vault/__tests__/search-vault.test.js +0 -93
  127. package/dist/vault/__tests__/search-vault.test.js.map +0 -1
  128. package/dist/vault/glossary.js +0 -27
  129. package/dist/vault/glossary.js.map +0 -1
  130. package/dist/vault/graph-health.js +0 -83
  131. package/dist/vault/graph-health.js.map +0 -1
  132. package/dist/vault/member.js +0 -67
  133. package/dist/vault/member.js.map +0 -1
  134. package/dist/vault/note-read.js +0 -70
  135. package/dist/vault/note-read.js.map +0 -1
  136. package/dist/vault/project.js +0 -68
  137. package/dist/vault/project.js.map +0 -1
  138. package/dist/vault/retrieval-types.js +0 -5
  139. package/dist/vault/retrieval-types.js.map +0 -1
  140. package/dist/vault/search-vault.js +0 -87
  141. package/dist/vault/search-vault.js.map +0 -1
  142. package/src/assets/presets/common/obsidian/daily-notes.json +0 -5
  143. package/src/assets/presets/common/obsidian/templates.json +0 -3
  144. package/src/assets/presets/common/templates/Daily Note.md +0 -19
  145. package/src/assets/presets/common/templates/Decision Record.md +0 -32
  146. package/src/assets/presets/common/templates/Investigation.md +0 -34
  147. package/src/assets/presets/common/templates/Meeting Notes.md +0 -25
  148. package/src/skills/challenge.md +0 -174
  149. package/src/skills/connect.md +0 -213
  150. package/src/skills/diagnose.md +0 -72
  151. package/src/skills/drift.md +0 -223
  152. package/src/skills/emerge.md +0 -168
  153. package/src/skills/organize.md +0 -206
  154. package/src/skills/trace.md +0 -156
  155. package/src/skills/weave.md +0 -287
  156. package/src/skills/wiki.md +0 -227
package/dist/index.js CHANGED
@@ -4682,13 +4682,13 @@ var require_ast = __commonJS({
4682
4682
  helperExpression: function helperExpression(node) {
4683
4683
  return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
4684
4684
  },
4685
- scopedId: function scopedId(path15) {
4686
- return /^\.|this\b/.test(path15.original);
4685
+ scopedId: function scopedId(path13) {
4686
+ return /^\.|this\b/.test(path13.original);
4687
4687
  },
4688
4688
  // an ID is simple if it only has one part, and that part is not
4689
4689
  // `..` or `this`.
4690
- simpleId: function simpleId(path15) {
4691
- return path15.parts.length === 1 && !AST.helpers.scopedId(path15) && !path15.depth;
4690
+ simpleId: function simpleId(path13) {
4691
+ return path13.parts.length === 1 && !AST.helpers.scopedId(path13) && !path13.depth;
4692
4692
  }
4693
4693
  }
4694
4694
  };
@@ -5758,12 +5758,12 @@ var require_helpers2 = __commonJS({
5758
5758
  loc
5759
5759
  };
5760
5760
  }
5761
- function prepareMustache(path15, params, hash2, open, strip, locInfo) {
5761
+ function prepareMustache(path13, params, hash2, open, strip, locInfo) {
5762
5762
  var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
5763
5763
  var decorator = /\*/.test(open);
5764
5764
  return {
5765
5765
  type: decorator ? "Decorator" : "MustacheStatement",
5766
- path: path15,
5766
+ path: path13,
5767
5767
  params,
5768
5768
  hash: hash2,
5769
5769
  escaped,
@@ -6033,9 +6033,9 @@ var require_compiler = __commonJS({
6033
6033
  },
6034
6034
  DecoratorBlock: function DecoratorBlock(decorator) {
6035
6035
  var program = decorator.program && this.compileProgram(decorator.program);
6036
- var params = this.setupFullMustacheParams(decorator, program, void 0), path15 = decorator.path;
6036
+ var params = this.setupFullMustacheParams(decorator, program, void 0), path13 = decorator.path;
6037
6037
  this.useDecorators = true;
6038
- this.opcode("registerDecorator", params.length, path15.original);
6038
+ this.opcode("registerDecorator", params.length, path13.original);
6039
6039
  },
6040
6040
  PartialStatement: function PartialStatement(partial2) {
6041
6041
  this.usePartial = true;
@@ -6099,46 +6099,46 @@ var require_compiler = __commonJS({
6099
6099
  }
6100
6100
  },
6101
6101
  ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
6102
- var path15 = sexpr.path, name = path15.parts[0], isBlock = program != null || inverse != null;
6103
- this.opcode("getContext", path15.depth);
6102
+ var path13 = sexpr.path, name = path13.parts[0], isBlock = program != null || inverse != null;
6103
+ this.opcode("getContext", path13.depth);
6104
6104
  this.opcode("pushProgram", program);
6105
6105
  this.opcode("pushProgram", inverse);
6106
- path15.strict = true;
6107
- this.accept(path15);
6106
+ path13.strict = true;
6107
+ this.accept(path13);
6108
6108
  this.opcode("invokeAmbiguous", name, isBlock);
6109
6109
  },
6110
6110
  simpleSexpr: function simpleSexpr(sexpr) {
6111
- var path15 = sexpr.path;
6112
- path15.strict = true;
6113
- this.accept(path15);
6111
+ var path13 = sexpr.path;
6112
+ path13.strict = true;
6113
+ this.accept(path13);
6114
6114
  this.opcode("resolvePossibleLambda");
6115
6115
  },
6116
6116
  helperSexpr: function helperSexpr(sexpr, program, inverse) {
6117
- var params = this.setupFullMustacheParams(sexpr, program, inverse), path15 = sexpr.path, name = path15.parts[0];
6117
+ var params = this.setupFullMustacheParams(sexpr, program, inverse), path13 = sexpr.path, name = path13.parts[0];
6118
6118
  if (this.options.knownHelpers[name]) {
6119
6119
  this.opcode("invokeKnownHelper", params.length, name);
6120
6120
  } else if (this.options.knownHelpersOnly) {
6121
6121
  throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
6122
6122
  } else {
6123
- path15.strict = true;
6124
- path15.falsy = true;
6125
- this.accept(path15);
6126
- this.opcode("invokeHelper", params.length, path15.original, _ast2["default"].helpers.simpleId(path15));
6123
+ path13.strict = true;
6124
+ path13.falsy = true;
6125
+ this.accept(path13);
6126
+ this.opcode("invokeHelper", params.length, path13.original, _ast2["default"].helpers.simpleId(path13));
6127
6127
  }
6128
6128
  },
6129
- PathExpression: function PathExpression(path15) {
6130
- this.addDepth(path15.depth);
6131
- this.opcode("getContext", path15.depth);
6132
- var name = path15.parts[0], scoped = _ast2["default"].helpers.scopedId(path15), blockParamId = !path15.depth && !scoped && this.blockParamIndex(name);
6129
+ PathExpression: function PathExpression(path13) {
6130
+ this.addDepth(path13.depth);
6131
+ this.opcode("getContext", path13.depth);
6132
+ var name = path13.parts[0], scoped = _ast2["default"].helpers.scopedId(path13), blockParamId = !path13.depth && !scoped && this.blockParamIndex(name);
6133
6133
  if (blockParamId) {
6134
- this.opcode("lookupBlockParam", blockParamId, path15.parts);
6134
+ this.opcode("lookupBlockParam", blockParamId, path13.parts);
6135
6135
  } else if (!name) {
6136
6136
  this.opcode("pushContext");
6137
- } else if (path15.data) {
6137
+ } else if (path13.data) {
6138
6138
  this.options.data = true;
6139
- this.opcode("lookupData", path15.depth, path15.parts, path15.strict);
6139
+ this.opcode("lookupData", path13.depth, path13.parts, path13.strict);
6140
6140
  } else {
6141
- this.opcode("lookupOnContext", path15.parts, path15.falsy, path15.strict, scoped);
6141
+ this.opcode("lookupOnContext", path13.parts, path13.falsy, path13.strict, scoped);
6142
6142
  }
6143
6143
  },
6144
6144
  StringLiteral: function StringLiteral(string4) {
@@ -6488,16 +6488,16 @@ var require_util = __commonJS({
6488
6488
  }
6489
6489
  exports2.urlGenerate = urlGenerate;
6490
6490
  function normalize(aPath) {
6491
- var path15 = aPath;
6491
+ var path13 = aPath;
6492
6492
  var url2 = urlParse(aPath);
6493
6493
  if (url2) {
6494
6494
  if (!url2.path) {
6495
6495
  return aPath;
6496
6496
  }
6497
- path15 = url2.path;
6497
+ path13 = url2.path;
6498
6498
  }
6499
- var isAbsolute = exports2.isAbsolute(path15);
6500
- var parts = path15.split(/\/+/);
6499
+ var isAbsolute = exports2.isAbsolute(path13);
6500
+ var parts = path13.split(/\/+/);
6501
6501
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
6502
6502
  part = parts[i];
6503
6503
  if (part === ".") {
@@ -6514,15 +6514,15 @@ var require_util = __commonJS({
6514
6514
  }
6515
6515
  }
6516
6516
  }
6517
- path15 = parts.join("/");
6518
- if (path15 === "") {
6519
- path15 = isAbsolute ? "/" : ".";
6517
+ path13 = parts.join("/");
6518
+ if (path13 === "") {
6519
+ path13 = isAbsolute ? "/" : ".";
6520
6520
  }
6521
6521
  if (url2) {
6522
- url2.path = path15;
6522
+ url2.path = path13;
6523
6523
  return urlGenerate(url2);
6524
6524
  }
6525
- return path15;
6525
+ return path13;
6526
6526
  }
6527
6527
  exports2.normalize = normalize;
6528
6528
  function join2(aRoot, aPath) {
@@ -9303,8 +9303,8 @@ var require_printer = __commonJS({
9303
9303
  return this.accept(sexpr.path) + " " + params + hash2;
9304
9304
  };
9305
9305
  PrintVisitor.prototype.PathExpression = function(id) {
9306
- var path15 = id.parts.join("/");
9307
- return (id.data ? "@" : "") + "PATH:" + path15;
9306
+ var path13 = id.parts.join("/");
9307
+ return (id.data ? "@" : "") + "PATH:" + path13;
9308
9308
  };
9309
9309
  PrintVisitor.prototype.StringLiteral = function(string4) {
9310
9310
  return '"' + string4.value + '"';
@@ -12015,10 +12015,10 @@ function mergeDefs(...defs) {
12015
12015
  function cloneDef(schema) {
12016
12016
  return mergeDefs(schema._zod.def);
12017
12017
  }
12018
- function getElementAtPath(obj, path15) {
12019
- if (!path15)
12018
+ function getElementAtPath(obj, path13) {
12019
+ if (!path13)
12020
12020
  return obj;
12021
- return path15.reduce((acc, key) => acc?.[key], obj);
12021
+ return path13.reduce((acc, key) => acc?.[key], obj);
12022
12022
  }
12023
12023
  function promiseAllObject(promisesObj) {
12024
12024
  const keys = Object.keys(promisesObj);
@@ -12379,11 +12379,11 @@ function aborted(x, startIndex = 0) {
12379
12379
  }
12380
12380
  return false;
12381
12381
  }
12382
- function prefixIssues(path15, issues) {
12382
+ function prefixIssues(path13, issues) {
12383
12383
  return issues.map((iss) => {
12384
12384
  var _a;
12385
12385
  (_a = iss).path ?? (_a.path = []);
12386
- iss.path.unshift(path15);
12386
+ iss.path.unshift(path13);
12387
12387
  return iss;
12388
12388
  });
12389
12389
  }
@@ -12551,7 +12551,7 @@ function treeifyError(error45, _mapper) {
12551
12551
  return issue2.message;
12552
12552
  };
12553
12553
  const result = { errors: [] };
12554
- const processError = (error46, path15 = []) => {
12554
+ const processError = (error46, path13 = []) => {
12555
12555
  var _a, _b;
12556
12556
  for (const issue2 of error46.issues) {
12557
12557
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -12561,7 +12561,7 @@ function treeifyError(error45, _mapper) {
12561
12561
  } else if (issue2.code === "invalid_element") {
12562
12562
  processError({ issues: issue2.issues }, issue2.path);
12563
12563
  } else {
12564
- const fullpath = [...path15, ...issue2.path];
12564
+ const fullpath = [...path13, ...issue2.path];
12565
12565
  if (fullpath.length === 0) {
12566
12566
  result.errors.push(mapper(issue2));
12567
12567
  continue;
@@ -12593,8 +12593,8 @@ function treeifyError(error45, _mapper) {
12593
12593
  }
12594
12594
  function toDotPath(_path) {
12595
12595
  const segs = [];
12596
- const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12597
- for (const seg of path15) {
12596
+ const path13 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12597
+ for (const seg of path13) {
12598
12598
  if (typeof seg === "number")
12599
12599
  segs.push(`[${seg}]`);
12600
12600
  else if (typeof seg === "symbol")
@@ -23791,9 +23791,6 @@ function renderTemplate(templateStr, data) {
23791
23791
  }
23792
23792
  return compiled(data);
23793
23793
  }
23794
- function today() {
23795
- return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
23796
- }
23797
23794
 
23798
23795
  // dist/vault/preset.js
23799
23796
  import path from "node:path";
@@ -24276,8 +24273,8 @@ function getErrorMap2() {
24276
24273
 
24277
24274
  // node_modules/zod/v3/helpers/parseUtil.js
24278
24275
  var makeIssue = (params) => {
24279
- const { data, path: path15, errorMaps, issueData } = params;
24280
- const fullPath = [...path15, ...issueData.path || []];
24276
+ const { data, path: path13, errorMaps, issueData } = params;
24277
+ const fullPath = [...path13, ...issueData.path || []];
24281
24278
  const fullIssue = {
24282
24279
  ...issueData,
24283
24280
  path: fullPath
@@ -24393,11 +24390,11 @@ var errorUtil;
24393
24390
 
24394
24391
  // node_modules/zod/v3/types.js
24395
24392
  var ParseInputLazyPath = class {
24396
- constructor(parent, value, path15, key) {
24393
+ constructor(parent, value, path13, key) {
24397
24394
  this._cachedPath = [];
24398
24395
  this.parent = parent;
24399
24396
  this.data = value;
24400
- this._path = path15;
24397
+ this._path = path13;
24401
24398
  this._key = key;
24402
24399
  }
24403
24400
  get path() {
@@ -27840,52 +27837,26 @@ var coerce = {
27840
27837
  var NEVER2 = INVALID;
27841
27838
 
27842
27839
  // dist/plugin-config.js
27843
- var MemberSchema = external_exports2.object({
27844
- name: external_exports2.string(),
27845
- role: external_exports2.string().default("")
27846
- });
27847
- var ProjectSchema = external_exports2.object({
27848
- name: external_exports2.string(),
27849
- description: external_exports2.string().default("")
27850
- });
27851
- var GlossaryEntrySchema = external_exports2.object({
27840
+ var TaxonomyEntrySchema = external_exports2.object({
27852
27841
  term: external_exports2.string(),
27853
27842
  definition: external_exports2.string(),
27854
- domain: external_exports2.string().default("")
27843
+ domain: external_exports2.string().default(""),
27844
+ tags: external_exports2.array(external_exports2.string()).default([])
27855
27845
  });
27856
27846
  var VaultConfigSchema = external_exports2.object({
27857
27847
  kbName: external_exports2.string().min(1),
27858
27848
  ownerName: external_exports2.string().default(""),
27859
27849
  vaultPath: external_exports2.string(),
27860
- members: external_exports2.array(MemberSchema).default([]),
27861
- projects: external_exports2.array(ProjectSchema).default([]),
27862
- glossaryEntries: external_exports2.array(GlossaryEntrySchema).default([]),
27863
- jiraHost: external_exports2.string().default(""),
27864
- jiraProject: external_exports2.string().default(""),
27865
27850
  preset: external_exports2.string().default("minimal"),
27866
27851
  provider: external_exports2.enum(["copilot", "gemini", "skip"]).default("skip"),
27867
27852
  /** GCP Project ID — used for BigQuery MCP env and Gemini provider config */
27868
27853
  gcpProjectId: external_exports2.string().default(""),
27869
27854
  /** MCP server names to skip (user deselected in init flow) */
27870
- mcpSkip: external_exports2.array(external_exports2.string()).default([])
27871
- });
27872
- var AddMemberSchema = external_exports2.object({
27873
- vaultPath: external_exports2.string(),
27874
- name: external_exports2.string(),
27875
- role: external_exports2.string().default(""),
27876
- team: external_exports2.string().default("")
27877
- });
27878
- var AddProjectSchema = external_exports2.object({
27879
- vaultPath: external_exports2.string(),
27880
- name: external_exports2.string(),
27881
- description: external_exports2.string().default(""),
27882
- team: external_exports2.string().default("")
27883
- });
27884
- var AddGlossaryTermSchema = external_exports2.object({
27885
- vaultPath: external_exports2.string(),
27886
- term: external_exports2.string(),
27887
- definition: external_exports2.string(),
27888
- domain: external_exports2.string().default("")
27855
+ mcpSkip: external_exports2.array(external_exports2.string()).default([]),
27856
+ /** What domain this knowledge base covers (used in SCHEMA.md generation) */
27857
+ wikiDomain: external_exports2.string().default(""),
27858
+ /** Agent autonomy level: auto = agent applies changes, review = agent reports first */
27859
+ compilationMode: external_exports2.enum(["auto", "review"]).default("review")
27889
27860
  });
27890
27861
  var VaultStatusSchema = external_exports2.object({
27891
27862
  vaultPath: external_exports2.string()
@@ -27921,15 +27892,19 @@ var VaultDoctorSchema = external_exports2.object({
27921
27892
 
27922
27893
  // dist/vault/preset.js
27923
27894
  function getPresetsDir() {
27895
+ const distAssets = path.resolve(import.meta.dirname, "assets", "presets");
27924
27896
  const srcPresets = path.resolve(import.meta.dirname, "..", "assets", "presets");
27925
- const distPresets = path.resolve(import.meta.dirname, "..", "..", "src", "assets", "presets");
27897
+ const devPresets = path.resolve(import.meta.dirname, "..", "..", "src", "assets", "presets");
27898
+ if (fs.existsSync(distAssets))
27899
+ return distAssets;
27926
27900
  if (fs.existsSync(srcPresets))
27927
27901
  return srcPresets;
27928
- if (fs.existsSync(distPresets))
27929
- return distPresets;
27902
+ if (fs.existsSync(devPresets))
27903
+ return devPresets;
27930
27904
  throw new Error(`Cannot find presets directory. Looked in:
27905
+ ${distAssets}
27931
27906
  ${srcPresets}
27932
- ${distPresets}`);
27907
+ ${devPresets}`);
27933
27908
  }
27934
27909
  function listPresets() {
27935
27910
  const presetsDir = getPresetsDir();
@@ -28287,10 +28262,11 @@ async function configureProvider(provider, gcpProjectId) {
28287
28262
 
28288
28263
  // dist/vault/manifest.js
28289
28264
  import path4 from "node:path";
28290
- var PKG_VERSION = "1.1.2";
28265
+ var PKG_VERSION = "2.0.1";
28291
28266
  var InfrastructureSchema = external_exports2.object({
28292
28267
  skills: external_exports2.array(external_exports2.string()).default([]),
28293
28268
  commands: external_exports2.array(external_exports2.string()).default([]),
28269
+ // deprecated — kept for backward compat parsing
28294
28270
  obsidianConfig: external_exports2.array(external_exports2.string()).default([]),
28295
28271
  templates: external_exports2.array(external_exports2.string()).default([])
28296
28272
  });
@@ -28303,7 +28279,7 @@ var ManifestSchema = external_exports2.object({
28303
28279
  });
28304
28280
  var MANIFEST_DIR = ".byoao";
28305
28281
  var MANIFEST_FILE = "manifest.json";
28306
- function today2() {
28282
+ function today() {
28307
28283
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
28308
28284
  }
28309
28285
  function manifestPath(vaultPath) {
@@ -28326,8 +28302,8 @@ async function writeManifest(vaultPath, preset, installedFiles, versionOverride)
28326
28302
  const manifest = {
28327
28303
  version: versionOverride ?? PKG_VERSION,
28328
28304
  preset,
28329
- createdAt: existing?.createdAt ?? today2(),
28330
- updatedAt: today2(),
28305
+ createdAt: existing?.createdAt ?? today(),
28306
+ updatedAt: today(),
28331
28307
  infrastructure: {
28332
28308
  skills: installedFiles.skills,
28333
28309
  commands: installedFiles.commands,
@@ -28388,7 +28364,6 @@ function countWikilinks(content) {
28388
28364
  const matches = stripped.match(/\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g);
28389
28365
  return matches ? matches.length : 0;
28390
28366
  }
28391
- var MINIMAL_DIRECTORIES = [];
28392
28367
  function makeContext(vaultPath, kbName, preserveObsidian = false) {
28393
28368
  return {
28394
28369
  vaultPath,
@@ -28410,11 +28385,7 @@ var MCP_DISPLAY_NAMES = {
28410
28385
  atlassian: { name: "Atlassian", description: "Jira issues, Confluence pages" },
28411
28386
  bigquery: { name: "BigQuery", description: "Data warehouse queries and analysis" }
28412
28387
  };
28413
- async function createMinimalCore(ctx, _glossaryEntries = []) {
28414
- for (const dir of MINIMAL_DIRECTORIES) {
28415
- await fs.ensureDir(path6.join(ctx.vaultPath, dir));
28416
- }
28417
- ctx.directories.push(...MINIMAL_DIRECTORIES);
28388
+ async function createMinimalCore(ctx) {
28418
28389
  if (!ctx.preserveObsidian) {
28419
28390
  await fs.ensureDir(path6.join(ctx.vaultPath, ".obsidian"));
28420
28391
  const obsidianSrc = path6.join(ctx.commonDir, "obsidian");
@@ -28439,23 +28410,51 @@ async function createMinimalCore(ctx, _glossaryEntries = []) {
28439
28410
  ctx.filesCreated++;
28440
28411
  }
28441
28412
  }
28442
- async function createAgentsMd(ctx, ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject) {
28413
+ async function createLlmWikiCore(ctx, wikiDomain = "") {
28414
+ const agentDirs = ["entities", "concepts", "comparisons", "queries"];
28415
+ for (const dir of agentDirs) {
28416
+ const dirPath = path6.join(ctx.vaultPath, dir);
28417
+ if (!await fs.pathExists(dirPath)) {
28418
+ await fs.ensureDir(dirPath);
28419
+ ctx.filesCreated++;
28420
+ ctx.directories.push(dir);
28421
+ }
28422
+ }
28423
+ const schemaTemplatePath = path6.join(ctx.commonDir, "SCHEMA.md.hbs");
28424
+ if (await fs.pathExists(schemaTemplatePath)) {
28425
+ const schemaTemplate = await fs.readFile(schemaTemplatePath, "utf-8");
28426
+ const schemaContent = renderTemplate(schemaTemplate, {
28427
+ KB_NAME: ctx.kbName,
28428
+ WIKI_DOMAIN: wikiDomain || ""
28429
+ });
28430
+ const schemaPath = path6.join(ctx.vaultPath, "SCHEMA.md");
28431
+ if (!await fs.pathExists(schemaPath)) {
28432
+ await fs.writeFile(schemaPath, schemaContent);
28433
+ ctx.filesCreated++;
28434
+ }
28435
+ }
28436
+ const logContent = `# Agent Activity Log
28437
+
28438
+ Entries are appended here during /cook operations.
28439
+
28440
+ `;
28441
+ const logPath = path6.join(ctx.vaultPath, "log.md");
28442
+ if (!await fs.pathExists(logPath)) {
28443
+ await fs.writeFile(logPath, logContent);
28444
+ ctx.filesCreated++;
28445
+ }
28446
+ }
28447
+ async function createAgentsMd(ctx, ownerName, presetConfig, presetDir) {
28443
28448
  const agentsTemplate = await fs.readFile(path6.join(ctx.commonDir, "AGENTS.md.hbs"), "utf-8");
28444
28449
  let roleSection = "";
28445
28450
  const agentSectionPath = path6.join(presetDir, "agent-section.hbs");
28446
28451
  if (await fs.pathExists(agentSectionPath)) {
28447
28452
  const agentSectionTemplate = await fs.readFile(agentSectionPath, "utf-8");
28448
- let projectsList;
28449
- if (projects.length > 0) {
28450
- projectsList = projects.map((p) => `- [[${p.name}]] \u2014 ${p.description}`).join("\n");
28451
- } else {
28452
- projectsList = "(No projects added yet \u2014 create notes in Projects/)";
28453
- }
28454
28453
  roleSection = renderTemplate(agentSectionTemplate, {
28455
- PROJECTS: projectsList,
28456
- JIRA_HOST: jiraHost,
28457
- JIRA_PROJECT: jiraProject,
28458
- HAS_JIRA: !!(jiraHost && jiraProject)
28454
+ PROJECTS: "(Use /cook to discover projects from your notes)",
28455
+ JIRA_HOST: "",
28456
+ JIRA_PROJECT: "",
28457
+ HAS_JIRA: false
28459
28458
  });
28460
28459
  }
28461
28460
  const agentsContent = renderTemplate(agentsTemplate, {
@@ -28475,119 +28474,23 @@ async function applyPresetOverlay(ctx, presetConfig, presetDir) {
28475
28474
  }
28476
28475
  ctx.directories.push(...presetConfig.directories);
28477
28476
  const allTemplateNames = [];
28478
- const templateDest = path6.join(ctx.vaultPath, "Knowledge/templates");
28479
28477
  const presetTemplatesDir = path6.join(presetDir, "templates");
28480
28478
  if (await fs.pathExists(presetTemplatesDir)) {
28479
+ const templateDest = path6.join(ctx.vaultPath, "templates");
28481
28480
  await fs.ensureDir(templateDest);
28482
28481
  const files = await fs.readdir(presetTemplatesDir);
28483
28482
  for (const file2 of files) {
28484
28483
  await fs.copy(path6.join(presetTemplatesDir, file2), path6.join(templateDest, file2), { overwrite: false });
28485
28484
  allTemplateNames.push(file2.replace(/\.md$/, ""));
28486
28485
  ctx.filesCreated++;
28487
- ctx.installedFiles.templates.push(`Knowledge/templates/${file2}`);
28486
+ ctx.installedFiles.templates.push(`templates/${file2}`);
28488
28487
  }
28489
28488
  }
28490
28489
  return allTemplateNames;
28491
28490
  }
28492
- async function createPeopleNotes(ctx, members) {
28493
- if (members.length === 0)
28494
- return;
28495
- await fs.ensureDir(path6.join(ctx.vaultPath, "People"));
28496
- if (!ctx.directories.includes("People")) {
28497
- ctx.directories.push("People");
28498
- }
28499
- for (const member of members) {
28500
- const content = `---
28501
- title: "${member.name}"
28502
- type: person
28503
- team: "${ctx.kbName}"
28504
- role: "${member.role}"
28505
- status: active
28506
- tags: [person]
28507
- ---
28508
-
28509
- # ${member.name}
28510
-
28511
- **Role**: ${member.role}
28512
- **Team**: ${ctx.kbName}
28513
- `;
28514
- const memberPath = path6.join(ctx.vaultPath, `People/${member.name}.md`);
28515
- if (!await fs.pathExists(memberPath)) {
28516
- await fs.writeFile(memberPath, content);
28517
- ctx.filesCreated++;
28518
- }
28519
- }
28520
- }
28521
- async function createProjectNotes(ctx, projects) {
28522
- if (projects.length === 0)
28523
- return;
28524
- await fs.ensureDir(path6.join(ctx.vaultPath, "Projects"));
28525
- if (!ctx.directories.includes("Projects")) {
28526
- ctx.directories.push("Projects");
28527
- }
28528
- for (const project of projects) {
28529
- const content = `---
28530
- title: "${project.name}"
28531
- type: feature
28532
- status: active
28533
- date: ${today()}
28534
- team: "${ctx.kbName}"
28535
- jira: ""
28536
- stakeholders: []
28537
- priority: ""
28538
- tags: [project]
28539
- ---
28540
-
28541
- # ${project.name}
28542
-
28543
- ${project.description}
28544
- `;
28545
- const projectPath = path6.join(ctx.vaultPath, `Projects/${project.name}.md`);
28546
- if (!await fs.pathExists(projectPath)) {
28547
- await fs.writeFile(projectPath, content);
28548
- ctx.filesCreated++;
28549
- }
28550
- }
28551
- }
28552
- async function createTeamIndex(ctx, members, projects) {
28553
- await fs.ensureDir(path6.join(ctx.vaultPath, "People"));
28554
- if (!ctx.directories.includes("People")) {
28555
- ctx.directories.push("People");
28556
- }
28557
- let teamIndexContent = `---
28558
- title: "${ctx.kbName} Team"
28559
- type: reference
28560
- team: "${ctx.kbName}"
28561
- tags: [team]
28562
- ---
28563
-
28564
- # ${ctx.kbName} Team
28565
-
28566
- ## Members
28567
-
28568
- `;
28569
- if (members.length > 0) {
28570
- teamIndexContent += "| Name | Role |\n|------|------|\n";
28571
- teamIndexContent += members.map((m) => `| [[${m.name}]] | ${m.role} |`).join("\n");
28572
- } else {
28573
- teamIndexContent += "(No members added yet)";
28574
- }
28575
- teamIndexContent += "\n\n## Active Projects\n\n";
28576
- if (projects.length > 0) {
28577
- teamIndexContent += projects.map((p) => `- [[${p.name}]] \u2014 ${p.description}`).join("\n");
28578
- } else {
28579
- teamIndexContent += "(No projects added yet)";
28580
- }
28581
- teamIndexContent += "\n";
28582
- const teamIndexPath = path6.join(ctx.vaultPath, `People/${ctx.kbName} Team.md`);
28583
- if (!await fs.pathExists(teamIndexPath)) {
28584
- await fs.writeFile(teamIndexPath, teamIndexContent);
28585
- ctx.filesCreated++;
28586
- }
28587
- }
28588
28491
  async function createVault(config2) {
28589
- const { kbName, vaultPath, members, projects, glossaryEntries, jiraHost, jiraProject, preset } = config2;
28590
- const presetName = preset ?? "pm-tpm";
28492
+ const { kbName, vaultPath, preset } = config2;
28493
+ const presetName = preset ?? "minimal";
28591
28494
  const { config: presetConfig, presetsDir } = loadPreset(presetName);
28592
28495
  const presetDir = path6.join(presetsDir, presetName);
28593
28496
  const initMode = detectInitMode(vaultPath);
@@ -28600,15 +28503,10 @@ async function createVault(config2) {
28600
28503
  ctx.mcpServices.push(info);
28601
28504
  }
28602
28505
  }
28603
- await createMinimalCore(ctx, glossaryEntries);
28604
- const allTemplateNames = await applyPresetOverlay(ctx, presetConfig, presetDir);
28605
- await createAgentsMd(ctx, config2.ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject);
28606
- await createPeopleNotes(ctx, members);
28607
- await createProjectNotes(ctx, projects);
28608
- const hasPeopleDir = presetConfig.directories.includes("People") || members.length > 0;
28609
- if (hasPeopleDir) {
28610
- await createTeamIndex(ctx, members, projects);
28611
- }
28506
+ await createMinimalCore(ctx);
28507
+ await createLlmWikiCore(ctx, config2.wikiDomain);
28508
+ await applyPresetOverlay(ctx, presetConfig, presetDir);
28509
+ await createAgentsMd(ctx, config2.ownerName, presetConfig, presetDir);
28612
28510
  await configureOpenCodeProject(ctx.vaultPath, ctx.installedFiles);
28613
28511
  const mcpOptions = {};
28614
28512
  if (config2.mcpSkip && config2.mcpSkip.length > 0) {
@@ -28675,27 +28573,33 @@ async function configureOpenCodeProject(vaultPath, installedFiles) {
28675
28573
  }
28676
28574
  }
28677
28575
  }
28678
- const byoaoSkillsSrc = path6.join(assetsDir, "..", "skills");
28679
- const commandsDest = path6.join(vaultPath, ".opencode", "commands");
28576
+ const byoaoSkillsSrc = path6.join(assetsDir, "skills");
28680
28577
  if (await fs.pathExists(byoaoSkillsSrc)) {
28681
- await fs.ensureDir(commandsDest);
28682
- const files = await fs.readdir(byoaoSkillsSrc);
28683
- for (const file2 of files) {
28684
- if (file2.endsWith(".md")) {
28685
- await fs.copy(path6.join(byoaoSkillsSrc, file2), path6.join(commandsDest, file2), { overwrite: true });
28686
- installedFiles.commands.push(`.opencode/commands/${file2}`);
28578
+ const entries = await fs.readdir(byoaoSkillsSrc, { withFileTypes: true });
28579
+ for (const entry of entries) {
28580
+ if (entry.isDirectory()) {
28581
+ const srcSkill = path6.join(byoaoSkillsSrc, entry.name, "SKILL.md");
28582
+ if (await fs.pathExists(srcSkill)) {
28583
+ const destDir = path6.join(skillsDest, entry.name);
28584
+ await fs.ensureDir(destDir);
28585
+ await fs.copy(srcSkill, path6.join(destDir, "SKILL.md"), { overwrite: true });
28586
+ installedFiles.skills.push(`.opencode/skills/${entry.name}/SKILL.md`);
28587
+ }
28687
28588
  }
28688
28589
  }
28689
28590
  }
28690
28591
  }
28691
28592
  function resolveAssetsDir() {
28593
+ const distAssets = path6.resolve(import.meta.dirname, "assets");
28692
28594
  const srcAssets = path6.resolve(import.meta.dirname, "..", "assets");
28693
- const distAssets = path6.resolve(import.meta.dirname, "..", "..", "src", "assets");
28694
- if (fs.existsSync(srcAssets))
28695
- return srcAssets;
28595
+ const devAssets = path6.resolve(import.meta.dirname, "..", "..", "src", "assets");
28696
28596
  if (fs.existsSync(distAssets))
28697
28597
  return distAssets;
28698
- return srcAssets;
28598
+ if (fs.existsSync(srcAssets))
28599
+ return srcAssets;
28600
+ if (fs.existsSync(devAssets))
28601
+ return devAssets;
28602
+ return distAssets;
28699
28603
  }
28700
28604
 
28701
28605
  // dist/vault/obsidian-check.js
@@ -28815,26 +28719,13 @@ function formatObsidianStatus(status) {
28815
28719
  import path7 from "node:path";
28816
28720
  import os3 from "node:os";
28817
28721
  var byoao_init_vault = tool({
28818
- description: "Create a personal knowledge base in Obsidian. Creates directory structure, templates, glossary, agent routing file (AGENTS.md), and optional people/project notes with wikilinks. Checks that Obsidian is installed first.",
28722
+ description: "Create an LLM Wiki knowledge base in Obsidian. Sets up agent directories (entities/, concepts/, comparisons/, queries/), SCHEMA.md, log.md, and AI routing (AGENTS.md). Your existing notes become raw material for /cook.",
28819
28723
  args: {
28820
28724
  kbName: tool.schema.string().describe(`Knowledge base name (e.g. "Jay's KB")`),
28821
28725
  ownerName: tool.schema.string().optional().describe("Owner's name"),
28822
28726
  vaultPath: tool.schema.string().optional().describe("Where to create the vault. Defaults to ~/Documents/{kbName}"),
28823
- members: tool.schema.array(tool.schema.object({
28824
- name: tool.schema.string().describe("Person's name"),
28825
- role: tool.schema.string().optional().describe("Person's role")
28826
- })).optional().describe("People to create notes for"),
28827
- projects: tool.schema.array(tool.schema.object({
28828
- name: tool.schema.string().describe("Project name"),
28829
- description: tool.schema.string().optional().describe("One-line description")
28830
- })).optional().describe("Active projects to create project notes for"),
28831
- glossaryEntries: tool.schema.array(tool.schema.object({
28832
- term: tool.schema.string().describe("Domain term"),
28833
- definition: tool.schema.string().describe("Brief definition")
28834
- })).optional().describe("Domain terms to add to the glossary"),
28835
- jiraHost: tool.schema.string().optional().describe("JIRA host (e.g. 'mycompany.atlassian.net')"),
28836
- jiraProject: tool.schema.string().optional().describe("JIRA project key (e.g. 'HDR')"),
28837
- preset: tool.schema.string().optional().describe("Role preset (default: 'minimal'). Use 'pm-tpm' for project management.")
28727
+ preset: tool.schema.string().optional().describe("Work profile (default: 'minimal'). Use 'pm-tpm' for PM/TPM with Atlassian + BigQuery."),
28728
+ wikiDomain: tool.schema.string().optional().describe("What domain this knowledge base covers (e.g. 'AI/ML research', 'product management')")
28838
28729
  },
28839
28730
  async execute(args) {
28840
28731
  const obsidianStatus = checkObsidian();
@@ -28848,12 +28739,8 @@ Please install Obsidian first, then try again.`;
28848
28739
  kbName: args.kbName,
28849
28740
  ownerName: args.ownerName || "",
28850
28741
  vaultPath: resolvedPath,
28851
- members: args.members || [],
28852
- projects: args.projects || [],
28853
- glossaryEntries: args.glossaryEntries || [],
28854
- jiraHost: args.jiraHost || "",
28855
- jiraProject: args.jiraProject || "",
28856
- preset: args.preset || "minimal"
28742
+ preset: args.preset || "minimal",
28743
+ wikiDomain: args.wikiDomain || ""
28857
28744
  });
28858
28745
  const result = await createVault(config2);
28859
28746
  let output = `\u2713 Knowledge base created at: ${result.vaultPath}
@@ -28953,188 +28840,18 @@ Open in Obsidian: "Open folder as vault" \u2192 select "${result.vaultPath}"`;
28953
28840
  if (result.initMode === "existing" || result.initMode === "obsidian-vault") {
28954
28841
  output += `
28955
28842
 
28956
- \u2192 Next step: run /weave now \u2014 it will scan your existing notes, add frontmatter metadata (including dates), create wikilinks between related content, and build your Glossary from frequently mentioned concepts.`;
28843
+ \u2192 Next step: run /cook now \u2014 it will scan your existing notes, identify entities and concepts, and compile them into structured knowledge pages.`;
28957
28844
  } else {
28958
28845
  output += `
28959
28846
 
28960
- \u2192 Next step: add a few notes, then run /weave to connect them into a knowledge graph. See "Start Here" in the vault for details.`;
28847
+ \u2192 Next step: add a few notes, then run /cook to compile them into knowledge pages. See "Start Here" in the vault for details.`;
28961
28848
  }
28962
28849
  return output;
28963
28850
  }
28964
28851
  });
28965
28852
 
28966
- // dist/vault/member.js
28967
- import path8 from "node:path";
28968
- async function addMember(input) {
28969
- const { vaultPath, name, role, team } = input;
28970
- let wikilinksAdded = 0;
28971
- const personPath = path8.join(vaultPath, `People/${name}.md`);
28972
- if (await fs.pathExists(personPath)) {
28973
- throw new Error(`Person note already exists: ${personPath}`);
28974
- }
28975
- const content = `---
28976
- title: "${name}"
28977
- type: person
28978
- team: "${team}"
28979
- role: "${role}"
28980
- status: active
28981
- tags: [person]
28982
- ---
28983
-
28984
- # ${name}
28985
-
28986
- **Role**: ${role}
28987
- **Team**: ${team}
28988
- `;
28989
- await fs.writeFile(personPath, content);
28990
- const teamFiles = await fs.readdir(path8.join(vaultPath, "People"));
28991
- const teamIndexFile = teamFiles.find((f) => f.endsWith("Team.md"));
28992
- if (teamIndexFile) {
28993
- const teamIndexPath = path8.join(vaultPath, "People", teamIndexFile);
28994
- let teamContent = await fs.readFile(teamIndexPath, "utf-8");
28995
- const tableRow = `| [[${name}]] | ${role} |`;
28996
- if (teamContent.includes("|------|------|")) {
28997
- teamContent = teamContent.replace(/(^\|------|------\|$)/m, `$1
28998
- ${tableRow}`);
28999
- wikilinksAdded++;
29000
- }
29001
- await fs.writeFile(teamIndexPath, teamContent);
29002
- }
29003
- for (const agentFile of ["AGENTS.md", "AGENT.md"]) {
29004
- const agentPath = path8.join(vaultPath, agentFile);
29005
- if (await fs.pathExists(agentPath)) {
29006
- let agentContent = await fs.readFile(agentPath, "utf-8");
29007
- if (agentContent.includes("(No members added yet")) {
29008
- const table = `| Name | Role |
29009
- |------|------|
29010
- | [[${name}]] | ${role} |`;
29011
- agentContent = agentContent.replace(/\(No members added yet[^)]*\)/, table);
29012
- wikilinksAdded++;
29013
- } else if (agentContent.includes("|------|------|")) {
29014
- const teamSectionMatch = agentContent.match(/## Team[^\n]*\n[\s\S]*?(\|------|------\|[^\n]*(?:\n\|[^\n]*)*)/);
29015
- if (teamSectionMatch) {
29016
- const existingTable = teamSectionMatch[1];
29017
- const newTable = existingTable + `
29018
- | [[${name}]] | ${role} |`;
29019
- agentContent = agentContent.replace(existingTable, newTable);
29020
- wikilinksAdded++;
29021
- }
29022
- }
29023
- await fs.writeFile(agentPath, agentContent);
29024
- }
29025
- }
29026
- return { filePath: personPath, wikilinksAdded };
29027
- }
29028
-
29029
- // dist/tools/add-person.js
29030
- var byoao_add_person = tool({
29031
- description: "Add a person note to an existing vault. Creates a person note in People/ and updates the team index and AGENTS.md wikilinks.",
29032
- args: {
29033
- vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
29034
- name: tool.schema.string().describe("Person's full name"),
29035
- role: tool.schema.string().optional().describe("Person's role/title"),
29036
- team: tool.schema.string().optional().describe("Team or KB name")
29037
- },
29038
- async execute(args) {
29039
- const result = await addMember({
29040
- vaultPath: args.vaultPath,
29041
- name: args.name,
29042
- role: args.role || "",
29043
- team: args.team || ""
29044
- });
29045
- return `Added person: ${args.name}
29046
- File: ${result.filePath}
29047
- Wikilinks updated: ${result.wikilinksAdded}`;
29048
- }
29049
- });
29050
-
29051
- // dist/vault/project.js
29052
- import path9 from "node:path";
29053
- async function addProject(input) {
29054
- const { vaultPath, name, description, team } = input;
29055
- let wikilinksAdded = 0;
29056
- const projectPath = path9.join(vaultPath, `Projects/${name}.md`);
29057
- if (await fs.pathExists(projectPath)) {
29058
- throw new Error(`Project note already exists: ${projectPath}`);
29059
- }
29060
- const content = `---
29061
- title: "${name}"
29062
- type: feature
29063
- status: active
29064
- date: ${today()}
29065
- team: "${team}"
29066
- jira: ""
29067
- stakeholders: []
29068
- priority: ""
29069
- tags: [project]
29070
- ---
29071
-
29072
- # ${name}
29073
-
29074
- ${description}
29075
- `;
29076
- await fs.writeFile(projectPath, content);
29077
- const peoplePath = path9.join(vaultPath, "People");
29078
- if (await fs.pathExists(peoplePath)) {
29079
- const teamFiles = await fs.readdir(peoplePath);
29080
- const teamIndexFile = teamFiles.find((f) => f.endsWith("Team.md"));
29081
- if (teamIndexFile) {
29082
- const teamIndexPath = path9.join(peoplePath, teamIndexFile);
29083
- let teamContent = await fs.readFile(teamIndexPath, "utf-8");
29084
- const projectLine = `- [[${name}]] \u2014 ${description}`;
29085
- if (teamContent.includes("(No projects added yet)")) {
29086
- teamContent = teamContent.replace("(No projects added yet)", projectLine);
29087
- } else if (teamContent.includes("## Active Projects")) {
29088
- teamContent = teamContent.replace(/(## Active Projects\n\n)([\s\S]*?)(\n\n|$)/, `$1$2
29089
- ${projectLine}$3`);
29090
- }
29091
- wikilinksAdded++;
29092
- await fs.writeFile(teamIndexPath, teamContent);
29093
- }
29094
- }
29095
- for (const agentFile of ["AGENTS.md", "AGENT.md"]) {
29096
- const agentPath = path9.join(vaultPath, agentFile);
29097
- if (await fs.pathExists(agentPath)) {
29098
- let agentContent = await fs.readFile(agentPath, "utf-8");
29099
- const projectLine = `- [[${name}]] \u2014 ${description}`;
29100
- if (agentContent.includes("(No projects added yet")) {
29101
- agentContent = agentContent.replace(/\(No projects added yet[^)]*\)/, projectLine);
29102
- wikilinksAdded++;
29103
- } else if (agentContent.includes("## Active Projects")) {
29104
- agentContent = agentContent.replace(/(## Active Projects[^\n]*\n\n)([\s\S]*?)(\n\n|$)/, `$1$2
29105
- ${projectLine}$3`);
29106
- wikilinksAdded++;
29107
- }
29108
- await fs.writeFile(agentPath, agentContent);
29109
- }
29110
- }
29111
- return { filePath: projectPath, wikilinksAdded };
29112
- }
29113
-
29114
- // dist/tools/add-project.js
29115
- var byoao_add_project = tool({
29116
- description: "Add a new project note to an existing vault. Creates a project note in Projects/ and updates the team index and AGENTS.md wikilinks.",
29117
- args: {
29118
- vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
29119
- name: tool.schema.string().describe("Project name"),
29120
- description: tool.schema.string().optional().describe("One-line project description"),
29121
- team: tool.schema.string().optional().describe("Team name")
29122
- },
29123
- async execute(args) {
29124
- const result = await addProject({
29125
- vaultPath: args.vaultPath,
29126
- name: args.name,
29127
- description: args.description || "",
29128
- team: args.team || ""
29129
- });
29130
- return `\u2713 Added project: ${args.name}
29131
- File: ${result.filePath}
29132
- Wikilinks updated: ${result.wikilinksAdded}`;
29133
- }
29134
- });
29135
-
29136
28853
  // dist/vault/status.js
29137
- import path10 from "node:path";
28854
+ import path8 from "node:path";
29138
28855
  async function getAllMarkdownFiles(dirPath) {
29139
28856
  const results = [];
29140
28857
  async function walk(dir) {
@@ -29142,7 +28859,7 @@ async function getAllMarkdownFiles(dirPath) {
29142
28859
  return;
29143
28860
  const entries = await fs.readdir(dir, { withFileTypes: true });
29144
28861
  for (const entry of entries) {
29145
- const fullPath = path10.join(dir, entry.name);
28862
+ const fullPath = path8.join(dir, entry.name);
29146
28863
  if (entry.isDirectory()) {
29147
28864
  if (!entry.name.startsWith(".")) {
29148
28865
  await walk(fullPath);
@@ -29173,11 +28890,15 @@ async function getVaultStatus(vaultPath) {
29173
28890
  brokenLinks: [],
29174
28891
  directories: {},
29175
28892
  hasObsidianConfig: false,
29176
- hasAgentMd: false
28893
+ hasAgentMd: false,
28894
+ agentPages: { entities: 0, concepts: 0, comparisons: 0, queries: 0 },
28895
+ hasSchema: false,
28896
+ hasLog: false,
28897
+ hasIndexBase: false
29177
28898
  };
29178
28899
  }
29179
28900
  const allFiles = await getAllMarkdownFiles(vaultPath);
29180
- const noteNames = new Set(allFiles.map((f) => path10.basename(f, ".md")));
28901
+ const noteNames = new Set(allFiles.map((f) => path8.basename(f, ".md")));
29181
28902
  let wikilinkCount = 0;
29182
28903
  const brokenLinksSet = /* @__PURE__ */ new Set();
29183
28904
  for (const file2 of allFiles) {
@@ -29202,12 +28923,24 @@ async function getVaultStatus(vaultPath) {
29202
28923
  "Daily"
29203
28924
  ];
29204
28925
  for (const dir of topDirs) {
29205
- const dirPath = path10.join(vaultPath, dir);
28926
+ const dirPath = path8.join(vaultPath, dir);
29206
28927
  if (await fs.pathExists(dirPath)) {
29207
28928
  const files = await getAllMarkdownFiles(dirPath);
29208
28929
  directories[dir] = files.length;
29209
28930
  }
29210
28931
  }
28932
+ const agentDirNames = ["entities", "concepts", "comparisons", "queries"];
28933
+ const agentPages = {
28934
+ entities: 0,
28935
+ concepts: 0,
28936
+ comparisons: 0,
28937
+ queries: 0
28938
+ };
28939
+ for (const name of agentDirNames) {
28940
+ const dirPath = path8.join(vaultPath, name);
28941
+ const mdFiles = await getAllMarkdownFiles(dirPath);
28942
+ agentPages[name] = mdFiles.length;
28943
+ }
29211
28944
  return {
29212
28945
  exists: true,
29213
28946
  vaultPath,
@@ -29215,8 +28948,12 @@ async function getVaultStatus(vaultPath) {
29215
28948
  wikilinkCount,
29216
28949
  brokenLinks: Array.from(brokenLinksSet),
29217
28950
  directories,
29218
- hasObsidianConfig: await fs.pathExists(path10.join(vaultPath, ".obsidian")),
29219
- hasAgentMd: await fs.pathExists(path10.join(vaultPath, "AGENTS.md")) || await fs.pathExists(path10.join(vaultPath, "AGENT.md"))
28951
+ hasObsidianConfig: await fs.pathExists(path8.join(vaultPath, ".obsidian")),
28952
+ hasAgentMd: await fs.pathExists(path8.join(vaultPath, "AGENTS.md")) || await fs.pathExists(path8.join(vaultPath, "AGENT.md")),
28953
+ agentPages,
28954
+ hasSchema: await fs.pathExists(path8.join(vaultPath, "SCHEMA.md")),
28955
+ hasLog: await fs.pathExists(path8.join(vaultPath, "log.md")),
28956
+ hasIndexBase: await fs.pathExists(path8.join(vaultPath, "INDEX.base"))
29220
28957
  };
29221
28958
  }
29222
28959
  function formatVaultStatus(status) {
@@ -29236,6 +28973,10 @@ function formatVaultStatus(status) {
29236
28973
  lines.push("");
29237
28974
  lines.push(`Config: ${status.hasObsidianConfig ? "\u2713" : "\u2717"} .obsidian/`);
29238
28975
  lines.push(`Agent: ${status.hasAgentMd ? "\u2713" : "\u2717"} AGENTS.md`);
28976
+ lines.push("");
28977
+ lines.push("LLM Wiki v2 (agent pages):");
28978
+ lines.push(` entities: ${status.agentPages.entities} \xB7 concepts: ${status.agentPages.concepts} \xB7 comparisons: ${status.agentPages.comparisons} \xB7 queries: ${status.agentPages.queries}`);
28979
+ lines.push(` SCHEMA.md: ${status.hasSchema ? "\u2713" : "\u2717"} \xB7 log.md: ${status.hasLog ? "\u2713" : "\u2717"} \xB7 INDEX.base: ${status.hasIndexBase ? "\u2713" : "\u2717"}`);
29239
28980
  if (status.brokenLinks.length > 0) {
29240
28981
  lines.push("");
29241
28982
  lines.push(`\u26A0\uFE0F Broken links (${status.brokenLinks.length}):`);
@@ -29253,7 +28994,7 @@ function formatVaultStatus(status) {
29253
28994
 
29254
28995
  // dist/tools/vault-status.js
29255
28996
  var byoao_vault_status = tool({
29256
- description: "Check the health of an Obsidian vault \u2014 note count, wikilink count, broken links, directory breakdown, and Obsidian installation status.",
28997
+ description: "Check the health of an Obsidian vault \u2014 note count, wikilink count, broken links, directory breakdown, Obsidian installation status, and LLM Wiki v2 signals: per-directory markdown counts under entities/, concepts/, comparisons/, queries/, plus presence of SCHEMA.md, log.md, and INDEX.base at the vault root.",
29257
28998
  args: {
29258
28999
  vaultPath: tool.schema.string().describe("Path to the Obsidian vault")
29259
29000
  },
@@ -29268,12 +29009,18 @@ var byoao_vault_status = tool({
29268
29009
  });
29269
29010
 
29270
29011
  // dist/vault/doctor.js
29271
- import path11 from "node:path";
29012
+ import path9 from "node:path";
29013
+ import { stat } from "node:fs/promises";
29014
+ var LLM_WIKI_V2_AGENT_DIRS = ["entities", "concepts", "comparisons", "queries"];
29015
+ function isAgentWikiPage(relativePath) {
29016
+ const top = relativePath.split(path9.sep)[0];
29017
+ return LLM_WIKI_V2_AGENT_DIRS.includes(top);
29018
+ }
29272
29019
  async function collectMarkdownFiles(dir) {
29273
29020
  const results = [];
29274
29021
  const entries = await fs.readdir(dir, { withFileTypes: true });
29275
29022
  for (const entry of entries) {
29276
- const fullPath = path11.join(dir, entry.name);
29023
+ const fullPath = path9.join(dir, entry.name);
29277
29024
  if (entry.isDirectory()) {
29278
29025
  if (entry.name === ".obsidian" || entry.name === ".git")
29279
29026
  continue;
@@ -29294,10 +29041,10 @@ function extractWikilinks2(content) {
29294
29041
  async function getVaultDiagnosis(vaultPath) {
29295
29042
  const issues = [];
29296
29043
  const allFiles = await collectMarkdownFiles(vaultPath);
29297
- const noteNames = new Set(allFiles.map((f) => path11.basename(f, ".md")));
29044
+ const noteNames = new Set(allFiles.map((f) => path9.basename(f, ".md")));
29298
29045
  let healthyNotes = 0;
29299
29046
  for (const filePath of allFiles) {
29300
- const relativePath = path11.relative(vaultPath, filePath);
29047
+ const relativePath = path9.relative(vaultPath, filePath);
29301
29048
  if (relativePath.startsWith("Knowledge/templates/"))
29302
29049
  continue;
29303
29050
  const content = await fs.readFile(filePath, "utf-8");
@@ -29331,15 +29078,26 @@ async function getVaultDiagnosis(vaultPath) {
29331
29078
  hasIssue = true;
29332
29079
  }
29333
29080
  }
29081
+ const contra = data?.contradictions;
29082
+ const contraList = Array.isArray(contra) && contra.some((x) => x != null && String(x).trim() !== "");
29083
+ const contraStr = typeof contra === "string" && contra.trim() !== "";
29084
+ if (contraList || contraStr) {
29085
+ issues.push({
29086
+ severity: "warning",
29087
+ category: "contradiction",
29088
+ file: relativePath,
29089
+ message: "Note lists `contradictions` in frontmatter \u2014 review conflicting claims against linked agent pages"
29090
+ });
29091
+ }
29334
29092
  if (!hasIssue)
29335
29093
  healthyNotes++;
29336
29094
  }
29337
29095
  let agentContent = null;
29338
- let agentResolvedPath = path11.join(vaultPath, "AGENTS.md");
29096
+ let agentResolvedPath = path9.join(vaultPath, "AGENTS.md");
29339
29097
  if (await fs.pathExists(agentResolvedPath)) {
29340
29098
  agentContent = await fs.readFile(agentResolvedPath, "utf-8");
29341
29099
  } else {
29342
- agentResolvedPath = path11.join(vaultPath, "AGENT.md");
29100
+ agentResolvedPath = path9.join(vaultPath, "AGENT.md");
29343
29101
  if (await fs.pathExists(agentResolvedPath)) {
29344
29102
  agentContent = await fs.readFile(agentResolvedPath, "utf-8");
29345
29103
  }
@@ -29356,24 +29114,54 @@ async function getVaultDiagnosis(vaultPath) {
29356
29114
  }
29357
29115
  }
29358
29116
  }
29117
+ for (const dirName of LLM_WIKI_V2_AGENT_DIRS) {
29118
+ const dirPath = path9.join(vaultPath, dirName);
29119
+ const exists = await fs.pathExists(dirPath);
29120
+ const isDir = exists && (await stat(dirPath)).isDirectory();
29121
+ if (!isDir) {
29122
+ issues.push({
29123
+ severity: "warning",
29124
+ category: "agent-drift",
29125
+ message: `LLM Wiki v2: expected agent directory \`${dirName}/\` at vault root`
29126
+ });
29127
+ }
29128
+ }
29129
+ const schemaPath = path9.join(vaultPath, "SCHEMA.md");
29130
+ if (!await fs.pathExists(schemaPath)) {
29131
+ issues.push({
29132
+ severity: "warning",
29133
+ category: "agent-drift",
29134
+ message: "LLM Wiki v2: missing SCHEMA.md at vault root"
29135
+ });
29136
+ }
29137
+ const logMdPath = path9.join(vaultPath, "log.md");
29138
+ if (!await fs.pathExists(logMdPath)) {
29139
+ issues.push({
29140
+ severity: "warning",
29141
+ category: "agent-drift",
29142
+ message: "LLM Wiki v2: missing log.md at vault root"
29143
+ });
29144
+ }
29359
29145
  const allLinksMap = /* @__PURE__ */ new Map();
29360
29146
  const incomingLinks = /* @__PURE__ */ new Set();
29361
29147
  for (const filePath of allFiles) {
29362
29148
  const content = await fs.readFile(filePath, "utf-8");
29363
29149
  const links = extractWikilinks2(content);
29364
- const name = path11.basename(filePath, ".md");
29150
+ const name = path9.basename(filePath, ".md");
29365
29151
  allLinksMap.set(name, new Set(links));
29366
29152
  for (const link of links) {
29367
29153
  incomingLinks.add(link);
29368
29154
  }
29369
29155
  }
29370
29156
  for (const filePath of allFiles) {
29371
- const relativePath = path11.relative(vaultPath, filePath);
29157
+ const relativePath = path9.relative(vaultPath, filePath);
29372
29158
  if (relativePath.startsWith("Knowledge/templates/"))
29373
29159
  continue;
29374
29160
  if (relativePath === "AGENT.md" || relativePath === "AGENTS.md")
29375
29161
  continue;
29376
- const name = path11.basename(filePath, ".md");
29162
+ if (isAgentWikiPage(relativePath))
29163
+ continue;
29164
+ const name = path9.basename(filePath, ".md");
29377
29165
  const outgoing = allLinksMap.get(name) || /* @__PURE__ */ new Set();
29378
29166
  const hasIncoming = incomingLinks.has(name);
29379
29167
  const hasOutgoing = outgoing.size > 0;
@@ -29387,7 +29175,7 @@ async function getVaultDiagnosis(vaultPath) {
29387
29175
  }
29388
29176
  }
29389
29177
  for (const filePath of allFiles) {
29390
- const relativePath = path11.relative(vaultPath, filePath);
29178
+ const relativePath = path9.relative(vaultPath, filePath);
29391
29179
  const content = await fs.readFile(filePath, "utf-8");
29392
29180
  const links = extractWikilinks2(content);
29393
29181
  for (const link of links) {
@@ -29413,7 +29201,7 @@ async function getVaultDiagnosis(vaultPath) {
29413
29201
 
29414
29202
  // dist/tools/vault-doctor.js
29415
29203
  var byoao_vault_doctor = tool({
29416
- description: "Scan an Obsidian vault and produce a diagnostic report. Checks: missing frontmatter, missing type/tags, AGENTS.md drift, orphan notes, broken wikilinks.",
29204
+ description: "Scan an Obsidian vault and produce a diagnostic report. Checks: missing frontmatter, missing type/tags, AGENTS.md drift, orphan notes (user notes only; agent pages under entities/, concepts/, comparisons/, queries/ are excluded), broken wikilinks, LLM Wiki v2 layout (agent directories, SCHEMA.md, log.md at vault root), and notes with contradictions frontmatter.",
29417
29205
  args: {
29418
29206
  vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault")
29419
29207
  },
@@ -29479,154 +29267,16 @@ var byoao_switch_provider = tool({
29479
29267
  }
29480
29268
  });
29481
29269
 
29482
- // dist/vault/graph-health.js
29483
- import path12 from "node:path";
29484
-
29485
- // dist/vault/obsidian-cli.js
29486
- import { execFileSync, execSync as execSync3 } from "node:child_process";
29487
- import { platform as platform2 } from "node:os";
29488
- var _cliAvailableCache = null;
29489
- function isObsidianCliAvailable() {
29490
- if (_cliAvailableCache !== null)
29491
- return _cliAvailableCache;
29492
- const os5 = platform2();
29493
- try {
29494
- if (os5 === "darwin") {
29495
- execSync3("pgrep -x Obsidian", { stdio: "pipe", timeout: 3e3 });
29496
- _cliAvailableCache = true;
29497
- } else if (os5 === "linux") {
29498
- execSync3("pgrep -x obsidian", { stdio: "pipe", timeout: 3e3 });
29499
- _cliAvailableCache = true;
29500
- } else if (os5 === "win32") {
29501
- const result = execSync3('tasklist /FI "IMAGENAME eq Obsidian.exe" /NH', { stdio: "pipe", timeout: 3e3, encoding: "utf-8" });
29502
- _cliAvailableCache = result.includes("Obsidian.exe");
29503
- } else {
29504
- _cliAvailableCache = false;
29505
- }
29506
- } catch {
29507
- _cliAvailableCache = false;
29508
- }
29509
- return _cliAvailableCache;
29510
- }
29511
- function execObsidianCmd(args) {
29512
- try {
29513
- const output = execFileSync("obsidian", args, {
29514
- stdio: "pipe",
29515
- encoding: "utf-8",
29516
- timeout: 1e4
29517
- });
29518
- return { success: true, output: output.trim() };
29519
- } catch (err) {
29520
- const msg = err instanceof Error ? err.message : String(err);
29521
- return { success: false, output: "", error: msg };
29522
- }
29523
- }
29524
-
29525
- // dist/vault/retrieval-types.js
29526
- var DEFAULT_RESULT_LIMIT = 20;
29527
-
29528
- // dist/vault/graph-health.js
29529
- var ALL_CHECKS = ["orphans", "unresolved", "deadends"];
29530
- function parseCheckOutput(check2, output) {
29531
- const lines = output.split("\n").filter((l) => l.trim().length > 0);
29532
- return lines.map((line) => {
29533
- const trimmed = line.trim();
29534
- const isPath = trimmed.includes("/") || trimmed.endsWith(".md");
29535
- const title = isPath ? path12.basename(trimmed, ".md") : trimmed;
29536
- return {
29537
- title,
29538
- path: isPath ? trimmed : "",
29539
- file: title,
29540
- metadata: { check: check2 }
29541
- };
29542
- });
29543
- }
29544
- async function getGraphHealth(input) {
29545
- const { vaultPath, check: check2 = "all", limit = DEFAULT_RESULT_LIMIT } = input;
29546
- const mode = "graph-health";
29547
- const base = {
29548
- mode,
29549
- vault: vaultPath,
29550
- fallback: "none"
29551
- };
29552
- if (!isObsidianCliAvailable()) {
29553
- return {
29554
- ...base,
29555
- status: "runtime_unavailable",
29556
- summary: "Obsidian CLI not available",
29557
- results: [],
29558
- truncated: false,
29559
- diagnostics: ["Obsidian CLI not available"]
29560
- };
29561
- }
29562
- const checks = check2 === "all" ? ALL_CHECKS : [check2];
29563
- const allItems = [];
29564
- const diagnostics = [];
29565
- for (const checkType of checks) {
29566
- const cliResult = execObsidianCmd([checkType, "--vault", vaultPath]);
29567
- if (!cliResult.success) {
29568
- diagnostics.push(`${checkType} check failed: ${cliResult.error ?? "unknown error"}`);
29569
- continue;
29570
- }
29571
- if (cliResult.output.trim().length > 0) {
29572
- allItems.push(...parseCheckOutput(checkType, cliResult.output));
29573
- }
29574
- }
29575
- if (allItems.length === 0 && diagnostics.length === 0) {
29576
- return {
29577
- ...base,
29578
- status: "no_results",
29579
- summary: "No issues found \u2014 vault graph is healthy",
29580
- results: [],
29581
- truncated: false,
29582
- diagnostics
29583
- };
29584
- }
29585
- const truncated = allItems.length > limit;
29586
- const results = allItems.slice(0, limit);
29587
- return {
29588
- ...base,
29589
- status: allItems.length > 0 ? "ok" : "no_results",
29590
- summary: `Found ${allItems.length} graph issues across ${checks.join(", ")} checks`,
29591
- results,
29592
- truncated,
29593
- totalMatches: allItems.length,
29594
- diagnostics
29595
- };
29596
- }
29597
-
29598
- // dist/tools/graph-health.js
29599
- var byoao_graph_health = tool({
29600
- description: "Diagnose Obsidian vault graph health \u2014 find orphan notes (no links in or out), unresolved links (broken wikilinks), and dead-end notes. Uses Obsidian CLI for vault-aware analysis.",
29601
- args: {
29602
- vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
29603
- check: tool.schema.enum(["all", "orphans", "unresolved", "deadends"]).optional().describe("Which check to run: 'all' (default), 'orphans', 'unresolved', or 'deadends'"),
29604
- limit: tool.schema.number().optional().describe("Maximum number of results to return (default: 20)")
29605
- },
29606
- async execute(args) {
29607
- const result = await getGraphHealth({
29608
- vaultPath: args.vaultPath,
29609
- check: args.check,
29610
- limit: args.limit
29611
- });
29612
- return JSON.stringify(result, null, 2);
29613
- }
29614
- });
29615
-
29616
29270
  // dist/vault/upgrade.js
29617
- import path13 from "node:path";
29618
- var OBSIDIAN_CONFIG_FILES = [
29619
- "core-plugins.json",
29620
- "daily-notes.json",
29621
- "templates.json"
29622
- ];
29271
+ import path10 from "node:path";
29272
+ var OBSIDIAN_CONFIG_FILES = ["core-plugins.json"];
29623
29273
  async function scanInstalledAssets(vaultPath) {
29624
29274
  const skills = await scanSkillDirs(vaultPath);
29625
29275
  const commands = await scanDir(vaultPath, ".opencode/commands", ".md");
29626
29276
  const templates = await scanDir(vaultPath, "Knowledge/templates", ".md");
29627
29277
  const obsidianConfig = [];
29628
29278
  for (const file2 of OBSIDIAN_CONFIG_FILES) {
29629
- const abs = path13.join(vaultPath, ".obsidian", file2);
29279
+ const abs = path10.join(vaultPath, ".obsidian", file2);
29630
29280
  if (await fs.pathExists(abs)) {
29631
29281
  obsidianConfig.push(`.obsidian/${file2}`);
29632
29282
  }
@@ -29634,21 +29284,21 @@ async function scanInstalledAssets(vaultPath) {
29634
29284
  return { skills, commands, obsidianConfig, templates };
29635
29285
  }
29636
29286
  async function scanDir(vaultPath, relDir, ext) {
29637
- const absDir = path13.join(vaultPath, relDir);
29287
+ const absDir = path10.join(vaultPath, relDir);
29638
29288
  if (!await fs.pathExists(absDir))
29639
29289
  return [];
29640
29290
  const files = await fs.readdir(absDir);
29641
29291
  return files.filter((f) => f.endsWith(ext)).map((f) => `${relDir}/${f}`);
29642
29292
  }
29643
29293
  async function scanSkillDirs(vaultPath) {
29644
- const skillsRoot = path13.join(vaultPath, ".opencode", "skills");
29294
+ const skillsRoot = path10.join(vaultPath, ".opencode", "skills");
29645
29295
  if (!await fs.pathExists(skillsRoot))
29646
29296
  return [];
29647
29297
  const results = [];
29648
29298
  const entries = await fs.readdir(skillsRoot, { withFileTypes: true });
29649
29299
  for (const entry of entries) {
29650
29300
  if (entry.isDirectory()) {
29651
- const skillMd = path13.join(skillsRoot, entry.name, "SKILL.md");
29301
+ const skillMd = path10.join(skillsRoot, entry.name, "SKILL.md");
29652
29302
  if (await fs.pathExists(skillMd)) {
29653
29303
  results.push(`.opencode/skills/${entry.name}/SKILL.md`);
29654
29304
  }
@@ -29656,7 +29306,7 @@ async function scanSkillDirs(vaultPath) {
29656
29306
  }
29657
29307
  return results;
29658
29308
  }
29659
- var DEFAULT_PRESET = "pm-tpm";
29309
+ var DEFAULT_PRESET = "minimal";
29660
29310
  async function bootstrapManifest(vaultPath, preset) {
29661
29311
  const installedFiles = await scanInstalledAssets(vaultPath);
29662
29312
  await writeManifest(vaultPath, preset ?? DEFAULT_PRESET, installedFiles, "0.0.0");
@@ -29677,7 +29327,7 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
29677
29327
  const installed = new Set(manifest.infrastructure[key]);
29678
29328
  const shippedPaths = new Set(shipped.map((s) => s.relativePath));
29679
29329
  for (const entry of shipped) {
29680
- const onDisk = fs.existsSync(path13.join(vaultPath, entry.relativePath));
29330
+ const onDisk = fs.existsSync(path10.join(vaultPath, entry.relativePath));
29681
29331
  items.push({
29682
29332
  file: entry.relativePath,
29683
29333
  action: onDisk ? "update" : "add",
@@ -29700,23 +29350,140 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
29700
29350
  items
29701
29351
  };
29702
29352
  }
29353
+ var LLM_WIKI_AGENT_DIRS = ["entities", "concepts", "comparisons", "queries"];
29354
+ var LOG_MD_PLACEHOLDER = `# Agent Activity Log
29355
+
29356
+ Entries are appended here during /cook operations.
29357
+
29358
+ `;
29359
+ async function migrateV1ToV2Infrastructure(vaultPath) {
29360
+ for (const dir of LLM_WIKI_AGENT_DIRS) {
29361
+ const dirPath = path10.join(vaultPath, dir);
29362
+ if (!await fs.pathExists(dirPath)) {
29363
+ await fs.ensureDir(dirPath);
29364
+ }
29365
+ }
29366
+ const schemaPath = path10.join(vaultPath, "SCHEMA.md");
29367
+ if (!await fs.pathExists(schemaPath)) {
29368
+ const commonDir = getCommonDir();
29369
+ const schemaTemplatePath = path10.join(commonDir, "SCHEMA.md.hbs");
29370
+ let content;
29371
+ if (await fs.pathExists(schemaTemplatePath)) {
29372
+ const schemaTemplate = await fs.readFile(schemaTemplatePath, "utf-8");
29373
+ content = renderTemplate(schemaTemplate, {
29374
+ KB_NAME: path10.basename(vaultPath),
29375
+ WIKI_DOMAIN: ""
29376
+ });
29377
+ } else {
29378
+ content = `# SCHEMA
29379
+
29380
+ This file describes the vault knowledge schema. Update it as your model evolves.
29381
+
29382
+ `;
29383
+ }
29384
+ await fs.writeFile(schemaPath, content, "utf-8");
29385
+ }
29386
+ const logPath = path10.join(vaultPath, "log.md");
29387
+ if (!await fs.pathExists(logPath)) {
29388
+ await fs.writeFile(logPath, LOG_MD_PLACEHOLDER, "utf-8");
29389
+ }
29390
+ }
29391
+ var BYOAO_SKILL_NAMES = [
29392
+ "ask",
29393
+ "challenge",
29394
+ "connect",
29395
+ "cook",
29396
+ "diagnose",
29397
+ "drift",
29398
+ "health",
29399
+ "ideas",
29400
+ "organize",
29401
+ "prep",
29402
+ "trace",
29403
+ "wiki"
29404
+ ];
29405
+ async function migrateCommandsToSkills(vaultPath) {
29406
+ const commandsDir = path10.join(vaultPath, ".opencode", "commands");
29407
+ if (!await fs.pathExists(commandsDir))
29408
+ return;
29409
+ const skillsDir = path10.join(vaultPath, ".opencode", "skills");
29410
+ for (const name of BYOAO_SKILL_NAMES) {
29411
+ const src = path10.join(commandsDir, `${name}.md`);
29412
+ if (!await fs.pathExists(src))
29413
+ continue;
29414
+ const destDir = path10.join(skillsDir, name);
29415
+ const dest = path10.join(destDir, "SKILL.md");
29416
+ if (await fs.pathExists(dest)) {
29417
+ await fs.remove(src);
29418
+ continue;
29419
+ }
29420
+ await fs.ensureDir(destDir);
29421
+ await fs.move(src, dest);
29422
+ }
29423
+ const remaining = await fs.readdir(commandsDir);
29424
+ if (remaining.length === 0) {
29425
+ await fs.remove(commandsDir);
29426
+ }
29427
+ }
29428
+ async function collectV1DeprecatedInfrastructureItems(vaultPath) {
29429
+ const items = [];
29430
+ const templatesDir = path10.join(vaultPath, "Knowledge", "templates");
29431
+ if (await fs.pathExists(templatesDir)) {
29432
+ const files = await fs.readdir(templatesDir);
29433
+ for (const f of files) {
29434
+ if (f.endsWith(".md")) {
29435
+ items.push({
29436
+ file: `Knowledge/templates/${f}`,
29437
+ action: "deprecated",
29438
+ category: "templates"
29439
+ });
29440
+ }
29441
+ }
29442
+ }
29443
+ for (const cmd of ["weave.md", "emerge.md"]) {
29444
+ const rel = `.opencode/commands/${cmd}`;
29445
+ if (await fs.pathExists(path10.join(vaultPath, rel))) {
29446
+ items.push({
29447
+ file: rel,
29448
+ action: "deprecated",
29449
+ category: "commands"
29450
+ });
29451
+ }
29452
+ }
29453
+ return items;
29454
+ }
29455
+ function mergeForcedDeprecatedIntoPlan(items, forced) {
29456
+ const forcedFiles = new Set(forced.map((i) => i.file));
29457
+ const filtered = items.filter((i) => !(forcedFiles.has(i.file) && (i.action === "add" || i.action === "update")));
29458
+ const byFile = new Map(filtered.map((i) => [i.file, i]));
29459
+ for (const f of forced) {
29460
+ byFile.set(f.file, f);
29461
+ }
29462
+ return [...byFile.values()];
29463
+ }
29703
29464
  function resolveAssetsDir2() {
29704
- const srcAssets = path13.resolve(import.meta.dirname, "..", "assets");
29705
- const distAssets = path13.resolve(import.meta.dirname, "..", "..", "src", "assets");
29706
- if (fs.existsSync(srcAssets))
29707
- return srcAssets;
29465
+ const distAssets = path10.resolve(import.meta.dirname, "assets");
29466
+ const srcAssets = path10.resolve(import.meta.dirname, "..", "assets");
29467
+ const devAssets = path10.resolve(import.meta.dirname, "..", "..", "src", "assets");
29708
29468
  if (fs.existsSync(distAssets))
29709
29469
  return distAssets;
29710
- return srcAssets;
29470
+ if (fs.existsSync(srcAssets))
29471
+ return srcAssets;
29472
+ if (fs.existsSync(devAssets))
29473
+ return devAssets;
29474
+ return distAssets;
29711
29475
  }
29712
29476
  function resolveSkillsDir() {
29713
- const srcSkills = path13.resolve(import.meta.dirname, "..", "skills");
29714
- const distSkills = path13.resolve(import.meta.dirname, "..", "..", "src", "skills");
29715
- if (fs.existsSync(srcSkills))
29716
- return srcSkills;
29477
+ const distSkills = path10.resolve(import.meta.dirname, "assets", "skills");
29478
+ const srcSkills = path10.resolve(import.meta.dirname, "..", "skills");
29479
+ const devSkills = path10.resolve(import.meta.dirname, "..", "..", "src", "skills");
29717
29480
  if (fs.existsSync(distSkills))
29718
29481
  return distSkills;
29719
- return srcSkills;
29482
+ if (fs.existsSync(srcSkills))
29483
+ return srcSkills;
29484
+ if (fs.existsSync(devSkills))
29485
+ return devSkills;
29486
+ return distSkills;
29720
29487
  }
29721
29488
  function resolvePackageAssets(preset) {
29722
29489
  const assetsDir = resolveAssetsDir2();
@@ -29726,32 +29493,35 @@ function resolvePackageAssets(preset) {
29726
29493
  const commands = [];
29727
29494
  const obsidianConfig = [];
29728
29495
  const templates = [];
29729
- const obsidianSkillsDir = path13.join(assetsDir, "obsidian-skills");
29496
+ const obsidianSkillsDir = path10.join(assetsDir, "obsidian-skills");
29730
29497
  if (fs.existsSync(obsidianSkillsDir)) {
29731
29498
  for (const file2 of fs.readdirSync(obsidianSkillsDir)) {
29732
29499
  if (file2.endsWith(".md")) {
29733
29500
  const skillName = file2.replace(/\.md$/, "");
29734
29501
  skills.push({
29735
29502
  relativePath: `.opencode/skills/${skillName}/SKILL.md`,
29736
- sourcePath: path13.join(obsidianSkillsDir, file2)
29503
+ sourcePath: path10.join(obsidianSkillsDir, file2)
29737
29504
  });
29738
29505
  }
29739
29506
  }
29740
29507
  }
29741
29508
  if (fs.existsSync(skillsDir)) {
29742
- for (const file2 of fs.readdirSync(skillsDir)) {
29743
- if (file2.endsWith(".md")) {
29744
- commands.push({
29745
- relativePath: `.opencode/commands/${file2}`,
29746
- sourcePath: path13.join(skillsDir, file2)
29747
- });
29509
+ for (const entry of fs.readdirSync(skillsDir, { withFileTypes: true })) {
29510
+ if (entry.isDirectory()) {
29511
+ const skillMd = path10.join(skillsDir, entry.name, "SKILL.md");
29512
+ if (fs.existsSync(skillMd)) {
29513
+ skills.push({
29514
+ relativePath: `.opencode/skills/${entry.name}/SKILL.md`,
29515
+ sourcePath: skillMd
29516
+ });
29517
+ }
29748
29518
  }
29749
29519
  }
29750
29520
  }
29751
- const obsidianSrcDir = path13.join(commonDir, "obsidian");
29521
+ const obsidianSrcDir = path10.join(commonDir, "obsidian");
29752
29522
  if (fs.existsSync(obsidianSrcDir)) {
29753
29523
  for (const file2 of OBSIDIAN_CONFIG_FILES) {
29754
- const srcPath = path13.join(obsidianSrcDir, file2);
29524
+ const srcPath = path10.join(obsidianSrcDir, file2);
29755
29525
  if (fs.existsSync(srcPath)) {
29756
29526
  obsidianConfig.push({
29757
29527
  relativePath: `.obsidian/${file2}`,
@@ -29760,26 +29530,26 @@ function resolvePackageAssets(preset) {
29760
29530
  }
29761
29531
  }
29762
29532
  }
29763
- const commonTemplatesDir = path13.join(commonDir, "templates");
29533
+ const commonTemplatesDir = path10.join(commonDir, "templates");
29764
29534
  if (fs.existsSync(commonTemplatesDir)) {
29765
29535
  for (const file2 of fs.readdirSync(commonTemplatesDir)) {
29766
29536
  if (file2.endsWith(".md")) {
29767
29537
  templates.push({
29768
29538
  relativePath: `Knowledge/templates/${file2}`,
29769
- sourcePath: path13.join(commonTemplatesDir, file2)
29539
+ sourcePath: path10.join(commonTemplatesDir, file2)
29770
29540
  });
29771
29541
  }
29772
29542
  }
29773
29543
  }
29774
29544
  try {
29775
29545
  const { presetsDir } = loadPreset(preset);
29776
- const presetTemplatesDir = path13.join(presetsDir, preset, "templates");
29546
+ const presetTemplatesDir = path10.join(presetsDir, preset, "templates");
29777
29547
  if (fs.existsSync(presetTemplatesDir)) {
29778
29548
  for (const file2 of fs.readdirSync(presetTemplatesDir)) {
29779
29549
  if (file2.endsWith(".md")) {
29780
29550
  templates.push({
29781
29551
  relativePath: `Knowledge/templates/${file2}`,
29782
- sourcePath: path13.join(presetTemplatesDir, file2)
29552
+ sourcePath: path10.join(presetTemplatesDir, file2)
29783
29553
  });
29784
29554
  }
29785
29555
  }
@@ -29811,14 +29581,24 @@ async function upgradeVault(vaultPath, options2) {
29811
29581
  dryRun
29812
29582
  };
29813
29583
  }
29814
- const legacyAgentMd = path13.join(vaultPath, "AGENT.md");
29815
- const newAgentsMd = path13.join(vaultPath, "AGENTS.md");
29584
+ const legacyAgentMd = path10.join(vaultPath, "AGENT.md");
29585
+ const newAgentsMd = path10.join(vaultPath, "AGENTS.md");
29816
29586
  if (!dryRun && await fs.pathExists(legacyAgentMd) && !await fs.pathExists(newAgentsMd)) {
29817
29587
  await fs.rename(legacyAgentMd, newAgentsMd);
29818
29588
  }
29589
+ if (!dryRun) {
29590
+ await migrateV1ToV2Infrastructure(vaultPath);
29591
+ }
29592
+ if (!dryRun) {
29593
+ await migrateCommandsToSkills(vaultPath);
29594
+ }
29819
29595
  const effectivePreset = preset ?? manifest.preset;
29820
29596
  const packageAssets = resolvePackageAssets(effectivePreset);
29821
- const plan = buildUpgradePlan(vaultPath, manifest, packageAssets);
29597
+ let plan = buildUpgradePlan(vaultPath, manifest, packageAssets);
29598
+ plan = {
29599
+ ...plan,
29600
+ items: mergeForcedDeprecatedIntoPlan(plan.items, await collectV1DeprecatedInfrastructureItems(vaultPath))
29601
+ };
29822
29602
  const added = [];
29823
29603
  const updated = [];
29824
29604
  const deprecated = [];
@@ -29835,8 +29615,8 @@ async function upgradeVault(vaultPath, options2) {
29835
29615
  if (item.action === "add" || item.action === "update") {
29836
29616
  const source = sourceMap.get(item.file);
29837
29617
  if (source) {
29838
- const dest = path13.join(vaultPath, item.file);
29839
- await fs.ensureDir(path13.dirname(dest));
29618
+ const dest = path10.join(vaultPath, item.file);
29619
+ await fs.ensureDir(path10.dirname(dest));
29840
29620
  await fs.copy(source, dest, { overwrite: true });
29841
29621
  if (item.action === "add") {
29842
29622
  added.push(item.file);
@@ -29931,17 +29711,17 @@ var byoao_vault_upgrade = tool({
29931
29711
  });
29932
29712
 
29933
29713
  // dist/tools/mcp-auth.js
29934
- import { spawn, execSync as execSync4 } from "node:child_process";
29935
- import path14 from "node:path";
29714
+ import { spawn, execSync as execSync3 } from "node:child_process";
29715
+ import path11 from "node:path";
29936
29716
  import os4 from "node:os";
29937
29717
  function findOpencodeBinary() {
29938
29718
  const candidates = [
29939
- path14.join(os4.homedir(), ".opencode/bin/opencode"),
29719
+ path11.join(os4.homedir(), ".opencode/bin/opencode"),
29940
29720
  "/usr/local/bin/opencode"
29941
29721
  ];
29942
29722
  for (const p of candidates) {
29943
29723
  try {
29944
- execSync4(`test -x "${p}"`, { stdio: "pipe" });
29724
+ execSync3(`test -x "${p}"`, { stdio: "pipe" });
29945
29725
  return p;
29946
29726
  } catch {
29947
29727
  }
@@ -30039,10 +29819,13 @@ The user may need to:
30039
29819
  }
30040
29820
  });
30041
29821
 
29822
+ // dist/hooks/system-transform.js
29823
+ import path12 from "node:path";
29824
+
30042
29825
  // dist/lib/logger.js
30043
29826
  import { join } from "node:path";
30044
29827
  import { homedir } from "node:os";
30045
- import { appendFile, stat, rename as rename3, mkdir as mkdir2, readFile as readFile2, unlink } from "node:fs/promises";
29828
+ import { appendFile, stat as stat2, rename as rename3, mkdir as mkdir2, readFile as readFile2, unlink } from "node:fs/promises";
30046
29829
  var LOG_DIR = process.env.BYOAO_LOG_DIR || join(homedir(), ".byoao", "logs");
30047
29830
  var LOG_FILE = join(LOG_DIR, "error.log");
30048
29831
  var MAX_LOG_SIZE = 512 * 1024;
@@ -30085,7 +29868,7 @@ async function ensureLogDir() {
30085
29868
  }
30086
29869
  async function rotateIfNeeded() {
30087
29870
  try {
30088
- const s = await stat(LOG_FILE);
29871
+ const s = await stat2(LOG_FILE);
30089
29872
  if (s.size >= MAX_LOG_SIZE) {
30090
29873
  await rename3(LOG_FILE, ROTATED_FILE);
30091
29874
  }
@@ -30116,6 +29899,20 @@ async function log(level, source, message, options2) {
30116
29899
  }
30117
29900
 
30118
29901
  // dist/hooks/system-transform.js
29902
+ function readVaultMarkdown(vaultPath, fileName) {
29903
+ const full = path12.join(vaultPath, fileName);
29904
+ if (!fs.existsSync(full))
29905
+ return null;
29906
+ try {
29907
+ return fs.readFileSync(full, "utf-8");
29908
+ } catch {
29909
+ void log("warn", "hook:system-transform", `Failed to read ${fileName}`, {
29910
+ context: { path: full }
29911
+ }).catch(() => {
29912
+ });
29913
+ return null;
29914
+ }
29915
+ }
30119
29916
  async function buildMcpAuthGuidance() {
30120
29917
  try {
30121
29918
  const config2 = await readOpencodeConfig();
@@ -30153,6 +29950,31 @@ async function buildMcpAuthGuidance() {
30153
29950
  }
30154
29951
  }
30155
29952
  async function systemTransformHook(_input, output) {
29953
+ const vaultPath = detectVaultContext(process.cwd());
29954
+ if (vaultPath) {
29955
+ let agentsTitle = "## AGENTS.md";
29956
+ let agents = readVaultMarkdown(vaultPath, "AGENTS.md");
29957
+ if (!agents) {
29958
+ agents = readVaultMarkdown(vaultPath, "AGENT.md");
29959
+ if (agents)
29960
+ agentsTitle = "## AGENT.md";
29961
+ }
29962
+ if (agents) {
29963
+ output.system.push(`
29964
+ ---
29965
+ ${agentsTitle}
29966
+
29967
+ ${agents}`);
29968
+ }
29969
+ const schema = readVaultMarkdown(vaultPath, "SCHEMA.md");
29970
+ if (schema) {
29971
+ output.system.push(`
29972
+ ---
29973
+ ## SCHEMA.md
29974
+
29975
+ ${schema}`);
29976
+ }
29977
+ }
30156
29978
  const mcpGuidance = await buildMcpAuthGuidance();
30157
29979
  if (mcpGuidance) {
30158
29980
  output.system.push(mcpGuidance);
@@ -30162,15 +29984,15 @@ async function systemTransformHook(_input, output) {
30162
29984
  // dist/hooks/idle-suggestions.js
30163
29985
  function getIdleSuggestion() {
30164
29986
  const suggestions = [
30165
- "Tip: run /weave to connect your notes with frontmatter and wikilinks",
29987
+ "Tip: run /cook to compile your notes into structured knowledge pages",
29988
+ "Tip: run /health to check knowledge page health",
29989
+ "Tip: run /wiki to regenerate INDEX.base",
30166
29990
  "Tip: run /trace to see how an idea evolved over time",
30167
- "Tip: run /emerge to discover patterns across your notes",
30168
29991
  "Tip: run /connect to bridge two topics using your vault's link graph",
30169
29992
  "Tip: run /ideas to generate actionable insights from your vault",
30170
29993
  "Tip: run /challenge to pressure-test a belief against your own notes",
30171
29994
  "Tip: run /drift to compare intentions vs actions over the past month",
30172
- "Tip: run /diagnose to check knowledge graph health",
30173
- "Tip: run /explain to document a codebase system in your vault"
29995
+ "Tip: run /diagnose to check overall vault health"
30174
29996
  ];
30175
29997
  const idx = (/* @__PURE__ */ new Date()).getMinutes() % suggestions.length;
30176
29998
  return suggestions[idx];
@@ -30181,12 +30003,9 @@ var BYOAOPlugin = async (ctx) => {
30181
30003
  const { client } = ctx;
30182
30004
  const tools = {
30183
30005
  byoao_init_vault,
30184
- byoao_add_person,
30185
- byoao_add_project,
30186
30006
  byoao_vault_status,
30187
30007
  byoao_vault_doctor,
30188
30008
  byoao_switch_provider,
30189
- byoao_graph_health,
30190
30009
  byoao_vault_upgrade,
30191
30010
  byoao_mcp_auth
30192
30011
  };