ai-cli-log 1.0.5 → 1.0.9
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 +50 -85
- package/dist/index.js +46 -30
- package/package.json +3 -1
- package/src/index.ts +48 -38
- package/.ai-cli-log/0001.txt +0 -360
- package/.ai-cli-log/0002.txt +0 -1791
- package/.ai-cli-log/0003.txt +0 -338
- package/.ai-cli-log/0004.txt +0 -116
- package/.ai-cli-log/0005.txt +0 -105
- package/.ai-cli-log/config.json +0 -32
- package/.ai-cli-log/gemini-2025-07-13T13-33-13-a-quick-gemini-test.txt +0 -174
- package/.ai-cli-log/gemini-2025-07-13T13-37-00-typescript-check-pass.txt +0 -105
- package/.ai-cli-log/gemini-2025-07-13T13-44-15-rename-ai-cli-logs-to-log.txt +0 -164
- package/.ai-cli-log/gemini-20250705-154601.txt +0 -1320
- package/.ai-cli-log/gemini-20250705-155547.txt +0 -726
- package/.ai-cli-log/gemini-20250705-165038.txt +0 -66
- package/.ai-cli-log/gemini-20250705-171429.txt +0 -216
- package/.ai-cli-log/gemini-20250705-191202.txt +0 -448
- package/.ai-cli-log/gemini-20250705-193741.txt +0 -901
- package/.ai-cli-log/gemini-20250705-194435.txt +0 -110
- package/.ai-cli-log/gemini-20250705-195926.txt +0 -415
- package/.ai-cli-log/gemini-20250705-201738.txt +0 -246
- package/.ai-cli-log/gemini-20250713-204921.txt +0 -3036
- package/.ai-cli-log/gemini-20250713-215941-update-ai-cli-log-documentation.txt +0 -400
- package/.ai-cli-log/gemini-20250713-220544-removed-debug-logs-successfully.txt +0 -258
- package/.ai-cli-log/gemini-20250713-221128-sessionsummarytxt.txt +0 -112
- package/.ai-cli-log/gemini-20250714-084659.txt +0 -86
- package/.ai-cli-log/gemini-20250714-085847-update-prompt-configuration.txt +0 -189
- package/.ai-cli-log/gemini-20250714-090905-add-sgpt-custom-summarizer.txt +0 -284
- package/.ai-cli-log/gemini-20250714-092329.txt +0 -110
- package/.ai-cli-log/gemini-20250714-092935.txt +0 -183
- package/.ai-cli-log/gemini-20250714-093205-heres-a-concise-summary-of-the-terminal-session-fix-sgpt-option-error-this-captures-1-the-action-fix-2-the-tool-involved-sgpt-3-the-issue-option-error-4-follows-the-requested-lowercase-hyphenated-format.txt +0 -140
- package/.ai-cli-log/gemini-20250714-094141-heres-the-concise-summary-build-check-clean-this-captures-1.txt +0 -111
- package/.ai-cli-log/gemini-20250714-094405-heres-the-concise-summary-clean-build-check-this-captures-1.txt +0 -111
- package/.ai-cli-log/gemini-20250714-094816-json-summary-format.txt +0 -132
- package/.ai-cli-log/gemini-20250714-094833-optimize-summary-logic.txt +0 -342
- package/.ai-cli-log/gemini-20250714-133202-refactor-config-initialization.txt +0 -1729
- package/.ai-cli-log/gemini-20250714-134138-update-summary-logic.txt +0 -153
- package/.ai-cli-log/gemini-20250714-134749-json-summary-format.txt +0 -214
- package/.ai-cli-log/gemini-20250714-140527.txt +0 -715
- package/.ai-cli-log/gemini-20250714-142018.txt +0 -86
- package/.ai-cli-log/gemini-20250714-142027-update-summary-format.txt +0 -86
- package/.ai-cli-log/gemini-20250714-142100-session-complete.txt +0 -86
- package/.ai-cli-log/gemini-20250714-142129-refactor-readme-structure.txt +0 -584
- package/.ai-cli-log/gemini-20250714-213153.txt +0 -1195
- package/.ai-cli-log/session-20250705-150655.txt +0 -174
- package/.ai-cli-log/session-20250705-151726.txt +0 -313
- package/.github/workflows/node.js.yml +0 -30
- package/GEMINI.md +0 -54
package/README.md
CHANGED
|
@@ -10,27 +10,33 @@ npm install -g ai-cli-log
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
Wrap any command with `ai-cli-log` to start a logging session.
|
|
13
|
+
Wrap any command with `ai-cli-log` to start a logging session. The core structure is:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
ai-cli-log <command> [args...]
|
|
16
|
+
ai-cli-log [global-options] run <command-to-log> [args...]
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
**Examples:**
|
|
20
20
|
|
|
21
21
|
- **Basic Logging:** Record a session with Google's Gemini CLI.
|
|
22
22
|
```bash
|
|
23
|
-
ai-cli-log gemini
|
|
23
|
+
ai-cli-log run gemini
|
|
24
24
|
```
|
|
25
25
|
*Logs are saved to the `.ai-cli-log/` directory.*
|
|
26
26
|
|
|
27
|
-
- **AI-Powered Filenames:** Use an AI summary for the log's filename.
|
|
27
|
+
- **AI-Powered Filenames:** Use an AI summary for the log's filename. The options must come **before** the `run` command.
|
|
28
28
|
```bash
|
|
29
|
-
|
|
29
|
+
# Enable summary with the default summarizer
|
|
30
|
+
ai-cli-log -s run gemini
|
|
30
31
|
# or
|
|
31
|
-
ai-cli-log --with-summary
|
|
32
|
+
ai-cli-log --with-summary run gemini
|
|
33
|
+
|
|
34
|
+
# Enable summary and specify a summarizer
|
|
35
|
+
ai-cli-log --by gemini-pro run gemini
|
|
36
|
+
# or
|
|
37
|
+
ai-cli-log --summarizer gemini-pro run gemini
|
|
32
38
|
```
|
|
33
|
-
This will use your default summarizer to generate a descriptive filename like `gemini-20250713-153000-fix-database-connection-error.
|
|
39
|
+
This will use your default (or specified) summarizer to generate a descriptive filename like `gemini-20250713-153000-fix-database-connection-error.txt`.
|
|
34
40
|
|
|
35
41
|
## Configuration
|
|
36
42
|
|
|
@@ -42,19 +48,19 @@ ai-cli-log <command> [args...]
|
|
|
42
48
|
|
|
43
49
|
You can create these files manually or by using the interactive setup command.
|
|
44
50
|
|
|
45
|
-
### Interactive Setup (
|
|
51
|
+
### Interactive Setup (`init`)
|
|
46
52
|
|
|
47
|
-
The
|
|
53
|
+
The `init` command helps you create a configuration file. It will scan for available AI tools, guide you through creating summarizer profiles, and set a default.
|
|
48
54
|
|
|
49
55
|
* **To create a global configuration:**
|
|
50
56
|
```bash
|
|
51
|
-
ai-cli-log
|
|
57
|
+
ai-cli-log init
|
|
52
58
|
```
|
|
53
59
|
This saves the configuration to `~/.config/ai-cli-log/config.json`.
|
|
54
60
|
|
|
55
61
|
* **To create a local (project-specific) configuration:**
|
|
56
62
|
```bash
|
|
57
|
-
ai-cli-log
|
|
63
|
+
ai-cli-log init --local
|
|
58
64
|
```
|
|
59
65
|
This saves the configuration to `.ai-cli-log/config.json` in the current directory.
|
|
60
66
|
|
|
@@ -83,23 +89,14 @@ Here is an example of a manual `config.json`:
|
|
|
83
89
|
{
|
|
84
90
|
"name": "sgpt",
|
|
85
91
|
"tool": "custom",
|
|
86
|
-
"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
* **To create a local, project-specific configuration file (at `.ai-cli-log/config.json`):**
|
|
95
|
-
```bash
|
|
96
|
-
ai-cli-log --init --local
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
This command will:
|
|
100
|
-
1. Scan for available AI tools on your system (like `gemini`, `sgpt`, or `ollama`).
|
|
101
|
-
2. Guide you through creating summarizer profiles for them.
|
|
102
|
-
3. Set a default summarizer.
|
|
92
|
+
"prompt": "You are a log summarizer. Your response MUST be a valid JSON object with one key: \"summary\" (a 3-5 word, lowercase, filename-friendly phrase). Example: {\"summary\": \"refactor-database-schema\"}. The session content is:",
|
|
93
|
+
"command": ["sgpt", "--chat", "session-summary", "\"{{prompt}}\""],
|
|
94
|
+
"maxLines": 50
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
103
100
|
|
|
104
101
|
## Features
|
|
105
102
|
|
|
@@ -108,7 +105,7 @@ This command will:
|
|
|
108
105
|
* **Accurate Rendering:** Uses `@xterm/headless` to interpret ANSI escape codes, ensuring the log accurately reflects the final terminal state (spinners, progress bars, etc.).
|
|
109
106
|
* **Configurable:** Supports different AI backends (`gemini`, `sgpt`, `ollama`, etc.) for generating summaries.
|
|
110
107
|
* **Performance-Aware:** When summarizing long sessions, it intelligently samples the beginning and end of the output to ensure fast and cost-effective summary generation.
|
|
111
|
-
* **
|
|
108
|
+
* **Plain Text Output:** Saves sessions as clean plain text files.
|
|
112
109
|
|
|
113
110
|
## Development Notes
|
|
114
111
|
|
|
@@ -118,7 +115,6 @@ Special thanks to Gemini for its invaluable help in the development of this tool
|
|
|
118
115
|
|
|
119
116
|
## TODO
|
|
120
117
|
|
|
121
|
-
* **Argument Parsing:** Refactor the manual argument parsing to use a robust library like `yargs` or `commander` to improve maintainability and provide standard features like `--help`.
|
|
122
118
|
* **Markdown Support:** Investigate and potentially implement saving logs in Markdown format, which could include session metadata (e.g., command, timestamp, summary) in a frontmatter block.
|
|
123
119
|
|
|
124
120
|
---
|
|
@@ -135,27 +131,33 @@ npm install -g ai-cli-log
|
|
|
135
131
|
|
|
136
132
|
## 使用方法
|
|
137
133
|
|
|
138
|
-
使用 `ai-cli-log`
|
|
134
|
+
使用 `ai-cli-log` 命令来包装任何您想记录的命令。核心结构是:
|
|
139
135
|
|
|
140
136
|
```bash
|
|
141
|
-
ai-cli-log
|
|
137
|
+
ai-cli-log [全局选项] run <要记录的命令> [参数...]
|
|
142
138
|
```
|
|
143
139
|
|
|
144
140
|
**示例:**
|
|
145
141
|
|
|
146
142
|
- **基本日志记录:** 记录与 Google Gemini CLI 的会话。
|
|
147
143
|
```bash
|
|
148
|
-
ai-cli-log gemini
|
|
144
|
+
ai-cli-log run gemini
|
|
149
145
|
```
|
|
150
146
|
*日志将保存到 `.ai-cli-log/` 目录中。*
|
|
151
147
|
|
|
152
|
-
- **AI 驱动的文件名:** 使用 AI
|
|
148
|
+
- **AI 驱动的文件名:** 使用 AI 摘要作为日志文件名。选项必须在 `run` 命令**之前**。
|
|
153
149
|
```bash
|
|
154
|
-
|
|
150
|
+
# 使用默认摘要器启用摘要
|
|
151
|
+
ai-cli-log -s run gemini
|
|
155
152
|
# 或
|
|
156
|
-
ai-cli-log --with-summary
|
|
153
|
+
ai-cli-log --with-summary run gemini
|
|
154
|
+
|
|
155
|
+
# 启用摘要并指定一个摘要器
|
|
156
|
+
ai-cli-log --by gemini-pro run gemini
|
|
157
|
+
# 或
|
|
158
|
+
ai-cli-log --summarizer gemini-pro run gemini
|
|
157
159
|
```
|
|
158
|
-
|
|
160
|
+
这将使用您默认(或指定)的摘要器生成一个描述性的文件名,例如 `gemini-20250713-153000-fix-database-connection-error.txt`。
|
|
159
161
|
|
|
160
162
|
## 配置
|
|
161
163
|
|
|
@@ -167,19 +169,19 @@ ai-cli-log <command> [args...]
|
|
|
167
169
|
|
|
168
170
|
您可以通过手动或使用交互式设置命令来创建这些文件。
|
|
169
171
|
|
|
170
|
-
### 交互式设置 (
|
|
172
|
+
### 交互式设置 (`init`)
|
|
171
173
|
|
|
172
|
-
|
|
174
|
+
`init` 命令可以帮助您创建配置文件。它会扫描可用的 AI 工具,引导您完成摘要器配置的创建,并设置一个默认值。
|
|
173
175
|
|
|
174
176
|
* **创建全局配置文件:**
|
|
175
177
|
```bash
|
|
176
|
-
ai-cli-log
|
|
178
|
+
ai-cli-log init
|
|
177
179
|
```
|
|
178
180
|
这会将配置保存到 `~/.config/ai-cli-log/config.json`。
|
|
179
181
|
|
|
180
182
|
* **创建本地(项目特定)配置文件:**
|
|
181
183
|
```bash
|
|
182
|
-
ai-cli-log
|
|
184
|
+
ai-cli-log init --local
|
|
183
185
|
```
|
|
184
186
|
这会将配置保存到当前目录的 `.ai-cli-log/config.json` 中。
|
|
185
187
|
|
|
@@ -195,22 +197,22 @@ ai-cli-log <command> [args...]
|
|
|
195
197
|
{
|
|
196
198
|
"name": "gemini-pro",
|
|
197
199
|
"tool": "gemini",
|
|
198
|
-
"prompt": "你是一个日志摘要器。你的响应必须是一个有效的 JSON
|
|
200
|
+
"prompt": "你是一个日志摘要器。你的响应必须是一个有效的 JSON 对象,其中包含一个键:\"summary\"(一个 3-5 个单词的、小写的、文件名友好的短语)。示例:{\"summary\": \"refactor-database-schema\"}。会话内容是:",
|
|
199
201
|
"maxLines": 100
|
|
200
202
|
},
|
|
201
203
|
{
|
|
202
204
|
"name": "ollama",
|
|
203
205
|
"tool": "ollama",
|
|
204
206
|
"model": "llama3",
|
|
205
|
-
"prompt": "你是一个日志摘要器。你的响应必须是一个有效的 JSON
|
|
207
|
+
"prompt": "你是一个日志摘要器。你的响应必须是一个有效的 JSON 对象,其中包含一个键:\"summary\"(一个 3-5 个单词的、小写的、文件名友好的短语)。示例:{\"summary\": \"refactor-database-schema\"}。会话内容是:",
|
|
206
208
|
"maxLines": 50
|
|
207
209
|
},
|
|
208
210
|
{
|
|
209
211
|
"name": "sgpt",
|
|
210
212
|
"tool": "custom",
|
|
211
|
-
"command": ["sgpt", "--chat", "session-summary", ""{{prompt}}""],
|
|
212
|
-
"prompt": "你是一个日志摘要器。你的响应必须是一个有效的 JSON
|
|
213
|
-
"maxLines":
|
|
213
|
+
"command": ["sgpt", "--chat", "session-summary", "\"{{prompt}}\""],
|
|
214
|
+
"prompt": "你是一个日志摘要器。你的响应必须是一个有效的 JSON 对象,其中包含一个键\"summary\"(一个 3-5 个单词的、小写的、文件名友好的短语)。示例:{\"summary\": \"refactor-database-schema\"}。会话内容是:",
|
|
215
|
+
"maxLines": 50
|
|
214
216
|
},
|
|
215
217
|
{
|
|
216
218
|
"name": "my-custom-summarizer",
|
|
@@ -238,40 +240,7 @@ ai-cli-log <command> [args...]
|
|
|
238
240
|
* **`prompt`**: 传递给摘要器命令的提示。会话内容将作为标准输入传递。
|
|
239
241
|
* **`maxLines`** (可选): 限制传递给摘要器的会话内容行数。如果会话内容超过此限制,将只采样开头和结尾的行。
|
|
240
242
|
* **`command`** (可选): 对于 `custom` 工具,指定要执行的命令数组。会话内容会通过管道传递给该命令的 `stdin`。`{{prompt}}` 占位符将被实际的提示字符串替换。例如: `["my-summarizer-script", "--prompt", "{{prompt}}"]`。
|
|
241
|
-
* **重要**: 摘要器的输出**必须**是一个有效的 JSON 对象,其中包含一个名为 `summary` 的键(例如,`{"summary": "
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
**Field Descriptions:**
|
|
245
|
-
|
|
246
|
-
* `summarizer.default` (optional): The name of the default summarizer configuration to use.
|
|
247
|
-
* `summarizer.summarizers`: An array of different summarizer configurations.
|
|
248
|
-
* **`name`**: A unique name you give to the summarizer configuration (e.g., `gemini-pro`, `ollama`, `claude-opus`, `my-custom-summarizer`).
|
|
249
|
-
* **`tool`**: The type of tool the summarizer uses.
|
|
250
|
-
* `gemini`: Uses the `gemini` CLI tool.
|
|
251
|
-
* `ollama`: Uses the `ollama` CLI tool.
|
|
252
|
-
* `claude`: Uses the `claude` CLI tool.
|
|
253
|
-
* `custom`: Uses a custom command.
|
|
254
|
-
* **`model`** (optional): For the `ollama` tool, specifies the model name to use (e.g., `llama3`).
|
|
255
|
-
* **`prompt`**: The prompt passed to the summarizer command. The session content will be passed as standard input.
|
|
256
|
-
* **`maxLines`** (optional): Limits the number of session content lines passed to the summarizer. If the session exceeds this limit, only the beginning and end lines will be sampled.
|
|
257
|
-
* **`command`** (optional): For the `custom` tool, specifies the command array to execute. The session content is piped to this command's `stdin`. The `{{prompt}}` placeholder will be replaced with the actual prompt string. Example: `["my-summarizer-script", "--prompt", "{{prompt}}"]`.
|
|
258
|
-
* **Important**: The output from the summarizer **MUST** be a valid JSON object containing a key named `summary` (e.g., `{"summary": "your-summary-phrase"}`).
|
|
259
|
-
|
|
260
|
-
### 交互式设置 (`--init`)
|
|
261
|
-
|
|
262
|
-
运行交互式设置来创建配置文件。
|
|
263
|
-
|
|
264
|
-
* **创建全局配置文件 (位于 `~/.config/ai-cli-log/config.json`):**
|
|
265
|
-
```bash
|
|
266
|
-
ai-cli-log --init
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
* **创建本地、项目特定的配置文件 (位于 `.ai-cli-log/config.json`):**
|
|
270
|
-
```bash
|
|
271
|
-
ai-cli-log --init --local
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
该命令将引导您完成配置过程,包括扫描可用的 AI 工具、创建摘要器配置和设置默认摘要器。
|
|
243
|
+
* **重要**: 摘要器的输出**必须**是一个有效的 JSON 对象,其中包含一个名为 `summary` 的键(例如,`{"summary": "fix-login-bug"}`)。
|
|
275
244
|
|
|
276
245
|
## 功能特性
|
|
277
246
|
|
|
@@ -290,8 +259,4 @@ ai-cli-log <command> [args...]
|
|
|
290
259
|
|
|
291
260
|
## 待办事项 (TODO)
|
|
292
261
|
|
|
293
|
-
*
|
|
294
|
-
* 当会话输出为空时,避免保存空的日志文件。
|
|
295
|
-
* 尾随空格和空行现在已从输出中删除,以解决内容不足导致大片空白区域的问题。
|
|
296
|
-
* **文件名约定:** 当前基于时间戳的文件名虽然功能上可行,但可能过于单调。评估其他更具描述性的文件名方案,同时仔细考虑如果使用 AI 摘要进行命名可能导致的信息泄露问题。
|
|
297
|
-
|
|
262
|
+
* **Markdown 支持:** 探寻并实现将日志保存为 Markdown 格式的可能性,可在文件的 frontmatter 中包含会话元数据(如:命令、时间戳、摘要等)。
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ const os = __importStar(require("os"));
|
|
|
44
44
|
const child_process_1 = require("child_process");
|
|
45
45
|
const headless_1 = require("@xterm/headless");
|
|
46
46
|
const readline_1 = __importDefault(require("readline"));
|
|
47
|
+
const commander_1 = require("commander");
|
|
47
48
|
// --- 1. CONFIGURATION & TYPE DEFINITIONS ---
|
|
48
49
|
const GLOBAL_CONFIG_DIR = path.join(os.homedir(), '.config', 'ai-cli-log');
|
|
49
50
|
const GLOBAL_CONFIG_PATH = path.join(GLOBAL_CONFIG_DIR, 'config.json');
|
|
@@ -125,7 +126,7 @@ async function handleInitCommand(isLocal) {
|
|
|
125
126
|
}
|
|
126
127
|
const config = readConfig();
|
|
127
128
|
const summarizersToUpdate = [];
|
|
128
|
-
const newPrompt = 'You are a log summarizer. Your response MUST be a valid JSON object
|
|
129
|
+
const newPrompt = 'You are a log summarizer. Your response MUST be a raw, valid JSON object and nothing else. Do not wrap it in markdown blocks like ```json. The JSON object must have a single key "summary" which is a 3-5 word, lowercase, filename-friendly phrase. Example: {"summary": "refactor-database-schema"}. The session content is:';
|
|
129
130
|
if (availableTools.includes('gemini')) {
|
|
130
131
|
const add = await ask('\n> Found Gemini. Add/update the \'gemini-pro\' summarizer? (Y/n): ');
|
|
131
132
|
if (add.toLowerCase() !== 'n') {
|
|
@@ -345,7 +346,10 @@ function runLoggingSession(command, commandArgs, summaryArg) {
|
|
|
345
346
|
const config = readConfig();
|
|
346
347
|
const summarizerName = (typeof summaryArg === 'string' ? summaryArg : config.summarizer.default) || 'default';
|
|
347
348
|
try {
|
|
348
|
-
|
|
349
|
+
// Pre-process the raw summary to extract JSON from markdown blocks if present
|
|
350
|
+
const jsonMatch = rawSummaryJson.match(/\{.*\}/s);
|
|
351
|
+
const cleanJson = jsonMatch ? jsonMatch[0] : rawSummaryJson;
|
|
352
|
+
const summaryData = JSON.parse(cleanJson);
|
|
349
353
|
const slug = summaryData.summary;
|
|
350
354
|
if (typeof slug !== 'string') {
|
|
351
355
|
throw new Error('Invalid JSON structure from summarizer: "summary" key is missing or not a string.');
|
|
@@ -382,34 +386,46 @@ function runLoggingSession(command, commandArgs, summaryArg) {
|
|
|
382
386
|
}
|
|
383
387
|
// --- 3. MAIN ENTRY POINT & ARGUMENT PARSER ---
|
|
384
388
|
function main() {
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
389
|
+
const program = new commander_1.Command();
|
|
390
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
391
|
+
const pkg = require('../package.json');
|
|
392
|
+
program
|
|
393
|
+
.name('ai-cli-log')
|
|
394
|
+
.description('A CLI tool to seamlessly log terminal sessions with AI models.')
|
|
395
|
+
.version(pkg.version, '-v, --version', 'Output the current version')
|
|
396
|
+
.option('-s, --with-summary', 'Enable AI summary for the session using the default summarizer.')
|
|
397
|
+
.option('--by <name>, --summarizer <name>', 'Specify a summarizer to use. Implies --with-summary.');
|
|
398
|
+
program
|
|
399
|
+
.command('init')
|
|
400
|
+
.description('Initialize or update the configuration file.')
|
|
401
|
+
.option('--local', 'Create the configuration file in the current directory\'s .ai-cli-log folder.', false)
|
|
402
|
+
.action((options) => {
|
|
403
|
+
handleInitCommand(options.local);
|
|
404
|
+
});
|
|
405
|
+
program
|
|
406
|
+
.command('run')
|
|
407
|
+
.usage('<command> [args...]')
|
|
408
|
+
.description("Run a command and log the session. Any options for ai-cli-log itself (like -s) must come before the 'run' command.")
|
|
409
|
+
.argument('<command>', 'The command to execute and log.')
|
|
410
|
+
.argument('[args...]', 'Arguments for the command.')
|
|
411
|
+
.allowUnknownOption()
|
|
412
|
+
.action((command, args) => {
|
|
413
|
+
const options = program.opts();
|
|
414
|
+
let summaryArg = false;
|
|
415
|
+
if (options.by) {
|
|
416
|
+
summaryArg = options.by;
|
|
417
|
+
}
|
|
418
|
+
else if (options.summarizer) {
|
|
419
|
+
summaryArg = options.summarizer;
|
|
420
|
+
}
|
|
421
|
+
else if (options.withSummary) {
|
|
422
|
+
summaryArg = true;
|
|
423
|
+
}
|
|
424
|
+
runLoggingSession(command, args, summaryArg);
|
|
425
|
+
});
|
|
426
|
+
program.parse(process.argv);
|
|
427
|
+
if (!process.argv.slice(2).length) {
|
|
428
|
+
program.help();
|
|
412
429
|
}
|
|
413
|
-
runLoggingSession(command, commandArgs, summaryArg);
|
|
414
430
|
}
|
|
415
431
|
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-cli-log",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Seamlessly log your AI-powered coding conversations. This command-line interface (CLI) tool captures your terminal interactions with AI models like Gemini and Claude, saving entire sessions as clean plain text documents for easy review and documentation.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,12 +23,14 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://github.com/alingse/ai-cli-log#readme",
|
|
25
25
|
"devDependencies": {
|
|
26
|
+
"@types/commander": "^2.12.0",
|
|
26
27
|
"@types/node": "^24.0.10",
|
|
27
28
|
"ts-node": "^10.9.2",
|
|
28
29
|
"typescript": "^5.8.3"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"@xterm/headless": "^5.5.0",
|
|
33
|
+
"commander": "^14.0.0",
|
|
32
34
|
"node-pty": "^1.0.0"
|
|
33
35
|
}
|
|
34
36
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import * as os from 'os';
|
|
|
7
7
|
import { spawn } from 'child_process';
|
|
8
8
|
import { Terminal } from '@xterm/headless';
|
|
9
9
|
import readline from 'readline';
|
|
10
|
+
import { Command } from 'commander';
|
|
10
11
|
|
|
11
12
|
// --- 1. CONFIGURATION & TYPE DEFINITIONS ---
|
|
12
13
|
|
|
@@ -110,7 +111,7 @@ async function handleInitCommand(isLocal: boolean) {
|
|
|
110
111
|
|
|
111
112
|
const config = readConfig();
|
|
112
113
|
const summarizersToUpdate: Summarizer[] = [];
|
|
113
|
-
const newPrompt = 'You are a log summarizer. Your response MUST be a valid JSON object
|
|
114
|
+
const newPrompt = 'You are a log summarizer. Your response MUST be a raw, valid JSON object and nothing else. Do not wrap it in markdown blocks like ```json. The JSON object must have a single key "summary" which is a 3-5 word, lowercase, filename-friendly phrase. Example: {"summary": "refactor-database-schema"}. The session content is:';
|
|
114
115
|
|
|
115
116
|
if (availableTools.includes('gemini')) {
|
|
116
117
|
const add = await ask('\n> Found Gemini. Add/update the \'gemini-pro\' summarizer? (Y/n): ');
|
|
@@ -357,7 +358,11 @@ function runLoggingSession(command: string, commandArgs: string[], summaryArg?:
|
|
|
357
358
|
const summarizerName = (typeof summaryArg === 'string' ? summaryArg : config.summarizer.default) || 'default';
|
|
358
359
|
|
|
359
360
|
try {
|
|
360
|
-
|
|
361
|
+
// Pre-process the raw summary to extract JSON from markdown blocks if present
|
|
362
|
+
const jsonMatch = rawSummaryJson.match(/\{.*\}/s);
|
|
363
|
+
const cleanJson = jsonMatch ? jsonMatch[0] : rawSummaryJson;
|
|
364
|
+
|
|
365
|
+
const summaryData = JSON.parse(cleanJson);
|
|
361
366
|
const slug = summaryData.summary;
|
|
362
367
|
|
|
363
368
|
if (typeof slug !== 'string') {
|
|
@@ -399,45 +404,50 @@ function runLoggingSession(command: string, commandArgs: string[], summaryArg?:
|
|
|
399
404
|
// --- 3. MAIN ENTRY POINT & ARGUMENT PARSER ---
|
|
400
405
|
|
|
401
406
|
function main() {
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
407
|
+
const program = new Command();
|
|
408
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
409
|
+
const pkg = require('../package.json');
|
|
410
|
+
|
|
411
|
+
program
|
|
412
|
+
.name('ai-cli-log')
|
|
413
|
+
.description('A CLI tool to seamlessly log terminal sessions with AI models.')
|
|
414
|
+
.version(pkg.version, '-v, --version', 'Output the current version')
|
|
415
|
+
.option('-s, --with-summary', 'Enable AI summary for the session using the default summarizer.')
|
|
416
|
+
.option('--by <name>, --summarizer <name>', 'Specify a summarizer to use. Implies --with-summary.');
|
|
417
|
+
|
|
418
|
+
program
|
|
419
|
+
.command('init')
|
|
420
|
+
.description('Initialize or update the configuration file.')
|
|
421
|
+
.option('--local', 'Create the configuration file in the current directory\'s .ai-cli-log folder.', false)
|
|
422
|
+
.action((options) => {
|
|
423
|
+
handleInitCommand(options.local);
|
|
424
|
+
});
|
|
410
425
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
426
|
+
program
|
|
427
|
+
.command('run')
|
|
428
|
+
.usage('<command> [args...]')
|
|
429
|
+
.description("Run a command and log the session. Any options for ai-cli-log itself (like -s) must come before the 'run' command.")
|
|
430
|
+
.argument('<command>', 'The command to execute and log.')
|
|
431
|
+
.argument('[args...]', 'Arguments for the command.')
|
|
432
|
+
.allowUnknownOption()
|
|
433
|
+
.action((command, args) => {
|
|
434
|
+
const options = program.opts();
|
|
435
|
+
let summaryArg: string | boolean = false;
|
|
436
|
+
if (options.by) {
|
|
437
|
+
summaryArg = options.by;
|
|
438
|
+
} else if (options.summarizer) {
|
|
439
|
+
summaryArg = options.summarizer;
|
|
440
|
+
} else if (options.withSummary) {
|
|
441
|
+
summaryArg = true;
|
|
442
|
+
}
|
|
443
|
+
runLoggingSession(command, args, summaryArg);
|
|
444
|
+
});
|
|
416
445
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
const otherArgs = args.filter(arg =>
|
|
420
|
-
!arg.startsWith('--with-summary') &&
|
|
421
|
-
!arg.startsWith('-s') &&
|
|
422
|
-
arg !== '--init' &&
|
|
423
|
-
arg !== '--local'
|
|
424
|
-
);
|
|
425
|
-
|
|
426
|
-
const command = otherArgs[0];
|
|
427
|
-
const commandArgs = otherArgs.slice(1);
|
|
428
|
-
|
|
429
|
-
if (!command) {
|
|
430
|
-
console.error('Usage: ai-cli-log [-s[=<summarizer>]] <command> [args...]');
|
|
431
|
-
console.error(' ai-cli-log --init [--local]');
|
|
432
|
-
process.exit(1);
|
|
433
|
-
}
|
|
446
|
+
program.parse(process.argv);
|
|
434
447
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
summaryArg = summaryArgRaw.includes('=') ? summaryArgRaw.split('=')[1] : true;
|
|
448
|
+
if (!process.argv.slice(2).length) {
|
|
449
|
+
program.help();
|
|
438
450
|
}
|
|
439
|
-
|
|
440
|
-
runLoggingSession(command, commandArgs, summaryArg);
|
|
441
451
|
}
|
|
442
452
|
|
|
443
|
-
main();
|
|
453
|
+
main();
|