@poping/yome 0.0.2 → 0.0.4

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 (276) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +11 -0
  3. package/README.md +306 -27
  4. package/README.zh-CN.md +333 -0
  5. package/bin/yome-calwatch +0 -0
  6. package/dist/agent.d.ts +24 -2
  7. package/dist/agent.js +34 -2
  8. package/dist/agent.js.map +1 -1
  9. package/dist/context.d.ts +2 -0
  10. package/dist/context.js +121 -13
  11. package/dist/context.js.map +1 -1
  12. package/dist/daemon/calendarPermission.d.ts +10 -0
  13. package/dist/daemon/calendarPermission.js +68 -0
  14. package/dist/daemon/calendarPermission.js.map +1 -0
  15. package/dist/daemon/cronCli.d.ts +19 -0
  16. package/dist/daemon/cronCli.js +403 -0
  17. package/dist/daemon/cronCli.js.map +1 -0
  18. package/dist/daemon/envHint.d.ts +5 -0
  19. package/dist/daemon/envHint.js +139 -0
  20. package/dist/daemon/envHint.js.map +1 -0
  21. package/dist/daemon/humanCron.d.ts +1 -0
  22. package/dist/daemon/humanCron.js +72 -0
  23. package/dist/daemon/humanCron.js.map +1 -0
  24. package/dist/daemon/humanOnce.d.ts +1 -0
  25. package/dist/daemon/humanOnce.js +54 -0
  26. package/dist/daemon/humanOnce.js.map +1 -0
  27. package/dist/daemon/index.d.ts +5 -0
  28. package/dist/daemon/index.js +168 -0
  29. package/dist/daemon/index.js.map +1 -0
  30. package/dist/daemon/launchd.d.ts +7 -0
  31. package/dist/daemon/launchd.js +93 -0
  32. package/dist/daemon/launchd.js.map +1 -0
  33. package/dist/daemon/log.d.ts +17 -0
  34. package/dist/daemon/log.js +57 -0
  35. package/dist/daemon/log.js.map +1 -0
  36. package/dist/daemon/paths.d.ts +11 -0
  37. package/dist/daemon/paths.js +27 -0
  38. package/dist/daemon/paths.js.map +1 -0
  39. package/dist/daemon/runTaskEntry.d.ts +1 -0
  40. package/dist/daemon/runTaskEntry.js +67 -0
  41. package/dist/daemon/runTaskEntry.js.map +1 -0
  42. package/dist/daemon/runner.d.ts +21 -0
  43. package/dist/daemon/runner.js +175 -0
  44. package/dist/daemon/runner.js.map +1 -0
  45. package/dist/daemon/scheduler.d.ts +5 -0
  46. package/dist/daemon/scheduler.js +162 -0
  47. package/dist/daemon/scheduler.js.map +1 -0
  48. package/dist/daemon/taskStore.d.ts +62 -0
  49. package/dist/daemon/taskStore.js +88 -0
  50. package/dist/daemon/taskStore.js.map +1 -0
  51. package/dist/daemon/triggers/calendar.d.ts +8 -0
  52. package/dist/daemon/triggers/calendar.js +248 -0
  53. package/dist/daemon/triggers/calendar.js.map +1 -0
  54. package/dist/daemon/triggers/childRunner.d.ts +14 -0
  55. package/dist/daemon/triggers/childRunner.js +111 -0
  56. package/dist/daemon/triggers/childRunner.js.map +1 -0
  57. package/dist/daemon/triggers/cron.d.ts +14 -0
  58. package/dist/daemon/triggers/cron.js +91 -0
  59. package/dist/daemon/triggers/cron.js.map +1 -0
  60. package/dist/daemon/triggers/file.d.ts +7 -0
  61. package/dist/daemon/triggers/file.js +123 -0
  62. package/dist/daemon/triggers/file.js.map +1 -0
  63. package/dist/daemon/triggers/once.d.ts +10 -0
  64. package/dist/daemon/triggers/once.js +80 -0
  65. package/dist/daemon/triggers/once.js.map +1 -0
  66. package/dist/index.js +240 -15
  67. package/dist/index.js.map +1 -1
  68. package/dist/llm.js +45 -2
  69. package/dist/llm.js.map +1 -1
  70. package/dist/loops/chain.js +8 -0
  71. package/dist/loops/chain.js.map +1 -1
  72. package/dist/loops/evaluator.js +8 -0
  73. package/dist/loops/evaluator.js.map +1 -1
  74. package/dist/loops/orchestrator.js +8 -0
  75. package/dist/loops/orchestrator.js.map +1 -1
  76. package/dist/loops/parallel.js.map +1 -1
  77. package/dist/loops/route.js +8 -0
  78. package/dist/loops/route.js.map +1 -1
  79. package/dist/loops/simple.js +15 -0
  80. package/dist/loops/simple.js.map +1 -1
  81. package/dist/permissions/index.d.ts +1 -1
  82. package/dist/permissions/index.js +1 -1
  83. package/dist/permissions/index.js.map +1 -1
  84. package/dist/permissions/loader.d.ts +20 -1
  85. package/dist/permissions/loader.js +51 -0
  86. package/dist/permissions/loader.js.map +1 -1
  87. package/dist/redact.d.ts +56 -0
  88. package/dist/redact.js +191 -0
  89. package/dist/redact.js.map +1 -0
  90. package/dist/skills/runner/applescript.d.ts +49 -0
  91. package/dist/skills/runner/applescript.js +100 -0
  92. package/dist/skills/runner/applescript.js.map +1 -0
  93. package/dist/skills/runner/dispatcher.d.ts +128 -0
  94. package/dist/skills/runner/dispatcher.js +617 -0
  95. package/dist/skills/runner/dispatcher.js.map +1 -0
  96. package/dist/skills/runner/dispatcher.test.d.ts +1 -0
  97. package/dist/skills/runner/dispatcher.test.js +141 -0
  98. package/dist/skills/runner/dispatcher.test.js.map +1 -0
  99. package/dist/skills/runner/kernel.d.ts +8 -0
  100. package/dist/skills/runner/kernel.js +731 -0
  101. package/dist/skills/runner/kernel.js.map +1 -0
  102. package/dist/skills/runner/nodeBackend.d.ts +32 -0
  103. package/dist/skills/runner/nodeBackend.js +147 -0
  104. package/dist/skills/runner/nodeBackend.js.map +1 -0
  105. package/dist/skills/runner/tokenizer.d.ts +36 -0
  106. package/dist/skills/runner/tokenizer.js +177 -0
  107. package/dist/skills/runner/tokenizer.js.map +1 -0
  108. package/dist/state/todos.d.ts +12 -0
  109. package/dist/state/todos.js +32 -0
  110. package/dist/state/todos.js.map +1 -0
  111. package/dist/threadCli.d.ts +11 -0
  112. package/dist/threadCli.js +177 -0
  113. package/dist/threadCli.js.map +1 -0
  114. package/dist/threadShare.d.ts +21 -0
  115. package/dist/threadShare.js +121 -0
  116. package/dist/threadShare.js.map +1 -0
  117. package/dist/threadSubmit.d.ts +32 -0
  118. package/dist/threadSubmit.js +199 -0
  119. package/dist/threadSubmit.js.map +1 -0
  120. package/dist/tools/askUser.d.ts +20 -0
  121. package/dist/tools/askUser.js +126 -0
  122. package/dist/tools/askUser.js.map +1 -0
  123. package/dist/tools/bash.js +63 -14
  124. package/dist/tools/bash.js.map +1 -1
  125. package/dist/tools/index.d.ts +24 -2
  126. package/dist/tools/index.js +54 -5
  127. package/dist/tools/index.js.map +1 -1
  128. package/dist/tools/skillCall.d.ts +2 -0
  129. package/dist/tools/skillCall.js +77 -0
  130. package/dist/tools/skillCall.js.map +1 -0
  131. package/dist/tools/todoWrite.d.ts +2 -0
  132. package/dist/tools/todoWrite.js +141 -0
  133. package/dist/tools/todoWrite.js.map +1 -0
  134. package/dist/tools/yome.d.ts +2 -0
  135. package/dist/tools/yome.js +87 -0
  136. package/dist/tools/yome.js.map +1 -0
  137. package/dist/ui/AgentPicker.js +3 -3
  138. package/dist/ui/AgentPicker.js.map +1 -1
  139. package/dist/ui/App.js +263 -61
  140. package/dist/ui/App.js.map +1 -1
  141. package/dist/ui/AskUserPrompt.d.ts +7 -0
  142. package/dist/ui/AskUserPrompt.js +78 -0
  143. package/dist/ui/AskUserPrompt.js.map +1 -0
  144. package/dist/ui/Banner.d.ts +2 -1
  145. package/dist/ui/Banner.js +23 -4
  146. package/dist/ui/Banner.js.map +1 -1
  147. package/dist/ui/InputBar.js +25 -36
  148. package/dist/ui/InputBar.js.map +1 -1
  149. package/dist/ui/Markdown.d.ts +2 -2
  150. package/dist/ui/Markdown.js +22 -7
  151. package/dist/ui/Markdown.js.map +1 -1
  152. package/dist/ui/MarketplacePicker.d.ts +7 -0
  153. package/dist/ui/MarketplacePicker.js +122 -0
  154. package/dist/ui/MarketplacePicker.js.map +1 -0
  155. package/dist/ui/MessageList.d.ts +12 -1
  156. package/dist/ui/MessageList.js +72 -7
  157. package/dist/ui/MessageList.js.map +1 -1
  158. package/dist/ui/ModelPicker.js +4 -4
  159. package/dist/ui/ModelPicker.js.map +1 -1
  160. package/dist/ui/MultilineTextInput.d.ts +31 -0
  161. package/dist/ui/MultilineTextInput.js +393 -0
  162. package/dist/ui/MultilineTextInput.js.map +1 -0
  163. package/dist/ui/MultilineTextInput.test.d.ts +1 -0
  164. package/dist/ui/MultilineTextInput.test.js +30 -0
  165. package/dist/ui/MultilineTextInput.test.js.map +1 -0
  166. package/dist/ui/PermissionPrompt.d.ts +16 -4
  167. package/dist/ui/PermissionPrompt.js +60 -15
  168. package/dist/ui/PermissionPrompt.js.map +1 -1
  169. package/dist/ui/SessionPicker.js +2 -2
  170. package/dist/ui/SessionPicker.js.map +1 -1
  171. package/dist/ui/ShimmerText.d.ts +8 -0
  172. package/dist/ui/ShimmerText.js +40 -0
  173. package/dist/ui/ShimmerText.js.map +1 -0
  174. package/dist/ui/Spinner.js +3 -9
  175. package/dist/ui/Spinner.js.map +1 -1
  176. package/dist/ui/TodoPanel.d.ts +7 -0
  177. package/dist/ui/TodoPanel.js +36 -0
  178. package/dist/ui/TodoPanel.js.map +1 -0
  179. package/dist/ui/TogglePicker.js +4 -4
  180. package/dist/ui/TogglePicker.js.map +1 -1
  181. package/dist/ui/ToolResult.js +6 -0
  182. package/dist/ui/ToolResult.js.map +1 -1
  183. package/dist/ui/UnifiedSkillsPicker.d.ts +10 -0
  184. package/dist/ui/UnifiedSkillsPicker.js +63 -0
  185. package/dist/ui/UnifiedSkillsPicker.js.map +1 -0
  186. package/dist/ui/animation.d.ts +3 -0
  187. package/dist/ui/animation.js +48 -0
  188. package/dist/ui/animation.js.map +1 -0
  189. package/dist/ui/useThrottledStream.d.ts +7 -0
  190. package/dist/ui/useThrottledStream.js +63 -0
  191. package/dist/ui/useThrottledStream.js.map +1 -0
  192. package/dist/yomeSkills/auth.d.ts +20 -0
  193. package/dist/yomeSkills/auth.js +70 -0
  194. package/dist/yomeSkills/auth.js.map +1 -0
  195. package/dist/yomeSkills/blacklist.d.ts +33 -0
  196. package/dist/yomeSkills/blacklist.js +101 -0
  197. package/dist/yomeSkills/blacklist.js.map +1 -0
  198. package/dist/yomeSkills/capabilities.d.ts +54 -0
  199. package/dist/yomeSkills/capabilities.js +175 -0
  200. package/dist/yomeSkills/capabilities.js.map +1 -0
  201. package/dist/yomeSkills/capabilityGuard.d.ts +31 -0
  202. package/dist/yomeSkills/capabilityGuard.js +113 -0
  203. package/dist/yomeSkills/capabilityGuard.js.map +1 -0
  204. package/dist/yomeSkills/cli.d.ts +25 -0
  205. package/dist/yomeSkills/cli.js +624 -0
  206. package/dist/yomeSkills/cli.js.map +1 -0
  207. package/dist/yomeSkills/deprecate.d.ts +29 -0
  208. package/dist/yomeSkills/deprecate.js +99 -0
  209. package/dist/yomeSkills/deprecate.js.map +1 -0
  210. package/dist/yomeSkills/devLink.d.ts +17 -0
  211. package/dist/yomeSkills/devLink.js +91 -0
  212. package/dist/yomeSkills/devLink.js.map +1 -0
  213. package/dist/yomeSkills/doctor.d.ts +13 -0
  214. package/dist/yomeSkills/doctor.js +152 -0
  215. package/dist/yomeSkills/doctor.js.map +1 -0
  216. package/dist/yomeSkills/enable.d.ts +8 -0
  217. package/dist/yomeSkills/enable.js +67 -0
  218. package/dist/yomeSkills/enable.js.map +1 -0
  219. package/dist/yomeSkills/hubPing.d.ts +1 -0
  220. package/dist/yomeSkills/hubPing.js +41 -0
  221. package/dist/yomeSkills/hubPing.js.map +1 -0
  222. package/dist/yomeSkills/install.d.ts +18 -0
  223. package/dist/yomeSkills/install.js +143 -0
  224. package/dist/yomeSkills/install.js.map +1 -0
  225. package/dist/yomeSkills/installFromHubTarball.d.ts +26 -0
  226. package/dist/yomeSkills/installFromHubTarball.js +161 -0
  227. package/dist/yomeSkills/installFromHubTarball.js.map +1 -0
  228. package/dist/yomeSkills/installGithub.d.ts +33 -0
  229. package/dist/yomeSkills/installGithub.js +213 -0
  230. package/dist/yomeSkills/installGithub.js.map +1 -0
  231. package/dist/yomeSkills/installMeta.d.ts +8 -0
  232. package/dist/yomeSkills/installMeta.js +76 -0
  233. package/dist/yomeSkills/installMeta.js.map +1 -0
  234. package/dist/yomeSkills/integrity.d.ts +26 -0
  235. package/dist/yomeSkills/integrity.js +107 -0
  236. package/dist/yomeSkills/integrity.js.map +1 -0
  237. package/dist/yomeSkills/invoke.d.ts +29 -0
  238. package/dist/yomeSkills/invoke.js +135 -0
  239. package/dist/yomeSkills/invoke.js.map +1 -0
  240. package/dist/yomeSkills/list.d.ts +11 -0
  241. package/dist/yomeSkills/list.js +55 -0
  242. package/dist/yomeSkills/list.js.map +1 -0
  243. package/dist/yomeSkills/login.d.ts +41 -0
  244. package/dist/yomeSkills/login.js +221 -0
  245. package/dist/yomeSkills/login.js.map +1 -0
  246. package/dist/yomeSkills/manifest.d.ts +60 -0
  247. package/dist/yomeSkills/manifest.js +47 -0
  248. package/dist/yomeSkills/manifest.js.map +1 -0
  249. package/dist/yomeSkills/paths.d.ts +13 -0
  250. package/dist/yomeSkills/paths.js +33 -0
  251. package/dist/yomeSkills/paths.js.map +1 -0
  252. package/dist/yomeSkills/publish.d.ts +18 -0
  253. package/dist/yomeSkills/publish.js +114 -0
  254. package/dist/yomeSkills/publish.js.map +1 -0
  255. package/dist/yomeSkills/rollback.d.ts +10 -0
  256. package/dist/yomeSkills/rollback.js +83 -0
  257. package/dist/yomeSkills/rollback.js.map +1 -0
  258. package/dist/yomeSkills/search.d.ts +21 -0
  259. package/dist/yomeSkills/search.js +31 -0
  260. package/dist/yomeSkills/search.js.map +1 -0
  261. package/dist/yomeSkills/skillsIndex.d.ts +36 -0
  262. package/dist/yomeSkills/skillsIndex.js +111 -0
  263. package/dist/yomeSkills/skillsIndex.js.map +1 -0
  264. package/dist/yomeSkills/unified.d.ts +53 -0
  265. package/dist/yomeSkills/unified.js +187 -0
  266. package/dist/yomeSkills/unified.js.map +1 -0
  267. package/dist/yomeSkills/uninstall.d.ts +7 -0
  268. package/dist/yomeSkills/uninstall.js +22 -0
  269. package/dist/yomeSkills/uninstall.js.map +1 -0
  270. package/dist/yomeSkills/update.d.ts +18 -0
  271. package/dist/yomeSkills/update.js +75 -0
  272. package/dist/yomeSkills/update.js.map +1 -0
  273. package/dist/yomeSkills/validate.d.ts +11 -0
  274. package/dist/yomeSkills/validate.js +99 -0
  275. package/dist/yomeSkills/validate.js.map +1 -0
  276. package/package.json +23 -6
@@ -0,0 +1,126 @@
1
+ // cli/src/tools/askUser.ts
2
+ //
3
+ // `AskUser` — agent tool that pauses execution and surfaces 1–4
4
+ // multiple-choice questions in the TUI. The agent uses it to clarify
5
+ // ambiguous requirements or to let the user pick between approaches
6
+ // BEFORE doing irreversible work.
7
+ //
8
+ // Routing:
9
+ // - In TUI mode: tools/index.ts has registered an ask-user handler
10
+ // (App.tsx mounts it on startup); this tool awaits the user's
11
+ // answers and returns them as JSON.
12
+ // - In headless / SDK mode: no handler is registered — the tool
13
+ // short-circuits with a "no UI available" answer so the agent can
14
+ // keep going (or pick a default itself).
15
+ let _askUserFn = null;
16
+ export function setAskUserHandler(fn) {
17
+ _askUserFn = fn;
18
+ }
19
+ // ── Tool ─────────────────────────────────────────────────────────────
20
+ const DESCRIPTION = 'Ask the user 1–4 multiple-choice questions during execution to clarify ambiguous ' +
21
+ 'requirements or let them pick between trade-offs. ' +
22
+ 'Each question has 2–4 options; do NOT include an "Other" option, the UI provides ' +
23
+ 'a custom-answer entry automatically. ' +
24
+ 'BLOCKING: this tool waits for the user to answer in the TUI before returning.';
25
+ export const askUserTool = {
26
+ name: 'AskUser',
27
+ description: DESCRIPTION,
28
+ inputSchema: {
29
+ type: 'object',
30
+ properties: {
31
+ questions: {
32
+ type: 'array',
33
+ description: '1–4 questions to ask the user (asked one at a time, in order).',
34
+ items: {
35
+ type: 'object',
36
+ properties: {
37
+ question: {
38
+ type: 'string',
39
+ description: 'Full question text. Should end with `?` and be self-contained.',
40
+ },
41
+ header: {
42
+ type: 'string',
43
+ description: 'Short chip label (≤ 12 chars), e.g. "Library", "Approach".',
44
+ },
45
+ options: {
46
+ type: 'array',
47
+ description: '2–4 mutually exclusive choices. Do NOT add an "Other" option.',
48
+ items: {
49
+ type: 'object',
50
+ properties: {
51
+ label: { type: 'string', description: 'Concise option label (1–5 words).' },
52
+ description: { type: 'string', description: 'Optional one-line explanation.' },
53
+ },
54
+ required: ['label'],
55
+ },
56
+ },
57
+ },
58
+ required: ['question', 'header', 'options'],
59
+ },
60
+ },
61
+ },
62
+ required: ['questions'],
63
+ },
64
+ isReadOnly() { return true; },
65
+ validateInput(input) {
66
+ if (!Array.isArray(input.questions) || input.questions.length === 0) {
67
+ return { valid: false, error: 'questions must be a non-empty array' };
68
+ }
69
+ if (input.questions.length > 4) {
70
+ return { valid: false, error: `at most 4 questions per call (got ${input.questions.length})` };
71
+ }
72
+ const seenQuestions = new Set();
73
+ for (let i = 0; i < input.questions.length; i++) {
74
+ const q = input.questions[i];
75
+ if (!q || typeof q !== 'object') {
76
+ return { valid: false, error: `questions[${i}] must be an object` };
77
+ }
78
+ if (typeof q.question !== 'string' || !q.question.trim()) {
79
+ return { valid: false, error: `questions[${i}].question must be a non-empty string` };
80
+ }
81
+ if (seenQuestions.has(q.question)) {
82
+ return { valid: false, error: `duplicate question text at questions[${i}]` };
83
+ }
84
+ seenQuestions.add(q.question);
85
+ if (typeof q.header !== 'string' || !q.header.trim()) {
86
+ return { valid: false, error: `questions[${i}].header must be a non-empty string` };
87
+ }
88
+ if (q.header.length > 12) {
89
+ return { valid: false, error: `questions[${i}].header must be ≤ 12 chars (got ${q.header.length})` };
90
+ }
91
+ if (!Array.isArray(q.options) || q.options.length < 2 || q.options.length > 4) {
92
+ return { valid: false, error: `questions[${i}].options must have 2–4 items` };
93
+ }
94
+ const seenLabels = new Set();
95
+ for (let j = 0; j < q.options.length; j++) {
96
+ const opt = q.options[j];
97
+ if (!opt || typeof opt !== 'object') {
98
+ return { valid: false, error: `questions[${i}].options[${j}] must be an object` };
99
+ }
100
+ if (typeof opt.label !== 'string' || !opt.label.trim()) {
101
+ return { valid: false, error: `questions[${i}].options[${j}].label must be a non-empty string` };
102
+ }
103
+ if (seenLabels.has(opt.label)) {
104
+ return { valid: false, error: `duplicate option label "${opt.label}" in questions[${i}]` };
105
+ }
106
+ seenLabels.add(opt.label);
107
+ }
108
+ }
109
+ return { valid: true };
110
+ },
111
+ async execute(input) {
112
+ const questions = input.questions;
113
+ if (!_askUserFn) {
114
+ // Headless / SDK / non-TUI host. Tell the agent there's no
115
+ // interactive UI so it can fall back to a default.
116
+ return JSON.stringify({
117
+ answers: {},
118
+ cancelled: true,
119
+ reason: 'No interactive UI is attached to this session. AskUser is unavailable here — pick a sensible default and proceed, or surface the question in your reply.',
120
+ }, null, 2);
121
+ }
122
+ const result = await _askUserFn(questions);
123
+ return JSON.stringify(result, null, 2);
124
+ },
125
+ };
126
+ //# sourceMappingURL=askUser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"askUser.js","sourceRoot":"","sources":["../../src/tools/askUser.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,23 @@
1
1
  import { spawn } from 'child_process';
2
2
  import { isContentAllowed, isContentDenied } from '../permissions/checker.js';
3
3
  const MAX_OUTPUT = 20_000;
4
- function runCommand(command, timeout) {
4
+ // Cap per-stream buffer to 4× the output limit. Without this, a runaway
5
+ // command (`cat /dev/urandom`, broken `npm run build`) accumulates an
6
+ // unbounded JS string in memory before we ever get to truncate it.
7
+ // This is the difference between "tool reports truncated" and "node
8
+ // process gets OOM-killed mid-session".
9
+ const MAX_BUFFER = MAX_OUTPUT * 4;
10
+ // ── Pure system shell ─────────────────────────────────────────────
11
+ //
12
+ // Bash used to call `tryKernel()` first to opportunistically intercept
13
+ // hub-skill invocations like `xl books`. That made routing implicit and
14
+ // hard to debug — it was never obvious whether a given Bash call had
15
+ // actually hit /bin/sh or had been redirected into AppleScript.
16
+ //
17
+ // The kernel intercept now lives behind a separate `Yome` tool
18
+ // (cli/src/tools/yome.ts). Bash is once again *only* a system shell;
19
+ // the agent picks the right tool up-front based on intent.
20
+ function runShell(command, timeout) {
5
21
  return new Promise((resolve) => {
6
22
  const proc = spawn('sh', ['-c', command], {
7
23
  cwd: process.cwd(),
@@ -10,15 +26,41 @@ function runCommand(command, timeout) {
10
26
  });
11
27
  let stdout = '';
12
28
  let stderr = '';
29
+ let stdoutOverflow = false;
30
+ let stderrOverflow = false;
13
31
  let killed = false;
14
32
  const timer = setTimeout(() => {
15
33
  killed = true;
16
34
  proc.kill('SIGTERM');
17
35
  }, timeout);
18
- proc.stdout.on('data', (data) => { stdout += data.toString(); });
19
- proc.stderr.on('data', (data) => { stderr += data.toString(); });
36
+ // Stream-side cap: once a buffer hits MAX_BUFFER chars we stop
37
+ // accumulating from that pipe. The child can keep running (we don't
38
+ // want to break commands that legitimately produce a lot of output —
39
+ // tests, builds, etc.) but the agent's memory stays bounded.
40
+ proc.stdout.on('data', (data) => {
41
+ if (stdoutOverflow)
42
+ return;
43
+ stdout += data.toString();
44
+ if (stdout.length > MAX_BUFFER) {
45
+ stdout = stdout.slice(0, MAX_BUFFER);
46
+ stdoutOverflow = true;
47
+ }
48
+ });
49
+ proc.stderr.on('data', (data) => {
50
+ if (stderrOverflow)
51
+ return;
52
+ stderr += data.toString();
53
+ if (stderr.length > MAX_BUFFER) {
54
+ stderr = stderr.slice(0, MAX_BUFFER);
55
+ stderrOverflow = true;
56
+ }
57
+ });
20
58
  proc.on('close', (code) => {
21
59
  clearTimeout(timer);
60
+ if (stdoutOverflow)
61
+ stdout += `\n[stdout capped at ${MAX_BUFFER} chars]`;
62
+ if (stderrOverflow)
63
+ stderr += `\n[stderr capped at ${MAX_BUFFER} chars]`;
22
64
  if (killed) {
23
65
  resolve({ stdout, stderr: `Command timed out after ${timeout / 1000}s`, exitCode: 124 });
24
66
  }
@@ -32,9 +74,24 @@ function runCommand(command, timeout) {
32
74
  });
33
75
  });
34
76
  }
77
+ function formatOutput(stdout, stderr, exitCode) {
78
+ if (exitCode === 0) {
79
+ const result = stdout.trim();
80
+ if (result.length > MAX_OUTPUT) {
81
+ return result.slice(0, MAX_OUTPUT) + `\n\n[Output truncated at ${MAX_OUTPUT} chars]`;
82
+ }
83
+ return result || '(no output)';
84
+ }
85
+ const output = [stdout.trim(), stderr.trim()].filter(Boolean).join('\n');
86
+ return `Exit code: ${exitCode}\n${output}`;
87
+ }
35
88
  export const bashTool = {
36
89
  name: 'Bash',
37
- description: 'Execute a shell command and return its output. Commands run in the current working directory.',
90
+ description: 'Execute a system shell command via /bin/sh and return its output. ' +
91
+ 'Use this for real shell operations: ls, cat, mkdir, git, curl, build/test runners, pipes, redirects, etc. ' +
92
+ 'Commands run in the current working directory. ' +
93
+ 'This tool does NOT route to yome hub skills — to invoke an installed skill (xl, ppt, cal, fs, rem, …) ' +
94
+ 'use the dedicated `Yome` tool instead.',
38
95
  inputSchema: {
39
96
  type: 'object',
40
97
  properties: {
@@ -63,16 +120,8 @@ export const bashTool = {
63
120
  async execute(input) {
64
121
  const command = input.command;
65
122
  const timeout = (input.timeout || 30) * 1000;
66
- const { stdout, stderr, exitCode } = await runCommand(command, timeout);
67
- if (exitCode === 0) {
68
- const result = stdout.trim();
69
- if (result.length > MAX_OUTPUT) {
70
- return result.slice(0, MAX_OUTPUT) + `\n\n[Output truncated at ${MAX_OUTPUT} chars]`;
71
- }
72
- return result || '(no output)';
73
- }
74
- const output = [stdout.trim(), stderr.trim()].filter(Boolean).join('\n');
75
- return `Exit code: ${exitCode}\n${output}`;
123
+ const { stdout, stderr, exitCode } = await runShell(command, timeout);
124
+ return formatOutput(stdout, stderr, exitCode);
76
125
  },
77
126
  };
78
127
  //# sourceMappingURL=bash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE9E,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B,SAAS,UAAU,CAAC,OAAe,EAAE,OAAe;IAClD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;YACxC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,KAAK,CAAC;QAEnB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC,EAAE,OAAO,CAAC,CAAC;QAEZ,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,2BAA2B,OAAO,GAAG,IAAI,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3F,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACvB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAY;IAC/B,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,+FAA+F;IAC5G,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;YACxE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;SAC7E;QACD,QAAQ,EAAE,CAAC,SAAS,CAAC;KACtB;IACD,UAAU,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC;IAC9B,gBAAgB,CAAC,KAA8B,EAAE,GAA0B;QACzE,MAAM,OAAO,GAAI,KAAK,CAAC,OAAkB,IAAI,EAAE,CAAC;QAChD,IAAI,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;YAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,sCAAsC,OAAO,EAAE,EAAE,CAAC;QACxF,CAAC;QACD,IAAI,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAC/B,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,sBAAsB,OAAO,GAAG,EAAE,CAAC;IAChF,CAAC;IACD,aAAa,CAAC,KAAK;QACjB,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;QACxD,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,KAAK;QACjB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAiB,CAAC;QACxC,MAAM,OAAO,GAAG,CAAE,KAAK,CAAC,OAAkB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;QAEzD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAExE,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;gBAC/B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,4BAA4B,UAAU,SAAS,CAAC;YACvF,CAAC;YACD,OAAO,MAAM,IAAI,aAAa,CAAC;QACjC,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,OAAO,cAAc,QAAQ,KAAK,MAAM,EAAE,CAAC;IAC7C,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,37 @@
1
1
  import type { ToolDef, AnthropicTool } from '../types.js';
2
2
  import type { ToolPermissionContext } from '../permissions/types.js';
3
3
  export declare const BASE_TOOLS: ToolDef[];
4
+ export { setAskUserHandler } from './askUser.js';
5
+ export type { AskUserQuestion, AskUserResult } from './askUser.js';
4
6
  export declare function registerTool(tool: ToolDef): void;
5
7
  export declare function getToolByName(name: string): ToolDef | undefined;
6
8
  export declare function getAllTools(): ToolDef[];
7
9
  export declare function getAnthropicTools(): AnthropicTool[];
10
+ /**
11
+ * Result returned by the UI after the user resolves an approval prompt.
12
+ * - allow: proceed with this single invocation
13
+ * - deny: refuse this invocation; optional `feedback` is forwarded to the model
14
+ * and `abort` cancels the rest of the current tool_use batch
15
+ */
16
+ export type AskPermissionResult = {
17
+ decision: 'allow';
18
+ } | {
19
+ decision: 'deny';
20
+ feedback?: string;
21
+ abort?: boolean;
22
+ };
8
23
  export declare function setPermissionContext(ctx: ToolPermissionContext): void;
9
24
  export declare function getPermissionContext(): ToolPermissionContext | null;
10
25
  /**
11
26
  * Register a callback that will be called when a tool requires user approval.
12
- * Return true to allow, false to deny.
27
+ * Return an AskPermissionResult describing the user's choice.
28
+ */
29
+ export declare function setAskPermissionHandler(fn: (toolName: string, message: string, input: Record<string, unknown>) => Promise<AskPermissionResult>): void;
30
+ /**
31
+ * Sentinel substring embedded in tool_result content when the user explicitly
32
+ * rejects a tool_use. Loops detect this prefix to short-circuit the remaining
33
+ * tool_use blocks in the same model turn (mirrors claude-code's REJECT_MESSAGE
34
+ * + cancelAndAbort behavior).
13
35
  */
14
- export declare function setAskPermissionHandler(fn: (toolName: string, message: string, input: Record<string, unknown>) => Promise<boolean>): void;
36
+ export declare const REJECT_SENTINEL = "[YOME_PERMISSION_DENIED]";
15
37
  export declare function executeTool(name: string, input: Record<string, unknown>, signal?: AbortSignal): Promise<string>;
@@ -3,19 +3,37 @@ import { readTool } from './read.js';
3
3
  import { editTool } from './edit.js';
4
4
  import { writeTool } from './write.js';
5
5
  import { bashTool } from './bash.js';
6
+ import { yomeTool } from './yome.js';
6
7
  import { globTool } from './glob.js';
7
8
  import { grepTool } from './grep.js';
8
9
  import { lsTool } from './ls.js';
10
+ import { askUserTool } from './askUser.js';
11
+ import { todoWriteTool } from './todoWrite.js';
9
12
  const DEFAULT_MAX_RESULT_CHARS = 20_000;
13
+ // Hub skill invocations are handled by the dedicated `Yome` tool, which
14
+ // runs the kernel in cli/src/skills/runner/kernel.ts. `Bash` is now a
15
+ // pure /bin/sh wrapper with no implicit skill routing — the agent picks
16
+ // the right tool based on intent (skill call vs shell op).
17
+ //
18
+ // `AskUser` and `TodoWrite` are interactive / state-management tools.
19
+ // AskUser pauses the agent loop until the TUI returns the user's
20
+ // answers (and degrades to "no UI" in headless mode); TodoWrite mutates
21
+ // session-scope todo state that the UI subscribes to.
10
22
  export const BASE_TOOLS = [
11
23
  readTool,
12
24
  editTool,
13
25
  writeTool,
14
26
  bashTool,
27
+ yomeTool,
28
+ askUserTool,
29
+ todoWriteTool,
15
30
  globTool,
16
31
  grepTool,
17
32
  lsTool,
18
33
  ];
34
+ // Re-export the AskUser handler hook so App.tsx can register the TUI
35
+ // implementation without reaching into the tools/ subtree directly.
36
+ export { setAskUserHandler } from './askUser.js';
19
37
  const toolMap = new Map();
20
38
  for (const t of BASE_TOOLS)
21
39
  toolMap.set(t.name, t);
@@ -47,11 +65,33 @@ export function getPermissionContext() {
47
65
  }
48
66
  /**
49
67
  * Register a callback that will be called when a tool requires user approval.
50
- * Return true to allow, false to deny.
68
+ * Return an AskPermissionResult describing the user's choice.
51
69
  */
52
70
  export function setAskPermissionHandler(fn) {
53
71
  _askPermissionFn = fn;
54
72
  }
73
+ /**
74
+ * Sentinel substring embedded in tool_result content when the user explicitly
75
+ * rejects a tool_use. Loops detect this prefix to short-circuit the remaining
76
+ * tool_use blocks in the same model turn (mirrors claude-code's REJECT_MESSAGE
77
+ * + cancelAndAbort behavior).
78
+ */
79
+ export const REJECT_SENTINEL = '[YOME_PERMISSION_DENIED]';
80
+ const DENIAL_GUIDANCE = 'IMPORTANT: You may attempt the user\'s underlying goal with a different tool or approach, ' +
81
+ 'but do not try to bypass the intent of this denial. If you cannot proceed without this ' +
82
+ 'capability, stop and explain to the user what you were trying to do and why.';
83
+ function buildRejectMessage(toolName, feedback) {
84
+ const base = `${REJECT_SENTINEL} The user rejected the ${toolName} tool use. ` +
85
+ `The action was NOT performed (no files changed, no commands executed). ` +
86
+ `Stop the current plan and wait for the user's next instruction unless they provided guidance below.`;
87
+ const tail = feedback && feedback.trim()
88
+ ? `\nUser feedback: ${feedback.trim()}`
89
+ : '';
90
+ return `${base}${tail}\n${DENIAL_GUIDANCE}`;
91
+ }
92
+ function buildAutoDenyMessage(toolName, reason) {
93
+ return `${REJECT_SENTINEL} Permission to use ${toolName} was denied by a configured rule: ${reason}. ${DENIAL_GUIDANCE}`;
94
+ }
55
95
  export async function executeTool(name, input, signal) {
56
96
  const tool = toolMap.get(name);
57
97
  if (!tool)
@@ -68,13 +108,22 @@ export async function executeTool(name, input, signal) {
68
108
  const toolResult = tool.checkPermissions?.(input, _permCtx);
69
109
  const decision = checkPermission(tool.name, tool.isReadOnly(), _permCtx, toolResult ?? undefined);
70
110
  if (decision.behavior === 'deny') {
71
- return `Permission denied: ${decision.message}`;
111
+ return buildAutoDenyMessage(tool.name, decision.message);
72
112
  }
73
113
  if (decision.behavior === 'ask') {
74
114
  if (_askPermissionFn) {
75
- const allowed = await _askPermissionFn(tool.name, decision.message, input);
76
- if (!allowed) {
77
- return `Permission denied by user for ${tool.name}.`;
115
+ const result = await _askPermissionFn(tool.name, decision.message, input);
116
+ if (result.decision === 'deny') {
117
+ if (result.abort) {
118
+ // Hard abort — caller listens on its own AbortSignal but we still
119
+ // return a synthetic tool_result so the model gets a chance to see
120
+ // why we stopped before the loop short-circuits.
121
+ try {
122
+ signal?.controller?.abort?.();
123
+ }
124
+ catch { /* noop */ }
125
+ }
126
+ return buildRejectMessage(tool.name, result.feedback);
78
127
  }
79
128
  }
80
129
  // If no handler is registered, fall through and allow (default permissive)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ToolDef } from '../types.js';
2
+ export declare const skillCallTool: ToolDef;
@@ -0,0 +1,77 @@
1
+ // cli/src/tools/skillCall.ts
2
+ //
3
+ // `SkillCall` — agent tool that invokes an action on an installed yome
4
+ // hub skill. This is the only correct way for the LLM to use hub skills;
5
+ // it must NOT try to map them to ad-hoc shell commands like
6
+ // `yome ppt new` (the model used to do that — `Bash(yome ppt new)`
7
+ // always fails since there's no such CLI subcommand).
8
+ //
9
+ // Input shape (kept minimal so the system prompt can teach it cheaply):
10
+ //
11
+ // {
12
+ // "slug": "@yome/ppt",
13
+ // "action": "new",
14
+ // "positionals": ["/Users/me/Desktop/hello.pptx"],
15
+ // "flags": { "force": true }
16
+ // }
17
+ //
18
+ // Output is the dispatcher's stdout (or stderr prefixed with "ERROR:").
19
+ import { invokeSkill } from '../yomeSkills/invoke.js';
20
+ export const skillCallTool = {
21
+ name: 'SkillCall',
22
+ description: 'Invoke an action on an installed yome hub skill. ' +
23
+ 'Use this whenever the user asks to do something that an installed skill (`yome skill list`) supports — ' +
24
+ 'for example creating/editing a PowerPoint with @yome/ppt. ' +
25
+ 'Do NOT shell out to commands like "yome ppt new" — those do not exist; only this tool dispatches skills.',
26
+ inputSchema: {
27
+ type: 'object',
28
+ properties: {
29
+ slug: {
30
+ type: 'string',
31
+ description: 'Skill slug like "@yome/ppt", or just the domain like "ppt".',
32
+ },
33
+ action: {
34
+ type: 'string',
35
+ description: 'Action name from the skill\'s command list (e.g. "new", "open", "slide.add", "title", "save", "export").',
36
+ },
37
+ positionals: {
38
+ type: 'array',
39
+ items: { type: 'string' },
40
+ description: 'Positional arguments. For ppt.new this is the .pptx path.',
41
+ },
42
+ flags: {
43
+ type: 'object',
44
+ description: 'Named flags. Values are strings, numbers, or booleans.',
45
+ },
46
+ },
47
+ required: ['slug', 'action'],
48
+ },
49
+ isReadOnly: () => false,
50
+ validateInput(input) {
51
+ if (typeof input.slug !== 'string' || input.slug.length === 0) {
52
+ return { valid: false, error: 'slug must be a non-empty string' };
53
+ }
54
+ if (typeof input.action !== 'string' || input.action.length === 0) {
55
+ return { valid: false, error: 'action must be a non-empty string' };
56
+ }
57
+ if (input.positionals !== undefined && !Array.isArray(input.positionals)) {
58
+ return { valid: false, error: 'positionals must be an array of strings' };
59
+ }
60
+ if (input.flags !== undefined && (typeof input.flags !== 'object' || Array.isArray(input.flags))) {
61
+ return { valid: false, error: 'flags must be an object' };
62
+ }
63
+ return { valid: true };
64
+ },
65
+ async execute(input) {
66
+ const slug = String(input.slug);
67
+ const action = String(input.action);
68
+ const positionals = input.positionals ?? [];
69
+ const flags = input.flags ?? {};
70
+ const r = await invokeSkill({ slugOrDomain: slug, action, positionals, flags });
71
+ if (!r.ok) {
72
+ return `ERROR (exit ${r.exitCode}): ${r.stderr || '(no stderr)'}`;
73
+ }
74
+ return r.stdout || '(no output)';
75
+ },
76
+ };
77
+ //# sourceMappingURL=skillCall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillCall.js","sourceRoot":"","sources":["../../src/tools/skillCall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ToolDef } from '../types.js';
2
+ export declare const todoWriteTool: ToolDef;