@poping/yome 0.0.2 → 0.0.3

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.
Files changed (185) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +11 -0
  3. package/README.md +308 -27
  4. package/README.zh-CN.md +335 -0
  5. package/dist/agent.d.ts +24 -2
  6. package/dist/agent.js +34 -2
  7. package/dist/agent.js.map +1 -1
  8. package/dist/context.d.ts +2 -0
  9. package/dist/context.js +116 -11
  10. package/dist/context.js.map +1 -1
  11. package/dist/index.js +147 -9
  12. package/dist/index.js.map +1 -1
  13. package/dist/llm.js +45 -2
  14. package/dist/llm.js.map +1 -1
  15. package/dist/loops/chain.js +8 -0
  16. package/dist/loops/chain.js.map +1 -1
  17. package/dist/loops/evaluator.js +8 -0
  18. package/dist/loops/evaluator.js.map +1 -1
  19. package/dist/loops/orchestrator.js +8 -0
  20. package/dist/loops/orchestrator.js.map +1 -1
  21. package/dist/loops/parallel.js.map +1 -1
  22. package/dist/loops/route.js +8 -0
  23. package/dist/loops/route.js.map +1 -1
  24. package/dist/loops/simple.js +15 -0
  25. package/dist/loops/simple.js.map +1 -1
  26. package/dist/permissions/index.d.ts +1 -1
  27. package/dist/permissions/index.js +1 -1
  28. package/dist/permissions/index.js.map +1 -1
  29. package/dist/permissions/loader.d.ts +20 -1
  30. package/dist/permissions/loader.js +51 -0
  31. package/dist/permissions/loader.js.map +1 -1
  32. package/dist/redact.d.ts +56 -0
  33. package/dist/redact.js +191 -0
  34. package/dist/redact.js.map +1 -0
  35. package/dist/skills/runner/applescript.d.ts +49 -0
  36. package/dist/skills/runner/applescript.js +100 -0
  37. package/dist/skills/runner/applescript.js.map +1 -0
  38. package/dist/skills/runner/dispatcher.d.ts +57 -0
  39. package/dist/skills/runner/dispatcher.js +407 -0
  40. package/dist/skills/runner/dispatcher.js.map +1 -0
  41. package/dist/skills/runner/kernel.d.ts +8 -0
  42. package/dist/skills/runner/kernel.js +732 -0
  43. package/dist/skills/runner/kernel.js.map +1 -0
  44. package/dist/skills/runner/tokenizer.d.ts +36 -0
  45. package/dist/skills/runner/tokenizer.js +177 -0
  46. package/dist/skills/runner/tokenizer.js.map +1 -0
  47. package/dist/threadCli.d.ts +11 -0
  48. package/dist/threadCli.js +177 -0
  49. package/dist/threadCli.js.map +1 -0
  50. package/dist/threadShare.d.ts +21 -0
  51. package/dist/threadShare.js +121 -0
  52. package/dist/threadShare.js.map +1 -0
  53. package/dist/threadSubmit.d.ts +32 -0
  54. package/dist/threadSubmit.js +199 -0
  55. package/dist/threadSubmit.js.map +1 -0
  56. package/dist/tools/bash.js +68 -13
  57. package/dist/tools/bash.js.map +1 -1
  58. package/dist/tools/index.d.ts +22 -2
  59. package/dist/tools/index.js +41 -5
  60. package/dist/tools/index.js.map +1 -1
  61. package/dist/tools/skillCall.d.ts +2 -0
  62. package/dist/tools/skillCall.js +77 -0
  63. package/dist/tools/skillCall.js.map +1 -0
  64. package/dist/ui/AgentPicker.js +3 -3
  65. package/dist/ui/AgentPicker.js.map +1 -1
  66. package/dist/ui/App.js +214 -61
  67. package/dist/ui/App.js.map +1 -1
  68. package/dist/ui/Banner.d.ts +2 -1
  69. package/dist/ui/Banner.js +23 -4
  70. package/dist/ui/Banner.js.map +1 -1
  71. package/dist/ui/InputBar.js +6 -3
  72. package/dist/ui/InputBar.js.map +1 -1
  73. package/dist/ui/Markdown.d.ts +2 -2
  74. package/dist/ui/Markdown.js +22 -7
  75. package/dist/ui/Markdown.js.map +1 -1
  76. package/dist/ui/MarketplacePicker.d.ts +7 -0
  77. package/dist/ui/MarketplacePicker.js +122 -0
  78. package/dist/ui/MarketplacePicker.js.map +1 -0
  79. package/dist/ui/MessageList.d.ts +4 -1
  80. package/dist/ui/MessageList.js +72 -7
  81. package/dist/ui/MessageList.js.map +1 -1
  82. package/dist/ui/ModelPicker.js +4 -4
  83. package/dist/ui/ModelPicker.js.map +1 -1
  84. package/dist/ui/PermissionPrompt.d.ts +16 -4
  85. package/dist/ui/PermissionPrompt.js +60 -15
  86. package/dist/ui/PermissionPrompt.js.map +1 -1
  87. package/dist/ui/SessionPicker.js +2 -2
  88. package/dist/ui/SessionPicker.js.map +1 -1
  89. package/dist/ui/ShimmerText.d.ts +8 -0
  90. package/dist/ui/ShimmerText.js +40 -0
  91. package/dist/ui/ShimmerText.js.map +1 -0
  92. package/dist/ui/Spinner.js +3 -9
  93. package/dist/ui/Spinner.js.map +1 -1
  94. package/dist/ui/TogglePicker.js +4 -4
  95. package/dist/ui/TogglePicker.js.map +1 -1
  96. package/dist/ui/ToolResult.js +6 -0
  97. package/dist/ui/ToolResult.js.map +1 -1
  98. package/dist/ui/UnifiedSkillsPicker.d.ts +10 -0
  99. package/dist/ui/UnifiedSkillsPicker.js +63 -0
  100. package/dist/ui/UnifiedSkillsPicker.js.map +1 -0
  101. package/dist/ui/animation.d.ts +3 -0
  102. package/dist/ui/animation.js +48 -0
  103. package/dist/ui/animation.js.map +1 -0
  104. package/dist/ui/useThrottledStream.d.ts +7 -0
  105. package/dist/ui/useThrottledStream.js +63 -0
  106. package/dist/ui/useThrottledStream.js.map +1 -0
  107. package/dist/yomeSkills/auth.d.ts +20 -0
  108. package/dist/yomeSkills/auth.js +70 -0
  109. package/dist/yomeSkills/auth.js.map +1 -0
  110. package/dist/yomeSkills/blacklist.d.ts +33 -0
  111. package/dist/yomeSkills/blacklist.js +101 -0
  112. package/dist/yomeSkills/blacklist.js.map +1 -0
  113. package/dist/yomeSkills/capabilities.d.ts +54 -0
  114. package/dist/yomeSkills/capabilities.js +175 -0
  115. package/dist/yomeSkills/capabilities.js.map +1 -0
  116. package/dist/yomeSkills/capabilityGuard.d.ts +31 -0
  117. package/dist/yomeSkills/capabilityGuard.js +113 -0
  118. package/dist/yomeSkills/capabilityGuard.js.map +1 -0
  119. package/dist/yomeSkills/cli.d.ts +17 -0
  120. package/dist/yomeSkills/cli.js +477 -0
  121. package/dist/yomeSkills/cli.js.map +1 -0
  122. package/dist/yomeSkills/devLink.d.ts +17 -0
  123. package/dist/yomeSkills/devLink.js +91 -0
  124. package/dist/yomeSkills/devLink.js.map +1 -0
  125. package/dist/yomeSkills/doctor.d.ts +13 -0
  126. package/dist/yomeSkills/doctor.js +152 -0
  127. package/dist/yomeSkills/doctor.js.map +1 -0
  128. package/dist/yomeSkills/enable.d.ts +8 -0
  129. package/dist/yomeSkills/enable.js +67 -0
  130. package/dist/yomeSkills/enable.js.map +1 -0
  131. package/dist/yomeSkills/hubPing.d.ts +1 -0
  132. package/dist/yomeSkills/hubPing.js +41 -0
  133. package/dist/yomeSkills/hubPing.js.map +1 -0
  134. package/dist/yomeSkills/install.d.ts +18 -0
  135. package/dist/yomeSkills/install.js +143 -0
  136. package/dist/yomeSkills/install.js.map +1 -0
  137. package/dist/yomeSkills/installGithub.d.ts +26 -0
  138. package/dist/yomeSkills/installGithub.js +192 -0
  139. package/dist/yomeSkills/installGithub.js.map +1 -0
  140. package/dist/yomeSkills/installMeta.d.ts +8 -0
  141. package/dist/yomeSkills/installMeta.js +76 -0
  142. package/dist/yomeSkills/installMeta.js.map +1 -0
  143. package/dist/yomeSkills/integrity.d.ts +26 -0
  144. package/dist/yomeSkills/integrity.js +107 -0
  145. package/dist/yomeSkills/integrity.js.map +1 -0
  146. package/dist/yomeSkills/invoke.d.ts +29 -0
  147. package/dist/yomeSkills/invoke.js +103 -0
  148. package/dist/yomeSkills/invoke.js.map +1 -0
  149. package/dist/yomeSkills/list.d.ts +11 -0
  150. package/dist/yomeSkills/list.js +55 -0
  151. package/dist/yomeSkills/list.js.map +1 -0
  152. package/dist/yomeSkills/login.d.ts +41 -0
  153. package/dist/yomeSkills/login.js +221 -0
  154. package/dist/yomeSkills/login.js.map +1 -0
  155. package/dist/yomeSkills/manifest.d.ts +60 -0
  156. package/dist/yomeSkills/manifest.js +47 -0
  157. package/dist/yomeSkills/manifest.js.map +1 -0
  158. package/dist/yomeSkills/paths.d.ts +13 -0
  159. package/dist/yomeSkills/paths.js +33 -0
  160. package/dist/yomeSkills/paths.js.map +1 -0
  161. package/dist/yomeSkills/publish.d.ts +16 -0
  162. package/dist/yomeSkills/publish.js +109 -0
  163. package/dist/yomeSkills/publish.js.map +1 -0
  164. package/dist/yomeSkills/rollback.d.ts +10 -0
  165. package/dist/yomeSkills/rollback.js +83 -0
  166. package/dist/yomeSkills/rollback.js.map +1 -0
  167. package/dist/yomeSkills/search.d.ts +21 -0
  168. package/dist/yomeSkills/search.js +31 -0
  169. package/dist/yomeSkills/search.js.map +1 -0
  170. package/dist/yomeSkills/skillsIndex.d.ts +36 -0
  171. package/dist/yomeSkills/skillsIndex.js +111 -0
  172. package/dist/yomeSkills/skillsIndex.js.map +1 -0
  173. package/dist/yomeSkills/unified.d.ts +53 -0
  174. package/dist/yomeSkills/unified.js +187 -0
  175. package/dist/yomeSkills/unified.js.map +1 -0
  176. package/dist/yomeSkills/uninstall.d.ts +7 -0
  177. package/dist/yomeSkills/uninstall.js +22 -0
  178. package/dist/yomeSkills/uninstall.js.map +1 -0
  179. package/dist/yomeSkills/update.d.ts +18 -0
  180. package/dist/yomeSkills/update.js +75 -0
  181. package/dist/yomeSkills/update.js.map +1 -0
  182. package/dist/yomeSkills/validate.d.ts +11 -0
  183. package/dist/yomeSkills/validate.js +99 -0
  184. package/dist/yomeSkills/validate.js.map +1 -0
  185. package/package.json +14 -5
@@ -0,0 +1,335 @@
1
+ <div align="center">
2
+
3
+ <img src=".assets/yome-icon.png" width="120" alt="Yome" />
4
+
5
+ # YOME AGENT
6
+
7
+ ### Empower Kernel · 赋能内核
8
+
9
+ *主动式上下文 · 原生应用赋能 · 智能 Bash 内核*
10
+ *让 AI 真正感知你、连接你、为你交付的开源底座。*
11
+
12
+ [English](./README.md) · [简体中文](./README.zh-CN.md)
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ Yome Agent 不是又一个 chat agent。它是 [Yome](https://yome.work) 的开源底盘 —— 一台把 LLM、你的设备、你机器上的原生 app 编织成统一运行环境的 **Empower Kernel**。
19
+
20
+ 模型已经很强了。它住在你 12 个 context 之外的某处。今天你是 context 与 tool 之间的 router; 80% 的工作日花在搬运而不是创造。Yome Agent 的存在是为了把这层路由职责从你手里拿走 —— 不是再造一个工具,而是让你已有的工具醒来。
21
+
22
+ ---
23
+
24
+ ## 60 秒上手
25
+
26
+ ```bash
27
+ # 安装
28
+ npm install -g @poping/yome
29
+
30
+ # 配置 (写入 ~/.yome/config.json)
31
+ yome --key sk-... --base-url https://your.endpoint --model your-model
32
+
33
+ # 运行
34
+ yome # 交互式 REPL
35
+ yome "总结一下 package.json" # 一次性
36
+
37
+ # 安装第一个原生 skill (PowerPoint 编辑器)
38
+ yome skill install github:Whopus/yome-skill-ppt
39
+ yome skill list
40
+ ```
41
+
42
+ `yome` 跑起来后,试一下:
43
+
44
+ ```
45
+ > 帮我新建一个 ppt,标题 "Q3 Review",保存到桌面
46
+ ```
47
+
48
+ 模型会自己用 Bash 调 `ppt new ~/Desktop/q3.pptx` → `ppt title 1 --text="Q3 Review"` → `ppt save`。Microsoft PowerPoint 在你桌面打开,文件落地。这就是 Empower Kernel 的最小闭环。
49
+
50
+ ---
51
+
52
+ ## 三大引擎
53
+
54
+ Yome Agent 由三个相互独立、又彼此咬合的引擎组成。每一个都是 Yome 商业蓝图中 *Agentic Empower Intelligence* 的一块 ground truth。
55
+
56
+ ---
57
+
58
+ ### 1. Agentic Contextual Engine · 主动式上下文引擎
59
+
60
+ > Context 不是一段静态字符串,而是一条 *living continuum*。
61
+
62
+ Agent loop 不能只活在用户敲下 Enter 的那 30 秒;它应当 always-on, never-forget, ambient。这是 Yome Agent 与传统 chat-style coding agent 的根本分野。
63
+
64
+ | 能力 | 含义 |
65
+ |---|---|
66
+ | **Daemon · 守护进程** | Agent 长驻后台,跨会话保持状态,不再"开个窗口才会思考" |
67
+ | **Live compaction · 即时压缩** | 长会话自动压缩历史,token 永远不爆,记忆永远不丢 |
68
+ | **Custom missions · 定制任务** | 把"每周一上午整理周报"这种重复任务沉淀成可复用 mission |
69
+ | **Async agent · 异步 agent** | 后台跑长任务,完成后主动 push 通知,而不是阻塞你的 prompt |
70
+
71
+ **当前可用:**
72
+
73
+ ```bash
74
+ yome thread list # 列出当前 cwd 的历史会话
75
+ yome thread share <session-id> --skill=<slug> # 构建脱敏的 case bundle
76
+ yome thread submit <bundle-dir> --skill=<slug> # 作为 PR 发布 (需要 gh CLI)
77
+ ```
78
+
79
+ 会话 / 历史压缩 / case bundle 这三件已落地。Daemon、custom missions、async agent 在 `next` 分支推进。
80
+
81
+ ---
82
+
83
+ ### 2. Agentic Native Skill · 原生应用赋能
84
+
85
+ > 真正稀缺的能力不是"另一个 prompt 模板",也不是"远端跑的 MCP wrapper"。是**调起你机器上已经装好的那些原生 app**,让它们听懂 agent 的指令。
86
+
87
+ 我们把这种 skill 叫 **Native Skill**:
88
+
89
+ | 类型 | 跑在哪 | 干什么 | 例子 |
90
+ |---|---|---|---|
91
+ | **Prompt Skill** | LLM context window | 加载一段 markdown 提示模板 | code-review, web-research |
92
+ | **MCP Server** | 远端进程 | 暴露 JSON-RPC tool 给 LLM | github MCP, filesystem MCP |
93
+ | **Native Skill** *(Yome)* | 你本机 (macOS / Win / Linux) | 通过 AppleScript / Win32 / DBus 驱动原生 app | ppt, xl, cal, mail, rem |
94
+
95
+ **安装 / 管理:**
96
+
97
+ ```bash
98
+ yome skill install github:Whopus/yome-skill-ppt
99
+ yome skill perms @yome/ppt # 查看授予的 capability
100
+ yome skill perms @yome/ppt --revoke=fs:write # 撤销某项
101
+ yome skill validate # 校验当前目录的 skill
102
+ yome skill publish # 发布到 hub (需要 `yome login`)
103
+ ```
104
+
105
+ **Capability 模型。** 每个 skill 必须在 manifest 里声明它需要的 OS 资源,用户在安装时显式 grant。这不是 prompt 里的"请求权限",是真正的 sandbox gate:
106
+
107
+ | Capability | 含义 |
108
+ |---|---|
109
+ | `applescript` | 可执行 AppleScript (仅 macOS) |
110
+ | `fs:read` / `fs:write` / `fs:delete` | 文件系统访问,作用域受限 |
111
+ | `network` | 出站网络 |
112
+ | `shell` | 任意 shell 命令 (危险,默认拒绝) |
113
+
114
+ 未授权的能力一律返回 `capability not granted: …`,模型看到错误会主动让你 grant,而不是默默失败。
115
+
116
+ **当前 Native Skills:**
117
+
118
+ | Skill | Domain | 状态 |
119
+ |---|---|---|
120
+ | `@yome/ppt` | `ppt` | **stable** — 16 个 action,batch-ready,4 套主题 (`--doc`) |
121
+ | `@yome/xl` | `xl` | beta |
122
+ | `@yome/cal` | `cal` | beta |
123
+ | `@yome/rem` | `rem` | beta |
124
+ | `@yome/mail` | `mail` | alpha |
125
+
126
+ ---
127
+
128
+ ### 3. Agentic Bash Kernel · 智能 Bash 内核
129
+
130
+ > Bash 即接口,skill 即 verb。**用户在 shell 里怎么用,模型在 Bash tool 里就怎么用。** 一套语法,两个用户。
131
+
132
+ 模型不需要学习新工具:
133
+
134
+ ```jsonc
135
+ // 模型工具列表里只有一个 Bash:
136
+ { "name": "Bash", "description": "Run a shell command." }
137
+
138
+ // 模型想加一张幻灯片时这样发:
139
+ Bash({ "command": "ppt slide.add" })
140
+
141
+ // kernel 在 /bin/sh 看到之前就拦截,路由到已安装的
142
+ // @yome/ppt skill, 跑 AppleScript, 返回结果。
143
+ ```
144
+
145
+ #### Skill 三层文档 · L1 / L2 / L3
146
+
147
+ 模型选择和使用 skill 的全部信息分布在三层。每一层都为 token / latency 优化:
148
+
149
+ | Layer | 在哪 | 给谁看 | 长度 |
150
+ |---|---|---|---|
151
+ | **L1 — Index** | system prompt 永驻 | 模型每次对话都看 | 3 行 / ~60 tokens per skill |
152
+ | **L2 — Signature** | `<domain> --help` 按需返回 | 模型决定要用之后 | ~50 行 / ~250 tokens |
153
+ | **L3 — Cookbook** | `<domain> --doc [name]` 按需返回 | 复杂任务时主动查阅 | KB 级 markdown |
154
+
155
+ **L1 看起来是这样** (system prompt 里 ppt skill 的真实块):
156
+
157
+ ```
158
+ ppt | when: user wants to create / edit / export PowerPoint .pptx slides
159
+ | effects: opens Microsoft PowerPoint, writes files (first save to ~/Desktop may show OS dialog)
160
+ | start: ppt --help
161
+ ```
162
+
163
+ 只有三个字段,因为 LLM 选 tool 时也只在乎这三件事:**何时该用 / 副作用是什么 / 第一步敲什么**。Skill 作者在 `yome-skill.json` 里写:
164
+
165
+ ```jsonc
166
+ "l1": {
167
+ "when": "user wants to create / edit / export PowerPoint .pptx slides",
168
+ "entry": "ppt --help",
169
+ "effects": "opens Microsoft PowerPoint, writes files"
170
+ }
171
+ ```
172
+
173
+ **L2 (`ppt --help`)** 是手写的 `SIGNATURE.md` —— 一行一 action,默认值内联,LLM 一眼扫完知道全部 args:
174
+
175
+ ```
176
+ ppt new [path] [--force] create blank presentation
177
+ ppt open <path> open existing .pptx
178
+ ppt save [--path=P] [--force] save (or save-as)
179
+ ppt slides TSV: index, title, shape count
180
+ ppt slide.add [--index=N] [--layout=N]
181
+ ppt title <slide> --text=<str>
182
+ ppt addtext <slide> --text=<str>
183
+ [--left=100 --top=200 --width=400 --height=50]
184
+ [--size=N --bold --italic]
185
+ [--color=red|#RRGGBB|R,G,B]
186
+ [--align=left|center|right]
187
+ ppt fmt <slide> --shape=<n> [--size=N --bold --italic --color --bg --align]
188
+ ppt export --format=pdf|png|jpg --path=<file> [--force]
189
+
190
+ ```
191
+
192
+ **L3 (`ppt --doc`)** 列出 cookbook 模板; `ppt --doc blue-white` 返回完整模板内容(配色、字号、batch 例子)。Skill 作者在 `docs/*.md` 里用 frontmatter 声明:
193
+
194
+ ```yaml
195
+ ---
196
+ name: blue-white
197
+ label: 蓝白风格
198
+ summary: 商务深蓝主色 + 白底,适合季度回顾、产品发布、销售汇报
199
+ tags: [theme, business]
200
+ ---
201
+ ```
202
+
203
+ #### Batch mode · 6 倍提速
204
+
205
+ 序列任务在 cli agent 里是头号性能杀手 —— 每个 AppleScript 调用 200ms cold-start。Yome Bash kernel 内置 `batch` verb 把 N 步合成一次调用; `--merge` 进一步把 N 个 AppleScript 合成一个 `osascript` 进程:
206
+
207
+ ```bash
208
+ ppt batch --merge <<EOF
209
+ new ~/Desktop/q3.pptx
210
+ title 1 --text="Q3 Review"
211
+ slide.add
212
+ title 2 --text="Revenue"
213
+ addtext 2 --text="+18% YoY" --size=72 --bold --color=green --align=center
214
+ slide.add
215
+ title 3 --text="Conclusion"
216
+ save
217
+ export --format=pdf --path=~/Desktop/q3.pdf
218
+ EOF
219
+ ```
220
+
221
+ 实测数字 —— 8 个连续 `ppt` action,M1 Mac:
222
+
223
+ | 模式 | Wall time | 提速 |
224
+ |---|---|---|
225
+ | 8 次独立 `ppt …` 调用 | 2041 ms | 1× |
226
+ | `ppt batch <<EOF…EOF` (顺序执行) | 2353 ms | 1× (含解析开销) |
227
+ | `ppt batch --merge <<EOF…EOF` | **334 ms** | **6.1×** |
228
+
229
+ Kernel 在 token 级别决定:第一个 token 是不是 reserved system command (47 个: `git`, `ls`, `cd`, `rm`, `node`…) ?是 → 直接放给 `/bin/sh`。否则 → 是不是某个已安装 skill 的 domain ?是 → 路由到 skill。否 → 透传给 shell。
230
+
231
+ 因此 *同一个 Bash tool* 同时承载了:
232
+
233
+ - 真 shell 命令 (`ls`, `git status`, `python script.py`)
234
+ - skill verb (`ppt new`, `cal create`)
235
+ - shell 复合 (`ppt slides | head -3` —— domain 命令的 stdout 喂给真 shell)
236
+ - 批量 (`ppt batch --merge <<EOF…EOF`)
237
+
238
+ ---
239
+
240
+ ## Skills Marketplace · Skill 市场
241
+
242
+ ```bash
243
+ yome skill search powerpoint # 搜索公共 hub
244
+ yome skill install github:Whopus/yome-skill-ppt
245
+ yome skill install ./my-local-skill # 本地目录
246
+ yome skill install github:owner/repo@v2 # 锁定到某 ref
247
+ yome skill update # 重新拉取所有已装 skill
248
+ yome skill rollback @yome/ppt # 一级撤销
249
+ yome skill enable / disable / link / unlink / doctor
250
+ ```
251
+
252
+ `yome skill publish` 把当前目录发布到公共 hub (需先 `yome login` 走 GitHub Device Flow)。Hub 只是发现层,skill 真身依然是 git repo —— 没有 vendor lock-in。
253
+
254
+ ---
255
+
256
+ ## 配置
257
+
258
+ ```bash
259
+ export YOME_API_KEY=sk-...
260
+ export YOME_BASE_URL=https://your.endpoint
261
+ export YOME_MODEL=claude-opus-4-6
262
+ export YOME_PROVIDER=anthropic # 或 openai (会从 base URL 自动检测)
263
+ ```
264
+
265
+ 或一次性写入 `~/.yome/config.json`:
266
+
267
+ ```bash
268
+ yome --key sk-... --base-url https://… --model …
269
+ ```
270
+
271
+ **存储布局:**
272
+
273
+ ```
274
+ ~/.yome/
275
+ ├── config.json # API 配置
276
+ ├── skills/ # 已安装的 native skill
277
+ │ ├── .index.json # 缓存的注册表
278
+ │ └── yome/
279
+ │ └── ppt/ # @yome/ppt skill, 就是 git repo 本体
280
+ └── threads/ # 会话历史 (按 cwd 分目录)
281
+ ```
282
+
283
+ ---
284
+
285
+ ## 哲学
286
+
287
+ > *用户不愿学习新产品,也不愿改变已有的行为模式。*
288
+
289
+ 我们不替代你的工具,而是在不打断现有流程的前提下进行**赋能 (Empower)**。Mail、Chat、Docs、Calendar、Files、Web —— 它们已经在你机器上,我们只是给它们装一层 living context 让它们苏醒。
290
+
291
+ | Before | After |
292
+ |---|---|
293
+ | Passive Tool · 被动工具 | Proactive Agent · 主动 Agent |
294
+ | You route context → tool | Yome 替你伸进每一台设备 |
295
+ | 12 contexts, 0 AI | 1 个 buddy,知道关于你的一切 |
296
+
297
+ ---
298
+
299
+ ## 项目状态
300
+
301
+ | 模块 | 状态 |
302
+ |---|---|
303
+ | Bash kernel (tokenizer + dispatcher + permission gate) | **stable** |
304
+ | Native skill 格式 (yome-skill.json + L1/L2/L3 docs) | **stable** |
305
+ | `@yome/ppt` (16 actions, batch + 4 themes) | **stable** |
306
+ | Skill hub (search / install / publish) | **stable** |
307
+ | Capability model (sandbox grants) | **stable** |
308
+ | Thread 历史 + case bundles | **stable** |
309
+ | Live history compaction | beta |
310
+ | Daemon (always-on agent) | experimental, 在 `next` 分支 |
311
+ | Custom missions (recurring tasks) | next-up |
312
+ | Async agent (后台长任务) | next-up |
313
+
314
+ **Daemon roadmap** *(scoped, 在 `next` 分支)*
315
+
316
+ - [ ] **系统消息拦截** — 微信 / 飞书 / Slack / WhatsApp / iMessage。实时捕获,过滤垃圾,主动协助回复,不漏任何重要消息。
317
+ - [ ] **日程 / Routine 自动化** — 订阅博主、社交频道、每日 digest、提醒闹铃、日历联动。不用打开就会自己跑。
318
+ - [ ] **状态变化监听** — 实验跑完、CPU / GPU 飙高、build 通过、有人 @你。在关键时刻推送,而不是事后汇总。
319
+
320
+ ---
321
+
322
+ ## License
323
+
324
+ [Apache License 2.0](./LICENSE) —— Yome Agent + 官方 skills (`yome-skill-ppt`, `yome-skill-xl`, `yome-skill-cal`, `yome-skill-rem`, `yome-skill-fs`)。
325
+
326
+ 社区贡献者发布到 Yome hub 的 skill 是作者自己的 git repo,各自适用其自己的 license。
327
+
328
+ ---
329
+
330
+ <div align="center">
331
+
332
+ **YOME — Your Universal AI Work Buddy.**
333
+ *Know everything. Run everywhere. Empower everyone.*
334
+
335
+ </div>
package/dist/agent.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { ToolPermissionContext, PermissionMode } from './permissions/types.js';
1
+ import { type AskPermissionResult } from './tools/index.js';
2
+ import type { ToolPermissionContext, PermissionMode, PermissionBehavior, PermissionRuleSource } from './permissions/types.js';
2
3
  import type { Skill } from './skills/index.js';
3
4
  import type { AgentDefinition } from './subagent/index.js';
4
5
  import type { AgentMessage } from './types.js';
@@ -7,23 +8,44 @@ import type { AgentLoopCallbacks } from './loops/index.js';
7
8
  import type { PastedImage } from './utils/imagePaste.js';
8
9
  export interface AgentCallbacks extends AgentLoopCallbacks {
9
10
  onLoopChanged?: (name: string) => void;
10
- onAskPermission?: (toolName: string, message: string, input: Record<string, unknown>) => Promise<boolean>;
11
+ onAskPermission?: (toolName: string, message: string, input: Record<string, unknown>) => Promise<AskPermissionResult>;
11
12
  }
12
13
  export declare class Agent {
13
14
  private config;
14
15
  private messages;
15
16
  private systemPrompt;
16
17
  private skills;
18
+ /**
19
+ * Cached skill list with includeDisabled=true. We re-read SKILL.md files
20
+ * only when explicitly invalidated (resetContext / reloadSkills /
21
+ * skill toggle picker reopens). Previously every call to getSkills() hit
22
+ * the filesystem — and it gets called on every render of the slash menu,
23
+ * the unified picker, and the system prompt rebuild. After ~50 turns
24
+ * that adds up to thousands of redundant readdirSync calls.
25
+ */
26
+ private cachedSkillsAll;
17
27
  private loopRegistry;
18
28
  private currentLoopName;
19
29
  private permissionContext;
20
30
  private sessionId;
21
31
  constructor(config: YomeConfig);
32
+ /** Drop the cached skill list so the next getSkills() call re-reads from disk. */
33
+ invalidateSkillsCache(): void;
22
34
  getSessionId(): string;
23
35
  getPermissionContext(): ToolPermissionContext;
24
36
  getConfig(): YomeConfig;
25
37
  switchModel(entry: ModelEntry): void;
26
38
  switchPermissionMode(mode: PermissionMode): void;
39
+ /**
40
+ * Append a rule to the live in-memory permission context AND update the
41
+ * tools subsystem so subsequent invocations see it without restarting.
42
+ *
43
+ * `source: 'session'` — never persisted, lives only for this Agent instance.
44
+ * `source: 'userSettings'` — caller is responsible for also writing to disk
45
+ * (via `addPermissionRuleToUserSettings`); this just mirrors the rule into
46
+ * memory so the current session benefits immediately.
47
+ */
48
+ addPermissionRule(ruleString: string, behavior: PermissionBehavior, source?: PermissionRuleSource): void;
27
49
  resetContext(): void;
28
50
  restoreSession(sessionId: string): void;
29
51
  getMessages(): AgentMessage[];
package/dist/agent.js CHANGED
@@ -3,7 +3,7 @@ import { getAnthropicTools, executeTool, registerTool, setPermissionContext, set
3
3
  import { loadAllSkills } from './skills/index.js';
4
4
  import { createLoopRegistry } from './loops/index.js';
5
5
  import { createAgentTool, clearAgentCache, getAllAgents } from './subagent/index.js';
6
- import { initializePermissionContext } from './permissions/loader.js';
6
+ import { initializePermissionContext, addRuleToContext } from './permissions/loader.js';
7
7
  import { modelEntryToConfig } from './config.js';
8
8
  import { createSessionId, appendMessage, loadSessionMessages, setSessionTitle } from './sessions.js';
9
9
  export class Agent {
@@ -11,6 +11,15 @@ export class Agent {
11
11
  messages = [];
12
12
  systemPrompt;
13
13
  skills = [];
14
+ /**
15
+ * Cached skill list with includeDisabled=true. We re-read SKILL.md files
16
+ * only when explicitly invalidated (resetContext / reloadSkills /
17
+ * skill toggle picker reopens). Previously every call to getSkills() hit
18
+ * the filesystem — and it gets called on every render of the slash menu,
19
+ * the unified picker, and the system prompt rebuild. After ~50 turns
20
+ * that adds up to thousands of redundant readdirSync calls.
21
+ */
22
+ cachedSkillsAll = null;
14
23
  loopRegistry = createLoopRegistry();
15
24
  currentLoopName = 'simple';
16
25
  permissionContext;
@@ -24,6 +33,10 @@ export class Agent {
24
33
  setPermissionContext(this.permissionContext);
25
34
  this.sessionId = createSessionId();
26
35
  }
36
+ /** Drop the cached skill list so the next getSkills() call re-reads from disk. */
37
+ invalidateSkillsCache() {
38
+ this.cachedSkillsAll = null;
39
+ }
27
40
  getSessionId() {
28
41
  return this.sessionId;
29
42
  }
@@ -40,10 +53,24 @@ export class Agent {
40
53
  this.permissionContext = { ...this.permissionContext, mode };
41
54
  setPermissionContext(this.permissionContext);
42
55
  }
56
+ /**
57
+ * Append a rule to the live in-memory permission context AND update the
58
+ * tools subsystem so subsequent invocations see it without restarting.
59
+ *
60
+ * `source: 'session'` — never persisted, lives only for this Agent instance.
61
+ * `source: 'userSettings'` — caller is responsible for also writing to disk
62
+ * (via `addPermissionRuleToUserSettings`); this just mirrors the rule into
63
+ * memory so the current session benefits immediately.
64
+ */
65
+ addPermissionRule(ruleString, behavior, source = 'session') {
66
+ this.permissionContext = addRuleToContext(this.permissionContext, ruleString, behavior, source);
67
+ setPermissionContext(this.permissionContext);
68
+ }
43
69
  resetContext() {
44
70
  this.messages = [];
45
71
  this.systemPrompt = buildSystemPrompt();
46
72
  this.skills = loadAllSkills();
73
+ this.cachedSkillsAll = null;
47
74
  clearAgentCache();
48
75
  registerTool(createAgentTool(this.config));
49
76
  this.sessionId = createSessionId();
@@ -53,6 +80,7 @@ export class Agent {
53
80
  this.messages = loadSessionMessages(sessionId);
54
81
  this.systemPrompt = buildSystemPrompt();
55
82
  this.skills = loadAllSkills();
83
+ this.cachedSkillsAll = null;
56
84
  clearAgentCache();
57
85
  registerTool(createAgentTool(this.config));
58
86
  }
@@ -66,13 +94,17 @@ export class Agent {
66
94
  setSessionTitle(this.sessionId, title);
67
95
  }
68
96
  getSkills() {
69
- return loadAllSkills(true);
97
+ if (!this.cachedSkillsAll) {
98
+ this.cachedSkillsAll = loadAllSkills(true);
99
+ }
100
+ return this.cachedSkillsAll;
70
101
  }
71
102
  getAgents() {
72
103
  return getAllAgents();
73
104
  }
74
105
  reloadSkills() {
75
106
  this.skills = loadAllSkills();
107
+ this.cachedSkillsAll = null;
76
108
  this.systemPrompt = buildSystemPrompt();
77
109
  clearAgentCache();
78
110
  registerTool(createAgentTool(this.config));
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/context.d.ts CHANGED
@@ -1 +1,3 @@
1
+ /** Force a re-fetch of git/tree info on next buildSystemPrompt call. */
2
+ export declare function invalidateCwdMeta(): void;
1
3
  export declare function buildSystemPrompt(): string;
package/dist/context.js CHANGED
@@ -2,6 +2,8 @@ import { execSync } from 'child_process';
2
2
  import { readdirSync } from 'fs';
3
3
  import { join, basename } from 'path';
4
4
  import { loadAllSkills } from './skills/index.js';
5
+ import { getInstalledFast } from './yomeSkills/skillsIndex.js';
6
+ import { readManifest } from './yomeSkills/manifest.js';
5
7
  function safeExec(cmd, cwd) {
6
8
  try {
7
9
  return execSync(cmd, { cwd, timeout: 5000, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
@@ -30,15 +32,36 @@ function getFileTree(dir, depth = 2, prefix = '') {
30
32
  catch { /* ignore */ }
31
33
  return lines.filter(Boolean).join('\n');
32
34
  }
35
+ let _cwdMetaCache = null;
36
+ const CWD_META_TTL_MS = 60_000;
37
+ function getCwdMeta(cwd) {
38
+ const now = Date.now();
39
+ if (_cwdMetaCache && _cwdMetaCache.cwd === cwd && _cwdMetaCache.expiresAt > now) {
40
+ return _cwdMetaCache;
41
+ }
42
+ _cwdMetaCache = {
43
+ cwd,
44
+ expiresAt: now + CWD_META_TTL_MS,
45
+ gitBranch: safeExec('git rev-parse --abbrev-ref HEAD', cwd),
46
+ gitStatus: safeExec('git status --porcelain', cwd),
47
+ tree: getFileTree(cwd),
48
+ };
49
+ return _cwdMetaCache;
50
+ }
51
+ /** Force a re-fetch of git/tree info on next buildSystemPrompt call. */
52
+ export function invalidateCwdMeta() {
53
+ _cwdMetaCache = null;
54
+ }
33
55
  export function buildSystemPrompt() {
34
56
  const cwd = process.cwd();
35
57
  const projectName = basename(cwd);
36
58
  const now = new Date();
37
59
  const dateStr = now.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' });
38
- const gitBranch = safeExec('git rev-parse --abbrev-ref HEAD', cwd);
39
- const gitStatus = safeExec('git status --porcelain', cwd);
60
+ const meta = getCwdMeta(cwd);
61
+ const gitBranch = meta.gitBranch;
62
+ const gitStatus = meta.gitStatus;
40
63
  const isGit = gitBranch !== null;
41
- const tree = getFileTree(cwd);
64
+ const tree = meta.tree;
42
65
  let prompt = `You are Yome, an AI coding assistant running in the user's terminal.
43
66
  You help with software engineering tasks: reading code, writing code, debugging, refactoring, and running commands.
44
67
 
@@ -79,23 +102,105 @@ You have these tools: Read, Edit, Write, Bash, Glob, Grep, LS.
79
102
  - Use Grep to search file contents.
80
103
  - Use LS to list directory contents.
81
104
  `;
105
+ // Prompt-style skills (Claude Code-format SKILL.md). The agent injects
106
+ // their markdown bodies into the prompt at /skill-name invocation time;
107
+ // here we just advertise them so the model knows they exist.
82
108
  const skills = loadAllSkills();
83
109
  if (skills.length > 0) {
84
110
  prompt += buildSkillsSection(skills);
85
111
  }
112
+ // Hub skills (yome-skill.json packages) — these carry typed command
113
+ // contracts and capability grants. Every installed + enabled hub skill
114
+ // is exposed to the model so it can reach for the right command
115
+ // (e.g. ppt.slide.add) instead of trying to roll one from shell.
116
+ const hubSkills = getInstalledFast().filter((s) => s.status === 'enabled');
117
+ if (hubSkills.length > 0) {
118
+ prompt += buildHubSkillsSection(hubSkills);
119
+ }
86
120
  return prompt;
87
121
  }
122
+ /**
123
+ * Prompt skills (Claude Code SKILL.md format) get the same 3-row L1
124
+ * shape as hub skills, just with different field sources:
125
+ * when ← frontmatter `when_to_use` (or `description` as fallback)
126
+ * effects ← always "loads markdown body into context (prompt-only)"
127
+ * unless the SKILL.md explicitly grants `allowed-tools`
128
+ * start ← `/skill-name [argument-hint]`
129
+ *
130
+ * Same visual shape means the model doesn't have to context-switch
131
+ * between two different docs styles when scanning available skills.
132
+ */
88
133
  function buildSkillsSection(skills) {
89
- let section = `\n## Available Skills\nThe user can invoke skills with \`/skill-name [args]\`. You can also invoke them when appropriate.\n\n`;
134
+ let section = `\n## Available Skills (prompt)\nUser invokes with \`/skill-name [args]\`; you can invoke them too when appropriate.\n\n`;
90
135
  for (const skill of skills) {
91
- section += `### /${skill.name}\n`;
92
- section += `${skill.description}\n`;
93
- if (skill.whenToUse)
94
- section += `When to use: ${skill.whenToUse}\n`;
95
- if (skill.argumentHint)
96
- section += `Usage: /${skill.name} ${skill.argumentHint}\n`;
97
- section += `Source: ${skill.source}\n\n`;
136
+ const head = `/${skill.name}`;
137
+ const pad = ' '.repeat(head.length);
138
+ const when = skill.whenToUse ?? skill.description;
139
+ const entry = skill.argumentHint ? `/${skill.name} ${skill.argumentHint}` : `/${skill.name}`;
140
+ const effects = (skill.allowedTools && skill.allowedTools.length > 0)
141
+ ? `runs tools: ${skill.allowedTools.join(', ')}`
142
+ : `prompt-only (no tools)`;
143
+ section += `${head} | when: ${when}\n`;
144
+ section += `${pad} | effects: ${effects}\n`;
145
+ section += `${pad} | start: ${entry}\n`;
98
146
  }
99
147
  return section;
100
148
  }
149
+ /**
150
+ * Hub skills are surfaced to the LLM in three layers:
151
+ * L1 — this section: ONE skill = THREE short rows answering the only
152
+ * questions the model actually has when picking a tool —
153
+ * when (trigger condition)
154
+ * effects (truthful side effects)
155
+ * start (first command to discover the rest)
156
+ * Authored as `l1: { when, entry, effects }` in yome-skill.json.
157
+ * L2 — `<domain> --help` (kernel reads SIGNATURE.md, fallback auto-gen).
158
+ * L3 — `<domain> --doc [name]` for cookbook templates / themes.
159
+ *
160
+ * The model is told once, in the footer, that --help / --doc / batch exist
161
+ * for every installed skill — so individual L1 blocks stay focused on
162
+ * the trigger / effects / entry triad.
163
+ */
164
+ function buildHubSkillsSection(entries) {
165
+ let section = `\n## Installed Hub Skills\nUse the Bash tool: \`<domain> <action> [args]\` (no \`yome\` prefix, no SkillCall).\n\n`;
166
+ for (const e of entries) {
167
+ const manifest = readManifest(e.installedAt);
168
+ section += renderL1Block(e.domain, manifest, e.description) + '\n';
169
+ }
170
+ section += `\nFor any installed skill:
171
+ \`<domain> --help\` one-screen signature (actions + args)
172
+ \`<domain> --doc\` list cookbook templates / themes
173
+ \`<domain> --doc <name>\` read one template
174
+ \`<domain> batch <<EOF…EOF\` run several sub-commands in one call (--keep-going, --merge)
175
+ `;
176
+ return section;
177
+ }
178
+ /**
179
+ * Render the 3-row pipe-aligned L1 block for one skill. Falls back to
180
+ * legacy `prompt_line`, then to `<domain> — <description>` so older
181
+ * yome-skill.json files keep producing *something* useful.
182
+ */
183
+ function renderL1Block(domain, manifest, fallbackDesc) {
184
+ const l1 = manifest?.l1;
185
+ if (l1 && (l1.when || l1.entry || l1.effects)) {
186
+ // Right-pad the domain column so the pipes line up vertically — easier
187
+ // for the model to scan when several skills are listed.
188
+ const head = domain;
189
+ const pad = ' '.repeat(head.length);
190
+ const lines = [];
191
+ if (l1.when)
192
+ lines.push(`${head} | when: ${l1.when}`);
193
+ if (l1.effects)
194
+ lines.push(`${pad} | effects: ${l1.effects}`);
195
+ if (l1.entry)
196
+ lines.push(`${pad} | start: ${l1.entry}`);
197
+ return lines.join('\n');
198
+ }
199
+ // Legacy single-line fallback — keeps backward compat with skills that
200
+ // used `prompt_line` before the structured l1 schema landed.
201
+ if (manifest?.prompt_line) {
202
+ return `- ${manifest.prompt_line}`;
203
+ }
204
+ return `- ${domain} — ${fallbackDesc ?? '(no description provided)'}`;
205
+ }
101
206
  //# sourceMappingURL=context.js.map