@jayjiang/byoao 1.1.2 → 2.0.1

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 (156) hide show
  1. package/dist/__tests__/plugin-config.test.js +7 -10
  2. package/dist/__tests__/plugin-config.test.js.map +1 -1
  3. package/dist/assets/obsidian-skills/byoao-conventions.md +30 -54
  4. package/dist/assets/obsidian-skills/vault-thinking.md +6 -5
  5. package/dist/assets/presets/common/AGENTS.md.hbs +29 -46
  6. package/dist/assets/presets/common/SCHEMA.md.hbs +57 -0
  7. package/dist/assets/presets/common/Start Here.md.hbs +29 -40
  8. package/dist/assets/presets/minimal/preset.json +3 -3
  9. package/dist/assets/presets/pm-tpm/preset.json +2 -2
  10. package/{src/skills/ask.md → dist/assets/skills/ask/SKILL.md} +30 -27
  11. package/dist/assets/skills/ask.md +28 -27
  12. package/dist/assets/skills/challenge/SKILL.md +134 -0
  13. package/dist/assets/skills/challenge.md +79 -121
  14. package/dist/assets/skills/connect/SKILL.md +126 -0
  15. package/dist/assets/skills/connect.md +75 -163
  16. package/dist/assets/skills/cook/SKILL.md +170 -0
  17. package/dist/assets/skills/cook.md +167 -0
  18. package/dist/assets/skills/diagnose/SKILL.md +134 -0
  19. package/dist/assets/skills/diagnose.md +102 -43
  20. package/dist/assets/skills/drift/SKILL.md +123 -0
  21. package/dist/assets/skills/drift.md +64 -165
  22. package/dist/assets/skills/health/SKILL.md +65 -0
  23. package/dist/assets/skills/health.md +63 -0
  24. package/{src/skills/ideas.md → dist/assets/skills/ideas/SKILL.md} +11 -10
  25. package/dist/assets/skills/ideas.md +11 -10
  26. package/dist/assets/skills/organize/SKILL.md +109 -0
  27. package/dist/assets/skills/organize.md +56 -155
  28. package/dist/assets/skills/prep/SKILL.md +65 -0
  29. package/dist/assets/skills/prep.md +63 -0
  30. package/dist/assets/skills/trace/SKILL.md +143 -0
  31. package/dist/assets/skills/trace.md +75 -90
  32. package/dist/assets/skills/wiki/SKILL.md +127 -0
  33. package/dist/assets/skills/wiki.md +77 -178
  34. package/dist/cli/cli-program.js +18 -15
  35. package/dist/cli/cli-program.js.map +1 -1
  36. package/dist/cli/installer.js +54 -29
  37. package/dist/cli/installer.js.map +1 -1
  38. package/dist/hooks/idle-suggestions.js +4 -4
  39. package/dist/hooks/idle-suggestions.js.map +1 -1
  40. package/dist/hooks/system-transform.js +35 -1
  41. package/dist/hooks/system-transform.js.map +1 -1
  42. package/dist/index.js +455 -636
  43. package/dist/index.js.map +1 -1
  44. package/dist/plugin-config.js +6 -32
  45. package/dist/plugin-config.js.map +1 -1
  46. package/dist/tools/init-vault.js +8 -38
  47. package/dist/tools/init-vault.js.map +1 -1
  48. package/dist/tools/vault-doctor.js +1 -1
  49. package/dist/tools/vault-doctor.js.map +1 -1
  50. package/dist/tools/vault-status.js +1 -1
  51. package/dist/tools/vault-status.js.map +1 -1
  52. package/dist/vault/__tests__/create.test.js +48 -116
  53. package/dist/vault/__tests__/create.test.js.map +1 -1
  54. package/dist/vault/__tests__/doctor.test.js +14 -2
  55. package/dist/vault/__tests__/doctor.test.js.map +1 -1
  56. package/dist/vault/__tests__/manifest.test.js +2 -2
  57. package/dist/vault/__tests__/manifest.test.js.map +1 -1
  58. package/dist/vault/__tests__/status.test.js +12 -0
  59. package/dist/vault/__tests__/status.test.js.map +1 -1
  60. package/dist/vault/__tests__/upgrade.test.js +3 -3
  61. package/dist/vault/__tests__/upgrade.test.js.map +1 -1
  62. package/dist/vault/create.js +86 -196
  63. package/dist/vault/create.js.map +1 -1
  64. package/dist/vault/doctor.js +49 -0
  65. package/dist/vault/doctor.js.map +1 -1
  66. package/dist/vault/manifest.js +2 -2
  67. package/dist/vault/manifest.js.map +1 -1
  68. package/dist/vault/preset.js +10 -4
  69. package/dist/vault/preset.js.map +1 -1
  70. package/dist/vault/self-update.js +1 -1
  71. package/dist/vault/status.js +24 -0
  72. package/dist/vault/status.js.map +1 -1
  73. package/dist/vault/upgrade.js +165 -23
  74. package/dist/vault/upgrade.js.map +1 -1
  75. package/package.json +1 -1
  76. package/src/assets/obsidian-skills/byoao-conventions.md +9 -6
  77. package/src/assets/obsidian-skills/vault-thinking.md +6 -5
  78. package/src/assets/presets/common/AGENTS.md.hbs +23 -19
  79. package/src/assets/presets/common/SCHEMA.md.hbs +57 -0
  80. package/src/assets/presets/common/Start Here.md.hbs +29 -40
  81. package/src/assets/presets/minimal/preset.json +3 -3
  82. package/src/assets/presets/pm-tpm/preset.json +2 -2
  83. package/src/skills/ask/SKILL.md +135 -0
  84. package/src/skills/challenge/SKILL.md +134 -0
  85. package/src/skills/connect/SKILL.md +126 -0
  86. package/src/skills/cook/SKILL.md +170 -0
  87. package/src/skills/diagnose/SKILL.md +134 -0
  88. package/src/skills/drift/SKILL.md +123 -0
  89. package/src/skills/health/SKILL.md +65 -0
  90. package/src/skills/ideas/SKILL.md +173 -0
  91. package/src/skills/organize/SKILL.md +109 -0
  92. package/src/skills/prep/SKILL.md +65 -0
  93. package/src/skills/trace/SKILL.md +143 -0
  94. package/src/skills/wiki/SKILL.md +127 -0
  95. package/dist/assets/presets/common/Glossary.md.hbs +0 -16
  96. package/dist/assets/presets/common/obsidian/daily-notes.json +0 -5
  97. package/dist/assets/presets/common/obsidian/templates.json +0 -3
  98. package/dist/assets/presets/common/templates/Daily Note.md +0 -19
  99. package/dist/assets/presets/common/templates/Decision Record.md +0 -32
  100. package/dist/assets/presets/common/templates/Investigation.md +0 -34
  101. package/dist/assets/presets/common/templates/Meeting Notes.md +0 -25
  102. package/dist/assets/skills/emerge.md +0 -168
  103. package/dist/assets/skills/weave.md +0 -287
  104. package/dist/tools/add-glossary-term.js +0 -21
  105. package/dist/tools/add-glossary-term.js.map +0 -1
  106. package/dist/tools/add-person.js +0 -21
  107. package/dist/tools/add-person.js.map +0 -1
  108. package/dist/tools/add-project.js +0 -24
  109. package/dist/tools/add-project.js.map +0 -1
  110. package/dist/tools/graph-health.js +0 -25
  111. package/dist/tools/graph-health.js.map +0 -1
  112. package/dist/tools/note-read.js +0 -19
  113. package/dist/tools/note-read.js.map +0 -1
  114. package/dist/tools/search-vault.js +0 -22
  115. package/dist/tools/search-vault.js.map +0 -1
  116. package/dist/vault/__tests__/glossary.test.js +0 -68
  117. package/dist/vault/__tests__/glossary.test.js.map +0 -1
  118. package/dist/vault/__tests__/graph-health.test.js +0 -102
  119. package/dist/vault/__tests__/graph-health.test.js.map +0 -1
  120. package/dist/vault/__tests__/member.test.js +0 -85
  121. package/dist/vault/__tests__/member.test.js.map +0 -1
  122. package/dist/vault/__tests__/note-read.test.js +0 -71
  123. package/dist/vault/__tests__/note-read.test.js.map +0 -1
  124. package/dist/vault/__tests__/obsidian-cli.test.js +0 -108
  125. package/dist/vault/__tests__/obsidian-cli.test.js.map +0 -1
  126. package/dist/vault/__tests__/search-vault.test.js +0 -93
  127. package/dist/vault/__tests__/search-vault.test.js.map +0 -1
  128. package/dist/vault/glossary.js +0 -27
  129. package/dist/vault/glossary.js.map +0 -1
  130. package/dist/vault/graph-health.js +0 -83
  131. package/dist/vault/graph-health.js.map +0 -1
  132. package/dist/vault/member.js +0 -67
  133. package/dist/vault/member.js.map +0 -1
  134. package/dist/vault/note-read.js +0 -70
  135. package/dist/vault/note-read.js.map +0 -1
  136. package/dist/vault/project.js +0 -68
  137. package/dist/vault/project.js.map +0 -1
  138. package/dist/vault/retrieval-types.js +0 -5
  139. package/dist/vault/retrieval-types.js.map +0 -1
  140. package/dist/vault/search-vault.js +0 -87
  141. package/dist/vault/search-vault.js.map +0 -1
  142. package/src/assets/presets/common/obsidian/daily-notes.json +0 -5
  143. package/src/assets/presets/common/obsidian/templates.json +0 -3
  144. package/src/assets/presets/common/templates/Daily Note.md +0 -19
  145. package/src/assets/presets/common/templates/Decision Record.md +0 -32
  146. package/src/assets/presets/common/templates/Investigation.md +0 -34
  147. package/src/assets/presets/common/templates/Meeting Notes.md +0 -25
  148. package/src/skills/challenge.md +0 -174
  149. package/src/skills/connect.md +0 -213
  150. package/src/skills/diagnose.md +0 -72
  151. package/src/skills/drift.md +0 -223
  152. package/src/skills/emerge.md +0 -168
  153. package/src/skills/organize.md +0 -206
  154. package/src/skills/trace.md +0 -156
  155. package/src/skills/weave.md +0 -287
  156. package/src/skills/wiki.md +0 -227
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-vault.js","sourceRoot":"","sources":["../../src/tools/search-vault.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;IACrC,WAAW,EACT,iNAAiN;IACnN,IAAI,EAAE;QACJ,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC/E,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QAC/E,KAAK,EAAE,IAAI,CAAC,MAAM;aACf,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,mDAAmD,CAAC;KACjE;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;CACF,CAAC,CAAC"}
@@ -1,68 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
- import fs from "fs-extra";
3
- import path from "node:path";
4
- import os from "node:os";
5
- import { addGlossaryTerm } from "../glossary.js";
6
- let tmpDir;
7
- beforeEach(async () => {
8
- tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "byoao-glossary-"));
9
- await fs.ensureDir(path.join(tmpDir, "Knowledge"));
10
- });
11
- afterEach(async () => {
12
- await fs.remove(tmpDir);
13
- });
14
- const GLOSSARY_TEMPLATE = `---
15
- title: Glossary
16
- type: reference
17
- status: active
18
- tags: [glossary, reference]
19
- ---
20
-
21
- # Glossary
22
-
23
- Domain terms and key concepts in this knowledge base.
24
- Maintained by /weave — run it to discover and add new terms.
25
-
26
- | Term | Definition | Domain |
27
- |------|-----------|--------|
28
- | **API** | Application programming interface | engineering |
29
- `;
30
- describe("addGlossaryTerm", () => {
31
- it("appends term to existing glossary table", async () => {
32
- await fs.writeFile(path.join(tmpDir, "Knowledge/Glossary.md"), GLOSSARY_TEMPLATE);
33
- const result = await addGlossaryTerm({
34
- vaultPath: tmpDir,
35
- term: "SDK",
36
- definition: "Software development kit",
37
- domain: "engineering",
38
- });
39
- expect(result.termAdded).toBe("SDK");
40
- const content = await fs.readFile(path.join(tmpDir, "Knowledge/Glossary.md"), "utf-8");
41
- expect(content).toContain("**SDK**");
42
- expect(content).toContain("Software development kit");
43
- expect(content).toContain("| engineering |");
44
- // Original term still present
45
- expect(content).toContain("**API**");
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
- });
59
- it("throws when Glossary.md does not exist", async () => {
60
- await expect(addGlossaryTerm({
61
- vaultPath: tmpDir,
62
- term: "Test",
63
- definition: "A test",
64
- domain: "",
65
- })).rejects.toThrow("Glossary not found");
66
- });
67
- });
68
- //# sourceMappingURL=glossary.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"glossary.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/glossary.test.ts"],"names":[],"mappings":"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"}
@@ -1,102 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- vi.mock("../obsidian-cli.js", () => ({
3
- isObsidianCliAvailable: vi.fn(),
4
- execObsidianCmd: vi.fn(),
5
- }));
6
- import { getGraphHealth } from "../graph-health.js";
7
- import { isObsidianCliAvailable, execObsidianCmd } from "../obsidian-cli.js";
8
- const mockIsAvailable = vi.mocked(isObsidianCliAvailable);
9
- const mockExecCmd = vi.mocked(execObsidianCmd);
10
- beforeEach(() => {
11
- vi.resetAllMocks();
12
- });
13
- describe("getGraphHealth", () => {
14
- it("returns runtime_unavailable when CLI is not available", async () => {
15
- mockIsAvailable.mockReturnValue(false);
16
- const result = await getGraphHealth({ vaultPath: "/vault" });
17
- expect(result.status).toBe("runtime_unavailable");
18
- expect(result.mode).toBe("graph-health");
19
- expect(result.diagnostics).toContain("Obsidian CLI not available");
20
- });
21
- it("runs all three checks by default", async () => {
22
- mockIsAvailable.mockReturnValue(true);
23
- mockExecCmd.mockReturnValue({ success: true, output: "" });
24
- await getGraphHealth({ vaultPath: "/vault" });
25
- expect(mockExecCmd).toHaveBeenCalledTimes(3);
26
- expect(mockExecCmd).toHaveBeenCalledWith(["orphans", "--vault", "/vault"]);
27
- expect(mockExecCmd).toHaveBeenCalledWith(["unresolved", "--vault", "/vault"]);
28
- expect(mockExecCmd).toHaveBeenCalledWith(["deadends", "--vault", "/vault"]);
29
- });
30
- it("runs only the specified check", async () => {
31
- mockIsAvailable.mockReturnValue(true);
32
- mockExecCmd.mockReturnValue({ success: true, output: "" });
33
- await getGraphHealth({ vaultPath: "/vault", check: "orphans" });
34
- expect(mockExecCmd).toHaveBeenCalledTimes(1);
35
- expect(mockExecCmd).toHaveBeenCalledWith(["orphans", "--vault", "/vault"]);
36
- });
37
- it("returns no_results when vault is healthy", async () => {
38
- mockIsAvailable.mockReturnValue(true);
39
- mockExecCmd.mockReturnValue({ success: true, output: "" });
40
- const result = await getGraphHealth({ vaultPath: "/vault" });
41
- expect(result.status).toBe("no_results");
42
- expect(result.results).toHaveLength(0);
43
- expect(result.summary).toContain("No issues");
44
- });
45
- it("parses orphan results into structured items", async () => {
46
- mockIsAvailable.mockReturnValue(true);
47
- mockExecCmd.mockImplementation((args) => {
48
- if (args[0] === "orphans") {
49
- return {
50
- success: true,
51
- output: "Projects/Abandoned.md\nInbox/Random.md",
52
- };
53
- }
54
- return { success: true, output: "" };
55
- });
56
- const result = await getGraphHealth({ vaultPath: "/vault" });
57
- expect(result.status).toBe("ok");
58
- const orphans = result.results.filter((r) => r.metadata?.check === "orphans");
59
- expect(orphans).toHaveLength(2);
60
- expect(orphans[0].title).toBe("Abandoned");
61
- expect(orphans[0].path).toBe("Projects/Abandoned.md");
62
- });
63
- it("parses unresolved links into structured items", async () => {
64
- mockIsAvailable.mockReturnValue(true);
65
- mockExecCmd.mockImplementation((args) => {
66
- if (args[0] === "unresolved") {
67
- return { success: true, output: "Missing Note\nAnother Missing" };
68
- }
69
- return { success: true, output: "" };
70
- });
71
- const result = await getGraphHealth({ vaultPath: "/vault" });
72
- const unresolved = result.results.filter((r) => r.metadata?.check === "unresolved");
73
- expect(unresolved).toHaveLength(2);
74
- expect(unresolved[0].title).toBe("Missing Note");
75
- });
76
- it("continues when one check fails but others succeed", async () => {
77
- mockIsAvailable.mockReturnValue(true);
78
- mockExecCmd.mockImplementation((args) => {
79
- if (args[0] === "orphans") {
80
- return { success: false, output: "", error: "timeout" };
81
- }
82
- return { success: true, output: "Inbox/note.md" };
83
- });
84
- const result = await getGraphHealth({ vaultPath: "/vault" });
85
- // Should still return results from successful checks
86
- expect(result.results.length).toBeGreaterThan(0);
87
- expect(result.diagnostics).toContain("orphans check failed: timeout");
88
- });
89
- it("respects the limit parameter", async () => {
90
- mockIsAvailable.mockReturnValue(true);
91
- const lines = Array.from({ length: 30 }, (_, i) => `Notes/note${i}.md`);
92
- mockExecCmd.mockReturnValue({ success: true, output: lines.join("\n") });
93
- const result = await getGraphHealth({
94
- vaultPath: "/vault",
95
- check: "orphans",
96
- limit: 5,
97
- });
98
- expect(result.results).toHaveLength(5);
99
- expect(result.truncated).toBe(true);
100
- });
101
- });
102
- //# sourceMappingURL=graph-health.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-health.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/graph-health.test.ts"],"names":[],"mappings":"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"}
@@ -1,85 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
- import fs from "fs-extra";
3
- import path from "node:path";
4
- import os from "node:os";
5
- import { addMember } from "../member.js";
6
- let tmpDir;
7
- beforeEach(async () => {
8
- tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "byoao-member-"));
9
- await fs.ensureDir(path.join(tmpDir, "People"));
10
- });
11
- afterEach(async () => {
12
- await fs.remove(tmpDir);
13
- });
14
- describe("addMember", () => {
15
- it("creates person note with correct frontmatter", async () => {
16
- const result = await addMember({
17
- vaultPath: tmpDir,
18
- name: "Alice",
19
- role: "Engineer",
20
- team: "Platform",
21
- });
22
- expect(result.filePath).toContain("People/Alice.md");
23
- const content = await fs.readFile(path.join(tmpDir, "People/Alice.md"), "utf-8");
24
- expect(content).toContain("type: person");
25
- expect(content).toContain('team: "Platform"');
26
- expect(content).toContain('role: "Engineer"');
27
- expect(content).toContain("status: active");
28
- });
29
- it("updates team index table", async () => {
30
- // Create a team index file
31
- const teamIndexContent = `---
32
- title: "Platform Team"
33
- type: reference
34
- ---
35
-
36
- # Platform Team
37
-
38
- ## Members
39
-
40
- | Name | Role |
41
- |------|------|
42
-
43
- ## Active Projects
44
- `;
45
- await fs.writeFile(path.join(tmpDir, "People/Platform Team.md"), teamIndexContent);
46
- await addMember({
47
- vaultPath: tmpDir,
48
- name: "Bob",
49
- role: "PM",
50
- team: "Platform",
51
- });
52
- const updated = await fs.readFile(path.join(tmpDir, "People/Platform Team.md"), "utf-8");
53
- expect(updated).toContain("[[Bob]]");
54
- expect(updated).toContain("PM");
55
- });
56
- it("updates AGENT.md wikilinks", async () => {
57
- const agentContent = `# Agent
58
-
59
- ## Team
60
-
61
- (No members added yet — create notes in People/)
62
- `;
63
- await fs.writeFile(path.join(tmpDir, "AGENT.md"), agentContent);
64
- const result = await addMember({
65
- vaultPath: tmpDir,
66
- name: "Carol",
67
- role: "Designer",
68
- team: "Platform",
69
- });
70
- expect(result.wikilinksAdded).toBeGreaterThanOrEqual(1);
71
- const agent = await fs.readFile(path.join(tmpDir, "AGENT.md"), "utf-8");
72
- expect(agent).toContain("[[Carol]]");
73
- expect(agent).not.toContain("No members added yet");
74
- });
75
- it("throws when person already exists", async () => {
76
- await fs.writeFile(path.join(tmpDir, "People/Alice.md"), "# Alice");
77
- await expect(addMember({
78
- vaultPath: tmpDir,
79
- name: "Alice",
80
- role: "Eng",
81
- team: "T",
82
- })).rejects.toThrow("already exists");
83
- });
84
- });
85
- //# sourceMappingURL=member.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"member.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/member.test.ts"],"names":[],"mappings":"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"}
@@ -1,71 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- vi.mock("../obsidian-cli.js", () => ({
3
- isObsidianCliAvailable: vi.fn(),
4
- execObsidianCmd: vi.fn(),
5
- }));
6
- import { readNote } from "../note-read.js";
7
- import { isObsidianCliAvailable, execObsidianCmd } from "../obsidian-cli.js";
8
- const mockIsAvailable = vi.mocked(isObsidianCliAvailable);
9
- const mockExecCmd = vi.mocked(execObsidianCmd);
10
- beforeEach(() => {
11
- vi.resetAllMocks();
12
- });
13
- describe("readNote", () => {
14
- it("returns runtime_unavailable when CLI is not available", async () => {
15
- mockIsAvailable.mockReturnValue(false);
16
- const result = await readNote({ vaultPath: "/vault", file: "MyNote" });
17
- expect(result.status).toBe("runtime_unavailable");
18
- expect(result.mode).toBe("read");
19
- expect(result.diagnostics).toContain("Obsidian CLI not available");
20
- });
21
- it("returns runtime_unavailable when CLI command fails", async () => {
22
- mockIsAvailable.mockReturnValue(true);
23
- mockExecCmd.mockReturnValue({
24
- success: false,
25
- output: "",
26
- error: "Note not found",
27
- });
28
- const result = await readNote({ vaultPath: "/vault", file: "Missing" });
29
- expect(result.status).toBe("runtime_unavailable");
30
- expect(result.diagnostics[0]).toContain("Note not found");
31
- });
32
- it("returns note content as a single result item", async () => {
33
- mockIsAvailable.mockReturnValue(true);
34
- mockExecCmd.mockReturnValue({
35
- success: true,
36
- output: "---\ntype: project\ntags: [active]\n---\n\n# Refund Automation\n\nProject details here.",
37
- });
38
- const result = await readNote({ vaultPath: "/vault", file: "Refund Automation" });
39
- expect(result.status).toBe("ok");
40
- expect(result.results).toHaveLength(1);
41
- expect(result.results[0].title).toBe("Refund Automation");
42
- expect(result.results[0].file).toBe("Refund Automation");
43
- expect(result.results[0].snippet).toContain("Project details here");
44
- });
45
- it("returns no_results when CLI returns empty output", async () => {
46
- mockIsAvailable.mockReturnValue(true);
47
- mockExecCmd.mockReturnValue({ success: true, output: "" });
48
- const result = await readNote({ vaultPath: "/vault", file: "Empty" });
49
- expect(result.status).toBe("no_results");
50
- expect(result.results).toHaveLength(0);
51
- });
52
- it("passes vault path and file to CLI correctly", async () => {
53
- mockIsAvailable.mockReturnValue(true);
54
- mockExecCmd.mockReturnValue({ success: true, output: "content" });
55
- await readNote({ vaultPath: "/my/vault", file: "My Note" });
56
- expect(mockExecCmd).toHaveBeenCalledWith([
57
- "read",
58
- "--vault",
59
- "/my/vault",
60
- "My Note",
61
- ]);
62
- });
63
- it("truncates snippet for very long notes", async () => {
64
- mockIsAvailable.mockReturnValue(true);
65
- const longContent = "a".repeat(500);
66
- mockExecCmd.mockReturnValue({ success: true, output: longContent });
67
- const result = await readNote({ vaultPath: "/vault", file: "Long" });
68
- expect(result.results[0].snippet.length).toBeLessThanOrEqual(240);
69
- });
70
- });
71
- //# sourceMappingURL=note-read.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"note-read.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/note-read.test.ts"],"names":[],"mappings":"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"}
@@ -1,108 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
- // vi.mock factories are hoisted above variable declarations, so mocks must be
3
- // created with vi.hoisted() to be accessible inside factory callbacks.
4
- const { mockExecSync, mockSpawnSync, mockPlatform } = vi.hoisted(() => ({
5
- mockExecSync: vi.fn(),
6
- mockSpawnSync: vi.fn(),
7
- mockPlatform: vi.fn().mockReturnValue("darwin"),
8
- }));
9
- vi.mock("node:child_process", () => ({
10
- execSync: mockExecSync,
11
- spawnSync: mockSpawnSync,
12
- }));
13
- vi.mock("node:os", () => ({
14
- platform: mockPlatform,
15
- }));
16
- import { execObsidianCmd, isObsidianCliAvailable, } from "../obsidian-cli.js";
17
- beforeEach(() => {
18
- vi.resetAllMocks();
19
- mockPlatform.mockReturnValue("darwin");
20
- });
21
- describe("isObsidianCliAvailable", () => {
22
- it("uses `which` on macOS and returns true when the binary is found", () => {
23
- mockPlatform.mockReturnValue("darwin");
24
- mockExecSync.mockReturnValue("/Applications/Obsidian.app/Contents/MacOS/obsidian\n");
25
- expect(isObsidianCliAvailable()).toBe(true);
26
- expect(mockExecSync).toHaveBeenCalledWith("which obsidian", expect.objectContaining({ stdio: "pipe" }));
27
- });
28
- it("uses `which` on Linux and returns true when the binary is found", () => {
29
- mockPlatform.mockReturnValue("linux");
30
- mockExecSync.mockReturnValue("/usr/bin/obsidian\n");
31
- expect(isObsidianCliAvailable()).toBe(true);
32
- expect(mockExecSync).toHaveBeenCalledWith("which obsidian", expect.objectContaining({ stdio: "pipe" }));
33
- });
34
- it("uses `where` on Windows and returns true when the binary is found", () => {
35
- mockPlatform.mockReturnValue("win32");
36
- mockExecSync.mockReturnValue("C:\\Users\\dev\\AppData\\Local\\Obsidian\\obsidian.exe\n");
37
- expect(isObsidianCliAvailable()).toBe(true);
38
- expect(mockExecSync).toHaveBeenCalledWith("where obsidian", expect.objectContaining({ stdio: "pipe" }));
39
- });
40
- it("returns false when the binary is not found on any platform", () => {
41
- mockExecSync.mockImplementation(() => {
42
- throw new Error("not found");
43
- });
44
- expect(isObsidianCliAvailable()).toBe(false);
45
- });
46
- });
47
- describe("execObsidianCmd", () => {
48
- it("returns success when Obsidian exits 0 even if installer warning is present", () => {
49
- mockSpawnSync.mockReturnValue({
50
- stdout: "2026-04-07 Loading updated app package /tmp/obsidian.asar\n" +
51
- "Your Obsidian installer is out of date. Please download the latest installer which includes better CLI support: https://obsidian.md/download\n" +
52
- "Actual result data\n",
53
- stderr: "",
54
- status: 0,
55
- signal: null,
56
- error: undefined,
57
- });
58
- const result = execObsidianCmd(["help"]);
59
- expect(result.success).toBe(true);
60
- expect(result.output).toContain("Actual result data");
61
- });
62
- it("classifies missing CLI registrations", () => {
63
- const error = Object.assign(new Error("spawnSync obsidian ENOENT"), {
64
- code: "ENOENT",
65
- });
66
- mockSpawnSync.mockReturnValue({
67
- stdout: "",
68
- stderr: "",
69
- status: null,
70
- signal: null,
71
- error,
72
- });
73
- const result = execObsidianCmd(["read", "file=Test"]);
74
- expect(result.success).toBe(false);
75
- expect(result.reason).toBe("cli_not_registered");
76
- expect(result.guidance).toContain("Enable Obsidian CLI in Settings -> General -> Command line interface.");
77
- });
78
- it("returns sanitized output on success", () => {
79
- mockSpawnSync.mockReturnValue({
80
- stdout: "2026-04-07 Loading updated app package /tmp/obsidian.asar\nHello\n",
81
- stderr: "",
82
- status: 0,
83
- signal: null,
84
- error: undefined,
85
- });
86
- const result = execObsidianCmd(["read", "file=Hello"]);
87
- expect(result.success).toBe(true);
88
- expect(result.output).toBe("Hello");
89
- });
90
- it("prefixes vault-scoped commands with vault=<basename>", () => {
91
- mockSpawnSync.mockReturnValue({
92
- stdout: "",
93
- stderr: "",
94
- status: 0,
95
- signal: null,
96
- error: undefined,
97
- });
98
- execObsidianCmd(["search:context", "query=test"], {
99
- vaultPath: "/Users/dev/Documents/Tech & News",
100
- });
101
- expect(mockSpawnSync).toHaveBeenCalledWith("obsidian", ["vault=Tech & News", "search:context", "query=test"], expect.objectContaining({
102
- stdio: "pipe",
103
- encoding: "utf-8",
104
- timeout: 10000,
105
- }));
106
- });
107
- });
108
- //# sourceMappingURL=obsidian-cli.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"obsidian-cli.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/obsidian-cli.test.ts"],"names":[],"mappings":"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"}
@@ -1,93 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- // Mock obsidian-cli before importing the module under test
3
- vi.mock("../obsidian-cli.js", () => ({
4
- isObsidianCliAvailable: vi.fn(),
5
- execObsidianCmd: vi.fn(),
6
- }));
7
- import { searchVault } from "../search-vault.js";
8
- import { isObsidianCliAvailable, execObsidianCmd } from "../obsidian-cli.js";
9
- const mockIsAvailable = vi.mocked(isObsidianCliAvailable);
10
- const mockExecCmd = vi.mocked(execObsidianCmd);
11
- beforeEach(() => {
12
- vi.resetAllMocks();
13
- });
14
- describe("searchVault", () => {
15
- it("returns runtime_unavailable when CLI is not available", async () => {
16
- mockIsAvailable.mockReturnValue(false);
17
- const result = await searchVault({ vaultPath: "/vault", query: "test" });
18
- expect(result.status).toBe("runtime_unavailable");
19
- expect(result.mode).toBe("search:context");
20
- expect(result.fallback).toBe("none");
21
- expect(result.diagnostics).toContain("Obsidian CLI not available");
22
- });
23
- it("returns runtime_unavailable when CLI command fails", async () => {
24
- mockIsAvailable.mockReturnValue(true);
25
- mockExecCmd.mockReturnValue({
26
- success: false,
27
- output: "",
28
- error: "Vault not found",
29
- });
30
- const result = await searchVault({ vaultPath: "/vault", query: "test" });
31
- expect(result.status).toBe("runtime_unavailable");
32
- expect(result.diagnostics[0]).toContain("Vault not found");
33
- });
34
- it("returns no_results when CLI returns empty output", async () => {
35
- mockIsAvailable.mockReturnValue(true);
36
- mockExecCmd.mockReturnValue({ success: true, output: "" });
37
- const result = await searchVault({ vaultPath: "/vault", query: "test" });
38
- expect(result.status).toBe("no_results");
39
- expect(result.results).toHaveLength(0);
40
- });
41
- it("parses CLI output into structured results", async () => {
42
- mockIsAvailable.mockReturnValue(true);
43
- mockExecCmd.mockReturnValue({
44
- success: true,
45
- output: [
46
- "Projects/Refund Automation.md:Owner handoff for refund automation workflow",
47
- "Daily/2026-03-20.md:Discussed refund automation timeline with team",
48
- ].join("\n"),
49
- });
50
- const result = await searchVault({ vaultPath: "/vault", query: "refund" });
51
- expect(result.status).toBe("ok");
52
- expect(result.results).toHaveLength(2);
53
- expect(result.results[0].title).toBe("Refund Automation");
54
- expect(result.results[0].path).toBe("Projects/Refund Automation.md");
55
- expect(result.results[0].file).toBe("Refund Automation");
56
- expect(result.results[0].snippet).toContain("refund automation");
57
- });
58
- it("respects the limit parameter", async () => {
59
- mockIsAvailable.mockReturnValue(true);
60
- const lines = Array.from({ length: 30 }, (_, i) => `Notes/note${i}.md:content line ${i}`);
61
- mockExecCmd.mockReturnValue({ success: true, output: lines.join("\n") });
62
- const result = await searchVault({
63
- vaultPath: "/vault",
64
- query: "content",
65
- limit: 5,
66
- });
67
- expect(result.results).toHaveLength(5);
68
- expect(result.truncated).toBe(true);
69
- expect(result.totalMatches).toBe(30);
70
- });
71
- it("truncates snippets to MAX_SNIPPET_LENGTH", async () => {
72
- mockIsAvailable.mockReturnValue(true);
73
- const longLine = "a".repeat(500);
74
- mockExecCmd.mockReturnValue({
75
- success: true,
76
- output: `Notes/long.md:${longLine}`,
77
- });
78
- const result = await searchVault({ vaultPath: "/vault", query: "a" });
79
- expect(result.results[0].snippet.length).toBeLessThanOrEqual(240);
80
- });
81
- it("passes vault path and query to CLI correctly", async () => {
82
- mockIsAvailable.mockReturnValue(true);
83
- mockExecCmd.mockReturnValue({ success: true, output: "" });
84
- await searchVault({ vaultPath: "/my/vault", query: "hello world" });
85
- expect(mockExecCmd).toHaveBeenCalledWith([
86
- "search:context",
87
- "--vault",
88
- "/my/vault",
89
- "hello world",
90
- ]);
91
- });
92
- });
93
- //# sourceMappingURL=search-vault.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-vault.test.js","sourceRoot":"","sources":["../../../src/vault/__tests__/search-vault.test.ts"],"names":[],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- import { fs } from "../lib/cjs-modules.js";
2
- import path from "node:path";
3
- export async function addGlossaryTerm(input) {
4
- const { vaultPath, term, definition, domain } = input;
5
- const glossaryPath = path.join(vaultPath, "Knowledge/Glossary.md");
6
- if (!(await fs.pathExists(glossaryPath))) {
7
- throw new Error(`Glossary not found at: ${glossaryPath}`);
8
- }
9
- let content = await fs.readFile(glossaryPath, "utf-8");
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*$)/);
13
- if (tableMatch) {
14
- const [fullMatch, tableHeader, existingRows, trailing] = tableMatch;
15
- const updatedRows = existingRows.trim()
16
- ? `${existingRows.trim()}\n${newRow}`
17
- : newRow;
18
- content = content.replace(fullMatch, `${tableHeader}${updatedRows}\n`);
19
- }
20
- else {
21
- // Fallback: append to end of file
22
- content = content.trimEnd() + `\n${newRow}\n`;
23
- }
24
- await fs.writeFile(glossaryPath, content);
25
- return { glossaryPath, termAdded: term };
26
- }
27
- //# sourceMappingURL=glossary.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../src/vault/glossary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAC3C,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"}