@nemus-cli/nemus 0.2.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 (320) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/LICENSE +21 -0
  3. package/README.md +275 -0
  4. package/assets/README.md +53 -0
  5. package/assets/banner.png +0 -0
  6. package/assets/banner.svg +66 -0
  7. package/assets/favicon-32.png +0 -0
  8. package/assets/favicon-64.png +0 -0
  9. package/assets/icon-256.png +0 -0
  10. package/assets/icon.svg +23 -0
  11. package/assets/logo-256.png +0 -0
  12. package/assets/logo-512.png +0 -0
  13. package/assets/logo-wordmark.svg +35 -0
  14. package/assets/logo.svg +32 -0
  15. package/bin/workspace.js +130 -0
  16. package/dist/cli/ai-prompt.js +421 -0
  17. package/dist/cli/dashboard/AgentList.js +61 -0
  18. package/dist/cli/dashboard/DashboardSidebar.js +280 -0
  19. package/dist/cli/dashboard/HelpFooter.js +73 -0
  20. package/dist/cli/dashboard/StatusBadge.js +50 -0
  21. package/dist/cli/dashboard/index.js +11 -0
  22. package/dist/cli/dashboard/types.js +2 -0
  23. package/dist/cli/tui.js +48 -0
  24. package/dist/commands/ai-prompt.js +22 -0
  25. package/dist/commands/analyze-deps.js +138 -0
  26. package/dist/commands/archive.js +113 -0
  27. package/dist/commands/branch/create.js +119 -0
  28. package/dist/commands/branch/index.js +104 -0
  29. package/dist/commands/branch/merge.js +90 -0
  30. package/dist/commands/branch/rebase.js +84 -0
  31. package/dist/commands/branch/switch.js +165 -0
  32. package/dist/commands/cache/index.js +80 -0
  33. package/dist/commands/cache/manager.js +198 -0
  34. package/dist/commands/cleanup.js +153 -0
  35. package/dist/commands/configure-claude.js +55 -0
  36. package/dist/commands/configure.js +231 -0
  37. package/dist/commands/create.js +204 -0
  38. package/dist/commands/dashboard/hook-handler.js +162 -0
  39. package/dist/commands/dashboard/index.js +258 -0
  40. package/dist/commands/dashboard/launcher.js +40 -0
  41. package/dist/commands/dashboard/session-picker.js +106 -0
  42. package/dist/commands/dashboard/sidebar.js +39 -0
  43. package/dist/commands/dashboard/workspace-picker.js +95 -0
  44. package/dist/commands/delete.js +194 -0
  45. package/dist/commands/deprecated-aliases.js +44 -0
  46. package/dist/commands/diff.js +129 -0
  47. package/dist/commands/doctor.js +141 -0
  48. package/dist/commands/generate-docs.js +77 -0
  49. package/dist/commands/ghq-status.js +72 -0
  50. package/dist/commands/go.js +154 -0
  51. package/dist/commands/history.js +124 -0
  52. package/dist/commands/list.js +191 -0
  53. package/dist/commands/mcp/index.js +69 -0
  54. package/dist/commands/migrate.js +296 -0
  55. package/dist/commands/remove-repo.js +217 -0
  56. package/dist/commands/report-bug.js +112 -0
  57. package/dist/commands/run.js +147 -0
  58. package/dist/commands/save-context.js +171 -0
  59. package/dist/commands/sessions.js +129 -0
  60. package/dist/commands/status.js +138 -0
  61. package/dist/commands/suite/create.js +212 -0
  62. package/dist/commands/suite/delete.js +64 -0
  63. package/dist/commands/suite/export.js +126 -0
  64. package/dist/commands/suite/import.js +128 -0
  65. package/dist/commands/suite/index.js +94 -0
  66. package/dist/commands/suite/list.js +49 -0
  67. package/dist/commands/suite/use.js +227 -0
  68. package/dist/commands/sync.js +117 -0
  69. package/dist/commands/update.js +203 -0
  70. package/dist/mcp/install.js +550 -0
  71. package/dist/mcp/server.js +398 -0
  72. package/dist/mcp/tools.js +922 -0
  73. package/dist/pi-extensions/permission-sync.ts.template +41 -0
  74. package/dist/pi-extensions/permissions-gate.ts.template +69 -0
  75. package/dist/pi-extensions/pr-fix-trigger.ts.template +124 -0
  76. package/dist/pi-extensions/review-reminder.ts.template +58 -0
  77. package/dist/pi-extensions/workspace-input-status.ts.template +919 -0
  78. package/dist/program.js +136 -0
  79. package/dist/scripts/workspace-table.py +394 -0
  80. package/dist/types/dashboard.js +11 -0
  81. package/dist/types/index.js +2 -0
  82. package/dist/utils/agent-config.js +263 -0
  83. package/dist/utils/agent-state.js +178 -0
  84. package/dist/utils/banner.js +24 -0
  85. package/dist/utils/branch-operations.js +232 -0
  86. package/dist/utils/bug-report.js +355 -0
  87. package/dist/utils/cache.js +168 -0
  88. package/dist/utils/claude-integration.js +617 -0
  89. package/dist/utils/claude-sessions.js +260 -0
  90. package/dist/utils/cleanup-operations.js +120 -0
  91. package/dist/utils/colors.js +26 -0
  92. package/dist/utils/command-helpers.js +44 -0
  93. package/dist/utils/config.js +150 -0
  94. package/dist/utils/context-file.js +33 -0
  95. package/dist/utils/dashboard-hooks.js +172 -0
  96. package/dist/utils/dependency-analyzer.js +234 -0
  97. package/dist/utils/diff-operations.js +80 -0
  98. package/dist/utils/doc-generator.js +184 -0
  99. package/dist/utils/ghq-integration.js +332 -0
  100. package/dist/utils/git-operations.js +237 -0
  101. package/dist/utils/git-status.js +187 -0
  102. package/dist/utils/github.js +68 -0
  103. package/dist/utils/health-checks.js +345 -0
  104. package/dist/utils/history.js +150 -0
  105. package/dist/utils/hooks.js +100 -0
  106. package/dist/utils/logger.js +40 -0
  107. package/dist/utils/permission-sync.js +681 -0
  108. package/dist/utils/pi-extensions.js +224 -0
  109. package/dist/utils/progress.js +92 -0
  110. package/dist/utils/prompts.js +279 -0
  111. package/dist/utils/repo-resolver.js +260 -0
  112. package/dist/utils/retry.js +65 -0
  113. package/dist/utils/run-operations.js +30 -0
  114. package/dist/utils/suite.js +159 -0
  115. package/dist/utils/sync-operations.js +107 -0
  116. package/dist/utils/tmux-dashboard.js +184 -0
  117. package/dist/utils/validation.js +153 -0
  118. package/dist/utils/version-check.js +121 -0
  119. package/dist/utils/workspace-meta.js +185 -0
  120. package/install-shell-integration.sh +532 -0
  121. package/install.sh +401 -0
  122. package/package.json +90 -0
  123. package/remove-shell-block.awk +44 -0
  124. package/scripts/postinstall.js +85 -0
  125. package/skills/analyze-deps.md +23 -0
  126. package/skills/archive-workspace.md +26 -0
  127. package/skills/branch-create.md +18 -0
  128. package/skills/create-workspace.md +39 -0
  129. package/skills/delete-workspace.md +37 -0
  130. package/skills/list-org-repos.md +26 -0
  131. package/skills/list-suites.md +24 -0
  132. package/skills/list-workspaces.md +27 -0
  133. package/skills/refresh-workspace-docs.md +89 -0
  134. package/skills/remove-repo.md +25 -0
  135. package/skills/run-command.md +23 -0
  136. package/skills/save-context.md +68 -0
  137. package/skills/search-repos.md +31 -0
  138. package/skills/snapshot-list.md +18 -0
  139. package/skills/snapshot-save.md +12 -0
  140. package/skills/switch-branch.md +18 -0
  141. package/skills/update-cache.md +21 -0
  142. package/skills/update-workspace.md +66 -0
  143. package/skills/workspace-cleanup.md +18 -0
  144. package/skills/workspace-diff.md +23 -0
  145. package/skills/workspace-doctor.md +23 -0
  146. package/skills/workspace-info.md +45 -0
  147. package/skills/workspace-manager/SKILL.md +201 -0
  148. package/skills/workspace-manager/references/ai-prompt.md +44 -0
  149. package/skills/workspace-manager/references/analyze-deps.md +45 -0
  150. package/skills/workspace-manager/references/archive-workspace.md +38 -0
  151. package/skills/workspace-manager/references/branch-create.md +31 -0
  152. package/skills/workspace-manager/references/branch-merge.md +22 -0
  153. package/skills/workspace-manager/references/branch-rebase.md +22 -0
  154. package/skills/workspace-manager/references/cache-clear.md +18 -0
  155. package/skills/workspace-manager/references/cache-info.md +22 -0
  156. package/skills/workspace-manager/references/configure-claude.md +31 -0
  157. package/skills/workspace-manager/references/configure.md +35 -0
  158. package/skills/workspace-manager/references/create-workspace.md +45 -0
  159. package/skills/workspace-manager/references/dashboard.md +61 -0
  160. package/skills/workspace-manager/references/delete-workspace.md +33 -0
  161. package/skills/workspace-manager/references/generate-docs.md +36 -0
  162. package/skills/workspace-manager/references/ghq-status.md +28 -0
  163. package/skills/workspace-manager/references/go.md +33 -0
  164. package/skills/workspace-manager/references/history.md +41 -0
  165. package/skills/workspace-manager/references/list-org-repos.md +26 -0
  166. package/skills/workspace-manager/references/list-suites.md +21 -0
  167. package/skills/workspace-manager/references/list-workspaces.md +27 -0
  168. package/skills/workspace-manager/references/mcp.md +49 -0
  169. package/skills/workspace-manager/references/remove-repo.md +26 -0
  170. package/skills/workspace-manager/references/run-command.md +44 -0
  171. package/skills/workspace-manager/references/search-repos.md +24 -0
  172. package/skills/workspace-manager/references/sessions.md +27 -0
  173. package/skills/workspace-manager/references/suite-create.md +22 -0
  174. package/skills/workspace-manager/references/suite-delete.md +21 -0
  175. package/skills/workspace-manager/references/suite-export.md +19 -0
  176. package/skills/workspace-manager/references/suite-import.md +19 -0
  177. package/skills/workspace-manager/references/suite-use.md +27 -0
  178. package/skills/workspace-manager/references/switch-branch.md +25 -0
  179. package/skills/workspace-manager/references/update-cache.md +22 -0
  180. package/skills/workspace-manager/references/update-workspace.md +50 -0
  181. package/skills/workspace-manager/references/workspace-cleanup.md +33 -0
  182. package/skills/workspace-manager/references/workspace-diff.md +27 -0
  183. package/skills/workspace-manager/references/workspace-doctor.md +27 -0
  184. package/skills/workspace-manager/references/workspace-info.md +33 -0
  185. package/skills/workspace-manager/references/workspace-status.md +43 -0
  186. package/skills/workspace-manager/references/workspace-sync.md +26 -0
  187. package/skills/workspace-status.md +26 -0
  188. package/skills/workspace-sync.md +23 -0
  189. package/src/cli/ai-prompt.test.ts +667 -0
  190. package/src/cli/ai-prompt.ts +421 -0
  191. package/src/cli/dashboard/AgentList.tsx +44 -0
  192. package/src/cli/dashboard/DashboardSidebar.tsx +291 -0
  193. package/src/cli/dashboard/HelpFooter.tsx +22 -0
  194. package/src/cli/dashboard/StatusBadge.tsx +23 -0
  195. package/src/cli/dashboard/index.ts +5 -0
  196. package/src/cli/dashboard/types.ts +16 -0
  197. package/src/cli/tui.tsx +51 -0
  198. package/src/cli/workspace-cli.test.ts +30 -0
  199. package/src/commands/ai-prompt.ts +21 -0
  200. package/src/commands/analyze-deps.ts +119 -0
  201. package/src/commands/archive.ts +114 -0
  202. package/src/commands/branch/create.ts +94 -0
  203. package/src/commands/branch/index.ts +74 -0
  204. package/src/commands/branch/merge.ts +61 -0
  205. package/src/commands/branch/rebase.ts +54 -0
  206. package/src/commands/branch/switch.ts +150 -0
  207. package/src/commands/cache/index.ts +51 -0
  208. package/src/commands/cache/manager.ts +168 -0
  209. package/src/commands/cleanup.ts +132 -0
  210. package/src/commands/configure-claude.ts +55 -0
  211. package/src/commands/configure.ts +204 -0
  212. package/src/commands/create.ts +196 -0
  213. package/src/commands/dashboard/hook-handler.ts +138 -0
  214. package/src/commands/dashboard/index.ts +248 -0
  215. package/src/commands/dashboard/launcher.ts +42 -0
  216. package/src/commands/dashboard/session-picker.ts +73 -0
  217. package/src/commands/dashboard/sidebar.js +39 -0
  218. package/src/commands/dashboard/workspace-picker.ts +62 -0
  219. package/src/commands/delete.test.ts +250 -0
  220. package/src/commands/delete.ts +171 -0
  221. package/src/commands/deprecated-aliases.ts +55 -0
  222. package/src/commands/diff.ts +106 -0
  223. package/src/commands/doctor.ts +110 -0
  224. package/src/commands/generate-docs.ts +45 -0
  225. package/src/commands/ghq-status.ts +70 -0
  226. package/src/commands/go.ts +125 -0
  227. package/src/commands/history.ts +136 -0
  228. package/src/commands/list.test.ts +219 -0
  229. package/src/commands/list.ts +176 -0
  230. package/src/commands/mcp/index.ts +39 -0
  231. package/src/commands/migrate.ts +277 -0
  232. package/src/commands/remove-repo.ts +194 -0
  233. package/src/commands/report-bug.ts +88 -0
  234. package/src/commands/run.ts +125 -0
  235. package/src/commands/save-context.test.ts +113 -0
  236. package/src/commands/save-context.ts +141 -0
  237. package/src/commands/sessions.ts +99 -0
  238. package/src/commands/status.ts +111 -0
  239. package/src/commands/suite/create.ts +240 -0
  240. package/src/commands/suite/delete.ts +65 -0
  241. package/src/commands/suite/export.ts +97 -0
  242. package/src/commands/suite/import.ts +100 -0
  243. package/src/commands/suite/index.ts +66 -0
  244. package/src/commands/suite/list.ts +54 -0
  245. package/src/commands/suite/use.ts +232 -0
  246. package/src/commands/sync.ts +97 -0
  247. package/src/commands/update.ts +197 -0
  248. package/src/mcp/install.ts +529 -0
  249. package/src/mcp/server.ts +579 -0
  250. package/src/mcp/tools.test.ts +545 -0
  251. package/src/mcp/tools.ts +1019 -0
  252. package/src/mcp/update-workspace.test.ts +220 -0
  253. package/src/pi-extensions/permission-sync.ts.template +41 -0
  254. package/src/pi-extensions/permissions-gate.ts.template +69 -0
  255. package/src/pi-extensions/pr-fix-trigger.ts.template +124 -0
  256. package/src/pi-extensions/review-reminder.ts.template +58 -0
  257. package/src/pi-extensions/workspace-input-status.ts.template +919 -0
  258. package/src/program.ts +112 -0
  259. package/src/scripts/workspace-table.py +394 -0
  260. package/src/types/dashboard.ts +29 -0
  261. package/src/types/index.ts +109 -0
  262. package/src/types/ink.d.ts +171 -0
  263. package/src/utils/agent-config.test.ts +303 -0
  264. package/src/utils/agent-config.ts +264 -0
  265. package/src/utils/agent-state.test.ts +166 -0
  266. package/src/utils/agent-state.ts +135 -0
  267. package/src/utils/banner.ts +24 -0
  268. package/src/utils/branch-operations.ts +237 -0
  269. package/src/utils/bug-report.test.ts +174 -0
  270. package/src/utils/bug-report.ts +355 -0
  271. package/src/utils/cache.ts +150 -0
  272. package/src/utils/claude-integration.test.ts +381 -0
  273. package/src/utils/claude-integration.ts +649 -0
  274. package/src/utils/claude-sessions.test.ts +262 -0
  275. package/src/utils/claude-sessions.ts +251 -0
  276. package/src/utils/cleanup-operations.ts +94 -0
  277. package/src/utils/colors.ts +25 -0
  278. package/src/utils/command-helpers.ts +46 -0
  279. package/src/utils/config.test.ts +203 -0
  280. package/src/utils/config.ts +133 -0
  281. package/src/utils/context-file.ts +36 -0
  282. package/src/utils/dashboard-hooks.test.ts +168 -0
  283. package/src/utils/dashboard-hooks.ts +163 -0
  284. package/src/utils/dependency-analyzer.ts +243 -0
  285. package/src/utils/diff-operations.ts +59 -0
  286. package/src/utils/doc-generator.ts +187 -0
  287. package/src/utils/ghq-integration.test.ts +195 -0
  288. package/src/utils/ghq-integration.ts +317 -0
  289. package/src/utils/git-operations.test.ts +265 -0
  290. package/src/utils/git-operations.ts +233 -0
  291. package/src/utils/git-status.ts +171 -0
  292. package/src/utils/github.ts +74 -0
  293. package/src/utils/health-checks.ts +359 -0
  294. package/src/utils/history.ts +140 -0
  295. package/src/utils/hooks.ts +92 -0
  296. package/src/utils/logger.ts +37 -0
  297. package/src/utils/permission-sync.test.ts +593 -0
  298. package/src/utils/permission-sync.ts +720 -0
  299. package/src/utils/pi-extensions.test.ts +182 -0
  300. package/src/utils/pi-extensions.ts +226 -0
  301. package/src/utils/progress.ts +73 -0
  302. package/src/utils/prompts.test.ts +169 -0
  303. package/src/utils/prompts.ts +296 -0
  304. package/src/utils/repo-resolver.test.ts +313 -0
  305. package/src/utils/repo-resolver.ts +294 -0
  306. package/src/utils/retry.test.ts +124 -0
  307. package/src/utils/retry.ts +85 -0
  308. package/src/utils/run-operations.ts +38 -0
  309. package/src/utils/suite.test.ts +256 -0
  310. package/src/utils/suite.ts +144 -0
  311. package/src/utils/sync-operations.ts +87 -0
  312. package/src/utils/tmux-dashboard.ts +193 -0
  313. package/src/utils/validation.test.ts +139 -0
  314. package/src/utils/validation.ts +128 -0
  315. package/src/utils/version-check.test.ts +108 -0
  316. package/src/utils/version-check.ts +96 -0
  317. package/src/utils/workspace-meta.ts +173 -0
  318. package/sync-permissions.sh +137 -0
  319. package/tsconfig.json +20 -0
  320. package/uninstall.sh +162 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,86 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.1] - 2026-08-24
11
+
12
+ ### Security
13
+
14
+ - **Fixed a path-traversal vulnerability in the MCP server.** The MCP tool
15
+ handlers built filesystem paths (`path.join(WORKSPACES_DIR, workspace)`)
16
+ directly from the caller-supplied `workspace` argument with no validation, so
17
+ an MCP client could pass a value like `../../etc` to read, write, delete
18
+ (`delete-workspace`), or run commands (`run-command`) **outside** the
19
+ workspaces directory. All handlers now resolve workspace paths through a new
20
+ `safeWorkspacePath()` choke point that enforces an allowlist
21
+ (`^[A-Za-z0-9_-]+$`) **and** verifies the resolved path stays inside
22
+ `WORKSPACES_DIR`. The MCP input schemas additionally reject traversal
23
+ characters at the boundary (defense in depth). The archive/unarchive metadata
24
+ paths are hardened the same way.
25
+
26
+ ## [0.2.0] - 2026-08-24
27
+
28
+ ### Added
29
+
30
+ - **Investigate-first workspaces.** When `nemus -- "<prompt>"` doesn't name
31
+ concrete repos but asks the agent to figure out which repos are relevant (from
32
+ a trace, stack trace, or log search), Nemus now creates an **empty** workspace
33
+ and seeds the in-session agent with a discover-then-add workflow: it
34
+ investigates, maps services to repos (MCP `search-repos` when available, else
35
+ the `gh` CLI, honouring a configured org), adds them with `nemus update`, and
36
+ only then reads the code.
37
+ - `nemus create --allow-empty` creates a zero-repo workspace that still writes
38
+ the agent context + `.mcp.json`, so the agent lands with the tools to discover
39
+ and add repos.
40
+
41
+ ### Changed
42
+
43
+ - `nemus update` (CLI and MCP) regenerates the agent context after a successful
44
+ add, so a freshly-populated workspace stops reporting "0 repositories."
45
+ - Context regeneration now **preserves operator-authored `## Notes`** instead of
46
+ overwriting them.
47
+ - Shell integration probes installed agents (claude → pi → opencode → codex →
48
+ gemini) when `primaryAgent=auto`, instead of assuming `claude`.
49
+
50
+ ### Fixed
51
+
52
+ - Extraction now coerces malformed model output (wrong field types) to safe
53
+ empties instead of throwing.
54
+ - Corrected internal command references that still invoked the pre-rename `w`
55
+ binary; they now use `nemus`.
56
+
57
+ ## [0.1.0] - 2026-08-24
58
+
59
+ Initial open-source release of **Nemus**.
60
+
61
+ ### Added
62
+
63
+ - Multi-repository **workspaces**: create, list, update, delete, and jump to
64
+ folders of related Git repositories.
65
+ - Bulk operations across every repo in a workspace: `status`, `sync`, `diff`,
66
+ `run`, and `doctor` (health checks + score).
67
+ - **Branch operations** (switch/create/merge/rebase) across all repos.
68
+ - **Suites** — reusable repo collections with optional post-clone hooks, plus
69
+ export/import.
70
+ - **Snapshots** — capture and restore exact workspace state.
71
+ - **Cache** management for the GitHub repo list.
72
+ - **Dependency analysis** and **doc generation** across a workspace.
73
+ - **AI-agent integration** for Claude Code, pi, OpenCode, Codex, and Gemini:
74
+ generated context files, skills installation, hooks (where supported), and an
75
+ **MCP server** (`nemus-mcp`).
76
+ - Provider-agnostic by design — works with whatever model provider your agent
77
+ supports (Anthropic, OpenAI, Google, or Amazon Bedrock).
78
+ - Natural-language front door: `nemus -- "<prompt>"`.
79
+ - Interactive TUI and a multi-agent dashboard.
80
+ - Automatic retries with backoff on flaky network operations.
81
+ - Optional shell integration (auto-cd on create + quick-navigate helper).
82
+
83
+ [Unreleased]: https://github.com/me-public/nemus/compare/v0.2.1...HEAD
84
+ [0.2.1]: https://github.com/me-public/nemus/compare/v0.2.0...v0.2.1
85
+ [0.2.0]: https://github.com/me-public/nemus/compare/v0.1.0...v0.2.0
86
+ [0.1.0]: https://github.com/me-public/nemus/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nemus contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,275 @@
1
+ <p align="center">
2
+ <img src="assets/logo-wordmark.svg" alt="Nemus" width="320" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ <b>Multi-repo workspaces for the AI-agent era.</b><br/>
7
+ Create, sync, and operate across dozens of Git repositories with a single command —
8
+ and wire them up to your favorite coding agent.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://github.com/me-public/nemus/actions/workflows/ci.yml"><img src="https://github.com/me-public/nemus/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
13
+ <a href="https://www.npmjs.com/package/@nemus-cli/nemus"><img src="https://img.shields.io/npm/v/@nemus-cli/nemus.svg" alt="npm" /></a>
14
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT" /></a>
15
+ <img src="https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg" alt="Node >= 22" />
16
+ </p>
17
+
18
+ ---
19
+
20
+ ## The name
21
+
22
+ **Nemus** (_NEH-mus_) is Latin for a **grove** — a small wood of trees sharing
23
+ soil and roots. It's a fitting picture of what the tool manages: a cluster of
24
+ repositories, each its own tree, growing together in one workspace. It also nods
25
+ to the branch-and-commit shape of Git itself.
26
+
27
+ ## Why Nemus?
28
+
29
+ Modern products span many repositories. Nemus keeps a **workspace** — a named folder
30
+ of related repos — in sync and lets you act across all of them at once: clone, pull,
31
+ branch, run commands, check status, and diff. Then it connects that workspace to a
32
+ coding agent (Claude Code, pi, OpenCode, Codex, Gemini) with generated context files,
33
+ skills, and an MCP server, so "work on the payments stack" becomes a single prompt.
34
+
35
+ - 🌳 **Workspaces** — group repos, clone them all, jump in.
36
+ - 🔁 **Operate in bulk** — status, sync, diff, run, branch across every repo.
37
+ - 📦 **Suites & snapshots** — save reusable repo collections and exact states.
38
+ - 🤖 **Agent-native** — first-class integration with multiple coding agents.
39
+ - 🩺 **Healthy by default** — health checks, dependency analysis, retries.
40
+
41
+ ## A full clone per workspace — on purpose
42
+
43
+ This is the core design decision, so it's worth being explicit: **every workspace
44
+ gets its own independent, full `git clone` of each repo.** Two workspaces that both
45
+ contain `api` hold two separate clones — each with its own `.git`, index, stash,
46
+ hooks, config, branches, and build artifacts.
47
+
48
+ A reasonable question is *"why not `git worktree`?"* Worktrees attach multiple
49
+ working directories to **one shared repository**, which is great for flipping
50
+ between branches of a **single** repo. But Nemus is built for **many repos worked
51
+ on in parallel — often by AI agents — at the same time**, and there full clones win:
52
+
53
+ | | **Nemus: clone per workspace** | **`git worktree`** |
54
+ |---|---|---|
55
+ | **Scope** | Spans **many repos** per workspace uniformly | A **single-repo** feature (`git worktree add` lives inside one repo) |
56
+ | **Isolation** | Total: separate `.git`, index, stash, config, **hooks**, and build outputs (`node_modules/`, `target/`, `dist/`) | Partial: worktrees **share** the object store, config, and hooks |
57
+ | **Same branch, twice** | ✅ Two workspaces can both sit on `main` (e.g. stable vs. experiment) | ❌ Git refuses to check out the same branch in two worktrees |
58
+ | **Parallel agents** | Safe: one agent's rebase/branch-switch/`gc`/dirty tree can't touch another's | Risky: aggressive concurrent ops share one object DB + refs |
59
+ | **Per-workspace remotes/creds** | ✅ Each clone can point at a different fork/remote | ❌ Remotes are shared |
60
+ | **Disposable** | It's just a directory — `rm -rf` is safe | Needs `git worktree remove`; a stale/broken worktree can corrupt the parent's list |
61
+ | **Tooling** | Every dir is a normal repo — IDEs, scripts, and git tools "just work" | Some tools mishandle the `.git`-file pointer / shared hooks |
62
+
63
+ **The honest trade-off:** full clones use more disk and take longer to set up than a
64
+ worktree that shares the object store. Nemus leans into that on purpose and softens
65
+ it — clones run **in parallel**, retry on flaky networks, and the repo list is
66
+ cached. For juggling many repos across several workspaces (and several agents), the
67
+ bulletproof isolation is worth the extra gigabytes. If you're switching branches
68
+ within one repo, plain `git worktree` is still the right tool — Nemus solves the
69
+ different problem of *many* repos in *many* independent workspaces.
70
+
71
+ ## Quick Start
72
+
73
+ ```bash
74
+ # Install globally
75
+ npm install -g @nemus-cli/nemus
76
+
77
+ # One-time setup (choose your GitHub org, agent, clone protocol…)
78
+ nemus configure
79
+
80
+ # Create your first workspace (interactive repo picker with fuzzy search)
81
+ nemus create
82
+
83
+ # Or let an agent do it — describe what you need in plain English
84
+ nemus -- create a workspace with all payments-related repos
85
+ ```
86
+
87
+ After creation you're dropped into the workspace directory with all repos cloned.
88
+
89
+ > `nemus` and the shorter `nem` are equivalent. Use whichever you like.
90
+
91
+ ## Installation
92
+
93
+ ### From npm (recommended)
94
+
95
+ ```bash
96
+ npm install -g @nemus-cli/nemus
97
+ ```
98
+
99
+ The postinstall step sets up optional shell integration (auto-cd into new
100
+ workspaces + a quick-navigate helper).
101
+
102
+ ### From source
103
+
104
+ ```bash
105
+ git clone https://github.com/me-public/nemus.git
106
+ cd nemus
107
+ npm install
108
+ npm run build
109
+ npm link # makes `nemus` / `nem` available on your PATH
110
+ ```
111
+
112
+ ### Prerequisites
113
+
114
+ - **Node.js 22+**
115
+ - Git
116
+ - [GitHub CLI](https://cli.github.com/) (`gh`), authenticated via `gh auth login`
117
+ - SSH keys configured for GitHub (recommended; HTTPS also supported)
118
+
119
+ ## Connecting AI agents
120
+
121
+ Nemus is agent-agnostic. It detects installed agent CLIs and, for each active
122
+ agent, writes the right context file, installs skills, and (where supported)
123
+ registers its MCP server and hooks.
124
+
125
+ | Agent | CLI | Context file | MCP | Notes |
126
+ |-------|-----|--------------|-----|-------|
127
+ | **Claude Code** | `claude` | `CLAUDE.md` | ✅ | Hooks + status line supported |
128
+ | **pi** | `pi` | `AGENTS.md` | — | |
129
+ | **OpenCode** | `opencode` | `AGENTS.md` | ✅ | Reads `~/.claude/skills` natively |
130
+ | **Codex** (OpenAI) | `codex` | `AGENTS.md` | ✅ | Reads `~/.codex/config.toml` |
131
+ | **Gemini** (Google) | `gemini` | `GEMINI.md` | ✅ | |
132
+
133
+ Choose your agent(s) during `nemus configure`, or set them any time:
134
+
135
+ ```bash
136
+ nemus configure # interactive
137
+ # aiAgent: claude | pi | opencode | codex | gemini | both | auto
138
+ # primaryAgent: claude | pi | opencode | codex | gemini | auto
139
+ ```
140
+
141
+ - `auto` detects installed CLIs and picks sensibly.
142
+ - `both` means **every** installed agent (context files + skills written for all).
143
+
144
+ ### Model providers
145
+
146
+ The agent CLIs own model/provider auth, so Nemus works with **any provider your
147
+ agent supports** — Anthropic, OpenAI, Google, or **Amazon Bedrock** — with no extra
148
+ configuration in Nemus. For example, Claude Code and pi both run against Bedrock via
149
+ their own environment (`CLAUDE_CODE_USE_BEDROCK=1`, or pi's `amazon-bedrock`
150
+ provider); Codex and Gemini authenticate to OpenAI and Google respectively. Point
151
+ your agent at whichever provider you like — Nemus just drives the agent.
152
+
153
+ ## Usage
154
+
155
+ Every command has a short alias (shown in parentheses).
156
+
157
+ ### Create & manage workspaces
158
+
159
+ ```bash
160
+ nemus create # (c) interactive create
161
+ nemus list # (l) list workspaces
162
+ nemus update # (u) add repos to a workspace
163
+ nemus delete # (del) delete a workspace
164
+ nemus go [name] # jump to a workspace directory
165
+ ```
166
+
167
+ ### Operate across all repos
168
+
169
+ ```bash
170
+ nemus status my-workspace # (st) git status for every repo
171
+ nemus sync my-workspace # (s) git pull every repo (auto-retries on flaky network)
172
+ nemus diff my-workspace # (d) combined diff summary (--full for raw diffs)
173
+ nemus run my-workspace "npm install" # (r) run a command in every repo
174
+ nemus doctor my-workspace # (doc) health checks + score
175
+ ```
176
+
177
+ ```
178
+ Repo Branch Status Ahead/Behind Modified
179
+ ─────────────────────────────────────────────────────────────────────
180
+ api main ✓ Clean Up to date -
181
+ web feature/x ⚠ 2 modified ↑1 2 files
182
+ shared-lib main ✓ Clean ↓3 -
183
+ ```
184
+
185
+ ### Suites (reusable repo collections)
186
+
187
+ ```bash
188
+ nemus suite create # (sc) save a set of repos (+ optional post-clone hooks)
189
+ nemus suite list # (sls)
190
+ nemus suite use # (fs) create a workspace from a suite
191
+ nemus suite export my-suite -o my-suite.json
192
+ nemus suite import my-suite.json
193
+ ```
194
+
195
+ ### Branches & snapshots
196
+
197
+ ```bash
198
+ nemus branch switch # (sb) switch every repo to a branch
199
+ nemus branch create ws feature/new-thing # (bc)
200
+ nemus snapshot save ws # (ss) capture exact branches/commits/dirty state
201
+ nemus snapshot restore <id> # (sr)
202
+ ```
203
+
204
+ ### AI assistant
205
+
206
+ ```bash
207
+ nemus -- create a workspace for the payments team
208
+ nemus -- list my workspaces and show their status
209
+
210
+ # Investigate-first: create an EMPTY workspace and let the agent discover the repos
211
+ nemus -- search the logs for the OCR 500s, find the services in the trace, and open those repos
212
+ ```
213
+
214
+ **Investigate-first workspaces:** when your prompt doesn't name concrete repos but
215
+ asks the agent to *figure out* which repos are relevant (from a trace, a stack
216
+ trace, or a log search), Nemus creates an **empty** workspace and hands the agent a
217
+ discover-then-add workflow: it investigates, maps the services it finds to repos
218
+ (fuzzy `search-repos`, or the `gh` CLI), adds them with `nemus update`, and only
219
+ then digs into the code.
220
+
221
+ Nemus exposes an **MCP server** (`nemus-mcp`) so MCP-capable agents can search
222
+ repos, create/update workspaces, check status, and more directly from a prompt.
223
+
224
+ Run `nemus --help` for the full command reference.
225
+
226
+ ## Configuration
227
+
228
+ `nemus configure` writes `~/.workspace-manager-cache/config.json`. Environment
229
+ variables override it:
230
+
231
+ ```bash
232
+ export WORKSPACE_MANAGER_DIR="$HOME/my-workspaces" # default: ~/workspaces
233
+ export WORKSPACE_MANAGER_CACHE_DIR="$HOME/.cache/nemus" # default: ~/.workspace-manager-cache
234
+ ```
235
+
236
+ Key settings: `githubOrg` (which org's repos to list — leave empty to list your
237
+ own), `cloneProtocol` (`ssh`|`https`), `aiAgent`, `primaryAgent`, `installMcp`.
238
+
239
+ ## Workspace layout
240
+
241
+ ```
242
+ ~/workspaces/
243
+ └── my-workspace/
244
+ ├── .workspace-meta.json # repos, timestamps, health
245
+ ├── AGENTS.md / CLAUDE.md # generated agent context
246
+ ├── api/ # cloned repos
247
+ ├── web/
248
+ └── shared-lib/
249
+ ```
250
+
251
+ ## Development
252
+
253
+ ```bash
254
+ npm run build # compile TypeScript
255
+ npm test # run the test suite (vitest)
256
+ npm run typecheck # tsc --noEmit
257
+ npm link # use your local build globally
258
+ ```
259
+
260
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines and
261
+ [docs/architecture.md](docs/architecture.md) for a tour of the codebase.
262
+
263
+ ## Releasing
264
+
265
+ Releases are automated and gated by a manual approval. Bump the version, merge to
266
+ `main`, and approve the deployment — see [docs/releasing.md](docs/releasing.md).
267
+
268
+ ## Contributing
269
+
270
+ Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) and our
271
+ [Code of Conduct](CODE_OF_CONDUCT.md). Security issues: see [SECURITY.md](SECURITY.md).
272
+
273
+ ## License
274
+
275
+ [MIT](LICENSE) © Nemus contributors
@@ -0,0 +1,53 @@
1
+ # Nemus brand assets
2
+
3
+ Original artwork for **Nemus** (Latin for *grove*). The mark is an **organic
4
+ sapling that doubles as a git commit graph** — a trunk branching into commit-dot
5
+ "buds," with one highlighted *active* node. It reads at once as a young *tree* (the
6
+ grove), a *branch/commit graph*, and repos growing from a shared root. The square
7
+ app **icon** is a bold negative-space tree with a `>_` terminal prompt carved into
8
+ the canopy, so it stays legible down to favicon sizes. Hero imagery uses a
9
+ terminal-window motif in a GitHub-dark palette for a developer-native feel.
10
+
11
+ ## Files
12
+
13
+ | File | Use |
14
+ |------|-----|
15
+ | `logo.svg` / `logo-256.png` / `logo-512.png` | The logo mark. Transparent background — use on light or dark surfaces. |
16
+ | `logo-wordmark.svg` | Mark + "Nemus" wordmark. Use in README headers and docs. |
17
+ | `icon.svg` / `icon-256.png` | Square app icon (rounded-rect green background). Use for avatars/app icons. |
18
+ | `favicon-32.png` / `favicon-64.png` | Favicons derived from the icon. |
19
+ | `banner.svg` / `banner.png` | 1280×640 social/repo banner (GitHub "social preview"). |
20
+
21
+ ## Color palette
22
+
23
+ GitHub-familiar greens on a dark canvas.
24
+
25
+ | Token | Hex | Use |
26
+ |-------|-----|-----|
27
+ | Green (primary) | `#3FB950` | Primary brand green (nodes) |
28
+ | Green (deep) | `#238636` / `#2EA043` | Edges, gradients, wordmark on light/dark |
29
+ | Green (bright) | `#56D364` | Node highlights |
30
+ | Mint | `#7EE2A8` | Accent / subtitle text on dark |
31
+ | Canvas | `#0D1117` / `#0A0E14` | Dark backgrounds (banner, icon) |
32
+ | Panel | `#161B22` | Terminal window / tile surface |
33
+ | Border | `#30363D` | Hairline borders |
34
+ | Text | `#E6EDF3` | Primary text on dark |
35
+ | Muted | `#7D8590` / `#8B949E` | Secondary text |
36
+
37
+ Terminal traffic-light dots: `#FF5F56` `#FFBD2E` `#27C93F`.
38
+
39
+ ## Regenerating the PNGs
40
+
41
+ The PNGs are rasterized from the SVGs with [`rsvg-convert`](https://gitlab.gnome.org/GNOME/librsvg)
42
+ (or ImageMagick's `magick`):
43
+
44
+ ```bash
45
+ rsvg-convert -w 512 -h 512 logo.svg -o logo-512.png
46
+ rsvg-convert -w 256 -h 256 logo.svg -o logo-256.png
47
+ rsvg-convert -w 256 -h 256 icon.svg -o icon-256.png
48
+ rsvg-convert -w 64 -h 64 icon.svg -o favicon-64.png
49
+ rsvg-convert -w 32 -h 32 icon.svg -o favicon-32.png
50
+ rsvg-convert -w 1280 -h 640 banner.svg -o banner.png
51
+ ```
52
+
53
+ All artwork is original and released under the project's [MIT license](../LICENSE).
Binary file
@@ -0,0 +1,66 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 640" width="1280" height="640" role="img" aria-label="Nemus — multi-repo workspaces for the AI-agent era">
2
+ <title>Nemus</title>
3
+ <defs>
4
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
5
+ <stop offset="0" stop-color="#0D1117"/>
6
+ <stop offset="1" stop-color="#0A0E14"/>
7
+ </linearGradient>
8
+ <radialGradient id="glow" cx="0.72" cy="0.32" r="0.55">
9
+ <stop offset="0" stop-color="#2EA043" stop-opacity="0.32"/>
10
+ <stop offset="1" stop-color="#2EA043" stop-opacity="0"/>
11
+ </radialGradient>
12
+ <linearGradient id="edge" x1="0" y1="0" x2="0" y2="1">
13
+ <stop offset="0" stop-color="#3FB950"/>
14
+ <stop offset="1" stop-color="#1F7A34"/>
15
+ </linearGradient>
16
+ <radialGradient id="node" cx="0.34" cy="0.28" r="0.9">
17
+ <stop offset="0" stop-color="#7EE2A8"/>
18
+ <stop offset="0.5" stop-color="#3FB950"/>
19
+ <stop offset="1" stop-color="#2EA043"/>
20
+ </radialGradient>
21
+ </defs>
22
+
23
+ <rect width="1280" height="640" fill="url(#bg)"/>
24
+ <rect width="1280" height="640" fill="url(#glow)"/>
25
+
26
+ <!-- wordmark + tagline -->
27
+ <text x="96" y="150" font-family="'SF Mono','JetBrains Mono','Fira Code',ui-monospace,Menlo,Consolas,monospace" font-size="112" font-weight="700" letter-spacing="-3" fill="#E6EDF3">Nemus</text>
28
+ <text x="100" y="204" font-family="ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif" font-size="30" font-weight="500" fill="#7EE2A8">Multi-repo workspaces for the AI-agent era</text>
29
+
30
+ <!-- terminal window -->
31
+ <g transform="translate(96,258)">
32
+ <rect x="0" y="0" width="620" height="300" rx="16" fill="#161B22" stroke="#30363D" stroke-width="2"/>
33
+ <rect x="0" y="0" width="620" height="44" rx="16" fill="#0D1117"/>
34
+ <rect x="0" y="28" width="620" height="16" fill="#0D1117"/>
35
+ <circle cx="26" cy="22" r="7" fill="#FF5F56"/>
36
+ <circle cx="50" cy="22" r="7" fill="#FFBD2E"/>
37
+ <circle cx="74" cy="22" r="7" fill="#27C93F"/>
38
+ <text x="310" y="27" text-anchor="middle" font-family="ui-monospace,Menlo,Consolas,monospace" font-size="16" fill="#7D8590">nemus</text>
39
+
40
+ <g font-family="'SF Mono','JetBrains Mono',ui-monospace,Menlo,Consolas,monospace" font-size="22">
41
+ <text x="30" y="98" fill="#7EE2A8">$ <tspan fill="#E6EDF3">nemus create payments</tspan></text>
42
+ <text x="30" y="140" fill="#7D8590">✓ cloned 12 repositories</text>
43
+ <text x="30" y="182" fill="#7D8590">✓ wrote AGENTS.md · installed skills</text>
44
+ <text x="30" y="224" fill="#7EE2A8">$ <tspan fill="#E6EDF3">nemus -- "start the checkout refactor"</tspan></text>
45
+ <text x="30" y="266" fill="#3FB950">▸ launching agent<tspan fill="#3FB950">█</tspan></text>
46
+ </g>
47
+ </g>
48
+
49
+ <!-- mark on the right -->
50
+ <g transform="translate(858,150) scale(1.5)">
51
+ <g fill="none" stroke-linecap="round">
52
+ <path d="M120 210 L120 150 Q120 140 128 132 L150 108" stroke="url(#edge)" stroke-width="20"/>
53
+ <path d="M122 158 Q108 140 86 128 L70 118" stroke="url(#edge)" stroke-width="13"/>
54
+ <path d="M128 132 L128 78" stroke="url(#edge)" stroke-width="13"/>
55
+ <path d="M86 128 L70 92" stroke="#238636" stroke-width="9"/>
56
+ </g>
57
+ <g>
58
+ <circle cx="150" cy="104" r="15" fill="url(#node)"/>
59
+ <circle cx="150" cy="104" r="15" fill="none" stroke="#7EE2A8" stroke-width="2.5" opacity="0.9"/>
60
+ <circle cx="128" cy="74" r="13" fill="url(#node)"/>
61
+ <circle cx="70" cy="114" r="12" fill="url(#node)"/>
62
+ <circle cx="70" cy="88" r="9" fill="url(#node)"/>
63
+ <circle cx="120" cy="212" r="10" fill="#2EA043"/>
64
+ </g>
65
+ </g>
66
+ </svg>
Binary file
Binary file
Binary file
@@ -0,0 +1,23 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256" role="img" aria-label="Nemus icon">
2
+ <title>Nemus</title>
3
+ <defs>
4
+ <linearGradient id="tile" x1="0" y1="0" x2="1" y2="1">
5
+ <stop offset="0" stop-color="#3FB950"/>
6
+ <stop offset="1" stop-color="#1F7A34"/>
7
+ </linearGradient>
8
+ </defs>
9
+
10
+ <rect x="0" y="0" width="256" height="256" rx="58" fill="url(#tile)"/>
11
+
12
+ <!-- tree carved out of the green (negative space); canopy = 3 lobes -->
13
+ <g fill="#0D1117">
14
+ <rect x="118" y="150" width="20" height="70" rx="9"/>
15
+ <circle cx="128" cy="106" r="54"/>
16
+ <circle cx="84" cy="138" r="30"/>
17
+ <circle cx="172" cy="138" r="30"/>
18
+ </g>
19
+
20
+ <!-- terminal wink: a ">" prompt + cursor cut back in green inside the canopy -->
21
+ <path d="M108 90 l22 18 -22 18" fill="none" stroke="#56D364" stroke-width="11" stroke-linecap="round" stroke-linejoin="round"/>
22
+ <rect x="140" y="115" width="26" height="11" rx="5.5" fill="#56D364"/>
23
+ </svg>
Binary file
Binary file
@@ -0,0 +1,35 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 200" width="640" height="200" role="img" aria-label="Nemus">
2
+ <title>Nemus</title>
3
+ <defs>
4
+ <linearGradient id="edge" x1="0" y1="0" x2="0" y2="1">
5
+ <stop offset="0" stop-color="#3FB950"/>
6
+ <stop offset="1" stop-color="#1F7A34"/>
7
+ </linearGradient>
8
+ <radialGradient id="node" cx="0.34" cy="0.28" r="0.9">
9
+ <stop offset="0" stop-color="#7EE2A8"/>
10
+ <stop offset="0.5" stop-color="#3FB950"/>
11
+ <stop offset="1" stop-color="#2EA043"/>
12
+ </radialGradient>
13
+ </defs>
14
+
15
+ <!-- mark -->
16
+ <g transform="translate(-14,-22) scale(0.82)">
17
+ <g fill="none" stroke-linecap="round">
18
+ <path d="M120 210 L120 150 Q120 140 128 132 L150 108" stroke="url(#edge)" stroke-width="20"/>
19
+ <path d="M122 158 Q108 140 86 128 L70 118" stroke="url(#edge)" stroke-width="13"/>
20
+ <path d="M128 132 L128 78" stroke="url(#edge)" stroke-width="13"/>
21
+ <path d="M86 128 L70 92" stroke="#238636" stroke-width="9"/>
22
+ </g>
23
+ <g>
24
+ <circle cx="150" cy="104" r="15" fill="url(#node)"/>
25
+ <circle cx="150" cy="104" r="15" fill="none" stroke="#7EE2A8" stroke-width="2.5" opacity="0.9"/>
26
+ <circle cx="128" cy="74" r="13" fill="url(#node)"/>
27
+ <circle cx="70" cy="114" r="12" fill="url(#node)"/>
28
+ <circle cx="70" cy="88" r="9" fill="url(#node)"/>
29
+ <circle cx="120" cy="212" r="10" fill="#2EA043"/>
30
+ </g>
31
+ </g>
32
+
33
+ <!-- wordmark: mid-green reads on light AND dark -->
34
+ <text x="196" y="130" font-family="'SF Mono','JetBrains Mono','Fira Code',ui-monospace,Menlo,Consolas,monospace" font-size="104" font-weight="700" letter-spacing="-3" fill="#2EA043">Nemus</text>
35
+ </svg>
@@ -0,0 +1,32 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256" role="img" aria-label="Nemus">
2
+ <title>Nemus</title>
3
+ <defs>
4
+ <linearGradient id="edge" x1="0" y1="0" x2="0" y2="1">
5
+ <stop offset="0" stop-color="#3FB950"/>
6
+ <stop offset="1" stop-color="#1F7A34"/>
7
+ </linearGradient>
8
+ <radialGradient id="node" cx="0.34" cy="0.28" r="0.9">
9
+ <stop offset="0" stop-color="#7EE2A8"/>
10
+ <stop offset="0.5" stop-color="#3FB950"/>
11
+ <stop offset="1" stop-color="#2EA043"/>
12
+ </radialGradient>
13
+ </defs>
14
+
15
+ <!-- an asymmetric sapling that doubles as a git commit graph -->
16
+ <g transform="translate(18,8)">
17
+ <g fill="none" stroke-linecap="round">
18
+ <path d="M120 210 L120 150 Q120 140 128 132 L150 108" stroke="url(#edge)" stroke-width="20"/>
19
+ <path d="M122 158 Q108 140 86 128 L70 118" stroke="url(#edge)" stroke-width="13"/>
20
+ <path d="M128 132 L128 78" stroke="url(#edge)" stroke-width="13"/>
21
+ <path d="M86 128 L70 92" stroke="#238636" stroke-width="9"/>
22
+ </g>
23
+ <g>
24
+ <circle cx="150" cy="104" r="15" fill="url(#node)"/>
25
+ <circle cx="150" cy="104" r="15" fill="none" stroke="#7EE2A8" stroke-width="2.5" opacity="0.9"/>
26
+ <circle cx="128" cy="74" r="13" fill="url(#node)"/>
27
+ <circle cx="70" cy="114" r="12" fill="url(#node)"/>
28
+ <circle cx="70" cy="88" r="9" fill="url(#node)"/>
29
+ <circle cx="120" cy="212" r="10" fill="#2EA043"/>
30
+ </g>
31
+ </g>
32
+ </svg>