zoe-agent 0.3.1

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 (267) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/LICENSE +96 -0
  3. package/README.md +568 -0
  4. package/dist/adapters/cli/agent.d.ts +59 -0
  5. package/dist/adapters/cli/agent.js +232 -0
  6. package/dist/adapters/cli/bootstrap.d.ts +25 -0
  7. package/dist/adapters/cli/bootstrap.js +204 -0
  8. package/dist/adapters/cli/commands/build-registry.d.ts +14 -0
  9. package/dist/adapters/cli/commands/build-registry.js +88 -0
  10. package/dist/adapters/cli/commands/clear.d.ts +7 -0
  11. package/dist/adapters/cli/commands/clear.js +10 -0
  12. package/dist/adapters/cli/commands/compact.d.ts +13 -0
  13. package/dist/adapters/cli/commands/compact.js +96 -0
  14. package/dist/adapters/cli/commands/exit.d.ts +7 -0
  15. package/dist/adapters/cli/commands/exit.js +9 -0
  16. package/dist/adapters/cli/commands/gateway.d.ts +7 -0
  17. package/dist/adapters/cli/commands/gateway.js +152 -0
  18. package/dist/adapters/cli/commands/help.d.ts +9 -0
  19. package/dist/adapters/cli/commands/help.js +12 -0
  20. package/dist/adapters/cli/commands/models.d.ts +10 -0
  21. package/dist/adapters/cli/commands/models.js +32 -0
  22. package/dist/adapters/cli/commands/registry.d.ts +70 -0
  23. package/dist/adapters/cli/commands/registry.js +111 -0
  24. package/dist/adapters/cli/commands/settings-utils.d.ts +38 -0
  25. package/dist/adapters/cli/commands/settings-utils.js +182 -0
  26. package/dist/adapters/cli/commands/settings.d.ts +9 -0
  27. package/dist/adapters/cli/commands/settings.js +395 -0
  28. package/dist/adapters/cli/commands/skills.d.ts +7 -0
  29. package/dist/adapters/cli/commands/skills.js +21 -0
  30. package/dist/adapters/cli/config-loader.d.ts +27 -0
  31. package/dist/adapters/cli/config-loader.js +48 -0
  32. package/dist/adapters/cli/docker-utils.d.ts +37 -0
  33. package/dist/adapters/cli/docker-utils.js +90 -0
  34. package/dist/adapters/cli/index.d.ts +2 -0
  35. package/dist/adapters/cli/index.js +88 -0
  36. package/dist/adapters/cli/repl.d.ts +22 -0
  37. package/dist/adapters/cli/repl.js +256 -0
  38. package/dist/adapters/cli/setup.d.ts +19 -0
  39. package/dist/adapters/cli/setup.js +613 -0
  40. package/dist/adapters/cli/system-prompts.d.ts +56 -0
  41. package/dist/adapters/cli/system-prompts.js +131 -0
  42. package/dist/adapters/cli/tui/app.d.ts +58 -0
  43. package/dist/adapters/cli/tui/app.js +314 -0
  44. package/dist/adapters/cli/tui/components/assistant-message.d.ts +5 -0
  45. package/dist/adapters/cli/tui/components/assistant-message.js +9 -0
  46. package/dist/adapters/cli/tui/components/autocomplete.d.ts +19 -0
  47. package/dist/adapters/cli/tui/components/autocomplete.js +75 -0
  48. package/dist/adapters/cli/tui/components/command-palette.d.ts +15 -0
  49. package/dist/adapters/cli/tui/components/command-palette.js +50 -0
  50. package/dist/adapters/cli/tui/components/diff-viewer.d.ts +5 -0
  51. package/dist/adapters/cli/tui/components/diff-viewer.js +109 -0
  52. package/dist/adapters/cli/tui/components/error-message.d.ts +5 -0
  53. package/dist/adapters/cli/tui/components/error-message.js +8 -0
  54. package/dist/adapters/cli/tui/components/footer.d.ts +20 -0
  55. package/dist/adapters/cli/tui/components/footer.js +19 -0
  56. package/dist/adapters/cli/tui/components/goal-status.d.ts +12 -0
  57. package/dist/adapters/cli/tui/components/goal-status.js +22 -0
  58. package/dist/adapters/cli/tui/components/info-message.d.ts +5 -0
  59. package/dist/adapters/cli/tui/components/info-message.js +8 -0
  60. package/dist/adapters/cli/tui/components/logo-banner.d.ts +7 -0
  61. package/dist/adapters/cli/tui/components/logo-banner.js +33 -0
  62. package/dist/adapters/cli/tui/components/markdown.d.ts +9 -0
  63. package/dist/adapters/cli/tui/components/markdown.js +92 -0
  64. package/dist/adapters/cli/tui/components/message-area.d.ts +19 -0
  65. package/dist/adapters/cli/tui/components/message-area.js +55 -0
  66. package/dist/adapters/cli/tui/components/permission-prompt.d.ts +13 -0
  67. package/dist/adapters/cli/tui/components/permission-prompt.js +32 -0
  68. package/dist/adapters/cli/tui/components/prompt-area.d.ts +22 -0
  69. package/dist/adapters/cli/tui/components/prompt-area.js +68 -0
  70. package/dist/adapters/cli/tui/components/text-input.d.ts +27 -0
  71. package/dist/adapters/cli/tui/components/text-input.js +142 -0
  72. package/dist/adapters/cli/tui/components/tool-call-block.d.ts +11 -0
  73. package/dist/adapters/cli/tui/components/tool-call-block.js +68 -0
  74. package/dist/adapters/cli/tui/components/user-message.d.ts +5 -0
  75. package/dist/adapters/cli/tui/components/user-message.js +8 -0
  76. package/dist/adapters/cli/tui/diff/file-write-meta.d.ts +11 -0
  77. package/dist/adapters/cli/tui/diff/file-write-meta.js +11 -0
  78. package/dist/adapters/cli/tui/diff/line-diff.d.ts +17 -0
  79. package/dist/adapters/cli/tui/diff/line-diff.js +44 -0
  80. package/dist/adapters/cli/tui/feed-serializer.d.ts +29 -0
  81. package/dist/adapters/cli/tui/feed-serializer.js +70 -0
  82. package/dist/adapters/cli/tui/file-index.d.ts +8 -0
  83. package/dist/adapters/cli/tui/file-index.js +41 -0
  84. package/dist/adapters/cli/tui/hooks/use-agent.d.ts +54 -0
  85. package/dist/adapters/cli/tui/hooks/use-agent.js +177 -0
  86. package/dist/adapters/cli/tui/hooks/use-feed.d.ts +16 -0
  87. package/dist/adapters/cli/tui/hooks/use-feed.js +25 -0
  88. package/dist/adapters/cli/tui/hooks/use-file-watcher.d.ts +10 -0
  89. package/dist/adapters/cli/tui/hooks/use-file-watcher.js +43 -0
  90. package/dist/adapters/cli/tui/hooks/use-keybindings.d.ts +16 -0
  91. package/dist/adapters/cli/tui/hooks/use-keybindings.js +25 -0
  92. package/dist/adapters/cli/tui/hooks/use-theme.d.ts +8 -0
  93. package/dist/adapters/cli/tui/hooks/use-theme.js +12 -0
  94. package/dist/adapters/cli/tui/index.d.ts +19 -0
  95. package/dist/adapters/cli/tui/index.js +206 -0
  96. package/dist/adapters/cli/tui/ink-reset.d.ts +29 -0
  97. package/dist/adapters/cli/tui/ink-reset.js +57 -0
  98. package/dist/adapters/cli/tui/layout.d.ts +15 -0
  99. package/dist/adapters/cli/tui/layout.js +15 -0
  100. package/dist/adapters/cli/tui/logo/gradient.d.ts +11 -0
  101. package/dist/adapters/cli/tui/logo/gradient.js +31 -0
  102. package/dist/adapters/cli/tui/overlays/help-dialog.d.ts +4 -0
  103. package/dist/adapters/cli/tui/overlays/help-dialog.js +26 -0
  104. package/dist/adapters/cli/tui/overlays/model-selector.d.ts +14 -0
  105. package/dist/adapters/cli/tui/overlays/model-selector.js +43 -0
  106. package/dist/adapters/cli/tui/overlays/session-selector.d.ts +35 -0
  107. package/dist/adapters/cli/tui/overlays/session-selector.js +162 -0
  108. package/dist/adapters/cli/tui/overlays/settings-overlay.d.ts +24 -0
  109. package/dist/adapters/cli/tui/overlays/settings-overlay.js +126 -0
  110. package/dist/adapters/cli/tui/session-export.d.ts +21 -0
  111. package/dist/adapters/cli/tui/session-export.js +63 -0
  112. package/dist/adapters/cli/tui/theme.d.ts +23 -0
  113. package/dist/adapters/cli/tui/theme.js +22 -0
  114. package/dist/adapters/cli/tui/types.d.ts +52 -0
  115. package/dist/adapters/cli/tui/types.js +12 -0
  116. package/dist/adapters/sdk/agent.d.ts +20 -0
  117. package/dist/adapters/sdk/agent.js +356 -0
  118. package/dist/adapters/sdk/http.d.ts +43 -0
  119. package/dist/adapters/sdk/http.js +61 -0
  120. package/dist/adapters/sdk/index.d.ts +58 -0
  121. package/dist/adapters/sdk/index.js +209 -0
  122. package/dist/adapters/sdk/settings.d.ts +18 -0
  123. package/dist/adapters/sdk/settings.js +57 -0
  124. package/dist/adapters/sdk/tools.d.ts +7 -0
  125. package/dist/adapters/sdk/tools.js +13 -0
  126. package/dist/adapters/server/auth.d.ts +53 -0
  127. package/dist/adapters/server/auth.js +168 -0
  128. package/dist/adapters/server/index.d.ts +40 -0
  129. package/dist/adapters/server/index.js +255 -0
  130. package/dist/adapters/server/rest-gateway.d.ts +13 -0
  131. package/dist/adapters/server/rest-gateway.js +218 -0
  132. package/dist/adapters/server/rest.d.ts +37 -0
  133. package/dist/adapters/server/rest.js +341 -0
  134. package/dist/adapters/server/server-core.d.ts +55 -0
  135. package/dist/adapters/server/server-core.js +121 -0
  136. package/dist/adapters/server/session-store.d.ts +81 -0
  137. package/dist/adapters/server/session-store.js +272 -0
  138. package/dist/adapters/server/settings-handlers.d.ts +24 -0
  139. package/dist/adapters/server/settings-handlers.js +360 -0
  140. package/dist/adapters/server/standalone.d.ts +19 -0
  141. package/dist/adapters/server/standalone.js +113 -0
  142. package/dist/adapters/server/websocket.d.ts +26 -0
  143. package/dist/adapters/server/websocket.js +68 -0
  144. package/dist/adapters/server/ws-handlers.d.ts +32 -0
  145. package/dist/adapters/server/ws-handlers.js +523 -0
  146. package/dist/adapters/server/ws-types.d.ts +304 -0
  147. package/dist/adapters/server/ws-types.js +7 -0
  148. package/dist/core/agent-loop.d.ts +68 -0
  149. package/dist/core/agent-loop.js +423 -0
  150. package/dist/core/config.d.ts +115 -0
  151. package/dist/core/config.js +189 -0
  152. package/dist/core/errors.d.ts +58 -0
  153. package/dist/core/errors.js +88 -0
  154. package/dist/core/hooks.d.ts +35 -0
  155. package/dist/core/hooks.js +49 -0
  156. package/dist/core/index.d.ts +23 -0
  157. package/dist/core/index.js +29 -0
  158. package/dist/core/message-convert.d.ts +41 -0
  159. package/dist/core/message-convert.js +94 -0
  160. package/dist/core/middleware/auth.d.ts +24 -0
  161. package/dist/core/middleware/auth.js +28 -0
  162. package/dist/core/middleware/logging.d.ts +23 -0
  163. package/dist/core/middleware/logging.js +28 -0
  164. package/dist/core/middleware/rate-limit.d.ts +27 -0
  165. package/dist/core/middleware/rate-limit.js +38 -0
  166. package/dist/core/middleware/semantic-tools.d.ts +10 -0
  167. package/dist/core/middleware/semantic-tools.js +43 -0
  168. package/dist/core/middleware.d.ts +48 -0
  169. package/dist/core/middleware.js +38 -0
  170. package/dist/core/permission.d.ts +25 -0
  171. package/dist/core/permission.js +50 -0
  172. package/dist/core/provider-config.d.ts +129 -0
  173. package/dist/core/provider-config.js +273 -0
  174. package/dist/core/provider-env.d.ts +39 -0
  175. package/dist/core/provider-env.js +142 -0
  176. package/dist/core/provider-resolver.d.ts +12 -0
  177. package/dist/core/provider-resolver.js +12 -0
  178. package/dist/core/session-store.d.ts +75 -0
  179. package/dist/core/session-store.js +245 -0
  180. package/dist/core/settings-manager.d.ts +57 -0
  181. package/dist/core/settings-manager.js +359 -0
  182. package/dist/core/settings-schema.d.ts +38 -0
  183. package/dist/core/settings-schema.js +171 -0
  184. package/dist/core/skill-catalog.d.ts +6 -0
  185. package/dist/core/skill-catalog.js +17 -0
  186. package/dist/core/skill-invoker.d.ts +127 -0
  187. package/dist/core/skill-invoker.js +182 -0
  188. package/dist/core/stream-accumulator.d.ts +21 -0
  189. package/dist/core/stream-accumulator.js +51 -0
  190. package/dist/core/stream-manager.d.ts +58 -0
  191. package/dist/core/stream-manager.js +212 -0
  192. package/dist/core/tool-executor.d.ts +84 -0
  193. package/dist/core/tool-executor.js +256 -0
  194. package/dist/core/types.d.ts +259 -0
  195. package/dist/core/types.js +11 -0
  196. package/dist/gateway/gateway.d.ts +52 -0
  197. package/dist/gateway/gateway.js +537 -0
  198. package/dist/gateway/index.d.ts +21 -0
  199. package/dist/gateway/index.js +31 -0
  200. package/dist/gateway/openapi-importer.d.ts +15 -0
  201. package/dist/gateway/openapi-importer.js +66 -0
  202. package/dist/gateway/semantic-scorer.d.ts +7 -0
  203. package/dist/gateway/semantic-scorer.js +24 -0
  204. package/dist/gateway/settings-adapter.d.ts +49 -0
  205. package/dist/gateway/settings-adapter.js +137 -0
  206. package/dist/gateway/tool-factory.d.ts +9 -0
  207. package/dist/gateway/tool-factory.js +414 -0
  208. package/dist/gateway/types.d.ts +68 -0
  209. package/dist/gateway/types.js +7 -0
  210. package/dist/models-catalog.js +46 -0
  211. package/dist/providers/anthropic.d.ts +22 -0
  212. package/dist/providers/anthropic.js +148 -0
  213. package/dist/providers/factory.d.ts +10 -0
  214. package/dist/providers/factory.js +25 -0
  215. package/dist/providers/openai.d.ts +15 -0
  216. package/dist/providers/openai.js +71 -0
  217. package/dist/providers/types.d.ts +48 -0
  218. package/dist/providers/types.js +1 -0
  219. package/dist/skills/args.d.ts +37 -0
  220. package/dist/skills/args.js +99 -0
  221. package/dist/skills/index.d.ts +11 -0
  222. package/dist/skills/index.js +23 -0
  223. package/dist/skills/loader.d.ts +3 -0
  224. package/dist/skills/loader.js +59 -0
  225. package/dist/skills/parser.d.ts +7 -0
  226. package/dist/skills/parser.js +152 -0
  227. package/dist/skills/registry.d.ts +13 -0
  228. package/dist/skills/registry.js +74 -0
  229. package/dist/skills/resolver.d.ts +19 -0
  230. package/dist/skills/resolver.js +116 -0
  231. package/dist/skills/types.d.ts +74 -0
  232. package/dist/skills/types.js +50 -0
  233. package/dist/tools/browser.d.ts +2 -0
  234. package/dist/tools/browser.js +68 -0
  235. package/dist/tools/core.d.ts +20 -0
  236. package/dist/tools/core.js +244 -0
  237. package/dist/tools/email.d.ts +2 -0
  238. package/dist/tools/email.js +61 -0
  239. package/dist/tools/image.d.ts +2 -0
  240. package/dist/tools/image.js +257 -0
  241. package/dist/tools/index.d.ts +2 -0
  242. package/dist/tools/index.js +88 -0
  243. package/dist/tools/interface.d.ts +22 -0
  244. package/dist/tools/interface.js +1 -0
  245. package/dist/tools/notify.d.ts +2 -0
  246. package/dist/tools/notify.js +100 -0
  247. package/dist/tools/prompt-optimizer.d.ts +2 -0
  248. package/dist/tools/prompt-optimizer.js +65 -0
  249. package/dist/tools/screenshot.d.ts +2 -0
  250. package/dist/tools/screenshot.js +184 -0
  251. package/dist/tools/search.d.ts +2 -0
  252. package/dist/tools/search.js +78 -0
  253. package/dist/tools/todos.d.ts +10 -0
  254. package/dist/tools/todos.js +50 -0
  255. package/package.json +119 -0
  256. package/skills/docker-ops/SKILL.md +329 -0
  257. package/skills/k8s-deploy/SKILL.md +397 -0
  258. package/skills/log-analyzer/SKILL.md +331 -0
  259. package/skills/speckit-analyze/SKILL.md +260 -0
  260. package/skills/speckit-checklist/SKILL.md +374 -0
  261. package/skills/speckit-clarify/SKILL.md +286 -0
  262. package/skills/speckit-constitution/SKILL.md +157 -0
  263. package/skills/speckit-implement/SKILL.md +224 -0
  264. package/skills/speckit-plan/SKILL.md +171 -0
  265. package/skills/speckit-specify/SKILL.md +346 -0
  266. package/skills/speckit-tasks/SKILL.md +215 -0
  267. package/skills/speckit-taskstoissues/SKILL.md +107 -0
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Zoe Core — Config Utilities
3
+ *
4
+ * Config loading, merging, and environment overrides.
5
+ * Chalk-free — suitable for all adapters (CLI, SDK, Server).
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import * as os from 'os';
10
+ import { DEFAULT_MODELS } from '../models-catalog.js';
11
+ // ── Constants ──────────────────────────────────────────────────────────
12
+ const GLOBAL_CONFIG_DIR = path.join(os.homedir(), '.zoe');
13
+ const GLOBAL_CONFIG_FILE = path.join(GLOBAL_CONFIG_DIR, 'setting.json');
14
+ const LOCAL_CONFIG_FILE = path.join(process.cwd(), '.zoe', 'setting.json');
15
+ // ── Config path helpers ────────────────────────────────────────────────
16
+ /**
17
+ * Returns the config file path for the given scope.
18
+ */
19
+ export function getConfigPath(global) {
20
+ return global ? GLOBAL_CONFIG_FILE : LOCAL_CONFIG_FILE;
21
+ }
22
+ /**
23
+ * Returns the config directory path for the given scope.
24
+ */
25
+ export function getConfigDir(global) {
26
+ return global ? GLOBAL_CONFIG_DIR : path.join(process.cwd(), '.zoe');
27
+ }
28
+ /**
29
+ * Returns both global and local config paths.
30
+ */
31
+ export function getConfigPaths() {
32
+ return {
33
+ global: GLOBAL_CONFIG_FILE,
34
+ local: LOCAL_CONFIG_FILE,
35
+ globalDir: GLOBAL_CONFIG_DIR,
36
+ };
37
+ }
38
+ // ── JSON loading ───────────────────────────────────────────────────────
39
+ /**
40
+ * Load and parse a JSON config file.
41
+ * Returns `{ config, warning }` — warning is set if parsing failed.
42
+ */
43
+ export function loadJsonConfig(filePath) {
44
+ if (fs.existsSync(filePath)) {
45
+ try {
46
+ return { config: JSON.parse(fs.readFileSync(filePath, 'utf-8')) };
47
+ }
48
+ catch (e) {
49
+ return {
50
+ config: {},
51
+ warning: `Warning: Failed to parse config file at ${filePath}`,
52
+ };
53
+ }
54
+ }
55
+ return { config: {} };
56
+ }
57
+ // ── Merge & overlay ────────────────────────────────────────────────────
58
+ /**
59
+ * Load global and local configs and merge them.
60
+ * Priority: local > global.
61
+ */
62
+ export function loadMergedConfig() {
63
+ const global = loadJsonConfig(GLOBAL_CONFIG_FILE);
64
+ const local = loadJsonConfig(LOCAL_CONFIG_FILE);
65
+ return { ...global.config, ...local.config };
66
+ }
67
+ /**
68
+ * Apply environment variable overrides to the merged config.
69
+ * Env vars take priority over JSON config for tool settings.
70
+ * Also injects provider API keys from env vars into the models map.
71
+ */
72
+ export function applyEnvOverrides(config) {
73
+ // Tool settings
74
+ if (process.env.SMTP_HOST)
75
+ config.smtpHost = process.env.SMTP_HOST;
76
+ if (process.env.SMTP_PORT)
77
+ config.smtpPort = process.env.SMTP_PORT;
78
+ if (process.env.SMTP_USER)
79
+ config.smtpUser = process.env.SMTP_USER;
80
+ if (process.env.SMTP_PASS)
81
+ config.smtpPass = process.env.SMTP_PASS;
82
+ if (process.env.TAVILY_API_KEY)
83
+ config.tavilyApiKey = process.env.TAVILY_API_KEY;
84
+ if (process.env.FEISHU_WEBHOOK)
85
+ config.feishuWebhook = process.env.FEISHU_WEBHOOK;
86
+ if (process.env.FEISHU_KEYWORD)
87
+ config.feishuKeyword = process.env.FEISHU_KEYWORD;
88
+ if (process.env.DINGTALK_WEBHOOK)
89
+ config.dingtalkWebhook = process.env.DINGTALK_WEBHOOK;
90
+ if (process.env.DINGTALK_KEYWORD)
91
+ config.dingtalkKeyword = process.env.DINGTALK_KEYWORD;
92
+ if (process.env.WECOM_WEBHOOK)
93
+ config.wecomWebhook = process.env.WECOM_WEBHOOK;
94
+ if (process.env.WECOM_KEYWORD)
95
+ config.wecomKeyword = process.env.WECOM_KEYWORD;
96
+ // Permission level
97
+ if (process.env.ZOE_PERMISSION) {
98
+ const val = process.env.ZOE_PERMISSION;
99
+ if (val === "strict" || val === "moderate" || val === "permissive") {
100
+ config.permissionLevel = val;
101
+ }
102
+ }
103
+ // Provider API keys — inject into models map from env vars
104
+ if (!config.models)
105
+ config.models = {};
106
+ if (process.env.OPENAI_API_KEY) {
107
+ config.models.openai = {
108
+ apiKey: process.env.OPENAI_API_KEY,
109
+ model: process.env.OPENAI_MODEL || config.models.openai?.model || DEFAULT_MODELS.openai,
110
+ };
111
+ }
112
+ if (process.env.OPENAI_COMPAT_API_KEY) {
113
+ config.models['openai-compatible'] = {
114
+ apiKey: process.env.OPENAI_COMPAT_API_KEY,
115
+ baseUrl: process.env.OPENAI_COMPAT_BASE_URL || process.env.OPENAI_BASE_URL || config.models['openai-compatible']?.baseUrl || 'https://api.openai.com/v1',
116
+ model: process.env.OPENAI_COMPAT_MODEL || process.env.LLM_MODEL || process.env.ZOE_MODEL || config.models['openai-compatible']?.model || DEFAULT_MODELS['openai-compatible'],
117
+ };
118
+ }
119
+ if (process.env.ANTHROPIC_API_KEY) {
120
+ config.models.anthropic = {
121
+ apiKey: process.env.ANTHROPIC_API_KEY,
122
+ model: process.env.ANTHROPIC_MODEL || config.models.anthropic?.model || DEFAULT_MODELS.anthropic,
123
+ };
124
+ }
125
+ if (process.env.GLM_API_KEY) {
126
+ config.models.glm = {
127
+ apiKey: process.env.GLM_API_KEY,
128
+ model: process.env.GLM_MODEL || config.models.glm?.model || DEFAULT_MODELS.glm,
129
+ };
130
+ }
131
+ return config;
132
+ }
133
+ /**
134
+ * Auto-migrate legacy config format (top-level apiKey/baseUrl/model) to the
135
+ * models map format used by the current architecture.
136
+ */
137
+ export function migrateLegacyFormat(config, options) {
138
+ if (!config.models && (config.apiKey || process.env.OPENAI_API_KEY)) {
139
+ config.models = {
140
+ openai: {
141
+ apiKey: process.env.OPENAI_API_KEY || config.apiKey || '',
142
+ model: options?.model || process.env.OPENAI_MODEL || config.model || DEFAULT_MODELS.openai,
143
+ },
144
+ };
145
+ if (!config.provider)
146
+ config.provider = 'openai';
147
+ }
148
+ return config;
149
+ }
150
+ /**
151
+ * Resolve the active provider type from CLI flags, env vars, and config.
152
+ * Checks LLM_PROVIDER env var as a standard alias for ZOE_PROVIDER.
153
+ */
154
+ export function resolveActiveProviderType(config, options) {
155
+ return (options?.provider ||
156
+ process.env.LLM_PROVIDER ||
157
+ process.env.ZOE_PROVIDER ||
158
+ config.provider ||
159
+ 'openai');
160
+ }
161
+ // ── Save ───────────────────────────────────────────────────────────────
162
+ /**
163
+ * Save config to disk. If a local config exists, saves there; otherwise global.
164
+ */
165
+ export function saveConfig(config) {
166
+ const targetFile = fs.existsSync(path.join(process.cwd(), '.zoe', 'setting.json'))
167
+ ? LOCAL_CONFIG_FILE
168
+ : GLOBAL_CONFIG_FILE;
169
+ writeConfigToPath(config, targetFile);
170
+ }
171
+ /**
172
+ * Save config to a specific path.
173
+ * Throws on failure — callers handle error display.
174
+ */
175
+ export function writeConfigToPath(config, targetFile) {
176
+ const dir = path.dirname(targetFile);
177
+ if (!fs.existsSync(dir))
178
+ fs.mkdirSync(dir, { recursive: true });
179
+ fs.writeFileSync(targetFile, JSON.stringify(config, null, 2), { mode: 0o600 });
180
+ }
181
+ // ── Utility ────────────────────────────────────────────────────────────
182
+ /**
183
+ * Mask a secret string for display, showing only first 3 and last 4 chars.
184
+ */
185
+ export function maskSecret(secret) {
186
+ if (!secret || secret.length < 8)
187
+ return '******';
188
+ return `${secret.slice(0, 3)}...${secret.slice(-4)}`;
189
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Zoe Core — Error class hierarchy
3
+ *
4
+ * Proper class hierarchy for all Zoe errors.
5
+ * Each error class carries a `code`, `retryable` flag, and domain-specific
6
+ * metadata (e.g. `provider`, `tool`, `steps`).
7
+ */
8
+ /**
9
+ * Base class for all Zoe errors.
10
+ *
11
+ * Carries a machine-readable `code` and a `retryable` flag so callers can
12
+ * decide whether to retry automatically.
13
+ */
14
+ export declare class ZoeError extends Error {
15
+ /** Machine-readable error code, e.g. "PROVIDER_ERROR", "TOOL_FAILED". */
16
+ code: string;
17
+ /** Whether the operation that caused this error can be retried. */
18
+ retryable: boolean;
19
+ constructor(message: string, code: string, retryable?: boolean);
20
+ }
21
+ /**
22
+ * Error originating from a provider (LLM API call failure, auth, rate-limit, etc.).
23
+ */
24
+ export declare class ProviderError extends ZoeError {
25
+ /** The provider name that produced the error, if known. */
26
+ provider?: string;
27
+ constructor(message: string, provider?: string);
28
+ }
29
+ /**
30
+ * Error from tool execution.
31
+ */
32
+ export declare class ToolError extends ZoeError {
33
+ /** The tool name that produced the error, if known. */
34
+ tool?: string;
35
+ constructor(message: string, tool?: string);
36
+ }
37
+ /**
38
+ * Thrown when the agent loop exceeds the configured maximum number of steps.
39
+ */
40
+ export declare class MaxStepsError extends ZoeError {
41
+ /** The number of steps that were executed. */
42
+ steps: number;
43
+ constructor(steps: number, maxSteps: number);
44
+ }
45
+ /**
46
+ * Thrown when an operation is aborted (e.g. via AbortSignal).
47
+ */
48
+ export declare class AbortedError extends ZoeError {
49
+ constructor(message?: string);
50
+ }
51
+ /**
52
+ * Error from gateway operations (MCP client, REST proxy, target management).
53
+ */
54
+ export declare class GatewayError extends ZoeError {
55
+ /** The target name that produced the error, if known. */
56
+ target?: string;
57
+ constructor(message: string, target?: string, retryable?: boolean);
58
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Zoe Core — Error class hierarchy
3
+ *
4
+ * Proper class hierarchy for all Zoe errors.
5
+ * Each error class carries a `code`, `retryable` flag, and domain-specific
6
+ * metadata (e.g. `provider`, `tool`, `steps`).
7
+ */
8
+ // ── Base error ──────────────────────────────────────────────────────────
9
+ /**
10
+ * Base class for all Zoe errors.
11
+ *
12
+ * Carries a machine-readable `code` and a `retryable` flag so callers can
13
+ * decide whether to retry automatically.
14
+ */
15
+ export class ZoeError extends Error {
16
+ /** Machine-readable error code, e.g. "PROVIDER_ERROR", "TOOL_FAILED". */
17
+ code;
18
+ /** Whether the operation that caused this error can be retried. */
19
+ retryable;
20
+ constructor(message, code, retryable = false) {
21
+ super(message);
22
+ this.name = "ZoeError";
23
+ this.code = code;
24
+ this.retryable = retryable;
25
+ }
26
+ }
27
+ // ── Provider errors ─────────────────────────────────────────────────────
28
+ /**
29
+ * Error originating from a provider (LLM API call failure, auth, rate-limit, etc.).
30
+ */
31
+ export class ProviderError extends ZoeError {
32
+ /** The provider name that produced the error, if known. */
33
+ provider;
34
+ constructor(message, provider) {
35
+ super(message, "PROVIDER_ERROR", true);
36
+ this.name = "ProviderError";
37
+ this.provider = provider;
38
+ }
39
+ }
40
+ // ── Tool errors ─────────────────────────────────────────────────────────
41
+ /**
42
+ * Error from tool execution.
43
+ */
44
+ export class ToolError extends ZoeError {
45
+ /** The tool name that produced the error, if known. */
46
+ tool;
47
+ constructor(message, tool) {
48
+ super(message, "TOOL_FAILED", true);
49
+ this.name = "ToolError";
50
+ this.tool = tool;
51
+ }
52
+ }
53
+ // ── Max steps ───────────────────────────────────────────────────────────
54
+ /**
55
+ * Thrown when the agent loop exceeds the configured maximum number of steps.
56
+ */
57
+ export class MaxStepsError extends ZoeError {
58
+ /** The number of steps that were executed. */
59
+ steps;
60
+ constructor(steps, maxSteps) {
61
+ super(`Maximum steps reached (${steps}/${maxSteps})`, "MAX_STEPS", false);
62
+ this.name = "MaxStepsError";
63
+ this.steps = steps;
64
+ }
65
+ }
66
+ // ── Aborted ─────────────────────────────────────────────────────────────
67
+ /**
68
+ * Thrown when an operation is aborted (e.g. via AbortSignal).
69
+ */
70
+ export class AbortedError extends ZoeError {
71
+ constructor(message) {
72
+ super(message ?? "Operation was aborted", "ABORTED", false);
73
+ this.name = "AbortedError";
74
+ }
75
+ }
76
+ // ── Gateway errors ──────────────────────────────────────────────────────
77
+ /**
78
+ * Error from gateway operations (MCP client, REST proxy, target management).
79
+ */
80
+ export class GatewayError extends ZoeError {
81
+ /** The target name that produced the error, if known. */
82
+ target;
83
+ constructor(message, target, retryable = true) {
84
+ super(message, "GATEWAY_ERROR", retryable);
85
+ this.name = "GatewayError";
86
+ this.target = target;
87
+ }
88
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Zoe SDK — Hook executor
3
+ *
4
+ * Wraps a user-supplied `Hooks` object in a safe executor that:
5
+ * - treats missing hooks as no-ops
6
+ * - awaits async hooks
7
+ * - catches and logs hook errors without failing the main flow
8
+ */
9
+ import type { Hooks, StepResult, ZoeError, GenerateTextResult } from "./types.js";
10
+ export interface HookExecutor {
11
+ beforeToolCall(call: {
12
+ name: string;
13
+ args: Record<string, unknown>;
14
+ }): Promise<void>;
15
+ afterToolCall(result: {
16
+ name: string;
17
+ output: string;
18
+ duration: number;
19
+ }): Promise<void>;
20
+ onStep(step: StepResult): Promise<void>;
21
+ onError(error: ZoeError): Promise<void>;
22
+ onFinish(result: GenerateTextResult): Promise<void>;
23
+ }
24
+ /**
25
+ * Create a safe hook executor from an optional `Hooks` object.
26
+ *
27
+ * Every method on the returned `HookExecutor` is safe to call even when
28
+ * the caller provided no hooks — undefined hooks are treated as no-ops,
29
+ * and any error thrown by a hook is caught, logged, and swallowed so
30
+ * the main agent loop is never disrupted.
31
+ *
32
+ * @param hooks Optional user-supplied hooks
33
+ * @returns A `HookExecutor` whose methods are always safe to invoke
34
+ */
35
+ export declare function createHookExecutor(hooks?: Hooks): HookExecutor;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Zoe SDK — Hook executor
3
+ *
4
+ * Wraps a user-supplied `Hooks` object in a safe executor that:
5
+ * - treats missing hooks as no-ops
6
+ * - awaits async hooks
7
+ * - catches and logs hook errors without failing the main flow
8
+ */
9
+ /**
10
+ * Create a safe hook executor from an optional `Hooks` object.
11
+ *
12
+ * Every method on the returned `HookExecutor` is safe to call even when
13
+ * the caller provided no hooks — undefined hooks are treated as no-ops,
14
+ * and any error thrown by a hook is caught, logged, and swallowed so
15
+ * the main agent loop is never disrupted.
16
+ *
17
+ * @param hooks Optional user-supplied hooks
18
+ * @returns A `HookExecutor` whose methods are always safe to invoke
19
+ */
20
+ export function createHookExecutor(hooks) {
21
+ const h = hooks ?? {};
22
+ async function run(fn, label) {
23
+ if (fn == null)
24
+ return;
25
+ try {
26
+ await fn();
27
+ }
28
+ catch (err) {
29
+ console.error(`[zoe] ${label} hook error:`, err);
30
+ }
31
+ }
32
+ return {
33
+ async beforeToolCall(call) {
34
+ await run(() => h.beforeToolCall?.(call), "beforeToolCall");
35
+ },
36
+ async afterToolCall(result) {
37
+ await run(() => h.afterToolCall?.(result), "afterToolCall");
38
+ },
39
+ async onStep(step) {
40
+ await run(() => h.onStep?.(step), "onStep");
41
+ },
42
+ async onError(error) {
43
+ await run(() => h.onError?.(error), "onError");
44
+ },
45
+ async onFinish(result) {
46
+ await run(() => h.onFinish?.(result), "onFinish");
47
+ },
48
+ };
49
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Zoe Core Module
3
+ *
4
+ * Central orchestrators and utilities for the Zoe unified architecture.
5
+ */
6
+ export { invokeSkill, createSkillProviderSwitcher, type SkillInvocationResult, type SkillProviderSwitcher, type ProviderSwitcherConfig, } from './skill-invoker.js';
7
+ export { buildSkillCatalog } from './skill-catalog.js';
8
+ export { runAgentLoop, type AgentLoopOptions, type AgentLoopResult, type AgentLoopError, type ProviderFactory, } from './agent-loop.js';
9
+ export { createHookExecutor, type HookExecutor } from './hooks.js';
10
+ export { StreamManager } from './stream-manager.js';
11
+ export { createSessionStore, createMemoryStore, createPersistenceBackend, persistSession, registerBackend, FilePersistenceBackend, MemoryPersistenceBackend } from './session-store.js';
12
+ export type { BackendFactory } from './session-store.js';
13
+ export { ZoeError, ProviderError, ToolError, MaxStepsError, AbortedError, } from './errors.js';
14
+ export type { ProviderType, MultiProviderConfig, Message, ToolCall, StepResult, Usage, CumulativeUsage, UserToolDefinition, ToolContext, ToolResult, Hooks, GenerateTextOptions, GenerateTextResult, StreamTextOptions, StreamTextResult, AgentCreateOptions, SdkAgent, AgentResponse, SessionStore, SessionData, PersistenceBackend, PersistenceConfig, SkillMetadata, PermissionLevel, ToolRiskCategory, } from './types.js';
15
+ export { provider, configureProviders, getProviderConfig, getDefaultProviderType, getDefaultProvider, getProvider, resolveProviderConfigFromApp, resolveFromEnv, resolveFromConfigFile, migrateLegacyConfig, addProvider, updateProviderConfig, removeProvider, resolveGLMModel, } from './provider-resolver.js';
16
+ export type { ResolvedProviderConfig, AppConfig, } from './provider-resolver.js';
17
+ export { generateId, now, estimateTokens, toZoeError, messageToProviderMessage, providerToolCallToToolCall, providerResponseToMessages, } from './message-convert.js';
18
+ export { CORE_TOOLS, COMM_TOOLS, ADVANCED_TOOLS, ALL_TOOLS, tool, resolveTools, getToolGroup, registerTool, executeTool, getAllToolDefinitions, } from './tool-executor.js';
19
+ export { checkToolPermission, getToolRiskCategory, resolvePermissionLevel, } from './permission.js';
20
+ export { compose, type PipelineContext, type Middleware, } from './middleware.js';
21
+ export { loggingMiddleware, type LoggingOptions } from './middleware/logging.js';
22
+ export { rateLimitMiddleware, type RateLimitOptions } from './middleware/rate-limit.js';
23
+ export { authMiddleware, type AuthOptions } from './middleware/auth.js';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Zoe Core Module
3
+ *
4
+ * Central orchestrators and utilities for the Zoe unified architecture.
5
+ */
6
+ export { invokeSkill, createSkillProviderSwitcher, } from './skill-invoker.js';
7
+ export { buildSkillCatalog } from './skill-catalog.js';
8
+ export { runAgentLoop, } from './agent-loop.js';
9
+ export { createHookExecutor } from './hooks.js';
10
+ export { StreamManager } from './stream-manager.js';
11
+ export { createSessionStore, createMemoryStore, createPersistenceBackend, persistSession, registerBackend, FilePersistenceBackend, MemoryPersistenceBackend } from './session-store.js';
12
+ // Export error classes (canonical definitions live in ./errors.ts)
13
+ export { ZoeError, ProviderError, ToolError, MaxStepsError, AbortedError, } from './errors.js';
14
+ // ZoeError is also re-exported as a value from types.ts, but the canonical
15
+ // class export comes from ./errors.js above. The `export type` block omits
16
+ // ZoeError intentionally to avoid a duplicate value export.
17
+ // Export provider resolver functions
18
+ export { provider, configureProviders, getProviderConfig, getDefaultProviderType, getDefaultProvider, getProvider, resolveProviderConfigFromApp, resolveFromEnv, resolveFromConfigFile, migrateLegacyConfig, addProvider, updateProviderConfig, removeProvider, resolveGLMModel, } from './provider-resolver.js';
19
+ // Export message conversion helpers
20
+ export { generateId, now, estimateTokens, toZoeError, messageToProviderMessage, providerToolCallToToolCall, providerResponseToMessages, } from './message-convert.js';
21
+ // Export tool executor
22
+ export { CORE_TOOLS, COMM_TOOLS, ADVANCED_TOOLS, ALL_TOOLS, tool, resolveTools, getToolGroup, registerTool, executeTool, getAllToolDefinitions, } from './tool-executor.js';
23
+ // Export permission system
24
+ export { checkToolPermission, getToolRiskCategory, resolvePermissionLevel, } from './permission.js';
25
+ // Export middleware pipeline
26
+ export { compose, } from './middleware.js';
27
+ export { loggingMiddleware } from './middleware/logging.js';
28
+ export { rateLimitMiddleware } from './middleware/rate-limit.js';
29
+ export { authMiddleware } from './middleware/auth.js';
@@ -0,0 +1,41 @@
1
+ /** Zoe Core — Message conversion helpers */
2
+ import type { Message, ToolCall } from "./types.js";
3
+ import { ZoeError } from "./errors.js";
4
+ import type { ProviderMessage, ProviderResponse, ProviderToolCall } from "../providers/types.js";
5
+ /**
6
+ * Generate a unique identifier using crypto.randomUUID().
7
+ */
8
+ export declare function generateId(): string;
9
+ /**
10
+ * Get the current Unix timestamp in milliseconds.
11
+ */
12
+ export declare function now(): number;
13
+ /**
14
+ * Rough token estimate: ~4 characters per token.
15
+ */
16
+ export declare function estimateTokens(text: string): number;
17
+ /**
18
+ * Create a ZoeError from a plain Error or unknown value.
19
+ * Uses the proper class hierarchy based on the error code.
20
+ */
21
+ export declare function toZoeError(err: unknown, code: string): ZoeError;
22
+ /**
23
+ * Convert an SDK Message to ProviderMessage format.
24
+ */
25
+ export declare function messageToProviderMessage(msg: Message): ProviderMessage;
26
+ /**
27
+ * Convert a ProviderToolCall to SDK ToolCall format.
28
+ */
29
+ export declare function providerToolCallToToolCall(tc: ProviderToolCall): ToolCall;
30
+ /**
31
+ * Convert a ProviderResponse into an array of SDK Message objects.
32
+ *
33
+ * A single provider response may contain both text content and tool calls.
34
+ * This function normalises it into one or more Message objects:
35
+ * - An assistant message with text content (and optional toolCalls)
36
+ * - If only tool calls with no text, an assistant message with empty content
37
+ *
38
+ * @param response - The raw ProviderResponse from the LLM provider.
39
+ * @returns Array of Message objects representing the response.
40
+ */
41
+ export declare function providerResponseToMessages(response: ProviderResponse): Message[];
@@ -0,0 +1,94 @@
1
+ /** Zoe Core — Message conversion helpers */
2
+ import { ZoeError, ProviderError, ToolError } from "./errors.js";
3
+ /**
4
+ * Generate a unique identifier using crypto.randomUUID().
5
+ */
6
+ export function generateId() {
7
+ return crypto.randomUUID();
8
+ }
9
+ /**
10
+ * Get the current Unix timestamp in milliseconds.
11
+ */
12
+ export function now() {
13
+ return Date.now();
14
+ }
15
+ /**
16
+ * Rough token estimate: ~4 characters per token.
17
+ */
18
+ export function estimateTokens(text) {
19
+ return Math.ceil(text.length / 4);
20
+ }
21
+ /**
22
+ * Create a ZoeError from a plain Error or unknown value.
23
+ * Uses the proper class hierarchy based on the error code.
24
+ */
25
+ export function toZoeError(err, code) {
26
+ const message = err instanceof Error ? err.message : String(err);
27
+ switch (code) {
28
+ case "PROVIDER_ERROR":
29
+ return new ProviderError(message);
30
+ case "TOOL_FAILED":
31
+ return new ToolError(message);
32
+ default:
33
+ return new ZoeError(message, code, code === "PROVIDER_ERROR");
34
+ }
35
+ }
36
+ /**
37
+ * Convert an SDK Message to ProviderMessage format.
38
+ */
39
+ export function messageToProviderMessage(msg) {
40
+ const pm = { role: msg.role, content: msg.content };
41
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
42
+ pm.tool_calls = msg.toolCalls.map((tc) => ({
43
+ id: tc.id,
44
+ name: tc.name,
45
+ arguments: JSON.stringify(tc.arguments),
46
+ }));
47
+ }
48
+ if (msg.toolCallId) {
49
+ pm.tool_call_id = msg.toolCallId;
50
+ }
51
+ return pm;
52
+ }
53
+ /**
54
+ * Convert a ProviderToolCall to SDK ToolCall format.
55
+ */
56
+ export function providerToolCallToToolCall(tc) {
57
+ let args;
58
+ try {
59
+ args = JSON.parse(tc.arguments);
60
+ }
61
+ catch {
62
+ args = { raw: tc.arguments };
63
+ }
64
+ return {
65
+ id: tc.id,
66
+ name: tc.name,
67
+ arguments: args,
68
+ };
69
+ }
70
+ /**
71
+ * Convert a ProviderResponse into an array of SDK Message objects.
72
+ *
73
+ * A single provider response may contain both text content and tool calls.
74
+ * This function normalises it into one or more Message objects:
75
+ * - An assistant message with text content (and optional toolCalls)
76
+ * - If only tool calls with no text, an assistant message with empty content
77
+ *
78
+ * @param response - The raw ProviderResponse from the LLM provider.
79
+ * @returns Array of Message objects representing the response.
80
+ */
81
+ export function providerResponseToMessages(response) {
82
+ const messages = [];
83
+ // Build assistant message
84
+ const toolCalls = response.tool_calls?.map(providerToolCallToToolCall) ?? [];
85
+ const assistantMsg = {
86
+ id: generateId(),
87
+ role: "assistant",
88
+ content: response.content ?? "",
89
+ timestamp: now(),
90
+ ...(toolCalls.length > 0 ? { toolCalls } : {}),
91
+ };
92
+ messages.push(assistantMsg);
93
+ return messages;
94
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Zoe Middleware — Auth
3
+ *
4
+ * Simple, composable auth validation middleware.
5
+ */
6
+ import type { PipelineContext, Middleware } from "../middleware.js";
7
+ export interface AuthOptions {
8
+ /** Validate the request context. Throw or return false to reject. */
9
+ validate: (ctx: PipelineContext) => boolean | Promise<boolean>;
10
+ /** Error message on rejection (default: "Unauthorized") */
11
+ errorMessage?: string;
12
+ }
13
+ /**
14
+ * Create an auth middleware.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const mw = authMiddleware({
19
+ * validate: (ctx) => !!ctx.metadata.apiKey,
20
+ * errorMessage: "API key required",
21
+ * });
22
+ * ```
23
+ */
24
+ export declare function authMiddleware(options: AuthOptions): Middleware;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Zoe Middleware — Auth
3
+ *
4
+ * Simple, composable auth validation middleware.
5
+ */
6
+ import { ZoeError } from "../errors.js";
7
+ /**
8
+ * Create an auth middleware.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const mw = authMiddleware({
13
+ * validate: (ctx) => !!ctx.metadata.apiKey,
14
+ * errorMessage: "API key required",
15
+ * });
16
+ * ```
17
+ */
18
+ export function authMiddleware(options) {
19
+ const { validate } = options;
20
+ const errorMessage = options.errorMessage ?? "Unauthorized";
21
+ return async (ctx, next) => {
22
+ const allowed = await validate(ctx);
23
+ if (!allowed) {
24
+ throw new ZoeError(errorMessage, "UNAUTHORIZED", false);
25
+ }
26
+ await next();
27
+ };
28
+ }