@kairyou/agent-tools 0.11.0 → 0.13.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.
@@ -0,0 +1,113 @@
1
+ // integrations/log/opencode-plugin.mjs
2
+ import { spawn } from "node:child_process";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ var HOOK = path.join(path.dirname(fileURLToPath(import.meta.url)), "hook.mjs");
6
+ var sendQueue = Promise.resolve();
7
+ function send(payload) {
8
+ sendQueue = sendQueue.then(
9
+ () => new Promise((resolve) => {
10
+ try {
11
+ const child = spawn("node", [HOOK], {
12
+ stdio: ["pipe", "ignore", "ignore"],
13
+ windowsHide: true
14
+ });
15
+ child.on("error", () => resolve());
16
+ child.on("exit", () => resolve());
17
+ child.stdin.write(JSON.stringify(payload));
18
+ child.stdin.end();
19
+ } catch {
20
+ resolve();
21
+ }
22
+ })
23
+ );
24
+ }
25
+ var AgentToolsLog = async ({ directory, project } = {}) => {
26
+ const cwd = directory || project?.worktree || process.cwd();
27
+ const assistantMessageIds = /* @__PURE__ */ new Set();
28
+ const lastAssistantText = /* @__PURE__ */ new Map();
29
+ return {
30
+ "chat.message": async (_input, output) => {
31
+ const message = output?.message;
32
+ if (message?.role !== "user") return;
33
+ const text = (output?.parts || []).filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n");
34
+ if (!text.trim()) return;
35
+ send({
36
+ hook_event_name: "UserPromptSubmit",
37
+ session_id: message.sessionID,
38
+ cwd,
39
+ prompt: text
40
+ });
41
+ },
42
+ "tool.execute.before": async (input, output) => {
43
+ const tool = String(input?.tool || "");
44
+ if (tool === "bash") return;
45
+ const args = output?.args;
46
+ if (!args || typeof args !== "object") return;
47
+ send({
48
+ hook_event_name: "PreToolUse",
49
+ session_id: input?.sessionID,
50
+ cwd,
51
+ tool_name: tool === "write" ? "Write" : "Edit",
52
+ tool_input: args
53
+ });
54
+ },
55
+ "tool.execute.after": async (input, output) => {
56
+ const sessionId = input?.sessionID;
57
+ const tool = String(input?.tool || "");
58
+ if (tool === "bash") {
59
+ send({
60
+ hook_event_name: "PostToolUse",
61
+ session_id: sessionId,
62
+ cwd,
63
+ tool_name: "Bash",
64
+ tool_input: { command: String(input?.args?.command || "") }
65
+ });
66
+ return;
67
+ }
68
+ const files = output?.metadata?.files;
69
+ if (!Array.isArray(files)) return;
70
+ for (const file of files) {
71
+ if (!file?.filePath) continue;
72
+ send({
73
+ hook_event_name: "PostToolUse",
74
+ session_id: sessionId,
75
+ cwd,
76
+ tool_name: tool === "write" ? "Write" : "Edit",
77
+ tool_input: { file_path: file.filePath }
78
+ });
79
+ }
80
+ },
81
+ event: async ({ event }) => {
82
+ const type = event?.type;
83
+ const properties = event?.properties || {};
84
+ if (type === "message.updated") {
85
+ if (properties.info?.role === "assistant") assistantMessageIds.add(properties.info.id);
86
+ return;
87
+ }
88
+ if (type === "message.part.updated") {
89
+ const part = properties.part;
90
+ if (part?.type === "text" && assistantMessageIds.has(part.messageID)) {
91
+ lastAssistantText.set(part.sessionID, String(part.text || ""));
92
+ }
93
+ return;
94
+ }
95
+ if (type === "session.idle") {
96
+ send({
97
+ hook_event_name: "Stop",
98
+ session_id: properties.sessionID,
99
+ cwd,
100
+ last_assistant_message: lastAssistantText.get(properties.sessionID) || ""
101
+ });
102
+ lastAssistantText.delete(properties.sessionID);
103
+ return;
104
+ }
105
+ if (type === "session.deleted") {
106
+ lastAssistantText.delete(properties.sessionID);
107
+ }
108
+ }
109
+ };
110
+ };
111
+ export {
112
+ AgentToolsLog
113
+ };
package/docs/en/extras.md CHANGED
@@ -19,13 +19,13 @@ Usage:
19
19
  - `/at-self-eval summarize July for C:\projects\project-a and C:\projects\project-b` — only those projects
20
20
  - `/at-self-eval also include C:\projects\project-c` — add to the default scope
21
21
  - Paste a daily/weekly log, or give a file path, to add business context
22
- - `/at-self-eval summarize from C:\projects\todo.md only` — log only, Git is not read
22
+ - `/at-self-eval summarize from C:\logs\daily-log.md only` — log only, Git is not read
23
23
 
24
24
  Review the generated result before use.
25
25
 
26
26
  ## at-daily-log
27
27
 
28
- Summarize the day's Git activity across projects into a daily work log.
28
+ Distill each day's Git commits across projects into a work report; runs when invoked.
29
29
 
30
30
  ```bash
31
31
  npx -y skills@latest add kairyou/agent-tools --skill at-daily-log -g -y
@@ -35,29 +35,111 @@ Usage:
35
35
 
36
36
  - `/at-daily-log` — print today's log
37
37
  - `/at-daily-log 2026-07-31` — pick the date
38
+ - `/at-daily-log last week` / `/at-daily-log the last two weeks` — one entry per active day, empty days skipped
38
39
  - `/at-daily-log summarize today for C:\projects\project-a` — only that project
39
40
  - `/at-daily-log also include C:\projects\project-c` — add to the default scope
40
41
  - `/at-daily-log record the log` — record to the configured file; rerunning a day only refreshes the generated part
41
- - `/at-daily-log record it to C:\projects\todo.md` — record to that file
42
- - `/at-daily-log record every workday at 18:00` — guides you through an OS scheduled task
42
+ - `/at-daily-log record it to C:\logs\daily-log.md` — record to that file
43
+ - `/at-daily-log record daily at 18:00` — guides you through an OS scheduled task; days without commits are not written
43
44
 
45
+ Recorded output example:
46
+
47
+ ```markdown
48
+ + 2026-08-03
49
+ <!-- daily-log:2026-08-03:start 5,a1b2c3d -->
50
+ 1. project-a: finished the login module refactor with regression coverage.
51
+ 2. project-b: fixed the timezone offset in report exports.
52
+ <!-- daily-log:2026-08-03:end -->
53
+ ```
54
+
55
+ The `<!-- ... -->` comments are boundary markers: an update rewrites only what sits
56
+ between them, and everything else in the file (such as your own notes) is left alone.
57
+
58
+ Paired with the `log` capability below, work that ships no code, such as troubleshooting, also reaches the report.
44
59
  Review the generated result before use.
45
60
 
46
- ## Optional configuration
61
+ ## log
62
+
63
+ Record each day's AI sessions across projects into a work log; runs automatically
64
+ once installed.
65
+
66
+ Independent of and complementary to `at-daily-log` above; use them together or alone.
67
+
68
+ ```bash
69
+ npx -y @kairyou/agent-tools@latest log -a claude codex opencode
70
+ ```
71
+
72
+ - `format: "daily"` (default): a single markdown file, one dated entry per day, each turn summarized into one line
73
+ - `format: "detailed"`: one full report per day with each turn's request and outcome, the files changed, and approximate lines added/removed (measured against the current file when several turns touch one)
74
+ - Codex: run `/hooks` once after installing to approve it; opencode: restart after installing or updating
75
+
76
+ `daily` output example:
77
+
78
+ ```markdown
79
+ + 2026-08-03
80
+ <!-- log:2026-08-03:start -->
81
+ 1. project-a: traced the login timeout to sessions never renewing.
82
+ 2. project-a: fixed the login timeout, added regression tests.
83
+ 3. project-b: traced empty report exports to an inverted permission filter.
84
+ <!-- log:2026-08-03:end -->
85
+ ```
86
+
87
+ One line per turn, written from the AI's own summary at the end of that turn; no
88
+ cross-turn consolidation. Updates likewise rewrite only what sits between the markers.
89
+
90
+ `detailed` output example (excerpt):
91
+
92
+ ```markdown
93
+ # AI Log - 2026-08-03
94
+
95
+ ## Overview
96
+
97
+ - Prompts: 5
98
+ - Changed files: 3
99
+ - Line changes: +120/-30
100
+
101
+ ## Sessions
102
+
103
+ - Time: 2026-08-03 10:12:01 -> 2026-08-03 10:20:45
104
+ - Project: project-a
105
+
106
+ Request
107
+ (request excerpt)
108
+
109
+ Outcome
110
+ (outcome summary)
111
+
112
+ Changes
113
+ - src/auth/session.ts | diff +42/-8 | 3 ops
114
+ ```
115
+
116
+ ## Configuration
47
117
 
48
118
  All in `~/.agent-tools/config.jsonc`:
49
119
 
50
120
  ```jsonc
51
121
  {
52
- // at-self-eval, at-daily-log: default projects (otherwise just the current repo)
122
+ // log capability: AI session log
123
+ "log": {
124
+ "enabled": true, // false: pause recording without uninstalling
125
+ "output": "C:\\logs\\ai-log.md", // daily: one file; detailed: a directory
126
+ "language": "zh", // zh | en
127
+ "format": "daily", // daily | detailed
128
+ "projects": [ // optional: record only these; entries may override the keys above
129
+ "C:\\projects\\project-a",
130
+ { "path": "C:\\projects\\project-b", "format": "detailed", "output": "C:\\logs\\project-b" }
131
+ ]
132
+ },
133
+ // at-self-eval, at-daily-log: default projects (otherwise just the current repo);
134
+ // prompt: free text that tunes how that project is summarized
53
135
  "workProjects": [
54
136
  "C:\\projects\\project-a",
55
- "C:\\projects\\project-b"
137
+ { "path": "C:\\projects\\project-b", "prompt": "refer to `phoenix` as `Shop App` in the output; skip commits starting with `test:`" }
56
138
  // "C:\\projects\\temporarily-disabled"
57
139
  ],
58
140
  // at-daily-log: default file when asked to record; at-self-eval also reads it as fallback
59
141
  "dailyLog": {
60
- "output": "C:\\projects\\todo.md"
142
+ "output": "C:\\logs\\daily-log.md"
61
143
  }
62
144
  }
63
145
  ```
@@ -18,13 +18,13 @@ npx -y skills@latest add kairyou/agent-tools --skill at-self-eval -g -y
18
18
  - `/at-self-eval 统计 C:\projects\project-a 和 C:\projects\project-b 的 7 月工作` — 只统计指定项目
19
19
  - `/at-self-eval 另外包含 C:\projects\project-c` — 在默认范围上追加
20
20
  - 可粘贴日报或周报文本, 也可提供文件路径补充业务背景
21
- - `/at-self-eval 只根据 C:\projects\todo.md 总结` — 只凭日志生成, 不读 Git
21
+ - `/at-self-eval 只根据 C:\logs\daily-log.md 总结` — 只凭日志生成, 不读 Git
22
22
 
23
23
  生成的结果请人工核对.
24
24
 
25
25
  ## at-daily-log
26
26
 
27
- 汇总一天内各项目的 Git 活动, 生成工作日报.
27
+ 按天把各项目的 Git 提交提炼成工作日报, 调用时生成.
28
28
 
29
29
  ```bash
30
30
  npx -y skills@latest add kairyou/agent-tools --skill at-daily-log -g -y
@@ -34,29 +34,110 @@ npx -y skills@latest add kairyou/agent-tools --skill at-daily-log -g -y
34
34
 
35
35
  - `/at-daily-log` — 输出今天的日报
36
36
  - `/at-daily-log 2026-07-31` — 指定日期
37
+ - `/at-daily-log 上周` / `/at-daily-log 最近两周` — 范围内每天一条, 跳过没有提交的日子
37
38
  - `/at-daily-log 统计 C:\projects\project-a 今天的工作` — 只统计指定项目
38
39
  - `/at-daily-log 另外包含 C:\projects\project-c` — 在默认范围上追加
39
40
  - `/at-daily-log 记录日报` — 记录到配置的文件; 同一天重复执行只更新生成的部分
40
- - `/at-daily-log 记录到 C:\projects\todo.md` — 记录到指定文件
41
- - `/at-daily-log 每个工作日 18:00 自动记录` — 引导搭建系统定时任务
41
+ - `/at-daily-log 记录到 C:\logs\daily-log.md` — 记录到指定文件
42
+ - `/at-daily-log 每天 18:00 自动记录` — 引导搭建系统定时任务; 没有提交的日子不会写入
42
43
 
44
+ 记录到文件的示例:
45
+
46
+ ```markdown
47
+ + 2026-08-03
48
+ <!-- daily-log:2026-08-03:start 5,a1b2c3d -->
49
+ 1. project-a: 完成登录模块重构, 覆盖回归用例.
50
+ 2. project-b: 修复导出报表的时区偏移.
51
+ <!-- daily-log:2026-08-03:end -->
52
+ ```
53
+
54
+ `<!-- ... -->` 注释是边界标记: 更新只重写两个标记之间的内容, 文件里的其他部分
55
+ (比如你手写的备注)不会被碰.
56
+
57
+ 搭配下方的 `log` 使用时, 排查问题这类没提交代码的工作也能进日报.
43
58
  生成的结果请人工核对.
44
59
 
45
- ## 可选配置
60
+ ## log
61
+
62
+ 按天把各项目的 AI 会话记录成工作日志, 安装后自动运行.
63
+
64
+ 和上面的 `at-daily-log` 独立互补, 可一起使用或单独使用.
65
+
66
+ ```bash
67
+ npx -y @kairyou/agent-tools@latest log -a claude codex opencode
68
+ ```
69
+
70
+ - `format: "daily"` (默认): 单一 md 文件, 每天一个日期条目, 每轮对话总结成一行
71
+ - `format: "detailed"`: 每天一份详细报告, 含每轮的请求与结果, 改动的文件和近似的增删行数(多轮改同一文件时按当前文件计算)
72
+ - Codex 安装后运行 `/hooks` 批准一次; opencode 安装或更新后需要重启
73
+
74
+ `daily` 输出示例:
75
+
76
+ ```markdown
77
+ + 2026-08-03
78
+ <!-- log:2026-08-03:start -->
79
+ 1. project-a: 排查登录超时, 定位到会话缓存没有续期.
80
+ 2. project-a: 修复登录超时, 补充回归用例.
81
+ 3. project-b: 定位报表导出为空的问题, 原因是权限过滤条件写反.
82
+ <!-- log:2026-08-03:end -->
83
+ ```
84
+
85
+ 每轮一行, 内容是那一轮结束时 AI 自己写的总结, 不做跨轮归纳; 同样只重写标记之间
86
+ 的部分, 文件里的其他内容不会被碰.
87
+
88
+ `detailed` 输出示例(节选):
89
+
90
+ ```markdown
91
+ # AI 日报 - 2026-08-03
92
+
93
+ ## 今日概览
94
+
95
+ - 请求次数: 5
96
+ - 变更文件数: 3
97
+ - 总行变更: +120/-30
98
+
99
+ ## 会话记录
100
+
101
+ - Time: 2026-08-03 10:12:01 -> 2026-08-03 10:20:45
102
+ - Project: project-a
103
+
104
+ Request
105
+ (请求原文摘录)
106
+
107
+ Outcome
108
+ (结果摘要)
109
+
110
+ Changes
111
+ - src/auth/session.ts | 变更 +42/-8 | 操作 3 次
112
+ ```
113
+
114
+ ## 配置
46
115
 
47
116
  都在 `~/.agent-tools/config.jsonc`:
48
117
 
49
118
  ```jsonc
50
119
  {
51
- // at-self-eval, at-daily-log: 默认统计的项目(不配则只统计当前项目)
120
+ // log capability: AI 会话日志
121
+ "log": {
122
+ "enabled": true, // false: 临时停止记录, 不用卸载
123
+ "output": "C:\\logs\\ai-log.md", // daily: 单一文件; detailed: 目录
124
+ "language": "zh", // zh | en
125
+ "format": "daily", // daily | detailed
126
+ "projects": [ // 可选: 只记录这些目录, 条目可覆盖上面的键
127
+ "C:\\projects\\project-a",
128
+ { "path": "C:\\projects\\project-b", "format": "detailed", "output": "C:\\logs\\project-b" }
129
+ ]
130
+ },
131
+ // at-self-eval, at-daily-log: 默认统计的项目(不配则只统计当前项目);
132
+ // prompt: 该项目的提示词, 用来优化生成的日报和总结
52
133
  "workProjects": [
53
134
  "C:\\projects\\project-a",
54
- "C:\\projects\\project-b"
135
+ { "path": "C:\\projects\\project-b", "prompt": "输出里把 `phoenix` 称作 `商城App`, 跳过 `test:` 开头的提交" }
55
136
  // "C:\\projects\\temporarily-disabled"
56
137
  ],
57
138
  // at-daily-log: 记录日报的默认文件; 未提供日志时 at-self-eval 也读它作补充
58
139
  "dailyLog": {
59
- "output": "C:\\projects\\todo.md"
140
+ "output": "C:\\logs\\daily-log.md"
60
141
  }
61
142
  }
62
143
  ```