change-log-agent 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -41
- package/dist/index.mjs +43 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,89 +1,117 @@
|
|
|
1
|
-
#
|
|
1
|
+
# change-log-agent
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **Turn messy git commits into polished project documentation with a single command.**
|
|
4
4
|
|
|
5
|
-
`log-agent`
|
|
5
|
+
`change-log-agent` is a CLI tool built on an **agent-based workflow**. Rather than simply copying text, it drives your local **Claude Code** instance to transform raw git commit history into well-structured, human-readable documentation (README, CHANGELOG, etc.).
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Highlights
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
11
|
+
- **Zero API Cost** — Uses your existing Claude Pro/Team subscription. No extra API token charges.
|
|
12
|
+
- **Agent-Based Workflow** — Dynamically generates a Mission Spec and lets the AI decide how to best organize your documentation.
|
|
13
|
+
- **Surgical Precision** — Uses HTML comment markers (`<!-- log-agent-start -->` / `<!-- log-agent-end -->`) to scope changes. Only the marked section is modified; the rest of your file stays untouched.
|
|
14
|
+
- **Incremental Sync** — Automatically detects the last update date from the marked section, fetching only new commits to avoid redundant processing.
|
|
15
|
+
- **Context-Aware** — Filters out trivial commits (typos, formatting) and intelligently summarizes changes based on project context.
|
|
15
16
|
|
|
16
17
|
---
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
+
## How It Works
|
|
19
20
|
|
|
20
|
-
1.
|
|
21
|
-
2.
|
|
22
|
-
3.
|
|
23
|
-
4.
|
|
21
|
+
1. **Detect** — Scans the target file for marker tags and identifies the last sync date.
|
|
22
|
+
2. **Extract** — Fetches new commits from git history since the last sync.
|
|
23
|
+
3. **Plan** — Generates a Mission Spec describing how the AI should update the document.
|
|
24
|
+
4. **Execute** — Invokes `claude -p` to apply precise edits to the target file.
|
|
24
25
|
|
|
25
26
|
---
|
|
26
27
|
|
|
27
|
-
##
|
|
28
|
+
## Getting Started
|
|
28
29
|
|
|
29
|
-
###
|
|
30
|
+
### Prerequisites
|
|
30
31
|
|
|
31
|
-
-
|
|
32
|
-
-
|
|
32
|
+
- **Node.js** v18+
|
|
33
|
+
- **Claude Code** installed and authenticated:
|
|
33
34
|
|
|
34
35
|
```bash
|
|
35
36
|
npm install -g @anthropic-ai/claude-code
|
|
36
37
|
claude login
|
|
37
38
|
```
|
|
38
39
|
|
|
39
|
-
###
|
|
40
|
+
### Install
|
|
40
41
|
|
|
41
42
|
```bash
|
|
42
|
-
|
|
43
|
-
git clone https://github.com/your-username/log-agent.git
|
|
44
|
-
cd log-agent
|
|
45
|
-
|
|
46
|
-
# 安裝依賴
|
|
47
|
-
npm install
|
|
48
|
-
|
|
49
|
-
# 編譯
|
|
50
|
-
npm run build
|
|
43
|
+
npm install -g change-log-agent
|
|
51
44
|
```
|
|
52
45
|
|
|
53
|
-
###
|
|
46
|
+
### Prepare Your Target File
|
|
54
47
|
|
|
55
|
-
|
|
48
|
+
Add the following markers to your `README.md` or `CHANGELOG.md`:
|
|
56
49
|
|
|
57
50
|
```markdown
|
|
58
|
-
##
|
|
51
|
+
## Changelog
|
|
59
52
|
|
|
60
53
|
<!-- log-agent-start -->
|
|
61
54
|
<!-- log-agent-end -->
|
|
62
55
|
```
|
|
63
56
|
|
|
64
|
-
###
|
|
57
|
+
### Run
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Basic usage — auto-detects date, updates README.md
|
|
61
|
+
log-agent sync
|
|
62
|
+
|
|
63
|
+
# Specify a start date
|
|
64
|
+
log-agent sync --since 2026-02-01
|
|
65
|
+
|
|
66
|
+
# Target a different file
|
|
67
|
+
log-agent sync --target CHANGELOG.md
|
|
68
|
+
|
|
69
|
+
# Preview mode — prints Mission Spec without executing
|
|
70
|
+
log-agent sync --dry-run
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Or run without installing:
|
|
65
74
|
|
|
66
75
|
```bash
|
|
67
|
-
|
|
68
|
-
npx ts-node src/index.ts sync
|
|
76
|
+
npx change-log-agent sync
|
|
69
77
|
```
|
|
70
78
|
|
|
79
|
+
### CLI Options
|
|
80
|
+
|
|
81
|
+
| Option | Description | Default |
|
|
82
|
+
|--------|-------------|---------|
|
|
83
|
+
| `--since <date>` | Only include commits after this date | Auto-detected from markers |
|
|
84
|
+
| `--target <file>` | File to update | `README.md` |
|
|
85
|
+
| `--dry-run` | Preview the Mission Spec without executing | `false` |
|
|
86
|
+
|
|
71
87
|
---
|
|
72
88
|
|
|
73
|
-
##
|
|
89
|
+
## Project Structure
|
|
74
90
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
| File | Responsibility |
|
|
92
|
+
|------|----------------|
|
|
93
|
+
| `src/index.ts` | CLI entry point and orchestration |
|
|
94
|
+
| `src/core/git.ts` | Git commands and commit log extraction |
|
|
95
|
+
| `src/core/template.ts` | Mission Spec generation |
|
|
96
|
+
| `src/core/bridge.ts` | Claude Code bridge (`claude -p` invocation) |
|
|
97
|
+
| `src/core/marker.ts` | Marker detection and date extraction |
|
|
78
98
|
|
|
79
99
|
---
|
|
80
100
|
|
|
81
|
-
##
|
|
101
|
+
## Contributing
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git clone https://github.com/ericcai0814/change-log-agent.git
|
|
105
|
+
cd change-log-agent
|
|
106
|
+
npm install
|
|
107
|
+
npm run build
|
|
108
|
+
npm test
|
|
109
|
+
```
|
|
82
110
|
|
|
83
|
-
|
|
111
|
+
Issues and pull requests are welcome!
|
|
84
112
|
|
|
85
113
|
---
|
|
86
114
|
|
|
87
|
-
License
|
|
115
|
+
## License
|
|
88
116
|
|
|
89
|
-
MIT
|
|
117
|
+
MIT — see [LICENSE](LICENSE) for details.
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { execa } from "execa";
|
|
5
|
-
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import { createInterface } from "node:readline/promises";
|
|
7
|
+
import { stdin, stdout } from "node:process";
|
|
6
8
|
|
|
7
9
|
//#region src/core/git.ts
|
|
8
10
|
/**
|
|
@@ -101,19 +103,29 @@ async function checkMarkers(filePath) {
|
|
|
101
103
|
const lastDate = hasStart && hasEnd ? extractLastDate(content) : void 0;
|
|
102
104
|
return {
|
|
103
105
|
found: hasStart && hasEnd,
|
|
106
|
+
fileExists: true,
|
|
104
107
|
lastDate,
|
|
105
108
|
startTag: START_TAG,
|
|
106
109
|
endTag: END_TAG
|
|
107
110
|
};
|
|
108
|
-
} catch {
|
|
111
|
+
} catch (error) {
|
|
109
112
|
return {
|
|
110
113
|
found: false,
|
|
114
|
+
fileExists: !(error instanceof Error && "code" in error && error.code === "ENOENT"),
|
|
111
115
|
lastDate: void 0,
|
|
112
116
|
startTag: START_TAG,
|
|
113
117
|
endTag: END_TAG
|
|
114
118
|
};
|
|
115
119
|
}
|
|
116
120
|
}
|
|
121
|
+
const MARKER_TEMPLATE = `# Changelog
|
|
122
|
+
|
|
123
|
+
${START_TAG}
|
|
124
|
+
${END_TAG}
|
|
125
|
+
`;
|
|
126
|
+
async function createMarkerFile(filePath) {
|
|
127
|
+
await writeFile(filePath, MARKER_TEMPLATE, "utf-8");
|
|
128
|
+
}
|
|
117
129
|
function extractLastDate(content) {
|
|
118
130
|
const startIdx = content.indexOf(START_TAG);
|
|
119
131
|
const endIdx = content.indexOf(END_TAG);
|
|
@@ -121,16 +133,39 @@ function extractLastDate(content) {
|
|
|
121
133
|
return [...content.slice(startIdx, endIdx).matchAll(/###\s+(\d{4}-\d{2}-\d{2})/g)].map((m) => m[1]).filter((d) => d !== void 0).sort().at(-1);
|
|
122
134
|
}
|
|
123
135
|
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/utils/prompt.ts
|
|
138
|
+
async function confirmPrompt(message) {
|
|
139
|
+
const rl = createInterface({
|
|
140
|
+
input: stdin,
|
|
141
|
+
output: stdout
|
|
142
|
+
});
|
|
143
|
+
try {
|
|
144
|
+
const trimmed = (await rl.question(`${message} (Y/n) `)).trim().toLowerCase();
|
|
145
|
+
return trimmed === "" || trimmed === "y";
|
|
146
|
+
} finally {
|
|
147
|
+
rl.close();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
124
151
|
//#endregion
|
|
125
152
|
//#region src/index.ts
|
|
126
153
|
const program = new Command();
|
|
127
154
|
program.name("log-agent").description("AI-Powered Agentic Documentation CLI").version("0.1.0");
|
|
128
|
-
|
|
129
|
-
const { target: targetFile, since, dryRun } = options;
|
|
155
|
+
async function syncAction(options) {
|
|
156
|
+
const { target: targetFile, since, dryRun, yes: autoYes } = options;
|
|
130
157
|
try {
|
|
131
158
|
console.log(chalk.blue("Starting log-agent sync..."));
|
|
132
159
|
const markers = await checkMarkers(targetFile);
|
|
133
|
-
if (!dryRun && !markers.found) {
|
|
160
|
+
if (!dryRun && !markers.found) if (!markers.fileExists) {
|
|
161
|
+
if (!(autoYes || await confirmPrompt(`${targetFile} not found. Create it?`))) {
|
|
162
|
+
console.error(chalk.red("Aborted."));
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
await createMarkerFile(targetFile);
|
|
167
|
+
console.log(chalk.green(`Created ${targetFile} with markers.`));
|
|
168
|
+
} else {
|
|
134
169
|
console.error(chalk.red(`Markers not found in ${targetFile}.`));
|
|
135
170
|
console.error(chalk.gray(`Add these lines to your file:\n ${markers.startTag}\n ${markers.endTag}`));
|
|
136
171
|
process.exitCode = 1;
|
|
@@ -164,8 +199,9 @@ program.command("sync").description("Sync git log to documentation").option("--s
|
|
|
164
199
|
else console.error(chalk.red(`Sync failed: ${message}`));
|
|
165
200
|
process.exitCode = 1;
|
|
166
201
|
}
|
|
167
|
-
}
|
|
202
|
+
}
|
|
203
|
+
program.command("sync").description("Sync git log to documentation").option("--since <date>", "Only include commits after this date (e.g. 2026-02-01)").option("--target <file>", "Target file to update", "CHANGELOG.md").option("--dry-run", "Preview the mission spec without executing", false).option("--yes", "Skip interactive confirmation (for CI/CD)", false).action(syncAction);
|
|
168
204
|
program.parse();
|
|
169
205
|
|
|
170
206
|
//#endregion
|
|
171
|
-
export {
|
|
207
|
+
export { syncAction };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "change-log-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "AI-powered CLI that syncs git commit history to project documentation via Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/ericcai0814/log-agent.git"
|
|
30
|
+
"url": "git+https://github.com/ericcai0814/change-log-agent.git"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"chalk": "^5.6.2",
|