@jayjiang/byoao 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/__tests__/plugin-config.test.js +11 -8
  2. package/dist/__tests__/plugin-config.test.js.map +1 -1
  3. package/dist/cli/cli-program.js +253 -157
  4. package/dist/cli/cli-program.js.map +1 -1
  5. package/dist/cli/installer.js +4 -11
  6. package/dist/cli/installer.js.map +1 -1
  7. package/dist/hooks/idle-suggestions.js +3 -3
  8. package/dist/hooks/idle-suggestions.js.map +1 -1
  9. package/dist/hooks/system-transform.js +37 -14
  10. package/dist/hooks/system-transform.js.map +1 -1
  11. package/dist/index.js +4 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/plugin-config.js +5 -2
  14. package/dist/plugin-config.js.map +1 -1
  15. package/dist/tools/add-glossary-term.js +2 -0
  16. package/dist/tools/add-glossary-term.js.map +1 -1
  17. package/dist/tools/add-person.js +21 -0
  18. package/dist/tools/add-person.js.map +1 -0
  19. package/dist/tools/init-vault.js +11 -9
  20. package/dist/tools/init-vault.js.map +1 -1
  21. package/dist/tools/vault-upgrade.js +77 -0
  22. package/dist/tools/vault-upgrade.js.map +1 -0
  23. package/dist/vault/__tests__/create.test.js +105 -39
  24. package/dist/vault/__tests__/create.test.js.map +1 -1
  25. package/dist/vault/__tests__/glossary.test.js +25 -14
  26. package/dist/vault/__tests__/glossary.test.js.map +1 -1
  27. package/dist/vault/__tests__/manifest.test.js +76 -0
  28. package/dist/vault/__tests__/manifest.test.js.map +1 -0
  29. package/dist/vault/__tests__/member.test.js +2 -4
  30. package/dist/vault/__tests__/member.test.js.map +1 -1
  31. package/dist/vault/__tests__/upgrade.test.js +181 -0
  32. package/dist/vault/__tests__/upgrade.test.js.map +1 -0
  33. package/dist/vault/create.js +211 -146
  34. package/dist/vault/create.js.map +1 -1
  35. package/dist/vault/doctor.js +1 -1
  36. package/dist/vault/doctor.js.map +1 -1
  37. package/dist/vault/glossary.js +8 -14
  38. package/dist/vault/glossary.js.map +1 -1
  39. package/dist/vault/manifest.js +68 -0
  40. package/dist/vault/manifest.js.map +1 -0
  41. package/dist/vault/member.js +1 -1
  42. package/dist/vault/member.js.map +1 -1
  43. package/dist/vault/project.js +1 -1
  44. package/dist/vault/project.js.map +1 -1
  45. package/dist/vault/upgrade.js +266 -0
  46. package/dist/vault/upgrade.js.map +1 -0
  47. package/dist/vault/vault-detect.js +30 -0
  48. package/dist/vault/vault-detect.js.map +1 -1
  49. package/package.json +3 -1
  50. package/src/assets/presets/common/AGENT.md.hbs +34 -67
  51. package/src/assets/presets/common/Glossary.md.hbs +7 -35
  52. package/src/assets/presets/common/Start Here.md.hbs +32 -64
  53. package/src/assets/presets/minimal/preset.json +28 -0
  54. package/src/skills/{vault-doctor.md → diagnose.md} +12 -12
  55. package/src/skills/{system-explainer.md → explain.md} +8 -8
  56. package/src/skills/weave.md +240 -0
  57. package/src/assets/web-clipper/confluence-page.json +0 -63
  58. package/src/assets/web-clipper/general-article.json +0 -53
  59. package/src/assets/web-clipper/jira-issue.json +0 -68
  60. package/src/assets/web-clipper/meeting-notes.json +0 -53
  61. package/src/skills/enrich-document.md +0 -52
@@ -1,31 +1,25 @@
1
1
  import fs from "fs-extra";
2
2
  import path from "node:path";
3
3
  export async function addGlossaryTerm(input) {
4
- const { vaultPath, term, definition } = input;
4
+ const { vaultPath, term, definition, domain } = input;
5
5
  const glossaryPath = path.join(vaultPath, "Knowledge/Glossary.md");
6
6
  if (!(await fs.pathExists(glossaryPath))) {
7
7
  throw new Error(`Glossary not found at: ${glossaryPath}`);
8
8
  }
9
9
  let content = await fs.readFile(glossaryPath, "utf-8");
10
- // Find the Core Terms table and append a new row
11
- const newRow = `| **${term}** | ${definition} |`;
12
- // Find the last row in the Core Terms table (after |------|-----------|)
13
- const tableMatch = content.match(/(## Core Terms\n\n\| Term \| Definition \|\n\|------|-----------\|\n)([\s\S]*?)(\n\n---|\n\n##|\n*$)/);
10
+ const newRow = `| **${term}** | ${definition} | ${domain ?? ""} |`;
11
+ // Find the glossary table (Term | Definition | Domain)
12
+ const tableMatch = content.match(/(\| Term \| Definition \| Domain \|\n\|------\|-----------|--------\|\n)([\s\S]*?)(\n*$)/);
14
13
  if (tableMatch) {
15
- const [fullMatch, tableHeader, existingRows, tableEnd] = tableMatch;
14
+ const [fullMatch, tableHeader, existingRows, trailing] = tableMatch;
16
15
  const updatedRows = existingRows.trim()
17
16
  ? `${existingRows.trim()}\n${newRow}`
18
17
  : newRow;
19
- content = content.replace(fullMatch, `${tableHeader}${updatedRows}\n${tableEnd}`);
18
+ content = content.replace(fullMatch, `${tableHeader}${updatedRows}\n`);
20
19
  }
21
20
  else {
22
- // Fallback: just append before the "How to Add" section
23
- if (content.includes("## How to Add a New Term")) {
24
- content = content.replace("## How to Add a New Term", `${newRow}\n\n## How to Add a New Term`);
25
- }
26
- else {
27
- content += `\n${newRow}\n`;
28
- }
21
+ // Fallback: append to end of file
22
+ content = content.trimEnd() + `\n${newRow}\n`;
29
23
  }
30
24
  await fs.writeFile(glossaryPath, content);
31
25
  return { glossaryPath, termAdded: term };
@@ -1 +1 @@
1
- {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../src/vault/glossary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAQ7B,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAA2B;IAE3B,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAE9C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;IACnE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEvD,iDAAiD;IACjD,MAAM,MAAM,GAAG,OAAO,IAAI,QAAQ,UAAU,IAAI,CAAC;IAEjD,yEAAyE;IACzE,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAC9B,sGAAsG,CACvG,CAAC;IAEF,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAG,UAAU,CAAC;QACpE,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE;YACrC,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE;YACrC,CAAC,CAAC,MAAM,CAAC;QACX,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,SAAS,EACT,GAAG,WAAW,GAAG,WAAW,KAAK,QAAQ,EAAE,CAC5C,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,wDAAwD;QACxD,IAAI,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;YACjD,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,0BAA0B,EAC1B,GAAG,MAAM,8BAA8B,CACxC,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,KAAK,MAAM,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAE1C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../src/vault/glossary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAQ7B,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAA2B;IAE3B,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAEtD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;IACnE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG,OAAO,IAAI,QAAQ,UAAU,MAAM,MAAM,IAAI,EAAE,IAAI,CAAC;IAEnE,uDAAuD;IACvD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAC9B,0FAA0F,CAC3F,CAAC;IAEF,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAG,UAAU,CAAC;QACpE,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE;YACrC,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE;YACrC,CAAC,CAAC,MAAM,CAAC;QACX,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,SAAS,EACT,GAAG,WAAW,GAAG,WAAW,IAAI,CACjC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,kCAAkC;QAClC,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,KAAK,MAAM,IAAI,CAAC;IAChD,CAAC;IAED,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAE1C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,68 @@
1
+ import fs from "fs-extra";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ import { createRequire } from "node:module";
5
+ const require = createRequire(import.meta.url);
6
+ const PKG_VERSION = require("../../package.json").version;
7
+ // ── Schema ──────────────────────────────────────────────────────
8
+ const InfrastructureSchema = z.object({
9
+ skills: z.array(z.string()).default([]),
10
+ commands: z.array(z.string()).default([]),
11
+ obsidianConfig: z.array(z.string()).default([]),
12
+ templates: z.array(z.string()).default([]),
13
+ });
14
+ export const ManifestSchema = z.object({
15
+ version: z.string(),
16
+ preset: z.string(),
17
+ createdAt: z.string(),
18
+ updatedAt: z.string(),
19
+ infrastructure: InfrastructureSchema,
20
+ });
21
+ // ── Constants ───────────────────────────────────────────────────
22
+ const MANIFEST_DIR = ".byoao";
23
+ const MANIFEST_FILE = "manifest.json";
24
+ // ── Functions ───────────────────────────────────────────────────
25
+ function today() {
26
+ return new Date().toISOString().slice(0, 10);
27
+ }
28
+ function manifestPath(vaultPath) {
29
+ return path.join(vaultPath, MANIFEST_DIR, MANIFEST_FILE);
30
+ }
31
+ /** Read and validate the manifest. Returns null if missing or invalid. */
32
+ export async function readManifest(vaultPath) {
33
+ const mp = manifestPath(vaultPath);
34
+ if (!(await fs.pathExists(mp)))
35
+ return null;
36
+ try {
37
+ const raw = await fs.readJson(mp);
38
+ return ManifestSchema.parse(raw);
39
+ }
40
+ catch {
41
+ /* Corrupt JSON or schema mismatch — treat as missing */
42
+ return null;
43
+ }
44
+ }
45
+ /** Write the manifest to .byoao/manifest.json. */
46
+ export async function writeManifest(vaultPath, preset, installedFiles, versionOverride) {
47
+ const mp = manifestPath(vaultPath);
48
+ const existing = await readManifest(vaultPath);
49
+ const manifest = {
50
+ version: versionOverride ?? PKG_VERSION,
51
+ preset,
52
+ createdAt: existing?.createdAt ?? today(),
53
+ updatedAt: today(),
54
+ infrastructure: {
55
+ skills: installedFiles.skills,
56
+ commands: installedFiles.commands,
57
+ obsidianConfig: installedFiles.obsidianConfig,
58
+ templates: installedFiles.templates,
59
+ },
60
+ };
61
+ await fs.ensureDir(path.dirname(mp));
62
+ await fs.writeJson(mp, manifest, { spaces: 2 });
63
+ }
64
+ /** Exported for use by upgrade module to get package version. */
65
+ export function getPackageVersion() {
66
+ return PKG_VERSION;
67
+ }
68
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/vault/manifest.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ tags: [person]
39
39
  await fs.writeFile(teamIndexPath, teamContent);
40
40
  }
41
41
  // 3. Update AGENT.md wikilinks
42
- for (const agentFile of ["AGENT.md", "CLAUDE.md"]) {
42
+ for (const agentFile of ["AGENT.md"]) {
43
43
  const agentPath = path.join(vaultPath, agentFile);
44
44
  if (await fs.pathExists(agentPath)) {
45
45
  let agentContent = await fs.readFile(agentPath, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"member.js","sourceRoot":"","sources":["../../src/vault/member.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"member.js","sourceRoot":"","sources":["../../src/vault/member.ts"],"names":[],"mappings":"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"}
@@ -47,7 +47,7 @@ ${description}
47
47
  }
48
48
  }
49
49
  // 3. Update AGENT.md wikilinks
50
- for (const agentFile of ["AGENT.md", "CLAUDE.md"]) {
50
+ for (const agentFile of ["AGENT.md"]) {
51
51
  const agentPath = path.join(vaultPath, agentFile);
52
52
  if (await fs.pathExists(agentPath)) {
53
53
  let agentContent = await fs.readFile(agentPath, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/vault/project.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/vault/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,266 @@
1
+ import fs from "fs-extra";
2
+ import path from "node:path";
3
+ import { readManifest, writeManifest, getPackageVersion, } from "./manifest.js";
4
+ import { loadPreset, getCommonDir } from "./preset.js";
5
+ import { detectVaultContext } from "./vault-detect.js";
6
+ // ── Constants ───────────────────────────────────────────────────
7
+ const OBSIDIAN_CONFIG_FILES = [
8
+ "core-plugins.json",
9
+ "daily-notes.json",
10
+ "templates.json",
11
+ ];
12
+ // ── Scanning ────────────────────────────────────────────────────
13
+ /** Scan vault for installed infrastructure files. Returns relative paths. */
14
+ export async function scanInstalledAssets(vaultPath) {
15
+ const skills = await scanDir(vaultPath, ".opencode/skills", ".md");
16
+ const commands = await scanDir(vaultPath, ".opencode/commands", ".md");
17
+ const templates = await scanDir(vaultPath, "Knowledge/templates", ".md");
18
+ const obsidianConfig = [];
19
+ for (const file of OBSIDIAN_CONFIG_FILES) {
20
+ const abs = path.join(vaultPath, ".obsidian", file);
21
+ if (await fs.pathExists(abs)) {
22
+ obsidianConfig.push(`.obsidian/${file}`);
23
+ }
24
+ }
25
+ return { skills, commands, obsidianConfig, templates };
26
+ }
27
+ async function scanDir(vaultPath, relDir, ext) {
28
+ const absDir = path.join(vaultPath, relDir);
29
+ if (!(await fs.pathExists(absDir)))
30
+ return [];
31
+ const files = await fs.readdir(absDir);
32
+ return files
33
+ .filter((f) => f.endsWith(ext))
34
+ .map((f) => `${relDir}/${f}`);
35
+ }
36
+ // ── Bootstrap ───────────────────────────────────────────────────
37
+ const DEFAULT_PRESET = "pm-tpm";
38
+ /** Bootstrap a manifest for vaults created before the manifest existed. */
39
+ export async function bootstrapManifest(vaultPath, preset) {
40
+ const installedFiles = await scanInstalledAssets(vaultPath);
41
+ await writeManifest(vaultPath, preset ?? DEFAULT_PRESET, installedFiles, "0.0.0");
42
+ const manifest = await readManifest(vaultPath);
43
+ return manifest;
44
+ }
45
+ // ── Plan Building ───────────────────────────────────────────────
46
+ /** Build an upgrade plan by comparing package assets against vault state. */
47
+ export function buildUpgradePlan(vaultPath, manifest, packageAssets) {
48
+ const items = [];
49
+ const pkgVersion = getPackageVersion();
50
+ const categories = [
51
+ { key: "skills", category: "skills" },
52
+ { key: "commands", category: "commands" },
53
+ { key: "obsidianConfig", category: "obsidianConfig" },
54
+ { key: "templates", category: "templates" },
55
+ ];
56
+ for (const { key, category } of categories) {
57
+ const shipped = packageAssets[key];
58
+ const installed = new Set(manifest.infrastructure[key]);
59
+ const shippedPaths = new Set(shipped.map((s) => s.relativePath));
60
+ for (const entry of shipped) {
61
+ const onDisk = fs.existsSync(path.join(vaultPath, entry.relativePath));
62
+ items.push({
63
+ file: entry.relativePath,
64
+ action: onDisk ? "update" : "add",
65
+ category,
66
+ });
67
+ }
68
+ for (const installedPath of installed) {
69
+ if (!shippedPaths.has(installedPath)) {
70
+ items.push({
71
+ file: installedPath,
72
+ action: "deprecated",
73
+ category,
74
+ });
75
+ }
76
+ }
77
+ }
78
+ return {
79
+ fromVersion: manifest.version,
80
+ toVersion: pkgVersion,
81
+ items,
82
+ };
83
+ }
84
+ // ── Asset Resolution ────────────────────────────────────────────
85
+ function resolveAssetsDir() {
86
+ const srcAssets = path.resolve(import.meta.dirname, "..", "assets");
87
+ const distAssets = path.resolve(import.meta.dirname, "..", "..", "src", "assets");
88
+ if (fs.existsSync(srcAssets))
89
+ return srcAssets;
90
+ if (fs.existsSync(distAssets))
91
+ return distAssets;
92
+ return srcAssets;
93
+ }
94
+ function resolveSkillsDir() {
95
+ const srcSkills = path.resolve(import.meta.dirname, "..", "skills");
96
+ const distSkills = path.resolve(import.meta.dirname, "..", "..", "src", "skills");
97
+ if (fs.existsSync(srcSkills))
98
+ return srcSkills;
99
+ if (fs.existsSync(distSkills))
100
+ return distSkills;
101
+ return srcSkills;
102
+ }
103
+ /** Resolve package assets for a given preset. */
104
+ function resolvePackageAssets(preset) {
105
+ const assetsDir = resolveAssetsDir();
106
+ const skillsDir = resolveSkillsDir();
107
+ const commonDir = getCommonDir();
108
+ const skills = [];
109
+ const commands = [];
110
+ const obsidianConfig = [];
111
+ const templates = [];
112
+ // 1. Obsidian skills → .opencode/skills/
113
+ const obsidianSkillsDir = path.join(assetsDir, "obsidian-skills");
114
+ if (fs.existsSync(obsidianSkillsDir)) {
115
+ for (const file of fs.readdirSync(obsidianSkillsDir)) {
116
+ if (file.endsWith(".md")) {
117
+ skills.push({
118
+ relativePath: `.opencode/skills/${file}`,
119
+ sourcePath: path.join(obsidianSkillsDir, file),
120
+ });
121
+ }
122
+ }
123
+ }
124
+ // 2. BYOAO commands (src/skills/) → .opencode/commands/
125
+ if (fs.existsSync(skillsDir)) {
126
+ for (const file of fs.readdirSync(skillsDir)) {
127
+ if (file.endsWith(".md")) {
128
+ commands.push({
129
+ relativePath: `.opencode/commands/${file}`,
130
+ sourcePath: path.join(skillsDir, file),
131
+ });
132
+ }
133
+ }
134
+ }
135
+ // 3. Obsidian config from common
136
+ const obsidianSrcDir = path.join(commonDir, "obsidian");
137
+ if (fs.existsSync(obsidianSrcDir)) {
138
+ for (const file of OBSIDIAN_CONFIG_FILES) {
139
+ const srcPath = path.join(obsidianSrcDir, file);
140
+ if (fs.existsSync(srcPath)) {
141
+ obsidianConfig.push({
142
+ relativePath: `.obsidian/${file}`,
143
+ sourcePath: srcPath,
144
+ });
145
+ }
146
+ }
147
+ }
148
+ // 4. Templates: common + preset
149
+ const commonTemplatesDir = path.join(commonDir, "templates");
150
+ if (fs.existsSync(commonTemplatesDir)) {
151
+ for (const file of fs.readdirSync(commonTemplatesDir)) {
152
+ if (file.endsWith(".md")) {
153
+ templates.push({
154
+ relativePath: `Knowledge/templates/${file}`,
155
+ sourcePath: path.join(commonTemplatesDir, file),
156
+ });
157
+ }
158
+ }
159
+ }
160
+ try {
161
+ const { presetsDir } = loadPreset(preset);
162
+ const presetTemplatesDir = path.join(presetsDir, preset, "templates");
163
+ if (fs.existsSync(presetTemplatesDir)) {
164
+ for (const file of fs.readdirSync(presetTemplatesDir)) {
165
+ if (file.endsWith(".md")) {
166
+ templates.push({
167
+ relativePath: `Knowledge/templates/${file}`,
168
+ sourcePath: path.join(presetTemplatesDir, file),
169
+ });
170
+ }
171
+ }
172
+ }
173
+ }
174
+ catch {
175
+ /* Preset not found — use common templates only */
176
+ }
177
+ return { skills, commands, obsidianConfig, templates };
178
+ }
179
+ // ── Upgrade Execution ───────────────────────────────────────────
180
+ /** Upgrade a BYOAO vault's infrastructure files to the current package version. */
181
+ export async function upgradeVault(vaultPath, options) {
182
+ const { preset, dryRun = false, force = false } = options ?? {};
183
+ // 1. Validate this is a BYOAO vault
184
+ const detectedPath = detectVaultContext(vaultPath);
185
+ if (!detectedPath) {
186
+ throw new Error(`No BYOAO vault detected at "${vaultPath}". ` +
187
+ "Expected .obsidian/ and AGENT.md or Knowledge/Glossary.md.");
188
+ }
189
+ // 2. Read or bootstrap manifest
190
+ let manifest = await readManifest(vaultPath);
191
+ if (!manifest) {
192
+ manifest = await bootstrapManifest(vaultPath, preset);
193
+ }
194
+ const pkgVersion = getPackageVersion();
195
+ const fromVersion = manifest.version;
196
+ // 3. Check if upgrade needed
197
+ if (fromVersion === pkgVersion && !force) {
198
+ return {
199
+ fromVersion,
200
+ toVersion: pkgVersion,
201
+ added: [],
202
+ updated: [],
203
+ deprecated: [],
204
+ errors: [],
205
+ dryRun,
206
+ };
207
+ }
208
+ // 4. Resolve package assets and build plan
209
+ const effectivePreset = preset ?? manifest.preset;
210
+ const packageAssets = resolvePackageAssets(effectivePreset);
211
+ const plan = buildUpgradePlan(vaultPath, manifest, packageAssets);
212
+ // 5. Execute plan (or dry run)
213
+ const added = [];
214
+ const updated = [];
215
+ const deprecated = [];
216
+ const errors = [];
217
+ if (!dryRun) {
218
+ // Build lookup from relativePath → sourcePath
219
+ const sourceMap = new Map();
220
+ for (const category of ["skills", "commands", "obsidianConfig", "templates"]) {
221
+ for (const entry of packageAssets[category]) {
222
+ sourceMap.set(entry.relativePath, entry.sourcePath);
223
+ }
224
+ }
225
+ for (const item of plan.items) {
226
+ try {
227
+ if (item.action === "add" || item.action === "update") {
228
+ const source = sourceMap.get(item.file);
229
+ if (source) {
230
+ const dest = path.join(vaultPath, item.file);
231
+ await fs.ensureDir(path.dirname(dest));
232
+ await fs.copy(source, dest, { overwrite: true });
233
+ if (item.action === "add") {
234
+ added.push(item.file);
235
+ }
236
+ else {
237
+ updated.push(item.file);
238
+ }
239
+ }
240
+ }
241
+ else if (item.action === "deprecated") {
242
+ deprecated.push(item.file);
243
+ }
244
+ }
245
+ catch (err) {
246
+ errors.push({
247
+ file: item.file,
248
+ error: err instanceof Error ? err.message : String(err),
249
+ });
250
+ }
251
+ }
252
+ // 6. Update manifest with new version and current file list
253
+ const installedFiles = await scanInstalledAssets(vaultPath);
254
+ await writeManifest(vaultPath, effectivePreset, installedFiles);
255
+ }
256
+ return {
257
+ fromVersion,
258
+ toVersion: pkgVersion,
259
+ added,
260
+ updated,
261
+ deprecated,
262
+ errors,
263
+ dryRun,
264
+ };
265
+ }
266
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/vault/upgrade.ts"],"names":[],"mappings":"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"}
@@ -26,4 +26,34 @@ export function detectVaultContext(dir) {
26
26
  }
27
27
  return null;
28
28
  }
29
+ /**
30
+ * Determine the init mode for a target path:
31
+ * - "obsidian-vault": .obsidian/ already exists — adopt with safety
32
+ * - "existing": folder has .md files but no .obsidian/
33
+ * - "fresh": empty or non-existent directory
34
+ */
35
+ export function detectInitMode(targetPath) {
36
+ if (!fs.existsSync(targetPath))
37
+ return "fresh";
38
+ const hasObsidian = fs.existsSync(path.join(targetPath, ".obsidian"));
39
+ if (hasObsidian)
40
+ return "obsidian-vault";
41
+ // Check for existing .md files (non-recursive, just top-level + one depth)
42
+ try {
43
+ const entries = fs.readdirSync(targetPath, { withFileTypes: true });
44
+ for (const entry of entries) {
45
+ if (entry.isFile() && entry.name.endsWith(".md"))
46
+ return "existing";
47
+ if (entry.isDirectory() && !entry.name.startsWith(".")) {
48
+ const subEntries = fs.readdirSync(path.join(targetPath, entry.name));
49
+ if (subEntries.some((f) => f.endsWith(".md")))
50
+ return "existing";
51
+ }
52
+ }
53
+ }
54
+ catch {
55
+ // Can't read directory — treat as fresh
56
+ }
57
+ return "fresh";
58
+ }
29
59
  //# sourceMappingURL=vault-detect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vault-detect.js","sourceRoot":"","sources":["../../src/vault/vault-detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS;QAExC,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,WAAW;YAAE,SAAS;QAE3B,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;QACnE,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC,CACjD,CAAC;QAEF,IAAI,UAAU,IAAI,WAAW,EAAE,CAAC;YAC9B,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"vault-detect.js","sourceRoot":"","sources":["../../src/vault/vault-detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS;QAExC,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,WAAW;YAAE,SAAS;QAE3B,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;QACnE,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC,CACjD,CAAC;QAEF,IAAI,UAAU,IAAI,WAAW,EAAE,CAAC;YAC9B,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAID;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,OAAO,CAAC;IAE/C,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IACtE,IAAI,WAAW;QAAE,OAAO,gBAAgB,CAAC;IAEzC,2EAA2E;IAC3E,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,OAAO,UAAU,CAAC;YACpE,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvD,MAAM,UAAU,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBACrE,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBAAE,OAAO,UAAU,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;IAC1C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayjiang/byoao",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Build Your Own AI OS — Obsidian + AI Agent",
5
5
  "type": "module",
6
6
  "engines": {
@@ -50,12 +50,14 @@
50
50
  "gray-matter": "^4.0.0",
51
51
  "handlebars": "^4.7.0",
52
52
  "inquirer": "^9.0.0",
53
+ "semver": "^7.7.4",
53
54
  "zod": "^3.23.0"
54
55
  },
55
56
  "devDependencies": {
56
57
  "@types/fs-extra": "^11.0.0",
57
58
  "@types/inquirer": "^9.0.0",
58
59
  "@types/node": "^20.0.0",
60
+ "@types/semver": "^7.7.1",
59
61
  "tsx": "^4.21.0",
60
62
  "typescript": "^5.4.0",
61
63
  "vitest": "^4.1.0"
@@ -1,80 +1,47 @@
1
- # {{TEAM_NAME}} Workspace
1
+ # {{KB_NAME}}
2
2
 
3
- {{{AGENT_DESCRIPTION}}}
3
+ {{#if OWNER_NAME}}This is {{OWNER_NAME}}'s personal knowledge base.{{else}}A personal knowledge base.{{/if}} It contains interconnected notes on work, ideas, projects, people, and domains of interest.
4
4
 
5
- ## Navigation
5
+ ## How to Navigate
6
6
 
7
- - Search by frontmatter: `type`, `status`, `team`, `tags`
8
- - Follow `[[wikilinks]]` to traverse knowledge graph
9
- - `Knowledge/` for domain reference
10
- - `People/` for team roster
7
+ 1. **Start with [[Glossary]]** the entity dictionary for this knowledge base.
8
+ Every term is a key concept the owner cares about. Scan it first to
9
+ understand domain vocabulary.
10
+ 2. **Use frontmatter** to find relevant notes: `domain`, `type`, `tags`,
11
+ and `references` fields narrow down context quickly.
12
+ 3. **Follow wikilinks** — `[[links]]` connect related notes. Follow them
13
+ to build understanding of a topic.
14
+ 4. **Check backlinks** — discover related notes the user didn't mention.
15
+ 5. **Chain**: Glossary → domain notes → references → backlinks → details.
11
16
 
12
- ## Domain Knowledge
17
+ ## Frontmatter Fields
13
18
 
14
- - [[Glossary]] — centralized term reference (start here for any domain question)
15
-
16
- ### Concept Notes (Knowledge/concepts/)
17
-
18
- Complex domain concepts with rich wikilinks. Created as terms graduate from the Glossary.
19
+ | Field | Purpose |
20
+ |-------------|--------------------------------------------------|
21
+ | `domain` | Knowledge area (e.g. analytics, infrastructure) |
22
+ | `type` | Note kind (meeting, idea, reference, daily, etc) |
23
+ | `references`| Related notes follow for deeper context |
24
+ | `tags` | Flexible categorization |
25
+ | `status` | draft / active / completed / archived |
19
26
 
20
27
  {{{ROLE_SECTION}}}
21
28
 
22
- ## Team (People/)
23
-
24
- {{{TEAM_TABLE}}}
25
-
26
- ## Templates (Knowledge/templates/)
27
-
28
- Use Obsidian's template plugin (Ctrl/Cmd+T) to insert:
29
- {{{TEMPLATE_LIST}}}
30
-
31
- ## Document Conventions
32
-
33
- Rules for creating and modifying notes in this vault.
34
-
35
- ### Required Frontmatter
36
-
37
- Every note must include:
38
-
39
- ```yaml
40
- ---
41
- title: ""
42
- type: "" # see Note Types below
43
- status: "" # draft | active | completed | archived
44
- date: YYYY-MM-DD
45
- tags: []
46
- ---
47
- ```
48
-
49
- ### Note Types & Directory Mapping
50
-
51
- | type | Directory | Additional Required Fields |
52
- |------|-----------|---------------------------|
53
- | `feature` | `Projects/` | `project`, `jira`, `stakeholders`, `priority` |
54
- | `sprint-handoff` | `Sprints/` | `sprint`, `sprint-dates`, `jira-board` |
55
- | `meeting` | Caller's choice | `participants`, `meeting-type` |
56
- | `investigation` | Associated project folder | `jira`, `hypothesis` |
57
- | `decision` | Associated project folder | `decision`, `decided-by` |
58
- | `daily` | `Daily/` | — |
59
- | `reference` | `Knowledge/` | — |
60
- | `person` | `People/` | `team`, `role` |
61
-
62
- ### File Creation Rules
29
+ <!-- byoao:domains:start -->
30
+ ## Key Domains
63
31
 
64
- - Use `obsidian create template=<TemplateName>` when a matching template exists
65
- - If no template matches, manually construct frontmatter per the Required Frontmatter spec
66
- - File naming: Title Case or kebab-case{{#if HAS_JIRA}}, JIRA tickets use `{{JIRA_PROJECT}}-XXXX-Description.md`{{/if}}
67
- - Place files in the directory matching their `type` (see table above)
32
+ (Auto-generated by /weave run it to discover domains across vault notes)
68
33
 
69
- ### Wikilink Rules
34
+ <!-- byoao:domains:end -->
70
35
 
71
- - People → `[[Person Name]]`
72
- - Projects → `[[Project Name]]`
73
- - Domain terms → check `[[Glossary]]` before defining inline
74
- - Teams → link to the team index note in `People/`
36
+ <!-- byoao:conventions:start -->
37
+ ## Conventions
75
38
 
76
- ### Non-Compliant Documents
39
+ - Notes may or may not have frontmatter. Use /weave to enrich.
40
+ - Wikilinks are the primary connection mechanism.
41
+ - No strict directory rules — notes live wherever the user puts them.
42
+ - The knowledge graph (frontmatter + wikilinks) is the source of truth,
43
+ not the folder structure.
44
+ - Use `/weave` to connect new notes into the graph.
45
+ - Use `/diagnose` to check knowledge graph health.
77
46
 
78
- - User-created documents may not follow these conventions
79
- - Use `/enrich-document` to add missing frontmatter and wikilinks
80
- - Use `/vault-doctor` to diagnose vault-wide compliance issues
47
+ <!-- byoao:conventions:end -->