@downcity/plugins 1.0.174 → 1.0.193

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 (301) hide show
  1. package/bin/BuiltinPlugins.d.ts +4 -9
  2. package/bin/BuiltinPlugins.d.ts.map +1 -1
  3. package/bin/BuiltinPlugins.js +4 -8
  4. package/bin/BuiltinPlugins.js.map +1 -1
  5. package/bin/chat/Action.d.ts +8 -2
  6. package/bin/chat/Action.d.ts.map +1 -1
  7. package/bin/chat/Action.js +9 -5
  8. package/bin/chat/Action.js.map +1 -1
  9. package/bin/chat/ChatPlugin.d.ts +2 -22
  10. package/bin/chat/ChatPlugin.d.ts.map +1 -1
  11. package/bin/chat/ChatPlugin.js +2 -21
  12. package/bin/chat/ChatPlugin.js.map +1 -1
  13. package/bin/chat/Index.d.ts +1 -1
  14. package/bin/chat/Index.d.ts.map +1 -1
  15. package/bin/chat/channels/BaseChatChannel.js +1 -1
  16. package/bin/chat/channels/BaseChatChannel.js.map +1 -1
  17. package/bin/chat/channels/Configuration.d.ts +1 -1
  18. package/bin/chat/channels/Configuration.js +1 -1
  19. package/bin/chat/channels/RuntimeChannel.d.ts +2 -3
  20. package/bin/chat/channels/RuntimeChannel.d.ts.map +1 -1
  21. package/bin/chat/channels/RuntimeChannel.js +0 -8
  22. package/bin/chat/channels/RuntimeChannel.js.map +1 -1
  23. package/bin/chat/channels/feishu/Feishu.d.ts.map +1 -1
  24. package/bin/chat/channels/feishu/Feishu.js +2 -1
  25. package/bin/chat/channels/feishu/Feishu.js.map +1 -1
  26. package/bin/chat/runtime/ChannelContextStore.d.ts.map +1 -1
  27. package/bin/chat/runtime/ChannelContextStore.js +13 -12
  28. package/bin/chat/runtime/ChannelContextStore.js.map +1 -1
  29. package/bin/chat/runtime/ChatActionExecution.d.ts +26 -1
  30. package/bin/chat/runtime/ChatActionExecution.d.ts.map +1 -1
  31. package/bin/chat/runtime/ChatActionExecution.js +31 -3
  32. package/bin/chat/runtime/ChatActionExecution.js.map +1 -1
  33. package/bin/chat/runtime/ChatActionInput.d.ts +1 -2
  34. package/bin/chat/runtime/ChatActionInput.d.ts.map +1 -1
  35. package/bin/chat/runtime/ChatActionInput.js +1 -27
  36. package/bin/chat/runtime/ChatActionInput.js.map +1 -1
  37. package/bin/chat/runtime/ChatChannelActions.d.ts +2 -66
  38. package/bin/chat/runtime/ChatChannelActions.d.ts.map +1 -1
  39. package/bin/chat/runtime/ChatChannelActions.js +3 -195
  40. package/bin/chat/runtime/ChatChannelActions.js.map +1 -1
  41. package/bin/chat/runtime/ChatChannelConfig.d.ts +2 -23
  42. package/bin/chat/runtime/ChatChannelConfig.d.ts.map +1 -1
  43. package/bin/chat/runtime/ChatChannelConfig.js +3 -116
  44. package/bin/chat/runtime/ChatChannelConfig.js.map +1 -1
  45. package/bin/chat/runtime/ChatChannelCore.d.ts +0 -14
  46. package/bin/chat/runtime/ChatChannelCore.d.ts.map +1 -1
  47. package/bin/chat/runtime/ChatChannelCore.js +1 -1
  48. package/bin/chat/runtime/ChatChannelCore.js.map +1 -1
  49. package/bin/chat/runtime/ChatChannelFacade.d.ts +1 -1
  50. package/bin/chat/runtime/ChatChannelFacade.d.ts.map +1 -1
  51. package/bin/chat/runtime/ChatChannelFacade.js +1 -1
  52. package/bin/chat/runtime/ChatChannelFacade.js.map +1 -1
  53. package/bin/chat/runtime/ChatHistoryStore.d.ts.map +1 -1
  54. package/bin/chat/runtime/ChatHistoryStore.js +4 -3
  55. package/bin/chat/runtime/ChatHistoryStore.js.map +1 -1
  56. package/bin/chat/runtime/ChatPluginActionRegistry.d.ts.map +1 -1
  57. package/bin/chat/runtime/ChatPluginActionRegistry.js +27 -89
  58. package/bin/chat/runtime/ChatPluginActionRegistry.js.map +1 -1
  59. package/bin/chat/runtime/ChatPluginSystem.d.ts +3 -2
  60. package/bin/chat/runtime/ChatPluginSystem.d.ts.map +1 -1
  61. package/bin/chat/runtime/ChatPluginSystem.js +5 -5
  62. package/bin/chat/runtime/ChatPluginSystem.js.map +1 -1
  63. package/bin/chat/runtime/ChatQueueStore.d.ts +1 -1
  64. package/bin/chat/runtime/ChatQueueStore.js +2 -2
  65. package/bin/chat/runtime/ChatQueueStore.js.map +1 -1
  66. package/bin/chat/runtime/ChatQueueWorker.js +1 -1
  67. package/bin/chat/runtime/ChatQueueWorker.js.map +1 -1
  68. package/bin/chat/runtime/ChatSessionDelete.d.ts.map +1 -1
  69. package/bin/chat/runtime/ChatSessionDelete.js +11 -20
  70. package/bin/chat/runtime/ChatSessionDelete.js.map +1 -1
  71. package/bin/chat/runtime/ChatStorage.d.ts +32 -0
  72. package/bin/chat/runtime/ChatStorage.d.ts.map +1 -0
  73. package/bin/chat/runtime/ChatStorage.js +158 -0
  74. package/bin/chat/runtime/ChatStorage.js.map +1 -0
  75. package/bin/chat/runtime/SystemPrompt.d.ts +3 -2
  76. package/bin/chat/runtime/SystemPrompt.d.ts.map +1 -1
  77. package/bin/chat/runtime/SystemPrompt.js +4 -5
  78. package/bin/chat/runtime/SystemPrompt.js.map +1 -1
  79. package/bin/chat/types/ChannelConfiguration.d.ts +2 -2
  80. package/bin/chat/types/ChatPluginActionPayload.d.ts +7 -45
  81. package/bin/chat/types/ChatPluginActionPayload.d.ts.map +1 -1
  82. package/bin/chat/types/ChatPluginOptions.d.ts +0 -21
  83. package/bin/chat/types/ChatPluginOptions.d.ts.map +1 -1
  84. package/bin/chat/types/ChatStorage.d.ts +36 -0
  85. package/bin/chat/types/ChatStorage.d.ts.map +1 -0
  86. package/bin/chat/types/ChatStorage.js +9 -0
  87. package/bin/chat/types/ChatStorage.js.map +1 -0
  88. package/bin/contact/Action.d.ts +3 -2
  89. package/bin/contact/Action.d.ts.map +1 -1
  90. package/bin/contact/Action.js +2 -2
  91. package/bin/contact/Action.js.map +1 -1
  92. package/bin/contact/ContactPlugin.d.ts.map +1 -1
  93. package/bin/contact/ContactPlugin.js +17 -14
  94. package/bin/contact/ContactPlugin.js.map +1 -1
  95. package/bin/contact/runtime/ChatRuntime.js +1 -1
  96. package/bin/contact/runtime/ChatRuntime.js.map +1 -1
  97. package/bin/contact/types/ContactPluginOptions.d.ts +4 -0
  98. package/bin/contact/types/ContactPluginOptions.d.ts.map +1 -1
  99. package/bin/index.d.ts +5 -5
  100. package/bin/index.d.ts.map +1 -1
  101. package/bin/index.js +2 -2
  102. package/bin/index.js.map +1 -1
  103. package/bin/memory/Action.d.ts.map +1 -1
  104. package/bin/memory/Action.js +16 -4
  105. package/bin/memory/Action.js.map +1 -1
  106. package/bin/memory/runtime/Store.d.ts.map +1 -1
  107. package/bin/memory/runtime/Store.js +0 -22
  108. package/bin/memory/runtime/Store.js.map +1 -1
  109. package/bin/memory/runtime/Writer.d.ts +1 -1
  110. package/bin/memory/runtime/Writer.d.ts.map +1 -1
  111. package/bin/memory/runtime/Writer.js +2 -4
  112. package/bin/memory/runtime/Writer.js.map +1 -1
  113. package/bin/skill/Command.d.ts +3 -11
  114. package/bin/skill/Command.d.ts.map +1 -1
  115. package/bin/skill/Command.js +3 -31
  116. package/bin/skill/Command.js.map +1 -1
  117. package/bin/skill/PROMPT.d.ts +1 -1
  118. package/bin/skill/PROMPT.d.ts.map +1 -1
  119. package/bin/skill/PROMPT.js +1 -1
  120. package/bin/skill/PROMPT.js.map +1 -1
  121. package/bin/skill/Plugin.d.ts +3 -2
  122. package/bin/skill/Plugin.d.ts.map +1 -1
  123. package/bin/skill/Plugin.js +37 -129
  124. package/bin/skill/Plugin.js.map +1 -1
  125. package/bin/skill/runtime/Prompt.d.ts +11 -2
  126. package/bin/skill/runtime/Prompt.d.ts.map +1 -1
  127. package/bin/skill/runtime/Prompt.js +93 -8
  128. package/bin/skill/runtime/Prompt.js.map +1 -1
  129. package/bin/skill/runtime/SystemProvider.d.ts +2 -1
  130. package/bin/skill/runtime/SystemProvider.d.ts.map +1 -1
  131. package/bin/skill/runtime/SystemProvider.js +4 -9
  132. package/bin/skill/runtime/SystemProvider.js.map +1 -1
  133. package/bin/skill/types/SkillPlugin.d.ts +6 -18
  134. package/bin/skill/types/SkillPlugin.d.ts.map +1 -1
  135. package/bin/skill/types/SkillPlugin.js +2 -2
  136. package/bin/sound/Plugin.d.ts +69 -0
  137. package/bin/sound/Plugin.d.ts.map +1 -0
  138. package/bin/sound/Plugin.js +623 -0
  139. package/bin/sound/Plugin.js.map +1 -0
  140. package/bin/sound/types/SoundPlugin.d.ts +150 -0
  141. package/bin/sound/types/SoundPlugin.d.ts.map +1 -0
  142. package/bin/sound/types/SoundPlugin.js +10 -0
  143. package/bin/sound/types/SoundPlugin.js.map +1 -0
  144. package/bin/task/Action.d.ts +2 -0
  145. package/bin/task/Action.d.ts.map +1 -1
  146. package/bin/task/Action.js +6 -0
  147. package/bin/task/Action.js.map +1 -1
  148. package/bin/task/runtime/Runner.d.ts +4 -0
  149. package/bin/task/runtime/Runner.d.ts.map +1 -1
  150. package/bin/task/runtime/Runner.js +15 -11
  151. package/bin/task/runtime/Runner.js.map +1 -1
  152. package/bin/task/runtime/TaskActionExecution.d.ts +2 -0
  153. package/bin/task/runtime/TaskActionExecution.d.ts.map +1 -1
  154. package/bin/task/runtime/TaskActionExecution.js +1 -0
  155. package/bin/task/runtime/TaskActionExecution.js.map +1 -1
  156. package/bin/task/runtime/TaskPluginActionRegistry.d.ts.map +1 -1
  157. package/bin/task/runtime/TaskPluginActionRegistry.js +1 -0
  158. package/bin/task/runtime/TaskPluginActionRegistry.js.map +1 -1
  159. package/bin/task/runtime/TaskRunChatDispatch.js +1 -1
  160. package/bin/task/runtime/TaskRunChatDispatch.js.map +1 -1
  161. package/bin/task/runtime/TaskRunnerRound.d.ts.map +1 -1
  162. package/bin/task/runtime/TaskRunnerRound.js +19 -26
  163. package/bin/task/runtime/TaskRunnerRound.js.map +1 -1
  164. package/bin/task/runtime/TaskRunnerSession.d.ts +6 -2
  165. package/bin/task/runtime/TaskRunnerSession.d.ts.map +1 -1
  166. package/bin/task/runtime/TaskRunnerSession.js +93 -72
  167. package/bin/task/runtime/TaskRunnerSession.js.map +1 -1
  168. package/bin/task/runtime/TaskRunnerTypes.d.ts +4 -4
  169. package/bin/task/runtime/TaskRunnerTypes.d.ts.map +1 -1
  170. package/bin/task/types/TaskPluginOptions.d.ts.map +1 -1
  171. package/bin/web/PROMPT.d.ts +1 -1
  172. package/bin/web/PROMPT.d.ts.map +1 -1
  173. package/bin/web/PROMPT.js +2 -2
  174. package/bin/web/PROMPT.js.map +1 -1
  175. package/bin/web/Plugin.d.ts +1 -21
  176. package/bin/web/Plugin.d.ts.map +1 -1
  177. package/bin/web/Plugin.js +14 -79
  178. package/bin/web/Plugin.js.map +1 -1
  179. package/bin/web/runtime/Prompt.d.ts +14 -0
  180. package/bin/web/runtime/Prompt.d.ts.map +1 -0
  181. package/bin/web/runtime/Prompt.js +77 -0
  182. package/bin/web/runtime/Prompt.js.map +1 -0
  183. package/bin/web/types/WebPlugin.d.ts +40 -29
  184. package/bin/web/types/WebPlugin.d.ts.map +1 -1
  185. package/bin/web/types/WebPlugin.js +11 -3
  186. package/bin/web/types/WebPlugin.js.map +1 -1
  187. package/bin/workboard/runtime/Collector.js +1 -1
  188. package/bin/workboard/runtime/Collector.js.map +1 -1
  189. package/bin/workboard/runtime/Normalizer.js +1 -1
  190. package/bin/workboard/runtime/Normalizer.js.map +1 -1
  191. package/bin/workboard/runtime/SessionSummary.d.ts.map +1 -1
  192. package/bin/workboard/runtime/SessionSummary.js +11 -38
  193. package/bin/workboard/runtime/SessionSummary.js.map +1 -1
  194. package/package.json +8 -4
  195. package/scripts/chat-access.test.mjs +1 -1
  196. package/scripts/chat-channel-config.test.mjs +15 -64
  197. package/scripts/chat-storage.test.mjs +92 -0
  198. package/scripts/skill-plugin.test.mjs +93 -0
  199. package/scripts/sound-plugin.test.mjs +250 -0
  200. package/scripts/web-plugin.test.mjs +85 -0
  201. package/src/BuiltinPlugins.ts +7 -17
  202. package/src/chat/Action.ts +16 -5
  203. package/src/chat/ChatPlugin.ts +6 -35
  204. package/src/chat/Index.ts +0 -1
  205. package/src/chat/channels/BaseChatChannel.ts +1 -1
  206. package/src/chat/channels/Configuration.ts +1 -1
  207. package/src/chat/channels/RuntimeChannel.ts +2 -14
  208. package/src/chat/channels/feishu/Feishu.ts +2 -1
  209. package/src/chat/runtime/ChannelContextStore.ts +16 -12
  210. package/src/chat/runtime/ChatActionExecution.ts +48 -3
  211. package/src/chat/runtime/ChatActionInput.ts +0 -31
  212. package/src/chat/runtime/ChatChannelActions.ts +3 -254
  213. package/src/chat/runtime/ChatChannelConfig.ts +4 -133
  214. package/src/chat/runtime/ChatChannelCore.ts +1 -15
  215. package/src/chat/runtime/ChatChannelFacade.ts +0 -4
  216. package/src/chat/runtime/ChatHistoryStore.ts +4 -3
  217. package/src/chat/runtime/ChatPluginActionRegistry.ts +26 -98
  218. package/src/chat/runtime/ChatPluginSystem.ts +9 -3
  219. package/src/chat/runtime/ChatQueueStore.ts +2 -2
  220. package/src/chat/runtime/ChatQueueWorker.ts +1 -1
  221. package/src/chat/runtime/ChatSessionDelete.ts +11 -21
  222. package/src/chat/runtime/ChatStorage.ts +203 -0
  223. package/src/chat/runtime/SystemPrompt.ts +8 -3
  224. package/src/chat/types/ChannelConfiguration.ts +2 -2
  225. package/src/chat/types/ChatPluginActionPayload.ts +8 -49
  226. package/src/chat/types/ChatPluginOptions.ts +0 -22
  227. package/src/chat/types/ChatStorage.ts +37 -0
  228. package/src/contact/Action.ts +9 -1
  229. package/src/contact/ContactPlugin.ts +38 -14
  230. package/src/contact/runtime/ChatRuntime.ts +1 -1
  231. package/src/contact/types/ContactPluginOptions.ts +6 -0
  232. package/src/index.ts +16 -14
  233. package/src/memory/Action.ts +19 -4
  234. package/src/memory/runtime/Store.ts +0 -27
  235. package/src/memory/runtime/Writer.ts +2 -5
  236. package/src/skill/Command.ts +3 -33
  237. package/src/skill/PROMPT.ts +1 -1
  238. package/src/skill/PROMPT.ts.txt +5 -1
  239. package/src/skill/Plugin.ts +49 -156
  240. package/src/skill/runtime/Prompt.ts +109 -9
  241. package/src/skill/runtime/SystemProvider.ts +5 -9
  242. package/src/skill/types/SkillPlugin.ts +6 -18
  243. package/src/sound/Plugin.ts +699 -0
  244. package/src/sound/types/SoundPlugin.ts +163 -0
  245. package/src/task/Action.ts +8 -0
  246. package/src/task/runtime/Runner.ts +19 -13
  247. package/src/task/runtime/TaskActionExecution.ts +3 -0
  248. package/src/task/runtime/TaskPluginActionRegistry.ts +1 -0
  249. package/src/task/runtime/TaskRunChatDispatch.ts +1 -1
  250. package/src/task/runtime/TaskRunnerRound.ts +20 -38
  251. package/src/task/runtime/TaskRunnerSession.ts +108 -72
  252. package/src/task/runtime/TaskRunnerTypes.ts +4 -4
  253. package/src/task/types/TaskPluginOptions.ts +1 -0
  254. package/src/web/PROMPT.ts +2 -2
  255. package/src/web/PROMPT.ts.txt +4 -2
  256. package/src/web/Plugin.ts +20 -90
  257. package/src/web/runtime/Prompt.ts +99 -0
  258. package/src/web/types/WebPlugin.ts +42 -29
  259. package/src/workboard/runtime/Collector.ts +1 -1
  260. package/src/workboard/runtime/Normalizer.ts +1 -1
  261. package/src/workboard/runtime/SessionSummary.ts +11 -42
  262. package/bin/asr/Plugin.d.ts +0 -63
  263. package/bin/asr/Plugin.d.ts.map +0 -1
  264. package/bin/asr/Plugin.js +0 -280
  265. package/bin/asr/Plugin.js.map +0 -1
  266. package/bin/asr/types/AsrPlugin.d.ts +0 -114
  267. package/bin/asr/types/AsrPlugin.d.ts.map +0 -1
  268. package/bin/asr/types/AsrPlugin.js +0 -10
  269. package/bin/asr/types/AsrPlugin.js.map +0 -1
  270. package/bin/chat/runtime/ChatSession.d.ts +0 -97
  271. package/bin/chat/runtime/ChatSession.d.ts.map +0 -1
  272. package/bin/chat/runtime/ChatSession.js +0 -91
  273. package/bin/chat/runtime/ChatSession.js.map +0 -1
  274. package/bin/chat/runtime/ChatSessionContextComposer.d.ts +0 -45
  275. package/bin/chat/runtime/ChatSessionContextComposer.d.ts.map +0 -1
  276. package/bin/chat/runtime/ChatSessionContextComposer.js +0 -60
  277. package/bin/chat/runtime/ChatSessionContextComposer.js.map +0 -1
  278. package/bin/chat/runtime/ChatSessionTypes.d.ts +0 -30
  279. package/bin/chat/runtime/ChatSessionTypes.d.ts.map +0 -1
  280. package/bin/chat/runtime/ChatSessionTypes.js +0 -9
  281. package/bin/chat/runtime/ChatSessionTypes.js.map +0 -1
  282. package/bin/tts/Plugin.d.ts +0 -49
  283. package/bin/tts/Plugin.d.ts.map +0 -1
  284. package/bin/tts/Plugin.js +0 -247
  285. package/bin/tts/Plugin.js.map +0 -1
  286. package/bin/tts/types/TtsPlugin.d.ts +0 -122
  287. package/bin/tts/types/TtsPlugin.d.ts.map +0 -1
  288. package/bin/tts/types/TtsPlugin.js +0 -10
  289. package/bin/tts/types/TtsPlugin.js.map +0 -1
  290. package/bin/web/runtime/Install.d.ts +0 -19
  291. package/bin/web/runtime/Install.d.ts.map +0 -1
  292. package/bin/web/runtime/Install.js +0 -178
  293. package/bin/web/runtime/Install.js.map +0 -1
  294. package/src/asr/Plugin.ts +0 -322
  295. package/src/asr/types/AsrPlugin.ts +0 -118
  296. package/src/chat/runtime/ChatSession.ts +0 -168
  297. package/src/chat/runtime/ChatSessionContextComposer.ts +0 -106
  298. package/src/chat/runtime/ChatSessionTypes.ts +0 -32
  299. package/src/tts/Plugin.ts +0 -284
  300. package/src/tts/types/TtsPlugin.ts +0 -129
  301. package/src/web/runtime/Install.ts +0 -241
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - skill 不再作为 service 存在,而是作为显式 action + system 提供者接入 plugin 体系。
6
- * - `find/install/list/lookup` 全部通过 plugin actions 暴露。
6
+ * - `find/install` action 只返回 Shell 操作提示,不执行命令或修改文件。
7
+ * - `list/lookup` action 负责读取当前可发现的本地 skill。
7
8
  * - skills overview 文本通过 `plugin.system` 注入,不再依赖 plugin.system。
8
9
  */
9
10
 
@@ -21,14 +22,15 @@ import type {
21
22
  } from "@/skill/types/SkillPlugin.js";
22
23
  import { SKILL_PLUGIN_ACTIONS } from "@/skill/types/SkillPlugin.js";
23
24
  import { resolveSkillPluginOptions } from "@/skill/Config.js";
24
- import { skillFindCommand, skillInstallCommand } from "@/skill/Command.js";
25
25
  import {
26
- findLearnedSkillExact,
27
26
  listSkills,
28
27
  lookupSkill,
29
- searchLearnedSkills,
30
28
  } from "@/skill/Action.js";
31
29
  import { buildSkillsSystemText } from "@/skill/runtime/SystemProvider.js";
30
+ import {
31
+ render_skill_find_prompt,
32
+ render_skill_install_prompt,
33
+ } from "@/skill/runtime/Prompt.js";
32
34
  import { SKILL_PLUGIN_PROMPT } from "@/skill/SkillPromptAssets.js";
33
35
 
34
36
  /**
@@ -41,28 +43,6 @@ function readJsonObject(value: JsonValue): JsonObject {
41
43
  return value as JsonObject;
42
44
  }
43
45
 
44
- /**
45
- * 读取字符串选项。
46
- */
47
- function getStringOpt(
48
- opts: Record<string, JsonValue>,
49
- key: string,
50
- ): string | undefined {
51
- const value = opts[key];
52
- return typeof value === "string" ? value.trim() : undefined;
53
- }
54
-
55
- /**
56
- * 读取布尔选项。
57
- */
58
- function getBooleanOpt(
59
- opts: Record<string, JsonValue>,
60
- key: string,
61
- ): boolean | undefined {
62
- const value = opts[key];
63
- return typeof value === "boolean" ? value : undefined;
64
- }
65
-
66
46
  /**
67
47
  * XML 属性转义。
68
48
  */
@@ -74,61 +54,49 @@ function sanitizeXmlAttr(value: string): string {
74
54
  .replace(/>/g, "&gt;");
75
55
  }
76
56
 
77
- /**
78
- * 从 install spec 推断候选 skill 标识。
79
- */
80
- function inferSkillQueryFromSpec(spec: string): string {
81
- const raw = String(spec || "").trim();
82
- if (!raw) return "";
83
- const normalized = raw.split(/[?#]/, 1)[0]?.trim() || raw;
84
-
85
- const atIndex = normalized.lastIndexOf("@");
86
- if (atIndex > 0 && atIndex < normalized.length - 1) {
87
- return normalized.slice(atIndex + 1).trim();
88
- }
89
-
90
- if (!normalized.includes("/")) return normalized;
91
- return "";
92
- }
93
-
94
57
  function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
95
58
  return {
96
59
  name: "skill",
97
60
  title: "Skill Catalog And Loader",
98
61
  description:
99
- "Finds, installs, lists, and reads local skills, and injects the current skill overview into system prompts so the agent knows what capabilities are available.",
100
- async system(context) {
62
+ "Lists and reads local skills, and injects scan-aware discovery and installation guidance into system prompts.",
63
+ async system(context, run_context) {
101
64
  const dynamicText = String(
102
65
  await buildSkillsSystemText({
103
66
  rootPath: context.rootPath,
104
67
  options,
105
- }),
68
+ }, run_context),
106
69
  ).trim();
107
70
  return [SKILL_PLUGIN_PROMPT, dynamicText].filter(Boolean).join("\n\n");
108
71
  },
109
72
  actions: {
110
73
  [SKILL_PLUGIN_ACTIONS.find]: createAction({
111
- description: "Find unlearned skills that are not in `list`; install only if missing.",
74
+ description:
75
+ "Return shell instructions for finding a skill. This action does not execute the search.",
112
76
  input_schema: {
113
77
  zod: z.object({
114
- query: z.string(),
78
+ query: z.string().trim().min(1),
115
79
  }),
116
80
  json_schema: {
117
81
  type: "object",
118
82
  required: ["query"],
119
83
  properties: {
120
- query: { type: "string", description: "Skill search query." },
84
+ query: {
85
+ type: "string",
86
+ description: "Skill search query.",
87
+ },
121
88
  },
122
89
  },
123
90
  },
124
91
  examples: [
125
92
  {
126
- title: "Find skill",
127
- payload: { query: "web-search" },
93
+ title: "Get skill search instructions",
94
+ payload: { query: "web access" },
128
95
  },
129
96
  ],
130
97
  command: {
131
- description: "Find unlearned skills that are not in `list`; install only if missing.",
98
+ description:
99
+ "Return shell instructions for finding a skill without executing the search.",
132
100
  configure(command) {
133
101
  command.argument("<query>");
134
102
  },
@@ -138,144 +106,69 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
138
106
  return { query };
139
107
  },
140
108
  },
141
- async execute(params): Promise<PluginActionResult<JsonObject>> {
109
+ execute(params): PluginActionResult<JsonObject> {
142
110
  const payload = params.input as SkillPluginFindPayload;
143
- const rootPath = params.context.rootPath;
144
- const exactLearned = findLearnedSkillExact(
145
- rootPath,
146
- payload.query,
147
- options,
148
- );
149
- if (exactLearned) {
150
- return {
151
- success: true,
152
- data: {
153
- query: payload.query,
154
- message: "This skill is already in list; installation is not needed. Run lookup before using it.",
155
- workflow: ["list", "lookup"],
156
- nextAction: "lookup",
157
- learnedSkill: exactLearned,
158
- learnedHints: [],
159
- } as JsonObject,
160
- };
161
- }
162
-
163
- const learnedHints = searchLearnedSkills(
164
- rootPath,
165
- payload.query,
166
- 5,
167
- options,
168
- );
169
- await skillFindCommand(payload.query);
170
111
  return {
171
112
  success: true,
113
+ message: "Skill search instructions ready; no search was executed.",
172
114
  data: {
115
+ kind: "instructions",
173
116
  query: payload.query,
174
- message: "Missing-skill search completed. If the target is not in list, install it and then run lookup.",
175
- workflow: ["find", "install", "lookup"],
176
- nextAction: "install",
177
- learnedSkill: null,
178
- learnedHints,
179
- } as JsonObject,
117
+ prompt: render_skill_find_prompt(payload.query),
118
+ },
180
119
  };
181
120
  },
182
121
  }),
183
122
  [SKILL_PLUGIN_ACTIONS.install]: createAction({
184
- description: "Install a skill that is not in `list`; run lookup after installation.",
123
+ description:
124
+ "Return scan-aware shell instructions for installing a skill. This action does not install anything.",
185
125
  input_schema: {
186
126
  zod: z.object({
187
- spec: z.string(),
188
- global: z.boolean().optional(),
189
- yes: z.boolean().optional(),
190
- agent: z.string().optional(),
127
+ spec: z.string().trim().min(1),
191
128
  }),
192
129
  json_schema: {
193
130
  type: "object",
194
131
  required: ["spec"],
195
132
  properties: {
196
- spec: { type: "string", description: "Skill installation spec." },
197
- global: { type: "boolean", description: "Whether to install globally." },
198
- yes: { type: "boolean", description: "Skip confirmation." },
199
- agent: { type: "string", description: "Target agent." },
133
+ spec: {
134
+ type: "string",
135
+ description: "Skill installation source or spec.",
136
+ },
200
137
  },
201
138
  },
202
139
  },
203
140
  examples: [
204
141
  {
205
- title: "Install skill",
206
- payload: { spec: "web-search", global: true, yes: true },
142
+ title: "Get skill installation instructions",
143
+ payload: { spec: "owner/repository@skill-name" },
207
144
  },
208
145
  ],
209
146
  command: {
210
- description: "Install a skill that is not in `list`; run lookup after installation.",
147
+ description:
148
+ "Return scan-aware shell instructions without installing a skill.",
211
149
  configure(command) {
212
- command
213
- .argument("<spec>")
214
- .option("-g, --global", "全局安装(默认 true)", true)
215
- .option("-y, --yes", "跳过确认(默认 true)", true)
216
- .option("--agent <agent>", "指定 agent");
150
+ command.argument("<spec>");
217
151
  },
218
- mapInput({ args, opts }): SkillPluginInstallPayload {
152
+ mapInput({ args }): SkillPluginInstallPayload {
219
153
  const spec = String(args[0] || "").trim();
220
154
  if (!spec) throw new Error("Missing spec");
221
- return {
222
- spec,
223
- global: getBooleanOpt(opts, "global"),
224
- yes: getBooleanOpt(opts, "yes"),
225
- agent: getStringOpt(opts, "agent"),
226
- };
155
+ return { spec };
227
156
  },
228
157
  },
229
- async execute(params): Promise<PluginActionResult<JsonObject>> {
158
+ execute(params): PluginActionResult<JsonObject> {
230
159
  const payload = params.input as SkillPluginInstallPayload;
231
- const rootPath = params.context.rootPath;
232
- const queryFromSpec = inferSkillQueryFromSpec(payload.spec);
233
- const beforeList = listSkills(rootPath, options).skills;
234
- const beforeIds = new Set(beforeList.map((item) => item.id));
235
-
236
- const learnedBefore =
237
- findLearnedSkillExact(rootPath, queryFromSpec, options) ||
238
- findLearnedSkillExact(rootPath, payload.spec, options);
239
- if (learnedBefore) {
240
- return {
241
- success: true,
242
- data: {
243
- spec: payload.spec,
244
- skipped: true,
245
- message: "The skill is already in list; installation is not needed. Run lookup before using it.",
246
- workflow: ["list", "lookup"],
247
- nextAction: "lookup",
248
- queryFromSpec,
249
- addedSkills: [],
250
- learnedSkill: learnedBefore,
251
- } as JsonObject,
252
- };
253
- }
254
-
255
- await skillInstallCommand(payload.spec, {
256
- global: payload.global,
257
- yes: payload.yes,
258
- agent: payload.agent,
259
- });
260
- const afterList = listSkills(rootPath, options).skills;
261
- const addedSkills = afterList.filter((item) => !beforeIds.has(item.id));
262
- const learnedAfter =
263
- findLearnedSkillExact(rootPath, queryFromSpec, options) ||
264
- findLearnedSkillExact(rootPath, payload.spec, options) ||
265
- (addedSkills.length === 1 ? addedSkills[0] : undefined);
266
-
267
160
  return {
268
161
  success: true,
162
+ message: "Skill installation instructions ready; no files were changed.",
269
163
  data: {
164
+ kind: "instructions",
270
165
  spec: payload.spec,
271
- message: "Skill learning completed. Before using the skill, run lookup to read its SKILL.md content.",
272
- workflow: ["find", "install", "lookup"],
273
- nextAction: "lookup",
274
- skipped: false,
275
- queryFromSpec,
276
- addedSkills,
277
- learnedSkill: learnedAfter || null,
278
- } as JsonObject,
166
+ prompt: render_skill_install_prompt(
167
+ params.context.rootPath,
168
+ options,
169
+ payload.spec,
170
+ ),
171
+ },
279
172
  };
280
173
  },
281
174
  }),
@@ -405,7 +298,7 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
405
298
  }
406
299
 
407
300
  /**
408
- * SkillPlugin:技能发现、安装、读取与 system 注入。
301
+ * SkillPlugin:技能发现、读取与扫描感知的 system 注入。
409
302
  */
410
303
  export class SkillPlugin extends BasePlugin {
411
304
  readonly name = "skill";
@@ -2,30 +2,119 @@
2
2
  * Skill plugin prompt section 渲染器。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 仅负责渲染运行时动态清单(已发现 skills + 扫描根目录)。
5
+ * - 负责渲染运行时动态清单,以及 find/install action 返回的纯提示词。
6
6
  * - 稳定规则放在 `SkillPromptAssets.ts`,避免分散在代码里维护。
7
7
  * - 仅做字符串渲染,不做文件 IO。
8
8
  */
9
9
 
10
10
  import { getSkillSearchRoots } from "./Paths.js";
11
11
  import type { SkillDefinition } from "@/skill/types/SkillDefinition.js";
12
+ import type { SkillRoot } from "@/skill/types/SkillRoot.js";
12
13
  import type { SkillPluginOptions } from "@/skill/types/SkillPlugin.js";
13
14
 
15
+ /**
16
+ * 把外部输入编码为单个 POSIX Shell 参数。
17
+ *
18
+ * 关键点(中文):action 只返回提示词,但提示中的命令仍需避免把 query/spec 解释为额外 Shell 语法。
19
+ */
20
+ function quote_shell_argument(value: string): string {
21
+ return `'${String(value).replaceAll("'", "'\\''")}'`;
22
+ }
23
+
24
+ /**
25
+ * 根据已配置扫描根生成安装位置提示。
26
+ */
27
+ function render_install_root_instructions(
28
+ roots: SkillRoot[],
29
+ spec_argument: string,
30
+ ): string {
31
+ if (roots.length === 0) {
32
+ return [
33
+ "- No scan roots are configured.",
34
+ " Do not install a skill until the SkillPlugin configuration provides a discoverable root.",
35
+ ].join("\n");
36
+ }
37
+
38
+ return roots
39
+ .map((root) => {
40
+ if (root.source === "project") {
41
+ return [
42
+ `- [project] Install from the project root with \`npx -y skills add ${spec_argument} -y\`.`,
43
+ ` The installed skill must end up under \`${root.resolved}/<skill-id>/SKILL.md\`.`,
44
+ ].join("\n");
45
+ }
46
+ if (root.source === "home") {
47
+ return [
48
+ `- [home] Install globally with \`npx -y skills add ${spec_argument} -g -y\`.`,
49
+ ` The installed skill must end up under \`${root.resolved}/<skill-id>/SKILL.md\`.`,
50
+ ].join("\n");
51
+ }
52
+ return [
53
+ `- [custom] Install or copy the skill into \`${root.resolved}/<skill-id>/SKILL.md\`.`,
54
+ " The skills CLI has no generic custom-root flag, so verify the final path instead of assuming installation succeeded.",
55
+ ].join("\n");
56
+ })
57
+ .join("\n");
58
+ }
59
+
60
+ /**
61
+ * 生成 find action 返回的纯提示词。
62
+ */
63
+ export function render_skill_find_prompt(query: string): string {
64
+ const query_argument = quote_shell_argument(query);
65
+ return [
66
+ "# Find Skill Instructions",
67
+ "",
68
+ "This action only returns instructions. It has not searched for or installed anything.",
69
+ "Use the available web or browser capability to search these Skill catalogs:",
70
+ "- https://www.skills.sh/",
71
+ "- https://app.lobehub.com/community/skill",
72
+ `Use the available shell tool to run \`npx -y skills find ${query_argument}\`.`,
73
+ "Compare the catalog and CLI results, then choose an installation spec before calling the `skill.install` action.",
74
+ ].join("\n");
75
+ }
76
+
77
+ /**
78
+ * 生成 install action 返回的扫描感知纯提示词。
79
+ */
80
+ export function render_skill_install_prompt(
81
+ project_root: string,
82
+ options: SkillPluginOptions | null | undefined,
83
+ spec: string,
84
+ ): string {
85
+ const roots = getSkillSearchRoots(project_root, options);
86
+ const spec_argument = quote_shell_argument(spec);
87
+ return [
88
+ "# Install Skill Instructions",
89
+ "",
90
+ "This action only returns instructions. It has not installed or changed any files.",
91
+ "Install only into one of the configured scan roots:",
92
+ render_install_root_instructions(roots, spec_argument),
93
+ "",
94
+ [
95
+ "After the shell installation command completes, call",
96
+ "`plugin_call({ plugin: \"skill\", action: \"list\", payload: {} })`",
97
+ "and check whether the new skill appears. Then call `skill.lookup` before using it.",
98
+ ].join(" "),
99
+ ].join("\n");
100
+ }
101
+
14
102
  /**
15
103
  * 渲染 skills 系统提示片段。
16
104
  *
17
105
  * 约束(中文)
18
106
  * - 为控制 token 成本,最多展示前 40 个 skill。
19
107
  * - roots 会按扫描顺序输出,便于排查冲突覆盖。
108
+ * - 查找与安装指引必须根据实际 roots 生成,不能假设固定安装范围。
20
109
  */
21
- export function renderSkillsPromptSection(
22
- projectRoot: string,
110
+ export function render_skills_prompt_section(
111
+ project_root: string,
23
112
  options: SkillPluginOptions | null | undefined,
24
113
  skills: SkillDefinition[],
25
114
  ): string {
26
- const roots = getSkillSearchRoots(projectRoot, options);
115
+ const roots = getSkillSearchRoots(project_root, options);
27
116
 
28
- const skillsSection =
117
+ const skills_section =
29
118
  skills.length > 0
30
119
  ? skills
31
120
  .map((skill) => {
@@ -35,15 +124,20 @@ export function renderSkillsPromptSection(
35
124
  .join("\n")
36
125
  : "- (none)";
37
126
 
38
- const rootsSection =
127
+ const roots_section =
39
128
  roots.length > 0
40
129
  ? roots
41
130
  .map((root) => {
42
- return `- [${root.source}] ${root.display}`;
131
+ return `- [${root.source}] ${root.display} -> ${root.resolved}`;
43
132
  })
44
133
  .join("\n")
45
134
  : "- (none)";
46
135
 
136
+ const ignore_notice =
137
+ Array.isArray(options?.ignore) && options.ignore.length > 0
138
+ ? "Configured ignore rules are active. A matching skill will not appear in `list`, even if its files exist in a scan root."
139
+ : "";
140
+
47
141
  return [
48
142
  "# Runtime Skills Inventory",
49
143
  "",
@@ -51,10 +145,16 @@ export function renderSkillsPromptSection(
51
145
  "All skills in `Available Skills` are already available locally.",
52
146
  "",
53
147
  "## Available Skills",
54
- skillsSection,
148
+ skills_section,
55
149
  "",
56
150
  "## Skill Roots (scan order, higher wins on conflicts)",
57
- rootsSection,
151
+ roots_section,
152
+ "",
153
+ "## Missing Skill Workflow",
154
+ "Call `skill.find` with the search query to receive Shell search instructions.",
155
+ "After choosing a spec, call `skill.install` to receive scan-aware installation instructions.",
156
+ "Both actions return prompts only. They do not execute commands or change files.",
157
+ ignore_notice,
58
158
  ]
59
159
  .filter(Boolean)
60
160
  .join("\n");
@@ -7,9 +7,9 @@
7
7
  * - `lookup` 行为为无状态:由 action 读取 SKILL.md 后通过协议注入 user message
8
8
  */
9
9
 
10
- import { getSessionRunContext } from "@downcity/agent";
10
+ import type { PluginRunContext } from "@downcity/agent";
11
11
  import { discoverSkillsSync } from "./Discovery.js";
12
- import { renderSkillsPromptSection } from "./Prompt.js";
12
+ import { render_skills_prompt_section } from "./Prompt.js";
13
13
  import { setSessionAvailableSkills } from "./Store.js";
14
14
  import type { SkillPluginOptions } from "@/skill/types/SkillPlugin.js";
15
15
 
@@ -18,11 +18,6 @@ type SkillSystemRuntime = {
18
18
  options?: SkillPluginOptions | null;
19
19
  };
20
20
 
21
- function getCurrentSessionId(): string {
22
- const run_context = getSessionRunContext();
23
- return String(run_context?.sessionId || "").trim();
24
- }
25
-
26
21
  /**
27
22
  * 构建 skill plugin system 文本。
28
23
  *
@@ -33,8 +28,9 @@ function getCurrentSessionId(): string {
33
28
  */
34
29
  export async function buildSkillsSystemText(
35
30
  runtime: SkillSystemRuntime,
31
+ run_context?: PluginRunContext,
36
32
  ): Promise<string> {
37
- const sessionId = getCurrentSessionId();
33
+ const sessionId = String(run_context?.sessionId || "").trim();
38
34
  const discoveredSkills = discoverSkillsSync(
39
35
  runtime.rootPath,
40
36
  runtime.options,
@@ -44,7 +40,7 @@ export async function buildSkillsSystemText(
44
40
  setSessionAvailableSkills(sessionId, discoveredSkills);
45
41
  }
46
42
 
47
- return renderSkillsPromptSection(
43
+ return render_skills_prompt_section(
48
44
  runtime.rootPath,
49
45
  runtime.options,
50
46
  discoveredSkills,
@@ -15,11 +15,11 @@ import type { SkillRootSource } from "@/skill/types/SkillRoot.js";
15
15
  */
16
16
  export const SKILL_PLUGIN_ACTIONS = {
17
17
  /**
18
- * 查找 skill
18
+ * 返回查找 skill 的 Shell 操作提示。
19
19
  */
20
20
  find: "find",
21
21
  /**
22
- * 安装 skill。
22
+ * 返回扫描感知的安装提示。
23
23
  */
24
24
  install: "install",
25
25
  /**
@@ -33,35 +33,23 @@ export const SKILL_PLUGIN_ACTIONS = {
33
33
  } as const;
34
34
 
35
35
  /**
36
- * skill 查找输入。
36
+ * skill 查找提示 action 输入。
37
37
  */
38
38
  export type SkillPluginFindPayload = {
39
39
  /**
40
- * 用户输入的 skill 查询词。
40
+ * 需要查找的 skill 关键词。
41
41
  */
42
42
  query: string;
43
43
  };
44
44
 
45
45
  /**
46
- * skill 安装输入。
46
+ * skill 安装提示 action 输入。
47
47
  */
48
48
  export type SkillPluginInstallPayload = {
49
49
  /**
50
- * skill 安装 spec。
50
+ * `skills` CLI 接受的安装来源或 skill spec。
51
51
  */
52
52
  spec: string;
53
- /**
54
- * 是否全局安装。
55
- */
56
- global?: boolean;
57
- /**
58
- * 是否跳过确认。
59
- */
60
- yes?: boolean;
61
- /**
62
- * 安装目标 agent 名称。
63
- */
64
- agent?: string;
65
53
  };
66
54
 
67
55
  /**