@jayjiang/byoao 1.1.2 → 2.0.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 (136) 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/dist/assets/skills/ask.md +28 -27
  11. package/dist/assets/skills/challenge.md +79 -121
  12. package/dist/assets/skills/connect.md +75 -163
  13. package/dist/assets/skills/cook.md +167 -0
  14. package/dist/assets/skills/diagnose.md +102 -43
  15. package/dist/assets/skills/drift.md +64 -165
  16. package/dist/assets/skills/health.md +63 -0
  17. package/dist/assets/skills/ideas.md +11 -10
  18. package/dist/assets/skills/organize.md +56 -155
  19. package/dist/assets/skills/prep.md +63 -0
  20. package/dist/assets/skills/trace.md +75 -90
  21. package/dist/assets/skills/wiki.md +77 -178
  22. package/dist/cli/cli-program.js +17 -14
  23. package/dist/cli/cli-program.js.map +1 -1
  24. package/dist/cli/installer.js +10 -4
  25. package/dist/cli/installer.js.map +1 -1
  26. package/dist/hooks/idle-suggestions.js +4 -4
  27. package/dist/hooks/idle-suggestions.js.map +1 -1
  28. package/dist/hooks/system-transform.js +35 -1
  29. package/dist/hooks/system-transform.js.map +1 -1
  30. package/dist/index.js +395 -623
  31. package/dist/index.js.map +1 -1
  32. package/dist/plugin-config.js +6 -32
  33. package/dist/plugin-config.js.map +1 -1
  34. package/dist/tools/init-vault.js +8 -38
  35. package/dist/tools/init-vault.js.map +1 -1
  36. package/dist/tools/vault-doctor.js +1 -1
  37. package/dist/tools/vault-doctor.js.map +1 -1
  38. package/dist/tools/vault-status.js +1 -1
  39. package/dist/tools/vault-status.js.map +1 -1
  40. package/dist/vault/__tests__/create.test.js +47 -115
  41. package/dist/vault/__tests__/create.test.js.map +1 -1
  42. package/dist/vault/__tests__/doctor.test.js +14 -2
  43. package/dist/vault/__tests__/doctor.test.js.map +1 -1
  44. package/dist/vault/__tests__/manifest.test.js +2 -2
  45. package/dist/vault/__tests__/manifest.test.js.map +1 -1
  46. package/dist/vault/__tests__/status.test.js +12 -0
  47. package/dist/vault/__tests__/status.test.js.map +1 -1
  48. package/dist/vault/__tests__/upgrade.test.js +3 -3
  49. package/dist/vault/__tests__/upgrade.test.js.map +1 -1
  50. package/dist/vault/create.js +75 -188
  51. package/dist/vault/create.js.map +1 -1
  52. package/dist/vault/doctor.js +49 -0
  53. package/dist/vault/doctor.js.map +1 -1
  54. package/dist/vault/manifest.js +1 -1
  55. package/dist/vault/preset.js +10 -4
  56. package/dist/vault/preset.js.map +1 -1
  57. package/dist/vault/self-update.js +1 -1
  58. package/dist/vault/status.js +24 -0
  59. package/dist/vault/status.js.map +1 -1
  60. package/dist/vault/upgrade.js +120 -16
  61. package/dist/vault/upgrade.js.map +1 -1
  62. package/package.json +1 -1
  63. package/src/assets/obsidian-skills/byoao-conventions.md +9 -6
  64. package/src/assets/obsidian-skills/vault-thinking.md +6 -5
  65. package/src/assets/presets/common/AGENTS.md.hbs +23 -19
  66. package/src/assets/presets/common/SCHEMA.md.hbs +57 -0
  67. package/src/assets/presets/common/Start Here.md.hbs +29 -40
  68. package/src/assets/presets/minimal/preset.json +3 -3
  69. package/src/assets/presets/pm-tpm/preset.json +2 -2
  70. package/src/skills/ask.md +28 -27
  71. package/src/skills/challenge.md +79 -121
  72. package/src/skills/connect.md +75 -163
  73. package/src/skills/cook.md +167 -0
  74. package/src/skills/diagnose.md +102 -43
  75. package/src/skills/drift.md +64 -165
  76. package/src/skills/health.md +63 -0
  77. package/src/skills/ideas.md +11 -10
  78. package/src/skills/organize.md +56 -155
  79. package/src/skills/prep.md +63 -0
  80. package/src/skills/trace.md +75 -90
  81. package/src/skills/wiki.md +77 -178
  82. package/dist/assets/presets/common/Glossary.md.hbs +0 -16
  83. package/dist/assets/presets/common/obsidian/daily-notes.json +0 -5
  84. package/dist/assets/presets/common/obsidian/templates.json +0 -3
  85. package/dist/assets/presets/common/templates/Daily Note.md +0 -19
  86. package/dist/assets/presets/common/templates/Decision Record.md +0 -32
  87. package/dist/assets/presets/common/templates/Investigation.md +0 -34
  88. package/dist/assets/presets/common/templates/Meeting Notes.md +0 -25
  89. package/dist/assets/skills/emerge.md +0 -168
  90. package/dist/assets/skills/weave.md +0 -287
  91. package/dist/tools/add-glossary-term.js +0 -21
  92. package/dist/tools/add-glossary-term.js.map +0 -1
  93. package/dist/tools/add-person.js +0 -21
  94. package/dist/tools/add-person.js.map +0 -1
  95. package/dist/tools/add-project.js +0 -24
  96. package/dist/tools/add-project.js.map +0 -1
  97. package/dist/tools/graph-health.js +0 -25
  98. package/dist/tools/graph-health.js.map +0 -1
  99. package/dist/tools/note-read.js +0 -19
  100. package/dist/tools/note-read.js.map +0 -1
  101. package/dist/tools/search-vault.js +0 -22
  102. package/dist/tools/search-vault.js.map +0 -1
  103. package/dist/vault/__tests__/glossary.test.js +0 -68
  104. package/dist/vault/__tests__/glossary.test.js.map +0 -1
  105. package/dist/vault/__tests__/graph-health.test.js +0 -102
  106. package/dist/vault/__tests__/graph-health.test.js.map +0 -1
  107. package/dist/vault/__tests__/member.test.js +0 -85
  108. package/dist/vault/__tests__/member.test.js.map +0 -1
  109. package/dist/vault/__tests__/note-read.test.js +0 -71
  110. package/dist/vault/__tests__/note-read.test.js.map +0 -1
  111. package/dist/vault/__tests__/obsidian-cli.test.js +0 -108
  112. package/dist/vault/__tests__/obsidian-cli.test.js.map +0 -1
  113. package/dist/vault/__tests__/search-vault.test.js +0 -93
  114. package/dist/vault/__tests__/search-vault.test.js.map +0 -1
  115. package/dist/vault/glossary.js +0 -27
  116. package/dist/vault/glossary.js.map +0 -1
  117. package/dist/vault/graph-health.js +0 -83
  118. package/dist/vault/graph-health.js.map +0 -1
  119. package/dist/vault/member.js +0 -67
  120. package/dist/vault/member.js.map +0 -1
  121. package/dist/vault/note-read.js +0 -70
  122. package/dist/vault/note-read.js.map +0 -1
  123. package/dist/vault/project.js +0 -68
  124. package/dist/vault/project.js.map +0 -1
  125. package/dist/vault/retrieval-types.js +0 -5
  126. package/dist/vault/retrieval-types.js.map +0 -1
  127. package/dist/vault/search-vault.js +0 -87
  128. package/dist/vault/search-vault.js.map +0 -1
  129. package/src/assets/presets/common/obsidian/daily-notes.json +0 -5
  130. package/src/assets/presets/common/obsidian/templates.json +0 -3
  131. package/src/assets/presets/common/templates/Daily Note.md +0 -19
  132. package/src/assets/presets/common/templates/Decision Record.md +0 -32
  133. package/src/assets/presets/common/templates/Investigation.md +0 -34
  134. package/src/assets/presets/common/templates/Meeting Notes.md +0 -25
  135. package/src/skills/emerge.md +0 -168
  136. package/src/skills/weave.md +0 -287
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,7 +28262,7 @@ 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.0";
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([]),
@@ -28303,7 +28278,7 @@ var ManifestSchema = external_exports2.object({
28303
28278
  });
28304
28279
  var MANIFEST_DIR = ".byoao";
28305
28280
  var MANIFEST_FILE = "manifest.json";
28306
- function today2() {
28281
+ function today() {
28307
28282
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
28308
28283
  }
28309
28284
  function manifestPath(vaultPath) {
@@ -28326,8 +28301,8 @@ async function writeManifest(vaultPath, preset, installedFiles, versionOverride)
28326
28301
  const manifest = {
28327
28302
  version: versionOverride ?? PKG_VERSION,
28328
28303
  preset,
28329
- createdAt: existing?.createdAt ?? today2(),
28330
- updatedAt: today2(),
28304
+ createdAt: existing?.createdAt ?? today(),
28305
+ updatedAt: today(),
28331
28306
  infrastructure: {
28332
28307
  skills: installedFiles.skills,
28333
28308
  commands: installedFiles.commands,
@@ -28388,7 +28363,6 @@ function countWikilinks(content) {
28388
28363
  const matches = stripped.match(/\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g);
28389
28364
  return matches ? matches.length : 0;
28390
28365
  }
28391
- var MINIMAL_DIRECTORIES = [];
28392
28366
  function makeContext(vaultPath, kbName, preserveObsidian = false) {
28393
28367
  return {
28394
28368
  vaultPath,
@@ -28410,11 +28384,7 @@ var MCP_DISPLAY_NAMES = {
28410
28384
  atlassian: { name: "Atlassian", description: "Jira issues, Confluence pages" },
28411
28385
  bigquery: { name: "BigQuery", description: "Data warehouse queries and analysis" }
28412
28386
  };
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);
28387
+ async function createMinimalCore(ctx) {
28418
28388
  if (!ctx.preserveObsidian) {
28419
28389
  await fs.ensureDir(path6.join(ctx.vaultPath, ".obsidian"));
28420
28390
  const obsidianSrc = path6.join(ctx.commonDir, "obsidian");
@@ -28439,23 +28409,51 @@ async function createMinimalCore(ctx, _glossaryEntries = []) {
28439
28409
  ctx.filesCreated++;
28440
28410
  }
28441
28411
  }
28442
- async function createAgentsMd(ctx, ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject) {
28412
+ async function createLlmWikiCore(ctx, wikiDomain = "") {
28413
+ const agentDirs = ["entities", "concepts", "comparisons", "queries"];
28414
+ for (const dir of agentDirs) {
28415
+ const dirPath = path6.join(ctx.vaultPath, dir);
28416
+ if (!await fs.pathExists(dirPath)) {
28417
+ await fs.ensureDir(dirPath);
28418
+ ctx.filesCreated++;
28419
+ ctx.directories.push(dir);
28420
+ }
28421
+ }
28422
+ const schemaTemplatePath = path6.join(ctx.commonDir, "SCHEMA.md.hbs");
28423
+ if (await fs.pathExists(schemaTemplatePath)) {
28424
+ const schemaTemplate = await fs.readFile(schemaTemplatePath, "utf-8");
28425
+ const schemaContent = renderTemplate(schemaTemplate, {
28426
+ KB_NAME: ctx.kbName,
28427
+ WIKI_DOMAIN: wikiDomain || ""
28428
+ });
28429
+ const schemaPath = path6.join(ctx.vaultPath, "SCHEMA.md");
28430
+ if (!await fs.pathExists(schemaPath)) {
28431
+ await fs.writeFile(schemaPath, schemaContent);
28432
+ ctx.filesCreated++;
28433
+ }
28434
+ }
28435
+ const logContent = `# Agent Activity Log
28436
+
28437
+ Entries are appended here during /cook operations.
28438
+
28439
+ `;
28440
+ const logPath = path6.join(ctx.vaultPath, "log.md");
28441
+ if (!await fs.pathExists(logPath)) {
28442
+ await fs.writeFile(logPath, logContent);
28443
+ ctx.filesCreated++;
28444
+ }
28445
+ }
28446
+ async function createAgentsMd(ctx, ownerName, presetConfig, presetDir) {
28443
28447
  const agentsTemplate = await fs.readFile(path6.join(ctx.commonDir, "AGENTS.md.hbs"), "utf-8");
28444
28448
  let roleSection = "";
28445
28449
  const agentSectionPath = path6.join(presetDir, "agent-section.hbs");
28446
28450
  if (await fs.pathExists(agentSectionPath)) {
28447
28451
  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
28452
  roleSection = renderTemplate(agentSectionTemplate, {
28455
- PROJECTS: projectsList,
28456
- JIRA_HOST: jiraHost,
28457
- JIRA_PROJECT: jiraProject,
28458
- HAS_JIRA: !!(jiraHost && jiraProject)
28453
+ PROJECTS: "(Use /cook to discover projects from your notes)",
28454
+ JIRA_HOST: "",
28455
+ JIRA_PROJECT: "",
28456
+ HAS_JIRA: false
28459
28457
  });
28460
28458
  }
28461
28459
  const agentsContent = renderTemplate(agentsTemplate, {
@@ -28475,119 +28473,23 @@ async function applyPresetOverlay(ctx, presetConfig, presetDir) {
28475
28473
  }
28476
28474
  ctx.directories.push(...presetConfig.directories);
28477
28475
  const allTemplateNames = [];
28478
- const templateDest = path6.join(ctx.vaultPath, "Knowledge/templates");
28479
28476
  const presetTemplatesDir = path6.join(presetDir, "templates");
28480
28477
  if (await fs.pathExists(presetTemplatesDir)) {
28478
+ const templateDest = path6.join(ctx.vaultPath, "templates");
28481
28479
  await fs.ensureDir(templateDest);
28482
28480
  const files = await fs.readdir(presetTemplatesDir);
28483
28481
  for (const file2 of files) {
28484
28482
  await fs.copy(path6.join(presetTemplatesDir, file2), path6.join(templateDest, file2), { overwrite: false });
28485
28483
  allTemplateNames.push(file2.replace(/\.md$/, ""));
28486
28484
  ctx.filesCreated++;
28487
- ctx.installedFiles.templates.push(`Knowledge/templates/${file2}`);
28485
+ ctx.installedFiles.templates.push(`templates/${file2}`);
28488
28486
  }
28489
28487
  }
28490
28488
  return allTemplateNames;
28491
28489
  }
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
28490
  async function createVault(config2) {
28589
- const { kbName, vaultPath, members, projects, glossaryEntries, jiraHost, jiraProject, preset } = config2;
28590
- const presetName = preset ?? "pm-tpm";
28491
+ const { kbName, vaultPath, preset } = config2;
28492
+ const presetName = preset ?? "minimal";
28591
28493
  const { config: presetConfig, presetsDir } = loadPreset(presetName);
28592
28494
  const presetDir = path6.join(presetsDir, presetName);
28593
28495
  const initMode = detectInitMode(vaultPath);
@@ -28600,15 +28502,10 @@ async function createVault(config2) {
28600
28502
  ctx.mcpServices.push(info);
28601
28503
  }
28602
28504
  }
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
- }
28505
+ await createMinimalCore(ctx);
28506
+ await createLlmWikiCore(ctx, config2.wikiDomain);
28507
+ await applyPresetOverlay(ctx, presetConfig, presetDir);
28508
+ await createAgentsMd(ctx, config2.ownerName, presetConfig, presetDir);
28612
28509
  await configureOpenCodeProject(ctx.vaultPath, ctx.installedFiles);
28613
28510
  const mcpOptions = {};
28614
28511
  if (config2.mcpSkip && config2.mcpSkip.length > 0) {
@@ -28689,13 +28586,16 @@ async function configureOpenCodeProject(vaultPath, installedFiles) {
28689
28586
  }
28690
28587
  }
28691
28588
  function resolveAssetsDir() {
28589
+ const distAssets = path6.resolve(import.meta.dirname, "assets");
28692
28590
  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;
28591
+ const devAssets = path6.resolve(import.meta.dirname, "..", "..", "src", "assets");
28696
28592
  if (fs.existsSync(distAssets))
28697
28593
  return distAssets;
28698
- return srcAssets;
28594
+ if (fs.existsSync(srcAssets))
28595
+ return srcAssets;
28596
+ if (fs.existsSync(devAssets))
28597
+ return devAssets;
28598
+ return distAssets;
28699
28599
  }
28700
28600
 
28701
28601
  // dist/vault/obsidian-check.js
@@ -28815,26 +28715,13 @@ function formatObsidianStatus(status) {
28815
28715
  import path7 from "node:path";
28816
28716
  import os3 from "node:os";
28817
28717
  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.",
28718
+ 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
28719
  args: {
28820
28720
  kbName: tool.schema.string().describe(`Knowledge base name (e.g. "Jay's KB")`),
28821
28721
  ownerName: tool.schema.string().optional().describe("Owner's name"),
28822
28722
  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.")
28723
+ preset: tool.schema.string().optional().describe("Work profile (default: 'minimal'). Use 'pm-tpm' for PM/TPM with Atlassian + BigQuery."),
28724
+ wikiDomain: tool.schema.string().optional().describe("What domain this knowledge base covers (e.g. 'AI/ML research', 'product management')")
28838
28725
  },
28839
28726
  async execute(args) {
28840
28727
  const obsidianStatus = checkObsidian();
@@ -28848,12 +28735,8 @@ Please install Obsidian first, then try again.`;
28848
28735
  kbName: args.kbName,
28849
28736
  ownerName: args.ownerName || "",
28850
28737
  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"
28738
+ preset: args.preset || "minimal",
28739
+ wikiDomain: args.wikiDomain || ""
28857
28740
  });
28858
28741
  const result = await createVault(config2);
28859
28742
  let output = `\u2713 Knowledge base created at: ${result.vaultPath}
@@ -28953,188 +28836,18 @@ Open in Obsidian: "Open folder as vault" \u2192 select "${result.vaultPath}"`;
28953
28836
  if (result.initMode === "existing" || result.initMode === "obsidian-vault") {
28954
28837
  output += `
28955
28838
 
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.`;
28839
+ \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
28840
  } else {
28958
28841
  output += `
28959
28842
 
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.`;
28843
+ \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
28844
  }
28962
28845
  return output;
28963
28846
  }
28964
28847
  });
28965
28848
 
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
28849
  // dist/vault/status.js
29137
- import path10 from "node:path";
28850
+ import path8 from "node:path";
29138
28851
  async function getAllMarkdownFiles(dirPath) {
29139
28852
  const results = [];
29140
28853
  async function walk(dir) {
@@ -29142,7 +28855,7 @@ async function getAllMarkdownFiles(dirPath) {
29142
28855
  return;
29143
28856
  const entries = await fs.readdir(dir, { withFileTypes: true });
29144
28857
  for (const entry of entries) {
29145
- const fullPath = path10.join(dir, entry.name);
28858
+ const fullPath = path8.join(dir, entry.name);
29146
28859
  if (entry.isDirectory()) {
29147
28860
  if (!entry.name.startsWith(".")) {
29148
28861
  await walk(fullPath);
@@ -29173,11 +28886,15 @@ async function getVaultStatus(vaultPath) {
29173
28886
  brokenLinks: [],
29174
28887
  directories: {},
29175
28888
  hasObsidianConfig: false,
29176
- hasAgentMd: false
28889
+ hasAgentMd: false,
28890
+ agentPages: { entities: 0, concepts: 0, comparisons: 0, queries: 0 },
28891
+ hasSchema: false,
28892
+ hasLog: false,
28893
+ hasIndexBase: false
29177
28894
  };
29178
28895
  }
29179
28896
  const allFiles = await getAllMarkdownFiles(vaultPath);
29180
- const noteNames = new Set(allFiles.map((f) => path10.basename(f, ".md")));
28897
+ const noteNames = new Set(allFiles.map((f) => path8.basename(f, ".md")));
29181
28898
  let wikilinkCount = 0;
29182
28899
  const brokenLinksSet = /* @__PURE__ */ new Set();
29183
28900
  for (const file2 of allFiles) {
@@ -29202,12 +28919,24 @@ async function getVaultStatus(vaultPath) {
29202
28919
  "Daily"
29203
28920
  ];
29204
28921
  for (const dir of topDirs) {
29205
- const dirPath = path10.join(vaultPath, dir);
28922
+ const dirPath = path8.join(vaultPath, dir);
29206
28923
  if (await fs.pathExists(dirPath)) {
29207
28924
  const files = await getAllMarkdownFiles(dirPath);
29208
28925
  directories[dir] = files.length;
29209
28926
  }
29210
28927
  }
28928
+ const agentDirNames = ["entities", "concepts", "comparisons", "queries"];
28929
+ const agentPages = {
28930
+ entities: 0,
28931
+ concepts: 0,
28932
+ comparisons: 0,
28933
+ queries: 0
28934
+ };
28935
+ for (const name of agentDirNames) {
28936
+ const dirPath = path8.join(vaultPath, name);
28937
+ const mdFiles = await getAllMarkdownFiles(dirPath);
28938
+ agentPages[name] = mdFiles.length;
28939
+ }
29211
28940
  return {
29212
28941
  exists: true,
29213
28942
  vaultPath,
@@ -29215,8 +28944,12 @@ async function getVaultStatus(vaultPath) {
29215
28944
  wikilinkCount,
29216
28945
  brokenLinks: Array.from(brokenLinksSet),
29217
28946
  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"))
28947
+ hasObsidianConfig: await fs.pathExists(path8.join(vaultPath, ".obsidian")),
28948
+ hasAgentMd: await fs.pathExists(path8.join(vaultPath, "AGENTS.md")) || await fs.pathExists(path8.join(vaultPath, "AGENT.md")),
28949
+ agentPages,
28950
+ hasSchema: await fs.pathExists(path8.join(vaultPath, "SCHEMA.md")),
28951
+ hasLog: await fs.pathExists(path8.join(vaultPath, "log.md")),
28952
+ hasIndexBase: await fs.pathExists(path8.join(vaultPath, "INDEX.base"))
29220
28953
  };
29221
28954
  }
29222
28955
  function formatVaultStatus(status) {
@@ -29236,6 +28969,10 @@ function formatVaultStatus(status) {
29236
28969
  lines.push("");
29237
28970
  lines.push(`Config: ${status.hasObsidianConfig ? "\u2713" : "\u2717"} .obsidian/`);
29238
28971
  lines.push(`Agent: ${status.hasAgentMd ? "\u2713" : "\u2717"} AGENTS.md`);
28972
+ lines.push("");
28973
+ lines.push("LLM Wiki v2 (agent pages):");
28974
+ lines.push(` entities: ${status.agentPages.entities} \xB7 concepts: ${status.agentPages.concepts} \xB7 comparisons: ${status.agentPages.comparisons} \xB7 queries: ${status.agentPages.queries}`);
28975
+ lines.push(` SCHEMA.md: ${status.hasSchema ? "\u2713" : "\u2717"} \xB7 log.md: ${status.hasLog ? "\u2713" : "\u2717"} \xB7 INDEX.base: ${status.hasIndexBase ? "\u2713" : "\u2717"}`);
29239
28976
  if (status.brokenLinks.length > 0) {
29240
28977
  lines.push("");
29241
28978
  lines.push(`\u26A0\uFE0F Broken links (${status.brokenLinks.length}):`);
@@ -29253,7 +28990,7 @@ function formatVaultStatus(status) {
29253
28990
 
29254
28991
  // dist/tools/vault-status.js
29255
28992
  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.",
28993
+ 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
28994
  args: {
29258
28995
  vaultPath: tool.schema.string().describe("Path to the Obsidian vault")
29259
28996
  },
@@ -29268,12 +29005,18 @@ var byoao_vault_status = tool({
29268
29005
  });
29269
29006
 
29270
29007
  // dist/vault/doctor.js
29271
- import path11 from "node:path";
29008
+ import path9 from "node:path";
29009
+ import { stat } from "node:fs/promises";
29010
+ var LLM_WIKI_V2_AGENT_DIRS = ["entities", "concepts", "comparisons", "queries"];
29011
+ function isAgentWikiPage(relativePath) {
29012
+ const top = relativePath.split(path9.sep)[0];
29013
+ return LLM_WIKI_V2_AGENT_DIRS.includes(top);
29014
+ }
29272
29015
  async function collectMarkdownFiles(dir) {
29273
29016
  const results = [];
29274
29017
  const entries = await fs.readdir(dir, { withFileTypes: true });
29275
29018
  for (const entry of entries) {
29276
- const fullPath = path11.join(dir, entry.name);
29019
+ const fullPath = path9.join(dir, entry.name);
29277
29020
  if (entry.isDirectory()) {
29278
29021
  if (entry.name === ".obsidian" || entry.name === ".git")
29279
29022
  continue;
@@ -29294,10 +29037,10 @@ function extractWikilinks2(content) {
29294
29037
  async function getVaultDiagnosis(vaultPath) {
29295
29038
  const issues = [];
29296
29039
  const allFiles = await collectMarkdownFiles(vaultPath);
29297
- const noteNames = new Set(allFiles.map((f) => path11.basename(f, ".md")));
29040
+ const noteNames = new Set(allFiles.map((f) => path9.basename(f, ".md")));
29298
29041
  let healthyNotes = 0;
29299
29042
  for (const filePath of allFiles) {
29300
- const relativePath = path11.relative(vaultPath, filePath);
29043
+ const relativePath = path9.relative(vaultPath, filePath);
29301
29044
  if (relativePath.startsWith("Knowledge/templates/"))
29302
29045
  continue;
29303
29046
  const content = await fs.readFile(filePath, "utf-8");
@@ -29331,15 +29074,26 @@ async function getVaultDiagnosis(vaultPath) {
29331
29074
  hasIssue = true;
29332
29075
  }
29333
29076
  }
29077
+ const contra = data?.contradictions;
29078
+ const contraList = Array.isArray(contra) && contra.some((x) => x != null && String(x).trim() !== "");
29079
+ const contraStr = typeof contra === "string" && contra.trim() !== "";
29080
+ if (contraList || contraStr) {
29081
+ issues.push({
29082
+ severity: "warning",
29083
+ category: "contradiction",
29084
+ file: relativePath,
29085
+ message: "Note lists `contradictions` in frontmatter \u2014 review conflicting claims against linked agent pages"
29086
+ });
29087
+ }
29334
29088
  if (!hasIssue)
29335
29089
  healthyNotes++;
29336
29090
  }
29337
29091
  let agentContent = null;
29338
- let agentResolvedPath = path11.join(vaultPath, "AGENTS.md");
29092
+ let agentResolvedPath = path9.join(vaultPath, "AGENTS.md");
29339
29093
  if (await fs.pathExists(agentResolvedPath)) {
29340
29094
  agentContent = await fs.readFile(agentResolvedPath, "utf-8");
29341
29095
  } else {
29342
- agentResolvedPath = path11.join(vaultPath, "AGENT.md");
29096
+ agentResolvedPath = path9.join(vaultPath, "AGENT.md");
29343
29097
  if (await fs.pathExists(agentResolvedPath)) {
29344
29098
  agentContent = await fs.readFile(agentResolvedPath, "utf-8");
29345
29099
  }
@@ -29356,24 +29110,54 @@ async function getVaultDiagnosis(vaultPath) {
29356
29110
  }
29357
29111
  }
29358
29112
  }
29113
+ for (const dirName of LLM_WIKI_V2_AGENT_DIRS) {
29114
+ const dirPath = path9.join(vaultPath, dirName);
29115
+ const exists = await fs.pathExists(dirPath);
29116
+ const isDir = exists && (await stat(dirPath)).isDirectory();
29117
+ if (!isDir) {
29118
+ issues.push({
29119
+ severity: "warning",
29120
+ category: "agent-drift",
29121
+ message: `LLM Wiki v2: expected agent directory \`${dirName}/\` at vault root`
29122
+ });
29123
+ }
29124
+ }
29125
+ const schemaPath = path9.join(vaultPath, "SCHEMA.md");
29126
+ if (!await fs.pathExists(schemaPath)) {
29127
+ issues.push({
29128
+ severity: "warning",
29129
+ category: "agent-drift",
29130
+ message: "LLM Wiki v2: missing SCHEMA.md at vault root"
29131
+ });
29132
+ }
29133
+ const logMdPath = path9.join(vaultPath, "log.md");
29134
+ if (!await fs.pathExists(logMdPath)) {
29135
+ issues.push({
29136
+ severity: "warning",
29137
+ category: "agent-drift",
29138
+ message: "LLM Wiki v2: missing log.md at vault root"
29139
+ });
29140
+ }
29359
29141
  const allLinksMap = /* @__PURE__ */ new Map();
29360
29142
  const incomingLinks = /* @__PURE__ */ new Set();
29361
29143
  for (const filePath of allFiles) {
29362
29144
  const content = await fs.readFile(filePath, "utf-8");
29363
29145
  const links = extractWikilinks2(content);
29364
- const name = path11.basename(filePath, ".md");
29146
+ const name = path9.basename(filePath, ".md");
29365
29147
  allLinksMap.set(name, new Set(links));
29366
29148
  for (const link of links) {
29367
29149
  incomingLinks.add(link);
29368
29150
  }
29369
29151
  }
29370
29152
  for (const filePath of allFiles) {
29371
- const relativePath = path11.relative(vaultPath, filePath);
29153
+ const relativePath = path9.relative(vaultPath, filePath);
29372
29154
  if (relativePath.startsWith("Knowledge/templates/"))
29373
29155
  continue;
29374
29156
  if (relativePath === "AGENT.md" || relativePath === "AGENTS.md")
29375
29157
  continue;
29376
- const name = path11.basename(filePath, ".md");
29158
+ if (isAgentWikiPage(relativePath))
29159
+ continue;
29160
+ const name = path9.basename(filePath, ".md");
29377
29161
  const outgoing = allLinksMap.get(name) || /* @__PURE__ */ new Set();
29378
29162
  const hasIncoming = incomingLinks.has(name);
29379
29163
  const hasOutgoing = outgoing.size > 0;
@@ -29387,7 +29171,7 @@ async function getVaultDiagnosis(vaultPath) {
29387
29171
  }
29388
29172
  }
29389
29173
  for (const filePath of allFiles) {
29390
- const relativePath = path11.relative(vaultPath, filePath);
29174
+ const relativePath = path9.relative(vaultPath, filePath);
29391
29175
  const content = await fs.readFile(filePath, "utf-8");
29392
29176
  const links = extractWikilinks2(content);
29393
29177
  for (const link of links) {
@@ -29413,7 +29197,7 @@ async function getVaultDiagnosis(vaultPath) {
29413
29197
 
29414
29198
  // dist/tools/vault-doctor.js
29415
29199
  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.",
29200
+ 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
29201
  args: {
29418
29202
  vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault")
29419
29203
  },
@@ -29479,154 +29263,16 @@ var byoao_switch_provider = tool({
29479
29263
  }
29480
29264
  });
29481
29265
 
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
29266
  // 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
- ];
29267
+ import path10 from "node:path";
29268
+ var OBSIDIAN_CONFIG_FILES = ["core-plugins.json"];
29623
29269
  async function scanInstalledAssets(vaultPath) {
29624
29270
  const skills = await scanSkillDirs(vaultPath);
29625
29271
  const commands = await scanDir(vaultPath, ".opencode/commands", ".md");
29626
29272
  const templates = await scanDir(vaultPath, "Knowledge/templates", ".md");
29627
29273
  const obsidianConfig = [];
29628
29274
  for (const file2 of OBSIDIAN_CONFIG_FILES) {
29629
- const abs = path13.join(vaultPath, ".obsidian", file2);
29275
+ const abs = path10.join(vaultPath, ".obsidian", file2);
29630
29276
  if (await fs.pathExists(abs)) {
29631
29277
  obsidianConfig.push(`.obsidian/${file2}`);
29632
29278
  }
@@ -29634,21 +29280,21 @@ async function scanInstalledAssets(vaultPath) {
29634
29280
  return { skills, commands, obsidianConfig, templates };
29635
29281
  }
29636
29282
  async function scanDir(vaultPath, relDir, ext) {
29637
- const absDir = path13.join(vaultPath, relDir);
29283
+ const absDir = path10.join(vaultPath, relDir);
29638
29284
  if (!await fs.pathExists(absDir))
29639
29285
  return [];
29640
29286
  const files = await fs.readdir(absDir);
29641
29287
  return files.filter((f) => f.endsWith(ext)).map((f) => `${relDir}/${f}`);
29642
29288
  }
29643
29289
  async function scanSkillDirs(vaultPath) {
29644
- const skillsRoot = path13.join(vaultPath, ".opencode", "skills");
29290
+ const skillsRoot = path10.join(vaultPath, ".opencode", "skills");
29645
29291
  if (!await fs.pathExists(skillsRoot))
29646
29292
  return [];
29647
29293
  const results = [];
29648
29294
  const entries = await fs.readdir(skillsRoot, { withFileTypes: true });
29649
29295
  for (const entry of entries) {
29650
29296
  if (entry.isDirectory()) {
29651
- const skillMd = path13.join(skillsRoot, entry.name, "SKILL.md");
29297
+ const skillMd = path10.join(skillsRoot, entry.name, "SKILL.md");
29652
29298
  if (await fs.pathExists(skillMd)) {
29653
29299
  results.push(`.opencode/skills/${entry.name}/SKILL.md`);
29654
29300
  }
@@ -29656,7 +29302,7 @@ async function scanSkillDirs(vaultPath) {
29656
29302
  }
29657
29303
  return results;
29658
29304
  }
29659
- var DEFAULT_PRESET = "pm-tpm";
29305
+ var DEFAULT_PRESET = "minimal";
29660
29306
  async function bootstrapManifest(vaultPath, preset) {
29661
29307
  const installedFiles = await scanInstalledAssets(vaultPath);
29662
29308
  await writeManifest(vaultPath, preset ?? DEFAULT_PRESET, installedFiles, "0.0.0");
@@ -29677,7 +29323,7 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
29677
29323
  const installed = new Set(manifest.infrastructure[key]);
29678
29324
  const shippedPaths = new Set(shipped.map((s) => s.relativePath));
29679
29325
  for (const entry of shipped) {
29680
- const onDisk = fs.existsSync(path13.join(vaultPath, entry.relativePath));
29326
+ const onDisk = fs.existsSync(path10.join(vaultPath, entry.relativePath));
29681
29327
  items.push({
29682
29328
  file: entry.relativePath,
29683
29329
  action: onDisk ? "update" : "add",
@@ -29700,23 +29346,103 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
29700
29346
  items
29701
29347
  };
29702
29348
  }
29349
+ var LLM_WIKI_AGENT_DIRS = ["entities", "concepts", "comparisons", "queries"];
29350
+ var LOG_MD_PLACEHOLDER = `# Agent Activity Log
29351
+
29352
+ Entries are appended here during /cook operations.
29353
+
29354
+ `;
29355
+ async function migrateV1ToV2Infrastructure(vaultPath) {
29356
+ for (const dir of LLM_WIKI_AGENT_DIRS) {
29357
+ const dirPath = path10.join(vaultPath, dir);
29358
+ if (!await fs.pathExists(dirPath)) {
29359
+ await fs.ensureDir(dirPath);
29360
+ }
29361
+ }
29362
+ const schemaPath = path10.join(vaultPath, "SCHEMA.md");
29363
+ if (!await fs.pathExists(schemaPath)) {
29364
+ const commonDir = getCommonDir();
29365
+ const schemaTemplatePath = path10.join(commonDir, "SCHEMA.md.hbs");
29366
+ let content;
29367
+ if (await fs.pathExists(schemaTemplatePath)) {
29368
+ const schemaTemplate = await fs.readFile(schemaTemplatePath, "utf-8");
29369
+ content = renderTemplate(schemaTemplate, {
29370
+ KB_NAME: path10.basename(vaultPath),
29371
+ WIKI_DOMAIN: ""
29372
+ });
29373
+ } else {
29374
+ content = `# SCHEMA
29375
+
29376
+ This file describes the vault knowledge schema. Update it as your model evolves.
29377
+
29378
+ `;
29379
+ }
29380
+ await fs.writeFile(schemaPath, content, "utf-8");
29381
+ }
29382
+ const logPath = path10.join(vaultPath, "log.md");
29383
+ if (!await fs.pathExists(logPath)) {
29384
+ await fs.writeFile(logPath, LOG_MD_PLACEHOLDER, "utf-8");
29385
+ }
29386
+ }
29387
+ async function collectV1DeprecatedInfrastructureItems(vaultPath) {
29388
+ const items = [];
29389
+ const templatesDir = path10.join(vaultPath, "Knowledge", "templates");
29390
+ if (await fs.pathExists(templatesDir)) {
29391
+ const files = await fs.readdir(templatesDir);
29392
+ for (const f of files) {
29393
+ if (f.endsWith(".md")) {
29394
+ items.push({
29395
+ file: `Knowledge/templates/${f}`,
29396
+ action: "deprecated",
29397
+ category: "templates"
29398
+ });
29399
+ }
29400
+ }
29401
+ }
29402
+ for (const cmd of ["weave.md", "emerge.md"]) {
29403
+ const rel = `.opencode/commands/${cmd}`;
29404
+ if (await fs.pathExists(path10.join(vaultPath, rel))) {
29405
+ items.push({
29406
+ file: rel,
29407
+ action: "deprecated",
29408
+ category: "commands"
29409
+ });
29410
+ }
29411
+ }
29412
+ return items;
29413
+ }
29414
+ function mergeForcedDeprecatedIntoPlan(items, forced) {
29415
+ const forcedFiles = new Set(forced.map((i) => i.file));
29416
+ const filtered = items.filter((i) => !(forcedFiles.has(i.file) && (i.action === "add" || i.action === "update")));
29417
+ const byFile = new Map(filtered.map((i) => [i.file, i]));
29418
+ for (const f of forced) {
29419
+ byFile.set(f.file, f);
29420
+ }
29421
+ return [...byFile.values()];
29422
+ }
29703
29423
  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;
29424
+ const distAssets = path10.resolve(import.meta.dirname, "assets");
29425
+ const srcAssets = path10.resolve(import.meta.dirname, "..", "assets");
29426
+ const devAssets = path10.resolve(import.meta.dirname, "..", "..", "src", "assets");
29708
29427
  if (fs.existsSync(distAssets))
29709
29428
  return distAssets;
29710
- return srcAssets;
29429
+ if (fs.existsSync(srcAssets))
29430
+ return srcAssets;
29431
+ if (fs.existsSync(devAssets))
29432
+ return devAssets;
29433
+ return distAssets;
29711
29434
  }
29712
29435
  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;
29436
+ const distSkills = path10.resolve(import.meta.dirname, "assets", "skills");
29437
+ const srcSkills = path10.resolve(import.meta.dirname, "..", "skills");
29438
+ const devSkills = path10.resolve(import.meta.dirname, "..", "..", "src", "skills");
29717
29439
  if (fs.existsSync(distSkills))
29718
29440
  return distSkills;
29719
- return srcSkills;
29441
+ if (fs.existsSync(srcSkills))
29442
+ return srcSkills;
29443
+ if (fs.existsSync(devSkills))
29444
+ return devSkills;
29445
+ return distSkills;
29720
29446
  }
29721
29447
  function resolvePackageAssets(preset) {
29722
29448
  const assetsDir = resolveAssetsDir2();
@@ -29726,14 +29452,14 @@ function resolvePackageAssets(preset) {
29726
29452
  const commands = [];
29727
29453
  const obsidianConfig = [];
29728
29454
  const templates = [];
29729
- const obsidianSkillsDir = path13.join(assetsDir, "obsidian-skills");
29455
+ const obsidianSkillsDir = path10.join(assetsDir, "obsidian-skills");
29730
29456
  if (fs.existsSync(obsidianSkillsDir)) {
29731
29457
  for (const file2 of fs.readdirSync(obsidianSkillsDir)) {
29732
29458
  if (file2.endsWith(".md")) {
29733
29459
  const skillName = file2.replace(/\.md$/, "");
29734
29460
  skills.push({
29735
29461
  relativePath: `.opencode/skills/${skillName}/SKILL.md`,
29736
- sourcePath: path13.join(obsidianSkillsDir, file2)
29462
+ sourcePath: path10.join(obsidianSkillsDir, file2)
29737
29463
  });
29738
29464
  }
29739
29465
  }
@@ -29743,15 +29469,15 @@ function resolvePackageAssets(preset) {
29743
29469
  if (file2.endsWith(".md")) {
29744
29470
  commands.push({
29745
29471
  relativePath: `.opencode/commands/${file2}`,
29746
- sourcePath: path13.join(skillsDir, file2)
29472
+ sourcePath: path10.join(skillsDir, file2)
29747
29473
  });
29748
29474
  }
29749
29475
  }
29750
29476
  }
29751
- const obsidianSrcDir = path13.join(commonDir, "obsidian");
29477
+ const obsidianSrcDir = path10.join(commonDir, "obsidian");
29752
29478
  if (fs.existsSync(obsidianSrcDir)) {
29753
29479
  for (const file2 of OBSIDIAN_CONFIG_FILES) {
29754
- const srcPath = path13.join(obsidianSrcDir, file2);
29480
+ const srcPath = path10.join(obsidianSrcDir, file2);
29755
29481
  if (fs.existsSync(srcPath)) {
29756
29482
  obsidianConfig.push({
29757
29483
  relativePath: `.obsidian/${file2}`,
@@ -29760,26 +29486,26 @@ function resolvePackageAssets(preset) {
29760
29486
  }
29761
29487
  }
29762
29488
  }
29763
- const commonTemplatesDir = path13.join(commonDir, "templates");
29489
+ const commonTemplatesDir = path10.join(commonDir, "templates");
29764
29490
  if (fs.existsSync(commonTemplatesDir)) {
29765
29491
  for (const file2 of fs.readdirSync(commonTemplatesDir)) {
29766
29492
  if (file2.endsWith(".md")) {
29767
29493
  templates.push({
29768
29494
  relativePath: `Knowledge/templates/${file2}`,
29769
- sourcePath: path13.join(commonTemplatesDir, file2)
29495
+ sourcePath: path10.join(commonTemplatesDir, file2)
29770
29496
  });
29771
29497
  }
29772
29498
  }
29773
29499
  }
29774
29500
  try {
29775
29501
  const { presetsDir } = loadPreset(preset);
29776
- const presetTemplatesDir = path13.join(presetsDir, preset, "templates");
29502
+ const presetTemplatesDir = path10.join(presetsDir, preset, "templates");
29777
29503
  if (fs.existsSync(presetTemplatesDir)) {
29778
29504
  for (const file2 of fs.readdirSync(presetTemplatesDir)) {
29779
29505
  if (file2.endsWith(".md")) {
29780
29506
  templates.push({
29781
29507
  relativePath: `Knowledge/templates/${file2}`,
29782
- sourcePath: path13.join(presetTemplatesDir, file2)
29508
+ sourcePath: path10.join(presetTemplatesDir, file2)
29783
29509
  });
29784
29510
  }
29785
29511
  }
@@ -29811,14 +29537,21 @@ async function upgradeVault(vaultPath, options2) {
29811
29537
  dryRun
29812
29538
  };
29813
29539
  }
29814
- const legacyAgentMd = path13.join(vaultPath, "AGENT.md");
29815
- const newAgentsMd = path13.join(vaultPath, "AGENTS.md");
29540
+ const legacyAgentMd = path10.join(vaultPath, "AGENT.md");
29541
+ const newAgentsMd = path10.join(vaultPath, "AGENTS.md");
29816
29542
  if (!dryRun && await fs.pathExists(legacyAgentMd) && !await fs.pathExists(newAgentsMd)) {
29817
29543
  await fs.rename(legacyAgentMd, newAgentsMd);
29818
29544
  }
29545
+ if (!dryRun) {
29546
+ await migrateV1ToV2Infrastructure(vaultPath);
29547
+ }
29819
29548
  const effectivePreset = preset ?? manifest.preset;
29820
29549
  const packageAssets = resolvePackageAssets(effectivePreset);
29821
- const plan = buildUpgradePlan(vaultPath, manifest, packageAssets);
29550
+ let plan = buildUpgradePlan(vaultPath, manifest, packageAssets);
29551
+ plan = {
29552
+ ...plan,
29553
+ items: mergeForcedDeprecatedIntoPlan(plan.items, await collectV1DeprecatedInfrastructureItems(vaultPath))
29554
+ };
29822
29555
  const added = [];
29823
29556
  const updated = [];
29824
29557
  const deprecated = [];
@@ -29835,8 +29568,8 @@ async function upgradeVault(vaultPath, options2) {
29835
29568
  if (item.action === "add" || item.action === "update") {
29836
29569
  const source = sourceMap.get(item.file);
29837
29570
  if (source) {
29838
- const dest = path13.join(vaultPath, item.file);
29839
- await fs.ensureDir(path13.dirname(dest));
29571
+ const dest = path10.join(vaultPath, item.file);
29572
+ await fs.ensureDir(path10.dirname(dest));
29840
29573
  await fs.copy(source, dest, { overwrite: true });
29841
29574
  if (item.action === "add") {
29842
29575
  added.push(item.file);
@@ -29931,17 +29664,17 @@ var byoao_vault_upgrade = tool({
29931
29664
  });
29932
29665
 
29933
29666
  // dist/tools/mcp-auth.js
29934
- import { spawn, execSync as execSync4 } from "node:child_process";
29935
- import path14 from "node:path";
29667
+ import { spawn, execSync as execSync3 } from "node:child_process";
29668
+ import path11 from "node:path";
29936
29669
  import os4 from "node:os";
29937
29670
  function findOpencodeBinary() {
29938
29671
  const candidates = [
29939
- path14.join(os4.homedir(), ".opencode/bin/opencode"),
29672
+ path11.join(os4.homedir(), ".opencode/bin/opencode"),
29940
29673
  "/usr/local/bin/opencode"
29941
29674
  ];
29942
29675
  for (const p of candidates) {
29943
29676
  try {
29944
- execSync4(`test -x "${p}"`, { stdio: "pipe" });
29677
+ execSync3(`test -x "${p}"`, { stdio: "pipe" });
29945
29678
  return p;
29946
29679
  } catch {
29947
29680
  }
@@ -30039,10 +29772,13 @@ The user may need to:
30039
29772
  }
30040
29773
  });
30041
29774
 
29775
+ // dist/hooks/system-transform.js
29776
+ import path12 from "node:path";
29777
+
30042
29778
  // dist/lib/logger.js
30043
29779
  import { join } from "node:path";
30044
29780
  import { homedir } from "node:os";
30045
- import { appendFile, stat, rename as rename3, mkdir as mkdir2, readFile as readFile2, unlink } from "node:fs/promises";
29781
+ import { appendFile, stat as stat2, rename as rename3, mkdir as mkdir2, readFile as readFile2, unlink } from "node:fs/promises";
30046
29782
  var LOG_DIR = process.env.BYOAO_LOG_DIR || join(homedir(), ".byoao", "logs");
30047
29783
  var LOG_FILE = join(LOG_DIR, "error.log");
30048
29784
  var MAX_LOG_SIZE = 512 * 1024;
@@ -30085,7 +29821,7 @@ async function ensureLogDir() {
30085
29821
  }
30086
29822
  async function rotateIfNeeded() {
30087
29823
  try {
30088
- const s = await stat(LOG_FILE);
29824
+ const s = await stat2(LOG_FILE);
30089
29825
  if (s.size >= MAX_LOG_SIZE) {
30090
29826
  await rename3(LOG_FILE, ROTATED_FILE);
30091
29827
  }
@@ -30116,6 +29852,20 @@ async function log(level, source, message, options2) {
30116
29852
  }
30117
29853
 
30118
29854
  // dist/hooks/system-transform.js
29855
+ function readVaultMarkdown(vaultPath, fileName) {
29856
+ const full = path12.join(vaultPath, fileName);
29857
+ if (!fs.existsSync(full))
29858
+ return null;
29859
+ try {
29860
+ return fs.readFileSync(full, "utf-8");
29861
+ } catch {
29862
+ void log("warn", "hook:system-transform", `Failed to read ${fileName}`, {
29863
+ context: { path: full }
29864
+ }).catch(() => {
29865
+ });
29866
+ return null;
29867
+ }
29868
+ }
30119
29869
  async function buildMcpAuthGuidance() {
30120
29870
  try {
30121
29871
  const config2 = await readOpencodeConfig();
@@ -30153,6 +29903,31 @@ async function buildMcpAuthGuidance() {
30153
29903
  }
30154
29904
  }
30155
29905
  async function systemTransformHook(_input, output) {
29906
+ const vaultPath = detectVaultContext(process.cwd());
29907
+ if (vaultPath) {
29908
+ let agentsTitle = "## AGENTS.md";
29909
+ let agents = readVaultMarkdown(vaultPath, "AGENTS.md");
29910
+ if (!agents) {
29911
+ agents = readVaultMarkdown(vaultPath, "AGENT.md");
29912
+ if (agents)
29913
+ agentsTitle = "## AGENT.md";
29914
+ }
29915
+ if (agents) {
29916
+ output.system.push(`
29917
+ ---
29918
+ ${agentsTitle}
29919
+
29920
+ ${agents}`);
29921
+ }
29922
+ const schema = readVaultMarkdown(vaultPath, "SCHEMA.md");
29923
+ if (schema) {
29924
+ output.system.push(`
29925
+ ---
29926
+ ## SCHEMA.md
29927
+
29928
+ ${schema}`);
29929
+ }
29930
+ }
30156
29931
  const mcpGuidance = await buildMcpAuthGuidance();
30157
29932
  if (mcpGuidance) {
30158
29933
  output.system.push(mcpGuidance);
@@ -30162,15 +29937,15 @@ async function systemTransformHook(_input, output) {
30162
29937
  // dist/hooks/idle-suggestions.js
30163
29938
  function getIdleSuggestion() {
30164
29939
  const suggestions = [
30165
- "Tip: run /weave to connect your notes with frontmatter and wikilinks",
29940
+ "Tip: run /cook to compile your notes into structured knowledge pages",
29941
+ "Tip: run /health to check knowledge page health",
29942
+ "Tip: run /wiki to regenerate INDEX.base",
30166
29943
  "Tip: run /trace to see how an idea evolved over time",
30167
- "Tip: run /emerge to discover patterns across your notes",
30168
29944
  "Tip: run /connect to bridge two topics using your vault's link graph",
30169
29945
  "Tip: run /ideas to generate actionable insights from your vault",
30170
29946
  "Tip: run /challenge to pressure-test a belief against your own notes",
30171
29947
  "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"
29948
+ "Tip: run /diagnose to check overall vault health"
30174
29949
  ];
30175
29950
  const idx = (/* @__PURE__ */ new Date()).getMinutes() % suggestions.length;
30176
29951
  return suggestions[idx];
@@ -30181,12 +29956,9 @@ var BYOAOPlugin = async (ctx) => {
30181
29956
  const { client } = ctx;
30182
29957
  const tools = {
30183
29958
  byoao_init_vault,
30184
- byoao_add_person,
30185
- byoao_add_project,
30186
29959
  byoao_vault_status,
30187
29960
  byoao_vault_doctor,
30188
29961
  byoao_switch_provider,
30189
- byoao_graph_health,
30190
29962
  byoao_vault_upgrade,
30191
29963
  byoao_mcp_auth
30192
29964
  };