@jayjiang/byoao 0.5.0 → 0.7.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 +11 -8
- package/dist/__tests__/plugin-config.test.js.map +1 -1
- package/dist/cli/cli-program.js +136 -158
- package/dist/cli/cli-program.js.map +1 -1
- package/dist/cli/installer.js +4 -11
- package/dist/cli/installer.js.map +1 -1
- package/dist/hooks/idle-suggestions.js +6 -3
- package/dist/hooks/idle-suggestions.js.map +1 -1
- package/dist/hooks/system-transform.js +37 -14
- package/dist/hooks/system-transform.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/plugin-config.js +5 -2
- package/dist/plugin-config.js.map +1 -1
- package/dist/tools/add-glossary-term.js +2 -0
- package/dist/tools/add-glossary-term.js.map +1 -1
- package/dist/tools/add-person.js +21 -0
- package/dist/tools/add-person.js.map +1 -0
- package/dist/tools/init-vault.js +11 -9
- package/dist/tools/init-vault.js.map +1 -1
- package/dist/vault/__tests__/create.test.js +96 -42
- package/dist/vault/__tests__/create.test.js.map +1 -1
- package/dist/vault/__tests__/glossary.test.js +25 -14
- package/dist/vault/__tests__/glossary.test.js.map +1 -1
- package/dist/vault/__tests__/member.test.js +2 -4
- package/dist/vault/__tests__/member.test.js.map +1 -1
- package/dist/vault/create.js +205 -157
- package/dist/vault/create.js.map +1 -1
- package/dist/vault/doctor.js +1 -1
- package/dist/vault/doctor.js.map +1 -1
- package/dist/vault/glossary.js +8 -14
- package/dist/vault/glossary.js.map +1 -1
- package/dist/vault/member.js +1 -1
- package/dist/vault/member.js.map +1 -1
- package/dist/vault/project.js +1 -1
- package/dist/vault/project.js.map +1 -1
- package/dist/vault/vault-detect.js +30 -0
- package/dist/vault/vault-detect.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/presets/common/AGENT.md.hbs +34 -67
- package/src/assets/presets/common/Glossary.md.hbs +7 -35
- package/src/assets/presets/common/Start Here.md.hbs +40 -60
- package/src/assets/presets/minimal/preset.json +28 -0
- package/src/skills/connect.md +202 -0
- package/src/skills/{vault-doctor.md → diagnose.md} +12 -12
- package/src/skills/emerge.md +155 -0
- package/src/skills/{system-explainer.md → explain.md} +8 -8
- package/src/skills/trace.md +141 -0
- package/src/skills/weave.md +240 -0
- package/src/assets/web-clipper/confluence-page.json +0 -63
- package/src/assets/web-clipper/general-article.json +0 -53
- package/src/assets/web-clipper/jira-issue.json +0 -68
- package/src/assets/web-clipper/meeting-notes.json +0 -53
- package/src/skills/enrich-document.md +0 -52
|
@@ -12,45 +12,56 @@ afterEach(async () => {
|
|
|
12
12
|
await fs.remove(tmpDir);
|
|
13
13
|
});
|
|
14
14
|
const GLOSSARY_TEMPLATE = `---
|
|
15
|
-
title:
|
|
15
|
+
title: Glossary
|
|
16
16
|
type: reference
|
|
17
|
-
|
|
17
|
+
status: active
|
|
18
|
+
tags: [glossary, reference]
|
|
18
19
|
---
|
|
19
20
|
|
|
20
|
-
#
|
|
21
|
+
# Glossary
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
Domain terms and key concepts in this knowledge base.
|
|
24
|
+
Maintained by /weave — run it to discover and add new terms.
|
|
23
25
|
|
|
24
|
-
| Term | Definition |
|
|
25
|
-
|
|
26
|
-
| **API** | Application programming interface |
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## How to Add a New Term
|
|
31
|
-
|
|
32
|
-
Just add it.
|
|
26
|
+
| Term | Definition | Domain |
|
|
27
|
+
|------|-----------|--------|
|
|
28
|
+
| **API** | Application programming interface | engineering |
|
|
33
29
|
`;
|
|
34
30
|
describe("addGlossaryTerm", () => {
|
|
35
|
-
it("appends term to existing
|
|
31
|
+
it("appends term to existing glossary table", async () => {
|
|
36
32
|
await fs.writeFile(path.join(tmpDir, "Knowledge/Glossary.md"), GLOSSARY_TEMPLATE);
|
|
37
33
|
const result = await addGlossaryTerm({
|
|
38
34
|
vaultPath: tmpDir,
|
|
39
35
|
term: "SDK",
|
|
40
36
|
definition: "Software development kit",
|
|
37
|
+
domain: "engineering",
|
|
41
38
|
});
|
|
42
39
|
expect(result.termAdded).toBe("SDK");
|
|
43
40
|
const content = await fs.readFile(path.join(tmpDir, "Knowledge/Glossary.md"), "utf-8");
|
|
44
41
|
expect(content).toContain("**SDK**");
|
|
45
42
|
expect(content).toContain("Software development kit");
|
|
43
|
+
expect(content).toContain("| engineering |");
|
|
46
44
|
// Original term still present
|
|
47
45
|
expect(content).toContain("**API**");
|
|
48
46
|
});
|
|
47
|
+
it("appends term with empty domain when domain not provided", async () => {
|
|
48
|
+
await fs.writeFile(path.join(tmpDir, "Knowledge/Glossary.md"), GLOSSARY_TEMPLATE);
|
|
49
|
+
const result = await addGlossaryTerm({
|
|
50
|
+
vaultPath: tmpDir,
|
|
51
|
+
term: "TDD",
|
|
52
|
+
definition: "Test-driven development",
|
|
53
|
+
domain: "",
|
|
54
|
+
});
|
|
55
|
+
expect(result.termAdded).toBe("TDD");
|
|
56
|
+
const content = await fs.readFile(path.join(tmpDir, "Knowledge/Glossary.md"), "utf-8");
|
|
57
|
+
expect(content).toContain("**TDD**");
|
|
58
|
+
});
|
|
49
59
|
it("throws when Glossary.md does not exist", async () => {
|
|
50
60
|
await expect(addGlossaryTerm({
|
|
51
61
|
vaultPath: tmpDir,
|
|
52
62
|
term: "Test",
|
|
53
63
|
definition: "A test",
|
|
64
|
+
domain: "",
|
|
54
65
|
})).rejects.toThrow("Glossary not found");
|
|
55
66
|
});
|
|
56
67
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glossary.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/glossary.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,IAAI,MAAc,CAAC;AAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;IACpB,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACrE,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG
|
|
1
|
+
{"version":3,"file":"glossary.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/glossary.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -53,8 +53,7 @@ type: reference
|
|
|
53
53
|
expect(updated).toContain("[[Bob]]");
|
|
54
54
|
expect(updated).toContain("PM");
|
|
55
55
|
});
|
|
56
|
-
it("updates AGENT.md
|
|
57
|
-
// Create AGENT.md and CLAUDE.md with placeholder
|
|
56
|
+
it("updates AGENT.md wikilinks", async () => {
|
|
58
57
|
const agentContent = `# Agent
|
|
59
58
|
|
|
60
59
|
## Team
|
|
@@ -62,14 +61,13 @@ type: reference
|
|
|
62
61
|
(No members added yet — create notes in People/)
|
|
63
62
|
`;
|
|
64
63
|
await fs.writeFile(path.join(tmpDir, "AGENT.md"), agentContent);
|
|
65
|
-
await fs.writeFile(path.join(tmpDir, "CLAUDE.md"), agentContent);
|
|
66
64
|
const result = await addMember({
|
|
67
65
|
vaultPath: tmpDir,
|
|
68
66
|
name: "Carol",
|
|
69
67
|
role: "Designer",
|
|
70
68
|
team: "Platform",
|
|
71
69
|
});
|
|
72
|
-
expect(result.wikilinksAdded).toBeGreaterThanOrEqual(
|
|
70
|
+
expect(result.wikilinksAdded).toBeGreaterThanOrEqual(1);
|
|
73
71
|
const agent = await fs.readFile(path.join(tmpDir, "AGENT.md"), "utf-8");
|
|
74
72
|
expect(agent).toContain("[[Carol]]");
|
|
75
73
|
expect(agent).not.toContain("No members added yet");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"member.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/member.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,IAAI,MAAc,CAAC;AAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;IACpB,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,SAAS,EAAE,MAAM;YACjB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAErD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC/B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACpC,OAAO,CACR,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,2BAA2B;QAC3B,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;CAa5B,CAAC;QACE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,yBAAyB,CAAC,EAC5C,gBAAgB,CACjB,CAAC;QAEF,MAAM,SAAS,CAAC;YACd,SAAS,EAAE,MAAM;YACjB,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC/B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,yBAAyB,CAAC,EAC5C,OAAO,CACR,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"member.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/member.test.ts"],"names":[],"mappings":"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"}
|
package/dist/vault/create.js
CHANGED
|
@@ -6,6 +6,7 @@ import { configureMcp } from "./mcp.js";
|
|
|
6
6
|
import { configureObsidianPlugins } from "./obsidian-plugins.js";
|
|
7
7
|
import { configureProvider } from "./provider.js";
|
|
8
8
|
import { writeManifest } from "./manifest.js";
|
|
9
|
+
import { detectInitMode } from "./vault-detect.js";
|
|
9
10
|
function countWikilinks(content) {
|
|
10
11
|
const stripped = content
|
|
11
12
|
.replace(/```[\s\S]*?```/g, "")
|
|
@@ -13,100 +14,97 @@ function countWikilinks(content) {
|
|
|
13
14
|
const matches = stripped.match(/\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g);
|
|
14
15
|
return matches ? matches.length : 0;
|
|
15
16
|
}
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
"
|
|
17
|
+
// Minimal directories: the core of every knowledge base
|
|
18
|
+
const MINIMAL_DIRECTORIES = [
|
|
19
|
+
"Daily",
|
|
19
20
|
"Knowledge",
|
|
20
|
-
"Knowledge/concepts",
|
|
21
21
|
"Knowledge/templates",
|
|
22
|
-
"People",
|
|
23
|
-
"Systems",
|
|
24
|
-
"Archive",
|
|
25
|
-
"Daily",
|
|
26
22
|
];
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
function makeContext(vaultPath, kbName, preserveObsidian = false) {
|
|
24
|
+
return {
|
|
25
|
+
vaultPath,
|
|
26
|
+
kbName,
|
|
27
|
+
commonDir: getCommonDir(),
|
|
28
|
+
preserveObsidian,
|
|
29
|
+
filesCreated: 0,
|
|
30
|
+
directories: [],
|
|
31
|
+
installedFiles: {
|
|
32
|
+
skills: [],
|
|
33
|
+
commands: [],
|
|
34
|
+
obsidianConfig: [],
|
|
35
|
+
templates: [],
|
|
36
|
+
},
|
|
39
37
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Composable creation functions
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Create the minimal core: directories, .obsidian/ config, common templates,
|
|
44
|
+
* Glossary.md, Start Here.md.
|
|
45
|
+
*/
|
|
46
|
+
export async function createMinimalCore(ctx, glossaryEntries = []) {
|
|
47
|
+
// 1. Create minimal directories
|
|
48
|
+
for (const dir of MINIMAL_DIRECTORIES) {
|
|
49
|
+
await fs.ensureDir(path.join(ctx.vaultPath, dir));
|
|
45
50
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
ctx.directories.push(...MINIMAL_DIRECTORIES);
|
|
52
|
+
// 2. Copy .obsidian config from common (skip if preserving existing vault config)
|
|
53
|
+
if (!ctx.preserveObsidian) {
|
|
54
|
+
await fs.ensureDir(path.join(ctx.vaultPath, ".obsidian"));
|
|
55
|
+
const obsidianSrc = path.join(ctx.commonDir, "obsidian");
|
|
56
|
+
if (await fs.pathExists(obsidianSrc)) {
|
|
57
|
+
await fs.copy(obsidianSrc, path.join(ctx.vaultPath, ".obsidian"), { overwrite: false });
|
|
58
|
+
const obsidianFiles = await fs.readdir(obsidianSrc);
|
|
59
|
+
ctx.filesCreated += obsidianFiles.length;
|
|
60
|
+
for (const f of obsidianFiles) {
|
|
61
|
+
ctx.installedFiles.obsidianConfig.push(`.obsidian/${f}`);
|
|
62
|
+
}
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
|
-
// 3. Copy
|
|
58
|
-
const templateDest = path.join(vaultPath, "Knowledge/templates");
|
|
59
|
-
const
|
|
60
|
-
// Common templates
|
|
61
|
-
const commonTemplatesDir = path.join(commonDir, "templates");
|
|
65
|
+
// 3. Copy common templates
|
|
66
|
+
const templateDest = path.join(ctx.vaultPath, "Knowledge/templates");
|
|
67
|
+
const commonTemplatesDir = path.join(ctx.commonDir, "templates");
|
|
62
68
|
if (await fs.pathExists(commonTemplatesDir)) {
|
|
63
69
|
const files = await fs.readdir(commonTemplatesDir);
|
|
64
70
|
for (const file of files) {
|
|
65
71
|
await fs.copy(path.join(commonTemplatesDir, file), path.join(templateDest, file), { overwrite: false });
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
installedFiles.templates.push(`Knowledge/templates/${file}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Preset templates
|
|
72
|
-
const presetTemplatesDir = path.join(presetDir, "templates");
|
|
73
|
-
if (await fs.pathExists(presetTemplatesDir)) {
|
|
74
|
-
const files = await fs.readdir(presetTemplatesDir);
|
|
75
|
-
for (const file of files) {
|
|
76
|
-
await fs.copy(path.join(presetTemplatesDir, file), path.join(templateDest, file), { overwrite: false });
|
|
77
|
-
allTemplateNames.push(file.replace(/\.md$/, ""));
|
|
78
|
-
filesCreated++;
|
|
79
|
-
installedFiles.templates.push(`Knowledge/templates/${file}`);
|
|
72
|
+
ctx.filesCreated++;
|
|
73
|
+
ctx.installedFiles.templates.push(`Knowledge/templates/${file}`);
|
|
80
74
|
}
|
|
81
75
|
}
|
|
82
76
|
// 4. Generate Glossary.md
|
|
83
|
-
const glossaryTemplate = await fs.readFile(path.join(commonDir, "Glossary.md.hbs"), "utf-8");
|
|
77
|
+
const glossaryTemplate = await fs.readFile(path.join(ctx.commonDir, "Glossary.md.hbs"), "utf-8");
|
|
84
78
|
let glossaryRows = "";
|
|
85
79
|
if (glossaryEntries.length > 0) {
|
|
86
80
|
glossaryRows = glossaryEntries
|
|
87
|
-
.map((e) => `| **${e.term}** | ${e.definition} |`)
|
|
81
|
+
.map((e) => `| **${e.term}** | ${e.definition} | ${e.domain} |`)
|
|
88
82
|
.join("\n");
|
|
89
83
|
}
|
|
90
84
|
const glossaryContent = renderTemplate(glossaryTemplate, {
|
|
91
|
-
|
|
85
|
+
KB_NAME: ctx.kbName,
|
|
92
86
|
date: today(),
|
|
93
87
|
GLOSSARY_ENTRIES: glossaryRows,
|
|
94
88
|
});
|
|
95
|
-
const glossaryPath = path.join(vaultPath, "Knowledge/Glossary.md");
|
|
89
|
+
const glossaryPath = path.join(ctx.vaultPath, "Knowledge/Glossary.md");
|
|
96
90
|
if (!(await fs.pathExists(glossaryPath))) {
|
|
97
91
|
await fs.writeFile(glossaryPath, glossaryContent);
|
|
98
|
-
filesCreated++;
|
|
92
|
+
ctx.filesCreated++;
|
|
99
93
|
}
|
|
100
94
|
// 5. Generate Start Here.md
|
|
101
|
-
const startHereTemplate = await fs.readFile(path.join(commonDir, "Start Here.md.hbs"), "utf-8");
|
|
102
|
-
const startHereContent = renderTemplate(startHereTemplate, {
|
|
103
|
-
const startHerePath = path.join(vaultPath, "Start Here.md");
|
|
95
|
+
const startHereTemplate = await fs.readFile(path.join(ctx.commonDir, "Start Here.md.hbs"), "utf-8");
|
|
96
|
+
const startHereContent = renderTemplate(startHereTemplate, { KB_NAME: ctx.kbName });
|
|
97
|
+
const startHerePath = path.join(ctx.vaultPath, "Start Here.md");
|
|
104
98
|
if (!(await fs.pathExists(startHerePath))) {
|
|
105
99
|
await fs.writeFile(startHerePath, startHereContent);
|
|
106
|
-
filesCreated++;
|
|
100
|
+
ctx.filesCreated++;
|
|
107
101
|
}
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Generate AGENT.md from the common skeleton + preset section.
|
|
105
|
+
*/
|
|
106
|
+
export async function createAgentMd(ctx, ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject) {
|
|
107
|
+
const agentSkeletonTemplate = await fs.readFile(path.join(ctx.commonDir, "AGENT.md.hbs"), "utf-8");
|
|
110
108
|
// Render preset agent-section
|
|
111
109
|
let roleSection = "";
|
|
112
110
|
const agentSectionPath = path.join(presetDir, "agent-section.hbs");
|
|
@@ -128,42 +126,68 @@ export async function createVault(config) {
|
|
|
128
126
|
HAS_JIRA: !!(jiraHost && jiraProject),
|
|
129
127
|
});
|
|
130
128
|
}
|
|
131
|
-
// Build team table
|
|
132
|
-
let teamTable;
|
|
133
|
-
if (members.length > 0) {
|
|
134
|
-
const rows = members.map((m) => `| [[${m.name}]] | ${m.role} |`).join("\n");
|
|
135
|
-
teamTable = `| Name | Role |\n|------|------|\n${rows}`;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
teamTable = "(No members added yet — create notes in People/)";
|
|
139
|
-
}
|
|
140
|
-
// Build template list string
|
|
141
|
-
const templateList = allTemplateNames.map((t) => `- ${t}`).join("\n");
|
|
142
129
|
const agentContent = renderTemplate(agentSkeletonTemplate, {
|
|
143
|
-
|
|
144
|
-
|
|
130
|
+
KB_NAME: ctx.kbName,
|
|
131
|
+
OWNER_NAME: ownerName,
|
|
145
132
|
ROLE_SECTION: roleSection,
|
|
146
|
-
TEAM_TABLE: teamTable,
|
|
147
|
-
TEMPLATE_LIST: templateList,
|
|
148
|
-
JIRA_PROJECT: jiraProject,
|
|
149
|
-
HAS_JIRA: !!(jiraHost && jiraProject),
|
|
150
133
|
});
|
|
151
|
-
const agentMdPath = path.join(vaultPath, "AGENT.md");
|
|
152
|
-
const claudeMdPath = path.join(vaultPath, "CLAUDE.md");
|
|
134
|
+
const agentMdPath = path.join(ctx.vaultPath, "AGENT.md");
|
|
153
135
|
if (!(await fs.pathExists(agentMdPath))) {
|
|
154
136
|
await fs.writeFile(agentMdPath, agentContent);
|
|
155
|
-
filesCreated++;
|
|
137
|
+
ctx.filesCreated++;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Apply preset overlay: create preset-specific directories and copy preset templates.
|
|
142
|
+
* Returns the list of all template names (common + preset) for AGENT.md generation.
|
|
143
|
+
*/
|
|
144
|
+
export async function applyPresetOverlay(ctx, presetConfig, presetDir) {
|
|
145
|
+
// Create preset-specific directories
|
|
146
|
+
for (const dir of presetConfig.directories) {
|
|
147
|
+
await fs.ensureDir(path.join(ctx.vaultPath, dir));
|
|
148
|
+
}
|
|
149
|
+
ctx.directories.push(...presetConfig.directories);
|
|
150
|
+
// Collect common template names already installed
|
|
151
|
+
const templateDest = path.join(ctx.vaultPath, "Knowledge/templates");
|
|
152
|
+
const allTemplateNames = [];
|
|
153
|
+
// Read existing common templates (already copied by createMinimalCore)
|
|
154
|
+
if (await fs.pathExists(templateDest)) {
|
|
155
|
+
const existing = await fs.readdir(templateDest);
|
|
156
|
+
for (const file of existing) {
|
|
157
|
+
if (file.endsWith(".md")) {
|
|
158
|
+
allTemplateNames.push(file.replace(/\.md$/, ""));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Copy preset templates
|
|
163
|
+
const presetTemplatesDir = path.join(presetDir, "templates");
|
|
164
|
+
if (await fs.pathExists(presetTemplatesDir)) {
|
|
165
|
+
const files = await fs.readdir(presetTemplatesDir);
|
|
166
|
+
for (const file of files) {
|
|
167
|
+
await fs.copy(path.join(presetTemplatesDir, file), path.join(templateDest, file), { overwrite: false });
|
|
168
|
+
allTemplateNames.push(file.replace(/\.md$/, ""));
|
|
169
|
+
ctx.filesCreated++;
|
|
170
|
+
ctx.installedFiles.templates.push(`Knowledge/templates/${file}`);
|
|
171
|
+
}
|
|
156
172
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
173
|
+
return allTemplateNames;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Create people notes from members config.
|
|
177
|
+
* Ensures People/ directory exists.
|
|
178
|
+
*/
|
|
179
|
+
export async function createPeopleNotes(ctx, members) {
|
|
180
|
+
if (members.length === 0)
|
|
181
|
+
return;
|
|
182
|
+
await fs.ensureDir(path.join(ctx.vaultPath, "People"));
|
|
183
|
+
if (!ctx.directories.includes("People")) {
|
|
184
|
+
ctx.directories.push("People");
|
|
160
185
|
}
|
|
161
|
-
// 7. Create people notes
|
|
162
186
|
for (const member of members) {
|
|
163
187
|
const content = `---
|
|
164
188
|
title: "${member.name}"
|
|
165
189
|
type: person
|
|
166
|
-
team: "${
|
|
190
|
+
team: "${ctx.kbName}"
|
|
167
191
|
role: "${member.role}"
|
|
168
192
|
status: active
|
|
169
193
|
tags: [person]
|
|
@@ -172,22 +196,33 @@ tags: [person]
|
|
|
172
196
|
# ${member.name}
|
|
173
197
|
|
|
174
198
|
**Role**: ${member.role}
|
|
175
|
-
**Team**: ${
|
|
199
|
+
**Team**: ${ctx.kbName}
|
|
176
200
|
`;
|
|
177
|
-
const memberPath = path.join(vaultPath, `People/${member.name}.md`);
|
|
201
|
+
const memberPath = path.join(ctx.vaultPath, `People/${member.name}.md`);
|
|
178
202
|
if (!(await fs.pathExists(memberPath))) {
|
|
179
203
|
await fs.writeFile(memberPath, content);
|
|
180
|
-
filesCreated++;
|
|
204
|
+
ctx.filesCreated++;
|
|
181
205
|
}
|
|
182
206
|
}
|
|
183
|
-
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Create project notes from projects config.
|
|
210
|
+
* Ensures Projects/ directory exists.
|
|
211
|
+
*/
|
|
212
|
+
export async function createProjectNotes(ctx, projects) {
|
|
213
|
+
if (projects.length === 0)
|
|
214
|
+
return;
|
|
215
|
+
await fs.ensureDir(path.join(ctx.vaultPath, "Projects"));
|
|
216
|
+
if (!ctx.directories.includes("Projects")) {
|
|
217
|
+
ctx.directories.push("Projects");
|
|
218
|
+
}
|
|
184
219
|
for (const project of projects) {
|
|
185
220
|
const content = `---
|
|
186
221
|
title: "${project.name}"
|
|
187
222
|
type: feature
|
|
188
223
|
status: active
|
|
189
224
|
date: ${today()}
|
|
190
|
-
team: "${
|
|
225
|
+
team: "${ctx.kbName}"
|
|
191
226
|
jira: ""
|
|
192
227
|
stakeholders: []
|
|
193
228
|
priority: ""
|
|
@@ -198,98 +233,111 @@ tags: [project]
|
|
|
198
233
|
|
|
199
234
|
${project.description}
|
|
200
235
|
`;
|
|
201
|
-
const projectPath = path.join(vaultPath, `Projects/${project.name}.md`);
|
|
236
|
+
const projectPath = path.join(ctx.vaultPath, `Projects/${project.name}.md`);
|
|
202
237
|
if (!(await fs.pathExists(projectPath))) {
|
|
203
238
|
await fs.writeFile(projectPath, content);
|
|
204
|
-
filesCreated++;
|
|
239
|
+
ctx.filesCreated++;
|
|
205
240
|
}
|
|
206
241
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Create team index note in People/.
|
|
245
|
+
* Only call when the vault has a People/ directory (preset includes it or members exist).
|
|
246
|
+
*/
|
|
247
|
+
export async function createTeamIndex(ctx, members, projects) {
|
|
248
|
+
await fs.ensureDir(path.join(ctx.vaultPath, "People"));
|
|
249
|
+
if (!ctx.directories.includes("People")) {
|
|
250
|
+
ctx.directories.push("People");
|
|
251
|
+
}
|
|
252
|
+
let teamIndexContent = `---
|
|
253
|
+
title: "${ctx.kbName} Team"
|
|
211
254
|
type: reference
|
|
212
|
-
team: "${
|
|
255
|
+
team: "${ctx.kbName}"
|
|
213
256
|
tags: [team]
|
|
214
257
|
---
|
|
215
258
|
|
|
216
|
-
# ${
|
|
259
|
+
# ${ctx.kbName} Team
|
|
217
260
|
|
|
218
261
|
## Members
|
|
219
262
|
|
|
220
263
|
`;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
teamIndexContent += "(No members added yet)";
|
|
227
|
-
}
|
|
228
|
-
teamIndexContent += "\n\n## Active Projects\n\n";
|
|
229
|
-
if (projects.length > 0) {
|
|
230
|
-
teamIndexContent += projects
|
|
231
|
-
.map((p) => `- [[${p.name}]] — ${p.description}`)
|
|
232
|
-
.join("\n");
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
teamIndexContent += "(No projects added yet)";
|
|
236
|
-
}
|
|
237
|
-
teamIndexContent += "\n";
|
|
238
|
-
const teamIndexPath = path.join(vaultPath, `People/${teamName} Team.md`);
|
|
239
|
-
if (!(await fs.pathExists(teamIndexPath))) {
|
|
240
|
-
await fs.writeFile(teamIndexPath, teamIndexContent);
|
|
241
|
-
filesCreated++;
|
|
242
|
-
}
|
|
264
|
+
if (members.length > 0) {
|
|
265
|
+
teamIndexContent += "| Name | Role |\n|------|------|\n";
|
|
266
|
+
teamIndexContent += members.map((m) => `| [[${m.name}]] | ${m.role} |`).join("\n");
|
|
243
267
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
"Inbox",
|
|
247
|
-
"Knowledge/concepts",
|
|
248
|
-
"Systems",
|
|
249
|
-
"Archive",
|
|
250
|
-
"Daily",
|
|
251
|
-
];
|
|
252
|
-
// Add preset-specific dirs if they're empty
|
|
253
|
-
for (const dir of presetConfig.directories) {
|
|
254
|
-
dirsNeedingGitkeep.push(dir);
|
|
268
|
+
else {
|
|
269
|
+
teamIndexContent += "(No members added yet)";
|
|
255
270
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
await fs.writeFile(path.join(dirPath, ".gitkeep"), "");
|
|
262
|
-
}
|
|
263
|
-
}
|
|
271
|
+
teamIndexContent += "\n\n## Active Projects\n\n";
|
|
272
|
+
if (projects.length > 0) {
|
|
273
|
+
teamIndexContent += projects
|
|
274
|
+
.map((p) => `- [[${p.name}]] — ${p.description}`)
|
|
275
|
+
.join("\n");
|
|
264
276
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
277
|
+
else {
|
|
278
|
+
teamIndexContent += "(No projects added yet)";
|
|
279
|
+
}
|
|
280
|
+
teamIndexContent += "\n";
|
|
281
|
+
const teamIndexPath = path.join(ctx.vaultPath, `People/${ctx.kbName} Team.md`);
|
|
282
|
+
if (!(await fs.pathExists(teamIndexPath))) {
|
|
283
|
+
await fs.writeFile(teamIndexPath, teamIndexContent);
|
|
284
|
+
ctx.filesCreated++;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// Main orchestrator
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
export async function createVault(config) {
|
|
291
|
+
const { kbName, vaultPath, members, projects, glossaryEntries, jiraHost, jiraProject, preset } = config;
|
|
292
|
+
const presetName = preset ?? "pm-tpm"; // Fallback if config wasn't parsed through Zod
|
|
293
|
+
const { config: presetConfig, presetsDir } = loadPreset(presetName);
|
|
294
|
+
const presetDir = path.join(presetsDir, presetName);
|
|
295
|
+
const initMode = detectInitMode(vaultPath);
|
|
296
|
+
const preserveObsidian = initMode === "obsidian-vault";
|
|
297
|
+
const ctx = makeContext(vaultPath, kbName, preserveObsidian);
|
|
298
|
+
// 1. Create minimal core (dirs, .obsidian, common templates, Glossary, Start Here)
|
|
299
|
+
await createMinimalCore(ctx, glossaryEntries);
|
|
300
|
+
// 2. Apply preset overlay (preset dirs + preset templates)
|
|
301
|
+
const allTemplateNames = await applyPresetOverlay(ctx, presetConfig, presetDir);
|
|
302
|
+
// 3. Generate AGENT.md
|
|
303
|
+
await createAgentMd(ctx, config.ownerName, presetConfig, presetDir, projects, jiraHost, jiraProject);
|
|
304
|
+
// 4. Create people notes (conditional)
|
|
305
|
+
await createPeopleNotes(ctx, members);
|
|
306
|
+
// 5. Create project notes (conditional)
|
|
307
|
+
await createProjectNotes(ctx, projects);
|
|
308
|
+
// 6. Create team index (only when preset declares People/ or members exist)
|
|
309
|
+
const hasPeopleDir = presetConfig.directories.includes("People") || members.length > 0;
|
|
310
|
+
if (hasPeopleDir) {
|
|
311
|
+
await createTeamIndex(ctx, members, projects);
|
|
312
|
+
}
|
|
313
|
+
// 7. Configure vault as OpenCode project (plugin + skills + commands)
|
|
314
|
+
await configureOpenCodeProject(ctx.vaultPath, ctx.installedFiles);
|
|
315
|
+
// 8. Configure MCP servers in global OpenCode config
|
|
268
316
|
const mcpResult = await configureMcp(presetConfig);
|
|
269
|
-
//
|
|
270
|
-
const pluginsResult = await configureObsidianPlugins(vaultPath, presetConfig);
|
|
271
|
-
//
|
|
317
|
+
// 9. Install Obsidian community plugins from preset
|
|
318
|
+
const pluginsResult = await configureObsidianPlugins(ctx.vaultPath, presetConfig);
|
|
319
|
+
// 10. Configure AI provider in global OpenCode config
|
|
272
320
|
let providerResult = null;
|
|
273
321
|
if (config.provider && config.provider !== "skip") {
|
|
274
322
|
providerResult = await configureProvider(config.provider, config.provider === "gemini" ? config.gcpProjectId : undefined);
|
|
275
323
|
}
|
|
276
|
-
//
|
|
277
|
-
await writeManifest(vaultPath, presetName, installedFiles);
|
|
278
|
-
//
|
|
324
|
+
// 11. Write BYOAO manifest
|
|
325
|
+
await writeManifest(ctx.vaultPath, presetName, ctx.installedFiles);
|
|
326
|
+
// 12. Count wikilinks from all generated markdown files
|
|
279
327
|
let wikilinksCreated = 0;
|
|
280
|
-
const entries = await fs.readdir(vaultPath, { recursive: true });
|
|
328
|
+
const entries = await fs.readdir(ctx.vaultPath, { recursive: true });
|
|
281
329
|
for (const entry of entries) {
|
|
282
330
|
const entryStr = String(entry);
|
|
283
331
|
if (entryStr.endsWith(".md") && !entryStr.startsWith(".obsidian")) {
|
|
284
|
-
const content = await fs.readFile(path.join(vaultPath, entryStr), "utf-8");
|
|
332
|
+
const content = await fs.readFile(path.join(ctx.vaultPath, entryStr), "utf-8");
|
|
285
333
|
wikilinksCreated += countWikilinks(content);
|
|
286
334
|
}
|
|
287
335
|
}
|
|
288
336
|
return {
|
|
289
|
-
vaultPath,
|
|
290
|
-
filesCreated,
|
|
337
|
+
vaultPath: ctx.vaultPath,
|
|
338
|
+
filesCreated: ctx.filesCreated,
|
|
291
339
|
wikilinksCreated,
|
|
292
|
-
directories:
|
|
340
|
+
directories: ctx.directories,
|
|
293
341
|
mcpResult,
|
|
294
342
|
pluginsResult,
|
|
295
343
|
providerResult,
|