@kairyou/agent-tools 0.14.0 → 0.15.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.
@@ -19,9 +19,9 @@
19
19
  // log capability: AI session work log; see the extras doc for details.
20
20
  "log": {
21
21
  "enabled": true, // false: pause recording without uninstalling
22
- "output": "~/.agent-tools/logs/ai-log.md", // daily: one file; detailed: a directory
22
+ "output": "~/.agent-tools/logs/ai-log", // detailed: one <date>.md file per day; daily: one file
23
23
  "language": "zh", // zh | en (detailed report headings)
24
- "format": "daily", // daily | detailed
24
+ "format": "detailed", // detailed | daily
25
25
  "projects": [ // record only these; empty: record everything
26
26
  // "C:\\projects\\project-a"
27
27
  ]
package/dist/log/hook.mjs CHANGED
@@ -868,7 +868,8 @@ var ParseErrorCode;
868
868
  // integrations/log/hook.mjs
869
869
  var MAX_SNAPSHOT_BYTES = 512 * 1024;
870
870
  var MIN_RESULT_SUMMARY_LENGTH = 24;
871
- var DAILY_ITEM_MAX_CHARS = 160;
871
+ var DAILY_ITEM_TARGET_CHARS = 160;
872
+ var DAILY_ITEM_HARD_MAX_CHARS = 320;
872
873
  var INSTALL_ROOT = process.env.AGENT_TOOLS_HOME || path.join(os.homedir(), ".agent-tools");
873
874
  var CACHE_ROOT = path.join(INSTALL_ROOT, "cache", "log");
874
875
  async function main() {
@@ -980,7 +981,8 @@ async function loadLogConfig() {
980
981
  }
981
982
  const section = isPlainObject(parsed.log) ? parsed.log : {};
982
983
  const enabled = section.enabled !== false;
983
- const format2 = pickFormat(section.format, "daily");
984
+ const inferredFormat = section.format === void 0 && typeof section.output === "string" && section.output.trim().toLowerCase().endsWith(".md") ? "daily" : "detailed";
985
+ const format2 = pickFormat(section.format, inferredFormat);
984
986
  const language = pickLanguage(section.language, "zh");
985
987
  const output = pickOutput(section.output, format2, defaultOutput(format2));
986
988
  const projects = [];
@@ -1239,11 +1241,23 @@ function buildDailyItems(state, scopeKey) {
1239
1241
  function dailyItemText(turn) {
1240
1242
  const request = String(turn.request_text || "");
1241
1243
  const outcome = String(turn.result_summary || "");
1242
- if (!hasSubstantiveTurn(request, outcome) || isTrivialTurn(request, outcome)) return "";
1243
- const source = outcome || request;
1244
+ if (!outcome || !hasSubstantiveTurn(request, outcome) || isTrivialTurn(request, outcome)) return "";
1245
+ const source = outcome;
1244
1246
  const flattened = source.split("\n").map((line) => line.replace(/^[#>*\-\s`|]+/, "").trim()).filter(Boolean).join(" ");
1245
1247
  if (!flattened) return "";
1246
- return flattened.length > DAILY_ITEM_MAX_CHARS ? `${flattened.slice(0, DAILY_ITEM_MAX_CHARS - 3)}...` : flattened;
1248
+ return truncateDailyItem(flattened);
1249
+ }
1250
+ function truncateDailyItem(text) {
1251
+ if (text.length <= DAILY_ITEM_HARD_MAX_CHARS) return text;
1252
+ const limit = DAILY_ITEM_HARD_MAX_CHARS - 3;
1253
+ const prefix = text.slice(0, limit);
1254
+ const boundaries = [...prefix.matchAll(/[。!?;;]|[.!?](?=\s|$)/g)];
1255
+ const boundary = boundaries.at(-1)?.index;
1256
+ if (boundary !== void 0 && boundary + 1 >= Math.floor(DAILY_ITEM_TARGET_CHARS * 0.6)) {
1257
+ return `${prefix.slice(0, boundary + 1)}...`;
1258
+ }
1259
+ const targetPrefix = text.slice(0, DAILY_ITEM_TARGET_CHARS - 3);
1260
+ return `${targetPrefix}...`;
1247
1261
  }
1248
1262
  async function updateDailyFile(outputFile, day, items) {
1249
1263
  if (items.length === 0) return;
package/docs/en/extras.md CHANGED
@@ -69,8 +69,8 @@ Independent of and complementary to `at-daily-log` above; use them together or a
69
69
  npx -y @kairyou/agent-tools@latest log -a claude codex opencode
70
70
  ```
71
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)
72
+ - `format: "detailed"` (default): one detailed report per day with each turn's request and outcome, the files changed, and estimated lines added and removed
73
+ - `format: "daily"`: writes to a single Markdown file grouped by date; each completed answer with substantive results is recorded as one line, while pending prompts are omitted; content may be truncated by the length limit, so use it only as a lightweight activity index
74
74
  - Codex: run `/hooks` once after installing to approve it; opencode: restart after installing or updating
75
75
 
76
76
  `daily` output example:
@@ -123,9 +123,9 @@ All in `~/.agent-tools/config.jsonc`:
123
123
  // log capability: AI session log
124
124
  "log": {
125
125
  "enabled": true, // false: pause recording without uninstalling
126
- "output": "C:\\logs\\ai-log.md", // daily: one file; detailed: a directory
126
+ "output": "C:\\logs\\ai-log", // detailed: one <date>.md per day; daily: one file
127
127
  "language": "zh", // zh | en
128
- "format": "daily", // daily | detailed
128
+ "format": "detailed", // detailed | daily
129
129
  "projects": [ // optional: record only these; entries may override the keys above
130
130
  "C:\\projects\\project-a",
131
131
  { "path": "C:\\projects\\project-b", "format": "detailed", "output": "C:\\logs\\project-b" }
@@ -67,8 +67,8 @@ npx -y skills@latest add kairyou/agent-tools --skill at-daily-log -g -y
67
67
  npx -y @kairyou/agent-tools@latest log -a claude codex opencode
68
68
  ```
69
69
 
70
- - `format: "daily"` (默认): 单一 md 文件, 每天一个日期条目, 每轮对话总结成一行
71
- - `format: "detailed"`: 每天一份详细报告, 含每轮的请求与结果, 改动的文件和近似的增删行数(多轮改同一文件时按当前文件计算)
70
+ - `format: "detailed"` (默认): 每天生成一份详细报告, 记录每轮请求与结果, 修改的文件, 以及新增/删除代码行数的估算
71
+ - `format: "daily"`: 写入单个 Markdown 文件, 并按日期归档; 每个已完成且有实质结果的回答记录为一行, 不记录未完成的提问; 内容可能因长度限制被截断, 因此仅适合作为轻量活动索引
72
72
  - Codex 安装后运行 `/hooks` 批准一次; opencode 安装或更新后需要重启
73
73
 
74
74
  `daily` 输出示例:
@@ -120,9 +120,9 @@ Changes
120
120
  // log capability: AI 会话日志
121
121
  "log": {
122
122
  "enabled": true, // false: 临时停止记录, 不用卸载
123
- "output": "C:\\logs\\ai-log.md", // daily: 单一文件; detailed: 目录
123
+ "output": "C:\\logs\\ai-log", // detailed: 每天一个 <date>.md; daily: 单一文件
124
124
  "language": "zh", // zh | en
125
- "format": "daily", // daily | detailed
125
+ "format": "detailed", // detailed | daily
126
126
  "projects": [ // 可选: 只记录这些目录, 条目可覆盖上面的键
127
127
  "C:\\projects\\project-a",
128
128
  { "path": "C:\\projects\\project-b", "format": "detailed", "output": "C:\\logs\\project-b" }
@@ -26,7 +26,8 @@ import { parse as parseJsonc } from "jsonc-parser";
26
26
 
27
27
  const MAX_SNAPSHOT_BYTES = 512 * 1024;
28
28
  const MIN_RESULT_SUMMARY_LENGTH = 24;
29
- const DAILY_ITEM_MAX_CHARS = 160;
29
+ const DAILY_ITEM_TARGET_CHARS = 160;
30
+ const DAILY_ITEM_HARD_MAX_CHARS = 320;
30
31
 
31
32
  const INSTALL_ROOT = process.env.AGENT_TOOLS_HOME || path.join(os.homedir(), ".agent-tools");
32
33
  const CACHE_ROOT = path.join(INSTALL_ROOT, "cache", "log");
@@ -167,7 +168,15 @@ async function loadLogConfig() {
167
168
  }
168
169
  const section = isPlainObject(parsed.log) ? parsed.log : {};
169
170
  const enabled = section.enabled !== false;
170
- const format = pickFormat(section.format, "daily");
171
+ // Keep existing file-based configurations on daily while new installs use
172
+ // detailed by default. Explicit format always wins.
173
+ const inferredFormat =
174
+ section.format === undefined &&
175
+ typeof section.output === "string" &&
176
+ section.output.trim().toLowerCase().endsWith(".md")
177
+ ? "daily"
178
+ : "detailed";
179
+ const format = pickFormat(section.format, inferredFormat);
171
180
  const language = pickLanguage(section.language, "zh");
172
181
  const output = pickOutput(section.output, format, defaultOutput(format));
173
182
 
@@ -497,8 +506,11 @@ function buildDailyItems(state, scopeKey) {
497
506
  function dailyItemText(turn) {
498
507
  const request = String(turn.request_text || "");
499
508
  const outcome = String(turn.result_summary || "");
500
- if (!hasSubstantiveTurn(request, outcome) || isTrivialTurn(request, outcome)) return "";
501
- const source = outcome || request;
509
+ // Daily is an outcome index, not a prompt inbox. Keep request-only turns in
510
+ // detailed reports, but do not present an unfinished question as completed
511
+ // work in the compact daily file.
512
+ if (!outcome || !hasSubstantiveTurn(request, outcome) || isTrivialTurn(request, outcome)) return "";
513
+ const source = outcome;
502
514
  // Flattened rather than first-line: a structured summary often opens with a
503
515
  // preamble line, and the substance sits in the lines after it.
504
516
  const flattened = source
@@ -507,9 +519,23 @@ function dailyItemText(turn) {
507
519
  .filter(Boolean)
508
520
  .join(" ");
509
521
  if (!flattened) return "";
510
- return flattened.length > DAILY_ITEM_MAX_CHARS
511
- ? `${flattened.slice(0, DAILY_ITEM_MAX_CHARS - 3)}...`
512
- : flattened;
522
+ return truncateDailyItem(flattened);
523
+ }
524
+
525
+ function truncateDailyItem(text) {
526
+ if (text.length <= DAILY_ITEM_HARD_MAX_CHARS) return text;
527
+ const limit = DAILY_ITEM_HARD_MAX_CHARS - 3;
528
+ const prefix = text.slice(0, limit);
529
+ // Prefer the longest complete sentence within the hard cap. The target is a
530
+ // soft guide: retaining more complete context is better when the next
531
+ // sentence ends before the hard limit.
532
+ const boundaries = [...prefix.matchAll(/[。!?;;]|[.!?](?=\s|$)/g)];
533
+ const boundary = boundaries.at(-1)?.index;
534
+ if (boundary !== undefined && boundary + 1 >= Math.floor(DAILY_ITEM_TARGET_CHARS * 0.6)) {
535
+ return `${prefix.slice(0, boundary + 1)}...`;
536
+ }
537
+ const targetPrefix = text.slice(0, DAILY_ITEM_TARGET_CHARS - 3);
538
+ return `${targetPrefix}...`;
513
539
  }
514
540
 
515
541
  async function updateDailyFile(outputFile, day, items) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kairyou/agent-tools",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Reusable Agent Skills, plus integrations (statusline, provider usage, vision) that install into Codex, Claude Code, and opencode.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -68,10 +68,12 @@ context.
68
68
  AI session log, separate from `dailyLog.output`. It is a markdown file with dated
69
69
  entries, or a directory holding one `<date>.md` report per day; entries under
70
70
  `log.projects` may route their sessions to their own `output`, so check those paths
71
- too. Read the day's content as supplementary evidence, as it captures work that
72
- produced no commits, such as troubleshooting or research sessions. Merge, do not
73
- duplicate, work already backed by commits; when the key or the day's content is
74
- absent, skip this entirely.
71
+ too. When `log.format` is `daily`, read its single-line results only as activity
72
+ leads: they may be truncated and omit important context. Do not state a log-only
73
+ item as a confirmed outcome from a daily entry alone. When `log.format` is `detailed`, its
74
+ per-day reports are stronger supplementary evidence, but still do not replace Git
75
+ or user confirmation. If the `log` block or its output is absent, skip this entirely.
76
+ Merge, do not duplicate, work already backed by commits.
75
77
 
76
78
  ## Output
77
79
 
@@ -67,8 +67,12 @@ A pasted daily/weekly log or explicit file path provides business context. If ne
67
67
  supplied, optionally read `dailyLog.output` and `log.output` (an automatically recorded
68
68
  AI session log; a dated markdown file, or a directory of per-day `<date>.md` reports,
69
69
  of which read the dates inside the window; entries under `log.projects` may add their
70
- own `output` paths, check those too) from `~/.agent-tools/config.jsonc`; the
71
- latter also captures work that never produced commits,
70
+ own `output` paths, check those too) from `~/.agent-tools/config.jsonc`; when
71
+ `log.format` is `daily`, its single-line results may be truncated and are not
72
+ standalone proof of an outcome. When it is `detailed`, the per-day reports are stronger evidence;
73
+ use them as supplementary material, not as a replacement for Git or user
74
+ confirmation. If the `log` block or its output is absent, skip this source. The latter
75
+ also captures work that never produced commits,
72
76
  such as troubleshooting or research sessions. Explicit conversation input always wins;
73
77
  a missing key or file is non-fatal.
74
78