nano-duoshe 0.1.0-alpha.2

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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +282 -0
  3. package/README.zh-CN.md +285 -0
  4. package/dist/adapters/claude-md.d.ts +40 -0
  5. package/dist/adapters/claude-md.d.ts.map +1 -0
  6. package/dist/adapters/claude-md.js +108 -0
  7. package/dist/adapters/claude-md.js.map +1 -0
  8. package/dist/adapters/gitignore.d.ts +17 -0
  9. package/dist/adapters/gitignore.d.ts.map +1 -0
  10. package/dist/adapters/gitignore.js +49 -0
  11. package/dist/adapters/gitignore.js.map +1 -0
  12. package/dist/cli/assistant.d.ts +2 -0
  13. package/dist/cli/assistant.d.ts.map +1 -0
  14. package/dist/cli/assistant.js +36 -0
  15. package/dist/cli/assistant.js.map +1 -0
  16. package/dist/cli/commands/graph.d.ts +3 -0
  17. package/dist/cli/commands/graph.d.ts.map +1 -0
  18. package/dist/cli/commands/graph.js +97 -0
  19. package/dist/cli/commands/graph.js.map +1 -0
  20. package/dist/cli/commands/guide.d.ts +4 -0
  21. package/dist/cli/commands/guide.d.ts.map +1 -0
  22. package/dist/cli/commands/guide.js +118 -0
  23. package/dist/cli/commands/guide.js.map +1 -0
  24. package/dist/cli/commands/init.d.ts +3 -0
  25. package/dist/cli/commands/init.d.ts.map +1 -0
  26. package/dist/cli/commands/init.js +338 -0
  27. package/dist/cli/commands/init.js.map +1 -0
  28. package/dist/cli/commands/mcp.d.ts +3 -0
  29. package/dist/cli/commands/mcp.d.ts.map +1 -0
  30. package/dist/cli/commands/mcp.js +10 -0
  31. package/dist/cli/commands/mcp.js.map +1 -0
  32. package/dist/cli/commands/profile.d.ts +3 -0
  33. package/dist/cli/commands/profile.d.ts.map +1 -0
  34. package/dist/cli/commands/profile.js +91 -0
  35. package/dist/cli/commands/profile.js.map +1 -0
  36. package/dist/cli/commands/remember.d.ts +3 -0
  37. package/dist/cli/commands/remember.d.ts.map +1 -0
  38. package/dist/cli/commands/remember.js +110 -0
  39. package/dist/cli/commands/remember.js.map +1 -0
  40. package/dist/cli/commands/review.d.ts +3 -0
  41. package/dist/cli/commands/review.d.ts.map +1 -0
  42. package/dist/cli/commands/review.js +175 -0
  43. package/dist/cli/commands/review.js.map +1 -0
  44. package/dist/cli/commands/search.d.ts +3 -0
  45. package/dist/cli/commands/search.d.ts.map +1 -0
  46. package/dist/cli/commands/search.js +157 -0
  47. package/dist/cli/commands/search.js.map +1 -0
  48. package/dist/cli/commands/session.d.ts +3 -0
  49. package/dist/cli/commands/session.d.ts.map +1 -0
  50. package/dist/cli/commands/session.js +33 -0
  51. package/dist/cli/commands/session.js.map +1 -0
  52. package/dist/cli/commands/skill.d.ts +3 -0
  53. package/dist/cli/commands/skill.d.ts.map +1 -0
  54. package/dist/cli/commands/skill.js +81 -0
  55. package/dist/cli/commands/skill.js.map +1 -0
  56. package/dist/cli/commands/sync.d.ts +3 -0
  57. package/dist/cli/commands/sync.d.ts.map +1 -0
  58. package/dist/cli/commands/sync.js +43 -0
  59. package/dist/cli/commands/sync.js.map +1 -0
  60. package/dist/cli/commands/upgrade.d.ts +3 -0
  61. package/dist/cli/commands/upgrade.d.ts.map +1 -0
  62. package/dist/cli/commands/upgrade.js +87 -0
  63. package/dist/cli/commands/upgrade.js.map +1 -0
  64. package/dist/cli/index.d.ts +3 -0
  65. package/dist/cli/index.d.ts.map +1 -0
  66. package/dist/cli/index.js +143 -0
  67. package/dist/cli/index.js.map +1 -0
  68. package/dist/cli/log.d.ts +10 -0
  69. package/dist/cli/log.d.ts.map +1 -0
  70. package/dist/cli/log.js +25 -0
  71. package/dist/cli/log.js.map +1 -0
  72. package/dist/cli/nudge-throttle.d.ts +2 -0
  73. package/dist/cli/nudge-throttle.d.ts.map +1 -0
  74. package/dist/cli/nudge-throttle.js +44 -0
  75. package/dist/cli/nudge-throttle.js.map +1 -0
  76. package/dist/cli/stub.d.ts +2 -0
  77. package/dist/cli/stub.d.ts.map +1 -0
  78. package/dist/cli/stub.js +6 -0
  79. package/dist/cli/stub.js.map +1 -0
  80. package/dist/core/candidate/id.d.ts +2 -0
  81. package/dist/core/candidate/id.d.ts.map +1 -0
  82. package/dist/core/candidate/id.js +7 -0
  83. package/dist/core/candidate/id.js.map +1 -0
  84. package/dist/core/candidate/index.d.ts +5 -0
  85. package/dist/core/candidate/index.d.ts.map +1 -0
  86. package/dist/core/candidate/index.js +5 -0
  87. package/dist/core/candidate/index.js.map +1 -0
  88. package/dist/core/candidate/publish.d.ts +12 -0
  89. package/dist/core/candidate/publish.d.ts.map +1 -0
  90. package/dist/core/candidate/publish.js +79 -0
  91. package/dist/core/candidate/publish.js.map +1 -0
  92. package/dist/core/candidate/store.d.ts +14 -0
  93. package/dist/core/candidate/store.d.ts.map +1 -0
  94. package/dist/core/candidate/store.js +117 -0
  95. package/dist/core/candidate/store.js.map +1 -0
  96. package/dist/core/candidate/target.d.ts +5 -0
  97. package/dist/core/candidate/target.d.ts.map +1 -0
  98. package/dist/core/candidate/target.js +28 -0
  99. package/dist/core/candidate/target.js.map +1 -0
  100. package/dist/core/index/db.d.ts +5 -0
  101. package/dist/core/index/db.d.ts.map +1 -0
  102. package/dist/core/index/db.js +21 -0
  103. package/dist/core/index/db.js.map +1 -0
  104. package/dist/core/index/index.d.ts +4 -0
  105. package/dist/core/index/index.d.ts.map +1 -0
  106. package/dist/core/index/index.js +4 -0
  107. package/dist/core/index/index.js.map +1 -0
  108. package/dist/core/index/indexer.d.ts +7 -0
  109. package/dist/core/index/indexer.d.ts.map +1 -0
  110. package/dist/core/index/indexer.js +90 -0
  111. package/dist/core/index/indexer.js.map +1 -0
  112. package/dist/core/index/schema.d.ts +3 -0
  113. package/dist/core/index/schema.d.ts.map +1 -0
  114. package/dist/core/index/schema.js +35 -0
  115. package/dist/core/index/schema.js.map +1 -0
  116. package/dist/core/index/search.d.ts +15 -0
  117. package/dist/core/index/search.d.ts.map +1 -0
  118. package/dist/core/index/search.js +107 -0
  119. package/dist/core/index/search.js.map +1 -0
  120. package/dist/core/index/sections.d.ts +9 -0
  121. package/dist/core/index/sections.d.ts.map +1 -0
  122. package/dist/core/index/sections.js +55 -0
  123. package/dist/core/index/sections.js.map +1 -0
  124. package/dist/core/index/tokenize.d.ts +3 -0
  125. package/dist/core/index/tokenize.d.ts.map +1 -0
  126. package/dist/core/index/tokenize.js +28 -0
  127. package/dist/core/index/tokenize.js.map +1 -0
  128. package/dist/core/profile/detect.d.ts +10 -0
  129. package/dist/core/profile/detect.d.ts.map +1 -0
  130. package/dist/core/profile/detect.js +211 -0
  131. package/dist/core/profile/detect.js.map +1 -0
  132. package/dist/core/scanner/filetree.d.ts +10 -0
  133. package/dist/core/scanner/filetree.d.ts.map +1 -0
  134. package/dist/core/scanner/filetree.js +263 -0
  135. package/dist/core/scanner/filetree.js.map +1 -0
  136. package/dist/core/scanner/git.d.ts +5 -0
  137. package/dist/core/scanner/git.d.ts.map +1 -0
  138. package/dist/core/scanner/git.js +131 -0
  139. package/dist/core/scanner/git.js.map +1 -0
  140. package/dist/core/scanner/index.d.ts +13 -0
  141. package/dist/core/scanner/index.d.ts.map +1 -0
  142. package/dist/core/scanner/index.js +32 -0
  143. package/dist/core/scanner/index.js.map +1 -0
  144. package/dist/core/scanner/stack.d.ts +9 -0
  145. package/dist/core/scanner/stack.d.ts.map +1 -0
  146. package/dist/core/scanner/stack.js +719 -0
  147. package/dist/core/scanner/stack.js.map +1 -0
  148. package/dist/core/skills/manager.d.ts +21 -0
  149. package/dist/core/skills/manager.d.ts.map +1 -0
  150. package/dist/core/skills/manager.js +138 -0
  151. package/dist/core/skills/manager.js.map +1 -0
  152. package/dist/core/types.d.ts +107 -0
  153. package/dist/core/types.d.ts.map +1 -0
  154. package/dist/core/types.js +22 -0
  155. package/dist/core/types.js.map +1 -0
  156. package/dist/core/update/check.d.ts +9 -0
  157. package/dist/core/update/check.d.ts.map +1 -0
  158. package/dist/core/update/check.js +135 -0
  159. package/dist/core/update/check.js.map +1 -0
  160. package/dist/core/vault/config.d.ts +10 -0
  161. package/dist/core/vault/config.d.ts.map +1 -0
  162. package/dist/core/vault/config.js +39 -0
  163. package/dist/core/vault/config.js.map +1 -0
  164. package/dist/core/vault/index.d.ts +17 -0
  165. package/dist/core/vault/index.d.ts.map +1 -0
  166. package/dist/core/vault/index.js +66 -0
  167. package/dist/core/vault/index.js.map +1 -0
  168. package/dist/core/vault/paths.d.ts +24 -0
  169. package/dist/core/vault/paths.d.ts.map +1 -0
  170. package/dist/core/vault/paths.js +28 -0
  171. package/dist/core/vault/paths.js.map +1 -0
  172. package/dist/core/vault/templates.d.ts +21 -0
  173. package/dist/core/vault/templates.d.ts.map +1 -0
  174. package/dist/core/vault/templates.js +357 -0
  175. package/dist/core/vault/templates.js.map +1 -0
  176. package/dist/core/version.d.ts +2 -0
  177. package/dist/core/version.d.ts.map +1 -0
  178. package/dist/core/version.js +26 -0
  179. package/dist/core/version.js.map +1 -0
  180. package/dist/index.d.ts +2 -0
  181. package/dist/index.d.ts.map +1 -0
  182. package/dist/index.js +2 -0
  183. package/dist/index.js.map +1 -0
  184. package/dist/skills/devops/README.md +27 -0
  185. package/dist/skills/devops/skill.json +22 -0
  186. package/dist/skills/embedded/README.md +23 -0
  187. package/dist/skills/embedded/skill.json +40 -0
  188. package/dist/skills/graph/analyzer.d.ts +16 -0
  189. package/dist/skills/graph/analyzer.d.ts.map +1 -0
  190. package/dist/skills/graph/analyzer.js +163 -0
  191. package/dist/skills/graph/analyzer.js.map +1 -0
  192. package/dist/skills/graph/index.d.ts +5 -0
  193. package/dist/skills/graph/index.d.ts.map +1 -0
  194. package/dist/skills/graph/index.js +31 -0
  195. package/dist/skills/graph/index.js.map +1 -0
  196. package/dist/skills/graph/skill.json +8 -0
  197. package/dist/skills/matlab/README.md +26 -0
  198. package/dist/skills/matlab/skill.json +22 -0
  199. package/dist/skills/wordpress/README.md +31 -0
  200. package/dist/skills/wordpress/skill.json +17 -0
  201. package/package.json +69 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 guangdino
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,282 @@
1
+ # nano-duoshe
2
+
3
+ > Local-first project memory for AI coding agents (Claude Code / Codex / Cursor).
4
+ >
5
+ > Keep project conventions, decisions, gotchas, and module boundaries next to your code — so the agent doesn't start from zero every session.
6
+
7
+ **English** | [简体中文](./README.zh-CN.md)
8
+
9
+ ## Why
10
+
11
+ AI coding agents are powerful, but every new session hits the same cold-start problem:
12
+
13
+ - the agent doesn't remember your project structure;
14
+ - you re-explain architecture, conventions, and "don't touch this" rules every time;
15
+ - it re-suggests fixes you already rejected;
16
+ - it re-opens bugs you already solved;
17
+ - `CLAUDE.md` / `AGENTS.md` help, but they're flat hand-edited files — no review, no provenance, no search.
18
+
19
+ DuoShe drops a small local memory layer into each repo: long-term memory as Markdown, candidate memories that go through a review queue before becoming permanent, and SQLite FTS5 for search. Local, fast, rebuildable.
20
+
21
+ ---
22
+
23
+ ## 30-second start
24
+
25
+ ```bash
26
+ npm install -g nano-duoshe # install
27
+ cd your-project
28
+ duoshe init --guided # init + 3 core questions + smart skill suggestion
29
+ ```
30
+
31
+ That's it. After it finishes you'll have three daily commands:
32
+
33
+ ```bash
34
+ duoshe remember "..." # capture something you don't want to forget
35
+ duoshe review # see pending candidates, save or drop
36
+ duoshe search "..." # find what you wrote before
37
+ ```
38
+
39
+ ---
40
+
41
+ ## What it creates
42
+
43
+ ```text
44
+ your-project/
45
+ ├─ .duoshe/ # project memory vault (some public, some private)
46
+ │ ├─ PROJECT.md # ✅ overview, stack, conventions (commit)
47
+ │ ├─ CODEMAP.md # ✅ code map, entry points, routing notes (commit)
48
+ │ ├─ DECISIONS.md # ✅ architecture decisions and rationale (commit)
49
+ │ ├─ TROUBLESHOOTING.md # ✅ known issues and fixes (commit)
50
+ │ ├─ MODULES.md # ✅ module boundaries — especially "does NOT own" (commit)
51
+ │ ├─ TODO.md # ✅ current and upcoming work (commit)
52
+ │ ├─ SETUP.md # ✅ team onboarding guide (commit)
53
+ │ ├─ SKILLS/ # ✅ enabled skill manifests (commit)
54
+ │ ├─ config.json # ❌ local config (personal preference, don't commit)
55
+ │ ├─ CANDIDATES/ # ❌ pending drafts the user hasn't decided on (don't commit)
56
+ │ └─ index.db # ❌ SQLite FTS5 index, rebuildable (don't commit)
57
+ ├─ AGENTS.md # auto-appended DuoShe block pointing Codex at .duoshe/
58
+ ├─ CLAUDE.md # auto-appended DuoShe block pointing Claude Code at .duoshe/
59
+ └─ .gitignore # auto-maintained block for local state
60
+ ```
61
+
62
+ When run inside a git repo, `duoshe init` **auto-maintains `.gitignore`** so private state stays local. Public memory (`PROJECT.md` etc.) you just `git add` / `git commit` normally.
63
+
64
+ The core rule: **agents can propose memory; humans decide what becomes long-term knowledge.**
65
+
66
+ ---
67
+
68
+ ## Two ways to use it
69
+
70
+ ### 1. First time (use --guided)
71
+
72
+ ```bash
73
+ duoshe init --guided
74
+ ```
75
+
76
+ This:
77
+
78
+ 1. scans the project and generates draft templates;
79
+ 2. detects the project profile (embedded / algo / site-maintenance / AI-app / general / kid);
80
+ 3. installs the bundled skills (disabled by default);
81
+ 4. syncs `CLAUDE.md` / `AGENTS.md`;
82
+ 5. asks 3 core questions (what's the project, rules the AI must follow, zones not to touch);
83
+ 6. if it detected an embedded / algo / WordPress project, offers to enable the matching skill.
84
+
85
+ Takes about a minute end-to-end.
86
+
87
+ ### 2. Daily use (3 commands)
88
+
89
+ ```bash
90
+ duoshe remember "DB access must go through the service layer, not direct from routes"
91
+ duoshe review # list pending, then save <id> or drop <id>
92
+ duoshe search "service" # find prior notes
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Skills (opt-in domain support)
98
+
99
+ DuoShe ships several optional domain skills, **disabled by default**:
100
+
101
+ | Skill | When it helps |
102
+ |---|---|
103
+ | `embedded` | C firmware / FPGA / PLC (STM32, ESP32, Vivado, Codesys, TwinCAT) |
104
+ | `matlab` | Algorithms / control engineering (MATLAB / Simulink / heavy math) |
105
+ | `devops` | Infrastructure / IaC (Terraform, Ansible, Kubernetes) |
106
+ | `wordpress` | WordPress site maintenance (also fine for non-developers) |
107
+ | `graph` | Import-graph analysis, cycle detection, hot modules |
108
+
109
+ ```bash
110
+ duoshe skill list # list everything that's installed
111
+ duoshe skill enable embedded # turn one on (prints a short readme intro)
112
+ duoshe rescan # re-scan to apply the new detectors / dir labels
113
+ duoshe skill disable embedded # turn it off
114
+ ```
115
+
116
+ Once enabled, `rescan` uses the skill's extra detectors and directory labels to enrich project memory.
117
+
118
+ ---
119
+
120
+ ## Profile (project type)
121
+
122
+ `duoshe init` auto-detects a project profile, which controls the first-step hints and which skills get suggested.
123
+
124
+ ```bash
125
+ duoshe profile show # current profile + what a fresh scan would guess now
126
+ duoshe profile list # all available profiles
127
+ duoshe profile set embedded # set manually — won't get overwritten by auto-detect
128
+ ```
129
+
130
+ Profiles: `kid` (learning / tutorial), `non_dev_site` (site maintenance), `algo` (algorithms / research), `embedded` (firmware / FPGA / PLC), `ai_app` (AI app / agent), `general` (default).
131
+
132
+ ---
133
+
134
+ ## All commands
135
+
136
+ | Command | Description |
137
+ |---|---|
138
+ | `duoshe init` | Initialize memory vault (scan + generate drafts) in the current directory |
139
+ | `duoshe init --guided` | Recommended: init + 3 questions + smart skill suggestion |
140
+ | `duoshe init --force` | Force-rewrite drafts (sections marked `<!-- USER-CONFIRMED -->` are preserved) |
141
+ | `duoshe init --quick` | Skip git history scan (faster on large repos) |
142
+ | `duoshe guide` | Just the 3 questions (re-runnable any time after init) |
143
+ | `duoshe rescan` | Re-scan and refresh the code skeleton (preserves confirmed sections) |
144
+ | `duoshe remember "..."` | Add a pending memory candidate |
145
+ | `duoshe review` | List pending candidates |
146
+ | `duoshe save <id>` | Promote to long-term memory (alias: `publish`) |
147
+ | `duoshe drop <id>` | Discard (alias: `reject`) |
148
+ | `duoshe search "..."` | Search long-term memory via SQLite FTS5 |
149
+ | `duoshe reindex` | Rebuild the local search index |
150
+ | `duoshe skill list` | List available / enabled skills |
151
+ | `duoshe skill enable <name>` | Enable a skill |
152
+ | `duoshe skill disable <name>` | Disable a skill |
153
+ | `duoshe profile show / list / set` | View or change the project profile |
154
+ | `duoshe sync` | Sync DuoShe blocks in `CLAUDE.md` / `AGENTS.md` |
155
+ | `duoshe graph` | Analyze import dependencies (requires `graph` skill enabled) |
156
+ | `duoshe upgrade` | Check for a new nano-duoshe release |
157
+ | `duoshe uninstall` | Remove DuoShe blocks from `CLAUDE.md` / `AGENTS.md` (does not delete `.duoshe/`) |
158
+ | `duoshe mcp` | _Planned_: MCP stdio server |
159
+ | `duoshe session ...` | _Planned_: import conversation transcripts |
160
+
161
+ Candidate types: `decision`, `troubleshooting`, `module_boundary`, `project_fact`, `user_preference`.
162
+
163
+ ---
164
+
165
+ ## Team workflow
166
+
167
+ - After you `git push`, **teammates don't need to run `duoshe init`** — the repo already has the shared `.duoshe/` memory.
168
+ - For them to use `duoshe` commands locally: `npm i -g nano-duoshe`, then run anywhere in the project.
169
+ - First run rebuilds the local search index automatically (doesn't affect others).
170
+ - To make tools that don't read `CLAUDE.md` (e.g. Cursor) use the memory, see `.duoshe/SETUP.md`.
171
+
172
+ ---
173
+
174
+ ## Current status
175
+
176
+ `0.1.0-alpha.0`. Implemented:
177
+
178
+ - repo scan + PROJECT.md / CODEMAP.md / DECISIONS.md draft generation
179
+ - auto profile detection (6 profiles)
180
+ - 5 bundled optional skills (embedded / matlab / devops / wordpress / graph)
181
+ - CLAUDE.md / AGENTS.md auto-sync (preserves existing content)
182
+ - candidate → review → save / drop flow
183
+ - SQLite FTS5 search with CJK + Latin tokenization
184
+ - `.gitignore` auto-maintenance (private state isolation)
185
+ - simple guided mode (`init --guided`)
186
+ - soft update notifier + `duoshe upgrade`
187
+ - CI: Linux / macOS / Windows × Node 20/22 lint / typecheck / test / build
188
+
189
+ Planned:
190
+
191
+ - **M4**: session transcript import and deduplication
192
+ - **M5**: MCP stdio server (`memory.search`, `memory.get_project_context`, candidate tools)
193
+ - **M6**: Claude Code hook templates
194
+ - **v0.2**: optional LLM-assisted candidate extraction
195
+
196
+ ---
197
+
198
+ ## Design principles
199
+
200
+ - **Local-first.** Memory lives in your repo as Markdown and SQLite. No cloud.
201
+ - **Review before permanence.** Agent suggestions go through a candidate queue.
202
+ - **Traceable.** Saved memory keeps source metadata.
203
+ - **Tool-agnostic.** The CLI works everywhere; MCP is the next adapter.
204
+ - **Non-invasive.** DuoShe only edits its own delimited block in `CLAUDE.md` / `AGENTS.md`.
205
+ - **Rebuildable index.** `index.db` is derived data; regenerable any time.
206
+ - **Occam's razor.** The core is 5 essential commands; domain features grow as opt-in skills.
207
+
208
+ ---
209
+
210
+ ## Install
211
+
212
+ Once published:
213
+
214
+ ```bash
215
+ npm install -g nano-duoshe
216
+ ```
217
+
218
+ Local development:
219
+
220
+ ```bash
221
+ git clone https://github.com/guangdino/nano-duoshe.git
222
+ cd nano-duoshe
223
+ npm install
224
+ npm run build
225
+ npm link
226
+ ```
227
+
228
+ Requirements: Node.js 20+, npm, native build support for `better-sqlite3`.
229
+
230
+ ---
231
+
232
+ ## Privacy
233
+
234
+ DuoShe is local-first. Public memory files are normal Markdown — you decide what enters git. `index.db`, `CANDIDATES/`, and future `SESSIONS/` are rebuildable / noisy / private and should generally stay out of version control (`duoshe init` adds them to `.gitignore` automatically).
235
+
236
+ ---
237
+
238
+ ## Development
239
+
240
+ ```bash
241
+ npm install
242
+ npm run lint
243
+ npm run typecheck
244
+ npm test
245
+ npm run build
246
+ ```
247
+
248
+ | Script | Purpose |
249
+ |---|---|
250
+ | `npm run dev` | Run the TypeScript CLI through `tsx` |
251
+ | `npm run build` | Compile to `dist/` (with skill assets) |
252
+ | `npm test` | Vitest |
253
+ | `npm run lint` | Biome |
254
+ | `npm run prepublishOnly` | Release gate: lint + typecheck + test + build |
255
+
256
+ See [DESIGN.md](./DESIGN.md) for the engineering plan.
257
+
258
+ ---
259
+
260
+ ## Contributing
261
+
262
+ DuoShe is early. Issues, discussions, and small focused PRs are welcome.
263
+
264
+ Before opening a PR:
265
+
266
+ ```bash
267
+ npm run prepublishOnly
268
+ ```
269
+
270
+ Please keep changes aligned with these constraints:
271
+
272
+ - don't auto-promote agent output to long-term memory;
273
+ - preserve existing user content in `CLAUDE.md` / `AGENTS.md`;
274
+ - keep core logic independent from CLI and future MCP adapters;
275
+ - prefer simple local formats over remote services;
276
+ - new domain capabilities go in as skills rather than into the core.
277
+
278
+ ---
279
+
280
+ ## License
281
+
282
+ MIT. See [LICENSE](./LICENSE).
@@ -0,0 +1,285 @@
1
+ # nano-duoshe(夺舍)
2
+
3
+ > 本地优先的项目记忆层,给 AI 编程工具(Claude Code / Codex / Cursor)用。
4
+ >
5
+ > 把项目约定、决策、踩坑、模块边界放进代码仓库里 —— AI 下次进项目时不再像第一次来。
6
+
7
+ [English](./README.md) | **简体中文**
8
+
9
+ ## 为什么做 DuoShe
10
+
11
+ AI 编程工具已经很强,但有一个很烦的冷启动问题:
12
+
13
+ - 每次新会话都不记得项目结构;
14
+ - 你反复解释架构、约定和"千万别动"的地方;
15
+ - 它会重复推荐你已经否掉的方案;
16
+ - 它会重新踩你已经修过的坑;
17
+ - `CLAUDE.md` / `AGENTS.md` 有用,但本质是扁平手写文件,没有 review、来源追踪、也搜不动。
18
+
19
+ DuoShe 在每个项目里放一个轻量的本地记忆库:长期记忆是 Markdown,候选记忆先进 review 队列、确认后再保存,搜索用 SQLite FTS5。本地、快、可重建。
20
+
21
+ ---
22
+
23
+ ## 30 秒上手
24
+
25
+ ```bash
26
+ npm install -g nano-duoshe # 安装
27
+ cd your-project
28
+ duoshe init --guided # 初始化 + 3 个核心问题 + 智能推荐 skill
29
+ ```
30
+
31
+ 就这样。完成后会告诉你日常用 3 个命令:
32
+
33
+ ```bash
34
+ duoshe remember "..." # 想到什么先记下来
35
+ duoshe review # 看待确认的记录,保存或丢弃
36
+ duoshe search "..." # 在项目记忆里搜
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 它会生成什么
42
+
43
+ ```text
44
+ your-project/
45
+ ├─ .duoshe/ # 项目记忆库(部分文件公共、部分私人)
46
+ │ ├─ PROJECT.md # ✅ 项目概览、技术栈、约定(commit)
47
+ │ ├─ CODEMAP.md # ✅ 代码地图、入口、路由提示(commit)
48
+ │ ├─ DECISIONS.md # ✅ 架构决策和原因(commit)
49
+ │ ├─ TROUBLESHOOTING.md # ✅ 已知问题和修法(commit)
50
+ │ ├─ MODULES.md # ✅ 模块边界,特别是"不该做什么"(commit)
51
+ │ ├─ TODO.md # ✅ 当前 / 接下来的工作(commit)
52
+ │ ├─ SETUP.md # ✅ 给团队看的接入说明(commit)
53
+ │ ├─ SKILLS/ # ✅ 已启用的技能 manifest(commit)
54
+ │ ├─ config.json # ❌ 本地配置(个人偏好,不 commit)
55
+ │ ├─ CANDIDATES/ # ❌ 草稿状态的待确认记录(不 commit)
56
+ │ └─ index.db # ❌ SQLite FTS5 索引,可重建(不 commit)
57
+ ├─ AGENTS.md # 自动追加 DuoShe 块,引导 Codex 读 .duoshe/
58
+ ├─ CLAUDE.md # 自动追加 DuoShe 块,引导 Claude Code 读 .duoshe/
59
+ └─ .gitignore # 自动加入需要忽略的本地状态
60
+ ```
61
+
62
+ `duoshe init` 在 git 仓库里跑时会**自动维护 `.gitignore`**,把私人状态加进去。
63
+ 公共记忆(PROJECT.md 等)正常 `git add` / `git commit` 即可。
64
+
65
+ 核心规则:**AI 可以提出记忆,人来决定什么进入长期记忆。**
66
+
67
+ ---
68
+
69
+ ## 用 DuoShe 的两种姿势
70
+
71
+ ### 1. 第一次跑(推荐 --guided)
72
+
73
+ ```bash
74
+ duoshe init --guided
75
+ ```
76
+
77
+ 这会:
78
+
79
+ 1. 扫描项目,生成草稿模板;
80
+ 2. 检测项目类型(嵌入式 / 算法 / 网站 / AI 应用 / 通用 / 学习项目);
81
+ 3. 安装内置技能(默认不启用);
82
+ 4. 同步 `CLAUDE.md` / `AGENTS.md`;
83
+ 5. 问 3 个核心问题(项目是干嘛的、AI 必须记住的规矩、不要乱动的地方);
84
+ 6. 如果检测到嵌入式 / 算法 / WordPress,问你要不要启用对应 skill。
85
+
86
+ 完整体验 1 分钟左右。
87
+
88
+ ### 2. 日常用(3 个命令)
89
+
90
+ ```bash
91
+ duoshe remember "数据库操作必须走 service 层,不能在 route 里直查"
92
+ duoshe review # 看待确认,输入 save <id> / drop <id>
93
+ duoshe search "service" # 找过去记下的内容
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Skills(按需启用的扩展能力)
99
+
100
+ DuoShe 自带一些专项识别能力,**默认不启用**,按需打开:
101
+
102
+ | Skill | 适合什么场景 |
103
+ |---|---|
104
+ | `embedded` | 嵌入式开发(C 固件 / FPGA / PLC / STM32 / ESP32 / Vivado / Codesys) |
105
+ | `matlab` | 算法 / 控制工程(MATLAB / Simulink / 数学推导密集型项目) |
106
+ | `devops` | 基础设施 / IaC(Terraform / Ansible / Kubernetes) |
107
+ | `wordpress` | WordPress 站点维护(非开发者也能用) |
108
+ | `graph` | 依赖图分析、循环依赖检测、热点模块 |
109
+
110
+ 操作:
111
+
112
+ ```bash
113
+ duoshe skill list # 看所有已安装的
114
+ duoshe skill enable embedded # 启用一个(会打印一段引导)
115
+ duoshe rescan # 用新激活的 skill 重新扫描
116
+ duoshe skill disable embedded # 关掉
117
+ ```
118
+
119
+ 启用后 `rescan` 会用新增的探测器和目录标签丰富项目记忆。
120
+
121
+ ---
122
+
123
+ ## Profile(项目类型)
124
+
125
+ DuoShe 在 init 时会自动猜你的项目类型 —— 这影响 PROJECT.md 的引导提示和默认建议的 skill。
126
+
127
+ ```bash
128
+ duoshe profile show # 看当前类型 + 现在重新扫描会猜啥
129
+ duoshe profile list # 看所有可选类型
130
+ duoshe profile set embedded # 手动设置,下次不会被自动检测覆盖
131
+ ```
132
+
133
+ 类型:`kid`(学习 / 练习)、`non_dev_site`(网站维护)、`algo`(算法 / 研究)、`embedded`(嵌入式 / FPGA / PLC)、`ai_app`(AI 应用 / Agent)、`general`(通用)。
134
+
135
+ ---
136
+
137
+ ## 全部命令
138
+
139
+ | 命令 | 说明 |
140
+ |---|---|
141
+ | `duoshe init` | 在当前目录初始化记忆库(扫描 + 生成 PROJECT.md 等草稿) |
142
+ | `duoshe init --guided` | 推荐:初始化 + 3 个问题 + 智能推荐 skill |
143
+ | `duoshe init --force` | 强制重写草稿(带 `<!-- USER-CONFIRMED -->` 的内容会保留) |
144
+ | `duoshe init --quick` | 跳过 git 历史扫描(大仓库更快) |
145
+ | `duoshe guide` | 单独跑 3 个问题(init 后随时可再跑) |
146
+ | `duoshe rescan` | 重扫项目,刷新代码骨架(保留你确认过的部分) |
147
+ | `duoshe remember "..."` | 添加一条候选记忆(pending 状态) |
148
+ | `duoshe review` | 看待确认的记录 |
149
+ | `duoshe save <id>` | 保存到长期记忆(别名:`publish`) |
150
+ | `duoshe drop <id>` | 丢弃(别名:`reject`) |
151
+ | `duoshe search "..."` | 用 SQLite FTS5 搜长期记忆 |
152
+ | `duoshe reindex` | 重建本地搜索索引 |
153
+ | `duoshe skill list` | 列出所有可用 / 已启用技能 |
154
+ | `duoshe skill enable <name>` | 启用技能 |
155
+ | `duoshe skill disable <name>` | 禁用技能 |
156
+ | `duoshe profile show / list / set` | 看 / 改项目类型 |
157
+ | `duoshe sync` | 同步 CLAUDE.md / AGENTS.md 里的 DuoShe 块 |
158
+ | `duoshe graph` | 分析代码 import 依赖(需启用 graph skill) |
159
+ | `duoshe upgrade` | 检查 nano-duoshe 有没有新版本 |
160
+ | `duoshe uninstall` | 从 CLAUDE.md / AGENTS.md 移除 DuoShe 块(不删除 .duoshe/) |
161
+ | `duoshe mcp` | _规划中_:启动 MCP stdio server |
162
+ | `duoshe session ...` | _规划中_:导入对话 transcript |
163
+
164
+ 候选类型:`decision`、`troubleshooting`、`module_boundary`、`project_fact`、`user_preference`。
165
+
166
+ ---
167
+
168
+ ## 团队协作
169
+
170
+ - `git push` 之后,**其他人 pull 下来不用再跑 `duoshe init`** —— 仓库里已经有 `.duoshe/` 的公共记忆了。
171
+ - 队友想用 `duoshe` 命令搜索 / 记录,让他们 `npm i -g nano-duoshe`,然后在项目目录跑就行。
172
+ - 第一次跑命令时 duoshe 会自动重建本地搜索索引(不影响别人)。
173
+ - 想让 Cursor 之类不读 `CLAUDE.md` 的工具也用上记忆,看 `.duoshe/SETUP.md` 里的说明。
174
+
175
+ ---
176
+
177
+ ## 当前状态
178
+
179
+ `0.1.0-alpha.0`。已实现:
180
+
181
+ - 仓库扫描 + 生成 PROJECT.md / CODEMAP.md / DECISIONS.md 等草稿
182
+ - 项目类型自动检测(6 种 profile)
183
+ - 内置 5 个可选 skill(embedded / matlab / devops / wordpress / graph)
184
+ - CLAUDE.md / AGENTS.md 自动同步(不覆盖你的原内容)
185
+ - 候选记忆 → review → save / drop 流程
186
+ - SQLite FTS5 中英文搜索(CJK bigram + Latin 分词)
187
+ - `.gitignore` 自动维护(私人状态隔离)
188
+ - 简易引导模式(init --guided)
189
+ - 软更新通知 + `duoshe upgrade`
190
+ - CI workflow:Linux / macOS / Windows × Node 20/22 跑 lint / typecheck / test / build
191
+
192
+ 规划中:
193
+
194
+ - M4: Session transcript 导入和去重
195
+ - M5: MCP stdio server(`memory.search`、`memory.get_project_context` 等工具)
196
+ - M6: Claude Code hooks 模板
197
+ - v0.2: 可选的 LLM 辅助候选提取
198
+
199
+ ---
200
+
201
+ ## 设计原则
202
+
203
+ - **本地优先。** 记忆存仓库里,用 Markdown 和 SQLite,不依赖云服务。
204
+ - **先 review,再长期化。** AI 提的建议先进候选队列。
205
+ - **可追溯。** 保存后的记忆保留来源元信息。
206
+ - **工具中立。** CLI 永远可用,MCP 是下一步接入层。
207
+ - **不侵入。** DuoShe 只动 `CLAUDE.md` / `AGENTS.md` 里自己那段带标记的块。
208
+ - **索引可重建。** `index.db` 是派生数据,随时可以重新生成。
209
+ - **奥卡姆剃刀。** 核心只保留最不可少的 5 个命令;专项功能用 skill 按需启用。
210
+
211
+ ---
212
+
213
+ ## 安装
214
+
215
+ 正常用:
216
+
217
+ ```bash
218
+ npm install -g nano-duoshe
219
+ ```
220
+
221
+ 本地开发:
222
+
223
+ ```bash
224
+ git clone https://github.com/guangdino/nano-duoshe.git
225
+ cd nano-duoshe
226
+ npm install
227
+ npm run build
228
+ npm link
229
+ ```
230
+
231
+ 要求:Node.js 20+、npm、能编译 `better-sqlite3` 的环境。
232
+
233
+ ---
234
+
235
+ ## 隐私
236
+
237
+ DuoShe 默认本地优先。公共记忆是 Markdown,是否进 git 由你决定。`index.db`、`CANDIDATES/`、`SESSIONS/` 这些通常不建议提交(`duoshe init` 会自动加入 `.gitignore`)。
238
+
239
+ ---
240
+
241
+ ## 开发
242
+
243
+ ```bash
244
+ npm install
245
+ npm run lint
246
+ npm run typecheck
247
+ npm test
248
+ npm run build
249
+ ```
250
+
251
+ | 脚本 | 用途 |
252
+ |---|---|
253
+ | `npm run dev` | 通过 `tsx` 直接跑 TypeScript |
254
+ | `npm run build` | 编译到 `dist/`(含 skill 资源) |
255
+ | `npm test` | Vitest |
256
+ | `npm run lint` | Biome |
257
+ | `npm run prepublishOnly` | 发布前门禁:lint + typecheck + test + build |
258
+
259
+ 工程方案见 [DESIGN.md](./DESIGN.md)。
260
+
261
+ ---
262
+
263
+ ## 贡献
264
+
265
+ DuoShe 还很早期,欢迎 issue、讨论和小而清晰的 PR。
266
+
267
+ 提交 PR 前请先跑:
268
+
269
+ ```bash
270
+ npm run prepublishOnly
271
+ ```
272
+
273
+ 请尽量遵守这些约束:
274
+
275
+ - 不要让 AI 自动把内容晋升为长期记忆;
276
+ - 不要覆盖用户已有的 `CLAUDE.md` / `AGENTS.md` 内容;
277
+ - 保持 core 逻辑独立于 CLI 和未来 MCP adapter;
278
+ - 优先使用简单、本地、可检查的格式;
279
+ - 新增域专项能力优先考虑做成 skill,而不是塞进核心。
280
+
281
+ ---
282
+
283
+ ## License
284
+
285
+ MIT。见 [LICENSE](./LICENSE)。
@@ -0,0 +1,40 @@
1
+ export declare const BEGIN_MARK = "<!-- BEGIN DUOSHE -->";
2
+ export declare const END_MARK = "<!-- END DUOSHE -->";
3
+ export declare const SHELL_FILES: readonly ["CLAUDE.md", "AGENTS.md"];
4
+ export type ShellFile = (typeof SHELL_FILES)[number];
5
+ export type ShellAction = {
6
+ file: ShellFile;
7
+ status: "created";
8
+ path: string;
9
+ } | {
10
+ file: ShellFile;
11
+ status: "appended";
12
+ path: string;
13
+ } | {
14
+ file: ShellFile;
15
+ status: "updated";
16
+ path: string;
17
+ } | {
18
+ file: ShellFile;
19
+ status: "unchanged";
20
+ path: string;
21
+ } | {
22
+ file: ShellFile;
23
+ status: "skipped-no-existing";
24
+ path: string;
25
+ } | {
26
+ file: ShellFile;
27
+ status: "removed";
28
+ path: string;
29
+ };
30
+ export declare function buildShellBlock(): string;
31
+ export type SyncOptions = {
32
+ createIfMissing: boolean;
33
+ };
34
+ export declare function syncShells(projectRoot: string, opts: SyncOptions): ShellAction[];
35
+ export declare function uninstallShells(projectRoot: string): ShellAction[];
36
+ export declare function detectExistingShells(projectRoot: string): {
37
+ file: ShellFile;
38
+ exists: boolean;
39
+ }[];
40
+ //# sourceMappingURL=claude-md.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-md.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,0BAA0B,CAAC;AAClD,eAAO,MAAM,QAAQ,wBAAwB,CAAC;AAE9C,eAAO,MAAM,WAAW,qCAAsC,CAAC;AAC/D,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD,wBAAgB,eAAe,IAAI,MAAM,CAqCxC;AAUD,MAAM,MAAM,WAAW,GAAG;IACxB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAkCF,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,WAAW,EAAE,CAEhF;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAsBlE;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,EAAE,CAEhG"}