@jayjiang/byoao 1.1.1 → 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.
- package/dist/__tests__/plugin-config.test.js +7 -10
- package/dist/__tests__/plugin-config.test.js.map +1 -1
- package/dist/assets/obsidian-skills/byoao-conventions.md +30 -54
- package/dist/assets/obsidian-skills/vault-thinking.md +6 -5
- package/dist/assets/presets/common/AGENTS.md.hbs +29 -46
- package/dist/assets/presets/common/SCHEMA.md.hbs +57 -0
- package/dist/assets/presets/common/Start Here.md.hbs +29 -40
- package/dist/assets/presets/minimal/preset.json +3 -3
- package/dist/assets/presets/pm-tpm/preset.json +2 -2
- package/dist/assets/skills/ask.md +133 -0
- package/dist/assets/skills/challenge.md +132 -0
- package/dist/assets/skills/connect.md +125 -0
- package/dist/assets/skills/cook.md +167 -0
- package/dist/assets/skills/diagnose.md +131 -0
- package/dist/assets/skills/drift.md +122 -0
- package/dist/assets/skills/health.md +63 -0
- package/dist/assets/skills/ideas.md +173 -0
- package/dist/assets/skills/organize.md +107 -0
- package/dist/assets/skills/prep.md +63 -0
- package/dist/assets/skills/trace.md +141 -0
- package/dist/assets/skills/wiki.md +126 -0
- package/dist/cli/cli-program.js +17 -14
- package/dist/cli/cli-program.js.map +1 -1
- package/dist/cli/installer.js +47 -6
- package/dist/cli/installer.js.map +1 -1
- package/dist/hooks/idle-suggestions.js +4 -4
- package/dist/hooks/idle-suggestions.js.map +1 -1
- package/dist/hooks/system-transform.js +35 -1
- package/dist/hooks/system-transform.js.map +1 -1
- package/dist/index.js +397 -884
- package/dist/index.js.map +1 -1
- package/dist/plugin-config.js +6 -32
- package/dist/plugin-config.js.map +1 -1
- package/dist/tools/init-vault.js +8 -38
- package/dist/tools/init-vault.js.map +1 -1
- package/dist/tools/vault-doctor.js +1 -1
- package/dist/tools/vault-doctor.js.map +1 -1
- package/dist/tools/vault-status.js +1 -1
- package/dist/tools/vault-status.js.map +1 -1
- package/dist/vault/__tests__/create.test.js +48 -116
- package/dist/vault/__tests__/create.test.js.map +1 -1
- package/dist/vault/__tests__/doctor.test.js +14 -2
- package/dist/vault/__tests__/doctor.test.js.map +1 -1
- package/dist/vault/__tests__/manifest.test.js +2 -2
- package/dist/vault/__tests__/manifest.test.js.map +1 -1
- package/dist/vault/__tests__/status.test.js +13 -8
- package/dist/vault/__tests__/status.test.js.map +1 -1
- package/dist/vault/__tests__/upgrade.test.js +3 -3
- package/dist/vault/__tests__/upgrade.test.js.map +1 -1
- package/dist/vault/__tests__/vault-detect.test.js +1 -13
- package/dist/vault/__tests__/vault-detect.test.js.map +1 -1
- package/dist/vault/create.js +76 -229
- package/dist/vault/create.js.map +1 -1
- package/dist/vault/doctor.js +49 -0
- package/dist/vault/doctor.js.map +1 -1
- package/dist/vault/manifest.js +1 -1
- package/dist/vault/preset.js +10 -4
- package/dist/vault/preset.js.map +1 -1
- package/dist/vault/self-update.js +1 -1
- package/dist/vault/status.js +24 -3
- package/dist/vault/status.js.map +1 -1
- package/dist/vault/upgrade.js +121 -18
- package/dist/vault/upgrade.js.map +1 -1
- package/dist/vault/vault-detect.js +2 -4
- package/dist/vault/vault-detect.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/obsidian-skills/byoao-conventions.md +30 -54
- package/src/assets/obsidian-skills/vault-thinking.md +6 -5
- package/src/assets/presets/common/AGENTS.md.hbs +29 -46
- package/src/assets/presets/common/SCHEMA.md.hbs +57 -0
- package/src/assets/presets/common/Start Here.md.hbs +29 -40
- package/src/assets/presets/minimal/preset.json +3 -3
- package/src/assets/presets/pm-tpm/preset.json +2 -2
- package/src/skills/ask.md +133 -0
- package/src/skills/challenge.md +79 -115
- package/src/skills/connect.md +75 -156
- package/src/skills/cook.md +167 -0
- package/src/skills/diagnose.md +99 -41
- package/src/skills/drift.md +64 -159
- package/src/skills/health.md +63 -0
- package/src/skills/ideas.md +19 -12
- package/src/skills/organize.md +56 -156
- package/src/skills/prep.md +63 -0
- package/src/skills/trace.md +76 -84
- package/src/skills/wiki.md +126 -0
- package/dist/assets/presets/common/Glossary.md.hbs +0 -16
- package/dist/assets/presets/common/obsidian/daily-notes.json +0 -5
- package/dist/assets/presets/common/obsidian/templates.json +0 -3
- package/dist/assets/presets/common/templates/Daily Note.md +0 -19
- package/dist/assets/presets/common/templates/Decision Record.md +0 -32
- package/dist/assets/presets/common/templates/Investigation.md +0 -34
- package/dist/assets/presets/common/templates/Meeting Notes.md +0 -25
- package/dist/tools/add-glossary-term.js +0 -21
- package/dist/tools/add-glossary-term.js.map +0 -1
- package/dist/tools/add-person.js +0 -21
- package/dist/tools/add-person.js.map +0 -1
- package/dist/tools/add-project.js +0 -24
- package/dist/tools/add-project.js.map +0 -1
- package/dist/tools/graph-health.js +0 -25
- package/dist/tools/graph-health.js.map +0 -1
- package/dist/tools/note-read.js +0 -19
- package/dist/tools/note-read.js.map +0 -1
- package/dist/tools/search-vault.js +0 -22
- package/dist/tools/search-vault.js.map +0 -1
- package/dist/vault/__tests__/glossary.test.js +0 -68
- package/dist/vault/__tests__/glossary.test.js.map +0 -1
- package/dist/vault/__tests__/graph-health.test.js +0 -102
- package/dist/vault/__tests__/graph-health.test.js.map +0 -1
- package/dist/vault/__tests__/member.test.js +0 -85
- package/dist/vault/__tests__/member.test.js.map +0 -1
- package/dist/vault/__tests__/note-read.test.js +0 -71
- package/dist/vault/__tests__/note-read.test.js.map +0 -1
- package/dist/vault/__tests__/obsidian-cli.test.js +0 -108
- package/dist/vault/__tests__/obsidian-cli.test.js.map +0 -1
- package/dist/vault/__tests__/search-vault.test.js +0 -93
- package/dist/vault/__tests__/search-vault.test.js.map +0 -1
- package/dist/vault/glossary.js +0 -27
- package/dist/vault/glossary.js.map +0 -1
- package/dist/vault/graph-health.js +0 -83
- package/dist/vault/graph-health.js.map +0 -1
- package/dist/vault/member.js +0 -67
- package/dist/vault/member.js.map +0 -1
- package/dist/vault/note-read.js +0 -70
- package/dist/vault/note-read.js.map +0 -1
- package/dist/vault/project.js +0 -68
- package/dist/vault/project.js.map +0 -1
- package/dist/vault/retrieval-types.js +0 -5
- package/dist/vault/retrieval-types.js.map +0 -1
- package/dist/vault/search-vault.js +0 -87
- package/dist/vault/search-vault.js.map +0 -1
- package/src/assets/presets/common/Glossary.md.hbs +0 -16
- package/src/assets/presets/common/obsidian/daily-notes.json +0 -5
- package/src/assets/presets/common/obsidian/templates.json +0 -3
- package/src/assets/presets/common/templates/Daily Note.md +0 -19
- package/src/assets/presets/common/templates/Decision Record.md +0 -32
- package/src/assets/presets/common/templates/Investigation.md +0 -34
- package/src/assets/presets/common/templates/Meeting Notes.md +0 -25
- package/src/skills/emerge.md +0 -161
- package/src/skills/weave.md +0 -282
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(
|
|
4686
|
-
return /^\.|this\b/.test(
|
|
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(
|
|
4691
|
-
return
|
|
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(
|
|
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:
|
|
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),
|
|
6036
|
+
var params = this.setupFullMustacheParams(decorator, program, void 0), path13 = decorator.path;
|
|
6037
6037
|
this.useDecorators = true;
|
|
6038
|
-
this.opcode("registerDecorator", params.length,
|
|
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
|
|
6103
|
-
this.opcode("getContext",
|
|
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
|
-
|
|
6107
|
-
this.accept(
|
|
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
|
|
6112
|
-
|
|
6113
|
-
this.accept(
|
|
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),
|
|
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
|
-
|
|
6124
|
-
|
|
6125
|
-
this.accept(
|
|
6126
|
-
this.opcode("invokeHelper", params.length,
|
|
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(
|
|
6130
|
-
this.addDepth(
|
|
6131
|
-
this.opcode("getContext",
|
|
6132
|
-
var 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,
|
|
6134
|
+
this.opcode("lookupBlockParam", blockParamId, path13.parts);
|
|
6135
6135
|
} else if (!name) {
|
|
6136
6136
|
this.opcode("pushContext");
|
|
6137
|
-
} else if (
|
|
6137
|
+
} else if (path13.data) {
|
|
6138
6138
|
this.options.data = true;
|
|
6139
|
-
this.opcode("lookupData",
|
|
6139
|
+
this.opcode("lookupData", path13.depth, path13.parts, path13.strict);
|
|
6140
6140
|
} else {
|
|
6141
|
-
this.opcode("lookupOnContext",
|
|
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
|
|
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
|
-
|
|
6497
|
+
path13 = url2.path;
|
|
6498
6498
|
}
|
|
6499
|
-
var isAbsolute = exports2.isAbsolute(
|
|
6500
|
-
var parts =
|
|
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
|
-
|
|
6518
|
-
if (
|
|
6519
|
-
|
|
6517
|
+
path13 = parts.join("/");
|
|
6518
|
+
if (path13 === "") {
|
|
6519
|
+
path13 = isAbsolute ? "/" : ".";
|
|
6520
6520
|
}
|
|
6521
6521
|
if (url2) {
|
|
6522
|
-
url2.path =
|
|
6522
|
+
url2.path = path13;
|
|
6523
6523
|
return urlGenerate(url2);
|
|
6524
6524
|
}
|
|
6525
|
-
return
|
|
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
|
|
9307
|
-
return (id.data ? "@" : "") + "PATH:" +
|
|
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,
|
|
12019
|
-
if (!
|
|
12018
|
+
function getElementAtPath(obj, path13) {
|
|
12019
|
+
if (!path13)
|
|
12020
12020
|
return obj;
|
|
12021
|
-
return
|
|
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(
|
|
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(
|
|
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,
|
|
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 = [...
|
|
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
|
|
12597
|
-
for (const seg of
|
|
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:
|
|
24280
|
-
const fullPath = [...
|
|
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,
|
|
24393
|
+
constructor(parent, value, path13, key) {
|
|
24397
24394
|
this._cachedPath = [];
|
|
24398
24395
|
this.parent = parent;
|
|
24399
24396
|
this.data = value;
|
|
24400
|
-
this._path =
|
|
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
|
|
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
|
-
|
|
27873
|
-
|
|
27874
|
-
|
|
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
|
|
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(
|
|
27929
|
-
return
|
|
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
|
-
${
|
|
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 = "
|
|
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
|
|
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 ??
|
|
28330
|
-
updatedAt:
|
|
28304
|
+
createdAt: existing?.createdAt ?? today(),
|
|
28305
|
+
updatedAt: today(),
|
|
28331
28306
|
infrastructure: {
|
|
28332
28307
|
skills: installedFiles.skills,
|
|
28333
28308
|
commands: installedFiles.commands,
|
|
@@ -28354,8 +28329,7 @@ function detectVaultContext(dir) {
|
|
|
28354
28329
|
continue;
|
|
28355
28330
|
const hasAgentsMd = fs.existsSync(path5.join(candidate, "AGENTS.md"));
|
|
28356
28331
|
const hasAgentMdFallback = fs.existsSync(path5.join(candidate, "AGENT.md"));
|
|
28357
|
-
|
|
28358
|
-
if (hasAgentsMd || hasAgentMdFallback || hasGlossary) {
|
|
28332
|
+
if (hasAgentsMd || hasAgentMdFallback) {
|
|
28359
28333
|
return candidate;
|
|
28360
28334
|
}
|
|
28361
28335
|
}
|
|
@@ -28389,11 +28363,6 @@ function countWikilinks(content) {
|
|
|
28389
28363
|
const matches = stripped.match(/\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g);
|
|
28390
28364
|
return matches ? matches.length : 0;
|
|
28391
28365
|
}
|
|
28392
|
-
var MINIMAL_DIRECTORIES = [
|
|
28393
|
-
"Daily",
|
|
28394
|
-
"Knowledge",
|
|
28395
|
-
"Knowledge/templates"
|
|
28396
|
-
];
|
|
28397
28366
|
function makeContext(vaultPath, kbName, preserveObsidian = false) {
|
|
28398
28367
|
return {
|
|
28399
28368
|
vaultPath,
|
|
@@ -28415,11 +28384,7 @@ var MCP_DISPLAY_NAMES = {
|
|
|
28415
28384
|
atlassian: { name: "Atlassian", description: "Jira issues, Confluence pages" },
|
|
28416
28385
|
bigquery: { name: "BigQuery", description: "Data warehouse queries and analysis" }
|
|
28417
28386
|
};
|
|
28418
|
-
async function createMinimalCore(ctx
|
|
28419
|
-
for (const dir of MINIMAL_DIRECTORIES) {
|
|
28420
|
-
await fs.ensureDir(path6.join(ctx.vaultPath, dir));
|
|
28421
|
-
}
|
|
28422
|
-
ctx.directories.push(...MINIMAL_DIRECTORIES);
|
|
28387
|
+
async function createMinimalCore(ctx) {
|
|
28423
28388
|
if (!ctx.preserveObsidian) {
|
|
28424
28389
|
await fs.ensureDir(path6.join(ctx.vaultPath, ".obsidian"));
|
|
28425
28390
|
const obsidianSrc = path6.join(ctx.commonDir, "obsidian");
|
|
@@ -28432,31 +28397,6 @@ async function createMinimalCore(ctx, glossaryEntries = []) {
|
|
|
28432
28397
|
}
|
|
28433
28398
|
}
|
|
28434
28399
|
}
|
|
28435
|
-
const templateDest = path6.join(ctx.vaultPath, "Knowledge/templates");
|
|
28436
|
-
const commonTemplatesDir = path6.join(ctx.commonDir, "templates");
|
|
28437
|
-
if (await fs.pathExists(commonTemplatesDir)) {
|
|
28438
|
-
const files = await fs.readdir(commonTemplatesDir);
|
|
28439
|
-
for (const file2 of files) {
|
|
28440
|
-
await fs.copy(path6.join(commonTemplatesDir, file2), path6.join(templateDest, file2), { overwrite: false });
|
|
28441
|
-
ctx.filesCreated++;
|
|
28442
|
-
ctx.installedFiles.templates.push(`Knowledge/templates/${file2}`);
|
|
28443
|
-
}
|
|
28444
|
-
}
|
|
28445
|
-
const glossaryTemplate = await fs.readFile(path6.join(ctx.commonDir, "Glossary.md.hbs"), "utf-8");
|
|
28446
|
-
let glossaryRows = "";
|
|
28447
|
-
if (glossaryEntries.length > 0) {
|
|
28448
|
-
glossaryRows = glossaryEntries.map((e) => `| **${e.term}** | ${e.definition} | ${e.domain} |`).join("\n");
|
|
28449
|
-
}
|
|
28450
|
-
const glossaryContent = renderTemplate(glossaryTemplate, {
|
|
28451
|
-
KB_NAME: ctx.kbName,
|
|
28452
|
-
date: today(),
|
|
28453
|
-
GLOSSARY_ENTRIES: glossaryRows
|
|
28454
|
-
});
|
|
28455
|
-
const glossaryPath = path6.join(ctx.vaultPath, "Knowledge/Glossary.md");
|
|
28456
|
-
if (!await fs.pathExists(glossaryPath)) {
|
|
28457
|
-
await fs.writeFile(glossaryPath, glossaryContent);
|
|
28458
|
-
ctx.filesCreated++;
|
|
28459
|
-
}
|
|
28460
28400
|
const startHereTemplate = await fs.readFile(path6.join(ctx.commonDir, "Start Here.md.hbs"), "utf-8");
|
|
28461
28401
|
const startHereContent = renderTemplate(startHereTemplate, {
|
|
28462
28402
|
KB_NAME: ctx.kbName,
|
|
@@ -28469,23 +28409,51 @@ async function createMinimalCore(ctx, glossaryEntries = []) {
|
|
|
28469
28409
|
ctx.filesCreated++;
|
|
28470
28410
|
}
|
|
28471
28411
|
}
|
|
28472
|
-
async function
|
|
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) {
|
|
28473
28447
|
const agentsTemplate = await fs.readFile(path6.join(ctx.commonDir, "AGENTS.md.hbs"), "utf-8");
|
|
28474
28448
|
let roleSection = "";
|
|
28475
28449
|
const agentSectionPath = path6.join(presetDir, "agent-section.hbs");
|
|
28476
28450
|
if (await fs.pathExists(agentSectionPath)) {
|
|
28477
28451
|
const agentSectionTemplate = await fs.readFile(agentSectionPath, "utf-8");
|
|
28478
|
-
let projectsList;
|
|
28479
|
-
if (projects.length > 0) {
|
|
28480
|
-
projectsList = projects.map((p) => `- [[${p.name}]] \u2014 ${p.description}`).join("\n");
|
|
28481
|
-
} else {
|
|
28482
|
-
projectsList = "(No projects added yet \u2014 create notes in Projects/)";
|
|
28483
|
-
}
|
|
28484
28452
|
roleSection = renderTemplate(agentSectionTemplate, {
|
|
28485
|
-
PROJECTS:
|
|
28486
|
-
JIRA_HOST:
|
|
28487
|
-
JIRA_PROJECT:
|
|
28488
|
-
HAS_JIRA:
|
|
28453
|
+
PROJECTS: "(Use /cook to discover projects from your notes)",
|
|
28454
|
+
JIRA_HOST: "",
|
|
28455
|
+
JIRA_PROJECT: "",
|
|
28456
|
+
HAS_JIRA: false
|
|
28489
28457
|
});
|
|
28490
28458
|
}
|
|
28491
28459
|
const agentsContent = renderTemplate(agentsTemplate, {
|
|
@@ -28504,127 +28472,24 @@ async function applyPresetOverlay(ctx, presetConfig, presetDir) {
|
|
|
28504
28472
|
await fs.ensureDir(path6.join(ctx.vaultPath, dir));
|
|
28505
28473
|
}
|
|
28506
28474
|
ctx.directories.push(...presetConfig.directories);
|
|
28507
|
-
const templateDest = path6.join(ctx.vaultPath, "Knowledge/templates");
|
|
28508
28475
|
const allTemplateNames = [];
|
|
28509
|
-
if (await fs.pathExists(templateDest)) {
|
|
28510
|
-
const existing = await fs.readdir(templateDest);
|
|
28511
|
-
for (const file2 of existing) {
|
|
28512
|
-
if (file2.endsWith(".md")) {
|
|
28513
|
-
allTemplateNames.push(file2.replace(/\.md$/, ""));
|
|
28514
|
-
}
|
|
28515
|
-
}
|
|
28516
|
-
}
|
|
28517
28476
|
const presetTemplatesDir = path6.join(presetDir, "templates");
|
|
28518
28477
|
if (await fs.pathExists(presetTemplatesDir)) {
|
|
28478
|
+
const templateDest = path6.join(ctx.vaultPath, "templates");
|
|
28479
|
+
await fs.ensureDir(templateDest);
|
|
28519
28480
|
const files = await fs.readdir(presetTemplatesDir);
|
|
28520
28481
|
for (const file2 of files) {
|
|
28521
28482
|
await fs.copy(path6.join(presetTemplatesDir, file2), path6.join(templateDest, file2), { overwrite: false });
|
|
28522
28483
|
allTemplateNames.push(file2.replace(/\.md$/, ""));
|
|
28523
28484
|
ctx.filesCreated++;
|
|
28524
|
-
ctx.installedFiles.templates.push(`
|
|
28485
|
+
ctx.installedFiles.templates.push(`templates/${file2}`);
|
|
28525
28486
|
}
|
|
28526
28487
|
}
|
|
28527
28488
|
return allTemplateNames;
|
|
28528
28489
|
}
|
|
28529
|
-
async function createPeopleNotes(ctx, members) {
|
|
28530
|
-
if (members.length === 0)
|
|
28531
|
-
return;
|
|
28532
|
-
await fs.ensureDir(path6.join(ctx.vaultPath, "People"));
|
|
28533
|
-
if (!ctx.directories.includes("People")) {
|
|
28534
|
-
ctx.directories.push("People");
|
|
28535
|
-
}
|
|
28536
|
-
for (const member of members) {
|
|
28537
|
-
const content = `---
|
|
28538
|
-
title: "${member.name}"
|
|
28539
|
-
type: person
|
|
28540
|
-
team: "${ctx.kbName}"
|
|
28541
|
-
role: "${member.role}"
|
|
28542
|
-
status: active
|
|
28543
|
-
tags: [person]
|
|
28544
|
-
---
|
|
28545
|
-
|
|
28546
|
-
# ${member.name}
|
|
28547
|
-
|
|
28548
|
-
**Role**: ${member.role}
|
|
28549
|
-
**Team**: ${ctx.kbName}
|
|
28550
|
-
`;
|
|
28551
|
-
const memberPath = path6.join(ctx.vaultPath, `People/${member.name}.md`);
|
|
28552
|
-
if (!await fs.pathExists(memberPath)) {
|
|
28553
|
-
await fs.writeFile(memberPath, content);
|
|
28554
|
-
ctx.filesCreated++;
|
|
28555
|
-
}
|
|
28556
|
-
}
|
|
28557
|
-
}
|
|
28558
|
-
async function createProjectNotes(ctx, projects) {
|
|
28559
|
-
if (projects.length === 0)
|
|
28560
|
-
return;
|
|
28561
|
-
await fs.ensureDir(path6.join(ctx.vaultPath, "Projects"));
|
|
28562
|
-
if (!ctx.directories.includes("Projects")) {
|
|
28563
|
-
ctx.directories.push("Projects");
|
|
28564
|
-
}
|
|
28565
|
-
for (const project of projects) {
|
|
28566
|
-
const content = `---
|
|
28567
|
-
title: "${project.name}"
|
|
28568
|
-
type: feature
|
|
28569
|
-
status: active
|
|
28570
|
-
date: ${today()}
|
|
28571
|
-
team: "${ctx.kbName}"
|
|
28572
|
-
jira: ""
|
|
28573
|
-
stakeholders: []
|
|
28574
|
-
priority: ""
|
|
28575
|
-
tags: [project]
|
|
28576
|
-
---
|
|
28577
|
-
|
|
28578
|
-
# ${project.name}
|
|
28579
|
-
|
|
28580
|
-
${project.description}
|
|
28581
|
-
`;
|
|
28582
|
-
const projectPath = path6.join(ctx.vaultPath, `Projects/${project.name}.md`);
|
|
28583
|
-
if (!await fs.pathExists(projectPath)) {
|
|
28584
|
-
await fs.writeFile(projectPath, content);
|
|
28585
|
-
ctx.filesCreated++;
|
|
28586
|
-
}
|
|
28587
|
-
}
|
|
28588
|
-
}
|
|
28589
|
-
async function createTeamIndex(ctx, members, projects) {
|
|
28590
|
-
await fs.ensureDir(path6.join(ctx.vaultPath, "People"));
|
|
28591
|
-
if (!ctx.directories.includes("People")) {
|
|
28592
|
-
ctx.directories.push("People");
|
|
28593
|
-
}
|
|
28594
|
-
let teamIndexContent = `---
|
|
28595
|
-
title: "${ctx.kbName} Team"
|
|
28596
|
-
type: reference
|
|
28597
|
-
team: "${ctx.kbName}"
|
|
28598
|
-
tags: [team]
|
|
28599
|
-
---
|
|
28600
|
-
|
|
28601
|
-
# ${ctx.kbName} Team
|
|
28602
|
-
|
|
28603
|
-
## Members
|
|
28604
|
-
|
|
28605
|
-
`;
|
|
28606
|
-
if (members.length > 0) {
|
|
28607
|
-
teamIndexContent += "| Name | Role |\n|------|------|\n";
|
|
28608
|
-
teamIndexContent += members.map((m) => `| [[${m.name}]] | ${m.role} |`).join("\n");
|
|
28609
|
-
} else {
|
|
28610
|
-
teamIndexContent += "(No members added yet)";
|
|
28611
|
-
}
|
|
28612
|
-
teamIndexContent += "\n\n## Active Projects\n\n";
|
|
28613
|
-
if (projects.length > 0) {
|
|
28614
|
-
teamIndexContent += projects.map((p) => `- [[${p.name}]] \u2014 ${p.description}`).join("\n");
|
|
28615
|
-
} else {
|
|
28616
|
-
teamIndexContent += "(No projects added yet)";
|
|
28617
|
-
}
|
|
28618
|
-
teamIndexContent += "\n";
|
|
28619
|
-
const teamIndexPath = path6.join(ctx.vaultPath, `People/${ctx.kbName} Team.md`);
|
|
28620
|
-
if (!await fs.pathExists(teamIndexPath)) {
|
|
28621
|
-
await fs.writeFile(teamIndexPath, teamIndexContent);
|
|
28622
|
-
ctx.filesCreated++;
|
|
28623
|
-
}
|
|
28624
|
-
}
|
|
28625
28490
|
async function createVault(config2) {
|
|
28626
|
-
const { kbName, vaultPath,
|
|
28627
|
-
const presetName = preset ?? "
|
|
28491
|
+
const { kbName, vaultPath, preset } = config2;
|
|
28492
|
+
const presetName = preset ?? "minimal";
|
|
28628
28493
|
const { config: presetConfig, presetsDir } = loadPreset(presetName);
|
|
28629
28494
|
const presetDir = path6.join(presetsDir, presetName);
|
|
28630
28495
|
const initMode = detectInitMode(vaultPath);
|
|
@@ -28637,15 +28502,10 @@ async function createVault(config2) {
|
|
|
28637
28502
|
ctx.mcpServices.push(info);
|
|
28638
28503
|
}
|
|
28639
28504
|
}
|
|
28640
|
-
await createMinimalCore(ctx
|
|
28641
|
-
|
|
28642
|
-
await
|
|
28643
|
-
await
|
|
28644
|
-
await createProjectNotes(ctx, projects);
|
|
28645
|
-
const hasPeopleDir = presetConfig.directories.includes("People") || members.length > 0;
|
|
28646
|
-
if (hasPeopleDir) {
|
|
28647
|
-
await createTeamIndex(ctx, members, projects);
|
|
28648
|
-
}
|
|
28505
|
+
await createMinimalCore(ctx);
|
|
28506
|
+
await createLlmWikiCore(ctx, config2.wikiDomain);
|
|
28507
|
+
await applyPresetOverlay(ctx, presetConfig, presetDir);
|
|
28508
|
+
await createAgentsMd(ctx, config2.ownerName, presetConfig, presetDir);
|
|
28649
28509
|
await configureOpenCodeProject(ctx.vaultPath, ctx.installedFiles);
|
|
28650
28510
|
const mcpOptions = {};
|
|
28651
28511
|
if (config2.mcpSkip && config2.mcpSkip.length > 0) {
|
|
@@ -28726,13 +28586,16 @@ async function configureOpenCodeProject(vaultPath, installedFiles) {
|
|
|
28726
28586
|
}
|
|
28727
28587
|
}
|
|
28728
28588
|
function resolveAssetsDir() {
|
|
28589
|
+
const distAssets = path6.resolve(import.meta.dirname, "assets");
|
|
28729
28590
|
const srcAssets = path6.resolve(import.meta.dirname, "..", "assets");
|
|
28730
|
-
const
|
|
28731
|
-
if (fs.existsSync(srcAssets))
|
|
28732
|
-
return srcAssets;
|
|
28591
|
+
const devAssets = path6.resolve(import.meta.dirname, "..", "..", "src", "assets");
|
|
28733
28592
|
if (fs.existsSync(distAssets))
|
|
28734
28593
|
return distAssets;
|
|
28735
|
-
|
|
28594
|
+
if (fs.existsSync(srcAssets))
|
|
28595
|
+
return srcAssets;
|
|
28596
|
+
if (fs.existsSync(devAssets))
|
|
28597
|
+
return devAssets;
|
|
28598
|
+
return distAssets;
|
|
28736
28599
|
}
|
|
28737
28600
|
|
|
28738
28601
|
// dist/vault/obsidian-check.js
|
|
@@ -28852,26 +28715,13 @@ function formatObsidianStatus(status) {
|
|
|
28852
28715
|
import path7 from "node:path";
|
|
28853
28716
|
import os3 from "node:os";
|
|
28854
28717
|
var byoao_init_vault = tool({
|
|
28855
|
-
description: "Create
|
|
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.",
|
|
28856
28719
|
args: {
|
|
28857
28720
|
kbName: tool.schema.string().describe(`Knowledge base name (e.g. "Jay's KB")`),
|
|
28858
28721
|
ownerName: tool.schema.string().optional().describe("Owner's name"),
|
|
28859
28722
|
vaultPath: tool.schema.string().optional().describe("Where to create the vault. Defaults to ~/Documents/{kbName}"),
|
|
28860
|
-
|
|
28861
|
-
|
|
28862
|
-
role: tool.schema.string().optional().describe("Person's role")
|
|
28863
|
-
})).optional().describe("People to create notes for"),
|
|
28864
|
-
projects: tool.schema.array(tool.schema.object({
|
|
28865
|
-
name: tool.schema.string().describe("Project name"),
|
|
28866
|
-
description: tool.schema.string().optional().describe("One-line description")
|
|
28867
|
-
})).optional().describe("Active projects to create project notes for"),
|
|
28868
|
-
glossaryEntries: tool.schema.array(tool.schema.object({
|
|
28869
|
-
term: tool.schema.string().describe("Domain term"),
|
|
28870
|
-
definition: tool.schema.string().describe("Brief definition")
|
|
28871
|
-
})).optional().describe("Domain terms to add to the glossary"),
|
|
28872
|
-
jiraHost: tool.schema.string().optional().describe("JIRA host (e.g. 'mycompany.atlassian.net')"),
|
|
28873
|
-
jiraProject: tool.schema.string().optional().describe("JIRA project key (e.g. 'HDR')"),
|
|
28874
|
-
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')")
|
|
28875
28725
|
},
|
|
28876
28726
|
async execute(args) {
|
|
28877
28727
|
const obsidianStatus = checkObsidian();
|
|
@@ -28885,12 +28735,8 @@ Please install Obsidian first, then try again.`;
|
|
|
28885
28735
|
kbName: args.kbName,
|
|
28886
28736
|
ownerName: args.ownerName || "",
|
|
28887
28737
|
vaultPath: resolvedPath,
|
|
28888
|
-
|
|
28889
|
-
|
|
28890
|
-
glossaryEntries: args.glossaryEntries || [],
|
|
28891
|
-
jiraHost: args.jiraHost || "",
|
|
28892
|
-
jiraProject: args.jiraProject || "",
|
|
28893
|
-
preset: args.preset || "minimal"
|
|
28738
|
+
preset: args.preset || "minimal",
|
|
28739
|
+
wikiDomain: args.wikiDomain || ""
|
|
28894
28740
|
});
|
|
28895
28741
|
const result = await createVault(config2);
|
|
28896
28742
|
let output = `\u2713 Knowledge base created at: ${result.vaultPath}
|
|
@@ -28990,235 +28836,18 @@ Open in Obsidian: "Open folder as vault" \u2192 select "${result.vaultPath}"`;
|
|
|
28990
28836
|
if (result.initMode === "existing" || result.initMode === "obsidian-vault") {
|
|
28991
28837
|
output += `
|
|
28992
28838
|
|
|
28993
|
-
\u2192 Next step: run /
|
|
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.`;
|
|
28994
28840
|
} else {
|
|
28995
28841
|
output += `
|
|
28996
28842
|
|
|
28997
|
-
\u2192 Next step: add a few notes, then run /
|
|
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.`;
|
|
28998
28844
|
}
|
|
28999
28845
|
return output;
|
|
29000
28846
|
}
|
|
29001
28847
|
});
|
|
29002
28848
|
|
|
29003
|
-
// dist/vault/member.js
|
|
29004
|
-
import path8 from "node:path";
|
|
29005
|
-
async function addMember(input) {
|
|
29006
|
-
const { vaultPath, name, role, team } = input;
|
|
29007
|
-
let wikilinksAdded = 0;
|
|
29008
|
-
const personPath = path8.join(vaultPath, `People/${name}.md`);
|
|
29009
|
-
if (await fs.pathExists(personPath)) {
|
|
29010
|
-
throw new Error(`Person note already exists: ${personPath}`);
|
|
29011
|
-
}
|
|
29012
|
-
const content = `---
|
|
29013
|
-
title: "${name}"
|
|
29014
|
-
type: person
|
|
29015
|
-
team: "${team}"
|
|
29016
|
-
role: "${role}"
|
|
29017
|
-
status: active
|
|
29018
|
-
tags: [person]
|
|
29019
|
-
---
|
|
29020
|
-
|
|
29021
|
-
# ${name}
|
|
29022
|
-
|
|
29023
|
-
**Role**: ${role}
|
|
29024
|
-
**Team**: ${team}
|
|
29025
|
-
`;
|
|
29026
|
-
await fs.writeFile(personPath, content);
|
|
29027
|
-
const teamFiles = await fs.readdir(path8.join(vaultPath, "People"));
|
|
29028
|
-
const teamIndexFile = teamFiles.find((f) => f.endsWith("Team.md"));
|
|
29029
|
-
if (teamIndexFile) {
|
|
29030
|
-
const teamIndexPath = path8.join(vaultPath, "People", teamIndexFile);
|
|
29031
|
-
let teamContent = await fs.readFile(teamIndexPath, "utf-8");
|
|
29032
|
-
const tableRow = `| [[${name}]] | ${role} |`;
|
|
29033
|
-
if (teamContent.includes("|------|------|")) {
|
|
29034
|
-
teamContent = teamContent.replace(/(^\|------|------\|$)/m, `$1
|
|
29035
|
-
${tableRow}`);
|
|
29036
|
-
wikilinksAdded++;
|
|
29037
|
-
}
|
|
29038
|
-
await fs.writeFile(teamIndexPath, teamContent);
|
|
29039
|
-
}
|
|
29040
|
-
for (const agentFile of ["AGENTS.md", "AGENT.md"]) {
|
|
29041
|
-
const agentPath = path8.join(vaultPath, agentFile);
|
|
29042
|
-
if (await fs.pathExists(agentPath)) {
|
|
29043
|
-
let agentContent = await fs.readFile(agentPath, "utf-8");
|
|
29044
|
-
if (agentContent.includes("(No members added yet")) {
|
|
29045
|
-
const table = `| Name | Role |
|
|
29046
|
-
|------|------|
|
|
29047
|
-
| [[${name}]] | ${role} |`;
|
|
29048
|
-
agentContent = agentContent.replace(/\(No members added yet[^)]*\)/, table);
|
|
29049
|
-
wikilinksAdded++;
|
|
29050
|
-
} else if (agentContent.includes("|------|------|")) {
|
|
29051
|
-
const teamSectionMatch = agentContent.match(/## Team[^\n]*\n[\s\S]*?(\|------|------\|[^\n]*(?:\n\|[^\n]*)*)/);
|
|
29052
|
-
if (teamSectionMatch) {
|
|
29053
|
-
const existingTable = teamSectionMatch[1];
|
|
29054
|
-
const newTable = existingTable + `
|
|
29055
|
-
| [[${name}]] | ${role} |`;
|
|
29056
|
-
agentContent = agentContent.replace(existingTable, newTable);
|
|
29057
|
-
wikilinksAdded++;
|
|
29058
|
-
}
|
|
29059
|
-
}
|
|
29060
|
-
await fs.writeFile(agentPath, agentContent);
|
|
29061
|
-
}
|
|
29062
|
-
}
|
|
29063
|
-
return { filePath: personPath, wikilinksAdded };
|
|
29064
|
-
}
|
|
29065
|
-
|
|
29066
|
-
// dist/tools/add-person.js
|
|
29067
|
-
var byoao_add_person = tool({
|
|
29068
|
-
description: "Add a person note to an existing vault. Creates a person note in People/ and updates the team index and AGENTS.md wikilinks.",
|
|
29069
|
-
args: {
|
|
29070
|
-
vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
|
|
29071
|
-
name: tool.schema.string().describe("Person's full name"),
|
|
29072
|
-
role: tool.schema.string().optional().describe("Person's role/title"),
|
|
29073
|
-
team: tool.schema.string().optional().describe("Team or KB name")
|
|
29074
|
-
},
|
|
29075
|
-
async execute(args) {
|
|
29076
|
-
const result = await addMember({
|
|
29077
|
-
vaultPath: args.vaultPath,
|
|
29078
|
-
name: args.name,
|
|
29079
|
-
role: args.role || "",
|
|
29080
|
-
team: args.team || ""
|
|
29081
|
-
});
|
|
29082
|
-
return `Added person: ${args.name}
|
|
29083
|
-
File: ${result.filePath}
|
|
29084
|
-
Wikilinks updated: ${result.wikilinksAdded}`;
|
|
29085
|
-
}
|
|
29086
|
-
});
|
|
29087
|
-
|
|
29088
|
-
// dist/vault/project.js
|
|
29089
|
-
import path9 from "node:path";
|
|
29090
|
-
async function addProject(input) {
|
|
29091
|
-
const { vaultPath, name, description, team } = input;
|
|
29092
|
-
let wikilinksAdded = 0;
|
|
29093
|
-
const projectPath = path9.join(vaultPath, `Projects/${name}.md`);
|
|
29094
|
-
if (await fs.pathExists(projectPath)) {
|
|
29095
|
-
throw new Error(`Project note already exists: ${projectPath}`);
|
|
29096
|
-
}
|
|
29097
|
-
const content = `---
|
|
29098
|
-
title: "${name}"
|
|
29099
|
-
type: feature
|
|
29100
|
-
status: active
|
|
29101
|
-
date: ${today()}
|
|
29102
|
-
team: "${team}"
|
|
29103
|
-
jira: ""
|
|
29104
|
-
stakeholders: []
|
|
29105
|
-
priority: ""
|
|
29106
|
-
tags: [project]
|
|
29107
|
-
---
|
|
29108
|
-
|
|
29109
|
-
# ${name}
|
|
29110
|
-
|
|
29111
|
-
${description}
|
|
29112
|
-
`;
|
|
29113
|
-
await fs.writeFile(projectPath, content);
|
|
29114
|
-
const peoplePath = path9.join(vaultPath, "People");
|
|
29115
|
-
if (await fs.pathExists(peoplePath)) {
|
|
29116
|
-
const teamFiles = await fs.readdir(peoplePath);
|
|
29117
|
-
const teamIndexFile = teamFiles.find((f) => f.endsWith("Team.md"));
|
|
29118
|
-
if (teamIndexFile) {
|
|
29119
|
-
const teamIndexPath = path9.join(peoplePath, teamIndexFile);
|
|
29120
|
-
let teamContent = await fs.readFile(teamIndexPath, "utf-8");
|
|
29121
|
-
const projectLine = `- [[${name}]] \u2014 ${description}`;
|
|
29122
|
-
if (teamContent.includes("(No projects added yet)")) {
|
|
29123
|
-
teamContent = teamContent.replace("(No projects added yet)", projectLine);
|
|
29124
|
-
} else if (teamContent.includes("## Active Projects")) {
|
|
29125
|
-
teamContent = teamContent.replace(/(## Active Projects\n\n)([\s\S]*?)(\n\n|$)/, `$1$2
|
|
29126
|
-
${projectLine}$3`);
|
|
29127
|
-
}
|
|
29128
|
-
wikilinksAdded++;
|
|
29129
|
-
await fs.writeFile(teamIndexPath, teamContent);
|
|
29130
|
-
}
|
|
29131
|
-
}
|
|
29132
|
-
for (const agentFile of ["AGENTS.md", "AGENT.md"]) {
|
|
29133
|
-
const agentPath = path9.join(vaultPath, agentFile);
|
|
29134
|
-
if (await fs.pathExists(agentPath)) {
|
|
29135
|
-
let agentContent = await fs.readFile(agentPath, "utf-8");
|
|
29136
|
-
const projectLine = `- [[${name}]] \u2014 ${description}`;
|
|
29137
|
-
if (agentContent.includes("(No projects added yet")) {
|
|
29138
|
-
agentContent = agentContent.replace(/\(No projects added yet[^)]*\)/, projectLine);
|
|
29139
|
-
wikilinksAdded++;
|
|
29140
|
-
} else if (agentContent.includes("## Active Projects")) {
|
|
29141
|
-
agentContent = agentContent.replace(/(## Active Projects[^\n]*\n\n)([\s\S]*?)(\n\n|$)/, `$1$2
|
|
29142
|
-
${projectLine}$3`);
|
|
29143
|
-
wikilinksAdded++;
|
|
29144
|
-
}
|
|
29145
|
-
await fs.writeFile(agentPath, agentContent);
|
|
29146
|
-
}
|
|
29147
|
-
}
|
|
29148
|
-
return { filePath: projectPath, wikilinksAdded };
|
|
29149
|
-
}
|
|
29150
|
-
|
|
29151
|
-
// dist/tools/add-project.js
|
|
29152
|
-
var byoao_add_project = tool({
|
|
29153
|
-
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.",
|
|
29154
|
-
args: {
|
|
29155
|
-
vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
|
|
29156
|
-
name: tool.schema.string().describe("Project name"),
|
|
29157
|
-
description: tool.schema.string().optional().describe("One-line project description"),
|
|
29158
|
-
team: tool.schema.string().optional().describe("Team name")
|
|
29159
|
-
},
|
|
29160
|
-
async execute(args) {
|
|
29161
|
-
const result = await addProject({
|
|
29162
|
-
vaultPath: args.vaultPath,
|
|
29163
|
-
name: args.name,
|
|
29164
|
-
description: args.description || "",
|
|
29165
|
-
team: args.team || ""
|
|
29166
|
-
});
|
|
29167
|
-
return `\u2713 Added project: ${args.name}
|
|
29168
|
-
File: ${result.filePath}
|
|
29169
|
-
Wikilinks updated: ${result.wikilinksAdded}`;
|
|
29170
|
-
}
|
|
29171
|
-
});
|
|
29172
|
-
|
|
29173
|
-
// dist/vault/glossary.js
|
|
29174
|
-
import path10 from "node:path";
|
|
29175
|
-
async function addGlossaryTerm(input) {
|
|
29176
|
-
const { vaultPath, term, definition, domain: domain2 } = input;
|
|
29177
|
-
const glossaryPath = path10.join(vaultPath, "Knowledge/Glossary.md");
|
|
29178
|
-
if (!await fs.pathExists(glossaryPath)) {
|
|
29179
|
-
throw new Error(`Glossary not found at: ${glossaryPath}`);
|
|
29180
|
-
}
|
|
29181
|
-
let content = await fs.readFile(glossaryPath, "utf-8");
|
|
29182
|
-
const newRow = `| **${term}** | ${definition} | ${domain2 ?? ""} |`;
|
|
29183
|
-
const tableMatch = content.match(/(\| Term \| Definition \| Domain \|\n\|------\|-----------|--------\|\n)([\s\S]*?)(\n*$)/);
|
|
29184
|
-
if (tableMatch) {
|
|
29185
|
-
const [fullMatch, tableHeader, existingRows, trailing] = tableMatch;
|
|
29186
|
-
const updatedRows = existingRows.trim() ? `${existingRows.trim()}
|
|
29187
|
-
${newRow}` : newRow;
|
|
29188
|
-
content = content.replace(fullMatch, `${tableHeader}${updatedRows}
|
|
29189
|
-
`);
|
|
29190
|
-
} else {
|
|
29191
|
-
content = content.trimEnd() + `
|
|
29192
|
-
${newRow}
|
|
29193
|
-
`;
|
|
29194
|
-
}
|
|
29195
|
-
await fs.writeFile(glossaryPath, content);
|
|
29196
|
-
return { glossaryPath, termAdded: term };
|
|
29197
|
-
}
|
|
29198
|
-
|
|
29199
|
-
// dist/tools/add-glossary-term.js
|
|
29200
|
-
var byoao_add_glossary_term = tool({
|
|
29201
|
-
description: "Add a new term to the vault's Glossary.md. Appends a row to the Core Terms table.",
|
|
29202
|
-
args: {
|
|
29203
|
-
vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
|
|
29204
|
-
term: tool.schema.string().describe("The domain term to add"),
|
|
29205
|
-
definition: tool.schema.string().describe("Brief definition (1-2 sentences)"),
|
|
29206
|
-
domain: tool.schema.string().optional().describe("Knowledge domain (e.g. analytics, infrastructure)")
|
|
29207
|
-
},
|
|
29208
|
-
async execute(args) {
|
|
29209
|
-
const result = await addGlossaryTerm({
|
|
29210
|
-
vaultPath: args.vaultPath,
|
|
29211
|
-
term: args.term,
|
|
29212
|
-
definition: args.definition,
|
|
29213
|
-
domain: args.domain ?? ""
|
|
29214
|
-
});
|
|
29215
|
-
return `\u2713 Added glossary term: ${result.termAdded}
|
|
29216
|
-
File: ${result.glossaryPath}`;
|
|
29217
|
-
}
|
|
29218
|
-
});
|
|
29219
|
-
|
|
29220
28849
|
// dist/vault/status.js
|
|
29221
|
-
import
|
|
28850
|
+
import path8 from "node:path";
|
|
29222
28851
|
async function getAllMarkdownFiles(dirPath) {
|
|
29223
28852
|
const results = [];
|
|
29224
28853
|
async function walk(dir) {
|
|
@@ -29226,7 +28855,7 @@ async function getAllMarkdownFiles(dirPath) {
|
|
|
29226
28855
|
return;
|
|
29227
28856
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
29228
28857
|
for (const entry of entries) {
|
|
29229
|
-
const fullPath =
|
|
28858
|
+
const fullPath = path8.join(dir, entry.name);
|
|
29230
28859
|
if (entry.isDirectory()) {
|
|
29231
28860
|
if (!entry.name.startsWith(".")) {
|
|
29232
28861
|
await walk(fullPath);
|
|
@@ -29258,11 +28887,14 @@ async function getVaultStatus(vaultPath) {
|
|
|
29258
28887
|
directories: {},
|
|
29259
28888
|
hasObsidianConfig: false,
|
|
29260
28889
|
hasAgentMd: false,
|
|
29261
|
-
|
|
28890
|
+
agentPages: { entities: 0, concepts: 0, comparisons: 0, queries: 0 },
|
|
28891
|
+
hasSchema: false,
|
|
28892
|
+
hasLog: false,
|
|
28893
|
+
hasIndexBase: false
|
|
29262
28894
|
};
|
|
29263
28895
|
}
|
|
29264
28896
|
const allFiles = await getAllMarkdownFiles(vaultPath);
|
|
29265
|
-
const noteNames = new Set(allFiles.map((f) =>
|
|
28897
|
+
const noteNames = new Set(allFiles.map((f) => path8.basename(f, ".md")));
|
|
29266
28898
|
let wikilinkCount = 0;
|
|
29267
28899
|
const brokenLinksSet = /* @__PURE__ */ new Set();
|
|
29268
28900
|
for (const file2 of allFiles) {
|
|
@@ -29287,12 +28919,24 @@ async function getVaultStatus(vaultPath) {
|
|
|
29287
28919
|
"Daily"
|
|
29288
28920
|
];
|
|
29289
28921
|
for (const dir of topDirs) {
|
|
29290
|
-
const dirPath =
|
|
28922
|
+
const dirPath = path8.join(vaultPath, dir);
|
|
29291
28923
|
if (await fs.pathExists(dirPath)) {
|
|
29292
28924
|
const files = await getAllMarkdownFiles(dirPath);
|
|
29293
28925
|
directories[dir] = files.length;
|
|
29294
28926
|
}
|
|
29295
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
|
+
}
|
|
29296
28940
|
return {
|
|
29297
28941
|
exists: true,
|
|
29298
28942
|
vaultPath,
|
|
@@ -29300,9 +28944,12 @@ async function getVaultStatus(vaultPath) {
|
|
|
29300
28944
|
wikilinkCount,
|
|
29301
28945
|
brokenLinks: Array.from(brokenLinksSet),
|
|
29302
28946
|
directories,
|
|
29303
|
-
hasObsidianConfig: await fs.pathExists(
|
|
29304
|
-
hasAgentMd: await fs.pathExists(
|
|
29305
|
-
|
|
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"))
|
|
29306
28953
|
};
|
|
29307
28954
|
}
|
|
29308
28955
|
function formatVaultStatus(status) {
|
|
@@ -29322,7 +28969,10 @@ function formatVaultStatus(status) {
|
|
|
29322
28969
|
lines.push("");
|
|
29323
28970
|
lines.push(`Config: ${status.hasObsidianConfig ? "\u2713" : "\u2717"} .obsidian/`);
|
|
29324
28971
|
lines.push(`Agent: ${status.hasAgentMd ? "\u2713" : "\u2717"} AGENTS.md`);
|
|
29325
|
-
lines.push(
|
|
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"}`);
|
|
29326
28976
|
if (status.brokenLinks.length > 0) {
|
|
29327
28977
|
lines.push("");
|
|
29328
28978
|
lines.push(`\u26A0\uFE0F Broken links (${status.brokenLinks.length}):`);
|
|
@@ -29340,7 +28990,7 @@ function formatVaultStatus(status) {
|
|
|
29340
28990
|
|
|
29341
28991
|
// dist/tools/vault-status.js
|
|
29342
28992
|
var byoao_vault_status = tool({
|
|
29343
|
-
description: "Check the health of an Obsidian vault \u2014 note count, wikilink count, broken links, directory breakdown,
|
|
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.",
|
|
29344
28994
|
args: {
|
|
29345
28995
|
vaultPath: tool.schema.string().describe("Path to the Obsidian vault")
|
|
29346
28996
|
},
|
|
@@ -29355,12 +29005,18 @@ var byoao_vault_status = tool({
|
|
|
29355
29005
|
});
|
|
29356
29006
|
|
|
29357
29007
|
// dist/vault/doctor.js
|
|
29358
|
-
import
|
|
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
|
+
}
|
|
29359
29015
|
async function collectMarkdownFiles(dir) {
|
|
29360
29016
|
const results = [];
|
|
29361
29017
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
29362
29018
|
for (const entry of entries) {
|
|
29363
|
-
const fullPath =
|
|
29019
|
+
const fullPath = path9.join(dir, entry.name);
|
|
29364
29020
|
if (entry.isDirectory()) {
|
|
29365
29021
|
if (entry.name === ".obsidian" || entry.name === ".git")
|
|
29366
29022
|
continue;
|
|
@@ -29381,10 +29037,10 @@ function extractWikilinks2(content) {
|
|
|
29381
29037
|
async function getVaultDiagnosis(vaultPath) {
|
|
29382
29038
|
const issues = [];
|
|
29383
29039
|
const allFiles = await collectMarkdownFiles(vaultPath);
|
|
29384
|
-
const noteNames = new Set(allFiles.map((f) =>
|
|
29040
|
+
const noteNames = new Set(allFiles.map((f) => path9.basename(f, ".md")));
|
|
29385
29041
|
let healthyNotes = 0;
|
|
29386
29042
|
for (const filePath of allFiles) {
|
|
29387
|
-
const relativePath =
|
|
29043
|
+
const relativePath = path9.relative(vaultPath, filePath);
|
|
29388
29044
|
if (relativePath.startsWith("Knowledge/templates/"))
|
|
29389
29045
|
continue;
|
|
29390
29046
|
const content = await fs.readFile(filePath, "utf-8");
|
|
@@ -29418,15 +29074,26 @@ async function getVaultDiagnosis(vaultPath) {
|
|
|
29418
29074
|
hasIssue = true;
|
|
29419
29075
|
}
|
|
29420
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
|
+
}
|
|
29421
29088
|
if (!hasIssue)
|
|
29422
29089
|
healthyNotes++;
|
|
29423
29090
|
}
|
|
29424
29091
|
let agentContent = null;
|
|
29425
|
-
let agentResolvedPath =
|
|
29092
|
+
let agentResolvedPath = path9.join(vaultPath, "AGENTS.md");
|
|
29426
29093
|
if (await fs.pathExists(agentResolvedPath)) {
|
|
29427
29094
|
agentContent = await fs.readFile(agentResolvedPath, "utf-8");
|
|
29428
29095
|
} else {
|
|
29429
|
-
agentResolvedPath =
|
|
29096
|
+
agentResolvedPath = path9.join(vaultPath, "AGENT.md");
|
|
29430
29097
|
if (await fs.pathExists(agentResolvedPath)) {
|
|
29431
29098
|
agentContent = await fs.readFile(agentResolvedPath, "utf-8");
|
|
29432
29099
|
}
|
|
@@ -29443,24 +29110,54 @@ async function getVaultDiagnosis(vaultPath) {
|
|
|
29443
29110
|
}
|
|
29444
29111
|
}
|
|
29445
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
|
+
}
|
|
29446
29141
|
const allLinksMap = /* @__PURE__ */ new Map();
|
|
29447
29142
|
const incomingLinks = /* @__PURE__ */ new Set();
|
|
29448
29143
|
for (const filePath of allFiles) {
|
|
29449
29144
|
const content = await fs.readFile(filePath, "utf-8");
|
|
29450
29145
|
const links = extractWikilinks2(content);
|
|
29451
|
-
const name =
|
|
29146
|
+
const name = path9.basename(filePath, ".md");
|
|
29452
29147
|
allLinksMap.set(name, new Set(links));
|
|
29453
29148
|
for (const link of links) {
|
|
29454
29149
|
incomingLinks.add(link);
|
|
29455
29150
|
}
|
|
29456
29151
|
}
|
|
29457
29152
|
for (const filePath of allFiles) {
|
|
29458
|
-
const relativePath =
|
|
29153
|
+
const relativePath = path9.relative(vaultPath, filePath);
|
|
29459
29154
|
if (relativePath.startsWith("Knowledge/templates/"))
|
|
29460
29155
|
continue;
|
|
29461
29156
|
if (relativePath === "AGENT.md" || relativePath === "AGENTS.md")
|
|
29462
29157
|
continue;
|
|
29463
|
-
|
|
29158
|
+
if (isAgentWikiPage(relativePath))
|
|
29159
|
+
continue;
|
|
29160
|
+
const name = path9.basename(filePath, ".md");
|
|
29464
29161
|
const outgoing = allLinksMap.get(name) || /* @__PURE__ */ new Set();
|
|
29465
29162
|
const hasIncoming = incomingLinks.has(name);
|
|
29466
29163
|
const hasOutgoing = outgoing.size > 0;
|
|
@@ -29474,7 +29171,7 @@ async function getVaultDiagnosis(vaultPath) {
|
|
|
29474
29171
|
}
|
|
29475
29172
|
}
|
|
29476
29173
|
for (const filePath of allFiles) {
|
|
29477
|
-
const relativePath =
|
|
29174
|
+
const relativePath = path9.relative(vaultPath, filePath);
|
|
29478
29175
|
const content = await fs.readFile(filePath, "utf-8");
|
|
29479
29176
|
const links = extractWikilinks2(content);
|
|
29480
29177
|
for (const link of links) {
|
|
@@ -29500,7 +29197,7 @@ async function getVaultDiagnosis(vaultPath) {
|
|
|
29500
29197
|
|
|
29501
29198
|
// dist/tools/vault-doctor.js
|
|
29502
29199
|
var byoao_vault_doctor = tool({
|
|
29503
|
-
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.",
|
|
29504
29201
|
args: {
|
|
29505
29202
|
vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault")
|
|
29506
29203
|
},
|
|
@@ -29566,323 +29263,16 @@ var byoao_switch_provider = tool({
|
|
|
29566
29263
|
}
|
|
29567
29264
|
});
|
|
29568
29265
|
|
|
29569
|
-
// dist/vault/search-vault.js
|
|
29570
|
-
import path13 from "node:path";
|
|
29571
|
-
|
|
29572
|
-
// dist/vault/obsidian-cli.js
|
|
29573
|
-
import { execFileSync, execSync as execSync3 } from "node:child_process";
|
|
29574
|
-
import { platform as platform2 } from "node:os";
|
|
29575
|
-
var _cliAvailableCache = null;
|
|
29576
|
-
function isObsidianCliAvailable() {
|
|
29577
|
-
if (_cliAvailableCache !== null)
|
|
29578
|
-
return _cliAvailableCache;
|
|
29579
|
-
const os5 = platform2();
|
|
29580
|
-
try {
|
|
29581
|
-
if (os5 === "darwin") {
|
|
29582
|
-
execSync3("pgrep -x Obsidian", { stdio: "pipe", timeout: 3e3 });
|
|
29583
|
-
_cliAvailableCache = true;
|
|
29584
|
-
} else if (os5 === "linux") {
|
|
29585
|
-
execSync3("pgrep -x obsidian", { stdio: "pipe", timeout: 3e3 });
|
|
29586
|
-
_cliAvailableCache = true;
|
|
29587
|
-
} else if (os5 === "win32") {
|
|
29588
|
-
const result = execSync3('tasklist /FI "IMAGENAME eq Obsidian.exe" /NH', { stdio: "pipe", timeout: 3e3, encoding: "utf-8" });
|
|
29589
|
-
_cliAvailableCache = result.includes("Obsidian.exe");
|
|
29590
|
-
} else {
|
|
29591
|
-
_cliAvailableCache = false;
|
|
29592
|
-
}
|
|
29593
|
-
} catch {
|
|
29594
|
-
_cliAvailableCache = false;
|
|
29595
|
-
}
|
|
29596
|
-
return _cliAvailableCache;
|
|
29597
|
-
}
|
|
29598
|
-
function execObsidianCmd(args) {
|
|
29599
|
-
try {
|
|
29600
|
-
const output = execFileSync("obsidian", args, {
|
|
29601
|
-
stdio: "pipe",
|
|
29602
|
-
encoding: "utf-8",
|
|
29603
|
-
timeout: 1e4
|
|
29604
|
-
});
|
|
29605
|
-
return { success: true, output: output.trim() };
|
|
29606
|
-
} catch (err) {
|
|
29607
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
29608
|
-
return { success: false, output: "", error: msg };
|
|
29609
|
-
}
|
|
29610
|
-
}
|
|
29611
|
-
|
|
29612
|
-
// dist/vault/retrieval-types.js
|
|
29613
|
-
var DEFAULT_RESULT_LIMIT = 20;
|
|
29614
|
-
var MAX_SNIPPET_LENGTH = 240;
|
|
29615
|
-
|
|
29616
|
-
// dist/vault/search-vault.js
|
|
29617
|
-
async function searchVault(input) {
|
|
29618
|
-
const { vaultPath, query, limit = DEFAULT_RESULT_LIMIT } = input;
|
|
29619
|
-
const mode = "search:context";
|
|
29620
|
-
const base = {
|
|
29621
|
-
mode,
|
|
29622
|
-
vault: vaultPath,
|
|
29623
|
-
fallback: "none"
|
|
29624
|
-
};
|
|
29625
|
-
if (!isObsidianCliAvailable()) {
|
|
29626
|
-
return {
|
|
29627
|
-
...base,
|
|
29628
|
-
status: "runtime_unavailable",
|
|
29629
|
-
summary: "Obsidian CLI not available",
|
|
29630
|
-
results: [],
|
|
29631
|
-
truncated: false,
|
|
29632
|
-
diagnostics: ["Obsidian CLI not available"]
|
|
29633
|
-
};
|
|
29634
|
-
}
|
|
29635
|
-
const cliResult = execObsidianCmd([
|
|
29636
|
-
"search:context",
|
|
29637
|
-
"--vault",
|
|
29638
|
-
vaultPath,
|
|
29639
|
-
query
|
|
29640
|
-
]);
|
|
29641
|
-
if (!cliResult.success) {
|
|
29642
|
-
return {
|
|
29643
|
-
...base,
|
|
29644
|
-
status: "runtime_unavailable",
|
|
29645
|
-
summary: "Obsidian CLI command failed",
|
|
29646
|
-
results: [],
|
|
29647
|
-
truncated: false,
|
|
29648
|
-
diagnostics: [cliResult.error ?? "Unknown CLI error"]
|
|
29649
|
-
};
|
|
29650
|
-
}
|
|
29651
|
-
const lines = cliResult.output.split("\n").filter((l) => l.trim().length > 0);
|
|
29652
|
-
if (lines.length === 0) {
|
|
29653
|
-
return {
|
|
29654
|
-
...base,
|
|
29655
|
-
status: "no_results",
|
|
29656
|
-
summary: `No matches for "${query}"`,
|
|
29657
|
-
results: [],
|
|
29658
|
-
truncated: false,
|
|
29659
|
-
diagnostics: []
|
|
29660
|
-
};
|
|
29661
|
-
}
|
|
29662
|
-
const allItems = [];
|
|
29663
|
-
for (const line of lines) {
|
|
29664
|
-
const colonIdx = line.indexOf(":");
|
|
29665
|
-
if (colonIdx === -1)
|
|
29666
|
-
continue;
|
|
29667
|
-
const filePath = line.substring(0, colonIdx);
|
|
29668
|
-
const snippet = line.substring(colonIdx + 1).trim();
|
|
29669
|
-
const title = path13.basename(filePath, ".md");
|
|
29670
|
-
allItems.push({
|
|
29671
|
-
title,
|
|
29672
|
-
path: filePath,
|
|
29673
|
-
file: title,
|
|
29674
|
-
snippet: snippet.length > MAX_SNIPPET_LENGTH ? snippet.substring(0, MAX_SNIPPET_LENGTH) : snippet
|
|
29675
|
-
});
|
|
29676
|
-
}
|
|
29677
|
-
const truncated = allItems.length > limit;
|
|
29678
|
-
const results = allItems.slice(0, limit);
|
|
29679
|
-
return {
|
|
29680
|
-
...base,
|
|
29681
|
-
status: "ok",
|
|
29682
|
-
summary: `${allItems.length} matching notes for "${query}"`,
|
|
29683
|
-
results,
|
|
29684
|
-
truncated,
|
|
29685
|
-
totalMatches: allItems.length,
|
|
29686
|
-
diagnostics: []
|
|
29687
|
-
};
|
|
29688
|
-
}
|
|
29689
|
-
|
|
29690
|
-
// dist/tools/search-vault.js
|
|
29691
|
-
var byoao_search_vault = tool({
|
|
29692
|
-
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.",
|
|
29693
|
-
args: {
|
|
29694
|
-
vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
|
|
29695
|
-
query: tool.schema.string().describe("Text query to search for in vault notes"),
|
|
29696
|
-
limit: tool.schema.number().optional().describe("Maximum number of results to return (default: 20)")
|
|
29697
|
-
},
|
|
29698
|
-
async execute(args) {
|
|
29699
|
-
const result = await searchVault({
|
|
29700
|
-
vaultPath: args.vaultPath,
|
|
29701
|
-
query: args.query,
|
|
29702
|
-
limit: args.limit
|
|
29703
|
-
});
|
|
29704
|
-
return JSON.stringify(result, null, 2);
|
|
29705
|
-
}
|
|
29706
|
-
});
|
|
29707
|
-
|
|
29708
|
-
// dist/vault/note-read.js
|
|
29709
|
-
async function readNote(input) {
|
|
29710
|
-
const { vaultPath, file: file2 } = input;
|
|
29711
|
-
const mode = "read";
|
|
29712
|
-
const base = {
|
|
29713
|
-
mode,
|
|
29714
|
-
vault: vaultPath,
|
|
29715
|
-
fallback: "none"
|
|
29716
|
-
};
|
|
29717
|
-
if (!isObsidianCliAvailable()) {
|
|
29718
|
-
return {
|
|
29719
|
-
...base,
|
|
29720
|
-
status: "runtime_unavailable",
|
|
29721
|
-
summary: "Obsidian CLI not available",
|
|
29722
|
-
results: [],
|
|
29723
|
-
truncated: false,
|
|
29724
|
-
diagnostics: ["Obsidian CLI not available"]
|
|
29725
|
-
};
|
|
29726
|
-
}
|
|
29727
|
-
const cliResult = execObsidianCmd(["read", "--vault", vaultPath, file2]);
|
|
29728
|
-
if (!cliResult.success) {
|
|
29729
|
-
return {
|
|
29730
|
-
...base,
|
|
29731
|
-
status: "runtime_unavailable",
|
|
29732
|
-
summary: `Failed to read note "${file2}"`,
|
|
29733
|
-
results: [],
|
|
29734
|
-
truncated: false,
|
|
29735
|
-
diagnostics: [cliResult.error ?? "Unknown CLI error"]
|
|
29736
|
-
};
|
|
29737
|
-
}
|
|
29738
|
-
const content = cliResult.output.trim();
|
|
29739
|
-
if (content.length === 0) {
|
|
29740
|
-
return {
|
|
29741
|
-
...base,
|
|
29742
|
-
status: "no_results",
|
|
29743
|
-
summary: `Note "${file2}" is empty or not found`,
|
|
29744
|
-
results: [],
|
|
29745
|
-
truncated: false,
|
|
29746
|
-
diagnostics: []
|
|
29747
|
-
};
|
|
29748
|
-
}
|
|
29749
|
-
const snippet = content.length > MAX_SNIPPET_LENGTH ? content.substring(0, MAX_SNIPPET_LENGTH) : content;
|
|
29750
|
-
return {
|
|
29751
|
-
...base,
|
|
29752
|
-
status: "ok",
|
|
29753
|
-
summary: `Read note "${file2}" (${content.length} chars)`,
|
|
29754
|
-
results: [
|
|
29755
|
-
{
|
|
29756
|
-
title: file2,
|
|
29757
|
-
path: "",
|
|
29758
|
-
file: file2,
|
|
29759
|
-
snippet
|
|
29760
|
-
}
|
|
29761
|
-
],
|
|
29762
|
-
truncated: false,
|
|
29763
|
-
diagnostics: []
|
|
29764
|
-
};
|
|
29765
|
-
}
|
|
29766
|
-
|
|
29767
|
-
// dist/tools/note-read.js
|
|
29768
|
-
var byoao_note_read = tool({
|
|
29769
|
-
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.",
|
|
29770
|
-
args: {
|
|
29771
|
-
vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
|
|
29772
|
-
file: tool.schema.string().describe("Note name to read (without .md extension, e.g. 'Refund Automation')")
|
|
29773
|
-
},
|
|
29774
|
-
async execute(args) {
|
|
29775
|
-
const result = await readNote({
|
|
29776
|
-
vaultPath: args.vaultPath,
|
|
29777
|
-
file: args.file
|
|
29778
|
-
});
|
|
29779
|
-
return JSON.stringify(result, null, 2);
|
|
29780
|
-
}
|
|
29781
|
-
});
|
|
29782
|
-
|
|
29783
|
-
// dist/vault/graph-health.js
|
|
29784
|
-
import path14 from "node:path";
|
|
29785
|
-
var ALL_CHECKS = ["orphans", "unresolved", "deadends"];
|
|
29786
|
-
function parseCheckOutput(check2, output) {
|
|
29787
|
-
const lines = output.split("\n").filter((l) => l.trim().length > 0);
|
|
29788
|
-
return lines.map((line) => {
|
|
29789
|
-
const trimmed = line.trim();
|
|
29790
|
-
const isPath = trimmed.includes("/") || trimmed.endsWith(".md");
|
|
29791
|
-
const title = isPath ? path14.basename(trimmed, ".md") : trimmed;
|
|
29792
|
-
return {
|
|
29793
|
-
title,
|
|
29794
|
-
path: isPath ? trimmed : "",
|
|
29795
|
-
file: title,
|
|
29796
|
-
metadata: { check: check2 }
|
|
29797
|
-
};
|
|
29798
|
-
});
|
|
29799
|
-
}
|
|
29800
|
-
async function getGraphHealth(input) {
|
|
29801
|
-
const { vaultPath, check: check2 = "all", limit = DEFAULT_RESULT_LIMIT } = input;
|
|
29802
|
-
const mode = "graph-health";
|
|
29803
|
-
const base = {
|
|
29804
|
-
mode,
|
|
29805
|
-
vault: vaultPath,
|
|
29806
|
-
fallback: "none"
|
|
29807
|
-
};
|
|
29808
|
-
if (!isObsidianCliAvailable()) {
|
|
29809
|
-
return {
|
|
29810
|
-
...base,
|
|
29811
|
-
status: "runtime_unavailable",
|
|
29812
|
-
summary: "Obsidian CLI not available",
|
|
29813
|
-
results: [],
|
|
29814
|
-
truncated: false,
|
|
29815
|
-
diagnostics: ["Obsidian CLI not available"]
|
|
29816
|
-
};
|
|
29817
|
-
}
|
|
29818
|
-
const checks = check2 === "all" ? ALL_CHECKS : [check2];
|
|
29819
|
-
const allItems = [];
|
|
29820
|
-
const diagnostics = [];
|
|
29821
|
-
for (const checkType of checks) {
|
|
29822
|
-
const cliResult = execObsidianCmd([checkType, "--vault", vaultPath]);
|
|
29823
|
-
if (!cliResult.success) {
|
|
29824
|
-
diagnostics.push(`${checkType} check failed: ${cliResult.error ?? "unknown error"}`);
|
|
29825
|
-
continue;
|
|
29826
|
-
}
|
|
29827
|
-
if (cliResult.output.trim().length > 0) {
|
|
29828
|
-
allItems.push(...parseCheckOutput(checkType, cliResult.output));
|
|
29829
|
-
}
|
|
29830
|
-
}
|
|
29831
|
-
if (allItems.length === 0 && diagnostics.length === 0) {
|
|
29832
|
-
return {
|
|
29833
|
-
...base,
|
|
29834
|
-
status: "no_results",
|
|
29835
|
-
summary: "No issues found \u2014 vault graph is healthy",
|
|
29836
|
-
results: [],
|
|
29837
|
-
truncated: false,
|
|
29838
|
-
diagnostics
|
|
29839
|
-
};
|
|
29840
|
-
}
|
|
29841
|
-
const truncated = allItems.length > limit;
|
|
29842
|
-
const results = allItems.slice(0, limit);
|
|
29843
|
-
return {
|
|
29844
|
-
...base,
|
|
29845
|
-
status: allItems.length > 0 ? "ok" : "no_results",
|
|
29846
|
-
summary: `Found ${allItems.length} graph issues across ${checks.join(", ")} checks`,
|
|
29847
|
-
results,
|
|
29848
|
-
truncated,
|
|
29849
|
-
totalMatches: allItems.length,
|
|
29850
|
-
diagnostics
|
|
29851
|
-
};
|
|
29852
|
-
}
|
|
29853
|
-
|
|
29854
|
-
// dist/tools/graph-health.js
|
|
29855
|
-
var byoao_graph_health = tool({
|
|
29856
|
-
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.",
|
|
29857
|
-
args: {
|
|
29858
|
-
vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
|
|
29859
|
-
check: tool.schema.enum(["all", "orphans", "unresolved", "deadends"]).optional().describe("Which check to run: 'all' (default), 'orphans', 'unresolved', or 'deadends'"),
|
|
29860
|
-
limit: tool.schema.number().optional().describe("Maximum number of results to return (default: 20)")
|
|
29861
|
-
},
|
|
29862
|
-
async execute(args) {
|
|
29863
|
-
const result = await getGraphHealth({
|
|
29864
|
-
vaultPath: args.vaultPath,
|
|
29865
|
-
check: args.check,
|
|
29866
|
-
limit: args.limit
|
|
29867
|
-
});
|
|
29868
|
-
return JSON.stringify(result, null, 2);
|
|
29869
|
-
}
|
|
29870
|
-
});
|
|
29871
|
-
|
|
29872
29266
|
// dist/vault/upgrade.js
|
|
29873
|
-
import
|
|
29874
|
-
var OBSIDIAN_CONFIG_FILES = [
|
|
29875
|
-
"core-plugins.json",
|
|
29876
|
-
"daily-notes.json",
|
|
29877
|
-
"templates.json"
|
|
29878
|
-
];
|
|
29267
|
+
import path10 from "node:path";
|
|
29268
|
+
var OBSIDIAN_CONFIG_FILES = ["core-plugins.json"];
|
|
29879
29269
|
async function scanInstalledAssets(vaultPath) {
|
|
29880
29270
|
const skills = await scanSkillDirs(vaultPath);
|
|
29881
29271
|
const commands = await scanDir(vaultPath, ".opencode/commands", ".md");
|
|
29882
29272
|
const templates = await scanDir(vaultPath, "Knowledge/templates", ".md");
|
|
29883
29273
|
const obsidianConfig = [];
|
|
29884
29274
|
for (const file2 of OBSIDIAN_CONFIG_FILES) {
|
|
29885
|
-
const abs =
|
|
29275
|
+
const abs = path10.join(vaultPath, ".obsidian", file2);
|
|
29886
29276
|
if (await fs.pathExists(abs)) {
|
|
29887
29277
|
obsidianConfig.push(`.obsidian/${file2}`);
|
|
29888
29278
|
}
|
|
@@ -29890,21 +29280,21 @@ async function scanInstalledAssets(vaultPath) {
|
|
|
29890
29280
|
return { skills, commands, obsidianConfig, templates };
|
|
29891
29281
|
}
|
|
29892
29282
|
async function scanDir(vaultPath, relDir, ext) {
|
|
29893
|
-
const absDir =
|
|
29283
|
+
const absDir = path10.join(vaultPath, relDir);
|
|
29894
29284
|
if (!await fs.pathExists(absDir))
|
|
29895
29285
|
return [];
|
|
29896
29286
|
const files = await fs.readdir(absDir);
|
|
29897
29287
|
return files.filter((f) => f.endsWith(ext)).map((f) => `${relDir}/${f}`);
|
|
29898
29288
|
}
|
|
29899
29289
|
async function scanSkillDirs(vaultPath) {
|
|
29900
|
-
const skillsRoot =
|
|
29290
|
+
const skillsRoot = path10.join(vaultPath, ".opencode", "skills");
|
|
29901
29291
|
if (!await fs.pathExists(skillsRoot))
|
|
29902
29292
|
return [];
|
|
29903
29293
|
const results = [];
|
|
29904
29294
|
const entries = await fs.readdir(skillsRoot, { withFileTypes: true });
|
|
29905
29295
|
for (const entry of entries) {
|
|
29906
29296
|
if (entry.isDirectory()) {
|
|
29907
|
-
const skillMd =
|
|
29297
|
+
const skillMd = path10.join(skillsRoot, entry.name, "SKILL.md");
|
|
29908
29298
|
if (await fs.pathExists(skillMd)) {
|
|
29909
29299
|
results.push(`.opencode/skills/${entry.name}/SKILL.md`);
|
|
29910
29300
|
}
|
|
@@ -29912,7 +29302,7 @@ async function scanSkillDirs(vaultPath) {
|
|
|
29912
29302
|
}
|
|
29913
29303
|
return results;
|
|
29914
29304
|
}
|
|
29915
|
-
var DEFAULT_PRESET = "
|
|
29305
|
+
var DEFAULT_PRESET = "minimal";
|
|
29916
29306
|
async function bootstrapManifest(vaultPath, preset) {
|
|
29917
29307
|
const installedFiles = await scanInstalledAssets(vaultPath);
|
|
29918
29308
|
await writeManifest(vaultPath, preset ?? DEFAULT_PRESET, installedFiles, "0.0.0");
|
|
@@ -29933,7 +29323,7 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
|
|
|
29933
29323
|
const installed = new Set(manifest.infrastructure[key]);
|
|
29934
29324
|
const shippedPaths = new Set(shipped.map((s) => s.relativePath));
|
|
29935
29325
|
for (const entry of shipped) {
|
|
29936
|
-
const onDisk = fs.existsSync(
|
|
29326
|
+
const onDisk = fs.existsSync(path10.join(vaultPath, entry.relativePath));
|
|
29937
29327
|
items.push({
|
|
29938
29328
|
file: entry.relativePath,
|
|
29939
29329
|
action: onDisk ? "update" : "add",
|
|
@@ -29956,23 +29346,103 @@ function buildUpgradePlan(vaultPath, manifest, packageAssets) {
|
|
|
29956
29346
|
items
|
|
29957
29347
|
};
|
|
29958
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
|
+
}
|
|
29959
29423
|
function resolveAssetsDir2() {
|
|
29960
|
-
const
|
|
29961
|
-
const
|
|
29962
|
-
|
|
29963
|
-
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");
|
|
29964
29427
|
if (fs.existsSync(distAssets))
|
|
29965
29428
|
return distAssets;
|
|
29966
|
-
|
|
29429
|
+
if (fs.existsSync(srcAssets))
|
|
29430
|
+
return srcAssets;
|
|
29431
|
+
if (fs.existsSync(devAssets))
|
|
29432
|
+
return devAssets;
|
|
29433
|
+
return distAssets;
|
|
29967
29434
|
}
|
|
29968
29435
|
function resolveSkillsDir() {
|
|
29969
|
-
const
|
|
29970
|
-
const
|
|
29971
|
-
|
|
29972
|
-
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");
|
|
29973
29439
|
if (fs.existsSync(distSkills))
|
|
29974
29440
|
return distSkills;
|
|
29975
|
-
|
|
29441
|
+
if (fs.existsSync(srcSkills))
|
|
29442
|
+
return srcSkills;
|
|
29443
|
+
if (fs.existsSync(devSkills))
|
|
29444
|
+
return devSkills;
|
|
29445
|
+
return distSkills;
|
|
29976
29446
|
}
|
|
29977
29447
|
function resolvePackageAssets(preset) {
|
|
29978
29448
|
const assetsDir = resolveAssetsDir2();
|
|
@@ -29982,14 +29452,14 @@ function resolvePackageAssets(preset) {
|
|
|
29982
29452
|
const commands = [];
|
|
29983
29453
|
const obsidianConfig = [];
|
|
29984
29454
|
const templates = [];
|
|
29985
|
-
const obsidianSkillsDir =
|
|
29455
|
+
const obsidianSkillsDir = path10.join(assetsDir, "obsidian-skills");
|
|
29986
29456
|
if (fs.existsSync(obsidianSkillsDir)) {
|
|
29987
29457
|
for (const file2 of fs.readdirSync(obsidianSkillsDir)) {
|
|
29988
29458
|
if (file2.endsWith(".md")) {
|
|
29989
29459
|
const skillName = file2.replace(/\.md$/, "");
|
|
29990
29460
|
skills.push({
|
|
29991
29461
|
relativePath: `.opencode/skills/${skillName}/SKILL.md`,
|
|
29992
|
-
sourcePath:
|
|
29462
|
+
sourcePath: path10.join(obsidianSkillsDir, file2)
|
|
29993
29463
|
});
|
|
29994
29464
|
}
|
|
29995
29465
|
}
|
|
@@ -29999,15 +29469,15 @@ function resolvePackageAssets(preset) {
|
|
|
29999
29469
|
if (file2.endsWith(".md")) {
|
|
30000
29470
|
commands.push({
|
|
30001
29471
|
relativePath: `.opencode/commands/${file2}`,
|
|
30002
|
-
sourcePath:
|
|
29472
|
+
sourcePath: path10.join(skillsDir, file2)
|
|
30003
29473
|
});
|
|
30004
29474
|
}
|
|
30005
29475
|
}
|
|
30006
29476
|
}
|
|
30007
|
-
const obsidianSrcDir =
|
|
29477
|
+
const obsidianSrcDir = path10.join(commonDir, "obsidian");
|
|
30008
29478
|
if (fs.existsSync(obsidianSrcDir)) {
|
|
30009
29479
|
for (const file2 of OBSIDIAN_CONFIG_FILES) {
|
|
30010
|
-
const srcPath =
|
|
29480
|
+
const srcPath = path10.join(obsidianSrcDir, file2);
|
|
30011
29481
|
if (fs.existsSync(srcPath)) {
|
|
30012
29482
|
obsidianConfig.push({
|
|
30013
29483
|
relativePath: `.obsidian/${file2}`,
|
|
@@ -30016,26 +29486,26 @@ function resolvePackageAssets(preset) {
|
|
|
30016
29486
|
}
|
|
30017
29487
|
}
|
|
30018
29488
|
}
|
|
30019
|
-
const commonTemplatesDir =
|
|
29489
|
+
const commonTemplatesDir = path10.join(commonDir, "templates");
|
|
30020
29490
|
if (fs.existsSync(commonTemplatesDir)) {
|
|
30021
29491
|
for (const file2 of fs.readdirSync(commonTemplatesDir)) {
|
|
30022
29492
|
if (file2.endsWith(".md")) {
|
|
30023
29493
|
templates.push({
|
|
30024
29494
|
relativePath: `Knowledge/templates/${file2}`,
|
|
30025
|
-
sourcePath:
|
|
29495
|
+
sourcePath: path10.join(commonTemplatesDir, file2)
|
|
30026
29496
|
});
|
|
30027
29497
|
}
|
|
30028
29498
|
}
|
|
30029
29499
|
}
|
|
30030
29500
|
try {
|
|
30031
29501
|
const { presetsDir } = loadPreset(preset);
|
|
30032
|
-
const presetTemplatesDir =
|
|
29502
|
+
const presetTemplatesDir = path10.join(presetsDir, preset, "templates");
|
|
30033
29503
|
if (fs.existsSync(presetTemplatesDir)) {
|
|
30034
29504
|
for (const file2 of fs.readdirSync(presetTemplatesDir)) {
|
|
30035
29505
|
if (file2.endsWith(".md")) {
|
|
30036
29506
|
templates.push({
|
|
30037
29507
|
relativePath: `Knowledge/templates/${file2}`,
|
|
30038
|
-
sourcePath:
|
|
29508
|
+
sourcePath: path10.join(presetTemplatesDir, file2)
|
|
30039
29509
|
});
|
|
30040
29510
|
}
|
|
30041
29511
|
}
|
|
@@ -30048,7 +29518,7 @@ async function upgradeVault(vaultPath, options2) {
|
|
|
30048
29518
|
const { preset, dryRun = false, force = false } = options2 ?? {};
|
|
30049
29519
|
const detectedPath = detectVaultContext(vaultPath);
|
|
30050
29520
|
if (!detectedPath) {
|
|
30051
|
-
throw new Error(`No BYOAO vault detected at "${vaultPath}". Expected .obsidian/ and AGENTS.md
|
|
29521
|
+
throw new Error(`No BYOAO vault detected at "${vaultPath}". Expected .obsidian/ and AGENTS.md.`);
|
|
30052
29522
|
}
|
|
30053
29523
|
let manifest = await readManifest(vaultPath);
|
|
30054
29524
|
if (!manifest) {
|
|
@@ -30067,14 +29537,21 @@ async function upgradeVault(vaultPath, options2) {
|
|
|
30067
29537
|
dryRun
|
|
30068
29538
|
};
|
|
30069
29539
|
}
|
|
30070
|
-
const legacyAgentMd =
|
|
30071
|
-
const newAgentsMd =
|
|
29540
|
+
const legacyAgentMd = path10.join(vaultPath, "AGENT.md");
|
|
29541
|
+
const newAgentsMd = path10.join(vaultPath, "AGENTS.md");
|
|
30072
29542
|
if (!dryRun && await fs.pathExists(legacyAgentMd) && !await fs.pathExists(newAgentsMd)) {
|
|
30073
29543
|
await fs.rename(legacyAgentMd, newAgentsMd);
|
|
30074
29544
|
}
|
|
29545
|
+
if (!dryRun) {
|
|
29546
|
+
await migrateV1ToV2Infrastructure(vaultPath);
|
|
29547
|
+
}
|
|
30075
29548
|
const effectivePreset = preset ?? manifest.preset;
|
|
30076
29549
|
const packageAssets = resolvePackageAssets(effectivePreset);
|
|
30077
|
-
|
|
29550
|
+
let plan = buildUpgradePlan(vaultPath, manifest, packageAssets);
|
|
29551
|
+
plan = {
|
|
29552
|
+
...plan,
|
|
29553
|
+
items: mergeForcedDeprecatedIntoPlan(plan.items, await collectV1DeprecatedInfrastructureItems(vaultPath))
|
|
29554
|
+
};
|
|
30078
29555
|
const added = [];
|
|
30079
29556
|
const updated = [];
|
|
30080
29557
|
const deprecated = [];
|
|
@@ -30091,8 +29568,8 @@ async function upgradeVault(vaultPath, options2) {
|
|
|
30091
29568
|
if (item.action === "add" || item.action === "update") {
|
|
30092
29569
|
const source = sourceMap.get(item.file);
|
|
30093
29570
|
if (source) {
|
|
30094
|
-
const dest =
|
|
30095
|
-
await fs.ensureDir(
|
|
29571
|
+
const dest = path10.join(vaultPath, item.file);
|
|
29572
|
+
await fs.ensureDir(path10.dirname(dest));
|
|
30096
29573
|
await fs.copy(source, dest, { overwrite: true });
|
|
30097
29574
|
if (item.action === "add") {
|
|
30098
29575
|
added.push(item.file);
|
|
@@ -30187,17 +29664,17 @@ var byoao_vault_upgrade = tool({
|
|
|
30187
29664
|
});
|
|
30188
29665
|
|
|
30189
29666
|
// dist/tools/mcp-auth.js
|
|
30190
|
-
import { spawn, execSync as
|
|
30191
|
-
import
|
|
29667
|
+
import { spawn, execSync as execSync3 } from "node:child_process";
|
|
29668
|
+
import path11 from "node:path";
|
|
30192
29669
|
import os4 from "node:os";
|
|
30193
29670
|
function findOpencodeBinary() {
|
|
30194
29671
|
const candidates = [
|
|
30195
|
-
|
|
29672
|
+
path11.join(os4.homedir(), ".opencode/bin/opencode"),
|
|
30196
29673
|
"/usr/local/bin/opencode"
|
|
30197
29674
|
];
|
|
30198
29675
|
for (const p of candidates) {
|
|
30199
29676
|
try {
|
|
30200
|
-
|
|
29677
|
+
execSync3(`test -x "${p}"`, { stdio: "pipe" });
|
|
30201
29678
|
return p;
|
|
30202
29679
|
} catch {
|
|
30203
29680
|
}
|
|
@@ -30295,10 +29772,13 @@ The user may need to:
|
|
|
30295
29772
|
}
|
|
30296
29773
|
});
|
|
30297
29774
|
|
|
29775
|
+
// dist/hooks/system-transform.js
|
|
29776
|
+
import path12 from "node:path";
|
|
29777
|
+
|
|
30298
29778
|
// dist/lib/logger.js
|
|
30299
29779
|
import { join } from "node:path";
|
|
30300
29780
|
import { homedir } from "node:os";
|
|
30301
|
-
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";
|
|
30302
29782
|
var LOG_DIR = process.env.BYOAO_LOG_DIR || join(homedir(), ".byoao", "logs");
|
|
30303
29783
|
var LOG_FILE = join(LOG_DIR, "error.log");
|
|
30304
29784
|
var MAX_LOG_SIZE = 512 * 1024;
|
|
@@ -30341,7 +29821,7 @@ async function ensureLogDir() {
|
|
|
30341
29821
|
}
|
|
30342
29822
|
async function rotateIfNeeded() {
|
|
30343
29823
|
try {
|
|
30344
|
-
const s = await
|
|
29824
|
+
const s = await stat2(LOG_FILE);
|
|
30345
29825
|
if (s.size >= MAX_LOG_SIZE) {
|
|
30346
29826
|
await rename3(LOG_FILE, ROTATED_FILE);
|
|
30347
29827
|
}
|
|
@@ -30372,6 +29852,20 @@ async function log(level, source, message, options2) {
|
|
|
30372
29852
|
}
|
|
30373
29853
|
|
|
30374
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
|
+
}
|
|
30375
29869
|
async function buildMcpAuthGuidance() {
|
|
30376
29870
|
try {
|
|
30377
29871
|
const config2 = await readOpencodeConfig();
|
|
@@ -30409,6 +29903,31 @@ async function buildMcpAuthGuidance() {
|
|
|
30409
29903
|
}
|
|
30410
29904
|
}
|
|
30411
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
|
+
}
|
|
30412
29931
|
const mcpGuidance = await buildMcpAuthGuidance();
|
|
30413
29932
|
if (mcpGuidance) {
|
|
30414
29933
|
output.system.push(mcpGuidance);
|
|
@@ -30418,15 +29937,15 @@ async function systemTransformHook(_input, output) {
|
|
|
30418
29937
|
// dist/hooks/idle-suggestions.js
|
|
30419
29938
|
function getIdleSuggestion() {
|
|
30420
29939
|
const suggestions = [
|
|
30421
|
-
"Tip: run /
|
|
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",
|
|
30422
29943
|
"Tip: run /trace to see how an idea evolved over time",
|
|
30423
|
-
"Tip: run /emerge to discover patterns across your notes",
|
|
30424
29944
|
"Tip: run /connect to bridge two topics using your vault's link graph",
|
|
30425
29945
|
"Tip: run /ideas to generate actionable insights from your vault",
|
|
30426
29946
|
"Tip: run /challenge to pressure-test a belief against your own notes",
|
|
30427
29947
|
"Tip: run /drift to compare intentions vs actions over the past month",
|
|
30428
|
-
"Tip: run /diagnose to check
|
|
30429
|
-
"Tip: run /explain to document a codebase system in your vault"
|
|
29948
|
+
"Tip: run /diagnose to check overall vault health"
|
|
30430
29949
|
];
|
|
30431
29950
|
const idx = (/* @__PURE__ */ new Date()).getMinutes() % suggestions.length;
|
|
30432
29951
|
return suggestions[idx];
|
|
@@ -30437,15 +29956,9 @@ var BYOAOPlugin = async (ctx) => {
|
|
|
30437
29956
|
const { client } = ctx;
|
|
30438
29957
|
const tools = {
|
|
30439
29958
|
byoao_init_vault,
|
|
30440
|
-
byoao_add_person,
|
|
30441
|
-
byoao_add_project,
|
|
30442
|
-
byoao_add_glossary_term,
|
|
30443
29959
|
byoao_vault_status,
|
|
30444
29960
|
byoao_vault_doctor,
|
|
30445
29961
|
byoao_switch_provider,
|
|
30446
|
-
byoao_search_vault,
|
|
30447
|
-
byoao_note_read,
|
|
30448
|
-
byoao_graph_health,
|
|
30449
29962
|
byoao_vault_upgrade,
|
|
30450
29963
|
byoao_mcp_auth
|
|
30451
29964
|
};
|