@yottameta/yotta-logs 0.2.1 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,8 +1,21 @@
1
+ ## v0.3.0 (2026-09-08)
2
+
3
+ **评测驱动完善**:新增 FAQ,安装器错误处理与测试补齐。
4
+
5
+ - 新增 references/faq.md,覆盖格式、范围、脱敏、只读边界与安装排障。
6
+ - 安装器支持 --help、参数校验、统一退出码与人话错误提示。
7
+
1
8
  # 更新日志
2
9
 
10
+ ## v0.2.2 (2026-08-29)
11
+
12
+ - 安装方式统一为四方式(对齐发布规范 §3.3.1):方式一 `npx -y @yottameta/yotta-logs --agent <name>` / `--dir <dir>`(推荐,走 npm 源);方式二 `git clone https://github.com/YottaMeta/yotta-logs.git`;方式三 GitHub Download ZIP;方式四 `bash install.sh --agent/--dir/--list`。移除 `npx skills` 与 `-g` 推荐;中英双 README 安装节同步。
13
+ - 版本对齐:package.json / SKILL.md / CHANGELOG / 引擎 VERSION / 测试断言 / README 锚点 = 0.2.2。
14
+ - 无功能变更(仅文档与版本同步)。
15
+
3
16
  ## v0.2.1 (2026-08-27)
4
17
 
5
- 文档中英双版(老张拍板「英文门面 + 中文全档」):
18
+ 文档中英双版:
6
19
 
7
20
  - **README.md 改为英文**:作为 GitHub / npm / ClawHub 首页的英文门面(翻译 + 精简,覆盖定位 / 核心价值 / 命令 / 快速使用 / 安装 / 使用示例 / 开发校验全流程)。
8
21
  - **新增 README.zh-CN.md**:原中文完整主文档整体平移,继续服务中文用户,顶部加语言切换链接。
@@ -12,7 +25,7 @@
12
25
 
13
26
  ## v0.2.0 (2026-08-27)
14
27
 
15
- 多格式通用化:不再只认 JSONL,按「格式族 × 字段别名归一 + 配置兜底」适配一切格式(老张拍板三点:方向认可 / 版本 v0.2.0 / 默认检索范围动作工时定):
28
+ 多格式通用化:不再只认 JSONL,按「格式族 × 字段别名归一 + 配置兜底」适配一切格式:
16
29
 
17
30
  - **五大格式族 reader**:JSONL(支持嵌套子目录与 Codex rollout payload 形态)/ 单文件 JSON(数组、dict-of-lists)/ SQLite(opencode schema 实测 + 通用列映射兜底,只读 mode=ro)/ Markdown(YAML frontmatter 结构化记忆 + 自由笔记)/ 二进制(只降级读标题不崩)。
18
31
  - **统一 Record 模型**:{source, format, kind, session, time, role, text, path, meta};字段别名归一(time / role / text / session / title),秒 / 毫秒自动推断,JSON 字符串解包。
@@ -24,9 +37,9 @@
24
37
 
25
38
  ## v0.1.0 (2026-08-27)
26
39
 
27
- YottaMeta 自有实现首版(历史会话日志检索方向参考开源社区 session-logs 类技能思路,已完全重写,无上游代码):
40
+ YottaMeta 自有实现首版(历史会话日志检索方向参考开源社区 session-logs 类技能思路,已完全重写):
28
41
 
29
42
  - 元史(yotta-logs)—— 零依赖跨智能体会话日志检索引擎(Python 3.8+ 标准库)。
30
43
  - 能力:locate / scan / search / session / stats / tools / version;关键词 / 正则 / 日期 / 会话 ID / 别名 / 角色过滤;默认脱敏(--no-redact 关闭);--json 结构化输出;只读安全;容错 JSONL 解析(含 sessions.json 索引别名)。
31
44
  - 测试:scripts/test_yotta_logs.py 75 项全绿。
32
- - 版权:YottaMeta 纯自有 MIT + NOTICE 品牌声明;README 一行上游致谢。
45
+ - 版权:YottaMeta 纯自有 MIT + NOTICE 品牌声明。
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 YottaMeta
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
1
+ MIT License
2
+
3
+ Copyright (c) 2026 YottaMeta
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
21
  SOFTWARE.
package/README.md CHANGED
@@ -47,7 +47,7 @@ It is not tied to any single platform: it is an agent-agnostic toolkit that work
47
47
  | **Default scope** | Session + structured memory sources on by default; free notes / binary logs off unless explicitly enabled |
48
48
  | **Fault-tolerant** | Tolerates storage differences across agents; bad lines skipped without aborting; encrypted files fall back to titles |
49
49
  | **Pinpoint provenance** | Hits carry source / session ID / line / timestamp / role for exact tracing |
50
- | **Ecosystem distribution** | GitHub + npm + ClawHub synced; install via npx / install.sh / manual copy |
50
+ | **Ecosystem distribution** | GitHub + npm + ClawHub synced; four install methods (npx / git clone / Download ZIP / install.sh) |
51
51
 
52
52
  ## Commands
53
53
 
@@ -105,50 +105,39 @@ When --dir is omitted, the engine tries $YOTTA_LOGS_DIR, then full source discov
105
105
 
106
106
  ## Installation
107
107
 
108
- Three options — skill files always come from **npm** (GitHub can be slow without a proxy; npm supports mirrors).
108
+ Pick any of the four methods below; the order is the recommended priority. Skill files always come from **npm** (GitHub can be slow without a proxy; npm supports mirrors).
109
109
 
110
- ### Option 1: npm (recommended, one-liner)
111
- ```bash
112
- npx -y @yottameta/yotta-logs -g
113
- npx -y @yottameta/yotta-logs --dir /path/to/skills # any agent: install to a specific directory
110
+ ### Method 1: npm one-liner (recommended)
111
+
112
+ ```text
113
+ # Optional China mirror: npm config set registry https://registry.npmmirror.com
114
+ npx -y @yottameta/yotta-logs --agent <agent-name> # install to the agent's default user-level skills dir
115
+ npx -y @yottameta/yotta-logs --dir <your-skills-dir> # point to the skills dir itself (e.g. ~/.codex/skills)
114
116
  ```
115
- > Agent not in the preset list? Point --dir at its skills directory, or copy manually (Option 3). --list shows each agent's default directory. You can also `npm pack @yottameta/yotta-logs` and unpack the tarball.
116
117
 
117
- ### Option 2: install.sh one-liner
118
- From inside the skill folder (npm pack or git clone):
119
- ```bash
120
- bash install.sh -g # user-level; bash install.sh --list shows all directories
121
- bash install.sh --agent codex # specific agent (--list shows available entries)
122
- bash install.sh # project-level: auto-detect existing .claude/.cursor/.codex skills dirs
123
- bash install.sh --dir /path/to/skills
118
+ - `--agent <name>` installs to that agent's default user-level directory; `--list` shows each agent's default directory.
119
+ - `--dir <path>` installs to the given directory; for agents not in the preset list, point `--dir` at their skills directory.
120
+ - If the mirror has not synced the new package (404): add `--registry=https://registry.npmjs.org/` (a proxy may be needed in China), or wait for the mirror cache.
121
+
122
+ ### Method 2: git clone (developers / git available)
123
+
124
+ ```text
125
+ git clone https://github.com/YottaMeta/yotta-logs.git <your-skills-dir>/yotta-logs
126
+ ```
127
+
128
+ ### Method 3: GitHub Download ZIP (manual / no git)
129
+
130
+ On the GitHub repository `YottaMeta/yotta-logs`, click **Code → Download ZIP**, unzip it and put the `yotta-logs` folder into the agent's skills directory.
131
+
132
+ ### Method 4: install.sh (multi-agent one-liner script)
133
+
134
+ ```text
135
+ bash install.sh --agent <name> # install to the agent's default user-level directory
136
+ bash install.sh --dir <path> # install to the given directory
137
+ bash install.sh --list # list agents -> default directories
124
138
  ```
125
- > Covers 17 agents including Trae / Qwen / Comate / CodeBuddy / Kimi. On Windows, Git Bash is sufficient; otherwise use Option 3.
126
-
127
- ### Option 3: manual copy
128
- Copy the whole `yotta-logs` folder into the target agent's skills directory. Common locations (user-level; %USERPROFILE% on Windows, ~ on Linux/macOS):
129
-
130
- | Agent | User-level dir | Project-level dir |
131
- |---|---|---|
132
- | Codex | %USERPROFILE%\.codex\skills\yotta-logs\ | .codex\skills\ |
133
- | Claude Code | %USERPROFILE%\.claude\skills\yotta-logs\ | .claude\skills\ |
134
- | Cursor | %USERPROFILE%\.cursor\skills\yotta-logs\ | .cursor\skills\ |
135
- | Windsurf | %USERPROFILE%\.codeium\windsurf\skills\yotta-logs\ | .windsurf\skills\ |
136
- | opencode | %USERPROFILE%\.config\opencode\skills\yotta-logs\ | .opencode\skills\ |
137
- | Gemini | %USERPROFILE%\.gemini\skills\yotta-logs\ | .gemini\skills\ |
138
- | Goose | %USERPROFILE%\.config\goose\skills\yotta-logs\ | .goose\skills\ |
139
- | Amp | %USERPROFILE%\.config\agents\skills\yotta-logs\ | .agents\skills\ |
140
- | Kiro | %USERPROFILE%\.kiro\skills\yotta-logs\ | .kiro\skills\ |
141
- | WorkBuddy | %USERPROFILE%\.workbuddy\skills\yotta-logs\ | .workbuddy\skills\ |
142
- | Trae Code CLI | %USERPROFILE%\.traecli\skills\yotta-logs\ | .traecli\skills\ |
143
- | Trae IDE (CN) | %USERPROFILE%\.trae-cn\skills\yotta-logs\ | .trae\skills\ |
144
- | Qwen Code | %USERPROFILE%\.qwen\skills\yotta-logs\ | .qwen\skills\ |
145
- | Comate | %USERPROFILE%\.comate\skills\yotta-logs\ | .comate\skills\ |
146
- | CodeBuddy | %USERPROFILE%\.codebuddy\skills\yotta-logs\ | .codebuddy\skills\ |
147
- | Kimi | %USERPROFILE%\.kimi\skills\yotta-logs\ | .kimi\skills\ |
148
- | Generic AGENTS.md | %USERPROFILE%\.agents\skills\yotta-logs\ | .agents\skills\ |
149
-
150
- > If CODEX_HOME is set, Codex's default directory follows it; same for XDG_CONFIG_HOME with opencode. Note that .agents\skills is not universal — only OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot etc. read it; Claude Code and Codex do not by default. When in doubt, use --dir or let the agent install itself.
151
139
 
140
+ > Method 1 uses the npm registry (npmmirror / npmjs) and does not depend on GitHub; Methods 2/3 use GitHub and may fail without a proxy in China.
152
141
  ## Usage with an AI agent
153
142
 
154
143
  1. Wire this repo's SKILL.md into any agent's skills / rules system (see Installation above).
@@ -173,10 +162,18 @@ Copy the whole `yotta-logs` folder into the target agent's skills directory. Com
173
162
 
174
163
  ## Changelog
175
164
 
165
+ - v0.3.0 (2026-09-08): Evaluation-driven refinement — added FAQ, hardened installer error handling and exit codes, and added installer tests.
166
+
167
+ - v0.2.2 (2026-08-29): Install docs alignment — unified four install methods (npx -y @yottameta/yotta-logs --agent/--dir, git clone, GitHub Download ZIP, install.sh --agent/--dir/--list), removed the legacy GitHub-clone installer and global-install (-g) recommendations; bilingual README install section synced to 发布规范 §3.3.1. No functional change.
168
+
176
169
  - v0.2.1 (2026-08-27): Bilingual documentation — English README as the GitHub / npm / ClawHub homepage, full Chinese doc moved to README.zh-CN.md, English npm description.
177
170
  - v0.2.0 (2026-08-27): Multi-format generalization — JSONL / single-file JSON / SQLite (opencode etc.) / Markdown (memory + free notes) / binary; unified Record + field-alias normalization + config fallback; discover; new --source / --kind / --format filters and default search scope (session + structured memory on, free notes / binary logs off). See CHANGELOG.md.
178
171
  - v0.1.0 (2026-08-27): Initial release — zero-dependency JSONL session log search engine (locate / scan / search / session / stats / tools / version + default redaction + sessions.json alias + read-only).
179
172
 
173
+ ## References
174
+
175
+ - references/faq.md
176
+
180
177
  ## License
181
178
 
182
179
  MIT © YottaMeta — see [LICENSE](./LICENSE).
package/README.zh-CN.md CHANGED
@@ -47,7 +47,7 @@
47
47
  | **默认范围** | 会话源 + 结构化记忆源默认开;自由笔记 / 二进制日志默认关,可显式开 |
48
48
  | **容错** | 不同智能体的存储形态差异可容忍,坏行跳过不中断,加密文件只回退标题 |
49
49
  | **定位准确** | 命中结果带来源 / 会话 ID / 行号 / 时间戳 / 角色,可精确回溯出处 |
50
- | **生态分发** | GitHub + npm + ClawHub 三源同步发布;npx / install.sh / 手动复制三种安装方式 |
50
+ | **生态分发** | GitHub + npm + ClawHub 三源同步发布;npx / git clone / Download ZIP / install.sh 四种安装方式 |
51
51
 
52
52
  ## 功能体系
53
53
 
@@ -105,51 +105,39 @@ python3 scripts/yotta_logs.py search "部署方案" --dir /path/to/sessions --js
105
105
 
106
106
  ## 安装
107
107
 
108
- 三种方式任选其一,技能文件统一从 **npm** 获取(GitHub 无代理时较慢,npm 可配国内镜像加速)。
108
+ 以下四种方式任选,顺序即推荐优先级;技能文件一律从 **npm** 获取(GitHub 无代理较慢,npm 支持镜像)。
109
109
 
110
- ### 方式一:npm(推荐,一行安装)
111
- ```bash
112
- # 国内加速(可选):npm config set registry https://registry.npmmirror.com
113
- npx -y @yottameta/yotta-logs -g
114
- npx -y @yottameta/yotta-logs --dir <你的技能目录> # 任意智能体:指定目录安装
110
+ ### 方式一:npm 一行装(推荐)
111
+
112
+ ```text
113
+ # 可选国内加速:npm config set registry https://registry.npmmirror.com
114
+ npx -y @yottameta/yotta-logs --agent <智能体名称> # 装到指定智能体默认用户级技能目录
115
+ npx -y @yottameta/yotta-logs --dir <智能体的技能目录> # 指到技能目录本身(如 ~/.codex/skills)
115
116
  ```
116
- > 智能体不在预置列表里?用 --dir 指定它的 skills 目录,或手动复制(方式三)。--list 可查看各智能体对应的默认目录。想手动拿文件也可 npm pack @yottameta/yotta-logs 解包后按方式二/三安装。
117
117
 
118
- ### 方式二:install.sh 一键安装
119
- 获取技能文件夹后(npm pack 解包或 git clone),进入技能文件夹:
120
- ```bash
121
- bash install.sh -g # 用户级;bash install.sh --list 查看全部目录
122
- bash install.sh --agent codex # 指定智能体(--list 可查看可用项)
123
- bash install.sh # 项目级:自动检测已存在的 .claude/.cursor/.codex 等 skills 目录
124
- bash install.sh --dir /path/to/skills
118
+ - `--agent <name>` 自动装到该智能体默认用户级目录;`--list` 可查看各智能体默认目录。
119
+ - `--dir <路径>` 装到指定的技能目录;未收录的智能体用 `--dir` 指到它的技能目录。
120
+ - npmmirror 未同步新包(404):加 `--registry=https://registry.npmjs.org/`(国内需代理),或稍等镜像缓存。
121
+
122
+ ### 方式二:git clone(开发者 / 有 git 环境)
123
+
124
+ ```text
125
+ git clone https://github.com/YottaMeta/yotta-logs.git <智能体的技能目录>/yotta-logs
126
+ ```
127
+
128
+ ### 方式三:GitHub 下载压缩包(手动 / 无 git 环境)
129
+
130
+ 在 GitHub 仓库 `YottaMeta/yotta-logs` 点 **Code → Download ZIP**,解压后把 `yotta-logs` 文件夹放进智能体技能目录。
131
+
132
+ ### 方式四:install.sh(多智能体一键脚本)
133
+
134
+ ```text
135
+ bash install.sh --agent <name> # 装到指定智能体默认用户级目录
136
+ bash install.sh --dir <path> # 装到指定目录
137
+ bash install.sh --list # 列出智能体 -> 默认目录
125
138
  ```
126
- > 覆盖 17 类智能体,含国内 Trae / Qwen / Comate / CodeBuddy / Kimi。Windows 用户:装有 Git Bash 即可用;否则用方式三手动复制。
127
-
128
- ### 方式三:手动复制
129
- 把整个 yotta-logs 文件夹复制到目标智能体的 skills 目录。常见位置(用户级;Windows 用 %USERPROFILE%,Linux/macOS 用 ~):
130
-
131
- | 智能体 | 用户级目录 | 项目级目录 |
132
- |---|---|---|
133
- | Codex | %USERPROFILE%\.codex\skills\yotta-logs\ | .codex\skills\ |
134
- | Claude Code | %USERPROFILE%\.claude\skills\yotta-logs\ | .claude\skills\ |
135
- | Cursor | %USERPROFILE%\.cursor\skills\yotta-logs\ | .cursor\skills\ |
136
- | Windsurf | %USERPROFILE%\.codeium\windsurf\skills\yotta-logs\ | .windsurf\skills\ |
137
- | opencode | %USERPROFILE%\.config\opencode\skills\yotta-logs\ | .opencode\skills\ |
138
- | Gemini | %USERPROFILE%\.gemini\skills\yotta-logs\ | .gemini\skills\ |
139
- | Goose | %USERPROFILE%\.config\goose\skills\yotta-logs\ | .goose\skills\ |
140
- | Amp | %USERPROFILE%\.config\agents\skills\yotta-logs\ | .agents\skills\ |
141
- | Kiro | %USERPROFILE%\.kiro\skills\yotta-logs\ | .kiro\skills\ |
142
- | WorkBuddy | %USERPROFILE%\.workbuddy\skills\yotta-logs\ | .workbuddy\skills\ |
143
- | Trae Code CLI | %USERPROFILE%\.traecli\skills\yotta-logs\ | .traecli\skills\ |
144
- | Trae IDE(国内) | %USERPROFILE%\.trae-cn\skills\yotta-logs\ | .trae\skills\ |
145
- | Qwen Code | %USERPROFILE%\.qwen\skills\yotta-logs\ | .qwen\skills\ |
146
- | Comate | %USERPROFILE%\.comate\skills\yotta-logs\ | .comate\skills\ |
147
- | CodeBuddy | %USERPROFILE%\.codebuddy\skills\yotta-logs\ | .codebuddy\skills\ |
148
- | Kimi | %USERPROFILE%\.kimi\skills\yotta-logs\ | .kimi\skills\ |
149
- | 通用 AGENTS.md | %USERPROFILE%\.agents\skills\yotta-logs\ | .agents\skills\ |
150
-
151
- > Codex 默认目录若设置了环境变量 CODEX_HOME,以该变量为准;opencode 若设置 XDG_CONFIG_HOME 同理。.agents\skills 并非通用目录,仅 OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 等会读取,Claude Code 与 Codex 默认不读。不确定时用 --dir 指定,或让该智能体自行安装。
152
139
 
140
+ > 方式一走 npm 源(npmmirror / npmjs),不依赖 GitHub;方式二 / 三走 GitHub,国内无代理可能失败。
153
141
  ## 使用示例(AI 智能体)
154
142
 
155
143
  1. 将本仓库的 SKILL.md 接入任意 AI 智能体的技能/规则系统(见上方安装)。
@@ -174,9 +162,17 @@ bash install.sh --dir /path/to/skills
174
162
 
175
163
  ## 更新日志
176
164
 
165
+ - v0.3.0(2026-09-08):评测驱动完善——新增常见问题,安装器错误处理与退出码加固,并补齐安装器测试。
166
+
167
+ - v0.2.2(2026-08-29):安装方式统一为四方式(对齐发布规范 §3.3.1)——方式一 npx -y @yottameta/yotta-logs --agent / --dir(推荐,走 npm 源);方式二 git clone;方式三 GitHub Download ZIP;方式四 bash install.sh --agent/--dir/--list。移除旧式 GitHub 克隆安装器与全局安装(-g)推荐;中英 README 安装节同步。无功能变更。
168
+
177
169
  - v0.2.0(2026-08-27):多格式通用化——JSONL / 单文件 JSON / SQLite(opencode 等)/ Markdown(记忆 + 自由笔记)/ 二进制五大格式族,统一 Record + 字段别名归一 + 配置兜底,discover 全源登记,新增 --source / --kind / --format 过滤与默认检索范围(会话 + 结构化记忆开、自由笔记 / 二进制日志关)。详见 CHANGELOG.md。
178
170
  - v0.1.0(2026-08-27):首版——零依赖 JSONL 会话日志检索引擎(locate / scan / search / session / stats / tools / version + 默认脱敏 + sessions.json 别名 + 只读)。
179
171
 
172
+ ## 参考文档
173
+
174
+ - references/faq.md
175
+
180
176
  ## 许可证
181
177
 
182
178
  MIT © YottaMeta —— 详见 [LICENSE](./LICENSE)。
package/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: yotta-logs
3
- version: 0.2.1
3
+ version: 0.3.0
4
4
  description: 元史 —— 跨智能体的历史会话 / 记忆日志检索技能:零依赖检索 / 分析 JSONL、JSON、SQLite、Markdown 多格式会话与记忆文件,回溯旧对话与父会话上下文,为跨会话追溯提供原始日志依据。触发:用户问起先前聊过的内容 / 父会话 / 历史上下文、要查以前说过的结论、跨会话回溯某次讨论、需要从会话日志或记忆文件定位某段决策时。边界:仅读取本机自己的会话日志 / 记忆文件;不修改、不删除;只查本地不联网上传。
5
5
  license: MIT
6
6
  ---
@@ -84,6 +84,7 @@ python3 scripts/yotta_logs.py tools --dir /path/to/logs --format sqlite
84
84
  - references/format.md — 统一 Record 模型与各格式族读取规则
85
85
  - references/cli.md — CLI 子命令 / 参数 / 退出码 / JSON schema / 配置详解
86
86
  - references/security.md — 安全边界 / 脱敏规则 / 与元忆的差异化
87
+ - references/faq.md — 常见问题与安装排障
87
88
 
88
89
  ## 责任声明
89
90
 
package/bin/install.js CHANGED
@@ -1,163 +1,245 @@
1
- #!/usr/bin/env node
2
- /**
3
- * yotta-logs 跨平台安装器(YottaSkills)
4
- * 用法:
5
- * npx -y @yottameta/yotta-logs --agent <name> # 按智能体默认用户级目录安装(推荐)
6
- * npx -y @yottameta/yotta-logs --dir PATH # 装到指定目录(用户改了目录的智能体)
7
- * npx -y @yottameta/yotta-logs -g # 安装到全部已知智能体用户级目录
8
- * npx -y @yottameta/yotta-logs # 安装到检测到的项目级目录
9
- * npx -y @yottameta/yotta-logs --list # 列出智能体 -> 默认目录
10
- */
11
- 'use strict';
12
- const fs = require('fs');
13
- const path = require('path');
14
- const os = require('os');
15
-
16
- const SKILL_NAME = 'yotta-logs';
17
- const PKG_ROOT = path.join(__dirname, '..');
18
-
19
- // 智能体 -> 用户级默认技能目录(dirs 按优先级排列;--agent 装到第一个)
20
- // 依据官方文档:.agents/skills 并非通用目录,被 OpenCode / Cursor / Cline / Amp /
21
- // Kimi / Gemini CLI / GitHub Copilot 等读取;Claude Code 与 Codex 默认不读 .agents。
22
- const AGENT_DIRS = {
23
- claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
24
- cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
25
- codex: { label: 'Codex', dirs: ['.codex/skills'] }, // 特判:$CODEX_HOME/skills
26
- gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
27
- goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
28
- amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
29
- opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] }, // 特判:$XDG_CONFIG_HOME
30
- windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
31
- workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
32
- kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
33
- trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
34
- 'trae-cn': { label: 'Trae IDE(国内)', dirs: ['.trae-cn/skills'] },
35
- qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
36
- comate: { label: 'Comate 文心快码', dirs: ['.comate/skills'] },
37
- codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
38
- kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
39
- agents: { label: '通用 AGENTS.md', dirs: ['.agents/skills'] },
40
- };
41
-
42
- // Codex 用户级目录特判:优先 $CODEX_HOME/skills,否则 ~/.codex/skills
43
- function codexUserDir() {
44
- const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
45
- return path.join(base, 'skills');
46
- }
47
-
48
- // OpenCode 用户级目录特判:优先 $XDG_CONFIG_HOME/opencode/skills,否则 ~/.config/opencode/skills
49
- function opencodeUserDir() {
50
- const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
51
- return path.join(base, 'opencode', 'skills');
52
- }
53
-
54
- function resolveUserDir(rel) {
55
- if (rel === '.codex/skills') return codexUserDir();
56
- if (rel === '.config/opencode/skills') return opencodeUserDir();
57
- return path.join(os.homedir(), rel);
58
- }
59
-
60
- function installTo(dest) {
61
- const target = path.join(dest, SKILL_NAME);
62
- fs.mkdirSync(target, { recursive: true });
63
- copyDir(PKG_ROOT, target, new Set(['package.json', 'bin', 'node_modules', '.git']));
64
- console.log('installed -> ' + target);
65
- }
66
-
67
- function copyDir(src, dst, skip) {
68
- for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
69
- if (skip.has(entry.name)) continue;
70
- const s = path.join(src, entry.name);
71
- const d = path.join(dst, entry.name);
72
- if (entry.isDirectory()) {
73
- fs.mkdirSync(d, { recursive: true });
74
- copyDir(s, d, skip);
75
- } else if (entry.isFile()) {
76
- fs.copyFileSync(s, d);
77
- }
78
- }
79
- }
80
-
81
- function displayDir(rel) {
82
- if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
83
- return '~/' + rel;
84
- }
85
-
86
- function main() {
87
- const args = process.argv.slice(2);
88
- const isGlobal = args.includes('-g') || args.includes('--global');
89
- const list = args.includes('--list') || args.includes('-l');
90
- let explicitDir = null;
91
- const di = args.indexOf('--dir');
92
- if (di !== -1 && args[di + 1]) explicitDir = args[di + 1];
93
- let agent = null;
94
- const ai = args.indexOf('--agent');
95
- if (ai !== -1 && args[ai + 1]) agent = String(args[ai + 1]).toLowerCase();
96
-
97
- if (list) {
98
- console.log('智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):');
99
- for (const [key, v] of Object.entries(AGENT_DIRS)) {
100
- const resolved = v.dirs.map(displayDir);
101
- console.log(' ' + key.padEnd(10) + v.label.padEnd(18) + resolved.join('、'));
102
- }
103
- console.log('\n说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。');
104
- console.log('改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。');
105
- return;
106
- }
107
-
108
- if (explicitDir) { installTo(explicitDir); return; }
109
-
110
- if (agent) {
111
- const info = AGENT_DIRS[agent];
112
- if (!info) {
113
- console.log('未收录智能体: ' + agent + '。请用 --dir <路径> 指定技能目录。');
114
- console.log('可用: ' + Object.keys(AGENT_DIRS).join(', '));
115
- return;
116
- }
117
- installTo(resolveUserDir(info.dirs[0]));
118
- console.log('完成。');
119
- return;
120
- }
121
-
122
- if (isGlobal) {
123
- const seen = new Set();
124
- for (const v of Object.values(AGENT_DIRS)) {
125
- for (const d of v.dirs) {
126
- if (seen.has(d)) continue;
127
- seen.add(d);
128
- installTo(resolveUserDir(d));
129
- }
130
- }
131
- console.log('完成。');
132
- return;
133
- }
134
-
135
- const PROJECT_DIRS = [
136
- '.claude/skills',
137
- '.cursor/skills',
138
- '.codex/skills',
139
- '.config/goose/skills',
140
- '.config/agents/skills',
141
- '.opencode/skills',
142
- '.codeium/windsurf/skills',
143
- '.workbuddy/skills',
144
- '.kiro/skills',
145
- '.traecli/skills',
146
- '.gemini/skills',
147
- '.trae-cn/skills',
148
- '.qwen/skills',
149
- '.comate/skills',
150
- '.codebuddy/skills',
151
- '.kimi/skills',
152
- '.agents/skills',
153
- ];
154
- let installedAny = false;
155
- for (const d of PROJECT_DIRS) {
156
- if (fs.existsSync(d)) { installTo(d); installedAny = true; }
157
- }
158
- if (!installedAny) {
159
- console.log('未检测到项目级智能体目录。可手动复制,或用 --agent <name> / -g 装到用户级。');
160
- }
161
- }
162
-
163
- main();
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @yottameta/yotta-logs cross-platform installer.
4
+ *
5
+ * Usage:
6
+ * npx -y @yottameta/yotta-logs --agent <name>
7
+ * npx -y @yottameta/yotta-logs --dir <path>
8
+ * npx -y @yottameta/yotta-logs -g
9
+ * npx -y @yottameta/yotta-logs
10
+ * npx -y @yottameta/yotta-logs --list
11
+ */
12
+ 'use strict';
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const os = require('os');
17
+
18
+ const SKILL_NAME = 'yotta-logs';
19
+ const PKG_ROOT = path.join(__dirname, '..');
20
+ const COPY_SKIP = new Set(['package.json', 'bin', 'node_modules', '.git', '.github', 'test']);
21
+
22
+ const AGENT_DIRS = {
23
+ claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
24
+ cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
25
+ codex: { label: 'Codex', dirs: ['.codex/skills'] },
26
+ gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
27
+ goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
28
+ amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
29
+ opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] },
30
+ windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
31
+ workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
32
+ kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
33
+ trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
34
+ 'trae-cn': { label: 'Trae IDE', dirs: ['.trae-cn/skills'] },
35
+ qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
36
+ comate: { label: 'Comate', dirs: ['.comate/skills'] },
37
+ codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
38
+ kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
39
+ agents: { label: 'Generic AGENTS.md', dirs: ['.agents/skills'] },
40
+ };
41
+
42
+ class UsageError extends Error {}
43
+ class TargetError extends Error {}
44
+ class InstallError extends Error {}
45
+
46
+ function usage() {
47
+ console.log('yotta-logs installer');
48
+ console.log('');
49
+ console.log('Usage:');
50
+ console.log(' npx -y @yottameta/yotta-logs --agent <name> Install to an agent default directory');
51
+ console.log(' npx -y @yottameta/yotta-logs --dir <path> Install to a custom directory');
52
+ console.log(' npx -y @yottameta/yotta-logs -g Install to all known agent directories');
53
+ console.log(' npx -y @yottameta/yotta-logs Auto-detect project-level directories');
54
+ console.log(' npx -y @yottameta/yotta-logs --list List supported agent directories');
55
+ console.log('');
56
+ console.log('Options:');
57
+ console.log(' --agent <name> Agent key, see --list');
58
+ console.log(' --dir <path> Custom skills directory');
59
+ console.log(' -g, --global Install to all known user-level directories');
60
+ console.log(' --list, -l List supported agents');
61
+ console.log(' -h, --help Show this help');
62
+ }
63
+
64
+ function parseArgs(argv) {
65
+ const opts = { help: false, list: false, global: false, dir: null, agent: null };
66
+ for (let i = 0; i < argv.length; i++) {
67
+ const arg = argv[i];
68
+ if (arg === '--help' || arg === '-h') opts.help = true;
69
+ else if (arg === '--list' || arg === '-l') opts.list = true;
70
+ else if (arg === '--global' || arg === '-g') opts.global = true;
71
+ else if (arg === '--dir') {
72
+ const value = argv[++i];
73
+ if (!value) throw new UsageError('--dir requires a non-empty path');
74
+ opts.dir = value;
75
+ } else if (arg === '--agent') {
76
+ const value = argv[++i];
77
+ if (!value) throw new UsageError('--agent requires a non-empty name');
78
+ opts.agent = value.toLowerCase();
79
+ } else {
80
+ throw new UsageError('Unknown argument: ' + arg);
81
+ }
82
+ }
83
+ if (!opts.help) {
84
+ const selected = [opts.dir, opts.agent, opts.global].filter(Boolean).length;
85
+ if (selected > 1) throw new UsageError('Use only one of --dir, --agent, or -g');
86
+ }
87
+ return opts;
88
+ }
89
+
90
+ function codexUserDir() {
91
+ const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
92
+ return path.join(base, 'skills');
93
+ }
94
+
95
+ function opencodeUserDir() {
96
+ const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
97
+ return path.join(base, 'opencode', 'skills');
98
+ }
99
+
100
+ function resolveUserDir(rel) {
101
+ if (rel === '.codex/skills') return codexUserDir();
102
+ if (rel === '.config/opencode/skills') return opencodeUserDir();
103
+ return path.join(os.homedir(), rel);
104
+ }
105
+
106
+ function displayDir(rel) {
107
+ if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
108
+ return '~/' + rel;
109
+ }
110
+
111
+ function printList() {
112
+ console.log('Agent -> default skill directory:');
113
+ for (const [key, value] of Object.entries(AGENT_DIRS)) {
114
+ console.log(' ' + key.padEnd(12) + value.label.padEnd(20) + value.dirs.map(displayDir).join(', '));
115
+ }
116
+ console.log('');
117
+ console.log('Use --dir <path> for agents not listed. CODEX_HOME and XDG_CONFIG_HOME are respected.');
118
+ }
119
+
120
+ function assertSafeTarget(target) {
121
+ const rel = path.relative(PKG_ROOT, target);
122
+ if (rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel))) {
123
+ throw new UsageError('Target directory must be outside the skill source directory');
124
+ }
125
+ }
126
+
127
+ function copyDir(src, dst, skip) {
128
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
129
+ if (skip.has(entry.name)) continue;
130
+ const from = path.join(src, entry.name);
131
+ const to = path.join(dst, entry.name);
132
+ try {
133
+ if (entry.isDirectory()) {
134
+ fs.mkdirSync(to, { recursive: true });
135
+ copyDir(from, to, skip);
136
+ } else if (entry.isFile()) {
137
+ fs.copyFileSync(from, to);
138
+ }
139
+ } catch (err) {
140
+ throw new InstallError('Failed to copy ' + from + ' -> ' + to + ': ' + err.message);
141
+ }
142
+ }
143
+ }
144
+
145
+ function installTo(dest) {
146
+ if (!dest || typeof dest !== 'string') throw new UsageError('Destination directory is required');
147
+ const target = path.resolve(dest, SKILL_NAME);
148
+ assertSafeTarget(target);
149
+ try {
150
+ fs.mkdirSync(target, { recursive: true });
151
+ copyDir(PKG_ROOT, target, COPY_SKIP);
152
+ if (!fs.existsSync(path.join(target, 'SKILL.md'))) {
153
+ throw new InstallError('Installed directory is missing SKILL.md');
154
+ }
155
+ } catch (err) {
156
+ if (err instanceof UsageError || err instanceof InstallError) throw err;
157
+ throw new InstallError('Cannot install to ' + target + ': ' + err.message);
158
+ }
159
+ console.log('installed -> ' + target);
160
+ return target;
161
+ }
162
+
163
+ function projectDirs() {
164
+ return [
165
+ '.claude/skills',
166
+ '.cursor/skills',
167
+ '.codex/skills',
168
+ '.config/goose/skills',
169
+ '.config/agents/skills',
170
+ '.opencode/skills',
171
+ '.codeium/windsurf/skills',
172
+ '.workbuddy/skills',
173
+ '.kiro/skills',
174
+ '.traecli/skills',
175
+ '.gemini/skills',
176
+ '.trae-cn/skills',
177
+ '.qwen/skills',
178
+ '.comate/skills',
179
+ '.codebuddy/skills',
180
+ '.kimi/skills',
181
+ '.agents/skills',
182
+ ].filter((dir) => fs.existsSync(dir));
183
+ }
184
+
185
+ function run() {
186
+ const opts = parseArgs(process.argv.slice(2));
187
+ if (opts.help) { usage(); return; }
188
+ if (opts.list) { printList(); return; }
189
+
190
+ if (opts.dir) { installTo(opts.dir); return; }
191
+
192
+ if (opts.agent) {
193
+ const info = AGENT_DIRS[opts.agent];
194
+ if (!info) {
195
+ throw new UsageError('Unknown agent: ' + opts.agent + '. Available: ' + Object.keys(AGENT_DIRS).join(', ') + '. Use --dir for a custom directory.');
196
+ }
197
+ installTo(resolveUserDir(info.dirs[0]));
198
+ return;
199
+ }
200
+
201
+ if (opts.global) {
202
+ const seen = new Set();
203
+ let count = 0;
204
+ for (const value of Object.values(AGENT_DIRS)) {
205
+ for (const dir of value.dirs) {
206
+ if (seen.has(dir)) continue;
207
+ seen.add(dir);
208
+ installTo(resolveUserDir(dir));
209
+ count++;
210
+ }
211
+ }
212
+ console.log('Installed to ' + count + ' directories.');
213
+ return;
214
+ }
215
+
216
+ const dirs = projectDirs();
217
+ if (!dirs.length) {
218
+ throw new TargetError('No project-level agent directory detected. Use --agent <name> or --dir <path>.');
219
+ }
220
+ for (const dir of dirs) installTo(dir);
221
+ }
222
+
223
+ function main() {
224
+ try {
225
+ run();
226
+ } catch (err) {
227
+ if (err instanceof UsageError) {
228
+ console.error('Usage error: ' + err.message);
229
+ usage();
230
+ process.exitCode = 2;
231
+ } else if (err instanceof TargetError) {
232
+ console.error('Target error: ' + err.message);
233
+ process.exitCode = 4;
234
+ } else if (err instanceof InstallError) {
235
+ console.error('Install failed: ' + err.message);
236
+ console.error('Fix: check directory permissions and free space, then retry. Use --dir to choose another directory.');
237
+ process.exitCode = 1;
238
+ } else {
239
+ console.error('Unexpected error: ' + (err && err.message ? err.message : String(err)));
240
+ process.exitCode = 1;
241
+ }
242
+ }
243
+ }
244
+
245
+ main();
package/install.sh CHANGED
@@ -1,132 +1,132 @@
1
- #!/usr/bin/env bash
2
- # yotta-logs 多智能体安装脚本(YottaSkills 模板)
3
- # 用法:
4
- # bash install.sh --agent <name> # 按智能体默认用户级目录安装
5
- # bash install.sh --dir <path> # 装到指定目录(用户改过目录的智能体)
6
- # bash install.sh -g # 装到全部已知智能体用户级目录
7
- # bash install.sh # 检测并安装到已存在的项目级目录
8
- # bash install.sh --list # 列出智能体 -> 默认目录
9
- set -euo pipefail
10
-
11
- SKILL_NAME="yotta-logs"
12
- SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
- case "$(uname -s)" in
14
- MINGW*|MSYS*)
15
- SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -W)"
16
- ;;
17
- esac
18
-
19
- # 智能体 -> 用户级默认目录(--agent 装到第一个)
20
- # .agents/skills 并非通用目录:OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 读取。
21
- # 判断当前环境:Windows Git Bash 用 %USERPROFILE%,Unix 用 ~
22
- _IS_WINDOWS=0
23
- case "$(uname -s)" in
24
- MINGW*|MSYS*|CYGWIN*) _IS_WINDOWS=1 ;;
25
- esac
26
- dirs_for() {
27
- case "$1" in
28
- claude) echo ".claude/skills" ;;
29
- cursor) echo ".cursor/skills .agents/skills" ;;
30
- codex) echo "__CODEX__" ;;
31
- gemini) echo ".gemini/skills .agents/skills" ;;
32
- goose) echo ".config/goose/skills .agents/skills" ;;
33
- amp) echo ".config/agents/skills .agents/skills" ;;
34
- opencode) echo "__OPENCODE__" ;;
35
- windsurf) echo ".codeium/windsurf/skills" ;;
36
- workbuddy) echo ".workbuddy/skills" ;;
37
- kiro) echo ".kiro/skills" ;;
38
- trae) echo ".traecli/skills" ;;
39
- trae-cn) echo ".trae-cn/skills" ;;
40
- qwen) echo ".qwen/skills" ;;
41
- comate) echo ".comate/skills" ;;
42
- codebuddy) echo ".codebuddy/skills" ;;
43
- kimi) echo ".kimi/skills" ;;
44
- agents) echo ".agents/skills" ;;
45
- *) return 1 ;;
46
- esac
47
- }
48
-
49
- codex_dir() {
50
- if [ -n "${CODEX_HOME:-}" ]; then printf '%s' "$CODEX_HOME/skills"; else printf '%s' "$HOME/.codex/skills"; fi
51
- }
52
- opencode_dir() {
53
- if [ -n "${XDG_CONFIG_HOME:-}" ]; then printf '%s' "$XDG_CONFIG_HOME/opencode/skills"; else printf '%s' "$HOME/.config/opencode/skills"; fi
54
- }
55
- resolve_user() {
56
- case "$1" in
57
- __CODEX__) codex_dir ;;
58
- __OPENCODE__) opencode_dir ;;
59
- *) printf '%s' "$HOME/$1" ;;
60
- esac
61
- }
62
-
63
- install_to() {
64
- mkdir -p "$1/$SKILL_NAME"
65
- cp -r "$SOURCE_DIR/." "$1/$SKILL_NAME/"
66
- rm -rf "$1/$SKILL_NAME/.git"
67
- echo "installed -> $1/$SKILL_NAME"
68
- }
69
-
70
- list() {
71
- echo "智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):"
72
- for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
73
- local dirs first
74
- dirs="$(dirs_for "$a")"
75
- first="${dirs%% *}"
76
- case "$first" in
77
- __CODEX__) first=".codex/skills" ;;
78
- __OPENCODE__) first=".config/opencode/skills" ;;
79
- esac
80
- if [ "$_IS_WINDOWS" = "1" ]; then
81
- first="%USERPROFILE%\\${first//\//\\}"
82
- else
83
- first="~/$first"
84
- fi
85
- printf ' %-10s %s\n' "$a" "$first"
86
- done
87
- echo '说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。'
88
- echo '改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。'
89
- }
90
-
91
- main() {
92
- local agent="" dir="" global=0 show_list=0
93
- while [ $# -gt 0 ]; do
94
- case "$1" in
95
- --agent) shift; agent="${1:-}" ;;
96
- --dir) shift; dir="${1:-}" ;;
97
- -g|--global) global=1 ;;
98
- --list|-l) show_list=1 ;;
99
- *) echo "未知参数: $1" >&2; exit 2 ;;
100
- esac
101
- shift
102
- done
103
-
104
- if [ "$show_list" = "1" ]; then list; return; fi
105
- if [ -n "$dir" ]; then install_to "$dir"; echo "完成。"; return; fi
106
- if [ -n "$agent" ]; then
107
- local dirs first
108
- if ! dirs="$(dirs_for "$agent")"; then
109
- echo "未收录智能体: $agent。请用 --dir <路径> 指定技能目录。" >&2; exit 2
110
- fi
111
- first="${dirs%% *}"
112
- install_to "$(resolve_user "$first")"; echo "完成。"; return
113
- fi
114
- if [ "$global" = "1" ]; then
115
- echo "安装到全部已知智能体用户级目录..."
116
- local dirs rel
117
- for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
118
- dirs="$(dirs_for "$a")"
119
- for rel in $dirs; do install_to "$(resolve_user "$rel")"; done
120
- done
121
- echo "完成。"; return
122
- fi
123
- local installed=0 d
124
- for d in .claude/skills .cursor/skills .codex/skills .config/goose/skills .config/agents/skills .opencode/skills .codeium/windsurf/skills .workbuddy/skills .kiro/skills .traecli/skills .gemini/skills .trae-cn/skills .qwen/skills .comate/skills .codebuddy/skills .kimi/skills .agents/skills; do
125
- if [ -d "$d" ]; then install_to "$d"; installed=1; fi
126
- done
127
- if [ "$installed" = "0" ]; then
128
- echo "未检测到项目级智能体目录。可用 --agent <name> / -g 装到用户级,或 --dir 指定。"
129
- fi
130
- }
131
-
1
+ #!/usr/bin/env bash
2
+ # yotta-logs 多智能体安装脚本(YottaSkills 模板)
3
+ # 用法:
4
+ # bash install.sh --agent <name> # 按智能体默认用户级目录安装
5
+ # bash install.sh --dir <path> # 装到指定目录(用户改过目录的智能体)
6
+ # bash install.sh -g # 装到全部已知智能体用户级目录
7
+ # bash install.sh # 检测并安装到已存在的项目级目录
8
+ # bash install.sh --list # 列出智能体 -> 默认目录
9
+ set -euo pipefail
10
+
11
+ SKILL_NAME="yotta-logs"
12
+ SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ case "$(uname -s)" in
14
+ MINGW*|MSYS*)
15
+ SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -W)"
16
+ ;;
17
+ esac
18
+
19
+ # 智能体 -> 用户级默认目录(--agent 装到第一个)
20
+ # .agents/skills 并非通用目录:OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 读取。
21
+ # 判断当前环境:Windows Git Bash 用 %USERPROFILE%,Unix 用 ~
22
+ _IS_WINDOWS=0
23
+ case "$(uname -s)" in
24
+ MINGW*|MSYS*|CYGWIN*) _IS_WINDOWS=1 ;;
25
+ esac
26
+ dirs_for() {
27
+ case "$1" in
28
+ claude) echo ".claude/skills" ;;
29
+ cursor) echo ".cursor/skills .agents/skills" ;;
30
+ codex) echo "__CODEX__" ;;
31
+ gemini) echo ".gemini/skills .agents/skills" ;;
32
+ goose) echo ".config/goose/skills .agents/skills" ;;
33
+ amp) echo ".config/agents/skills .agents/skills" ;;
34
+ opencode) echo "__OPENCODE__" ;;
35
+ windsurf) echo ".codeium/windsurf/skills" ;;
36
+ workbuddy) echo ".workbuddy/skills" ;;
37
+ kiro) echo ".kiro/skills" ;;
38
+ trae) echo ".traecli/skills" ;;
39
+ trae-cn) echo ".trae-cn/skills" ;;
40
+ qwen) echo ".qwen/skills" ;;
41
+ comate) echo ".comate/skills" ;;
42
+ codebuddy) echo ".codebuddy/skills" ;;
43
+ kimi) echo ".kimi/skills" ;;
44
+ agents) echo ".agents/skills" ;;
45
+ *) return 1 ;;
46
+ esac
47
+ }
48
+
49
+ codex_dir() {
50
+ if [ -n "${CODEX_HOME:-}" ]; then printf '%s' "$CODEX_HOME/skills"; else printf '%s' "$HOME/.codex/skills"; fi
51
+ }
52
+ opencode_dir() {
53
+ if [ -n "${XDG_CONFIG_HOME:-}" ]; then printf '%s' "$XDG_CONFIG_HOME/opencode/skills"; else printf '%s' "$HOME/.config/opencode/skills"; fi
54
+ }
55
+ resolve_user() {
56
+ case "$1" in
57
+ __CODEX__) codex_dir ;;
58
+ __OPENCODE__) opencode_dir ;;
59
+ *) printf '%s' "$HOME/$1" ;;
60
+ esac
61
+ }
62
+
63
+ install_to() {
64
+ mkdir -p "$1/$SKILL_NAME"
65
+ cp -r "$SOURCE_DIR/." "$1/$SKILL_NAME/"
66
+ rm -rf "$1/$SKILL_NAME/.git"
67
+ echo "installed -> $1/$SKILL_NAME"
68
+ }
69
+
70
+ list() {
71
+ echo "智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):"
72
+ for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
73
+ local dirs first
74
+ dirs="$(dirs_for "$a")"
75
+ first="${dirs%% *}"
76
+ case "$first" in
77
+ __CODEX__) first=".codex/skills" ;;
78
+ __OPENCODE__) first=".config/opencode/skills" ;;
79
+ esac
80
+ if [ "$_IS_WINDOWS" = "1" ]; then
81
+ first="%USERPROFILE%\\${first//\//\\}"
82
+ else
83
+ first="~/$first"
84
+ fi
85
+ printf ' %-10s %s\n' "$a" "$first"
86
+ done
87
+ echo '说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。'
88
+ echo '改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。'
89
+ }
90
+
91
+ main() {
92
+ local agent="" dir="" global=0 show_list=0
93
+ while [ $# -gt 0 ]; do
94
+ case "$1" in
95
+ --agent) shift; agent="${1:-}" ;;
96
+ --dir) shift; dir="${1:-}" ;;
97
+ -g|--global) global=1 ;;
98
+ --list|-l) show_list=1 ;;
99
+ *) echo "未知参数: $1" >&2; exit 2 ;;
100
+ esac
101
+ shift
102
+ done
103
+
104
+ if [ "$show_list" = "1" ]; then list; return; fi
105
+ if [ -n "$dir" ]; then install_to "$dir"; echo "完成。"; return; fi
106
+ if [ -n "$agent" ]; then
107
+ local dirs first
108
+ if ! dirs="$(dirs_for "$agent")"; then
109
+ echo "未收录智能体: $agent。请用 --dir <路径> 指定技能目录。" >&2; exit 2
110
+ fi
111
+ first="${dirs%% *}"
112
+ install_to "$(resolve_user "$first")"; echo "完成。"; return
113
+ fi
114
+ if [ "$global" = "1" ]; then
115
+ echo "安装到全部已知智能体用户级目录..."
116
+ local dirs rel
117
+ for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
118
+ dirs="$(dirs_for "$a")"
119
+ for rel in $dirs; do install_to "$(resolve_user "$rel")"; done
120
+ done
121
+ echo "完成。"; return
122
+ fi
123
+ local installed=0 d
124
+ for d in .claude/skills .cursor/skills .codex/skills .config/goose/skills .config/agents/skills .opencode/skills .codeium/windsurf/skills .workbuddy/skills .kiro/skills .traecli/skills .gemini/skills .trae-cn/skills .qwen/skills .comate/skills .codebuddy/skills .kimi/skills .agents/skills; do
125
+ if [ -d "$d" ]; then install_to "$d"; installed=1; fi
126
+ done
127
+ if [ "$installed" = "0" ]; then
128
+ echo "未检测到项目级智能体目录。可用 --agent <name> / -g 装到用户级,或 --dir 指定。"
129
+ fi
130
+ }
131
+
132
132
  main "$@"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yottameta/yotta-logs",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Yuanshi — a skill for retrieving historical session / memory logs across AI agents: zero-dependency search and analysis of JSONL, JSON, SQLite and Markdown session & memory files (unified Record + field-alias normalization + config fallback), with full source discovery to recall past conversations and parent-session context. Triggers when the user asks about previously discussed content / a parent session / historical context, wants to look up an earlier conclusion, traces a past discussion across sessions, or needs to locate a decision in session logs or memory files. Boundaries: reads only the local agent's own session logs / memory files; never modifies or deletes records; local-only, never uploaded.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -18,7 +18,10 @@
18
18
  "bin",
19
19
  "NOTICE",
20
20
  "CHANGELOG.md",
21
- "README.zh-CN.md"
21
+ "README.zh-CN.md",
22
+ "!scripts/__pycache__",
23
+ "!**/__pycache__",
24
+ "!**/*.pyc"
22
25
  ],
23
26
  "repository": {
24
27
  "type": "git",
@@ -29,5 +32,8 @@
29
32
  },
30
33
  "bin": {
31
34
  "yotta-logs": "bin/install.js"
35
+ },
36
+ "scripts": {
37
+ "test": "node --test \"test/*.test.js\" && python scripts/test_yotta_logs.py"
32
38
  }
33
39
  }
@@ -120,7 +120,7 @@
120
120
 
121
121
  引擎零改动即可接入怪格式(个别 agent 私有 schema 用列映射接入)。
122
122
 
123
- ## 六、默认检索范围(2026-08-27 老张拍板)
123
+ ## 六、默认检索范围
124
124
 
125
125
  - 会话源(kind=session)+ 结构化记忆源(kind=memory)**默认开**;
126
126
  - 自由笔记(kind=note)与二进制日志(kind=log)**默认关**,可 `--kind note` / `--kind log` 显式开;
@@ -0,0 +1,54 @@
1
+ # 元史常见问题
2
+
3
+ ## 速查索引
4
+
5
+ - **格式**:支持哪些格式 · SQLite 要装依赖吗
6
+ - **范围**:默认扫哪里 · 自由笔记怎么开
7
+ - **检索**:查不到怎么办 · 如何精确到某个会话
8
+ - **安全**:会修改日志吗 · 如何脱敏
9
+
10
+ ---
11
+
12
+ ## 1. 支持哪些格式?
13
+
14
+ JSONL、单文件 JSON、SQLite、Markdown(结构化记忆与自由笔记)、部分二进制文件的标题回退。
15
+
16
+ ## 2. SQLite 需要额外依赖吗?
17
+
18
+ 不需要,使用 Python 标准库 `sqlite3`,只读打开。
19
+
20
+ ## 3. 默认扫描范围是什么?
21
+
22
+ 会话源与结构化记忆源默认开启;自由笔记和二进制日志默认关闭,可显式开启。
23
+
24
+ ## 4. 如何只查某个目录?
25
+
26
+ 用 `--dir <path>` 指定目录或文件;目录会自动嗅探格式族。
27
+
28
+ ## 5. 自由笔记怎么开启?
29
+
30
+ 用 `--kind note` 或在配置中调整默认范围。
31
+
32
+ ## 6. 查不到怎么办?
33
+
34
+ 先 `locate` 确认源是否存在,再 `scan` 查看可检索内容;确认关键词、日期、会话过滤是否过窄。
35
+
36
+ ## 7. 如何精确提取某个会话?
37
+
38
+ 先 `search` 获取会话 ID,再 `session <sid>` 提取原文。
39
+
40
+ ## 8. 会修改或删除日志吗?
41
+
42
+ 不会。所有操作只读。
43
+
44
+ ## 9. 输出会泄露敏感信息吗?
45
+
46
+ 默认自动脱敏疑似密钥、token、口令;如需原文可用 `--no-redact`,但请谨慎外传。
47
+
48
+ ## 10. JSON 输出有什么用?
49
+
50
+ 包含来源、会话 ID、行号、时间戳、角色等结构化字段,便于程序核对和自动化处理。
51
+
52
+ ## 11. 安装失败怎么办?
53
+
54
+ 确认智能体目录是否正确;未收录智能体用 `--dir` 指定路径;权限问题请检查目标目录写权限。
@@ -64,7 +64,7 @@ try:
64
64
  except Exception:
65
65
  pass
66
66
 
67
- VERSION = "0.2.1"
67
+ VERSION = "0.3.0"
68
68
  TOOL_NAME = "yotta-logs"
69
69
  TOOL_CN = "元史"
70
70
  DEFAULT_LIMIT = 50