@xiaofandegeng/rmemo 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/CONTRIBUTING.md +28 -0
- package/DEVELOPMENT_PLAN.md +77 -0
- package/LICENSE +22 -0
- package/README.md +150 -0
- package/README.zh-CN.md +156 -0
- package/bin/rmemo.js +63 -0
- package/package.json +47 -0
- package/src/cmd/check.js +30 -0
- package/src/cmd/context.js +15 -0
- package/src/cmd/done.js +55 -0
- package/src/cmd/hook.js +108 -0
- package/src/cmd/init.js +86 -0
- package/src/cmd/log.js +12 -0
- package/src/cmd/print.js +15 -0
- package/src/cmd/scan.js +25 -0
- package/src/cmd/start.js +41 -0
- package/src/cmd/status.js +147 -0
- package/src/cmd/todo.js +85 -0
- package/src/core/check.js +396 -0
- package/src/core/context.js +114 -0
- package/src/core/journal.js +31 -0
- package/src/core/scan.js +282 -0
- package/src/core/todos.js +143 -0
- package/src/lib/args.js +81 -0
- package/src/lib/git.js +35 -0
- package/src/lib/io.js +43 -0
- package/src/lib/paths.js +38 -0
- package/src/lib/stdin.js +12 -0
- package/src/lib/time.js +13 -0
- package/src/lib/walk.js +44 -0
- package/test/smoke.test.js +395 -0
package/CHANGELOG.md
ADDED
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for contributing to `rmemo`.
|
|
4
|
+
|
|
5
|
+
## Dev Setup
|
|
6
|
+
|
|
7
|
+
Requirements:
|
|
8
|
+
- Node.js >= 18
|
|
9
|
+
|
|
10
|
+
Run tests:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm test
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## What To Work On
|
|
17
|
+
|
|
18
|
+
Good first contributions:
|
|
19
|
+
- Improve scan heuristics (monorepo/subprojects/api contracts) without hardcoding to one framework
|
|
20
|
+
- Improve `check` output formatting and fix hints
|
|
21
|
+
- Add more safe default rules/templates for common project types
|
|
22
|
+
|
|
23
|
+
## Pull Requests
|
|
24
|
+
|
|
25
|
+
- Keep changes focused and small.
|
|
26
|
+
- Add/adjust tests in `test/` when behavior changes.
|
|
27
|
+
- If you change CLI flags/commands, update both `README.md` and `README.zh-CN.md`.
|
|
28
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Development Plan
|
|
2
|
+
|
|
3
|
+
This plan is optimized for "daily use" and long-term maintainability. Each milestone should keep the tool usable.
|
|
4
|
+
|
|
5
|
+
## v0.1 (Shipped)
|
|
6
|
+
|
|
7
|
+
Done:
|
|
8
|
+
- CLI: `init`, `scan`, `log`, `context`, `print`
|
|
9
|
+
- Repo scan (git-aware) -> `.repo-memory/manifest.json` + `.repo-memory/index.json`
|
|
10
|
+
- Context Pack generator -> `.repo-memory/context.md`
|
|
11
|
+
|
|
12
|
+
## v0.2 (Make Memory More Useful) (Shipped)
|
|
13
|
+
|
|
14
|
+
Goals:
|
|
15
|
+
- Produce a better "project memory" without tying to any specific repo type.
|
|
16
|
+
- Reduce manual work to keep rules/todos/journal consistent.
|
|
17
|
+
|
|
18
|
+
Done:
|
|
19
|
+
- Add `rmemo status` (+ `--format md|json` + `--mode brief|full`):
|
|
20
|
+
- Summarize "Next / Blockers / Recent log" from `.repo-memory/*`
|
|
21
|
+
- Output should be pasteable to issues/PR descriptions
|
|
22
|
+
- Improve scan heuristics:
|
|
23
|
+
- Detect monorepo candidates (workspaces, pnpm, turborepo, packages/apps)
|
|
24
|
+
- Detect common app folders (web/admin/backend/miniapp/mp) as hints only
|
|
25
|
+
- Detect API contract files and doc roots (openapi/swagger/docs)
|
|
26
|
+
- Add `rmemo start` as a daily entrypoint (scan + context + status brief)
|
|
27
|
+
- Add todo helpers: `rmemo todo add|block|ls`
|
|
28
|
+
|
|
29
|
+
## v0.3 (Rules Become Enforceable) (Shipped)
|
|
30
|
+
|
|
31
|
+
Goals:
|
|
32
|
+
- Prevent "AI drift" by making key conventions executable.
|
|
33
|
+
|
|
34
|
+
Done:
|
|
35
|
+
- Add `.repo-memory/rules.json` (generated by `init`):
|
|
36
|
+
- Structure rules: required dirs/files, forbidden paths, naming regexes
|
|
37
|
+
- Add `rmemo check`:
|
|
38
|
+
- Validate repo against rules.json (no network)
|
|
39
|
+
- Exit code for CI usage
|
|
40
|
+
- Print actionable diff-like messages
|
|
41
|
+
- Add forbidden content scanning: `forbiddenContent`
|
|
42
|
+
- Add `--staged` mode (pre-commit optimized, reads staged content from git index)
|
|
43
|
+
- Add `rmemo hook install`:
|
|
44
|
+
- Install a pre-commit hook to run `rmemo check` (opt-in)
|
|
45
|
+
|
|
46
|
+
## v0.4 (Workflow: Start/Stop The Day) (Shipped)
|
|
47
|
+
|
|
48
|
+
Goals:
|
|
49
|
+
- Make the daily routine effortless.
|
|
50
|
+
|
|
51
|
+
Done:
|
|
52
|
+
- Add `rmemo done`:
|
|
53
|
+
- Promptless mode: take stdin to append to journal
|
|
54
|
+
- Optionally extract "next steps" into todos.md
|
|
55
|
+
- Unify journal format for `log/done`
|
|
56
|
+
- Add todo lifecycle: `rmemo todo done|unblock` (remove by index)
|
|
57
|
+
|
|
58
|
+
## v0.5 (Polish + Adoption) (In Progress)
|
|
59
|
+
|
|
60
|
+
Goals:
|
|
61
|
+
- Make it easy for others to adopt.
|
|
62
|
+
|
|
63
|
+
Tasks:
|
|
64
|
+
- Add packaging metadata:
|
|
65
|
+
- repository/homepage/bugs fields
|
|
66
|
+
- `files` allowlist for npm
|
|
67
|
+
- `npm pack --dry-run` in CI
|
|
68
|
+
- Prepare npm publishing (name might be taken; decide final package name)
|
|
69
|
+
- Add docs:
|
|
70
|
+
- "How I use this with Cursor/Claude/ChatGPT"
|
|
71
|
+
- Examples of rules.md templates for web + miniapp projects
|
|
72
|
+
- Add `CHANGELOG.md` + `CONTRIBUTING.md`
|
|
73
|
+
|
|
74
|
+
## v0.6 (Optional)
|
|
75
|
+
|
|
76
|
+
- `rmemo scan --format md|json` to print scan results to stdout
|
|
77
|
+
- `rmemo check` output improvements (grouping + fix hints)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
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.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# rmemo
|
|
2
|
+
|
|
3
|
+
Repo memory + dev journal CLI: scan any project, persist conventions/progress, and generate an AI-ready context pack.
|
|
4
|
+
|
|
5
|
+
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
|
6
|
+
|
|
7
|
+
Docs:
|
|
8
|
+
- [Usage (AI Workflow)](./docs/USAGE.md)
|
|
9
|
+
- [Releasing](./RELEASING.md)
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
When you resume work the next day, AI tools often:
|
|
14
|
+
- forget project-specific rules and structure
|
|
15
|
+
- re-invent decisions you already made
|
|
16
|
+
- drift away from established conventions
|
|
17
|
+
|
|
18
|
+
`rmemo` fixes this by storing the "repo memory" inside the repo and generating a single `Context Pack` you can paste into any AI.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
For now, run it directly with Node:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
node bin/rmemo.js init
|
|
26
|
+
node bin/rmemo.js log "Finished user list page; next: add search filters"
|
|
27
|
+
node bin/rmemo.js context
|
|
28
|
+
node bin/rmemo.js print
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Later you can publish to npm and install globally.
|
|
32
|
+
|
|
33
|
+
## Use On Any Repo
|
|
34
|
+
|
|
35
|
+
From the target repo root:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
node /path/to/rmemo/bin/rmemo.js init
|
|
39
|
+
node /path/to/rmemo/bin/rmemo.js log "Did X; next: Y"
|
|
40
|
+
node /path/to/rmemo/bin/rmemo.js context
|
|
41
|
+
node /path/to/rmemo/bin/rmemo.js print
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or without changing directories:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
node /path/to/rmemo/bin/rmemo.js --root /path/to/your-repo init
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Files It Creates
|
|
51
|
+
|
|
52
|
+
- `.repo-memory/manifest.json`: detected structure, tech stack hints, key files
|
|
53
|
+
- `.repo-memory/index.json`: file list for context generation
|
|
54
|
+
- `.repo-memory/rules.md`: your conventions and constraints (human-written)
|
|
55
|
+
- `.repo-memory/todos.md`: next steps and blockers (human-written)
|
|
56
|
+
- `.repo-memory/journal/YYYY-MM-DD.md`: daily progress log (human-written)
|
|
57
|
+
- `.repo-memory/context.md`: generated AI-ready context pack (generated)
|
|
58
|
+
|
|
59
|
+
## Commands
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
rmemo init
|
|
63
|
+
rmemo scan
|
|
64
|
+
rmemo log <text>
|
|
65
|
+
rmemo context
|
|
66
|
+
rmemo print
|
|
67
|
+
rmemo status
|
|
68
|
+
rmemo check
|
|
69
|
+
rmemo hook install
|
|
70
|
+
rmemo start
|
|
71
|
+
rmemo done
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Enforcing Rules (CI / Hooks)
|
|
75
|
+
|
|
76
|
+
`rmemo` supports executable repo rules in `.repo-memory/rules.json`.
|
|
77
|
+
|
|
78
|
+
Example:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"schema": 1,
|
|
83
|
+
"requiredPaths": ["README.md"],
|
|
84
|
+
"forbiddenPaths": [".env", ".env.*"],
|
|
85
|
+
"forbiddenContent": [
|
|
86
|
+
{
|
|
87
|
+
"include": ["**/*"],
|
|
88
|
+
"exclude": ["**/*.png", "**/*.jpg", "**/*.zip"],
|
|
89
|
+
"match": "BEGIN PRIVATE KEY",
|
|
90
|
+
"message": "Do not commit private keys."
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"namingRules": [
|
|
94
|
+
{
|
|
95
|
+
"include": ["src/pages/**"],
|
|
96
|
+
"target": "basename",
|
|
97
|
+
"match": "^[a-z0-9-]+\\.vue$",
|
|
98
|
+
"message": "Page filenames must be kebab-case."
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Run:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
rmemo check
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Pre-commit usage (faster, checks only staged files):
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
rmemo check --staged
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Install a pre-commit hook (runs `rmemo check` before commit):
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
rmemo hook install
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Start-of-day entrypoint (scan + generate context + print status):
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
rmemo start
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
End-of-day note (append to journal; supports stdin):
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
rmemo done "Finished X; decided Y"
|
|
132
|
+
echo "Finished X; decided Y" | rmemo done
|
|
133
|
+
rmemo done --next "Tomorrow: implement Z" --blocker "Waiting for API spec" "Summary: ..."
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Todo helpers:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
rmemo todo add "Implement user search"
|
|
140
|
+
rmemo todo block "Backend API missing"
|
|
141
|
+
rmemo todo ls
|
|
142
|
+
rmemo todo done 1
|
|
143
|
+
rmemo todo unblock 1
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Roadmap (short)
|
|
147
|
+
|
|
148
|
+
- v0.2: better heuristics for monorepos, miniapp projects, and API contracts
|
|
149
|
+
- v0.3: `rmemo check` to enforce structure/rules (CI + git hook)
|
|
150
|
+
- v0.4: VS Code extension (quick log + generate/print context)
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# rmemo
|
|
2
|
+
|
|
3
|
+
面向任何代码仓库的“项目记忆 + 开发日志”CLI:自动扫描项目结构,沉淀约定/进度,一键生成可直接粘贴给 AI 的 Context Pack。
|
|
4
|
+
|
|
5
|
+
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
|
6
|
+
|
|
7
|
+
文档:
|
|
8
|
+
- [使用方式(配合 AI 开发)](./docs/USAGE.zh-CN.md)
|
|
9
|
+
- [发布说明](./RELEASING.md)
|
|
10
|
+
|
|
11
|
+
## 为什么需要它
|
|
12
|
+
|
|
13
|
+
隔天继续开发时,AI 工具经常会:
|
|
14
|
+
- 忘记项目结构和约定(目录边界、命名、规范)
|
|
15
|
+
- 重复做你已经做过的决策
|
|
16
|
+
- 逐渐偏离仓库里既有的模式(AI drift)
|
|
17
|
+
|
|
18
|
+
`rmemo` 的思路是把“项目记忆”放回仓库本身:把规则、进度、下一步、结构索引固化为文件,然后生成一个统一的 `Context Pack`,你可以把它喂给任何 AI(不绑定某一个模型/产品)。
|
|
19
|
+
|
|
20
|
+
## 安装 / 运行
|
|
21
|
+
|
|
22
|
+
目前是零依赖 Node 直接运行:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
node bin/rmemo.js init
|
|
26
|
+
node bin/rmemo.js log "完成用户列表页;下一步:加筛选条件"
|
|
27
|
+
node bin/rmemo.js context
|
|
28
|
+
node bin/rmemo.js print
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
后续可以发布到 npm,再全局安装。
|
|
32
|
+
|
|
33
|
+
## 用在任意项目
|
|
34
|
+
|
|
35
|
+
在目标项目根目录执行:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
node /path/to/rmemo/bin/rmemo.js init
|
|
39
|
+
node /path/to/rmemo/bin/rmemo.js log "做了 X;下一步 Y"
|
|
40
|
+
node /path/to/rmemo/bin/rmemo.js context
|
|
41
|
+
node /path/to/rmemo/bin/rmemo.js print
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
或者不切目录,直接指定仓库根路径:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
node /path/to/rmemo/bin/rmemo.js --root /path/to/your-repo init
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 它会创建哪些文件
|
|
51
|
+
|
|
52
|
+
- `.repo-memory/manifest.json`:检测到的结构信息、技术栈提示、关键文件
|
|
53
|
+
- `.repo-memory/index.json`:文件索引(用于生成 context)
|
|
54
|
+
- `.repo-memory/rules.md`:你的规则/约定(手写)
|
|
55
|
+
- `.repo-memory/rules.json`:可执行规则(用于 `check`)
|
|
56
|
+
- `.repo-memory/todos.md`:下一步与阻塞(手写/命令追加)
|
|
57
|
+
- `.repo-memory/journal/YYYY-MM-DD.md`:按天顺序记录进度(手写/命令追加)
|
|
58
|
+
- `.repo-memory/context.md`:生成的 AI 上下文包(生成文件)
|
|
59
|
+
|
|
60
|
+
## 命令
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
rmemo init
|
|
64
|
+
rmemo scan
|
|
65
|
+
rmemo log <text>
|
|
66
|
+
rmemo status
|
|
67
|
+
rmemo check
|
|
68
|
+
rmemo hook install
|
|
69
|
+
rmemo start
|
|
70
|
+
rmemo done
|
|
71
|
+
rmemo todo add <text>
|
|
72
|
+
rmemo todo block <text>
|
|
73
|
+
rmemo todo ls
|
|
74
|
+
rmemo context
|
|
75
|
+
rmemo print
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 可执行规则(CI / Hooks)
|
|
79
|
+
|
|
80
|
+
`rmemo` 支持在 `.repo-memory/rules.json` 里写规则,并用 `rmemo check` 在本地或 CI 执行。
|
|
81
|
+
|
|
82
|
+
示例:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"schema": 1,
|
|
87
|
+
"requiredPaths": ["README.md"],
|
|
88
|
+
"forbiddenPaths": [".env", ".env.*"],
|
|
89
|
+
"forbiddenContent": [
|
|
90
|
+
{
|
|
91
|
+
"include": ["**/*"],
|
|
92
|
+
"exclude": ["**/*.png", "**/*.jpg", "**/*.zip"],
|
|
93
|
+
"match": "BEGIN PRIVATE KEY",
|
|
94
|
+
"message": "禁止提交私钥内容。"
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"namingRules": [
|
|
98
|
+
{
|
|
99
|
+
"include": ["src/pages/**"],
|
|
100
|
+
"target": "basename",
|
|
101
|
+
"match": "^[a-z0-9-]+\\.vue$",
|
|
102
|
+
"message": "页面文件名必须是 kebab-case。"
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
执行检查:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
rmemo check
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Pre-commit 使用(更快,只检查暂存区文件):
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
rmemo check --staged
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
安装 git pre-commit hook(提交前自动执行 `rmemo check`):
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
rmemo hook install
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 日常工作流(推荐)
|
|
127
|
+
|
|
128
|
+
开工(扫描结构 + 生成 context + 打印 status,方便你粘贴给 AI):
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
rmemo start
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
收工(写入当天 journal;可选同时更新 Next/Blockers):
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
rmemo done "今天完成了什么/做了什么决策"
|
|
138
|
+
echo "今天总结..." | rmemo done
|
|
139
|
+
rmemo done --next "明天第一步做什么" --blocker "当前阻塞是什么" "今天总结..."
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
手动维护下一步/阻塞(不想打开文件改):
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
rmemo todo add "实现用户搜索"
|
|
146
|
+
rmemo todo block "后端接口还没出"
|
|
147
|
+
rmemo todo ls
|
|
148
|
+
rmemo todo done 1
|
|
149
|
+
rmemo todo unblock 1
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Roadmap(简版)
|
|
153
|
+
|
|
154
|
+
- v0.2:增强通用扫描(monorepo/子项目/API 契约/文档根目录)
|
|
155
|
+
- v0.3:规则能力增强 + 更好的 `check` 输出 + hooks/CI 体验打磨
|
|
156
|
+
- v0.4:VS Code 扩展(快速 log/start/done)
|
package/bin/rmemo.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { cmdInit } from "../src/cmd/init.js";
|
|
3
|
+
import { cmdScan } from "../src/cmd/scan.js";
|
|
4
|
+
import { cmdLog } from "../src/cmd/log.js";
|
|
5
|
+
import { cmdContext } from "../src/cmd/context.js";
|
|
6
|
+
import { cmdPrint } from "../src/cmd/print.js";
|
|
7
|
+
import { cmdStatus } from "../src/cmd/status.js";
|
|
8
|
+
import { cmdCheck } from "../src/cmd/check.js";
|
|
9
|
+
import { cmdHook } from "../src/cmd/hook.js";
|
|
10
|
+
import { cmdStart } from "../src/cmd/start.js";
|
|
11
|
+
import { cmdDone } from "../src/cmd/done.js";
|
|
12
|
+
import { cmdTodo } from "../src/cmd/todo.js";
|
|
13
|
+
import { parseArgs, printHelp } from "../src/lib/args.js";
|
|
14
|
+
import { exitWithError } from "../src/lib/io.js";
|
|
15
|
+
|
|
16
|
+
const argv = process.argv.slice(2);
|
|
17
|
+
const { cmd, rest, flags } = parseArgs(argv);
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
switch (cmd) {
|
|
21
|
+
case "init":
|
|
22
|
+
await cmdInit({ flags });
|
|
23
|
+
break;
|
|
24
|
+
case "scan":
|
|
25
|
+
await cmdScan({ flags });
|
|
26
|
+
break;
|
|
27
|
+
case "log":
|
|
28
|
+
await cmdLog({ rest, flags });
|
|
29
|
+
break;
|
|
30
|
+
case "context":
|
|
31
|
+
await cmdContext({ flags });
|
|
32
|
+
break;
|
|
33
|
+
case "print":
|
|
34
|
+
await cmdPrint({ flags });
|
|
35
|
+
break;
|
|
36
|
+
case "status":
|
|
37
|
+
await cmdStatus({ flags });
|
|
38
|
+
break;
|
|
39
|
+
case "check":
|
|
40
|
+
await cmdCheck({ flags });
|
|
41
|
+
break;
|
|
42
|
+
case "hook":
|
|
43
|
+
await cmdHook({ rest, flags });
|
|
44
|
+
break;
|
|
45
|
+
case "start":
|
|
46
|
+
await cmdStart({ flags });
|
|
47
|
+
break;
|
|
48
|
+
case "done":
|
|
49
|
+
await cmdDone({ rest, flags });
|
|
50
|
+
break;
|
|
51
|
+
case "todo":
|
|
52
|
+
await cmdTodo({ rest, flags });
|
|
53
|
+
break;
|
|
54
|
+
case "help":
|
|
55
|
+
case undefined:
|
|
56
|
+
printHelp();
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
exitWithError(`Unknown command: ${cmd}\n\nRun: rmemo help`);
|
|
60
|
+
}
|
|
61
|
+
} catch (err) {
|
|
62
|
+
exitWithError(err?.stack || err?.message || String(err));
|
|
63
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xiaofandegeng/rmemo",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Repo memory + dev journal CLI: scan any project, persist conventions/progress, and generate an AI-ready context pack.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"rmemo": "bin/rmemo.js"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+ssh://git@github.com/xiaofandegeng/rmemo.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/xiaofandegeng/rmemo/issues"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/xiaofandegeng/rmemo#readme",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "node --test",
|
|
23
|
+
"pack:dry": "npm_config_cache=.npm-cache npm pack --dry-run"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"bin/",
|
|
27
|
+
"src/",
|
|
28
|
+
"test/",
|
|
29
|
+
"README.md",
|
|
30
|
+
"README.zh-CN.md",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"DEVELOPMENT_PLAN.md",
|
|
33
|
+
"CHANGELOG.md",
|
|
34
|
+
"CONTRIBUTING.md"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"ai",
|
|
41
|
+
"developer-tools",
|
|
42
|
+
"cli",
|
|
43
|
+
"context",
|
|
44
|
+
"journal",
|
|
45
|
+
"knowledge-base"
|
|
46
|
+
]
|
|
47
|
+
}
|
package/src/cmd/check.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { resolveRoot } from "../lib/paths.js";
|
|
2
|
+
import { runCheck } from "../core/check.js";
|
|
3
|
+
|
|
4
|
+
export async function cmdCheck({ flags }) {
|
|
5
|
+
const root = resolveRoot(flags);
|
|
6
|
+
const maxFiles = Number(flags["max-files"] || 4000);
|
|
7
|
+
const preferGit = flags["no-git"] ? false : true;
|
|
8
|
+
const stagedOnly = !!flags.staged;
|
|
9
|
+
|
|
10
|
+
const res = await runCheck(root, { maxFiles, preferGit, stagedOnly });
|
|
11
|
+
|
|
12
|
+
for (const e of res.errors) {
|
|
13
|
+
process.stderr.write(`ERROR: ${e}\n`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (res.violations.length) {
|
|
17
|
+
for (const v of res.violations.slice(0, 200)) {
|
|
18
|
+
process.stderr.write(`VIOLATION: ${v.message}\n`);
|
|
19
|
+
}
|
|
20
|
+
if (res.violations.length > 200) process.stderr.write(`...and ${res.violations.length - 200} more\n`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (res.ok) {
|
|
24
|
+
process.stdout.write("OK: rules check passed\n");
|
|
25
|
+
} else if (!res.errors.length && res.violations.length) {
|
|
26
|
+
process.stderr.write(`FAIL: ${res.violations.length} violation(s)\n`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
process.exitCode = res.exitCode;
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { resolveRoot } from "../lib/paths.js";
|
|
4
|
+
import { generateContext } from "../core/context.js";
|
|
5
|
+
import { contextPath } from "../lib/paths.js";
|
|
6
|
+
|
|
7
|
+
export async function cmdContext({ flags }) {
|
|
8
|
+
const root = resolveRoot(flags);
|
|
9
|
+
const snipLines = Number(flags["snip-lines"] || 120);
|
|
10
|
+
const recentDays = Number(flags["recent-days"] || 7);
|
|
11
|
+
const s = await generateContext(root, { snipLines, recentDays });
|
|
12
|
+
await fs.writeFile(contextPath(root), s, "utf8");
|
|
13
|
+
process.stdout.write(`Wrote: ${path.relative(process.cwd(), contextPath(root))}\n`);
|
|
14
|
+
}
|
|
15
|
+
|
package/src/cmd/done.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { resolveRoot } from "../lib/paths.js";
|
|
3
|
+
import { readStdinText } from "../lib/stdin.js";
|
|
4
|
+
import { appendJournalEntry } from "../core/journal.js";
|
|
5
|
+
import { addTodoBlocker, addTodoNext } from "../core/todos.js";
|
|
6
|
+
|
|
7
|
+
function normalizeNote(s) {
|
|
8
|
+
const t = String(s || "").trim();
|
|
9
|
+
if (!t) return "";
|
|
10
|
+
// Collapse consecutive blank lines.
|
|
11
|
+
return t.replace(/\n{3,}/g, "\n\n").trim();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function appendJournal(root, text) {
|
|
15
|
+
return await appendJournalEntry(root, { kind: "Done", text });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function maybeAppendNext(root, nextText) {
|
|
19
|
+
if (!nextText) return null;
|
|
20
|
+
const p = await addTodoNext(root, nextText);
|
|
21
|
+
return p;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function cmdDone({ rest, flags }) {
|
|
25
|
+
const root = resolveRoot(flags);
|
|
26
|
+
|
|
27
|
+
const next = flags.next ? String(flags.next).trim() : "";
|
|
28
|
+
const blocker = flags.blocker ? String(flags.blocker).trim() : "";
|
|
29
|
+
const argText = normalizeNote(rest.join(" "));
|
|
30
|
+
const stdinText = argText ? "" : normalizeNote(await readStdinText());
|
|
31
|
+
|
|
32
|
+
const text = argText || stdinText;
|
|
33
|
+
if (!text) {
|
|
34
|
+
process.stderr.write(
|
|
35
|
+
[
|
|
36
|
+
"Missing note text.",
|
|
37
|
+
"Usage:",
|
|
38
|
+
" rmemo done \"today summary\"",
|
|
39
|
+
" echo \"today summary\" | rmemo done",
|
|
40
|
+
"Options:",
|
|
41
|
+
" --next \"tomorrow's next step\""
|
|
42
|
+
].join("\n") + "\n"
|
|
43
|
+
);
|
|
44
|
+
process.exitCode = 2;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const jp = await appendJournal(root, text);
|
|
49
|
+
const tp = await maybeAppendNext(root, next);
|
|
50
|
+
const bp = blocker ? await addTodoBlocker(root, blocker) : null;
|
|
51
|
+
|
|
52
|
+
process.stdout.write(`Wrote journal: ${path.relative(process.cwd(), jp)}\n`);
|
|
53
|
+
if (tp) process.stdout.write(`Updated todos: ${path.relative(process.cwd(), tp)}\n`);
|
|
54
|
+
if (bp && bp !== tp) process.stdout.write(`Updated todos: ${path.relative(process.cwd(), bp)}\n`);
|
|
55
|
+
}
|