deepclause-sdk 0.0.88 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +418 -914
  3. package/dist/agent.d.ts +19 -2
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +221 -4
  6. package/dist/agent.js.map +1 -1
  7. package/dist/cli/config.d.ts +323 -176
  8. package/dist/cli/config.d.ts.map +1 -1
  9. package/dist/cli/config.js +146 -188
  10. package/dist/cli/config.js.map +1 -1
  11. package/dist/cli/index.d.ts +3 -2
  12. package/dist/cli/index.d.ts.map +1 -1
  13. package/dist/cli/index.js +61 -425
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/login.d.ts +29 -0
  16. package/dist/cli/login.d.ts.map +1 -0
  17. package/dist/cli/login.js +184 -0
  18. package/dist/cli/login.js.map +1 -0
  19. package/dist/cli/readline.d.ts +6 -0
  20. package/dist/cli/readline.d.ts.map +1 -0
  21. package/dist/cli/readline.js +15 -0
  22. package/dist/cli/readline.js.map +1 -0
  23. package/dist/cli/repl-bin.d.ts +9 -0
  24. package/dist/cli/repl-bin.d.ts.map +1 -0
  25. package/dist/cli/repl-bin.js +16 -0
  26. package/dist/cli/repl-bin.js.map +1 -0
  27. package/dist/cli/repl.d.ts +191 -0
  28. package/dist/cli/repl.d.ts.map +1 -0
  29. package/dist/cli/repl.js +1232 -0
  30. package/dist/cli/repl.js.map +1 -0
  31. package/dist/cli/run.d.ts +17 -18
  32. package/dist/cli/run.d.ts.map +1 -1
  33. package/dist/cli/run.js +196 -183
  34. package/dist/cli/run.js.map +1 -1
  35. package/dist/cli/set-backend.d.ts +53 -0
  36. package/dist/cli/set-backend.d.ts.map +1 -0
  37. package/dist/cli/set-backend.js +259 -0
  38. package/dist/cli/set-backend.js.map +1 -0
  39. package/dist/cli/visualize.d.ts +38 -0
  40. package/dist/cli/visualize.d.ts.map +1 -0
  41. package/dist/cli/visualize.js +125 -0
  42. package/dist/cli/visualize.js.map +1 -0
  43. package/dist/compiler.d.ts +5 -52
  44. package/dist/compiler.d.ts.map +1 -1
  45. package/dist/compiler.js +4 -768
  46. package/dist/compiler.js.map +1 -1
  47. package/dist/index.d.ts +29 -2
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +20 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/judge/index.d.ts +9 -0
  52. package/dist/judge/index.d.ts.map +1 -0
  53. package/dist/judge/index.js +6 -0
  54. package/dist/judge/index.js.map +1 -0
  55. package/dist/judge/jev.d.ts +21 -0
  56. package/dist/judge/jev.d.ts.map +1 -0
  57. package/dist/judge/jev.js +218 -0
  58. package/dist/judge/jev.js.map +1 -0
  59. package/dist/judge/llm.d.ts +23 -0
  60. package/dist/judge/llm.d.ts.map +1 -0
  61. package/dist/judge/llm.js +120 -0
  62. package/dist/judge/llm.js.map +1 -0
  63. package/dist/judge/marshal.d.ts +26 -0
  64. package/dist/judge/marshal.d.ts.map +1 -0
  65. package/dist/judge/marshal.js +266 -0
  66. package/dist/judge/marshal.js.map +1 -0
  67. package/dist/judge/mock.d.ts +28 -0
  68. package/dist/judge/mock.d.ts.map +1 -0
  69. package/dist/judge/mock.js +98 -0
  70. package/dist/judge/mock.js.map +1 -0
  71. package/dist/judge/types.d.ts +95 -0
  72. package/dist/judge/types.d.ts.map +1 -0
  73. package/dist/judge/types.js +23 -0
  74. package/dist/judge/types.js.map +1 -0
  75. package/dist/prolog/bridge.d.ts +5 -1
  76. package/dist/prolog/bridge.d.ts.map +1 -1
  77. package/dist/prolog/bridge.js +29 -1
  78. package/dist/prolog/bridge.js.map +1 -1
  79. package/dist/prolog-src/deepclause_analysis.pl +10 -2
  80. package/dist/prolog-src/deepclause_mi.pl +2522 -118
  81. package/dist/repl/agent.d.ts +72 -0
  82. package/dist/repl/agent.d.ts.map +1 -0
  83. package/dist/repl/agent.js +366 -0
  84. package/dist/repl/agent.js.map +1 -0
  85. package/dist/repl/auth.d.ts +45 -0
  86. package/dist/repl/auth.d.ts.map +1 -0
  87. package/dist/repl/auth.js +116 -0
  88. package/dist/repl/auth.js.map +1 -0
  89. package/dist/repl/backend.d.ts +290 -0
  90. package/dist/repl/backend.d.ts.map +1 -0
  91. package/dist/repl/backend.js +370 -0
  92. package/dist/repl/backend.js.map +1 -0
  93. package/dist/repl/compaction.d.ts +122 -0
  94. package/dist/repl/compaction.d.ts.map +1 -0
  95. package/dist/repl/compaction.js +318 -0
  96. package/dist/repl/compaction.js.map +1 -0
  97. package/dist/repl/export.d.ts +30 -0
  98. package/dist/repl/export.d.ts.map +1 -0
  99. package/dist/repl/export.js +23 -0
  100. package/dist/repl/export.js.map +1 -0
  101. package/dist/repl/frames.d.ts +21 -0
  102. package/dist/repl/frames.d.ts.map +1 -0
  103. package/dist/repl/frames.js +79 -0
  104. package/dist/repl/frames.js.map +1 -0
  105. package/dist/repl/harness-tools.d.ts +74 -0
  106. package/dist/repl/harness-tools.d.ts.map +1 -0
  107. package/dist/repl/harness-tools.js +121 -0
  108. package/dist/repl/harness-tools.js.map +1 -0
  109. package/dist/repl/highlight.d.ts +30 -0
  110. package/dist/repl/highlight.d.ts.map +1 -0
  111. package/dist/repl/highlight.js +285 -0
  112. package/dist/repl/highlight.js.map +1 -0
  113. package/dist/repl/history.d.ts +234 -0
  114. package/dist/repl/history.d.ts.map +1 -0
  115. package/dist/repl/history.js +661 -0
  116. package/dist/repl/history.js.map +1 -0
  117. package/dist/repl/index.d.ts +120 -0
  118. package/dist/repl/index.d.ts.map +1 -0
  119. package/dist/repl/index.js +107 -0
  120. package/dist/repl/index.js.map +1 -0
  121. package/dist/repl/judge.d.ts +51 -0
  122. package/dist/repl/judge.d.ts.map +1 -0
  123. package/dist/repl/judge.js +58 -0
  124. package/dist/repl/judge.js.map +1 -0
  125. package/dist/repl/markdown.d.ts +25 -0
  126. package/dist/repl/markdown.d.ts.map +1 -0
  127. package/dist/repl/markdown.js +103 -0
  128. package/dist/repl/markdown.js.map +1 -0
  129. package/dist/repl/picker.d.ts +34 -0
  130. package/dist/repl/picker.d.ts.map +1 -0
  131. package/dist/repl/picker.js +81 -0
  132. package/dist/repl/picker.js.map +1 -0
  133. package/dist/repl/project-context.d.ts +16 -0
  134. package/dist/repl/project-context.d.ts.map +1 -0
  135. package/dist/repl/project-context.js +23 -0
  136. package/dist/repl/project-context.js.map +1 -0
  137. package/dist/repl/render.d.ts +160 -0
  138. package/dist/repl/render.d.ts.map +1 -0
  139. package/dist/repl/render.js +715 -0
  140. package/dist/repl/render.js.map +1 -0
  141. package/dist/repl/session.d.ts +356 -0
  142. package/dist/repl/session.d.ts.map +1 -0
  143. package/dist/repl/session.js +1275 -0
  144. package/dist/repl/session.js.map +1 -0
  145. package/dist/repl/status.d.ts +100 -0
  146. package/dist/repl/status.d.ts.map +1 -0
  147. package/dist/repl/status.js +218 -0
  148. package/dist/repl/status.js.map +1 -0
  149. package/dist/repl/tools.d.ts +53 -0
  150. package/dist/repl/tools.d.ts.map +1 -0
  151. package/dist/repl/tools.js +307 -0
  152. package/dist/repl/tools.js.map +1 -0
  153. package/dist/repl/toolset.d.ts +32 -0
  154. package/dist/repl/toolset.d.ts.map +1 -0
  155. package/dist/repl/toolset.js +82 -0
  156. package/dist/repl/toolset.js.map +1 -0
  157. package/dist/repl/tui/editor.d.ts +17 -0
  158. package/dist/repl/tui/editor.d.ts.map +1 -0
  159. package/dist/repl/tui/editor.js +39 -0
  160. package/dist/repl/tui/editor.js.map +1 -0
  161. package/dist/repl/tui/status-bar.d.ts +26 -0
  162. package/dist/repl/tui/status-bar.d.ts.map +1 -0
  163. package/dist/repl/tui/status-bar.js +47 -0
  164. package/dist/repl/tui/status-bar.js.map +1 -0
  165. package/dist/repl/tui/theme.d.ts +30 -0
  166. package/dist/repl/tui/theme.d.ts.map +1 -0
  167. package/dist/repl/tui/theme.js +81 -0
  168. package/dist/repl/tui/theme.js.map +1 -0
  169. package/dist/repl/tui/transcript.d.ts +39 -0
  170. package/dist/repl/tui/transcript.d.ts.map +1 -0
  171. package/dist/repl/tui/transcript.js +123 -0
  172. package/dist/repl/tui/transcript.js.map +1 -0
  173. package/dist/runner.d.ts +145 -13
  174. package/dist/runner.d.ts.map +1 -1
  175. package/dist/runner.js +600 -282
  176. package/dist/runner.js.map +1 -1
  177. package/dist/sdk.d.ts.map +1 -1
  178. package/dist/sdk.js +56 -32
  179. package/dist/sdk.js.map +1 -1
  180. package/dist/system/assets/docs/AGENT_PROMPT.md +1373 -0
  181. package/dist/system/assets/docs/DML_AUTHORING.md +195 -0
  182. package/dist/system/assets/docs/DML_REFERENCE.md +393 -72
  183. package/dist/system/assets/docs/HARNESS_EXAMPLES.md +172 -0
  184. package/dist/system/assets/docs/HARNESS_PATTERNS.md +562 -0
  185. package/dist/system/assets/docs/META_PROMPT.md +68 -0
  186. package/dist/system/assets/docs/PROLOG_SNIPPETS.md +117 -0
  187. package/dist/system/assets/index.d.ts +9 -17
  188. package/dist/system/assets/index.d.ts.map +1 -1
  189. package/dist/system/assets/index.js +26 -85
  190. package/dist/system/assets/index.js.map +1 -1
  191. package/dist/system/runtime/agentvm-manager.d.ts +9 -2
  192. package/dist/system/runtime/agentvm-manager.d.ts.map +1 -1
  193. package/dist/system/runtime/agentvm-manager.js +70 -44
  194. package/dist/system/runtime/agentvm-manager.js.map +1 -1
  195. package/dist/system/runtime/media.d.ts +23 -0
  196. package/dist/system/runtime/media.d.ts.map +1 -0
  197. package/dist/system/runtime/media.js +55 -0
  198. package/dist/system/runtime/media.js.map +1 -0
  199. package/dist/system/runtime/shell-limits.d.ts +21 -0
  200. package/dist/system/runtime/shell-limits.d.ts.map +1 -0
  201. package/dist/system/runtime/shell-limits.js +39 -0
  202. package/dist/system/runtime/shell-limits.js.map +1 -0
  203. package/dist/system/runtime/shell-manager.d.ts +8 -3
  204. package/dist/system/runtime/shell-manager.d.ts.map +1 -1
  205. package/dist/system/runtime/shell-manager.js +56 -39
  206. package/dist/system/runtime/shell-manager.js.map +1 -1
  207. package/dist/system/runtime/shell-tool-events.js +5 -0
  208. package/dist/system/runtime/shell-tool-events.js.map +1 -1
  209. package/dist/system/runtime/token-usage.d.ts +2 -0
  210. package/dist/system/runtime/token-usage.d.ts.map +1 -1
  211. package/dist/system/runtime/token-usage.js +7 -0
  212. package/dist/system/runtime/token-usage.js.map +1 -1
  213. package/dist/tools.d.ts +3 -21
  214. package/dist/tools.d.ts.map +1 -1
  215. package/dist/tools.js +14 -168
  216. package/dist/tools.js.map +1 -1
  217. package/dist/types.d.ts +149 -118
  218. package/dist/types.d.ts.map +1 -1
  219. package/dist/validate.d.ts +19 -0
  220. package/dist/validate.d.ts.map +1 -0
  221. package/dist/validate.js +338 -0
  222. package/dist/validate.js.map +1 -0
  223. package/dist/visualize/index.d.ts +52 -0
  224. package/dist/visualize/index.d.ts.map +1 -0
  225. package/dist/visualize/index.js +189 -0
  226. package/dist/visualize/index.js.map +1 -0
  227. package/package.json +17 -15
  228. package/src/prolog-src/deepclause_analysis.pl +10 -2
  229. package/src/prolog-src/deepclause_mi.pl +2522 -118
  230. package/dist/cli/commands.d.ts +0 -42
  231. package/dist/cli/commands.d.ts.map +0 -1
  232. package/dist/cli/commands.js +0 -246
  233. package/dist/cli/commands.js.map +0 -1
  234. package/dist/cli/compile.d.ts +0 -99
  235. package/dist/cli/compile.d.ts.map +0 -1
  236. package/dist/cli/compile.js +0 -363
  237. package/dist/cli/compile.js.map +0 -1
  238. package/dist/cli/default-skills.d.ts +0 -10
  239. package/dist/cli/default-skills.d.ts.map +0 -1
  240. package/dist/cli/default-skills.js +0 -206
  241. package/dist/cli/default-skills.js.map +0 -1
  242. package/dist/cli/interactive.d.ts +0 -2
  243. package/dist/cli/interactive.d.ts.map +0 -1
  244. package/dist/cli/interactive.js +0 -20
  245. package/dist/cli/interactive.js.map +0 -1
  246. package/dist/cli/mcp.d.ts +0 -56
  247. package/dist/cli/mcp.d.ts.map +0 -1
  248. package/dist/cli/mcp.js +0 -138
  249. package/dist/cli/mcp.js.map +0 -1
  250. package/dist/cli/prompt.d.ts +0 -2
  251. package/dist/cli/prompt.d.ts.map +0 -1
  252. package/dist/cli/prompt.js +0 -2
  253. package/dist/cli/prompt.js.map +0 -1
  254. package/dist/cli/search.d.ts +0 -19
  255. package/dist/cli/search.d.ts.map +0 -1
  256. package/dist/cli/search.js +0 -189
  257. package/dist/cli/search.js.map +0 -1
  258. package/dist/cli/tool-args.d.ts +0 -2
  259. package/dist/cli/tool-args.d.ts.map +0 -1
  260. package/dist/cli/tool-args.js +0 -39
  261. package/dist/cli/tool-args.js.map +0 -1
  262. package/dist/cli/tools.d.ts +0 -36
  263. package/dist/cli/tools.d.ts.map +0 -1
  264. package/dist/cli/tools.js +0 -229
  265. package/dist/cli/tools.js.map +0 -1
  266. package/dist/cli/tui/index.d.ts +0 -22
  267. package/dist/cli/tui/index.d.ts.map +0 -1
  268. package/dist/cli/tui/index.js +0 -29
  269. package/dist/cli/tui/index.js.map +0 -1
  270. package/dist/cli/tui.d.ts +0 -167
  271. package/dist/cli/tui.d.ts.map +0 -1
  272. package/dist/cli/tui.js +0 -5228
  273. package/dist/cli/tui.js.map +0 -1
  274. package/dist/compiler_prompt.d.ts +0 -20
  275. package/dist/compiler_prompt.d.ts.map +0 -1
  276. package/dist/compiler_prompt.js +0 -870
  277. package/dist/compiler_prompt.js.map +0 -1
  278. package/dist/deepclause-cli.skill +0 -0
  279. package/dist/prolog-src/deepclause_mi.pl.bak +0 -570
  280. package/dist/system/assets/compactors/default-memory-compactor.dml +0 -6
  281. package/dist/system/assets/docs/CONDUCTOR_PROMPT.md +0 -105
  282. package/dist/system/assets/docs/DML_COMPILER_PROMPT.md +0 -700
  283. package/dist/system/assets/docs/TUI.md +0 -150
  284. package/dist/system/assets/recipes/deepclause-coding-workflow/SKILL.md +0 -100
  285. package/dist/system/assets/skills/conductor.dml +0 -76
  286. package/dist/system/assets/skills/deep-planner.dml +0 -412
  287. package/dist/system/assets/skills/plan.dml +0 -429
  288. package/dist/system/assets/skills/security-planner.dml +0 -337
  289. package/dist/system/assets/skills/skill-creator.dml +0 -187
  290. package/dist/system/runtime/catalog-recipes.d.ts +0 -24
  291. package/dist/system/runtime/catalog-recipes.d.ts.map +0 -1
  292. package/dist/system/runtime/catalog-recipes.js +0 -273
  293. package/dist/system/runtime/catalog-recipes.js.map +0 -1
  294. package/dist/system/runtime/catalog-skills.d.ts +0 -50
  295. package/dist/system/runtime/catalog-skills.d.ts.map +0 -1
  296. package/dist/system/runtime/catalog-skills.js +0 -152
  297. package/dist/system/runtime/catalog-skills.js.map +0 -1
  298. package/dist/system/runtime/conductor.d.ts +0 -105
  299. package/dist/system/runtime/conductor.d.ts.map +0 -1
  300. package/dist/system/runtime/conductor.js +0 -732
  301. package/dist/system/runtime/conductor.js.map +0 -1
  302. package/dist/system/runtime/console-capture.d.ts +0 -9
  303. package/dist/system/runtime/console-capture.d.ts.map +0 -1
  304. package/dist/system/runtime/console-capture.js +0 -67
  305. package/dist/system/runtime/console-capture.js.map +0 -1
  306. package/dist/system/runtime/dml-executor.d.ts +0 -52
  307. package/dist/system/runtime/dml-executor.d.ts.map +0 -1
  308. package/dist/system/runtime/dml-executor.js +0 -203
  309. package/dist/system/runtime/dml-executor.js.map +0 -1
  310. package/dist/system/runtime/runtime-tools.d.ts +0 -31
  311. package/dist/system/runtime/runtime-tools.d.ts.map +0 -1
  312. package/dist/system/runtime/runtime-tools.js +0 -312
  313. package/dist/system/runtime/runtime-tools.js.map +0 -1
  314. package/dist/system/runtime/skill-creator.d.ts +0 -38
  315. package/dist/system/runtime/skill-creator.d.ts.map +0 -1
  316. package/dist/system/runtime/skill-creator.js +0 -763
  317. package/dist/system/runtime/skill-creator.js.map +0 -1
  318. package/src/prolog-src/deepclause_mi.pl.bak +0 -570
@@ -1,763 +0,0 @@
1
- import * as crypto from 'crypto';
2
- import * as fs from 'fs/promises';
3
- import * as os from 'os';
4
- import * as path from 'path';
5
- import { createDeepClause } from '../../sdk.js';
6
- import { analyzeAndAuditDML, analyzeDML, extractDescription, extractParameters, validateWithProlog } from '../../compiler.js';
7
- import { newsSearch, webSearch } from '../../cli/search.js';
8
- import { resolveCompactionConfig } from '../../cli/config.js';
9
- import { readSystemPromptAsset, readSystemSkillAsset } from '../assets/index.js';
10
- import { listLocalSkillCatalog } from './catalog-skills.js';
11
- import { withCapturedConsole } from './console-capture.js';
12
- import { executeDml } from './dml-executor.js';
13
- import { truncateUrlFetchTextBody } from './runtime-tools.js';
14
- import { createShellManager, describeShellExecutionBackend } from './shell-manager.js';
15
- import { createShellToolEventBridge } from './shell-tool-events.js';
16
- import { recordTokenUsage } from './token-usage.js';
17
- const CREATOR_TOOL_CATALOG = [
18
- { name: 'list_skills', description: 'List reusable local CLI skills that the new skill could compose.' },
19
- { name: 'web_search', description: 'Search the web for information.' },
20
- { name: 'news_search', description: 'Search recent news articles.' },
21
- { name: 'url_fetch', description: 'Fetch a URL and return its content.' },
22
- { name: 'bash', description: 'Run shell commands in the active workspace shell.' },
23
- { name: 'write_file', description: 'Write files inside the workspace.' },
24
- { name: 'validate_dml', description: 'Validate DML code from a file path.' },
25
- { name: 'test_dml', description: 'Execute a DML file with test arguments.' },
26
- { name: 'deploy_skill', description: 'Publish the generated skill into the local CLI catalog.' },
27
- { name: 'ask_user', description: 'Ask the user for clarification when needed.' },
28
- ];
29
- export async function compileWithSkillCreator(markdown, options) {
30
- if (options.onEvent) {
31
- return withCapturedConsole((entry) => options.onEvent?.({
32
- type: 'log',
33
- content: `[${entry.level}] ${entry.text}`,
34
- }), () => compileWithSkillCreatorInternal(markdown, options));
35
- }
36
- return compileWithSkillCreatorInternal(markdown, options);
37
- }
38
- async function compileWithSkillCreatorInternal(markdown, options) {
39
- const workspacePath = path.resolve(options.workspacePath);
40
- await fs.mkdir(workspacePath, { recursive: true });
41
- const outputDir = path.resolve(options.outputDir);
42
- const shell = createShellManager({
43
- workspacePath,
44
- sandbox: options.sandbox,
45
- network: options.config.agentvm?.network ?? false,
46
- hostConfig: options.config.shell,
47
- });
48
- const sdk = await createDeepClause({
49
- model: options.compileSelection.model,
50
- provider: options.compileSelection.provider,
51
- apiKey: options.compileSelection.apiKey,
52
- baseUrl: options.compileSelection.baseUrl,
53
- temperature: options.compileSelection.temperature,
54
- debug: options.verbose,
55
- trace: !!options.trace,
56
- streaming: (options.stream ?? false) || !!options.onEvent,
57
- maxTokens: options.compileSelection.maxOutputTokens ?? 65536,
58
- compaction: resolveCompactionConfig(options.config, path.resolve(options.workspaceRoot ?? workspacePath)),
59
- });
60
- let published;
61
- let finalAnswer = '';
62
- let runtimeError;
63
- const usageByModel = {};
64
- const emitEvent = (event) => {
65
- options.onEvent?.(event);
66
- if (event.type === 'output' && options.verbose && !options.onEvent && event.content) {
67
- console.log(event.content);
68
- }
69
- if (event.type === 'tool_call' && options.verbose && !options.onEvent && event.toolName) {
70
- console.log(` 🔧 ${event.toolName}`);
71
- }
72
- if (event.type === 'usage') {
73
- recordTokenUsage(usageByModel, options.compileSelection.id, event.usage);
74
- }
75
- if (event.type === 'answer' && event.content) {
76
- finalAnswer = event.content;
77
- }
78
- if (event.type === 'error') {
79
- runtimeError = event.content ?? 'Unknown skill creator error';
80
- }
81
- };
82
- try {
83
- registerSkillCreatorTools(sdk, {
84
- markdown,
85
- outputDir,
86
- baseName: options.baseName,
87
- workspaceRoot: path.resolve(options.workspaceRoot ?? workspacePath),
88
- workspacePath,
89
- shell,
90
- config: options.config,
91
- compileSelection: options.compileSelection,
92
- runSelection: options.runSelection,
93
- validateOnly: options.validateOnly ?? false,
94
- onPublish: (result) => {
95
- published = result;
96
- },
97
- sandbox: options.sandbox,
98
- signal: options.signal,
99
- onEvent: emitEvent,
100
- });
101
- const skillCreatorDml = await readSystemSkillAsset('skill-creator', {
102
- workspaceRoot: options.workspaceRoot,
103
- });
104
- const systemPrompt = await buildSkillCreatorSystemPrompt(path.resolve(options.workspaceRoot ?? workspacePath), options.config, options.compileSelection, options.maxAttempts, options.sandbox ?? false);
105
- const localMetadata = buildLocalMetadata(markdown, options.baseName);
106
- for await (const event of sdk.runDML(skillCreatorDml, {
107
- args: [markdown],
108
- params: {
109
- system_prompt: systemPrompt,
110
- auto_deploy: true,
111
- deployment_metadata_json: JSON.stringify(localMetadata),
112
- },
113
- workspacePath,
114
- gasLimit: Math.max(240, (options.maxAttempts ?? 3) * 160),
115
- onUserInput: options.onUserInput,
116
- signal: options.signal,
117
- })) {
118
- emitEvent(event);
119
- }
120
- if (runtimeError) {
121
- throw new Error(runtimeError);
122
- }
123
- const publishResult = published;
124
- if (!publishResult) {
125
- throw new Error(finalAnswer || 'Skill creator finished without producing a published artifact');
126
- }
127
- const analysis = await analyzeAndAuditDML(publishResult.dml, {
128
- audit: options.audit,
129
- model: options.compileSelection.model,
130
- provider: options.compileSelection.provider,
131
- baseUrl: options.compileSelection.baseUrl,
132
- });
133
- return {
134
- dml: publishResult.dml,
135
- meta: publishResult.meta,
136
- tools: publishResult.meta.tools,
137
- outputPath: publishResult.outputPath,
138
- explanation: finalAnswer || 'Skill creator runtime compiled and published the skill.',
139
- analysis,
140
- usageByModel,
141
- };
142
- }
143
- finally {
144
- await sdk.dispose();
145
- await shell.dispose();
146
- }
147
- }
148
- function registerSkillCreatorTools(sdk, context) {
149
- sdk.registerTool('list_skills', {
150
- description: 'List reusable local CLI skills from the current workspace catalog.',
151
- parameters: {
152
- type: 'object',
153
- properties: {},
154
- },
155
- execute: async () => listLocalSkillCatalog(context.workspaceRoot, { detailed: true }),
156
- });
157
- sdk.registerTool('web_search', {
158
- description: 'Search the web for information.',
159
- parameters: {
160
- type: 'object',
161
- properties: {
162
- query: { type: 'string', description: 'Search query.' },
163
- count: { type: 'number', description: 'Maximum result count.' },
164
- },
165
- required: ['query'],
166
- },
167
- execute: async (args) => webSearch({
168
- query: String(args.query ?? ''),
169
- count: typeof args.count === 'number' ? args.count : 10,
170
- signal: context.signal,
171
- }),
172
- });
173
- sdk.registerTool('news_search', {
174
- description: 'Search recent news.',
175
- parameters: {
176
- type: 'object',
177
- properties: {
178
- query: { type: 'string', description: 'Search query.' },
179
- count: { type: 'number', description: 'Maximum result count.' },
180
- },
181
- required: ['query'],
182
- },
183
- execute: async (args) => newsSearch({
184
- query: String(args.query ?? ''),
185
- count: typeof args.count === 'number' ? args.count : 10,
186
- signal: context.signal,
187
- }),
188
- });
189
- sdk.registerTool('url_fetch', {
190
- description: 'Fetch a URL or save it to a workspace file.',
191
- parameters: {
192
- type: 'object',
193
- properties: {
194
- url: { type: 'string', description: 'Absolute URL to fetch.' },
195
- save_to: { type: 'string', description: 'Optional file path inside the workspace.' },
196
- },
197
- required: ['url'],
198
- },
199
- execute: async (args) => urlFetch(context.workspacePath, args, context.signal),
200
- });
201
- sdk.registerTool('bash', {
202
- description: 'Run a shell command in the active workspace shell.',
203
- parameters: {
204
- type: 'object',
205
- properties: {
206
- command: { type: 'string', description: 'Shell command to execute.' },
207
- },
208
- required: ['command'],
209
- },
210
- execute: async (args) => {
211
- const command = String(args.command ?? '');
212
- return context.shell.exec(command, context.signal, createShellToolEventBridge({
213
- toolName: 'bash',
214
- toolArgs: { command },
215
- emit: context.onEvent,
216
- }));
217
- },
218
- });
219
- sdk.registerTool('write_file', {
220
- description: 'Write or overwrite a file inside the workspace.',
221
- parameters: {
222
- type: 'object',
223
- properties: {
224
- path: { type: 'string', description: 'Workspace-relative file path.' },
225
- content: { type: 'string', description: 'Full file content.' },
226
- },
227
- required: ['path', 'content'],
228
- },
229
- execute: async (args) => writeWorkspaceFile(context.workspacePath, args),
230
- });
231
- sdk.registerTool('validate_dml', {
232
- description: 'Validate DML code from a file path.',
233
- parameters: {
234
- type: 'object',
235
- properties: {
236
- dml_file: { type: 'string', description: 'Path to a .dml file inside the workspace.' },
237
- },
238
- required: ['dml_file'],
239
- },
240
- execute: async (args) => validateWorkspaceDml(context.workspacePath, args),
241
- });
242
- sdk.registerTool('test_dml', {
243
- description: 'Run a DML file with test arguments.',
244
- parameters: {
245
- type: 'object',
246
- properties: {
247
- dml_file: { type: 'string', description: 'Path to the DML file to test.' },
248
- test_input: { type: 'string', description: 'Single test input string.' },
249
- test_args: { type: 'string', description: 'JSON array of test arguments. Structured JSON values are preserved.' },
250
- },
251
- required: ['dml_file'],
252
- },
253
- execute: async (args) => runLocalTestDml(context, args),
254
- });
255
- sdk.registerTool('deploy_skill', {
256
- description: 'Publish the generated DML into the local CLI skill catalog.',
257
- parameters: {
258
- type: 'object',
259
- properties: {
260
- dml_file: { type: 'string', description: 'Path to the DML file to publish.' },
261
- spec_markdown: { type: 'string', description: 'Original specification markdown.' },
262
- metadata_json: { type: 'string', description: 'JSON metadata with slug, name, description, trigger_phrases.' },
263
- slug_override: { type: 'string', description: 'Optional slug override.' },
264
- },
265
- required: ['dml_file', 'spec_markdown', 'metadata_json'],
266
- },
267
- execute: async (args) => {
268
- const published = await publishSkill(context, args);
269
- context.onPublish(published);
270
- return {
271
- ok: true,
272
- slug: published.slug,
273
- version: published.meta.history.length,
274
- };
275
- },
276
- });
277
- }
278
- async function buildSkillCreatorSystemPrompt(workspaceRoot, config, compileSelection, maxAttempts, sandbox = false) {
279
- const promptTemplate = await readSystemPromptAsset('skill-creator', { workspaceRoot });
280
- const shellBackend = describeShellExecutionBackend(sandbox, config.shell);
281
- const toolsTable = [
282
- '| Tool | Description |',
283
- '|------|-------------|',
284
- ...CREATOR_TOOL_CATALOG.map((tool) => `| \`${tool.name}\` | ${tool.description} |`),
285
- ].join('\n');
286
- const llmAccessSection = [
287
- '## LLM Access from Scripts',
288
- '',
289
- 'The local CLI runtime does not provide an extra proxy-only script API.',
290
- 'Use DML task()/prompt() when the skill needs open-ended LLM reasoning or text generation. Deterministic or simple skills can be pure Prolog plus exec()/consult() with no task() at all.',
291
- `The compile slot currently resolves to \`${compileSelection.id}\`.`,
292
- ].join('\n');
293
- const runtimeSection = sandbox
294
- ? [
295
- '## Runtime Shell Context',
296
- `- Shell backend currently resolves to \`${shellBackend.backendLabel}\` (${shellBackend.description}).`,
297
- `- Host system for this compile run: \`${process.platform}\` / \`${process.arch}\` / \`${os.release()}\`.`,
298
- '- Shell commands run inside AgentVM because `--sandbox` is enabled.',
299
- `- AgentVM network access is ${config.agentvm?.network ? 'enabled' : 'disabled'}.`,
300
- '- Bubblewrap or host-shell wrapper behavior does not apply in this mode; use the AgentVM assumptions instead.',
301
- '- Package installation and outbound network behavior follow that sandbox setting.',
302
- '- Web research still goes through web_search, news_search, and url_fetch.',
303
- ].join('\n')
304
- : [
305
- '## Runtime Shell Context',
306
- `- Shell backend currently resolves to \`${shellBackend.backendLabel}\` (${shellBackend.description}).`,
307
- `- Host system for this compile run: \`${process.platform}\` / \`${process.arch}\` / \`${os.release()}\`.`,
308
- '- Shell commands run in the local workspace shell by default.',
309
- '- If the backend label contains `bwrap`, bash runs inside bubblewrap on the host rather than inside AgentVM.',
310
- '- If the backend label starts with `host[` and does not contain `bwrap`, commands run through the host shell executor/wrapper on the local machine.',
311
- '- Package installation uses the local machine environment, wrapper, and permissions.',
312
- '- Web research still goes through web_search, news_search, and url_fetch.',
313
- ].join('\n');
314
- const attemptSection = maxAttempts
315
- ? `\n\n## Iteration Budget\nKeep validation and testing loops within roughly ${maxAttempts} repair attempts before failing clearly.`
316
- : '';
317
- return `${promptTemplate
318
- .replace('{TOOLS_TABLE}', toolsTable)
319
- .replace('{LLM_ACCESS_SECTION}', llmAccessSection)}
320
-
321
- ${runtimeSection}
322
-
323
- ## Your Workflow
324
- 1. **Understand**: Read the specification carefully. If anything is unclear, use ask_user to ask for clarification.
325
- 2. **Research**: If the skill needs external APIs or domain knowledge, use search. If an existing local skill might already cover part of the task, call list_skills before re-implementing it.
326
- 3. **Plan**: Create a step-by-step plan for the DML program, including any local skill reuse.
327
- 4. **Prepare environment**: Use bash to install ALL packages the skill will need (pip install, apt-get install, npm install). Create helper directories under '.deepclause/tools/lib/<skill-or-tool-name>/' before writing helpers. If the skill uses Python, create a dedicated virtualenv in that directory and install Python dependencies there. Do this BEFORE writing any DML code. The skill itself must NOT install packages.
328
- 5. **Write**: Use write_file(path='my-skill.dml', content='...') to create or overwrite the DML file. Put helper scripts, templates, fixtures, and non-DML runtime assets in '.deepclause/tools/lib/<skill-or-tool-name>/'.
329
- 6. **Validate**: Use validate_dml(dml_file='my-skill.dml') and fix errors by rewriting the file.
330
- 7. **Test**: Use test_dml(dml_file='my-skill.dml', test_input='...') with a realistic test input and iterate until it works. When helper scripts depend on a virtualenv, test them through that virtualenv's interpreter.
331
- 8. **Publish**: Use deploy_skill(dml_file='my-skill.dml', ...) exactly once when the DML is ready.
332
-
333
- ## File-Based DML Only
334
- validate_dml, test_dml, and deploy_skill only accept file paths. Write the DML to disk first.
335
-
336
- ## Deterministic Skills
337
- - It is fine for a skill to use no task()/prompt() when the workflow is mostly deterministic or simple.
338
- - In those cases, prefer direct Prolog predicates, consult/use_module, and exec() calls.
339
- - Add task()/prompt() only when the skill needs open-ended reasoning, extraction, summarization, classification, or free-form text generation.
340
-
341
- ## Reusing Existing Skills
342
- - Call list_skills when the requested functionality overlaps with an existing local skill.
343
- - Prefer narrow wrapper tool predicates that internally call exec(run_skill(...)) for one specific child skill.
344
- - Do NOT expose a generic tool(run_skill(...)) predicate unless the user explicitly asked for a router or orchestration skill.
345
-
346
- ${runtimeSection}${attemptSection}`;
347
- }
348
- const SKILL_NAME_PATTERNS = [
349
- /(?:called|named)\s+["']?([A-Za-z0-9][A-Za-z0-9 _-]{1,79})["']?/i,
350
- /(?:create|build|make|write|generate|implement)(?:\s+me)?\s+(?:a|an|the)?\s*["']?([A-Za-z0-9][A-Za-z0-9 _-]{1,79}?)(?:["']?\s+skill\b|["']?$)/i,
351
- /(?:create|build|make|write|generate|implement)(?:\s+me)?\s+(?:a|an|the)?\s+skill\s+(?:to|for|that)\s+["']?([A-Za-z0-9][A-Za-z0-9 _-]{1,79})["']?/i,
352
- ];
353
- function cleanSkillLabel(value) {
354
- return value
355
- .trim()
356
- .replace(/[`"']/g, '')
357
- .replace(/\s+/g, ' ')
358
- .trim();
359
- }
360
- function findSkillNameCandidate(source) {
361
- const heading = source.match(/^#\s+(.+)$/m)?.[1];
362
- if (heading) {
363
- const cleaned = cleanSkillLabel(heading);
364
- if (cleaned) {
365
- return cleaned;
366
- }
367
- }
368
- for (const pattern of SKILL_NAME_PATTERNS) {
369
- const match = pattern.exec(source);
370
- if (!match?.[1]) {
371
- continue;
372
- }
373
- const cleaned = cleanSkillLabel(match[1]);
374
- if (cleaned) {
375
- return cleaned;
376
- }
377
- }
378
- return null;
379
- }
380
- function shortenSlug(slug, maxLength = 40) {
381
- if (slug.length <= maxLength) {
382
- return slug;
383
- }
384
- const boundary = slug.lastIndexOf('-', maxLength);
385
- if (boundary >= Math.floor(maxLength / 2)) {
386
- return slug.slice(0, boundary);
387
- }
388
- return slug.slice(0, maxLength).replace(/-+$/g, '');
389
- }
390
- export function normalizeSkillSlug(value, fallback = 'skill') {
391
- const slug = shortenSlug(value
392
- .trim()
393
- .replace(/[`"']/g, '')
394
- .toLowerCase()
395
- .replace(/[^a-z0-9]+/g, '-')
396
- .replace(/^-+|-+$/g, '')
397
- .replace(/-+/g, '-'));
398
- if (slug) {
399
- return slug;
400
- }
401
- const fallbackSlug = fallback
402
- .trim()
403
- .replace(/[`"']/g, '')
404
- .toLowerCase()
405
- .replace(/[^a-z0-9]+/g, '-')
406
- .replace(/^-+|-+$/g, '')
407
- .replace(/-+/g, '-');
408
- return fallbackSlug || 'skill';
409
- }
410
- function formatSkillName(value) {
411
- return cleanSkillLabel(value)
412
- .replace(/[-_]+/g, ' ')
413
- .split(/\s+/)
414
- .filter(Boolean)
415
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
416
- .join(' ');
417
- }
418
- export function deriveSkillSlugFromMarkdown(markdown, fallbackBaseName = 'skill') {
419
- const fallbackSlug = normalizeSkillSlug(fallbackBaseName, 'skill');
420
- const directCandidate = findSkillNameCandidate(markdown);
421
- if (directCandidate) {
422
- return normalizeSkillSlug(directCandidate, fallbackSlug);
423
- }
424
- const fallbackCandidate = findSkillNameCandidate(fallbackBaseName.replace(/[-_]+/g, ' '));
425
- if (fallbackCandidate) {
426
- return normalizeSkillSlug(fallbackCandidate, fallbackSlug);
427
- }
428
- return fallbackSlug;
429
- }
430
- function buildLocalMetadata(markdown, baseName) {
431
- const slug = deriveSkillSlugFromMarkdown(markdown, baseName);
432
- const nameCandidate = findSkillNameCandidate(markdown)
433
- ?? findSkillNameCandidate(baseName.replace(/[-_]+/g, ' '))
434
- ?? slug;
435
- const name = formatSkillName(nameCandidate) || formatSkillName(slug);
436
- const description = extractDescription(markdown);
437
- const triggerPhraseBase = name.replace(/\s+/g, ' ').trim().toLowerCase() || slug.replace(/[-_]+/g, ' ');
438
- const triggerPhrases = Array.from(new Set([
439
- triggerPhraseBase,
440
- `run ${triggerPhraseBase}`,
441
- `use ${triggerPhraseBase}`,
442
- ])).slice(0, 3);
443
- return {
444
- slug,
445
- name: name || formatSkillName(slug),
446
- description,
447
- trigger_phrases: triggerPhrases,
448
- };
449
- }
450
- function normalizeParameterName(name) {
451
- return name
452
- .trim()
453
- .replace(/[`"']/g, '')
454
- .replace(/([A-Z])/g, (_m, c, i) => (i > 0 ? '_' : '') + c.toLowerCase())
455
- .replace(/[\s-]+/g, '_')
456
- .replace(/[^a-z0-9_]/g, '')
457
- .replace(/_+/g, '_')
458
- .replace(/^_+|_+$/g, '');
459
- }
460
- function extractParameterDocs(markdown) {
461
- const parameterDocs = [];
462
- const lines = markdown.split('\n');
463
- let inParametersSection = false;
464
- for (const line of lines) {
465
- const trimmed = line.trim();
466
- if (!inParametersSection) {
467
- if (/^##\s+Parameters\b/i.test(trimmed)) {
468
- inParametersSection = true;
469
- }
470
- continue;
471
- }
472
- if (/^##\s+/.test(trimmed)) {
473
- break;
474
- }
475
- const match = /^-\s+`?([^`:(]+)`?\s*(?:\(([^)]*)\))?\s*:\s*(.+)$/.exec(trimmed);
476
- if (!match) {
477
- continue;
478
- }
479
- const [, rawName, qualifiers = '', description] = match;
480
- const defaultMatch = /default\s*:\s*(?:"([^"]+)"|'([^']+)'|([^,]+))/i.exec(qualifiers);
481
- const qualifierText = qualifiers.toLowerCase();
482
- parameterDocs.push({
483
- name: normalizeParameterName(rawName),
484
- description: description.trim(),
485
- required: qualifierText.includes('required')
486
- ? true
487
- : (qualifierText.includes('optional') || !!defaultMatch ? false : undefined),
488
- default: defaultMatch
489
- ? (defaultMatch[1] ?? defaultMatch[2] ?? defaultMatch[3]).trim()
490
- : undefined,
491
- });
492
- }
493
- return parameterDocs;
494
- }
495
- function mergeParameterDocs(parameters, parameterDocs) {
496
- const docsByName = new Map(parameterDocs.map((parameterDoc) => [parameterDoc.name, parameterDoc]));
497
- return parameters.map((parameter) => {
498
- const parameterDoc = docsByName.get(parameter.name);
499
- if (!parameterDoc) {
500
- return parameter;
501
- }
502
- return {
503
- ...parameter,
504
- description: parameterDoc.description ?? parameter.description,
505
- required: parameterDoc.required ?? parameter.required,
506
- default: parameterDoc.default ?? parameter.default,
507
- };
508
- });
509
- }
510
- function extractSkillCapabilities(analysis) {
511
- return Array.from(new Set(analysis.capabilities.filter((capability) => !capability.startsWith('tool_use('))));
512
- }
513
- function normalizeRuntimeArgList(value) {
514
- if (value === undefined || value === null) {
515
- return [];
516
- }
517
- if (Array.isArray(value)) {
518
- return value;
519
- }
520
- if (typeof value === 'string') {
521
- const trimmed = value.trim();
522
- if ((trimmed.startsWith('[') && trimmed.endsWith(']'))
523
- || (trimmed.startsWith('{') && trimmed.endsWith('}'))) {
524
- try {
525
- const parsed = JSON.parse(trimmed);
526
- return Array.isArray(parsed) ? parsed : [parsed];
527
- }
528
- catch {
529
- return [value];
530
- }
531
- }
532
- return [value];
533
- }
534
- return [value];
535
- }
536
- function resolveTestRunArgs(args) {
537
- const rawTestArgs = args.test_args;
538
- if (rawTestArgs !== undefined
539
- && rawTestArgs !== null
540
- && !(typeof rawTestArgs === 'string' && rawTestArgs.trim() === '')) {
541
- return normalizeRuntimeArgList(rawTestArgs);
542
- }
543
- return [args.test_input ?? 'test'];
544
- }
545
- function readMetadataName(metadata, fallbackName) {
546
- const name = metadata['name'];
547
- return typeof name === 'string' && name.trim() ? name.trim() : fallbackName;
548
- }
549
- function readMetadataTriggerPhrases(metadata, fallbackTriggerPhrases) {
550
- const rawTriggerPhrases = Array.isArray(metadata['trigger_phrases'])
551
- ? metadata['trigger_phrases']
552
- : (Array.isArray(metadata['triggerPhrases']) ? metadata['triggerPhrases'] : fallbackTriggerPhrases);
553
- return Array.from(new Set(rawTriggerPhrases
554
- .filter((triggerPhrase) => typeof triggerPhrase === 'string')
555
- .map((triggerPhrase) => triggerPhrase.trim())
556
- .filter((triggerPhrase) => triggerPhrase.length > 0)))
557
- .slice(0, 5);
558
- }
559
- async function writeWorkspaceFile(workspacePath, args) {
560
- const relPath = String(args.path ?? '');
561
- const content = String(args.content ?? '');
562
- if (!relPath) {
563
- return { success: false, error: 'path is required' };
564
- }
565
- const filePath = resolveWorkspacePath(workspacePath, relPath);
566
- await fs.mkdir(path.dirname(filePath), { recursive: true });
567
- await fs.writeFile(filePath, content, 'utf8');
568
- return { success: true, path: relPath, bytes: content.length };
569
- }
570
- async function validateWorkspaceDml(workspacePath, args) {
571
- const dmlPath = resolveWorkspacePath(workspacePath, String(args.dml_file ?? ''));
572
- const dml = await fs.readFile(dmlPath, 'utf8');
573
- const result = await validateWithProlog(dml);
574
- return {
575
- valid: result.valid,
576
- errors: result.errors,
577
- warnings: result.warnings ?? [],
578
- };
579
- }
580
- async function runLocalTestDml(context, args) {
581
- const dmlPath = resolveWorkspacePath(context.workspacePath, String(args.dml_file ?? ''));
582
- const dmlCode = await fs.readFile(dmlPath, 'utf8');
583
- const testArgs = resolveTestRunArgs(args);
584
- const result = await executeDml({
585
- dmlCode,
586
- config: context.config,
587
- workspacePath: context.workspacePath,
588
- selection: context.runSelection,
589
- args: testArgs,
590
- gasLimit: 120,
591
- headless: true,
592
- stream: false,
593
- trace: true,
594
- sandbox: context.sandbox,
595
- signal: context.signal,
596
- onEvent: context.onEvent,
597
- onUserInput: async () => '(simulated test input - no interactive user during test_dml)',
598
- skillCatalog: {
599
- workspaceRoot: context.workspaceRoot,
600
- },
601
- });
602
- const toolCalls = result.events
603
- .filter((event) => event.type === 'tool_call')
604
- .map((event) => ({ tool: event.toolName ?? '?', args: event.toolArgs }));
605
- const trace = Array.isArray(result.trace) ? result.trace : undefined;
606
- return {
607
- success: !result.error && !!result.answer,
608
- status: result.error ? 'error' : (result.answer ? 'ok' : 'completed_no_answer'),
609
- answer: result.answer || undefined,
610
- outputs: result.output.length > 0 ? result.output : undefined,
611
- errors: result.error ? [result.error] : undefined,
612
- trace,
613
- tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
614
- };
615
- }
616
- async function publishSkill(context, args) {
617
- const dmlPath = resolveWorkspacePath(context.workspacePath, String(args.dml_file ?? ''));
618
- const dml = await fs.readFile(dmlPath, 'utf8');
619
- const fallbackMetadata = buildLocalMetadata(context.markdown, context.baseName);
620
- const normalized = normalizeDeployInputs(String(args.spec_markdown ?? context.markdown), String(args.metadata_json ?? ''));
621
- const metadata = parseMetadataJson(normalized.metadataJson, fallbackMetadata);
622
- const requestedSlug = typeof args.slug_override === 'string' && args.slug_override.trim()
623
- ? args.slug_override
624
- : (typeof metadata.slug === 'string' && metadata.slug.trim() ? metadata.slug : fallbackMetadata.slug);
625
- const publishName = normalizeSkillSlug(requestedSlug, fallbackMetadata.slug);
626
- const meta = await buildMetaFile({
627
- dml,
628
- markdown: normalized.specMarkdown,
629
- outputDir: context.outputDir,
630
- publishName,
631
- model: context.compileSelection.model,
632
- provider: context.compileSelection.provider,
633
- name: readMetadataName(metadata, fallbackMetadata.name),
634
- triggerPhrases: readMetadataTriggerPhrases(metadata, fallbackMetadata.trigger_phrases),
635
- description: typeof metadata.description === 'string' ? metadata.description : extractDescription(normalized.specMarkdown),
636
- });
637
- const outputPath = path.join(context.outputDir, `${publishName}.dml`);
638
- if (!context.validateOnly) {
639
- await fs.mkdir(context.outputDir, { recursive: true });
640
- await fs.writeFile(outputPath, dml, 'utf8');
641
- await fs.writeFile(path.join(context.outputDir, `${publishName}.meta.json`), JSON.stringify(meta, null, 2) + '\n');
642
- }
643
- return {
644
- dml,
645
- meta,
646
- outputPath,
647
- slug: publishName,
648
- };
649
- }
650
- async function buildMetaFile(input) {
651
- const metaPath = path.join(input.outputDir, `${input.publishName}.meta.json`);
652
- const existing = await loadExistingMeta(metaPath);
653
- const sourceHash = computeHash(input.markdown);
654
- const history = existing?.history ?? [];
655
- const analysis = await analyzeDML(input.dml);
656
- const tools = extractToolNames(analysis);
657
- const parameters = mergeParameterDocs(extractParameters(input.dml), extractParameterDocs(input.markdown));
658
- const capabilities = extractSkillCapabilities(analysis);
659
- return {
660
- version: '1.0.0',
661
- source: input.publishName,
662
- sourceHash,
663
- compiledAt: new Date().toISOString(),
664
- model: input.model,
665
- provider: input.provider,
666
- name: input.name,
667
- triggerPhrases: input.triggerPhrases.length > 0 ? input.triggerPhrases : undefined,
668
- capabilities: capabilities.length > 0 ? capabilities : undefined,
669
- description: input.description,
670
- parameters,
671
- tools,
672
- history: [
673
- ...history,
674
- {
675
- version: history.length + 1,
676
- timestamp: new Date().toISOString(),
677
- sourceHash,
678
- model: input.model,
679
- provider: input.provider,
680
- },
681
- ],
682
- };
683
- }
684
- function extractToolNames(analysis) {
685
- return Array.from(new Set(analysis.capabilities
686
- .filter((capability) => capability.startsWith('tool_use(') && capability.endsWith(')'))
687
- .map((capability) => capability.slice('tool_use('.length, -1)))).sort();
688
- }
689
- async function urlFetch(workspacePath, args, signal) {
690
- const url = String(args.url ?? '');
691
- if (!url) {
692
- throw new Error('url is required');
693
- }
694
- const response = await fetch(url, { signal });
695
- const headers = Object.fromEntries(response.headers.entries());
696
- if (typeof args.save_to === 'string' && args.save_to.trim()) {
697
- const targetPath = resolveWorkspacePath(workspacePath, args.save_to);
698
- await fs.mkdir(path.dirname(targetPath), { recursive: true });
699
- const buffer = Buffer.from(await response.arrayBuffer());
700
- await fs.writeFile(targetPath, buffer);
701
- return {
702
- file_path: targetPath,
703
- size: buffer.byteLength,
704
- status: response.status,
705
- headers,
706
- };
707
- }
708
- const body = await response.text();
709
- const truncated = truncateUrlFetchTextBody(body);
710
- return {
711
- body: truncated.body,
712
- truncated: truncated.truncated,
713
- original_length: truncated.originalLength,
714
- returned_length: truncated.returnedLength,
715
- status: response.status,
716
- headers,
717
- };
718
- }
719
- function resolveWorkspacePath(workspacePath, filePath) {
720
- if (!filePath) {
721
- throw new Error('Path is required');
722
- }
723
- const resolved = path.resolve(workspacePath, filePath);
724
- if (!resolved.startsWith(path.resolve(workspacePath))) {
725
- throw new Error(`Path must stay inside workspace: ${filePath}`);
726
- }
727
- return resolved;
728
- }
729
- function normalizeDeployInputs(specMarkdown, metadataJson) {
730
- if (looksLikeJsonObject(specMarkdown) && !looksLikeJsonObject(metadataJson)) {
731
- return {
732
- specMarkdown: metadataJson,
733
- metadataJson: specMarkdown,
734
- };
735
- }
736
- return { specMarkdown, metadataJson };
737
- }
738
- function looksLikeJsonObject(value) {
739
- const trimmed = value.trim();
740
- return trimmed.startsWith('{') && trimmed.endsWith('}');
741
- }
742
- function parseMetadataJson(metadataJson, fallback) {
743
- try {
744
- const parsed = JSON.parse(metadataJson);
745
- return parsed && typeof parsed === 'object' ? parsed : fallback;
746
- }
747
- catch {
748
- return fallback;
749
- }
750
- }
751
- function computeHash(content) {
752
- return 'sha256:' + crypto.createHash('sha256').update(content).digest('hex').substring(0, 16);
753
- }
754
- async function loadExistingMeta(metaPath) {
755
- try {
756
- const content = await fs.readFile(metaPath, 'utf8');
757
- return JSON.parse(content);
758
- }
759
- catch {
760
- return null;
761
- }
762
- }
763
- //# sourceMappingURL=skill-creator.js.map