@jayjiang/byoao 1.1.0 → 1.1.2

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 (95) hide show
  1. package/dist/assets/obsidian-skills/byoao-conventions.md +103 -0
  2. package/dist/assets/obsidian-skills/defuddle.md +41 -0
  3. package/dist/assets/obsidian-skills/json-canvas.md +244 -0
  4. package/dist/assets/obsidian-skills/obsidian-bases.md +497 -0
  5. package/dist/assets/obsidian-skills/obsidian-cli.md +106 -0
  6. package/dist/assets/obsidian-skills/obsidian-markdown.md +196 -0
  7. package/dist/assets/obsidian-skills/vault-thinking.md +40 -0
  8. package/{src/assets/presets/common/AGENT.md.hbs → dist/assets/presets/common/AGENTS.md.hbs} +11 -15
  9. package/dist/assets/presets/common/Start Here.md.hbs +137 -0
  10. package/dist/assets/presets/common/obsidian/core-plugins.json +33 -0
  11. package/dist/assets/presets/common/obsidian/daily-notes.json +5 -0
  12. package/dist/assets/presets/common/obsidian/templates.json +3 -0
  13. package/dist/assets/presets/common/templates/Daily Note.md +19 -0
  14. package/dist/assets/presets/common/templates/Decision Record.md +32 -0
  15. package/dist/assets/presets/common/templates/Investigation.md +34 -0
  16. package/dist/assets/presets/common/templates/Meeting Notes.md +25 -0
  17. package/dist/assets/presets/minimal/preset.json +28 -0
  18. package/dist/assets/presets/pm-tpm/agent-section.hbs +15 -0
  19. package/dist/assets/presets/pm-tpm/preset.json +43 -0
  20. package/dist/assets/presets/pm-tpm/templates/Feature Doc.md +45 -0
  21. package/dist/assets/presets/pm-tpm/templates/Sprint Handoff.md +38 -0
  22. package/dist/assets/skills/ask.md +132 -0
  23. package/dist/assets/skills/challenge.md +174 -0
  24. package/dist/assets/skills/connect.md +213 -0
  25. package/dist/assets/skills/diagnose.md +72 -0
  26. package/dist/assets/skills/drift.md +223 -0
  27. package/dist/assets/skills/emerge.md +168 -0
  28. package/dist/assets/skills/ideas.md +172 -0
  29. package/dist/assets/skills/organize.md +206 -0
  30. package/dist/assets/skills/trace.md +156 -0
  31. package/dist/assets/skills/weave.md +287 -0
  32. package/dist/assets/skills/wiki.md +227 -0
  33. package/dist/cli/cli-program.js +1 -1
  34. package/dist/cli/cli-program.js.map +1 -1
  35. package/dist/cli/installer.js +37 -2
  36. package/dist/cli/installer.js.map +1 -1
  37. package/dist/hooks/__tests__/system-transform.test.js +47 -29
  38. package/dist/hooks/__tests__/system-transform.test.js.map +1 -1
  39. package/dist/hooks/system-transform.js +2 -113
  40. package/dist/hooks/system-transform.js.map +1 -1
  41. package/dist/index.js +162 -482
  42. package/dist/index.js.map +1 -1
  43. package/dist/lib/cjs-modules.js +4 -1
  44. package/dist/lib/cjs-modules.js.map +1 -1
  45. package/dist/tools/add-person.js +1 -1
  46. package/dist/tools/add-person.js.map +1 -1
  47. package/dist/tools/add-project.js +1 -1
  48. package/dist/tools/add-project.js.map +1 -1
  49. package/dist/tools/init-vault.js +1 -1
  50. package/dist/tools/init-vault.js.map +1 -1
  51. package/dist/tools/vault-doctor.js +1 -1
  52. package/dist/tools/vault-doctor.js.map +1 -1
  53. package/dist/vault/__tests__/create.test.js +23 -23
  54. package/dist/vault/__tests__/create.test.js.map +1 -1
  55. package/dist/vault/__tests__/obsidian-cli.test.js +108 -0
  56. package/dist/vault/__tests__/obsidian-cli.test.js.map +1 -0
  57. package/dist/vault/__tests__/status.test.js +1 -8
  58. package/dist/vault/__tests__/status.test.js.map +1 -1
  59. package/dist/vault/__tests__/vault-detect.test.js +1 -13
  60. package/dist/vault/__tests__/vault-detect.test.js.map +1 -1
  61. package/dist/vault/create.js +23 -64
  62. package/dist/vault/create.js.map +1 -1
  63. package/dist/vault/doctor.js +15 -6
  64. package/dist/vault/doctor.js.map +1 -1
  65. package/dist/vault/manifest.js +1 -1
  66. package/dist/vault/member.js +2 -2
  67. package/dist/vault/member.js.map +1 -1
  68. package/dist/vault/obsidian-cli.js +28 -5
  69. package/dist/vault/obsidian-cli.js.map +1 -1
  70. package/dist/vault/project.js +2 -2
  71. package/dist/vault/project.js.map +1 -1
  72. package/dist/vault/self-update.js +1 -1
  73. package/dist/vault/status.js +3 -5
  74. package/dist/vault/status.js.map +1 -1
  75. package/dist/vault/upgrade.js +7 -2
  76. package/dist/vault/upgrade.js.map +1 -1
  77. package/dist/vault/vault-detect.js +4 -5
  78. package/dist/vault/vault-detect.js.map +1 -1
  79. package/package.json +1 -1
  80. package/src/assets/obsidian-skills/byoao-conventions.md +28 -55
  81. package/src/assets/obsidian-skills/vault-thinking.md +1 -1
  82. package/src/assets/presets/common/AGENTS.md.hbs +25 -0
  83. package/src/assets/presets/common/Start Here.md.hbs +2 -2
  84. package/src/skills/ask.md +132 -0
  85. package/src/skills/challenge.md +8 -2
  86. package/src/skills/connect.md +8 -1
  87. package/src/skills/diagnose.md +12 -13
  88. package/src/skills/drift.md +8 -2
  89. package/src/skills/emerge.md +8 -1
  90. package/src/skills/ideas.md +9 -3
  91. package/src/skills/organize.md +3 -4
  92. package/src/skills/trace.md +10 -3
  93. package/src/skills/weave.md +84 -79
  94. package/src/skills/wiki.md +227 -0
  95. /package/{src → dist}/assets/presets/common/Glossary.md.hbs +0 -0
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(path18) {
4686
- return /^\.|this\b/.test(path18.original);
4685
+ scopedId: function scopedId(path15) {
4686
+ return /^\.|this\b/.test(path15.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(path18) {
4691
- return path18.parts.length === 1 && !AST.helpers.scopedId(path18) && !path18.depth;
4690
+ simpleId: function simpleId(path15) {
4691
+ return path15.parts.length === 1 && !AST.helpers.scopedId(path15) && !path15.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(path18, params, hash2, open, strip, locInfo) {
5761
+ function prepareMustache(path15, 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: path18,
5766
+ path: path15,
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), path18 = decorator.path;
6036
+ var params = this.setupFullMustacheParams(decorator, program, void 0), path15 = decorator.path;
6037
6037
  this.useDecorators = true;
6038
- this.opcode("registerDecorator", params.length, path18.original);
6038
+ this.opcode("registerDecorator", params.length, path15.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 path18 = sexpr.path, name = path18.parts[0], isBlock = program != null || inverse != null;
6103
- this.opcode("getContext", path18.depth);
6102
+ var path15 = sexpr.path, name = path15.parts[0], isBlock = program != null || inverse != null;
6103
+ this.opcode("getContext", path15.depth);
6104
6104
  this.opcode("pushProgram", program);
6105
6105
  this.opcode("pushProgram", inverse);
6106
- path18.strict = true;
6107
- this.accept(path18);
6106
+ path15.strict = true;
6107
+ this.accept(path15);
6108
6108
  this.opcode("invokeAmbiguous", name, isBlock);
6109
6109
  },
6110
6110
  simpleSexpr: function simpleSexpr(sexpr) {
6111
- var path18 = sexpr.path;
6112
- path18.strict = true;
6113
- this.accept(path18);
6111
+ var path15 = sexpr.path;
6112
+ path15.strict = true;
6113
+ this.accept(path15);
6114
6114
  this.opcode("resolvePossibleLambda");
6115
6115
  },
6116
6116
  helperSexpr: function helperSexpr(sexpr, program, inverse) {
6117
- var params = this.setupFullMustacheParams(sexpr, program, inverse), path18 = sexpr.path, name = path18.parts[0];
6117
+ var params = this.setupFullMustacheParams(sexpr, program, inverse), path15 = sexpr.path, name = path15.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
- path18.strict = true;
6124
- path18.falsy = true;
6125
- this.accept(path18);
6126
- this.opcode("invokeHelper", params.length, path18.original, _ast2["default"].helpers.simpleId(path18));
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));
6127
6127
  }
6128
6128
  },
6129
- PathExpression: function PathExpression(path18) {
6130
- this.addDepth(path18.depth);
6131
- this.opcode("getContext", path18.depth);
6132
- var name = path18.parts[0], scoped = _ast2["default"].helpers.scopedId(path18), blockParamId = !path18.depth && !scoped && this.blockParamIndex(name);
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);
6133
6133
  if (blockParamId) {
6134
- this.opcode("lookupBlockParam", blockParamId, path18.parts);
6134
+ this.opcode("lookupBlockParam", blockParamId, path15.parts);
6135
6135
  } else if (!name) {
6136
6136
  this.opcode("pushContext");
6137
- } else if (path18.data) {
6137
+ } else if (path15.data) {
6138
6138
  this.options.data = true;
6139
- this.opcode("lookupData", path18.depth, path18.parts, path18.strict);
6139
+ this.opcode("lookupData", path15.depth, path15.parts, path15.strict);
6140
6140
  } else {
6141
- this.opcode("lookupOnContext", path18.parts, path18.falsy, path18.strict, scoped);
6141
+ this.opcode("lookupOnContext", path15.parts, path15.falsy, path15.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 path18 = aPath;
6491
+ var path15 = aPath;
6492
6492
  var url2 = urlParse(aPath);
6493
6493
  if (url2) {
6494
6494
  if (!url2.path) {
6495
6495
  return aPath;
6496
6496
  }
6497
- path18 = url2.path;
6497
+ path15 = url2.path;
6498
6498
  }
6499
- var isAbsolute = exports2.isAbsolute(path18);
6500
- var parts = path18.split(/\/+/);
6499
+ var isAbsolute = exports2.isAbsolute(path15);
6500
+ var parts = path15.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
- path18 = parts.join("/");
6518
- if (path18 === "") {
6519
- path18 = isAbsolute ? "/" : ".";
6517
+ path15 = parts.join("/");
6518
+ if (path15 === "") {
6519
+ path15 = isAbsolute ? "/" : ".";
6520
6520
  }
6521
6521
  if (url2) {
6522
- url2.path = path18;
6522
+ url2.path = path15;
6523
6523
  return urlGenerate(url2);
6524
6524
  }
6525
- return path18;
6525
+ return path15;
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 path18 = id.parts.join("/");
9307
- return (id.data ? "@" : "") + "PATH:" + path18;
9306
+ var path15 = id.parts.join("/");
9307
+ return (id.data ? "@" : "") + "PATH:" + path15;
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, path18) {
12019
- if (!path18)
12018
+ function getElementAtPath(obj, path15) {
12019
+ if (!path15)
12020
12020
  return obj;
12021
- return path18.reduce((acc, key) => acc?.[key], obj);
12021
+ return path15.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(path18, issues) {
12382
+ function prefixIssues(path15, issues) {
12383
12383
  return issues.map((iss) => {
12384
12384
  var _a;
12385
12385
  (_a = iss).path ?? (_a.path = []);
12386
- iss.path.unshift(path18);
12386
+ iss.path.unshift(path15);
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, path18 = []) => {
12554
+ const processError = (error46, path15 = []) => {
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 = [...path18, ...issue2.path];
12564
+ const fullpath = [...path15, ...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 path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12597
- for (const seg of path18) {
12596
+ const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12597
+ for (const seg of path15) {
12598
12598
  if (typeof seg === "number")
12599
12599
  segs.push(`[${seg}]`);
12600
12600
  else if (typeof seg === "symbol")
@@ -23713,6 +23713,9 @@ var _semver = __toESM(require_semver2(), 1);
23713
23713
  import * as nodeFs from "node:fs";
23714
23714
  import * as nodeFsPromises from "node:fs/promises";
23715
23715
  import nodePath from "node:path";
23716
+ async function rename2(oldPath, newPath) {
23717
+ await nodeFsPromises.rename(oldPath, newPath);
23718
+ }
23716
23719
  async function copy(src, dest) {
23717
23720
  await nodeFsPromises.cp(src, dest, { recursive: true });
23718
23721
  }
@@ -23761,6 +23764,7 @@ var fs = {
23761
23764
  readdir: nodeFsPromises.readdir,
23762
23765
  mkdir: nodeFsPromises.mkdir,
23763
23766
  copy,
23767
+ rename: rename2,
23764
23768
  ensureDir,
23765
23769
  pathExists,
23766
23770
  pathExistsSync,
@@ -24272,8 +24276,8 @@ function getErrorMap2() {
24272
24276
 
24273
24277
  // node_modules/zod/v3/helpers/parseUtil.js
24274
24278
  var makeIssue = (params) => {
24275
- const { data, path: path18, errorMaps, issueData } = params;
24276
- const fullPath = [...path18, ...issueData.path || []];
24279
+ const { data, path: path15, errorMaps, issueData } = params;
24280
+ const fullPath = [...path15, ...issueData.path || []];
24277
24281
  const fullIssue = {
24278
24282
  ...issueData,
24279
24283
  path: fullPath
@@ -24389,11 +24393,11 @@ var errorUtil;
24389
24393
 
24390
24394
  // node_modules/zod/v3/types.js
24391
24395
  var ParseInputLazyPath = class {
24392
- constructor(parent, value, path18, key) {
24396
+ constructor(parent, value, path15, key) {
24393
24397
  this._cachedPath = [];
24394
24398
  this.parent = parent;
24395
24399
  this.data = value;
24396
- this._path = path18;
24400
+ this._path = path15;
24397
24401
  this._key = key;
24398
24402
  }
24399
24403
  get path() {
@@ -28283,7 +28287,7 @@ async function configureProvider(provider, gcpProjectId) {
28283
28287
 
28284
28288
  // dist/vault/manifest.js
28285
28289
  import path4 from "node:path";
28286
- var PKG_VERSION = "1.1.0";
28290
+ var PKG_VERSION = "1.1.2";
28287
28291
  var InfrastructureSchema = external_exports2.object({
28288
28292
  skills: external_exports2.array(external_exports2.string()).default([]),
28289
28293
  commands: external_exports2.array(external_exports2.string()).default([]),
@@ -28348,9 +28352,9 @@ function detectVaultContext(dir) {
28348
28352
  const hasObsidian = fs.existsSync(path5.join(candidate, ".obsidian"));
28349
28353
  if (!hasObsidian)
28350
28354
  continue;
28351
- const hasAgentMd = fs.existsSync(path5.join(candidate, "AGENT.md"));
28352
- const hasGlossary = fs.existsSync(path5.join(candidate, "Knowledge", "Glossary.md"));
28353
- if (hasAgentMd || hasGlossary) {
28355
+ const hasAgentsMd = fs.existsSync(path5.join(candidate, "AGENTS.md"));
28356
+ const hasAgentMdFallback = fs.existsSync(path5.join(candidate, "AGENT.md"));
28357
+ if (hasAgentsMd || hasAgentMdFallback) {
28354
28358
  return candidate;
28355
28359
  }
28356
28360
  }
@@ -28384,11 +28388,7 @@ function countWikilinks(content) {
28384
28388
  const matches = stripped.match(/\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g);
28385
28389
  return matches ? matches.length : 0;
28386
28390
  }
28387
- var MINIMAL_DIRECTORIES = [
28388
- "Daily",
28389
- "Knowledge",
28390
- "Knowledge/templates"
28391
- ];
28391
+ var MINIMAL_DIRECTORIES = [];
28392
28392
  function makeContext(vaultPath, kbName, preserveObsidian = false) {
28393
28393
  return {
28394
28394
  vaultPath,
@@ -28410,7 +28410,7 @@ var MCP_DISPLAY_NAMES = {
28410
28410
  atlassian: { name: "Atlassian", description: "Jira issues, Confluence pages" },
28411
28411
  bigquery: { name: "BigQuery", description: "Data warehouse queries and analysis" }
28412
28412
  };
28413
- async function createMinimalCore(ctx, glossaryEntries = []) {
28413
+ async function createMinimalCore(ctx, _glossaryEntries = []) {
28414
28414
  for (const dir of MINIMAL_DIRECTORIES) {
28415
28415
  await fs.ensureDir(path6.join(ctx.vaultPath, dir));
28416
28416
  }
@@ -28427,31 +28427,6 @@ async function createMinimalCore(ctx, glossaryEntries = []) {
28427
28427
  }
28428
28428
  }
28429
28429
  }
28430
- const templateDest = path6.join(ctx.vaultPath, "Knowledge/templates");
28431
- const commonTemplatesDir = path6.join(ctx.commonDir, "templates");
28432
- if (await fs.pathExists(commonTemplatesDir)) {
28433
- const files = await fs.readdir(commonTemplatesDir);
28434
- for (const file2 of files) {
28435
- await fs.copy(path6.join(commonTemplatesDir, file2), path6.join(templateDest, file2), { overwrite: false });
28436
- ctx.filesCreated++;
28437
- ctx.installedFiles.templates.push(`Knowledge/templates/${file2}`);
28438
- }
28439
- }
28440
- const glossaryTemplate = await fs.readFile(path6.join(ctx.commonDir, "Glossary.md.hbs"), "utf-8");
28441
- let glossaryRows = "";
28442
- if (glossaryEntries.length > 0) {
28443
- glossaryRows = glossaryEntries.map((e) => `| **${e.term}** | ${e.definition} | ${e.domain} |`).join("\n");
28444
- }
28445
- const glossaryContent = renderTemplate(glossaryTemplate, {
28446
- KB_NAME: ctx.kbName,
28447
- date: today(),
28448
- GLOSSARY_ENTRIES: glossaryRows
28449
- });
28450
- const glossaryPath = path6.join(ctx.vaultPath, "Knowledge/Glossary.md");
28451
- if (!await fs.pathExists(glossaryPath)) {
28452
- await fs.writeFile(glossaryPath, glossaryContent);
28453
- ctx.filesCreated++;
28454
- }
28455
28430
  const startHereTemplate = await fs.readFile(path6.join(ctx.commonDir, "Start Here.md.hbs"), "utf-8");
28456
28431
  const startHereContent = renderTemplate(startHereTemplate, {
28457
28432
  KB_NAME: ctx.kbName,
@@ -28464,8 +28439,8 @@ async function createMinimalCore(ctx, glossaryEntries = []) {
28464
28439
  ctx.filesCreated++;
28465
28440
  }
28466
28441
  }
28467
- async function createAgentMd(ctx, ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject) {
28468
- const agentSkeletonTemplate = await fs.readFile(path6.join(ctx.commonDir, "AGENT.md.hbs"), "utf-8");
28442
+ async function createAgentsMd(ctx, ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject) {
28443
+ const agentsTemplate = await fs.readFile(path6.join(ctx.commonDir, "AGENTS.md.hbs"), "utf-8");
28469
28444
  let roleSection = "";
28470
28445
  const agentSectionPath = path6.join(presetDir, "agent-section.hbs");
28471
28446
  if (await fs.pathExists(agentSectionPath)) {
@@ -28483,14 +28458,14 @@ async function createAgentMd(ctx, ownerName, presetConfig, presetDir, projects,
28483
28458
  HAS_JIRA: !!(jiraHost && jiraProject)
28484
28459
  });
28485
28460
  }
28486
- const agentContent = renderTemplate(agentSkeletonTemplate, {
28461
+ const agentsContent = renderTemplate(agentsTemplate, {
28487
28462
  KB_NAME: ctx.kbName,
28488
28463
  OWNER_NAME: ownerName,
28489
28464
  ROLE_SECTION: roleSection
28490
28465
  });
28491
- const agentMdPath = path6.join(ctx.vaultPath, "AGENT.md");
28492
- if (!await fs.pathExists(agentMdPath)) {
28493
- await fs.writeFile(agentMdPath, agentContent);
28466
+ const agentsMdPath = path6.join(ctx.vaultPath, "AGENTS.md");
28467
+ if (!await fs.pathExists(agentsMdPath)) {
28468
+ await fs.writeFile(agentsMdPath, agentsContent);
28494
28469
  ctx.filesCreated++;
28495
28470
  }
28496
28471
  }
@@ -28499,18 +28474,11 @@ async function applyPresetOverlay(ctx, presetConfig, presetDir) {
28499
28474
  await fs.ensureDir(path6.join(ctx.vaultPath, dir));
28500
28475
  }
28501
28476
  ctx.directories.push(...presetConfig.directories);
28502
- const templateDest = path6.join(ctx.vaultPath, "Knowledge/templates");
28503
28477
  const allTemplateNames = [];
28504
- if (await fs.pathExists(templateDest)) {
28505
- const existing = await fs.readdir(templateDest);
28506
- for (const file2 of existing) {
28507
- if (file2.endsWith(".md")) {
28508
- allTemplateNames.push(file2.replace(/\.md$/, ""));
28509
- }
28510
- }
28511
- }
28478
+ const templateDest = path6.join(ctx.vaultPath, "Knowledge/templates");
28512
28479
  const presetTemplatesDir = path6.join(presetDir, "templates");
28513
28480
  if (await fs.pathExists(presetTemplatesDir)) {
28481
+ await fs.ensureDir(templateDest);
28514
28482
  const files = await fs.readdir(presetTemplatesDir);
28515
28483
  for (const file2 of files) {
28516
28484
  await fs.copy(path6.join(presetTemplatesDir, file2), path6.join(templateDest, file2), { overwrite: false });
@@ -28634,7 +28602,7 @@ async function createVault(config2) {
28634
28602
  }
28635
28603
  await createMinimalCore(ctx, glossaryEntries);
28636
28604
  const allTemplateNames = await applyPresetOverlay(ctx, presetConfig, presetDir);
28637
- await createAgentMd(ctx, config2.ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject);
28605
+ await createAgentsMd(ctx, config2.ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject);
28638
28606
  await createPeopleNotes(ctx, members);
28639
28607
  await createProjectNotes(ctx, projects);
28640
28608
  const hasPeopleDir = presetConfig.directories.includes("People") || members.length > 0;
@@ -28847,7 +28815,7 @@ function formatObsidianStatus(status) {
28847
28815
  import path7 from "node:path";
28848
28816
  import os3 from "node:os";
28849
28817
  var byoao_init_vault = tool({
28850
- description: "Create a personal knowledge base in Obsidian. Creates directory structure, templates, glossary, agent routing file (AGENT.md), and optional people/project notes with wikilinks. Checks that Obsidian is installed first.",
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.",
28851
28819
  args: {
28852
28820
  kbName: tool.schema.string().describe(`Knowledge base name (e.g. "Jay's KB")`),
28853
28821
  ownerName: tool.schema.string().optional().describe("Owner's name"),
@@ -29032,7 +29000,7 @@ ${tableRow}`);
29032
29000
  }
29033
29001
  await fs.writeFile(teamIndexPath, teamContent);
29034
29002
  }
29035
- for (const agentFile of ["AGENT.md"]) {
29003
+ for (const agentFile of ["AGENTS.md", "AGENT.md"]) {
29036
29004
  const agentPath = path8.join(vaultPath, agentFile);
29037
29005
  if (await fs.pathExists(agentPath)) {
29038
29006
  let agentContent = await fs.readFile(agentPath, "utf-8");
@@ -29060,7 +29028,7 @@ ${tableRow}`);
29060
29028
 
29061
29029
  // dist/tools/add-person.js
29062
29030
  var byoao_add_person = tool({
29063
- description: "Add a person note to an existing vault. Creates a person note in People/ and updates the team index and AGENT.md wikilinks.",
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.",
29064
29032
  args: {
29065
29033
  vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
29066
29034
  name: tool.schema.string().describe("Person's full name"),
@@ -29124,7 +29092,7 @@ ${projectLine}$3`);
29124
29092
  await fs.writeFile(teamIndexPath, teamContent);
29125
29093
  }
29126
29094
  }
29127
- for (const agentFile of ["AGENT.md"]) {
29095
+ for (const agentFile of ["AGENTS.md", "AGENT.md"]) {
29128
29096
  const agentPath = path9.join(vaultPath, agentFile);
29129
29097
  if (await fs.pathExists(agentPath)) {
29130
29098
  let agentContent = await fs.readFile(agentPath, "utf-8");
@@ -29145,7 +29113,7 @@ ${projectLine}$3`);
29145
29113
 
29146
29114
  // dist/tools/add-project.js
29147
29115
  var byoao_add_project = tool({
29148
- description: "Add a new project note to an existing vault. Creates a project note in Projects/ and updates the team index and AGENT.md wikilinks.",
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.",
29149
29117
  args: {
29150
29118
  vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
29151
29119
  name: tool.schema.string().describe("Project name"),
@@ -29165,55 +29133,8 @@ var byoao_add_project = tool({
29165
29133
  }
29166
29134
  });
29167
29135
 
29168
- // dist/vault/glossary.js
29169
- import path10 from "node:path";
29170
- async function addGlossaryTerm(input) {
29171
- const { vaultPath, term, definition, domain: domain2 } = input;
29172
- const glossaryPath = path10.join(vaultPath, "Knowledge/Glossary.md");
29173
- if (!await fs.pathExists(glossaryPath)) {
29174
- throw new Error(`Glossary not found at: ${glossaryPath}`);
29175
- }
29176
- let content = await fs.readFile(glossaryPath, "utf-8");
29177
- const newRow = `| **${term}** | ${definition} | ${domain2 ?? ""} |`;
29178
- const tableMatch = content.match(/(\| Term \| Definition \| Domain \|\n\|------\|-----------|--------\|\n)([\s\S]*?)(\n*$)/);
29179
- if (tableMatch) {
29180
- const [fullMatch, tableHeader, existingRows, trailing] = tableMatch;
29181
- const updatedRows = existingRows.trim() ? `${existingRows.trim()}
29182
- ${newRow}` : newRow;
29183
- content = content.replace(fullMatch, `${tableHeader}${updatedRows}
29184
- `);
29185
- } else {
29186
- content = content.trimEnd() + `
29187
- ${newRow}
29188
- `;
29189
- }
29190
- await fs.writeFile(glossaryPath, content);
29191
- return { glossaryPath, termAdded: term };
29192
- }
29193
-
29194
- // dist/tools/add-glossary-term.js
29195
- var byoao_add_glossary_term = tool({
29196
- description: "Add a new term to the vault's Glossary.md. Appends a row to the Core Terms table.",
29197
- args: {
29198
- vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
29199
- term: tool.schema.string().describe("The domain term to add"),
29200
- definition: tool.schema.string().describe("Brief definition (1-2 sentences)"),
29201
- domain: tool.schema.string().optional().describe("Knowledge domain (e.g. analytics, infrastructure)")
29202
- },
29203
- async execute(args) {
29204
- const result = await addGlossaryTerm({
29205
- vaultPath: args.vaultPath,
29206
- term: args.term,
29207
- definition: args.definition,
29208
- domain: args.domain ?? ""
29209
- });
29210
- return `\u2713 Added glossary term: ${result.termAdded}
29211
- File: ${result.glossaryPath}`;
29212
- }
29213
- });
29214
-
29215
29136
  // dist/vault/status.js
29216
- import path11 from "node:path";
29137
+ import path10 from "node:path";
29217
29138
  async function getAllMarkdownFiles(dirPath) {
29218
29139
  const results = [];
29219
29140
  async function walk(dir) {
@@ -29221,7 +29142,7 @@ async function getAllMarkdownFiles(dirPath) {
29221
29142
  return;
29222
29143
  const entries = await fs.readdir(dir, { withFileTypes: true });
29223
29144
  for (const entry of entries) {
29224
- const fullPath = path11.join(dir, entry.name);
29145
+ const fullPath = path10.join(dir, entry.name);
29225
29146
  if (entry.isDirectory()) {
29226
29147
  if (!entry.name.startsWith(".")) {
29227
29148
  await walk(fullPath);
@@ -29252,12 +29173,11 @@ async function getVaultStatus(vaultPath) {
29252
29173
  brokenLinks: [],
29253
29174
  directories: {},
29254
29175
  hasObsidianConfig: false,
29255
- hasAgentMd: false,
29256
- hasGlossary: false
29176
+ hasAgentMd: false
29257
29177
  };
29258
29178
  }
29259
29179
  const allFiles = await getAllMarkdownFiles(vaultPath);
29260
- const noteNames = new Set(allFiles.map((f) => path11.basename(f, ".md")));
29180
+ const noteNames = new Set(allFiles.map((f) => path10.basename(f, ".md")));
29261
29181
  let wikilinkCount = 0;
29262
29182
  const brokenLinksSet = /* @__PURE__ */ new Set();
29263
29183
  for (const file2 of allFiles) {
@@ -29282,7 +29202,7 @@ async function getVaultStatus(vaultPath) {
29282
29202
  "Daily"
29283
29203
  ];
29284
29204
  for (const dir of topDirs) {
29285
- const dirPath = path11.join(vaultPath, dir);
29205
+ const dirPath = path10.join(vaultPath, dir);
29286
29206
  if (await fs.pathExists(dirPath)) {
29287
29207
  const files = await getAllMarkdownFiles(dirPath);
29288
29208
  directories[dir] = files.length;
@@ -29295,9 +29215,8 @@ async function getVaultStatus(vaultPath) {
29295
29215
  wikilinkCount,
29296
29216
  brokenLinks: Array.from(brokenLinksSet),
29297
29217
  directories,
29298
- hasObsidianConfig: await fs.pathExists(path11.join(vaultPath, ".obsidian")),
29299
- hasAgentMd: await fs.pathExists(path11.join(vaultPath, "AGENT.md")),
29300
- hasGlossary: await fs.pathExists(path11.join(vaultPath, "Knowledge/Glossary.md"))
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"))
29301
29220
  };
29302
29221
  }
29303
29222
  function formatVaultStatus(status) {
@@ -29316,8 +29235,7 @@ function formatVaultStatus(status) {
29316
29235
  }
29317
29236
  lines.push("");
29318
29237
  lines.push(`Config: ${status.hasObsidianConfig ? "\u2713" : "\u2717"} .obsidian/`);
29319
- lines.push(`Agent: ${status.hasAgentMd ? "\u2713" : "\u2717"} AGENT.md`);
29320
- lines.push(`Glossary: ${status.hasGlossary ? "\u2713" : "\u2717"} Glossary.md`);
29238
+ lines.push(`Agent: ${status.hasAgentMd ? "\u2713" : "\u2717"} AGENTS.md`);
29321
29239
  if (status.brokenLinks.length > 0) {
29322
29240
  lines.push("");
29323
29241
  lines.push(`\u26A0\uFE0F Broken links (${status.brokenLinks.length}):`);
@@ -29350,12 +29268,12 @@ var byoao_vault_status = tool({
29350
29268
  });
29351
29269
 
29352
29270
  // dist/vault/doctor.js
29353
- import path12 from "node:path";
29271
+ import path11 from "node:path";
29354
29272
  async function collectMarkdownFiles(dir) {
29355
29273
  const results = [];
29356
29274
  const entries = await fs.readdir(dir, { withFileTypes: true });
29357
29275
  for (const entry of entries) {
29358
- const fullPath = path12.join(dir, entry.name);
29276
+ const fullPath = path11.join(dir, entry.name);
29359
29277
  if (entry.isDirectory()) {
29360
29278
  if (entry.name === ".obsidian" || entry.name === ".git")
29361
29279
  continue;
@@ -29376,10 +29294,10 @@ function extractWikilinks2(content) {
29376
29294
  async function getVaultDiagnosis(vaultPath) {
29377
29295
  const issues = [];
29378
29296
  const allFiles = await collectMarkdownFiles(vaultPath);
29379
- const noteNames = new Set(allFiles.map((f) => path12.basename(f, ".md")));
29297
+ const noteNames = new Set(allFiles.map((f) => path11.basename(f, ".md")));
29380
29298
  let healthyNotes = 0;
29381
29299
  for (const filePath of allFiles) {
29382
- const relativePath = path12.relative(vaultPath, filePath);
29300
+ const relativePath = path11.relative(vaultPath, filePath);
29383
29301
  if (relativePath.startsWith("Knowledge/templates/"))
29384
29302
  continue;
29385
29303
  const content = await fs.readFile(filePath, "utf-8");
@@ -29416,16 +29334,24 @@ async function getVaultDiagnosis(vaultPath) {
29416
29334
  if (!hasIssue)
29417
29335
  healthyNotes++;
29418
29336
  }
29419
- const agentPath = path12.join(vaultPath, "AGENT.md");
29420
- if (await fs.pathExists(agentPath)) {
29421
- const agentContent = await fs.readFile(agentPath, "utf-8");
29337
+ let agentContent = null;
29338
+ let agentResolvedPath = path11.join(vaultPath, "AGENTS.md");
29339
+ if (await fs.pathExists(agentResolvedPath)) {
29340
+ agentContent = await fs.readFile(agentResolvedPath, "utf-8");
29341
+ } else {
29342
+ agentResolvedPath = path11.join(vaultPath, "AGENT.md");
29343
+ if (await fs.pathExists(agentResolvedPath)) {
29344
+ agentContent = await fs.readFile(agentResolvedPath, "utf-8");
29345
+ }
29346
+ }
29347
+ if (agentContent !== null) {
29422
29348
  const agentLinks = extractWikilinks2(agentContent);
29423
29349
  for (const linkTarget of agentLinks) {
29424
29350
  if (!noteNames.has(linkTarget)) {
29425
29351
  issues.push({
29426
29352
  severity: "warning",
29427
29353
  category: "agent-drift",
29428
- message: `AGENT.md links to [[${linkTarget}]] but no matching note found`
29354
+ message: `AGENTS.md links to [[${linkTarget}]] but no matching note found`
29429
29355
  });
29430
29356
  }
29431
29357
  }
@@ -29435,19 +29361,19 @@ async function getVaultDiagnosis(vaultPath) {
29435
29361
  for (const filePath of allFiles) {
29436
29362
  const content = await fs.readFile(filePath, "utf-8");
29437
29363
  const links = extractWikilinks2(content);
29438
- const name = path12.basename(filePath, ".md");
29364
+ const name = path11.basename(filePath, ".md");
29439
29365
  allLinksMap.set(name, new Set(links));
29440
29366
  for (const link of links) {
29441
29367
  incomingLinks.add(link);
29442
29368
  }
29443
29369
  }
29444
29370
  for (const filePath of allFiles) {
29445
- const relativePath = path12.relative(vaultPath, filePath);
29371
+ const relativePath = path11.relative(vaultPath, filePath);
29446
29372
  if (relativePath.startsWith("Knowledge/templates/"))
29447
29373
  continue;
29448
- if (relativePath === "AGENT.md")
29374
+ if (relativePath === "AGENT.md" || relativePath === "AGENTS.md")
29449
29375
  continue;
29450
- const name = path12.basename(filePath, ".md");
29376
+ const name = path11.basename(filePath, ".md");
29451
29377
  const outgoing = allLinksMap.get(name) || /* @__PURE__ */ new Set();
29452
29378
  const hasIncoming = incomingLinks.has(name);
29453
29379
  const hasOutgoing = outgoing.size > 0;
@@ -29461,7 +29387,7 @@ async function getVaultDiagnosis(vaultPath) {
29461
29387
  }
29462
29388
  }
29463
29389
  for (const filePath of allFiles) {
29464
- const relativePath = path12.relative(vaultPath, filePath);
29390
+ const relativePath = path11.relative(vaultPath, filePath);
29465
29391
  const content = await fs.readFile(filePath, "utf-8");
29466
29392
  const links = extractWikilinks2(content);
29467
29393
  for (const link of links) {
@@ -29487,7 +29413,7 @@ async function getVaultDiagnosis(vaultPath) {
29487
29413
 
29488
29414
  // dist/tools/vault-doctor.js
29489
29415
  var byoao_vault_doctor = tool({
29490
- description: "Scan an Obsidian vault and produce a diagnostic report. Checks: missing frontmatter, missing type/tags, AGENT.md drift, orphan notes, broken wikilinks.",
29416
+ description: "Scan an Obsidian vault and produce a diagnostic report. Checks: missing frontmatter, missing type/tags, AGENTS.md drift, orphan notes, broken wikilinks.",
29491
29417
  args: {
29492
29418
  vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault")
29493
29419
  },
@@ -29553,18 +29479,34 @@ var byoao_switch_provider = tool({
29553
29479
  }
29554
29480
  });
29555
29481
 
29556
- // dist/vault/search-vault.js
29557
- import path13 from "node:path";
29482
+ // dist/vault/graph-health.js
29483
+ import path12 from "node:path";
29558
29484
 
29559
29485
  // dist/vault/obsidian-cli.js
29560
- import { execFileSync } from "node:child_process";
29486
+ import { execFileSync, execSync as execSync3 } from "node:child_process";
29487
+ import { platform as platform2 } from "node:os";
29488
+ var _cliAvailableCache = null;
29561
29489
  function isObsidianCliAvailable() {
29490
+ if (_cliAvailableCache !== null)
29491
+ return _cliAvailableCache;
29492
+ const os5 = platform2();
29562
29493
  try {
29563
- execFileSync("obsidian", ["--version"], { stdio: "pipe" });
29564
- return true;
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
+ }
29565
29506
  } catch {
29566
- return false;
29507
+ _cliAvailableCache = false;
29567
29508
  }
29509
+ return _cliAvailableCache;
29568
29510
  }
29569
29511
  function execObsidianCmd(args) {
29570
29512
  try {
@@ -29582,184 +29524,15 @@ function execObsidianCmd(args) {
29582
29524
 
29583
29525
  // dist/vault/retrieval-types.js
29584
29526
  var DEFAULT_RESULT_LIMIT = 20;
29585
- var MAX_SNIPPET_LENGTH = 240;
29586
-
29587
- // dist/vault/search-vault.js
29588
- async function searchVault(input) {
29589
- const { vaultPath, query, limit = DEFAULT_RESULT_LIMIT } = input;
29590
- const mode = "search:context";
29591
- const base = {
29592
- mode,
29593
- vault: vaultPath,
29594
- fallback: "none"
29595
- };
29596
- if (!isObsidianCliAvailable()) {
29597
- return {
29598
- ...base,
29599
- status: "runtime_unavailable",
29600
- summary: "Obsidian CLI not available",
29601
- results: [],
29602
- truncated: false,
29603
- diagnostics: ["Obsidian CLI not available"]
29604
- };
29605
- }
29606
- const cliResult = execObsidianCmd([
29607
- "search:context",
29608
- "--vault",
29609
- vaultPath,
29610
- query
29611
- ]);
29612
- if (!cliResult.success) {
29613
- return {
29614
- ...base,
29615
- status: "runtime_unavailable",
29616
- summary: "Obsidian CLI command failed",
29617
- results: [],
29618
- truncated: false,
29619
- diagnostics: [cliResult.error ?? "Unknown CLI error"]
29620
- };
29621
- }
29622
- const lines = cliResult.output.split("\n").filter((l) => l.trim().length > 0);
29623
- if (lines.length === 0) {
29624
- return {
29625
- ...base,
29626
- status: "no_results",
29627
- summary: `No matches for "${query}"`,
29628
- results: [],
29629
- truncated: false,
29630
- diagnostics: []
29631
- };
29632
- }
29633
- const allItems = [];
29634
- for (const line of lines) {
29635
- const colonIdx = line.indexOf(":");
29636
- if (colonIdx === -1)
29637
- continue;
29638
- const filePath = line.substring(0, colonIdx);
29639
- const snippet = line.substring(colonIdx + 1).trim();
29640
- const title = path13.basename(filePath, ".md");
29641
- allItems.push({
29642
- title,
29643
- path: filePath,
29644
- file: title,
29645
- snippet: snippet.length > MAX_SNIPPET_LENGTH ? snippet.substring(0, MAX_SNIPPET_LENGTH) : snippet
29646
- });
29647
- }
29648
- const truncated = allItems.length > limit;
29649
- const results = allItems.slice(0, limit);
29650
- return {
29651
- ...base,
29652
- status: "ok",
29653
- summary: `${allItems.length} matching notes for "${query}"`,
29654
- results,
29655
- truncated,
29656
- totalMatches: allItems.length,
29657
- diagnostics: []
29658
- };
29659
- }
29660
-
29661
- // dist/tools/search-vault.js
29662
- var byoao_search_vault = tool({
29663
- description: "Search an Obsidian vault for notes matching a text query. Uses Obsidian CLI search:context for vault-aware results. Preferred over grep/rg for Obsidian vault knowledge queries about notes, tags, and content.",
29664
- args: {
29665
- vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
29666
- query: tool.schema.string().describe("Text query to search for in vault notes"),
29667
- limit: tool.schema.number().optional().describe("Maximum number of results to return (default: 20)")
29668
- },
29669
- async execute(args) {
29670
- const result = await searchVault({
29671
- vaultPath: args.vaultPath,
29672
- query: args.query,
29673
- limit: args.limit
29674
- });
29675
- return JSON.stringify(result, null, 2);
29676
- }
29677
- });
29678
-
29679
- // dist/vault/note-read.js
29680
- async function readNote(input) {
29681
- const { vaultPath, file: file2 } = input;
29682
- const mode = "read";
29683
- const base = {
29684
- mode,
29685
- vault: vaultPath,
29686
- fallback: "none"
29687
- };
29688
- if (!isObsidianCliAvailable()) {
29689
- return {
29690
- ...base,
29691
- status: "runtime_unavailable",
29692
- summary: "Obsidian CLI not available",
29693
- results: [],
29694
- truncated: false,
29695
- diagnostics: ["Obsidian CLI not available"]
29696
- };
29697
- }
29698
- const cliResult = execObsidianCmd(["read", "--vault", vaultPath, file2]);
29699
- if (!cliResult.success) {
29700
- return {
29701
- ...base,
29702
- status: "runtime_unavailable",
29703
- summary: `Failed to read note "${file2}"`,
29704
- results: [],
29705
- truncated: false,
29706
- diagnostics: [cliResult.error ?? "Unknown CLI error"]
29707
- };
29708
- }
29709
- const content = cliResult.output.trim();
29710
- if (content.length === 0) {
29711
- return {
29712
- ...base,
29713
- status: "no_results",
29714
- summary: `Note "${file2}" is empty or not found`,
29715
- results: [],
29716
- truncated: false,
29717
- diagnostics: []
29718
- };
29719
- }
29720
- const snippet = content.length > MAX_SNIPPET_LENGTH ? content.substring(0, MAX_SNIPPET_LENGTH) : content;
29721
- return {
29722
- ...base,
29723
- status: "ok",
29724
- summary: `Read note "${file2}" (${content.length} chars)`,
29725
- results: [
29726
- {
29727
- title: file2,
29728
- path: "",
29729
- file: file2,
29730
- snippet
29731
- }
29732
- ],
29733
- truncated: false,
29734
- diagnostics: []
29735
- };
29736
- }
29737
-
29738
- // dist/tools/note-read.js
29739
- var byoao_note_read = tool({
29740
- description: "Read a specific note from an Obsidian vault by name. Uses Obsidian CLI to resolve and read the note. Preferred over cat/Read for Obsidian vault notes.",
29741
- args: {
29742
- vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
29743
- file: tool.schema.string().describe("Note name to read (without .md extension, e.g. 'Refund Automation')")
29744
- },
29745
- async execute(args) {
29746
- const result = await readNote({
29747
- vaultPath: args.vaultPath,
29748
- file: args.file
29749
- });
29750
- return JSON.stringify(result, null, 2);
29751
- }
29752
- });
29753
29527
 
29754
29528
  // dist/vault/graph-health.js
29755
- import path14 from "node:path";
29756
29529
  var ALL_CHECKS = ["orphans", "unresolved", "deadends"];
29757
29530
  function parseCheckOutput(check2, output) {
29758
29531
  const lines = output.split("\n").filter((l) => l.trim().length > 0);
29759
29532
  return lines.map((line) => {
29760
29533
  const trimmed = line.trim();
29761
29534
  const isPath = trimmed.includes("/") || trimmed.endsWith(".md");
29762
- const title = isPath ? path14.basename(trimmed, ".md") : trimmed;
29535
+ const title = isPath ? path12.basename(trimmed, ".md") : trimmed;
29763
29536
  return {
29764
29537
  title,
29765
29538
  path: isPath ? trimmed : "",
@@ -29841,7 +29614,7 @@ var byoao_graph_health = tool({
29841
29614
  });
29842
29615
 
29843
29616
  // dist/vault/upgrade.js
29844
- import path15 from "node:path";
29617
+ import path13 from "node:path";
29845
29618
  var OBSIDIAN_CONFIG_FILES = [
29846
29619
  "core-plugins.json",
29847
29620
  "daily-notes.json",
@@ -29853,7 +29626,7 @@ async function scanInstalledAssets(vaultPath) {
29853
29626
  const templates = await scanDir(vaultPath, "Knowledge/templates", ".md");
29854
29627
  const obsidianConfig = [];
29855
29628
  for (const file2 of OBSIDIAN_CONFIG_FILES) {
29856
- const abs = path15.join(vaultPath, ".obsidian", file2);
29629
+ const abs = path13.join(vaultPath, ".obsidian", file2);
29857
29630
  if (await fs.pathExists(abs)) {
29858
29631
  obsidianConfig.push(`.obsidian/${file2}`);
29859
29632
  }
@@ -29861,21 +29634,21 @@ async function scanInstalledAssets(vaultPath) {
29861
29634
  return { skills, commands, obsidianConfig, templates };
29862
29635
  }
29863
29636
  async function scanDir(vaultPath, relDir, ext) {
29864
- const absDir = path15.join(vaultPath, relDir);
29637
+ const absDir = path13.join(vaultPath, relDir);
29865
29638
  if (!await fs.pathExists(absDir))
29866
29639
  return [];
29867
29640
  const files = await fs.readdir(absDir);
29868
29641
  return files.filter((f) => f.endsWith(ext)).map((f) => `${relDir}/${f}`);
29869
29642
  }
29870
29643
  async function scanSkillDirs(vaultPath) {
29871
- const skillsRoot = path15.join(vaultPath, ".opencode", "skills");
29644
+ const skillsRoot = path13.join(vaultPath, ".opencode", "skills");
29872
29645
  if (!await fs.pathExists(skillsRoot))
29873
29646
  return [];
29874
29647
  const results = [];
29875
29648
  const entries = await fs.readdir(skillsRoot, { withFileTypes: true });
29876
29649
  for (const entry of entries) {
29877
29650
  if (entry.isDirectory()) {
29878
- const skillMd = path15.join(skillsRoot, entry.name, "SKILL.md");
29651
+ const skillMd = path13.join(skillsRoot, entry.name, "SKILL.md");
29879
29652
  if (await fs.pathExists(skillMd)) {
29880
29653
  results.push(`.opencode/skills/${entry.name}/SKILL.md`);
29881
29654
  }
@@ -29904,7 +29677,7 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
29904
29677
  const installed = new Set(manifest.infrastructure[key]);
29905
29678
  const shippedPaths = new Set(shipped.map((s) => s.relativePath));
29906
29679
  for (const entry of shipped) {
29907
- const onDisk = fs.existsSync(path15.join(vaultPath, entry.relativePath));
29680
+ const onDisk = fs.existsSync(path13.join(vaultPath, entry.relativePath));
29908
29681
  items.push({
29909
29682
  file: entry.relativePath,
29910
29683
  action: onDisk ? "update" : "add",
@@ -29928,8 +29701,8 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
29928
29701
  };
29929
29702
  }
29930
29703
  function resolveAssetsDir2() {
29931
- const srcAssets = path15.resolve(import.meta.dirname, "..", "assets");
29932
- const distAssets = path15.resolve(import.meta.dirname, "..", "..", "src", "assets");
29704
+ const srcAssets = path13.resolve(import.meta.dirname, "..", "assets");
29705
+ const distAssets = path13.resolve(import.meta.dirname, "..", "..", "src", "assets");
29933
29706
  if (fs.existsSync(srcAssets))
29934
29707
  return srcAssets;
29935
29708
  if (fs.existsSync(distAssets))
@@ -29937,8 +29710,8 @@ function resolveAssetsDir2() {
29937
29710
  return srcAssets;
29938
29711
  }
29939
29712
  function resolveSkillsDir() {
29940
- const srcSkills = path15.resolve(import.meta.dirname, "..", "skills");
29941
- const distSkills = path15.resolve(import.meta.dirname, "..", "..", "src", "skills");
29713
+ const srcSkills = path13.resolve(import.meta.dirname, "..", "skills");
29714
+ const distSkills = path13.resolve(import.meta.dirname, "..", "..", "src", "skills");
29942
29715
  if (fs.existsSync(srcSkills))
29943
29716
  return srcSkills;
29944
29717
  if (fs.existsSync(distSkills))
@@ -29953,14 +29726,14 @@ function resolvePackageAssets(preset) {
29953
29726
  const commands = [];
29954
29727
  const obsidianConfig = [];
29955
29728
  const templates = [];
29956
- const obsidianSkillsDir = path15.join(assetsDir, "obsidian-skills");
29729
+ const obsidianSkillsDir = path13.join(assetsDir, "obsidian-skills");
29957
29730
  if (fs.existsSync(obsidianSkillsDir)) {
29958
29731
  for (const file2 of fs.readdirSync(obsidianSkillsDir)) {
29959
29732
  if (file2.endsWith(".md")) {
29960
29733
  const skillName = file2.replace(/\.md$/, "");
29961
29734
  skills.push({
29962
29735
  relativePath: `.opencode/skills/${skillName}/SKILL.md`,
29963
- sourcePath: path15.join(obsidianSkillsDir, file2)
29736
+ sourcePath: path13.join(obsidianSkillsDir, file2)
29964
29737
  });
29965
29738
  }
29966
29739
  }
@@ -29970,15 +29743,15 @@ function resolvePackageAssets(preset) {
29970
29743
  if (file2.endsWith(".md")) {
29971
29744
  commands.push({
29972
29745
  relativePath: `.opencode/commands/${file2}`,
29973
- sourcePath: path15.join(skillsDir, file2)
29746
+ sourcePath: path13.join(skillsDir, file2)
29974
29747
  });
29975
29748
  }
29976
29749
  }
29977
29750
  }
29978
- const obsidianSrcDir = path15.join(commonDir, "obsidian");
29751
+ const obsidianSrcDir = path13.join(commonDir, "obsidian");
29979
29752
  if (fs.existsSync(obsidianSrcDir)) {
29980
29753
  for (const file2 of OBSIDIAN_CONFIG_FILES) {
29981
- const srcPath = path15.join(obsidianSrcDir, file2);
29754
+ const srcPath = path13.join(obsidianSrcDir, file2);
29982
29755
  if (fs.existsSync(srcPath)) {
29983
29756
  obsidianConfig.push({
29984
29757
  relativePath: `.obsidian/${file2}`,
@@ -29987,26 +29760,26 @@ function resolvePackageAssets(preset) {
29987
29760
  }
29988
29761
  }
29989
29762
  }
29990
- const commonTemplatesDir = path15.join(commonDir, "templates");
29763
+ const commonTemplatesDir = path13.join(commonDir, "templates");
29991
29764
  if (fs.existsSync(commonTemplatesDir)) {
29992
29765
  for (const file2 of fs.readdirSync(commonTemplatesDir)) {
29993
29766
  if (file2.endsWith(".md")) {
29994
29767
  templates.push({
29995
29768
  relativePath: `Knowledge/templates/${file2}`,
29996
- sourcePath: path15.join(commonTemplatesDir, file2)
29769
+ sourcePath: path13.join(commonTemplatesDir, file2)
29997
29770
  });
29998
29771
  }
29999
29772
  }
30000
29773
  }
30001
29774
  try {
30002
29775
  const { presetsDir } = loadPreset(preset);
30003
- const presetTemplatesDir = path15.join(presetsDir, preset, "templates");
29776
+ const presetTemplatesDir = path13.join(presetsDir, preset, "templates");
30004
29777
  if (fs.existsSync(presetTemplatesDir)) {
30005
29778
  for (const file2 of fs.readdirSync(presetTemplatesDir)) {
30006
29779
  if (file2.endsWith(".md")) {
30007
29780
  templates.push({
30008
29781
  relativePath: `Knowledge/templates/${file2}`,
30009
- sourcePath: path15.join(presetTemplatesDir, file2)
29782
+ sourcePath: path13.join(presetTemplatesDir, file2)
30010
29783
  });
30011
29784
  }
30012
29785
  }
@@ -30019,7 +29792,7 @@ async function upgradeVault(vaultPath, options2) {
30019
29792
  const { preset, dryRun = false, force = false } = options2 ?? {};
30020
29793
  const detectedPath = detectVaultContext(vaultPath);
30021
29794
  if (!detectedPath) {
30022
- throw new Error(`No BYOAO vault detected at "${vaultPath}". Expected .obsidian/ and AGENT.md or Knowledge/Glossary.md.`);
29795
+ throw new Error(`No BYOAO vault detected at "${vaultPath}". Expected .obsidian/ and AGENTS.md.`);
30023
29796
  }
30024
29797
  let manifest = await readManifest(vaultPath);
30025
29798
  if (!manifest) {
@@ -30038,6 +29811,11 @@ async function upgradeVault(vaultPath, options2) {
30038
29811
  dryRun
30039
29812
  };
30040
29813
  }
29814
+ const legacyAgentMd = path13.join(vaultPath, "AGENT.md");
29815
+ const newAgentsMd = path13.join(vaultPath, "AGENTS.md");
29816
+ if (!dryRun && await fs.pathExists(legacyAgentMd) && !await fs.pathExists(newAgentsMd)) {
29817
+ await fs.rename(legacyAgentMd, newAgentsMd);
29818
+ }
30041
29819
  const effectivePreset = preset ?? manifest.preset;
30042
29820
  const packageAssets = resolvePackageAssets(effectivePreset);
30043
29821
  const plan = buildUpgradePlan(vaultPath, manifest, packageAssets);
@@ -30057,8 +29835,8 @@ async function upgradeVault(vaultPath, options2) {
30057
29835
  if (item.action === "add" || item.action === "update") {
30058
29836
  const source = sourceMap.get(item.file);
30059
29837
  if (source) {
30060
- const dest = path15.join(vaultPath, item.file);
30061
- await fs.ensureDir(path15.dirname(dest));
29838
+ const dest = path13.join(vaultPath, item.file);
29839
+ await fs.ensureDir(path13.dirname(dest));
30062
29840
  await fs.copy(source, dest, { overwrite: true });
30063
29841
  if (item.action === "add") {
30064
29842
  added.push(item.file);
@@ -30153,17 +29931,17 @@ var byoao_vault_upgrade = tool({
30153
29931
  });
30154
29932
 
30155
29933
  // dist/tools/mcp-auth.js
30156
- import { spawn, execSync as execSync3 } from "node:child_process";
30157
- import path16 from "node:path";
29934
+ import { spawn, execSync as execSync4 } from "node:child_process";
29935
+ import path14 from "node:path";
30158
29936
  import os4 from "node:os";
30159
29937
  function findOpencodeBinary() {
30160
29938
  const candidates = [
30161
- path16.join(os4.homedir(), ".opencode/bin/opencode"),
29939
+ path14.join(os4.homedir(), ".opencode/bin/opencode"),
30162
29940
  "/usr/local/bin/opencode"
30163
29941
  ];
30164
29942
  for (const p of candidates) {
30165
29943
  try {
30166
- execSync3(`test -x "${p}"`, { stdio: "pipe" });
29944
+ execSync4(`test -x "${p}"`, { stdio: "pipe" });
30167
29945
  return p;
30168
29946
  } catch {
30169
29947
  }
@@ -30261,13 +30039,10 @@ The user may need to:
30261
30039
  }
30262
30040
  });
30263
30041
 
30264
- // dist/hooks/system-transform.js
30265
- import path17 from "node:path";
30266
-
30267
30042
  // dist/lib/logger.js
30268
30043
  import { join } from "node:path";
30269
30044
  import { homedir } from "node:os";
30270
- import { appendFile, stat, rename, mkdir as mkdir2, readFile as readFile2, unlink } from "node:fs/promises";
30045
+ import { appendFile, stat, rename as rename3, mkdir as mkdir2, readFile as readFile2, unlink } from "node:fs/promises";
30271
30046
  var LOG_DIR = process.env.BYOAO_LOG_DIR || join(homedir(), ".byoao", "logs");
30272
30047
  var LOG_FILE = join(LOG_DIR, "error.log");
30273
30048
  var MAX_LOG_SIZE = 512 * 1024;
@@ -30312,7 +30087,7 @@ async function rotateIfNeeded() {
30312
30087
  try {
30313
30088
  const s = await stat(LOG_FILE);
30314
30089
  if (s.size >= MAX_LOG_SIZE) {
30315
- await rename(LOG_FILE, ROTATED_FILE);
30090
+ await rename3(LOG_FILE, ROTATED_FILE);
30316
30091
  }
30317
30092
  } catch {
30318
30093
  }
@@ -30341,86 +30116,6 @@ async function log(level, source, message, options2) {
30341
30116
  }
30342
30117
 
30343
30118
  // dist/hooks/system-transform.js
30344
- function readAgentMdFromCwd() {
30345
- const candidates = [
30346
- path17.join(process.cwd(), "AGENT.md"),
30347
- path17.join(process.cwd(), "..", "AGENT.md")
30348
- ];
30349
- for (const candidate of candidates) {
30350
- if (fs.existsSync(candidate)) {
30351
- try {
30352
- return fs.readFileSync(candidate, "utf-8");
30353
- } catch {
30354
- void log("warn", "hook:system-transform", "Failed to read AGENT.md", {
30355
- context: { path: candidate }
30356
- }).catch(() => {
30357
- });
30358
- return null;
30359
- }
30360
- }
30361
- }
30362
- return null;
30363
- }
30364
- function buildNavigationStrategy(vaultPath) {
30365
- const cliAvailable = isObsidianCliAvailable();
30366
- const header = [
30367
- "\n---",
30368
- "## BYOAO Navigation Strategy",
30369
- "",
30370
- "### Scope",
30371
- "",
30372
- `This session is connected to a BYOAO knowledge base at: \`${vaultPath}\``,
30373
- ""
30374
- ];
30375
- const scopeLines = cliAvailable ? [
30376
- `- **Inside the vault** (\`${vaultPath}/\` and its subdirectories): **ALWAYS use Obsidian CLI first** (see /obsidian-cli skill) or BYOAO tools (\`byoao_search_vault\`, \`byoao_note_read\`, \`byoao_graph_health\`). Obsidian CLI is graph-aware and understands wikilinks, backlinks, and frontmatter \u2014 grep/cat/find do not. Only fall back to find/grep when Obsidian CLI returns no results for a given query.`,
30377
- `- **Outside the vault** (code repositories, config files, system paths, etc.): use any appropriate tool (grep, cat, read, bash, etc.) freely.`
30378
- ] : [
30379
- `- **Obsidian CLI is NOT available** (either not installed or Obsidian is not running). Use built-in tools (find, grep, read) to access vault notes at \`${vaultPath}/\`.`,
30380
- `- BYOAO tools (\`byoao_search_vault\`, \`byoao_note_read\`, \`byoao_graph_health\`) are still available and preferred over raw find/grep when possible.`,
30381
- `- **Outside the vault** (code repositories, config files, system paths, etc.): use any appropriate tool freely.`
30382
- ];
30383
- const navigationSteps = cliAvailable ? [
30384
- "### Navigation Pattern (Progressive Disclosure)",
30385
- "",
30386
- "1. Read [[Glossary]] first \u2014 the entity dictionary for this knowledge base.",
30387
- " Every term is a key concept the user cares about.",
30388
- "2. Use `obsidian properties sort=count counts` to understand vault structure",
30389
- "3. Search by `domain` property or tags to find relevant notes",
30390
- "4. Read the `references` frontmatter of found notes for deeper context",
30391
- "5. Use `obsidian backlinks` to discover related notes the user didn't mention",
30392
- "6. Chain: Glossary \u2192 domain notes \u2192 references \u2192 backlinks \u2192 details",
30393
- "",
30394
- "If an Obsidian CLI search returns no results, retry with find/grep as a fallback."
30395
- ] : [
30396
- "### Navigation Pattern (Progressive Disclosure)",
30397
- "",
30398
- "1. Read [[Glossary]] first \u2014 the entity dictionary for this knowledge base.",
30399
- " Every term is a key concept the user cares about.",
30400
- "2. Use `byoao_search_vault` or grep frontmatter fields to understand vault structure",
30401
- "3. Search by `domain` property or tags to find relevant notes",
30402
- "4. Read the `references` frontmatter of found notes for deeper context",
30403
- "5. Use grep for `[[note name]]` patterns to discover backlinks manually",
30404
- "6. Chain: Glossary \u2192 domain notes \u2192 references \u2192 backlinks \u2192 details"
30405
- ];
30406
- const footer = [
30407
- "",
30408
- "### Key Frontmatter Fields",
30409
- "",
30410
- "| Field | Purpose |",
30411
- "|-------------|--------------------------------------------------|",
30412
- "| `domain` | Knowledge area \u2014 use to find related notes |",
30413
- "| `references`| Related notes \u2014 follow for deeper context |",
30414
- "| `type` | Note kind (meeting, idea, reference, daily, etc) |",
30415
- "| `tags` | Flexible categorization |",
30416
- "",
30417
- "### Vault Health",
30418
- "",
30419
- "If you notice broken wikilinks, orphan notes, or missing frontmatter while working,",
30420
- "suggest that the user run `/diagnose` to get a full vault health report."
30421
- ];
30422
- return [...header, ...scopeLines, "", ...navigationSteps, ...footer].join("\n");
30423
- }
30424
30119
  async function buildMcpAuthGuidance() {
30425
30120
  try {
30426
30121
  const config2 = await readOpencodeConfig();
@@ -30458,18 +30153,6 @@ async function buildMcpAuthGuidance() {
30458
30153
  }
30459
30154
  }
30460
30155
  async function systemTransformHook(_input, output) {
30461
- const agentMd = readAgentMdFromCwd();
30462
- if (agentMd) {
30463
- output.system.push(`
30464
- ---
30465
- ## BYOAO Vault Context (from AGENT.md)
30466
-
30467
- ${agentMd}`);
30468
- }
30469
- const vaultPath = detectVaultContext(process.cwd());
30470
- if (vaultPath) {
30471
- output.system.push(buildNavigationStrategy(vaultPath));
30472
- }
30473
30156
  const mcpGuidance = await buildMcpAuthGuidance();
30474
30157
  if (mcpGuidance) {
30475
30158
  output.system.push(mcpGuidance);
@@ -30500,12 +30183,9 @@ var BYOAOPlugin = async (ctx) => {
30500
30183
  byoao_init_vault,
30501
30184
  byoao_add_person,
30502
30185
  byoao_add_project,
30503
- byoao_add_glossary_term,
30504
30186
  byoao_vault_status,
30505
30187
  byoao_vault_doctor,
30506
30188
  byoao_switch_provider,
30507
- byoao_search_vault,
30508
- byoao_note_read,
30509
30189
  byoao_graph_health,
30510
30190
  byoao_vault_upgrade,
30511
30191
  byoao_mcp_auth