@archznn/crewloop-skills 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.
Files changed (250) hide show
  1. package/README.md +4 -16
  2. package/package.json +3 -3
  3. package/packages/cli/dist/agents.js +1 -1
  4. package/packages/cli/dist/agents.js.map +1 -1
  5. package/packages/cli/dist/cli.d.ts.map +1 -1
  6. package/packages/cli/dist/cli.js +31 -37
  7. package/packages/cli/dist/cli.js.map +1 -1
  8. package/packages/cli/dist/hooks.d.ts +6 -4
  9. package/packages/cli/dist/hooks.d.ts.map +1 -1
  10. package/packages/cli/dist/hooks.js +258 -98
  11. package/packages/cli/dist/hooks.js.map +1 -1
  12. package/packages/cli/dist/tests/cli.test.js +21 -0
  13. package/packages/cli/dist/tests/cli.test.js.map +1 -1
  14. package/packages/cli/dist/tests/hooks.test.js +253 -27
  15. package/packages/cli/dist/tests/hooks.test.js.map +1 -1
  16. package/references/conventions.md +1 -10
  17. package/references/workflow.md +1 -1
  18. package/servers/dashboard/README.md +55 -1
  19. package/servers/dashboard/bin/crewloop-shim.js +4 -0
  20. package/servers/dashboard/dist/adapters/agy.d.ts +19 -0
  21. package/servers/dashboard/dist/adapters/agy.d.ts.map +1 -0
  22. package/servers/dashboard/dist/adapters/agy.js +108 -0
  23. package/servers/dashboard/dist/adapters/agy.js.map +1 -0
  24. package/servers/dashboard/dist/adapters/codex.d.ts.map +1 -1
  25. package/servers/dashboard/dist/adapters/codex.js +2 -0
  26. package/servers/dashboard/dist/adapters/codex.js.map +1 -1
  27. package/servers/dashboard/dist/adapters/kimi.d.ts +1 -1
  28. package/servers/dashboard/dist/adapters/kimi.d.ts.map +1 -1
  29. package/servers/dashboard/dist/adapters/kimi.js +9 -0
  30. package/servers/dashboard/dist/adapters/kimi.js.map +1 -1
  31. package/servers/dashboard/dist/adapters/shim.d.ts +1 -1
  32. package/servers/dashboard/dist/adapters/shim.d.ts.map +1 -1
  33. package/servers/dashboard/dist/adapters/shim.js +32 -11
  34. package/servers/dashboard/dist/adapters/shim.js.map +1 -1
  35. package/servers/dashboard/dist/adapters/shim.test.js +46 -4
  36. package/servers/dashboard/dist/adapters/shim.test.js.map +1 -1
  37. package/servers/dashboard/dist/lib/constants.d.ts +5 -0
  38. package/servers/dashboard/dist/lib/constants.d.ts.map +1 -0
  39. package/servers/dashboard/dist/lib/constants.js +46 -0
  40. package/servers/dashboard/dist/lib/constants.js.map +1 -0
  41. package/servers/dashboard/dist/lib/format.d.ts +6 -0
  42. package/servers/dashboard/dist/lib/format.d.ts.map +1 -0
  43. package/servers/dashboard/dist/lib/format.js +52 -0
  44. package/servers/dashboard/dist/lib/format.js.map +1 -0
  45. package/servers/dashboard/dist/lib/graph.d.ts +22 -0
  46. package/servers/dashboard/dist/lib/graph.d.ts.map +1 -0
  47. package/servers/dashboard/dist/lib/graph.js +45 -0
  48. package/servers/dashboard/dist/lib/graph.js.map +1 -0
  49. package/servers/dashboard/dist/lib/invocations.d.ts +32 -0
  50. package/servers/dashboard/dist/lib/invocations.d.ts.map +1 -0
  51. package/servers/dashboard/dist/lib/invocations.js +135 -0
  52. package/servers/dashboard/dist/lib/invocations.js.map +1 -0
  53. package/servers/dashboard/dist/lib/invocations.test.d.ts +2 -0
  54. package/servers/dashboard/dist/lib/invocations.test.d.ts.map +1 -0
  55. package/servers/dashboard/dist/lib/invocations.test.js +68 -0
  56. package/servers/dashboard/dist/lib/invocations.test.js.map +1 -0
  57. package/servers/dashboard/dist/lib/paths.d.ts +2 -0
  58. package/servers/dashboard/dist/lib/paths.d.ts.map +1 -0
  59. package/servers/dashboard/dist/lib/paths.js +40 -0
  60. package/servers/dashboard/dist/lib/paths.js.map +1 -0
  61. package/servers/dashboard/dist/presenter.d.ts.map +1 -1
  62. package/servers/dashboard/dist/presenter.js +2 -0
  63. package/servers/dashboard/dist/presenter.js.map +1 -1
  64. package/servers/dashboard/dist/public/assets/index-DjmMKbPN.css +1 -0
  65. package/servers/dashboard/dist/public/assets/index-DzOqMleZ.js +5323 -0
  66. package/servers/dashboard/dist/public/assets/index-DzOqMleZ.js.map +1 -0
  67. package/servers/dashboard/dist/public/index.html +16 -0
  68. package/servers/dashboard/dist/server.d.ts.map +1 -1
  69. package/servers/dashboard/dist/server.js +5 -1
  70. package/servers/dashboard/dist/server.js.map +1 -1
  71. package/servers/dashboard/dist/skills/infer.d.ts.map +1 -1
  72. package/servers/dashboard/dist/skills/infer.js +0 -6
  73. package/servers/dashboard/dist/skills/infer.js.map +1 -1
  74. package/servers/dashboard/dist/skills/infer.test.js +10 -3
  75. package/servers/dashboard/dist/skills/infer.test.js.map +1 -1
  76. package/servers/dashboard/dist/skills/mapping.d.ts +0 -3
  77. package/servers/dashboard/dist/skills/mapping.d.ts.map +1 -1
  78. package/servers/dashboard/dist/skills/mapping.js +0 -18
  79. package/servers/dashboard/dist/skills/mapping.js.map +1 -1
  80. package/servers/dashboard/dist/skills/registry.d.ts.map +1 -1
  81. package/servers/dashboard/dist/skills/registry.js +0 -1
  82. package/servers/dashboard/dist/skills/registry.js.map +1 -1
  83. package/servers/dashboard/dist/tests/adapters.test.d.ts +2 -0
  84. package/servers/dashboard/dist/tests/adapters.test.d.ts.map +1 -0
  85. package/servers/dashboard/dist/tests/adapters.test.js +180 -0
  86. package/servers/dashboard/dist/tests/adapters.test.js.map +1 -0
  87. package/servers/dashboard/dist/tests/lib-helpers.test.d.ts +2 -0
  88. package/servers/dashboard/dist/tests/lib-helpers.test.d.ts.map +1 -0
  89. package/servers/dashboard/dist/tests/lib-helpers.test.js +123 -0
  90. package/servers/dashboard/dist/tests/lib-helpers.test.js.map +1 -0
  91. package/servers/dashboard/dist/tests/shim.test.d.ts +2 -0
  92. package/servers/dashboard/dist/tests/shim.test.d.ts.map +1 -0
  93. package/servers/dashboard/dist/tests/shim.test.js +133 -0
  94. package/servers/dashboard/dist/tests/shim.test.js.map +1 -0
  95. package/servers/dashboard/dist/types.d.ts +5 -2
  96. package/servers/dashboard/dist/types.d.ts.map +1 -1
  97. package/servers/dashboard/package.json +24 -6
  98. package/servers/dashboard/src/adapters/agy.ts +136 -0
  99. package/servers/dashboard/src/adapters/codex.ts +2 -0
  100. package/servers/dashboard/src/adapters/kimi.ts +11 -1
  101. package/servers/dashboard/src/adapters/shim.test.ts +57 -4
  102. package/servers/dashboard/src/adapters/shim.ts +31 -11
  103. package/servers/dashboard/src/lib/constants.ts +44 -0
  104. package/servers/dashboard/src/lib/format.ts +44 -0
  105. package/servers/dashboard/src/lib/graph.ts +69 -0
  106. package/servers/dashboard/src/lib/invocations.test.ts +70 -0
  107. package/servers/dashboard/src/lib/invocations.ts +172 -0
  108. package/servers/dashboard/src/lib/paths.ts +35 -0
  109. package/servers/dashboard/src/presenter.ts +2 -0
  110. package/servers/dashboard/src/server.ts +5 -1
  111. package/servers/dashboard/src/skills/infer.test.ts +11 -3
  112. package/servers/dashboard/src/skills/infer.ts +1 -8
  113. package/servers/dashboard/src/skills/mapping.ts +0 -20
  114. package/servers/dashboard/src/skills/registry.ts +0 -1
  115. package/servers/dashboard/src/tests/adapters.test.ts +198 -0
  116. package/servers/dashboard/src/tests/lib-helpers.test.ts +133 -0
  117. package/servers/dashboard/src/tests/shim.test.ts +153 -0
  118. package/servers/dashboard/src/types.ts +5 -3
  119. package/servers/dashboard/ui/index.html +15 -0
  120. package/servers/dashboard/ui/postcss.config.js +6 -0
  121. package/servers/dashboard/ui/src/App.tsx +360 -0
  122. package/servers/dashboard/ui/src/components/ActiveSkillPanel.tsx +69 -0
  123. package/servers/dashboard/ui/src/components/ActivityGraph.tsx +74 -0
  124. package/servers/dashboard/ui/src/components/CommandPalette.tsx +200 -0
  125. package/servers/dashboard/ui/src/components/FileActivity.tsx +20 -0
  126. package/servers/dashboard/ui/src/components/FileDiff.tsx +68 -0
  127. package/servers/dashboard/ui/src/components/FileList.tsx +64 -0
  128. package/servers/dashboard/ui/src/components/FilterBar.tsx +208 -0
  129. package/servers/dashboard/ui/src/components/Network3D.tsx +178 -0
  130. package/servers/dashboard/ui/src/components/SessionSelector.tsx +95 -0
  131. package/servers/dashboard/ui/src/components/Sidebar.tsx +110 -0
  132. package/servers/dashboard/ui/src/components/TelemetryPanel.tsx +57 -0
  133. package/servers/dashboard/ui/src/components/Timeline.tsx +57 -0
  134. package/servers/dashboard/ui/src/components/TimelineRow.tsx +112 -0
  135. package/servers/dashboard/ui/src/components/TopBar.tsx +116 -0
  136. package/servers/dashboard/ui/src/components/ViewHeader.tsx +19 -0
  137. package/servers/dashboard/ui/src/components/ui/Icon.tsx +105 -0
  138. package/servers/dashboard/ui/src/components/ui/StatusBadge.tsx +19 -0
  139. package/servers/dashboard/ui/src/components/views/FilesView.tsx +23 -0
  140. package/servers/dashboard/ui/src/components/views/NetworkView.tsx +20 -0
  141. package/servers/dashboard/ui/src/components/views/Overview.tsx +135 -0
  142. package/servers/dashboard/ui/src/components/views/SessionsView.tsx +84 -0
  143. package/servers/dashboard/ui/src/components/views/SettingsView.tsx +138 -0
  144. package/servers/dashboard/ui/src/components/views/SkillsView.tsx +92 -0
  145. package/servers/dashboard/ui/src/components/views/TimelineView.tsx +46 -0
  146. package/servers/dashboard/ui/src/contexts/FilterContext.tsx +41 -0
  147. package/servers/dashboard/ui/src/contexts/PinnedSessionsContext.tsx +80 -0
  148. package/servers/dashboard/ui/src/contexts/SettingsContext.tsx +60 -0
  149. package/servers/dashboard/ui/src/hooks/useCommandPalette.ts +36 -0
  150. package/servers/dashboard/ui/src/hooks/useKeyboardShortcut.ts +38 -0
  151. package/servers/dashboard/ui/src/hooks/useNow.ts +12 -0
  152. package/servers/dashboard/ui/src/hooks/useReducedMotion.ts +15 -0
  153. package/servers/dashboard/ui/src/hooks/useSessions.ts +64 -0
  154. package/servers/dashboard/ui/src/hooks/useTheme.ts +30 -0
  155. package/servers/dashboard/ui/src/hooks/useViewport.ts +19 -0
  156. package/servers/dashboard/ui/src/hooks/useWebSocket.ts +118 -0
  157. package/servers/dashboard/ui/src/lib/export.test.ts +33 -0
  158. package/servers/dashboard/ui/src/lib/export.ts +39 -0
  159. package/servers/dashboard/ui/src/lib/filter.test.ts +95 -0
  160. package/servers/dashboard/ui/src/lib/filter.ts +178 -0
  161. package/servers/dashboard/ui/src/lib/format.test.ts +25 -0
  162. package/servers/dashboard/ui/src/lib/search.test.ts +52 -0
  163. package/servers/dashboard/ui/src/lib/search.ts +60 -0
  164. package/servers/dashboard/ui/src/lib/settings.test.ts +50 -0
  165. package/servers/dashboard/ui/src/lib/settings.ts +56 -0
  166. package/servers/dashboard/ui/src/lib/types.ts +124 -0
  167. package/servers/dashboard/ui/src/main.tsx +19 -0
  168. package/servers/dashboard/ui/src/styles/index.css +155 -0
  169. package/servers/dashboard/ui/tailwind.config.js +45 -0
  170. package/servers/dashboard/ui/tsconfig.json +33 -0
  171. package/servers/dashboard/ui/tsconfig.node.json +10 -0
  172. package/servers/dashboard/ui/vite.config.ts +37 -0
  173. package/servers/dashboard/ui/vitest.config.ts +8 -0
  174. package/skills/accessibility-auditor/SKILL.md +0 -20
  175. package/skills/architect/SKILL.md +0 -45
  176. package/skills/designer/SKILL.md +0 -30
  177. package/skills/docs-writer/SKILL.md +0 -13
  178. package/skills/engineer/SKILL.md +0 -30
  179. package/skills/maintainer/SKILL.md +0 -20
  180. package/skills/orchestrator/SKILL.md +0 -13
  181. package/skills/product-manager/SKILL.md +0 -20
  182. package/skills/researcher/SKILL.md +0 -20
  183. package/skills/reviewer/SKILL.md +0 -30
  184. package/skills/security-guard/SKILL.md +0 -20
  185. package/skills/shipper/SKILL.md +0 -33
  186. package/skills/tester/SKILL.md +0 -20
  187. package/packages/cli/dist/mcp.d.ts +0 -28
  188. package/packages/cli/dist/mcp.d.ts.map +0 -1
  189. package/packages/cli/dist/mcp.js +0 -148
  190. package/packages/cli/dist/mcp.js.map +0 -1
  191. package/packages/cli/dist/tests/mcp.test.d.ts +0 -2
  192. package/packages/cli/dist/tests/mcp.test.d.ts.map +0 -1
  193. package/packages/cli/dist/tests/mcp.test.js +0 -232
  194. package/packages/cli/dist/tests/mcp.test.js.map +0 -1
  195. package/references/obsidian-mcp-usage.md +0 -190
  196. package/servers/dashboard/public/app.js +0 -516
  197. package/servers/dashboard/public/index.html +0 -96
  198. package/servers/dashboard/public/styles.css +0 -819
  199. package/servers/obsidian-mcp/README.md +0 -82
  200. package/servers/obsidian-mcp/pyproject.toml +0 -32
  201. package/servers/obsidian-mcp/src/obsidian_mcp/__init__.py +0 -0
  202. package/servers/obsidian-mcp/src/obsidian_mcp/config.py +0 -47
  203. package/servers/obsidian-mcp/src/obsidian_mcp/indexer/__init__.py +0 -0
  204. package/servers/obsidian-mcp/src/obsidian_mcp/indexer/embeddings.py +0 -105
  205. package/servers/obsidian-mcp/src/obsidian_mcp/indexer/indexer.py +0 -79
  206. package/servers/obsidian-mcp/src/obsidian_mcp/indexer/store.py +0 -141
  207. package/servers/obsidian-mcp/src/obsidian_mcp/indexer/sync.py +0 -37
  208. package/servers/obsidian-mcp/src/obsidian_mcp/learning/__init__.py +0 -0
  209. package/servers/obsidian-mcp/src/obsidian_mcp/learning/detector.py +0 -66
  210. package/servers/obsidian-mcp/src/obsidian_mcp/learning/note_generator.py +0 -40
  211. package/servers/obsidian-mcp/src/obsidian_mcp/main.py +0 -4
  212. package/servers/obsidian-mcp/src/obsidian_mcp/models.py +0 -42
  213. package/servers/obsidian-mcp/src/obsidian_mcp/privacy/__init__.py +0 -0
  214. package/servers/obsidian-mcp/src/obsidian_mcp/privacy/filter.py +0 -68
  215. package/servers/obsidian-mcp/src/obsidian_mcp/rag/__init__.py +0 -0
  216. package/servers/obsidian-mcp/src/obsidian_mcp/rag/engine.py +0 -50
  217. package/servers/obsidian-mcp/src/obsidian_mcp/rag/graph_search.py +0 -55
  218. package/servers/obsidian-mcp/src/obsidian_mcp/rag/text_search.py +0 -37
  219. package/servers/obsidian-mcp/src/obsidian_mcp/rag/vector_search.py +0 -118
  220. package/servers/obsidian-mcp/src/obsidian_mcp/server.py +0 -61
  221. package/servers/obsidian-mcp/src/obsidian_mcp/tools/__init__.py +0 -0
  222. package/servers/obsidian-mcp/src/obsidian_mcp/tools/create.py +0 -43
  223. package/servers/obsidian-mcp/src/obsidian_mcp/tools/delete.py +0 -16
  224. package/servers/obsidian-mcp/src/obsidian_mcp/tools/learn.py +0 -42
  225. package/servers/obsidian-mcp/src/obsidian_mcp/tools/list.py +0 -16
  226. package/servers/obsidian-mcp/src/obsidian_mcp/tools/read.py +0 -15
  227. package/servers/obsidian-mcp/src/obsidian_mcp/tools/registry.py +0 -130
  228. package/servers/obsidian-mcp/src/obsidian_mcp/tools/related.py +0 -20
  229. package/servers/obsidian-mcp/src/obsidian_mcp/tools/search.py +0 -26
  230. package/servers/obsidian-mcp/src/obsidian_mcp/tools/sync.py +0 -22
  231. package/servers/obsidian-mcp/src/obsidian_mcp/tools/update.py +0 -34
  232. package/servers/obsidian-mcp/src/obsidian_mcp/vault/__init__.py +0 -0
  233. package/servers/obsidian-mcp/src/obsidian_mcp/vault/parser.py +0 -82
  234. package/servers/obsidian-mcp/src/obsidian_mcp/vault/repository.py +0 -68
  235. package/servers/obsidian-mcp/src/obsidian_mcp/vault/writer.py +0 -61
  236. package/servers/obsidian-mcp/tests/conftest.py +0 -39
  237. package/servers/obsidian-mcp/tests/test_async_tools.py +0 -87
  238. package/servers/obsidian-mcp/tests/test_edge_cases.py +0 -59
  239. package/servers/obsidian-mcp/tests/test_indexer.py +0 -27
  240. package/servers/obsidian-mcp/tests/test_integration.py +0 -90
  241. package/servers/obsidian-mcp/tests/test_learning.py +0 -34
  242. package/servers/obsidian-mcp/tests/test_privacy.py +0 -31
  243. package/servers/obsidian-mcp/tests/test_privacy_config.py +0 -44
  244. package/servers/obsidian-mcp/tests/test_rag.py +0 -64
  245. package/servers/obsidian-mcp/tests/test_read_raw.py +0 -37
  246. package/servers/obsidian-mcp/tests/test_tfidf_fallback.py +0 -54
  247. package/servers/obsidian-mcp/tests/test_tools.py +0 -108
  248. package/servers/obsidian-mcp/tests/test_vault.py +0 -103
  249. package/servers/obsidian-mcp/tests/test_writer.py +0 -139
  250. package/skills/obsidian-second-brain/SKILL.md +0 -298
@@ -16,36 +16,6 @@ Before taking any action, you MUST read the global conventions in [conventions.m
16
16
 
17
17
  ---
18
18
 
19
- ## MEMORY & CONTEXT
20
-
21
- **Always invoke the `obsidian-second-brain` skill via the `Skill` tool.**
22
- Never read or write files inside `~/.lea` directly with `Read`, `Edit`, `Write`, or `Bash`.
23
-
24
- At the start of the task, the `obsidian-second-brain` skill will search and read the relevant layers for this role.
25
- At the end of the task, it will persist outcomes to the correct layers.
26
-
27
- This skill's targets:
28
- - **Read at start:** commit, branch, and project conventions
29
- - **Persist at end:** shipping log to journal; archived spec links updated in `Journal/loop-engineering-agents.md`; updated conventions to knowledge; active context to curated memory
30
-
31
- ## AFK MODE & ROLE PREFIX
32
-
33
- **Role prefix:** [SHIPPER SHIPPING]
34
-
35
- Print this prefix on its own line before the first line of every response.
36
-
37
- **AFK mode activation:**
38
- - User says "AFK", "estarei AFK", "modo AFK", "vou ficar AFK", or similar explicit marker.
39
- - `MEMORY.md` contains `afk: true`.
40
-
41
- **AFK mode behavior:**
42
- - Skip the navigation menu at the end.
43
- - State the next skill being activated.
44
- - Load the next skill via the Skill tool (do not wait for user choice).
45
-
46
- **Next skill:** Orchestrator (always).
47
-
48
- ---
49
19
 
50
20
  ## WORKFLOW
51
21
 
@@ -342,9 +312,6 @@ git stash pop
342
312
  # Archive specs before committing (move from changes/ to archive/)
343
313
  # Example: mv specs/changes/001-auth-jwt specs/archive/2024-01-15-001-auth-jwt/
344
314
 
345
- # Update Journal spec links after archiving
346
- - Invoke `obsidian-second-brain` to move the spec link from `## Specs / ### Active` to `## Specs / ### Archived` in `Journal/loop-engineering-agents.md`, updating the path to the archive location (e.g. `../../specs/archive/YYYY-MM-DD-NNN-name/specs/spec.md`). Do NOT read or write `~/.lea` directly.
347
-
348
315
  # Stage all changes
349
316
  git add -A
350
317
 
@@ -25,26 +25,6 @@ You do NOT write production code. You do NOT run git operations. You do NOT repl
25
25
 
26
26
  ---
27
27
 
28
- ## MEMORY & CONTEXT
29
-
30
- **Always invoke the `obsidian-second-brain` skill via the `Skill` tool.**
31
- Never read or write files inside `~/.lea` directly with `Read`, `Edit`, `Write`, or `Bash`.
32
-
33
- At the start of the task, the `obsidian-second-brain` skill will search and read the relevant layers for this role.
34
- At the end of the task, it will persist outcomes to the correct layers.
35
-
36
- This skill's targets:
37
- - **Read at start:** prior testing decisions, bug patterns, and acceptance criteria
38
- - **Persist at end:** test strategies to knowledge; bug reproductions to journal; active context to curated memory
39
-
40
- ### MCP Tools Reference
41
-
42
- | Tool | When to use |
43
- |------|-------------|
44
- | `search_notes` | Find prior testing heuristics in `Knowledge/` and bug patterns in `Journal/bugs*`. |
45
- | `learn_from_text` | Persist a testing heuristic or decision discovered during review. |
46
-
47
- ---
48
28
 
49
29
  ## WORKFLOW
50
30
 
@@ -1,28 +0,0 @@
1
- export type McpInstallStep = 'check_python' | 'create_venv' | 'install_package' | 'expose_binary' | 'complete';
2
- export interface McpInstallProgress {
3
- step: McpInstallStep;
4
- message: string;
5
- }
6
- export interface McpInstallOptions {
7
- dryRun?: boolean;
8
- force?: boolean;
9
- /** Python executable name/path. Default: "python3" on Unix, "python" on Windows. */
10
- pythonCmd?: string;
11
- /** Directory where the obsidian-mcp wrapper/symlink is placed. Default: <homedir>/.local/bin */
12
- localBinDir?: string;
13
- onProgress?: (progress: McpInstallProgress) => void;
14
- }
15
- export interface McpInstallResult {
16
- /** True if a new install or re-install happened. */
17
- installed: boolean;
18
- /** True if the binary was already present and force was false. */
19
- skipped: boolean;
20
- /** Absolute path to the exposed binary or wrapper. */
21
- binaryPath?: string;
22
- /** Error that did not block skill installation. */
23
- error?: Error;
24
- /** Wall-clock duration of the installation in milliseconds. */
25
- durationMs?: number;
26
- }
27
- export declare function installMcpServer(mcpSourceDir: string, options?: McpInstallOptions): McpInstallResult;
28
- //# sourceMappingURL=mcp.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,aAAa,GACb,iBAAiB,GACjB,eAAe,GACf,UAAU,CAAC;AAEf,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA0HD,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CA4DlB"}
@@ -1,148 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.installMcpServer = installMcpServer;
7
- const node_fs_1 = __importDefault(require("node:fs"));
8
- const node_path_1 = __importDefault(require("node:path"));
9
- const node_os_1 = __importDefault(require("node:os"));
10
- const node_child_process_1 = require("node:child_process");
11
- function defaultPythonCmd() {
12
- return node_os_1.default.platform() === 'win32' ? 'python' : 'python3';
13
- }
14
- function defaultLocalBinDir() {
15
- return node_path_1.default.join(node_os_1.default.homedir(), '.local', 'bin');
16
- }
17
- function venvBinDir() {
18
- return node_os_1.default.platform() === 'win32' ? 'Scripts' : 'bin';
19
- }
20
- function runCommand(cmd, args) {
21
- const result = spawnPlatform(cmd, args);
22
- if (result.error || result.status !== 0) {
23
- throw result.error || new Error(`Command failed: ${cmd} ${args.join(' ')}`);
24
- }
25
- }
26
- function commandExists(cmd) {
27
- const result = spawnPlatform(cmd, ['--version']);
28
- return result.status === 0;
29
- }
30
- function spawnPlatform(cmd, args) {
31
- if (node_os_1.default.platform() === 'win32') {
32
- return (0, node_child_process_1.spawnSync)('cmd', ['/c', cmd, ...args], { stdio: 'ignore' });
33
- }
34
- return (0, node_child_process_1.spawnSync)(cmd, args, { stdio: 'ignore' });
35
- }
36
- function ensureVenv(mcpSourceDir, pythonCmd, force) {
37
- const venvDir = node_path_1.default.join(mcpSourceDir, '.venv');
38
- if (force && node_fs_1.default.existsSync(venvDir)) {
39
- node_fs_1.default.rmSync(venvDir, { recursive: true, force: true });
40
- }
41
- if (!node_fs_1.default.existsSync(venvDir)) {
42
- runCommand(pythonCmd, ['-m', 'venv', venvDir]);
43
- }
44
- }
45
- function findExecutable(basePath) {
46
- if (node_os_1.default.platform() !== 'win32') {
47
- return basePath;
48
- }
49
- for (const ext of ['.exe', '.cmd']) {
50
- const candidate = `${basePath}${ext}`;
51
- if (node_fs_1.default.existsSync(candidate)) {
52
- return candidate;
53
- }
54
- }
55
- return basePath;
56
- }
57
- function venvPip(mcpSourceDir) {
58
- const venvDir = node_path_1.default.join(mcpSourceDir, '.venv');
59
- const basePath = node_path_1.default.join(venvDir, venvBinDir(), 'pip');
60
- return findExecutable(basePath);
61
- }
62
- function venvBinary(mcpSourceDir) {
63
- const venvDir = node_path_1.default.join(mcpSourceDir, '.venv');
64
- const basePath = node_path_1.default.join(venvDir, venvBinDir(), 'obsidian-mcp');
65
- return findExecutable(basePath);
66
- }
67
- function createWindowsWrapper(binaryPath, wrapperPath) {
68
- const content = `@echo off\r\n"${binaryPath}" %*\r\n`;
69
- node_fs_1.default.writeFileSync(wrapperPath, content);
70
- }
71
- function exposeBinary(mcpSourceDir, localBinDir, force) {
72
- node_fs_1.default.mkdirSync(localBinDir, { recursive: true });
73
- const sourceBinary = venvBinary(mcpSourceDir);
74
- const isWindows = node_os_1.default.platform() === 'win32';
75
- if (isWindows) {
76
- const wrapperPath = node_path_1.default.join(localBinDir, 'obsidian-mcp.cmd');
77
- const created = force || !node_fs_1.default.existsSync(wrapperPath);
78
- if (created) {
79
- createWindowsWrapper(sourceBinary, wrapperPath);
80
- }
81
- return { binaryPath: wrapperPath, created };
82
- }
83
- const targetBinary = node_path_1.default.join(localBinDir, 'obsidian-mcp');
84
- const created = force || !node_fs_1.default.existsSync(targetBinary);
85
- if (created) {
86
- if (node_fs_1.default.existsSync(targetBinary)) {
87
- node_fs_1.default.rmSync(targetBinary, { force: true });
88
- }
89
- node_fs_1.default.symlinkSync(sourceBinary, targetBinary);
90
- }
91
- return { binaryPath: targetBinary, created };
92
- }
93
- function emitProgress(onProgress, step, message) {
94
- if (onProgress) {
95
- onProgress({ step, message });
96
- }
97
- }
98
- function installMcpServer(mcpSourceDir, options = {}) {
99
- const startTime = Date.now();
100
- const pythonCmd = options.pythonCmd || defaultPythonCmd();
101
- const localBinDir = options.localBinDir || defaultLocalBinDir();
102
- const onProgress = options.onProgress;
103
- emitProgress(onProgress, 'check_python', 'Checking Python installation...');
104
- if (!commandExists(pythonCmd)) {
105
- return {
106
- installed: false,
107
- skipped: false,
108
- error: new Error(`Python not found: ${pythonCmd}`),
109
- durationMs: Date.now() - startTime,
110
- };
111
- }
112
- if (options.dryRun) {
113
- const binaryName = node_os_1.default.platform() === 'win32' ? 'obsidian-mcp.cmd' : 'obsidian-mcp';
114
- const binaryPath = node_path_1.default.join(localBinDir, binaryName);
115
- emitProgress(onProgress, 'complete', `Would install Obsidian MCP server at ${binaryPath}`);
116
- return {
117
- installed: true,
118
- skipped: false,
119
- binaryPath,
120
- durationMs: Date.now() - startTime,
121
- };
122
- }
123
- try {
124
- emitProgress(onProgress, 'create_venv', 'Creating Python virtual environment...');
125
- ensureVenv(mcpSourceDir, pythonCmd, options.force || false);
126
- emitProgress(onProgress, 'install_package', 'Installing Obsidian MCP server package...');
127
- const pip = venvPip(mcpSourceDir);
128
- runCommand(pip, ['install', '-q', '-e', mcpSourceDir]);
129
- emitProgress(onProgress, 'expose_binary', 'Exposing obsidian-mcp binary...');
130
- const { binaryPath, created } = exposeBinary(mcpSourceDir, localBinDir, options.force || false);
131
- emitProgress(onProgress, 'complete', 'Obsidian MCP server ready.');
132
- return {
133
- installed: created,
134
- skipped: !created,
135
- binaryPath,
136
- durationMs: Date.now() - startTime,
137
- };
138
- }
139
- catch (error) {
140
- return {
141
- installed: false,
142
- skipped: false,
143
- error: error instanceof Error ? error : new Error(String(error)),
144
- durationMs: Date.now() - startTime,
145
- };
146
- }
147
- }
148
- //# sourceMappingURL=mcp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=mcp.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp.test.d.ts","sourceRoot":"","sources":["../../src/tests/mcp.test.ts"],"names":[],"mappings":""}
@@ -1,232 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const node_test_1 = require("node:test");
7
- const node_assert_1 = __importDefault(require("node:assert"));
8
- const node_fs_1 = __importDefault(require("node:fs"));
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const node_os_1 = __importDefault(require("node:os"));
11
- const mcp_1 = require("../mcp");
12
- function createFakePython(baseDir) {
13
- const isWindows = node_os_1.default.platform() === 'win32';
14
- const binDir = node_path_1.default.join(baseDir, 'bin');
15
- node_fs_1.default.mkdirSync(binDir, { recursive: true });
16
- const pythonCmd = node_path_1.default.join(binDir, isWindows ? 'python.cmd' : 'python');
17
- const unixScript = `#!/bin/sh
18
- if [ "$1" = "--version" ]; then exit 0; fi
19
- if [ "$1" = "-m" ] && [ "$2" = "venv" ]; then
20
- VENV="$3"
21
- mkdir -p "$VENV/bin"
22
- mkdir -p "$VENV/Scripts"
23
- if [ -n "$CREWLOOP_PIP_FAIL" ]; then
24
- cat > "$VENV/bin/pip" <<'PIP_EOF'
25
- #!/bin/sh
26
- exit 1
27
- PIP_EOF
28
- else
29
- cat > "$VENV/bin/pip" <<'PIP_EOF'
30
- #!/bin/sh
31
- if [ "$1" = "install" ]; then
32
- touch "$(dirname "$0")/obsidian-mcp"
33
- exit 0
34
- fi
35
- exit 1
36
- PIP_EOF
37
- fi
38
- chmod +x "$VENV/bin/pip"
39
- exit 0
40
- fi
41
- exit 1
42
- `;
43
- const windowsScript = `@echo off
44
- if "%1"=="--version" exit /b 0
45
- if "%1"=="-m" if "%2"=="venv" (
46
- mkdir "%3/Scripts"
47
- mkdir "%3/bin"
48
- if defined CREWLOOP_PIP_FAIL (
49
- (
50
- echo @echo off
51
- echo exit /b 1
52
- ) > "%3/Scripts/pip.cmd"
53
- ) else (
54
- (
55
- echo @echo off
56
- echo if "%%1"=="install" ^(
57
- echo type nul ^> "%%~dp0obsidian-mcp.exe"
58
- echo exit /b 0
59
- echo ^)
60
- echo exit /b 1
61
- ) > "%3/Scripts/pip.cmd"
62
- )
63
- exit /b 0
64
- )
65
- exit /b 1
66
- `;
67
- node_fs_1.default.writeFileSync(pythonCmd, isWindows ? windowsScript : unixScript);
68
- if (!isWindows) {
69
- node_fs_1.default.chmodSync(pythonCmd, 0o755);
70
- }
71
- return { pythonCmd };
72
- }
73
- (0, node_test_1.describe)('mcp', () => {
74
- let mcpSourceDir;
75
- let localBinDir;
76
- let fakePythonDir;
77
- (0, node_test_1.before)(() => {
78
- mcpSourceDir = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), 'crewloop-mcp-'));
79
- localBinDir = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), 'crewloop-bin-'));
80
- fakePythonDir = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), 'crewloop-fakepy-'));
81
- node_fs_1.default.writeFileSync(node_path_1.default.join(mcpSourceDir, 'pyproject.toml'), '[project]\nname = "obsidian-mcp"\n');
82
- });
83
- (0, node_test_1.after)(() => {
84
- node_fs_1.default.rmSync(mcpSourceDir, { recursive: true, force: true });
85
- node_fs_1.default.rmSync(localBinDir, { recursive: true, force: true });
86
- node_fs_1.default.rmSync(fakePythonDir, { recursive: true, force: true });
87
- delete process.env.CREWLOOP_PIP_FAIL;
88
- });
89
- (0, node_test_1.it)('dry-run reports would-install without creating venv', () => {
90
- const { pythonCmd } = createFakePython(fakePythonDir);
91
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
92
- dryRun: true,
93
- pythonCmd,
94
- localBinDir,
95
- });
96
- node_assert_1.default.strictEqual(result.installed, true);
97
- node_assert_1.default.strictEqual(result.skipped, false);
98
- node_assert_1.default.strictEqual(result.error, undefined);
99
- node_assert_1.default.ok(result.binaryPath);
100
- node_assert_1.default.ok(!node_fs_1.default.existsSync(node_path_1.default.join(mcpSourceDir, '.venv')));
101
- });
102
- (0, node_test_1.it)('missing python is reported as an error but not thrown', () => {
103
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
104
- pythonCmd: node_path_1.default.join(fakePythonDir, 'missing-python'),
105
- localBinDir,
106
- });
107
- node_assert_1.default.strictEqual(result.installed, false);
108
- node_assert_1.default.strictEqual(result.skipped, false);
109
- node_assert_1.default.ok(result.error);
110
- node_assert_1.default.ok(result.error.message.includes('Python not found'));
111
- });
112
- (0, node_test_1.it)('pip failure is reported as an error', () => {
113
- const { pythonCmd } = createFakePython(fakePythonDir);
114
- process.env.CREWLOOP_PIP_FAIL = '1';
115
- try {
116
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
117
- pythonCmd,
118
- localBinDir,
119
- force: true,
120
- });
121
- node_assert_1.default.strictEqual(result.installed, false);
122
- node_assert_1.default.strictEqual(result.skipped, false);
123
- node_assert_1.default.ok(result.error);
124
- }
125
- finally {
126
- delete process.env.CREWLOOP_PIP_FAIL;
127
- }
128
- });
129
- (0, node_test_1.it)('successful install creates venv, runs pip, and exposes binary', () => {
130
- const { pythonCmd } = createFakePython(fakePythonDir);
131
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
132
- pythonCmd,
133
- localBinDir,
134
- force: true,
135
- });
136
- node_assert_1.default.strictEqual(result.installed, true);
137
- node_assert_1.default.strictEqual(result.skipped, false);
138
- node_assert_1.default.strictEqual(result.error, undefined);
139
- node_assert_1.default.ok(result.binaryPath);
140
- node_assert_1.default.ok(node_fs_1.default.existsSync(result.binaryPath));
141
- });
142
- (0, node_test_1.it)('skips install when binary already exists and force is false', () => {
143
- const { pythonCmd } = createFakePython(fakePythonDir);
144
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
145
- pythonCmd,
146
- localBinDir,
147
- });
148
- node_assert_1.default.strictEqual(result.installed, false);
149
- node_assert_1.default.strictEqual(result.skipped, true);
150
- node_assert_1.default.ok(result.binaryPath);
151
- });
152
- (0, node_test_1.it)('emits progress steps in order on successful install', () => {
153
- const { pythonCmd } = createFakePython(fakePythonDir);
154
- const steps = [];
155
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
156
- pythonCmd,
157
- localBinDir,
158
- force: true,
159
- onProgress: (progress) => steps.push(progress.step),
160
- });
161
- node_assert_1.default.strictEqual(result.error, undefined);
162
- node_assert_1.default.deepStrictEqual(steps, [
163
- 'check_python',
164
- 'create_venv',
165
- 'install_package',
166
- 'expose_binary',
167
- 'complete',
168
- ]);
169
- });
170
- (0, node_test_1.it)('dry-run emits check_python and complete only', () => {
171
- const { pythonCmd } = createFakePython(fakePythonDir);
172
- const steps = [];
173
- // Ensure a previous test did not leave a venv behind.
174
- const venvDir = node_path_1.default.join(mcpSourceDir, '.venv');
175
- if (node_fs_1.default.existsSync(venvDir)) {
176
- node_fs_1.default.rmSync(venvDir, { recursive: true, force: true });
177
- }
178
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
179
- pythonCmd,
180
- localBinDir,
181
- dryRun: true,
182
- onProgress: (progress) => steps.push(progress.step),
183
- });
184
- node_assert_1.default.strictEqual(result.error, undefined);
185
- node_assert_1.default.deepStrictEqual(steps, ['check_python', 'complete']);
186
- node_assert_1.default.ok(!node_fs_1.default.existsSync(venvDir));
187
- });
188
- (0, node_test_1.it)('missing Python emits only check_python and returns error', () => {
189
- const steps = [];
190
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
191
- pythonCmd: node_path_1.default.join(fakePythonDir, 'missing-python'),
192
- localBinDir,
193
- onProgress: (progress) => steps.push(progress.step),
194
- });
195
- node_assert_1.default.ok(result.error);
196
- node_assert_1.default.deepStrictEqual(steps, ['check_python']);
197
- });
198
- (0, node_test_1.it)('pip failure emits through install_package and returns error', () => {
199
- const { pythonCmd } = createFakePython(fakePythonDir);
200
- process.env.CREWLOOP_PIP_FAIL = '1';
201
- try {
202
- const steps = [];
203
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
204
- pythonCmd,
205
- localBinDir,
206
- force: true,
207
- onProgress: (progress) => steps.push(progress.step),
208
- });
209
- node_assert_1.default.ok(result.error);
210
- node_assert_1.default.deepStrictEqual(steps, [
211
- 'check_python',
212
- 'create_venv',
213
- 'install_package',
214
- ]);
215
- }
216
- finally {
217
- delete process.env.CREWLOOP_PIP_FAIL;
218
- }
219
- });
220
- (0, node_test_1.it)('reports duration in milliseconds', () => {
221
- const { pythonCmd } = createFakePython(fakePythonDir);
222
- const result = (0, mcp_1.installMcpServer)(mcpSourceDir, {
223
- pythonCmd,
224
- localBinDir,
225
- force: true,
226
- });
227
- node_assert_1.default.strictEqual(result.error, undefined);
228
- node_assert_1.default.ok(typeof result.durationMs === 'number');
229
- node_assert_1.default.ok(result.durationMs >= 0);
230
- });
231
- });
232
- //# sourceMappingURL=mcp.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp.test.js","sourceRoot":"","sources":["../../src/tests/mcp.test.ts"],"names":[],"mappings":"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"}