@smooai/config 2.0.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 (259) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +430 -0
  3. package/dist/chunk-3SU3SMKN.mjs +73 -0
  4. package/dist/chunk-3SU3SMKN.mjs.map +1 -0
  5. package/dist/chunk-CASNDTCH.mjs +12 -0
  6. package/dist/chunk-CASNDTCH.mjs.map +1 -0
  7. package/dist/chunk-GLLYQ6FK.mjs +173 -0
  8. package/dist/chunk-GLLYQ6FK.mjs.map +1 -0
  9. package/dist/chunk-HPSOF46N.mjs +71 -0
  10. package/dist/chunk-HPSOF46N.mjs.map +1 -0
  11. package/dist/chunk-HPXCKD6M.mjs +118 -0
  12. package/dist/chunk-HPXCKD6M.mjs.map +1 -0
  13. package/dist/chunk-J5LGTIGS.mjs +10 -0
  14. package/dist/chunk-J5LGTIGS.mjs.map +1 -0
  15. package/dist/chunk-LKV73SD2.mjs +25 -0
  16. package/dist/chunk-LKV73SD2.mjs.map +1 -0
  17. package/dist/chunk-MJ52ZIWV.mjs +98 -0
  18. package/dist/chunk-MJ52ZIWV.mjs.map +1 -0
  19. package/dist/chunk-O7BSFCCY.mjs +89 -0
  20. package/dist/chunk-O7BSFCCY.mjs.map +1 -0
  21. package/dist/chunk-QBM74JB5.mjs +47 -0
  22. package/dist/chunk-QBM74JB5.mjs.map +1 -0
  23. package/dist/chunk-QGMLTMB5.mjs +37 -0
  24. package/dist/chunk-QGMLTMB5.mjs.map +1 -0
  25. package/dist/chunk-SKX7CPGS.mjs +73 -0
  26. package/dist/chunk-SKX7CPGS.mjs.map +1 -0
  27. package/dist/chunk-VPKO6D4W.mjs +33 -0
  28. package/dist/chunk-VPKO6D4W.mjs.map +1 -0
  29. package/dist/chunk-YQWYYS7P.mjs +12194 -0
  30. package/dist/chunk-YQWYYS7P.mjs.map +1 -0
  31. package/dist/chunk-Z3CZGNU5.mjs +99 -0
  32. package/dist/chunk-Z3CZGNU5.mjs.map +1 -0
  33. package/dist/chunk-ZOKHXR5I.mjs +33 -0
  34. package/dist/chunk-ZOKHXR5I.mjs.map +1 -0
  35. package/dist/cli.mjs +1562 -0
  36. package/dist/cli.mjs.map +1 -0
  37. package/dist/config/FeatureFlagKey.d.mts +24 -0
  38. package/dist/config/FeatureFlagKey.d.ts +24 -0
  39. package/dist/config/FeatureFlagKey.js +31 -0
  40. package/dist/config/FeatureFlagKey.js.map +1 -0
  41. package/dist/config/FeatureFlagKey.mjs +8 -0
  42. package/dist/config/FeatureFlagKey.mjs.map +1 -0
  43. package/dist/config/PublicConfigKey.d.mts +22 -0
  44. package/dist/config/PublicConfigKey.d.ts +22 -0
  45. package/dist/config/PublicConfigKey.js +36 -0
  46. package/dist/config/PublicConfigKey.js.map +1 -0
  47. package/dist/config/PublicConfigKey.mjs +8 -0
  48. package/dist/config/PublicConfigKey.mjs.map +1 -0
  49. package/dist/config/SecretConfigKey.d.mts +22 -0
  50. package/dist/config/SecretConfigKey.d.ts +22 -0
  51. package/dist/config/SecretConfigKey.js +31 -0
  52. package/dist/config/SecretConfigKey.js.map +1 -0
  53. package/dist/config/SecretConfigKey.mjs +8 -0
  54. package/dist/config/SecretConfigKey.mjs.map +1 -0
  55. package/dist/config/config.d.mts +178 -0
  56. package/dist/config/config.d.ts +178 -0
  57. package/dist/config/config.js +12364 -0
  58. package/dist/config/config.js.map +1 -0
  59. package/dist/config/config.mjs +23 -0
  60. package/dist/config/config.mjs.map +1 -0
  61. package/dist/config/findAndProcessEnvConfig.d.mts +17 -0
  62. package/dist/config/findAndProcessEnvConfig.d.ts +17 -0
  63. package/dist/config/findAndProcessEnvConfig.js +12290 -0
  64. package/dist/config/findAndProcessEnvConfig.js.map +1 -0
  65. package/dist/config/findAndProcessEnvConfig.mjs +14 -0
  66. package/dist/config/findAndProcessEnvConfig.mjs.map +1 -0
  67. package/dist/config/findAndProcessFileConfig.d.mts +38 -0
  68. package/dist/config/findAndProcessFileConfig.d.ts +38 -0
  69. package/dist/config/findAndProcessFileConfig.js +12431 -0
  70. package/dist/config/findAndProcessFileConfig.js.map +1 -0
  71. package/dist/config/findAndProcessFileConfig.mjs +18 -0
  72. package/dist/config/findAndProcessFileConfig.mjs.map +1 -0
  73. package/dist/config/getCloudRegion.d.mts +8 -0
  74. package/dist/config/getCloudRegion.d.ts +8 -0
  75. package/dist/config/getCloudRegion.js +92 -0
  76. package/dist/config/getCloudRegion.js.map +1 -0
  77. package/dist/config/getCloudRegion.mjs +9 -0
  78. package/dist/config/getCloudRegion.mjs.map +1 -0
  79. package/dist/config/index.d.mts +5 -0
  80. package/dist/config/index.d.ts +5 -0
  81. package/dist/config/index.js +12638 -0
  82. package/dist/config/index.js.map +1 -0
  83. package/dist/config/index.mjs +33 -0
  84. package/dist/config/index.mjs.map +1 -0
  85. package/dist/config/parseConfigSchema.d.mts +13 -0
  86. package/dist/config/parseConfigSchema.d.ts +13 -0
  87. package/dist/config/parseConfigSchema.js +12177 -0
  88. package/dist/config/parseConfigSchema.js.map +1 -0
  89. package/dist/config/parseConfigSchema.mjs +16 -0
  90. package/dist/config/parseConfigSchema.mjs.map +1 -0
  91. package/dist/config/standardSchemaToJson.d.mts +6 -0
  92. package/dist/config/standardSchemaToJson.d.ts +6 -0
  93. package/dist/config/standardSchemaToJson.js +138 -0
  94. package/dist/config/standardSchemaToJson.js.map +1 -0
  95. package/dist/config/standardSchemaToJson.mjs +9 -0
  96. package/dist/config/standardSchemaToJson.mjs.map +1 -0
  97. package/dist/index.d.mts +2 -0
  98. package/dist/index.d.ts +2 -0
  99. package/dist/index.js +19 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/index.mjs +1 -0
  102. package/dist/index.mjs.map +1 -0
  103. package/dist/integration-tests/1/smooai-config/config.d.mts +4108 -0
  104. package/dist/integration-tests/1/smooai-config/config.d.ts +4108 -0
  105. package/dist/integration-tests/1/smooai-config/config.js +12353 -0
  106. package/dist/integration-tests/1/smooai-config/config.js.map +1 -0
  107. package/dist/integration-tests/1/smooai-config/config.mjs +12 -0
  108. package/dist/integration-tests/1/smooai-config/config.mjs.map +1 -0
  109. package/dist/integration-tests/1/smooai-config/default.d.mts +55 -0
  110. package/dist/integration-tests/1/smooai-config/default.d.ts +55 -0
  111. package/dist/integration-tests/1/smooai-config/default.js +12419 -0
  112. package/dist/integration-tests/1/smooai-config/default.js.map +1 -0
  113. package/dist/integration-tests/1/smooai-config/default.mjs +78 -0
  114. package/dist/integration-tests/1/smooai-config/default.mjs.map +1 -0
  115. package/dist/integration-tests/1/smooai-config/development.d.mts +41 -0
  116. package/dist/integration-tests/1/smooai-config/development.d.ts +41 -0
  117. package/dist/integration-tests/1/smooai-config/development.js +12403 -0
  118. package/dist/integration-tests/1/smooai-config/development.js.map +1 -0
  119. package/dist/integration-tests/1/smooai-config/development.mjs +62 -0
  120. package/dist/integration-tests/1/smooai-config/development.mjs.map +1 -0
  121. package/dist/integration-tests/1/smooai-config/production.aws.d.mts +128 -0
  122. package/dist/integration-tests/1/smooai-config/production.aws.d.ts +128 -0
  123. package/dist/integration-tests/1/smooai-config/production.aws.js +12371 -0
  124. package/dist/integration-tests/1/smooai-config/production.aws.js.map +1 -0
  125. package/dist/integration-tests/1/smooai-config/production.aws.mjs +30 -0
  126. package/dist/integration-tests/1/smooai-config/production.aws.mjs.map +1 -0
  127. package/dist/integration-tests/1/smooai-config/production.aws.us-east-1.d.mts +64 -0
  128. package/dist/integration-tests/1/smooai-config/production.aws.us-east-1.d.ts +64 -0
  129. package/dist/integration-tests/1/smooai-config/production.aws.us-east-1.js +12364 -0
  130. package/dist/integration-tests/1/smooai-config/production.aws.us-east-1.js.map +1 -0
  131. package/dist/integration-tests/1/smooai-config/production.aws.us-east-1.mjs +23 -0
  132. package/dist/integration-tests/1/smooai-config/production.aws.us-east-1.mjs.map +1 -0
  133. package/dist/integration-tests/1/smooai-config/production.aws.us-east-2.d.mts +64 -0
  134. package/dist/integration-tests/1/smooai-config/production.aws.us-east-2.d.ts +64 -0
  135. package/dist/integration-tests/1/smooai-config/production.aws.us-east-2.js +12364 -0
  136. package/dist/integration-tests/1/smooai-config/production.aws.us-east-2.js.map +1 -0
  137. package/dist/integration-tests/1/smooai-config/production.aws.us-east-2.mjs +23 -0
  138. package/dist/integration-tests/1/smooai-config/production.aws.us-east-2.mjs.map +1 -0
  139. package/dist/integration-tests/1/smooai-config/production.d.mts +42 -0
  140. package/dist/integration-tests/1/smooai-config/production.d.ts +42 -0
  141. package/dist/integration-tests/1/smooai-config/production.js +12399 -0
  142. package/dist/integration-tests/1/smooai-config/production.js.map +1 -0
  143. package/dist/integration-tests/1/smooai-config/production.mjs +58 -0
  144. package/dist/integration-tests/1/smooai-config/production.mjs.map +1 -0
  145. package/dist/integration-tests/1/smooai-config/staging.d.mts +129 -0
  146. package/dist/integration-tests/1/smooai-config/staging.d.ts +129 -0
  147. package/dist/integration-tests/1/smooai-config/staging.js +12377 -0
  148. package/dist/integration-tests/1/smooai-config/staging.js.map +1 -0
  149. package/dist/integration-tests/1/smooai-config/staging.mjs +36 -0
  150. package/dist/integration-tests/1/smooai-config/staging.mjs.map +1 -0
  151. package/dist/integration-tests/2/smooai-config/config.d.mts +1262 -0
  152. package/dist/integration-tests/2/smooai-config/config.d.ts +1262 -0
  153. package/dist/integration-tests/2/smooai-config/config.js +12301 -0
  154. package/dist/integration-tests/2/smooai-config/config.js.map +1 -0
  155. package/dist/integration-tests/2/smooai-config/config.mjs +12 -0
  156. package/dist/integration-tests/2/smooai-config/config.mjs.map +1 -0
  157. package/dist/integration-tests/2/smooai-config/default.d.mts +19 -0
  158. package/dist/integration-tests/2/smooai-config/default.d.ts +19 -0
  159. package/dist/integration-tests/2/smooai-config/default.js +12321 -0
  160. package/dist/integration-tests/2/smooai-config/default.js.map +1 -0
  161. package/dist/integration-tests/2/smooai-config/default.mjs +32 -0
  162. package/dist/integration-tests/2/smooai-config/default.mjs.map +1 -0
  163. package/dist/integration-tests/2/smooai-config/development.d.mts +9 -0
  164. package/dist/integration-tests/2/smooai-config/development.d.ts +9 -0
  165. package/dist/integration-tests/2/smooai-config/development.js +12311 -0
  166. package/dist/integration-tests/2/smooai-config/development.js.map +1 -0
  167. package/dist/integration-tests/2/smooai-config/development.mjs +22 -0
  168. package/dist/integration-tests/2/smooai-config/development.mjs.map +1 -0
  169. package/dist/integration-tests/2/smooai-config/production.aws.d.mts +26 -0
  170. package/dist/integration-tests/2/smooai-config/production.aws.d.ts +26 -0
  171. package/dist/integration-tests/2/smooai-config/production.aws.js +12311 -0
  172. package/dist/integration-tests/2/smooai-config/production.aws.js.map +1 -0
  173. package/dist/integration-tests/2/smooai-config/production.aws.mjs +22 -0
  174. package/dist/integration-tests/2/smooai-config/production.aws.mjs.map +1 -0
  175. package/dist/integration-tests/2/smooai-config/production.aws.us-east-1.d.mts +25 -0
  176. package/dist/integration-tests/2/smooai-config/production.aws.us-east-1.d.ts +25 -0
  177. package/dist/integration-tests/2/smooai-config/production.aws.us-east-1.js +12310 -0
  178. package/dist/integration-tests/2/smooai-config/production.aws.us-east-1.js.map +1 -0
  179. package/dist/integration-tests/2/smooai-config/production.aws.us-east-1.mjs +21 -0
  180. package/dist/integration-tests/2/smooai-config/production.aws.us-east-1.mjs.map +1 -0
  181. package/dist/integration-tests/2/smooai-config/production.d.mts +19 -0
  182. package/dist/integration-tests/2/smooai-config/production.d.ts +19 -0
  183. package/dist/integration-tests/2/smooai-config/production.js +12321 -0
  184. package/dist/integration-tests/2/smooai-config/production.js.map +1 -0
  185. package/dist/integration-tests/2/smooai-config/production.mjs +32 -0
  186. package/dist/integration-tests/2/smooai-config/production.mjs.map +1 -0
  187. package/dist/platform/client.d.mts +49 -0
  188. package/dist/platform/client.d.ts +49 -0
  189. package/dist/platform/client.js +123 -0
  190. package/dist/platform/client.js.map +1 -0
  191. package/dist/platform/client.mjs +8 -0
  192. package/dist/platform/client.mjs.map +1 -0
  193. package/dist/platform/server/server.async.d.mts +12 -0
  194. package/dist/platform/server/server.async.d.ts +12 -0
  195. package/dist/platform/server/server.async.js +12586 -0
  196. package/dist/platform/server/server.async.js.map +1 -0
  197. package/dist/platform/server/server.async.mjs +18 -0
  198. package/dist/platform/server/server.async.mjs.map +1 -0
  199. package/dist/platform/server/server.featureFlag.sync.d.mts +2 -0
  200. package/dist/platform/server/server.featureFlag.sync.d.ts +2 -0
  201. package/dist/platform/server/server.featureFlag.sync.js +12589 -0
  202. package/dist/platform/server/server.featureFlag.sync.js.map +1 -0
  203. package/dist/platform/server/server.featureFlag.sync.mjs +24 -0
  204. package/dist/platform/server/server.featureFlag.sync.mjs.map +1 -0
  205. package/dist/platform/server/server.publicConfig.sync.d.mts +2 -0
  206. package/dist/platform/server/server.publicConfig.sync.d.ts +2 -0
  207. package/dist/platform/server/server.publicConfig.sync.js +12589 -0
  208. package/dist/platform/server/server.publicConfig.sync.js.map +1 -0
  209. package/dist/platform/server/server.publicConfig.sync.mjs +24 -0
  210. package/dist/platform/server/server.publicConfig.sync.mjs.map +1 -0
  211. package/dist/platform/server/server.secretConfig.sync.d.mts +2 -0
  212. package/dist/platform/server/server.secretConfig.sync.d.ts +2 -0
  213. package/dist/platform/server/server.secretConfig.sync.js +12589 -0
  214. package/dist/platform/server/server.secretConfig.sync.js.map +1 -0
  215. package/dist/platform/server/server.secretConfig.sync.mjs +24 -0
  216. package/dist/platform/server/server.secretConfig.sync.mjs.map +1 -0
  217. package/dist/platform/server.d.mts +21 -0
  218. package/dist/platform/server.d.ts +21 -0
  219. package/dist/platform/server.js +12626 -0
  220. package/dist/platform/server.js.map +1 -0
  221. package/dist/platform/server.mjs +58 -0
  222. package/dist/platform/server.mjs.map +1 -0
  223. package/dist/react/hooks.d.mts +36 -0
  224. package/dist/react/hooks.d.ts +36 -0
  225. package/dist/react/hooks.js +90 -0
  226. package/dist/react/hooks.js.map +1 -0
  227. package/dist/react/hooks.mjs +14 -0
  228. package/dist/react/hooks.mjs.map +1 -0
  229. package/dist/react/index.d.mts +28 -0
  230. package/dist/react/index.d.ts +28 -0
  231. package/dist/react/index.js +194 -0
  232. package/dist/react/index.js.map +1 -0
  233. package/dist/react/index.mjs +17 -0
  234. package/dist/react/index.mjs.map +1 -0
  235. package/dist/schema-spec/smooai-config-schema-spec.d.mts +25 -0
  236. package/dist/schema-spec/smooai-config-schema-spec.d.ts +25 -0
  237. package/dist/schema-spec/smooai-config-schema-spec.js +177 -0
  238. package/dist/schema-spec/smooai-config-schema-spec.js.map +1 -0
  239. package/dist/schema-spec/smooai-config-schema-spec.mjs +154 -0
  240. package/dist/schema-spec/smooai-config-schema-spec.mjs.map +1 -0
  241. package/dist/utils/fs.d.mts +10 -0
  242. package/dist/utils/fs.d.ts +10 -0
  243. package/dist/utils/fs.js +74 -0
  244. package/dist/utils/fs.js.map +1 -0
  245. package/dist/utils/fs.mjs +11 -0
  246. package/dist/utils/fs.mjs.map +1 -0
  247. package/dist/utils/index.d.mts +29 -0
  248. package/dist/utils/index.d.ts +29 -0
  249. package/dist/utils/index.js +113 -0
  250. package/dist/utils/index.js.map +1 -0
  251. package/dist/utils/index.mjs +18 -0
  252. package/dist/utils/index.mjs.map +1 -0
  253. package/dist/utils/mergeReplaceArrays.d.mts +9 -0
  254. package/dist/utils/mergeReplaceArrays.d.ts +9 -0
  255. package/dist/utils/mergeReplaceArrays.js +63 -0
  256. package/dist/utils/mergeReplaceArrays.js.map +1 -0
  257. package/dist/utils/mergeReplaceArrays.mjs +9 -0
  258. package/dist/utils/mergeReplaceArrays.mjs.map +1 -0
  259. package/package.json +133 -0
package/dist/cli.mjs ADDED
@@ -0,0 +1,1562 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // src/cli/components/Banner.tsx
13
+ import { Box, Text } from "ink";
14
+ import BigText from "ink-big-text";
15
+ import Gradient from "ink-gradient";
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ function Banner({ title }) {
18
+ return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [
19
+ /* @__PURE__ */ jsx(Gradient, { colors: ["#f49f0a", "#ff6b6c"], children: /* @__PURE__ */ jsx(BigText, { text: "Smoo AI", font: "tiny" }) }),
20
+ /* @__PURE__ */ jsx(Text, { bold: true, children: title })
21
+ ] });
22
+ }
23
+ var init_Banner = __esm({
24
+ "src/cli/components/Banner.tsx"() {
25
+ "use strict";
26
+ }
27
+ });
28
+
29
+ // src/cli/components/TaskList.tsx
30
+ import { Box as Box2, Text as Text2 } from "ink";
31
+ import Spinner from "ink-spinner";
32
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
33
+ function TaskList({ tasks }) {
34
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, children: tasks.map((task, i) => /* @__PURE__ */ jsxs2(Box2, { children: [
35
+ /* @__PURE__ */ jsxs2(Box2, { width: 3, children: [
36
+ task.status === "running" && /* @__PURE__ */ jsx2(Text2, { color: "yellow", children: /* @__PURE__ */ jsx2(Spinner, { type: "dots" }) }),
37
+ task.status === "done" && /* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u2713" }),
38
+ task.status === "error" && /* @__PURE__ */ jsx2(Text2, { color: "red", children: "\u2717" }),
39
+ task.status === "pending" && /* @__PURE__ */ jsx2(Text2, { color: "gray", children: "\u25CB" })
40
+ ] }),
41
+ /* @__PURE__ */ jsx2(Text2, { color: task.status === "error" ? "red" : task.status === "done" ? "green" : void 0, children: task.label }),
42
+ task.error && /* @__PURE__ */ jsxs2(Text2, { color: "red", children: [
43
+ " \u2014 ",
44
+ task.error
45
+ ] })
46
+ ] }, i)) });
47
+ }
48
+ var init_TaskList = __esm({
49
+ "src/cli/components/TaskList.tsx"() {
50
+ "use strict";
51
+ }
52
+ });
53
+
54
+ // src/cli/utils/output.ts
55
+ function isInteractive(jsonFlag) {
56
+ if (jsonFlag) return false;
57
+ return Boolean(process.stdout.isTTY);
58
+ }
59
+ function jsonOutput(data, exitCode = 0) {
60
+ console.log(JSON.stringify(data, null, 2));
61
+ process.exit(exitCode);
62
+ }
63
+ var init_output = __esm({
64
+ "src/cli/utils/output.ts"() {
65
+ "use strict";
66
+ }
67
+ });
68
+
69
+ // src/cli/commands/init.tsx
70
+ var init_exports = {};
71
+ __export(init_exports, {
72
+ initLogic: () => initLogic,
73
+ runInit: () => runInit
74
+ });
75
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync } from "fs";
76
+ import { join } from "path";
77
+ import { render, Box as Box3, Text as Text3 } from "ink";
78
+ import { useEffect, useState } from "react";
79
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
80
+ async function initLogic(options) {
81
+ const configDir = join(process.cwd(), ".smooai-config");
82
+ const filesCreated = [];
83
+ const language = options.language ?? "typescript";
84
+ if (!existsSync(configDir)) {
85
+ mkdirSync(configDir, { recursive: true });
86
+ filesCreated.push(".smooai-config/");
87
+ }
88
+ switch (language) {
89
+ case "typescript": {
90
+ const defaultPath = join(configDir, "default.ts");
91
+ if (!existsSync(defaultPath)) {
92
+ writeFileSync(defaultPath, TS_DEFAULT_CONFIG);
93
+ filesCreated.push(".smooai-config/default.ts");
94
+ }
95
+ const devPath = join(configDir, "development.ts");
96
+ if (!existsSync(devPath)) {
97
+ writeFileSync(devPath, TS_ENV_CONFIG);
98
+ filesCreated.push(".smooai-config/development.ts");
99
+ }
100
+ break;
101
+ }
102
+ case "python": {
103
+ const genPath = join(configDir, "schema_gen.py");
104
+ if (!existsSync(genPath)) {
105
+ writeFileSync(genPath, PYTHON_SCHEMA_GEN);
106
+ filesCreated.push(".smooai-config/schema_gen.py");
107
+ }
108
+ const devPath = join(configDir, "development.json");
109
+ if (!existsSync(devPath)) {
110
+ writeFileSync(devPath, JSON_ENV_STARTER);
111
+ filesCreated.push(".smooai-config/development.json");
112
+ }
113
+ break;
114
+ }
115
+ case "go": {
116
+ const genPath = join(configDir, "main.go");
117
+ if (!existsSync(genPath)) {
118
+ writeFileSync(genPath, GO_SCHEMA_GEN);
119
+ filesCreated.push(".smooai-config/main.go");
120
+ }
121
+ const devPath = join(configDir, "development.json");
122
+ if (!existsSync(devPath)) {
123
+ writeFileSync(devPath, JSON_ENV_STARTER);
124
+ filesCreated.push(".smooai-config/development.json");
125
+ }
126
+ break;
127
+ }
128
+ case "rust": {
129
+ const cargoPath = join(configDir, "Cargo.toml");
130
+ if (!existsSync(cargoPath)) {
131
+ writeFileSync(cargoPath, RUST_CARGO_TOML);
132
+ filesCreated.push(".smooai-config/Cargo.toml");
133
+ }
134
+ const srcDir = join(configDir, "src");
135
+ if (!existsSync(srcDir)) {
136
+ mkdirSync(srcDir, { recursive: true });
137
+ }
138
+ const mainPath = join(srcDir, "main.rs");
139
+ if (!existsSync(mainPath)) {
140
+ writeFileSync(mainPath, RUST_MAIN_RS);
141
+ filesCreated.push(".smooai-config/src/main.rs");
142
+ }
143
+ const devPath = join(configDir, "development.json");
144
+ if (!existsSync(devPath)) {
145
+ writeFileSync(devPath, JSON_ENV_STARTER);
146
+ filesCreated.push(".smooai-config/development.json");
147
+ }
148
+ break;
149
+ }
150
+ default: {
151
+ const schemaPath = join(configDir, "schema.json");
152
+ if (!existsSync(schemaPath)) {
153
+ writeFileSync(schemaPath, JSON_SCHEMA_STARTER);
154
+ filesCreated.push(".smooai-config/schema.json");
155
+ }
156
+ const devPath = join(configDir, "development.json");
157
+ if (!existsSync(devPath)) {
158
+ writeFileSync(devPath, JSON_ENV_STARTER);
159
+ filesCreated.push(".smooai-config/development.json");
160
+ }
161
+ break;
162
+ }
163
+ }
164
+ const gitignorePath = join(process.cwd(), ".gitignore");
165
+ const localPattern = ".smooai-config/local.*";
166
+ if (existsSync(gitignorePath)) {
167
+ const content = readFileSync(gitignorePath, "utf-8");
168
+ if (!content.includes(localPattern)) {
169
+ appendFileSync(gitignorePath, `
170
+ # Smoo AI local config
171
+ ${localPattern}
172
+ `);
173
+ filesCreated.push(".gitignore (updated)");
174
+ }
175
+ }
176
+ return { success: true, filesCreated };
177
+ }
178
+ function InitUI({ options }) {
179
+ const [tasks, setTasks] = useState([
180
+ { label: "Creating .smooai-config/ directory", status: "pending" },
181
+ { label: "Writing config files", status: "pending" },
182
+ { label: "Updating .gitignore", status: "pending" }
183
+ ]);
184
+ const [result, setResult] = useState(null);
185
+ useEffect(() => {
186
+ (async () => {
187
+ setTasks((t) => t.map((task, i) => i === 0 ? { ...task, status: "running" } : task));
188
+ try {
189
+ const res = await initLogic(options);
190
+ setTasks([
191
+ { label: "Creating .smooai-config/ directory", status: "done" },
192
+ { label: "Writing config files", status: "done" },
193
+ { label: "Updating .gitignore", status: "done" }
194
+ ]);
195
+ setResult(res);
196
+ } catch (err) {
197
+ setTasks(
198
+ (t) => t.map((task) => task.status === "running" ? { ...task, status: "error", error: err instanceof Error ? err.message : String(err) } : task)
199
+ );
200
+ }
201
+ })();
202
+ }, []);
203
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
204
+ /* @__PURE__ */ jsx3(Banner, { title: "Initialize Project" }),
205
+ /* @__PURE__ */ jsx3(TaskList, { tasks }),
206
+ result && /* @__PURE__ */ jsxs3(Box3, { marginTop: 1, flexDirection: "column", children: [
207
+ /* @__PURE__ */ jsx3(Text3, { color: "green", bold: true, children: "Project initialized!" }),
208
+ result.filesCreated.map((f, i) => /* @__PURE__ */ jsxs3(Text3, { color: "gray", children: [
209
+ " ",
210
+ "Created: ",
211
+ f
212
+ ] }, i))
213
+ ] })
214
+ ] });
215
+ }
216
+ function runInit(options) {
217
+ if (!isInteractive(options.json)) {
218
+ initLogic(options).then(
219
+ (result) => jsonOutput(result),
220
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
221
+ );
222
+ return;
223
+ }
224
+ render(/* @__PURE__ */ jsx3(InitUI, { options }));
225
+ }
226
+ var TS_DEFAULT_CONFIG, TS_ENV_CONFIG, JSON_SCHEMA_STARTER, JSON_ENV_STARTER, PYTHON_SCHEMA_GEN, GO_SCHEMA_GEN, RUST_CARGO_TOML, RUST_MAIN_RS;
227
+ var init_init = __esm({
228
+ "src/cli/commands/init.tsx"() {
229
+ "use strict";
230
+ init_Banner();
231
+ init_TaskList();
232
+ init_output();
233
+ TS_DEFAULT_CONFIG = `import { defineConfig, StringSchema, BooleanSchema, NumberSchema } from '@smooai/config';
234
+
235
+ // Define your configuration schema
236
+ export default defineConfig({
237
+ publicConfigSchema: {
238
+ // Add your public config keys here
239
+ // Example: apiUrl: StringSchema,
240
+ },
241
+ secretConfigSchema: {
242
+ // Add your secret config keys here
243
+ // Example: databaseUrl: StringSchema,
244
+ },
245
+ featureFlagSchema: {
246
+ // Add your feature flag keys here
247
+ // Example: enableNewFeature: BooleanSchema,
248
+ },
249
+ });
250
+ `;
251
+ TS_ENV_CONFIG = `// Environment-specific overrides for development
252
+ // Import your config definition to get type-safe keys
253
+ // import config from './config';
254
+
255
+ export default {
256
+ // Override config values for this environment
257
+ };
258
+ `;
259
+ JSON_SCHEMA_STARTER = JSON.stringify(
260
+ {
261
+ $schema: "http://json-schema.org/draft-07/schema#",
262
+ type: "object",
263
+ properties: {
264
+ public: {
265
+ type: "object",
266
+ properties: {},
267
+ description: "Public configuration values"
268
+ },
269
+ secret: {
270
+ type: "object",
271
+ properties: {},
272
+ description: "Secret configuration values"
273
+ },
274
+ featureFlags: {
275
+ type: "object",
276
+ properties: {},
277
+ description: "Feature flag values"
278
+ }
279
+ }
280
+ },
281
+ null,
282
+ 2
283
+ );
284
+ JSON_ENV_STARTER = JSON.stringify(
285
+ {
286
+ public: {},
287
+ secret: {},
288
+ featureFlags: {}
289
+ },
290
+ null,
291
+ 2
292
+ );
293
+ PYTHON_SCHEMA_GEN = `"""Schema generator for Smoo AI config.
294
+
295
+ Run this file to generate JSON Schema output:
296
+ python3 schema_gen.py
297
+ """
298
+
299
+ import json
300
+ import sys
301
+
302
+ from pydantic import BaseModel
303
+
304
+ from smooai_config.schema import define_config
305
+
306
+
307
+ class PublicConfig(BaseModel):
308
+ # Add your public config fields here
309
+ # Example: api_url: str = "https://api.example.com"
310
+ pass
311
+
312
+
313
+ class SecretConfig(BaseModel):
314
+ # Add your secret config fields here
315
+ # Example: database_url: str
316
+ pass
317
+
318
+
319
+ class FeatureFlags(BaseModel):
320
+ # Add your feature flag fields here
321
+ # Example: enable_new_feature: bool = False
322
+ pass
323
+
324
+
325
+ config = define_config(
326
+ public=PublicConfig,
327
+ secret=SecretConfig,
328
+ feature_flags=FeatureFlags,
329
+ )
330
+
331
+ # Print JSON Schema to stdout for CLI consumption
332
+ json.dump(config.json_schema, sys.stdout, indent=2)
333
+ `;
334
+ GO_SCHEMA_GEN = [
335
+ "// Schema generator for Smoo AI config.",
336
+ "//",
337
+ "// Run this file to generate JSON Schema output:",
338
+ "// go run main.go",
339
+ "package main",
340
+ "",
341
+ "import (",
342
+ ' "encoding/json"',
343
+ ' "fmt"',
344
+ ' "log"',
345
+ "",
346
+ ' config "github.com/SmooAI/config/go/config"',
347
+ ")",
348
+ "",
349
+ "// PublicConfig defines public configuration values.",
350
+ "type PublicConfig struct {",
351
+ " // Add your public config fields here",
352
+ ' // Example: APIUrl string `json:"api_url"`',
353
+ "}",
354
+ "",
355
+ "// SecretConfig defines secret configuration values.",
356
+ "type SecretConfig struct {",
357
+ " // Add your secret config fields here",
358
+ "}",
359
+ "",
360
+ "// FeatureFlags defines feature flag values.",
361
+ "type FeatureFlags struct {",
362
+ " // Add your feature flag fields here",
363
+ "}",
364
+ "",
365
+ "func main() {",
366
+ " result, err := config.DefineConfigTyped(&PublicConfig{}, &SecretConfig{}, &FeatureFlags{})",
367
+ " if err != nil {",
368
+ " log.Fatal(err)",
369
+ " }",
370
+ "",
371
+ ' data, err := json.MarshalIndent(result.JSONSchema, "", " ")',
372
+ " if err != nil {",
373
+ " log.Fatal(err)",
374
+ " }",
375
+ " fmt.Println(string(data))",
376
+ "}",
377
+ ""
378
+ ].join("\n");
379
+ RUST_CARGO_TOML = `[package]
380
+ name = "smooai-config-gen"
381
+ version = "0.1.0"
382
+ edition = "2021"
383
+
384
+ [dependencies]
385
+ smooai-config = "1"
386
+ schemars = { version = "0.8", features = ["derive"] }
387
+ serde = { version = "1", features = ["derive"] }
388
+ serde_json = "1"
389
+ `;
390
+ RUST_MAIN_RS = `//! Schema generator for Smoo AI config.
391
+ //!
392
+ //! Run this to generate JSON Schema output:
393
+ //! cargo run --manifest-path .smooai-config/Cargo.toml
394
+
395
+ use schemars::JsonSchema;
396
+ use serde::{Deserialize, Serialize};
397
+ use smooai_config::schema::{define_config_typed, EmptySchema};
398
+
399
+ /// Public configuration values.
400
+ #[derive(Default, Serialize, Deserialize, JsonSchema)]
401
+ struct PublicConfig {
402
+ // Add your public config fields here
403
+ // Example: api_url: String,
404
+ }
405
+
406
+ /// Secret configuration values.
407
+ #[derive(Default, Serialize, Deserialize, JsonSchema)]
408
+ struct SecretConfig {
409
+ // Add your secret config fields here
410
+ }
411
+
412
+ /// Feature flag values.
413
+ #[derive(Default, Serialize, Deserialize, JsonSchema)]
414
+ struct FeatureFlags {
415
+ // Add your feature flag fields here
416
+ }
417
+
418
+ fn main() {
419
+ let config = define_config_typed::<PublicConfig, SecretConfig, FeatureFlags>();
420
+ let json = serde_json::to_string_pretty(&config.json_schema).unwrap();
421
+ println!("{}", json);
422
+ }
423
+ `;
424
+ }
425
+ });
426
+
427
+ // src/cli/utils/api-client.ts
428
+ var CliApiClient;
429
+ var init_api_client = __esm({
430
+ "src/cli/utils/api-client.ts"() {
431
+ "use strict";
432
+ CliApiClient = class {
433
+ baseUrl;
434
+ apiKey;
435
+ orgId;
436
+ constructor(credentials) {
437
+ this.baseUrl = credentials.baseUrl.replace(/\/+$/, "");
438
+ this.apiKey = credentials.apiKey;
439
+ this.orgId = credentials.orgId;
440
+ }
441
+ async fetchJson(path, options) {
442
+ const response = await fetch(`${this.baseUrl}${path}`, {
443
+ ...options,
444
+ headers: {
445
+ Authorization: `Bearer ${this.apiKey}`,
446
+ "Content-Type": "application/json",
447
+ ...options?.headers
448
+ }
449
+ });
450
+ if (!response.ok) {
451
+ const body = await response.text().catch(() => "");
452
+ throw new Error(`API error: HTTP ${response.status} ${response.statusText}${body ? ` \u2014 ${body}` : ""}`);
453
+ }
454
+ return response.json();
455
+ }
456
+ async listSchemas() {
457
+ return this.fetchJson(`/organizations/${this.orgId}/config/schemas`);
458
+ }
459
+ async getSchema(schemaId) {
460
+ return this.fetchJson(`/organizations/${this.orgId}/config/schemas/${schemaId}`);
461
+ }
462
+ async createSchema(data) {
463
+ return this.fetchJson(`/organizations/${this.orgId}/config/schemas`, {
464
+ method: "POST",
465
+ body: JSON.stringify(data)
466
+ });
467
+ }
468
+ async pushSchemaVersion(schemaId, data) {
469
+ return this.fetchJson(`/organizations/${this.orgId}/config/schemas/${schemaId}/push`, {
470
+ method: "POST",
471
+ body: JSON.stringify(data)
472
+ });
473
+ }
474
+ async listEnvironments() {
475
+ return this.fetchJson(`/organizations/${this.orgId}/config/environments`);
476
+ }
477
+ async getAllValues(environment) {
478
+ const result = await this.fetchJson(
479
+ `/organizations/${this.orgId}/config/values?environment=${encodeURIComponent(environment)}`
480
+ );
481
+ return result.values;
482
+ }
483
+ async getValue(key, environment) {
484
+ const result = await this.fetchJson(
485
+ `/organizations/${this.orgId}/config/values/${encodeURIComponent(key)}?environment=${encodeURIComponent(environment)}`
486
+ );
487
+ return result.value;
488
+ }
489
+ async setValue(data) {
490
+ return this.fetchJson(`/organizations/${this.orgId}/config/values`, {
491
+ method: "PUT",
492
+ body: JSON.stringify(data)
493
+ });
494
+ }
495
+ async getEnvironmentByName(envName) {
496
+ const envs = await this.listEnvironments();
497
+ return envs.find((e) => e.name === envName) ?? null;
498
+ }
499
+ async getSchemaByName(name) {
500
+ const schemas = await this.listSchemas();
501
+ return schemas.find((s) => s.name === name) ?? null;
502
+ }
503
+ };
504
+ }
505
+ });
506
+
507
+ // src/cli/utils/credentials.ts
508
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
509
+ import { homedir } from "os";
510
+ import { join as join2 } from "path";
511
+ function loadCredentials() {
512
+ try {
513
+ if (!existsSync2(CREDENTIALS_FILE)) return null;
514
+ const raw = readFileSync2(CREDENTIALS_FILE, "utf-8");
515
+ const parsed = JSON.parse(raw);
516
+ if (!parsed.apiKey || !parsed.orgId || !parsed.baseUrl) return null;
517
+ return parsed;
518
+ } catch {
519
+ return null;
520
+ }
521
+ }
522
+ function saveCredentials(credentials) {
523
+ mkdirSync2(SMOOAI_DIR, { recursive: true });
524
+ writeFileSync2(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), { mode: 384 });
525
+ }
526
+ function getCredentialsOrExit() {
527
+ const creds = loadCredentials();
528
+ if (!creds) {
529
+ console.error("Not logged in. Run `smooai-config login` first.");
530
+ process.exit(1);
531
+ }
532
+ return creds;
533
+ }
534
+ var SMOOAI_DIR, CREDENTIALS_FILE;
535
+ var init_credentials = __esm({
536
+ "src/cli/utils/credentials.ts"() {
537
+ "use strict";
538
+ SMOOAI_DIR = join2(homedir(), ".smooai");
539
+ CREDENTIALS_FILE = join2(SMOOAI_DIR, "credentials.json");
540
+ }
541
+ });
542
+
543
+ // src/cli/commands/login.tsx
544
+ var login_exports = {};
545
+ __export(login_exports, {
546
+ loginLogic: () => loginLogic,
547
+ runLogin: () => runLogin
548
+ });
549
+ import { render as render2, Box as Box4, Text as Text4 } from "ink";
550
+ import { useEffect as useEffect2, useState as useState2 } from "react";
551
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
552
+ async function loginLogic(options) {
553
+ const apiKey = options.apiKey;
554
+ const orgId = options.orgId;
555
+ const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
556
+ if (!apiKey) throw new Error("API key is required. Use --api-key flag.");
557
+ if (!orgId) throw new Error("Organization ID is required. Use --org-id flag.");
558
+ const client = new CliApiClient({ apiKey, orgId, baseUrl });
559
+ await client.listSchemas();
560
+ saveCredentials({ apiKey, orgId, baseUrl });
561
+ return { success: true, orgId };
562
+ }
563
+ function LoginUI({ options }) {
564
+ const [tasks, setTasks] = useState2([
565
+ { label: "Validating credentials", status: "pending" },
566
+ { label: "Saving to ~/.smooai/credentials.json", status: "pending" }
567
+ ]);
568
+ const [result, setResult] = useState2(null);
569
+ useEffect2(() => {
570
+ (async () => {
571
+ setTasks((t) => t.map((task, i) => i === 0 ? { ...task, status: "running" } : task));
572
+ try {
573
+ const res = await loginLogic(options);
574
+ setTasks([
575
+ { label: "Validating credentials", status: "done" },
576
+ { label: "Saving to ~/.smooai/credentials.json", status: "done" }
577
+ ]);
578
+ setResult({ orgId: res.orgId });
579
+ } catch (err) {
580
+ setTasks(
581
+ (t) => t.map((task) => task.status === "running" ? { ...task, status: "error", error: err instanceof Error ? err.message : String(err) } : task)
582
+ );
583
+ }
584
+ })();
585
+ }, []);
586
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
587
+ /* @__PURE__ */ jsx4(Banner, { title: "Login" }),
588
+ /* @__PURE__ */ jsx4(TaskList, { tasks }),
589
+ result && /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsxs4(Text4, { color: "green", bold: true, children: [
590
+ "Logged in successfully! Organization: ",
591
+ result.orgId
592
+ ] }) })
593
+ ] });
594
+ }
595
+ function runLogin(options) {
596
+ if (!isInteractive(options.json)) {
597
+ loginLogic(options).then(
598
+ (result) => jsonOutput(result),
599
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
600
+ );
601
+ return;
602
+ }
603
+ render2(/* @__PURE__ */ jsx4(LoginUI, { options }));
604
+ }
605
+ var DEFAULT_BASE_URL;
606
+ var init_login = __esm({
607
+ "src/cli/commands/login.tsx"() {
608
+ "use strict";
609
+ init_Banner();
610
+ init_TaskList();
611
+ init_api_client();
612
+ init_credentials();
613
+ init_output();
614
+ DEFAULT_BASE_URL = "https://api.smoo.ai";
615
+ }
616
+ });
617
+
618
+ // src/cli/utils/schema-loader.ts
619
+ import { execSync } from "child_process";
620
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
621
+ import { join as join3 } from "path";
622
+ function findLocalConfigDir() {
623
+ let dir = process.cwd();
624
+ const root = "/";
625
+ for (let i = 0; i < 10; i++) {
626
+ const candidate = join3(dir, ".smooai-config");
627
+ if (existsSync3(candidate)) return candidate;
628
+ const candidate2 = join3(dir, "smooai-config");
629
+ if (existsSync3(candidate2)) return candidate2;
630
+ const parent = join3(dir, "..");
631
+ if (parent === dir || dir === root) break;
632
+ dir = parent;
633
+ }
634
+ return null;
635
+ }
636
+ function runGenerator(command, filePath, format) {
637
+ try {
638
+ const output = execSync(command, {
639
+ encoding: "utf-8",
640
+ timeout: 3e4,
641
+ stdio: ["pipe", "pipe", "pipe"]
642
+ });
643
+ return {
644
+ format,
645
+ jsonSchema: JSON.parse(output.trim()),
646
+ filePath
647
+ };
648
+ } catch (err) {
649
+ throw new Error(`Failed to run generator ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
650
+ }
651
+ }
652
+ async function loadLocalSchema(configDir) {
653
+ const dir = configDir ?? findLocalConfigDir();
654
+ if (!dir) return null;
655
+ const jsonSchemaPath = join3(dir, "schema.json");
656
+ if (existsSync3(jsonSchemaPath)) {
657
+ const raw = readFileSync3(jsonSchemaPath, "utf-8");
658
+ return {
659
+ format: "json-schema",
660
+ jsonSchema: JSON.parse(raw),
661
+ filePath: jsonSchemaPath
662
+ };
663
+ }
664
+ const defaultTsPath = join3(dir, "default.ts");
665
+ const configTsPath = join3(dir, "config.ts");
666
+ const tsPath = existsSync3(configTsPath) ? configTsPath : existsSync3(defaultTsPath) ? defaultTsPath : null;
667
+ if (tsPath) {
668
+ try {
669
+ const mod = await import(tsPath);
670
+ const configDef = mod.default ?? mod;
671
+ if (configDef.serializedAllConfigSchema) {
672
+ return {
673
+ format: "typescript",
674
+ jsonSchema: configDef.serializedAllConfigSchema,
675
+ filePath: tsPath
676
+ };
677
+ }
678
+ } catch (err) {
679
+ throw new Error(`Failed to load TypeScript config from ${tsPath}: ${err}`);
680
+ }
681
+ }
682
+ const pyGenPath = join3(dir, "schema_gen.py");
683
+ if (existsSync3(pyGenPath)) {
684
+ return runGenerator(`python3 "${pyGenPath}"`, pyGenPath, "python-generator");
685
+ }
686
+ const goGenPath = join3(dir, "main.go");
687
+ if (existsSync3(goGenPath)) {
688
+ return runGenerator(`go run "${goGenPath}"`, goGenPath, "go-generator");
689
+ }
690
+ const cargoPath = join3(dir, "Cargo.toml");
691
+ if (existsSync3(cargoPath)) {
692
+ return runGenerator(`cargo run --manifest-path "${cargoPath}"`, cargoPath, "rust-generator");
693
+ }
694
+ return null;
695
+ }
696
+ var init_schema_loader = __esm({
697
+ "src/cli/utils/schema-loader.ts"() {
698
+ "use strict";
699
+ }
700
+ });
701
+
702
+ // src/schema-spec/smooai-config-schema-spec.ts
703
+ function validateSmooaiSchema(schema) {
704
+ const errors = [];
705
+ walkSchema(schema, "", errors);
706
+ return { valid: errors.length === 0, errors };
707
+ }
708
+ function walkSchema(node, path, errors) {
709
+ if (typeof node !== "object" || node === null || Array.isArray(node)) {
710
+ return;
711
+ }
712
+ const obj = node;
713
+ for (const key of Object.keys(obj)) {
714
+ if (key in REJECTED_KEYWORDS) {
715
+ const info = REJECTED_KEYWORDS[key];
716
+ errors.push({
717
+ path: path || "/",
718
+ keyword: key,
719
+ message: info.message,
720
+ suggestion: info.suggestion
721
+ });
722
+ continue;
723
+ }
724
+ if (SUPPORTED_KEYWORDS.has(key)) {
725
+ if (key === "format" && typeof obj[key] === "string" && !SUPPORTED_FORMATS.has(obj[key])) {
726
+ errors.push({
727
+ path: path || "/",
728
+ keyword: "format",
729
+ message: `Format "${obj[key]}" is not supported across all SDK languages.`,
730
+ suggestion: `Supported formats: ${[...SUPPORTED_FORMATS].join(", ")}. Use "pattern" for custom string validation.`
731
+ });
732
+ }
733
+ continue;
734
+ }
735
+ }
736
+ if (obj.properties && typeof obj.properties === "object") {
737
+ const props = obj.properties;
738
+ for (const [propName, propSchema] of Object.entries(props)) {
739
+ walkSchema(propSchema, `${path}/properties/${propName}`, errors);
740
+ }
741
+ }
742
+ if (obj.items && typeof obj.items === "object") {
743
+ walkSchema(obj.items, `${path}/items`, errors);
744
+ }
745
+ if (obj.additionalProperties && typeof obj.additionalProperties === "object") {
746
+ walkSchema(obj.additionalProperties, `${path}/additionalProperties`, errors);
747
+ }
748
+ for (const compKey of ["anyOf", "oneOf", "allOf"]) {
749
+ if (Array.isArray(obj[compKey])) {
750
+ obj[compKey].forEach((subSchema, i) => {
751
+ walkSchema(subSchema, `${path}/${compKey}/${i}`, errors);
752
+ });
753
+ }
754
+ }
755
+ for (const defsKey of ["$defs", "definitions"]) {
756
+ if (obj[defsKey] && typeof obj[defsKey] === "object") {
757
+ const defs = obj[defsKey];
758
+ for (const [defName, defSchema] of Object.entries(defs)) {
759
+ walkSchema(defSchema, `${path}/${defsKey}/${defName}`, errors);
760
+ }
761
+ }
762
+ }
763
+ }
764
+ var SUPPORTED_KEYWORDS, REJECTED_KEYWORDS, SUPPORTED_FORMATS;
765
+ var init_smooai_config_schema_spec = __esm({
766
+ "src/schema-spec/smooai-config-schema-spec.ts"() {
767
+ "use strict";
768
+ SUPPORTED_KEYWORDS = /* @__PURE__ */ new Set([
769
+ // Core
770
+ "type",
771
+ "properties",
772
+ "required",
773
+ "enum",
774
+ "const",
775
+ "default",
776
+ // Metadata
777
+ "title",
778
+ "description",
779
+ "$schema",
780
+ // String
781
+ "minLength",
782
+ "maxLength",
783
+ "pattern",
784
+ "format",
785
+ // Numeric
786
+ "minimum",
787
+ "maximum",
788
+ "exclusiveMinimum",
789
+ "exclusiveMaximum",
790
+ "multipleOf",
791
+ // Array
792
+ "items",
793
+ "minItems",
794
+ "maxItems",
795
+ "uniqueItems",
796
+ // Object
797
+ "additionalProperties",
798
+ // Composition
799
+ "anyOf",
800
+ "oneOf",
801
+ "allOf",
802
+ // References
803
+ "$ref",
804
+ "$defs",
805
+ "definitions"
806
+ ]);
807
+ REJECTED_KEYWORDS = {
808
+ if: {
809
+ message: "Conditional schemas (if/then/else) are not supported across all SDK languages.",
810
+ suggestion: 'Use "oneOf" or "anyOf" with discriminator properties instead.'
811
+ },
812
+ then: {
813
+ message: "Conditional schemas (if/then/else) are not supported across all SDK languages.",
814
+ suggestion: 'Use "oneOf" or "anyOf" with discriminator properties instead.'
815
+ },
816
+ else: {
817
+ message: "Conditional schemas (if/then/else) are not supported across all SDK languages.",
818
+ suggestion: 'Use "oneOf" or "anyOf" with discriminator properties instead.'
819
+ },
820
+ patternProperties: {
821
+ message: '"patternProperties" is not supported across all SDK languages.',
822
+ suggestion: 'Use explicit "properties" with known key names, or "additionalProperties" with a type constraint.'
823
+ },
824
+ propertyNames: {
825
+ message: '"propertyNames" is not supported across all SDK languages.',
826
+ suggestion: "Validate property names in application code instead."
827
+ },
828
+ dependencies: {
829
+ message: '"dependencies" is not supported across all SDK languages.',
830
+ suggestion: 'Use "required" within "oneOf"/"anyOf" variants to express conditional requirements.'
831
+ },
832
+ contains: {
833
+ message: '"contains" is not supported across all SDK languages.',
834
+ suggestion: 'Use "items" with a union type ("anyOf") instead.'
835
+ },
836
+ not: {
837
+ message: '"not" is not supported across all SDK languages.',
838
+ suggestion: 'Express the constraint positively using "enum", "oneOf", or validation in application code.'
839
+ },
840
+ prefixItems: {
841
+ message: '"prefixItems" (tuple validation) is not supported across all SDK languages.',
842
+ suggestion: 'Use an "object" with named fields instead of a positional tuple.'
843
+ },
844
+ unevaluatedProperties: {
845
+ message: '"unevaluatedProperties" is not supported across all SDK languages.',
846
+ suggestion: 'Use "additionalProperties" instead.'
847
+ },
848
+ unevaluatedItems: {
849
+ message: '"unevaluatedItems" is not supported across all SDK languages.',
850
+ suggestion: 'Use "items" with a specific schema instead.'
851
+ }
852
+ };
853
+ SUPPORTED_FORMATS = /* @__PURE__ */ new Set(["email", "uri", "uuid", "date-time", "ipv4", "ipv6"]);
854
+ }
855
+ });
856
+
857
+ // src/cli/utils/schema-validator.ts
858
+ import Ajv from "ajv";
859
+ function validateJsonSchema(schema) {
860
+ try {
861
+ ajv.compile(schema);
862
+ return { valid: true };
863
+ } catch (err) {
864
+ return {
865
+ valid: false,
866
+ errors: [err instanceof Error ? err.message : String(err)]
867
+ };
868
+ }
869
+ }
870
+ function validateValue(schema, key, value) {
871
+ const properties = schema.properties;
872
+ if (!properties || !properties[key]) {
873
+ const keySchema = schema[key];
874
+ if (!keySchema) {
875
+ return { valid: true };
876
+ }
877
+ if (typeof keySchema === "string") {
878
+ return validatePrimitiveType(keySchema, value);
879
+ }
880
+ if (typeof keySchema === "object") {
881
+ return validateWithAjv(keySchema, value);
882
+ }
883
+ return { valid: true };
884
+ }
885
+ return validateWithAjv(properties[key], value);
886
+ }
887
+ function validatePrimitiveType(schemaType, value) {
888
+ switch (schemaType) {
889
+ case "stringSchema":
890
+ if (typeof value !== "string") {
891
+ return { valid: false, errors: [`Expected string, got ${typeof value}`] };
892
+ }
893
+ return { valid: true };
894
+ case "booleanSchema":
895
+ if (typeof value !== "boolean" && value !== "true" && value !== "false") {
896
+ return { valid: false, errors: [`Expected boolean, got ${typeof value}`] };
897
+ }
898
+ return { valid: true };
899
+ case "numberSchema":
900
+ if (typeof value !== "number" && isNaN(Number(value))) {
901
+ return { valid: false, errors: [`Expected number, got ${typeof value}`] };
902
+ }
903
+ return { valid: true };
904
+ default:
905
+ return { valid: true };
906
+ }
907
+ }
908
+ function validateWithAjv(schema, value) {
909
+ try {
910
+ const validate = ajv.compile(schema);
911
+ const valid = validate(value);
912
+ if (!valid && validate.errors) {
913
+ return {
914
+ valid: false,
915
+ errors: validate.errors.map((e) => `${e.instancePath || "/"} ${e.message}`)
916
+ };
917
+ }
918
+ return { valid: true };
919
+ } catch (err) {
920
+ return { valid: false, errors: [err instanceof Error ? err.message : String(err)] };
921
+ }
922
+ }
923
+ var ajv;
924
+ var init_schema_validator = __esm({
925
+ "src/cli/utils/schema-validator.ts"() {
926
+ "use strict";
927
+ init_smooai_config_schema_spec();
928
+ ajv = new Ajv({ allErrors: true, strict: false });
929
+ }
930
+ });
931
+
932
+ // src/cli/commands/push.tsx
933
+ var push_exports = {};
934
+ __export(push_exports, {
935
+ pushLogic: () => pushLogic,
936
+ runPush: () => runPush
937
+ });
938
+ import { basename } from "path";
939
+ import { render as render3, Box as Box5, Text as Text5 } from "ink";
940
+ import { useEffect as useEffect3, useState as useState3 } from "react";
941
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
942
+ function computeSchemaDiff(local, remote) {
943
+ const localKeys = new Set(Object.keys(local));
944
+ const remoteKeys = new Set(Object.keys(remote));
945
+ const added = [...localKeys].filter((k) => !remoteKeys.has(k));
946
+ const removed = [...remoteKeys].filter((k) => !localKeys.has(k));
947
+ const changed = [...localKeys].filter((k) => {
948
+ if (!remoteKeys.has(k)) return false;
949
+ return JSON.stringify(local[k]) !== JSON.stringify(remote[k]);
950
+ });
951
+ return { added, removed, changed };
952
+ }
953
+ async function pushLogic(options) {
954
+ const creds = getCredentialsOrExit();
955
+ const client = new CliApiClient(creds);
956
+ const loaded = await loadLocalSchema();
957
+ if (!loaded) {
958
+ throw new Error("No local schema found. Run `smooai-config init` first or create .smooai-config/schema.json.");
959
+ }
960
+ const validation = validateJsonSchema(loaded.jsonSchema);
961
+ if (!validation.valid) {
962
+ throw new Error(`Invalid JSON Schema: ${validation.errors?.join(", ")}`);
963
+ }
964
+ const smooaiValidation = validateSmooaiSchema(loaded.jsonSchema);
965
+ if (!smooaiValidation.valid) {
966
+ const errorMessages = smooaiValidation.errors.map((e) => ` ${e.path}: ${e.message}
967
+ Suggestion: ${e.suggestion}`);
968
+ throw new Error(`Schema uses unsupported JSON Schema features:
969
+ ${errorMessages.join("\n")}`);
970
+ }
971
+ const schemaName = options.schemaName ?? basename(process.cwd());
972
+ const existingSchema = await client.getSchemaByName(schemaName).catch(() => null);
973
+ let diff;
974
+ if (existingSchema) {
975
+ diff = computeSchemaDiff(loaded.jsonSchema, existingSchema.jsonSchema);
976
+ const result = await client.pushSchemaVersion(existingSchema.id, {
977
+ jsonSchema: loaded.jsonSchema,
978
+ changeDescription: options.description
979
+ });
980
+ return { success: true, schema: result.schema, version: result.version, diff };
981
+ }
982
+ const schema = await client.createSchema({
983
+ name: schemaName,
984
+ jsonSchema: loaded.jsonSchema,
985
+ description: options.description
986
+ });
987
+ return { success: true, schema };
988
+ }
989
+ function DiffDisplay({ diff }) {
990
+ if (diff.added.length === 0 && diff.removed.length === 0 && diff.changed.length === 0) {
991
+ return /* @__PURE__ */ jsx5(Text5, { color: "gray", children: "No changes detected." });
992
+ }
993
+ return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
994
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "Schema Changes:" }),
995
+ diff.added.map((k) => /* @__PURE__ */ jsxs5(Text5, { color: "green", children: [
996
+ "+ ",
997
+ k
998
+ ] }, k)),
999
+ diff.removed.map((k) => /* @__PURE__ */ jsxs5(Text5, { color: "red", children: [
1000
+ "- ",
1001
+ k
1002
+ ] }, k)),
1003
+ diff.changed.map((k) => /* @__PURE__ */ jsxs5(Text5, { color: "yellow", children: [
1004
+ "~ ",
1005
+ k
1006
+ ] }, k))
1007
+ ] });
1008
+ }
1009
+ function PushUI({ options }) {
1010
+ const [tasks, setTasks] = useState3([
1011
+ { label: "Loading local schema", status: "pending" },
1012
+ { label: "Validating schema", status: "pending" },
1013
+ { label: "Pushing to platform", status: "pending" }
1014
+ ]);
1015
+ const [result, setResult] = useState3(null);
1016
+ useEffect3(() => {
1017
+ (async () => {
1018
+ setTasks((t) => t.map((task, i) => i === 0 ? { ...task, status: "running" } : task));
1019
+ try {
1020
+ setTasks((t) => [{ ...t[0], status: "done" }, { ...t[1], status: "running" }, t[2]]);
1021
+ const res = await pushLogic(options);
1022
+ setTasks([
1023
+ { label: "Loading local schema", status: "done" },
1024
+ { label: "Validating schema", status: "done" },
1025
+ { label: "Pushing to platform", status: "done" }
1026
+ ]);
1027
+ setResult(res);
1028
+ } catch (err) {
1029
+ setTasks(
1030
+ (t) => t.map((task) => task.status === "running" ? { ...task, status: "error", error: err instanceof Error ? err.message : String(err) } : task)
1031
+ );
1032
+ }
1033
+ })();
1034
+ }, []);
1035
+ return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
1036
+ /* @__PURE__ */ jsx5(Banner, { title: "Push Schema" }),
1037
+ /* @__PURE__ */ jsx5(TaskList, { tasks }),
1038
+ result?.diff && /* @__PURE__ */ jsx5(DiffDisplay, { diff: result.diff }),
1039
+ result && /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "green", bold: true, children: "Schema pushed successfully!" }) })
1040
+ ] });
1041
+ }
1042
+ function runPush(options) {
1043
+ if (!isInteractive(options.json)) {
1044
+ pushLogic(options).then(
1045
+ (result) => jsonOutput(result),
1046
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
1047
+ );
1048
+ return;
1049
+ }
1050
+ render3(/* @__PURE__ */ jsx5(PushUI, { options }));
1051
+ }
1052
+ var init_push = __esm({
1053
+ "src/cli/commands/push.tsx"() {
1054
+ "use strict";
1055
+ init_Banner();
1056
+ init_TaskList();
1057
+ init_api_client();
1058
+ init_credentials();
1059
+ init_output();
1060
+ init_schema_loader();
1061
+ init_schema_validator();
1062
+ }
1063
+ });
1064
+
1065
+ // src/cli/commands/pull.tsx
1066
+ var pull_exports = {};
1067
+ __export(pull_exports, {
1068
+ pullLogic: () => pullLogic,
1069
+ runPull: () => runPull
1070
+ });
1071
+ import { writeFileSync as writeFileSync3 } from "fs";
1072
+ import { join as join4 } from "path";
1073
+ import { render as render4, Box as Box6, Text as Text6 } from "ink";
1074
+ import { useEffect as useEffect4, useState as useState4 } from "react";
1075
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1076
+ async function pullLogic(options) {
1077
+ const creds = getCredentialsOrExit();
1078
+ const client = new CliApiClient(creds);
1079
+ const environment = options.environment ?? "development";
1080
+ const values = await client.getAllValues(environment);
1081
+ const configDir = findLocalConfigDir();
1082
+ let filePath;
1083
+ if (configDir) {
1084
+ const jsonPath = join4(configDir, `${environment}.json`);
1085
+ writeFileSync3(jsonPath, JSON.stringify(values, null, 2));
1086
+ filePath = jsonPath;
1087
+ }
1088
+ return { success: true, values, environment, filePath };
1089
+ }
1090
+ function PullUI({ options }) {
1091
+ const [tasks, setTasks] = useState4([
1092
+ { label: `Fetching values for ${options.environment ?? "development"}`, status: "pending" },
1093
+ { label: "Writing to local config", status: "pending" }
1094
+ ]);
1095
+ const [result, setResult] = useState4(null);
1096
+ useEffect4(() => {
1097
+ (async () => {
1098
+ setTasks((t) => t.map((task, i) => i === 0 ? { ...task, status: "running" } : task));
1099
+ try {
1100
+ const res = await pullLogic(options);
1101
+ setTasks([
1102
+ { label: `Fetching values for ${res.environment}`, status: "done" },
1103
+ { label: "Writing to local config", status: res.filePath ? "done" : "pending" }
1104
+ ]);
1105
+ setResult(res);
1106
+ } catch (err) {
1107
+ setTasks(
1108
+ (t) => t.map((task) => task.status === "running" ? { ...task, status: "error", error: err instanceof Error ? err.message : String(err) } : task)
1109
+ );
1110
+ }
1111
+ })();
1112
+ }, []);
1113
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
1114
+ /* @__PURE__ */ jsx6(Banner, { title: "Pull Config" }),
1115
+ /* @__PURE__ */ jsx6(TaskList, { tasks }),
1116
+ result && /* @__PURE__ */ jsxs6(Box6, { marginTop: 1, flexDirection: "column", children: [
1117
+ /* @__PURE__ */ jsxs6(Text6, { color: "green", bold: true, children: [
1118
+ "Pulled ",
1119
+ Object.keys(result.values).length,
1120
+ " values for ",
1121
+ result.environment
1122
+ ] }),
1123
+ result.filePath && /* @__PURE__ */ jsxs6(Text6, { color: "gray", children: [
1124
+ "Written to: ",
1125
+ result.filePath
1126
+ ] })
1127
+ ] })
1128
+ ] });
1129
+ }
1130
+ function runPull(options) {
1131
+ if (!isInteractive(options.json)) {
1132
+ pullLogic(options).then(
1133
+ (result) => jsonOutput(result),
1134
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
1135
+ );
1136
+ return;
1137
+ }
1138
+ render4(/* @__PURE__ */ jsx6(PullUI, { options }));
1139
+ }
1140
+ var init_pull = __esm({
1141
+ "src/cli/commands/pull.tsx"() {
1142
+ "use strict";
1143
+ init_Banner();
1144
+ init_TaskList();
1145
+ init_api_client();
1146
+ init_credentials();
1147
+ init_output();
1148
+ init_schema_loader();
1149
+ }
1150
+ });
1151
+
1152
+ // src/cli/commands/set.tsx
1153
+ var set_exports = {};
1154
+ __export(set_exports, {
1155
+ runSet: () => runSet,
1156
+ setLogic: () => setLogic
1157
+ });
1158
+ import { render as render5, Box as Box7, Text as Text7 } from "ink";
1159
+ import { useEffect as useEffect5, useState as useState5 } from "react";
1160
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1161
+ function parseValue(raw) {
1162
+ try {
1163
+ return JSON.parse(raw);
1164
+ } catch {
1165
+ return raw;
1166
+ }
1167
+ }
1168
+ async function setLogic(key, rawValue, options) {
1169
+ const creds = getCredentialsOrExit();
1170
+ const client = new CliApiClient(creds);
1171
+ const environment = options.environment ?? "development";
1172
+ const tier = options.tier ?? "public";
1173
+ const value = parseValue(rawValue);
1174
+ const env = await client.getEnvironmentByName(environment);
1175
+ if (!env) {
1176
+ throw new Error(`Environment "${environment}" not found. Create it first.`);
1177
+ }
1178
+ const schemas = await client.listSchemas();
1179
+ if (schemas.length > 0) {
1180
+ const schema = options.schemaName ? schemas.find((s) => s.name === options.schemaName) : schemas[0];
1181
+ if (schema?.jsonSchema) {
1182
+ const validation = validateValue(schema.jsonSchema, key, value);
1183
+ if (!validation.valid) {
1184
+ throw new Error(`Validation failed for "${key}": ${validation.errors?.join(", ")}`);
1185
+ }
1186
+ }
1187
+ if (schema) {
1188
+ await client.setValue({
1189
+ schemaId: schema.id,
1190
+ environmentId: env.id,
1191
+ key,
1192
+ value,
1193
+ tier
1194
+ });
1195
+ return { success: true, key, value, tier, environment };
1196
+ }
1197
+ }
1198
+ throw new Error("No schemas found. Push a schema first with `smooai-config push`.");
1199
+ }
1200
+ function SetUI({ configKey, value, options }) {
1201
+ const [tasks, setTasks] = useState5([
1202
+ { label: "Validating value", status: "pending" },
1203
+ { label: `Setting ${configKey}`, status: "pending" }
1204
+ ]);
1205
+ const [result, setResult] = useState5(null);
1206
+ useEffect5(() => {
1207
+ (async () => {
1208
+ setTasks((t) => t.map((task, i) => i === 0 ? { ...task, status: "running" } : task));
1209
+ try {
1210
+ const res = await setLogic(configKey, value, options);
1211
+ setTasks([
1212
+ { label: "Validating value", status: "done" },
1213
+ { label: `Setting ${configKey}`, status: "done" }
1214
+ ]);
1215
+ setResult(res);
1216
+ } catch (err) {
1217
+ setTasks(
1218
+ (t) => t.map((task) => task.status === "running" ? { ...task, status: "error", error: err instanceof Error ? err.message : String(err) } : task)
1219
+ );
1220
+ }
1221
+ })();
1222
+ }, []);
1223
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
1224
+ /* @__PURE__ */ jsx7(Banner, { title: "Set Config Value" }),
1225
+ /* @__PURE__ */ jsx7(TaskList, { tasks }),
1226
+ result && /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
1227
+ /* @__PURE__ */ jsx7(Text7, { color: "green", bold: true, children: "Value set successfully!" }),
1228
+ /* @__PURE__ */ jsxs7(Text7, { children: [
1229
+ result.key,
1230
+ " = ",
1231
+ JSON.stringify(result.value),
1232
+ " [",
1233
+ result.tier,
1234
+ "] (",
1235
+ result.environment,
1236
+ ")"
1237
+ ] })
1238
+ ] })
1239
+ ] });
1240
+ }
1241
+ function runSet(key, value, options) {
1242
+ if (!isInteractive(options.json)) {
1243
+ setLogic(key, value, options).then(
1244
+ (result) => jsonOutput(result),
1245
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
1246
+ );
1247
+ return;
1248
+ }
1249
+ render5(/* @__PURE__ */ jsx7(SetUI, { configKey: key, value, options }));
1250
+ }
1251
+ var init_set = __esm({
1252
+ "src/cli/commands/set.tsx"() {
1253
+ "use strict";
1254
+ init_Banner();
1255
+ init_TaskList();
1256
+ init_api_client();
1257
+ init_credentials();
1258
+ init_output();
1259
+ init_schema_validator();
1260
+ }
1261
+ });
1262
+
1263
+ // src/cli/commands/get.tsx
1264
+ var get_exports = {};
1265
+ __export(get_exports, {
1266
+ getLogic: () => getLogic,
1267
+ runGet: () => runGet
1268
+ });
1269
+ import { render as render6, Box as Box8, Text as Text8 } from "ink";
1270
+ import { useEffect as useEffect6, useState as useState6 } from "react";
1271
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1272
+ async function getLogic(key, options) {
1273
+ const creds = getCredentialsOrExit();
1274
+ const client = new CliApiClient(creds);
1275
+ const environment = options.environment ?? "development";
1276
+ const value = await client.getValue(key, environment);
1277
+ return { success: true, key, value, environment };
1278
+ }
1279
+ function GetUI({ configKey, options }) {
1280
+ const [tasks, setTasks] = useState6([{ label: `Fetching ${configKey}`, status: "pending" }]);
1281
+ const [result, setResult] = useState6(null);
1282
+ useEffect6(() => {
1283
+ (async () => {
1284
+ setTasks([{ label: `Fetching ${configKey}`, status: "running" }]);
1285
+ try {
1286
+ const res = await getLogic(configKey, options);
1287
+ setTasks([{ label: `Fetching ${configKey}`, status: "done" }]);
1288
+ setResult(res);
1289
+ } catch (err) {
1290
+ setTasks([
1291
+ {
1292
+ label: `Fetching ${configKey}`,
1293
+ status: "error",
1294
+ error: err instanceof Error ? err.message : String(err)
1295
+ }
1296
+ ]);
1297
+ }
1298
+ })();
1299
+ }, []);
1300
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
1301
+ /* @__PURE__ */ jsx8(Banner, { title: "Get Config Value" }),
1302
+ /* @__PURE__ */ jsx8(TaskList, { tasks }),
1303
+ result && /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
1304
+ /* @__PURE__ */ jsx8(Text8, { bold: true, children: result.key }),
1305
+ /* @__PURE__ */ jsx8(Text8, { children: typeof result.value === "object" ? JSON.stringify(result.value, null, 2) : String(result.value) }),
1306
+ /* @__PURE__ */ jsxs8(Text8, { color: "gray", children: [
1307
+ "Environment: ",
1308
+ result.environment
1309
+ ] })
1310
+ ] })
1311
+ ] });
1312
+ }
1313
+ function runGet(key, options) {
1314
+ if (!isInteractive(options.json)) {
1315
+ getLogic(key, options).then(
1316
+ (result) => jsonOutput(result),
1317
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
1318
+ );
1319
+ return;
1320
+ }
1321
+ render6(/* @__PURE__ */ jsx8(GetUI, { configKey: key, options }));
1322
+ }
1323
+ var init_get = __esm({
1324
+ "src/cli/commands/get.tsx"() {
1325
+ "use strict";
1326
+ init_Banner();
1327
+ init_TaskList();
1328
+ init_api_client();
1329
+ init_credentials();
1330
+ init_output();
1331
+ }
1332
+ });
1333
+
1334
+ // src/cli/commands/list.tsx
1335
+ var list_exports = {};
1336
+ __export(list_exports, {
1337
+ listLogic: () => listLogic,
1338
+ runList: () => runList
1339
+ });
1340
+ import { render as render7, Box as Box9, Text as Text9 } from "ink";
1341
+ import { useEffect as useEffect7, useState as useState7 } from "react";
1342
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1343
+ async function listLogic(options) {
1344
+ const creds = getCredentialsOrExit();
1345
+ const client = new CliApiClient(creds);
1346
+ const environment = options.environment ?? "development";
1347
+ const values = await client.getAllValues(environment);
1348
+ return { success: true, environment, values };
1349
+ }
1350
+ function ListUI({ options }) {
1351
+ const [tasks, setTasks] = useState7([{ label: `Fetching values for ${options.environment ?? "development"}`, status: "pending" }]);
1352
+ const [result, setResult] = useState7(null);
1353
+ useEffect7(() => {
1354
+ (async () => {
1355
+ setTasks([{ label: `Fetching values for ${options.environment ?? "development"}`, status: "running" }]);
1356
+ try {
1357
+ const res = await listLogic(options);
1358
+ setTasks([{ label: `Fetching values for ${res.environment}`, status: "done" }]);
1359
+ setResult(res);
1360
+ } catch (err) {
1361
+ setTasks([
1362
+ {
1363
+ label: `Fetching values for ${options.environment ?? "development"}`,
1364
+ status: "error",
1365
+ error: err instanceof Error ? err.message : String(err)
1366
+ }
1367
+ ]);
1368
+ }
1369
+ })();
1370
+ }, []);
1371
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
1372
+ /* @__PURE__ */ jsx9(Banner, { title: "List Config Values" }),
1373
+ /* @__PURE__ */ jsx9(TaskList, { tasks }),
1374
+ result && /* @__PURE__ */ jsxs9(Box9, { marginTop: 1, flexDirection: "column", children: [
1375
+ /* @__PURE__ */ jsxs9(Text9, { bold: true, children: [
1376
+ "Environment: ",
1377
+ result.environment,
1378
+ " (",
1379
+ Object.keys(result.values).length,
1380
+ " values)"
1381
+ ] }),
1382
+ /* @__PURE__ */ jsx9(Box9, { marginTop: 1, flexDirection: "column", children: Object.entries(result.values).map(([key, value]) => /* @__PURE__ */ jsxs9(Box9, { children: [
1383
+ /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: key }),
1384
+ /* @__PURE__ */ jsx9(Text9, { children: " = " }),
1385
+ /* @__PURE__ */ jsx9(Text9, { children: typeof value === "object" ? JSON.stringify(value) : String(value) })
1386
+ ] }, key)) }),
1387
+ Object.keys(result.values).length === 0 && /* @__PURE__ */ jsx9(Text9, { color: "gray", children: "No values found for this environment." })
1388
+ ] })
1389
+ ] });
1390
+ }
1391
+ function runList(options) {
1392
+ if (!isInteractive(options.json)) {
1393
+ listLogic(options).then(
1394
+ (result) => jsonOutput(result),
1395
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
1396
+ );
1397
+ return;
1398
+ }
1399
+ render7(/* @__PURE__ */ jsx9(ListUI, { options }));
1400
+ }
1401
+ var init_list = __esm({
1402
+ "src/cli/commands/list.tsx"() {
1403
+ "use strict";
1404
+ init_Banner();
1405
+ init_TaskList();
1406
+ init_api_client();
1407
+ init_credentials();
1408
+ init_output();
1409
+ }
1410
+ });
1411
+
1412
+ // src/cli/commands/diff.tsx
1413
+ var diff_exports = {};
1414
+ __export(diff_exports, {
1415
+ diffLogic: () => diffLogic,
1416
+ runDiff: () => runDiff
1417
+ });
1418
+ import { render as render8, Box as Box10, Text as Text10 } from "ink";
1419
+ import { useEffect as useEffect8, useState as useState8 } from "react";
1420
+ import { Fragment, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1421
+ function computeDiff(local, remote) {
1422
+ const localKeys = new Set(Object.keys(local));
1423
+ const remoteKeys = new Set(Object.keys(remote));
1424
+ const added = [...localKeys].filter((k) => !remoteKeys.has(k));
1425
+ const removed = [...remoteKeys].filter((k) => !localKeys.has(k));
1426
+ const changed = [...localKeys].filter((k) => {
1427
+ if (!remoteKeys.has(k)) return false;
1428
+ return JSON.stringify(local[k]) !== JSON.stringify(remote[k]);
1429
+ });
1430
+ return { added, removed, changed };
1431
+ }
1432
+ async function diffLogic(options) {
1433
+ const creds = getCredentialsOrExit();
1434
+ const client = new CliApiClient(creds);
1435
+ const loaded = await loadLocalSchema();
1436
+ if (!loaded) {
1437
+ throw new Error("No local schema found. Run `smooai-config init` first.");
1438
+ }
1439
+ const schemas = await client.listSchemas();
1440
+ const schemaName = options.schemaName;
1441
+ const remoteSchema = schemaName ? schemas.find((s) => s.name === schemaName) : schemas[0];
1442
+ if (!remoteSchema) {
1443
+ const added = Object.keys(loaded.jsonSchema);
1444
+ return {
1445
+ success: true,
1446
+ diff: { added, removed: [], changed: [] },
1447
+ hasChanges: added.length > 0
1448
+ };
1449
+ }
1450
+ const diff = computeDiff(loaded.jsonSchema, remoteSchema.jsonSchema);
1451
+ const hasChanges = diff.added.length > 0 || diff.removed.length > 0 || diff.changed.length > 0;
1452
+ return { success: true, diff, hasChanges };
1453
+ }
1454
+ function DiffUI({ options }) {
1455
+ const [tasks, setTasks] = useState8([
1456
+ { label: "Loading local schema", status: "pending" },
1457
+ { label: "Fetching remote schema", status: "pending" },
1458
+ { label: "Computing diff", status: "pending" }
1459
+ ]);
1460
+ const [result, setResult] = useState8(null);
1461
+ useEffect8(() => {
1462
+ (async () => {
1463
+ setTasks((t) => t.map((task, i) => i === 0 ? { ...task, status: "running" } : task));
1464
+ try {
1465
+ const res = await diffLogic(options);
1466
+ setTasks([
1467
+ { label: "Loading local schema", status: "done" },
1468
+ { label: "Fetching remote schema", status: "done" },
1469
+ { label: "Computing diff", status: "done" }
1470
+ ]);
1471
+ setResult(res);
1472
+ } catch (err) {
1473
+ setTasks(
1474
+ (t) => t.map((task) => task.status === "running" ? { ...task, status: "error", error: err instanceof Error ? err.message : String(err) } : task)
1475
+ );
1476
+ }
1477
+ })();
1478
+ }, []);
1479
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
1480
+ /* @__PURE__ */ jsx10(Banner, { title: "Schema Diff" }),
1481
+ /* @__PURE__ */ jsx10(TaskList, { tasks }),
1482
+ result && /* @__PURE__ */ jsx10(Box10, { marginTop: 1, flexDirection: "column", children: !result.hasChanges ? /* @__PURE__ */ jsx10(Text10, { color: "green", bold: true, children: "Schemas are in sync. No changes detected." }) : /* @__PURE__ */ jsxs10(Fragment, { children: [
1483
+ /* @__PURE__ */ jsx10(Text10, { bold: true, children: "Changes:" }),
1484
+ result.diff.added.map((k) => /* @__PURE__ */ jsxs10(Text10, { color: "green", children: [
1485
+ "+ ",
1486
+ k,
1487
+ " (new)"
1488
+ ] }, k)),
1489
+ result.diff.removed.map((k) => /* @__PURE__ */ jsxs10(Text10, { color: "red", children: [
1490
+ "- ",
1491
+ k,
1492
+ " (removed)"
1493
+ ] }, k)),
1494
+ result.diff.changed.map((k) => /* @__PURE__ */ jsxs10(Text10, { color: "yellow", children: [
1495
+ "~ ",
1496
+ k,
1497
+ " (modified)"
1498
+ ] }, k))
1499
+ ] }) })
1500
+ ] });
1501
+ }
1502
+ function runDiff(options) {
1503
+ if (!isInteractive(options.json)) {
1504
+ diffLogic(options).then(
1505
+ (result) => jsonOutput(result),
1506
+ (err) => jsonOutput({ success: false, error: err.message }, 1)
1507
+ );
1508
+ return;
1509
+ }
1510
+ render8(/* @__PURE__ */ jsx10(DiffUI, { options }));
1511
+ }
1512
+ var init_diff = __esm({
1513
+ "src/cli/commands/diff.tsx"() {
1514
+ "use strict";
1515
+ init_Banner();
1516
+ init_TaskList();
1517
+ init_api_client();
1518
+ init_credentials();
1519
+ init_output();
1520
+ init_schema_loader();
1521
+ }
1522
+ });
1523
+
1524
+ // src/cli/index.ts
1525
+ import { Command } from "commander";
1526
+ var program = new Command();
1527
+ program.name("smooai-config").description("Smoo AI Configuration Management CLI").version("1.1.0");
1528
+ program.option("--json", "Output in JSON format (auto-enabled when no TTY detected)");
1529
+ program.command("init").description("Initialize a project with .smooai-config/ directory").option("--language <lang>", "Project language: typescript, python, go, rust, other", "typescript").action(async (opts) => {
1530
+ const { runInit: runInit2 } = await Promise.resolve().then(() => (init_init(), init_exports));
1531
+ runInit2({ ...opts, json: program.opts().json ?? opts.json });
1532
+ });
1533
+ program.command("login").description("Store credentials for CLI access").option("--api-key <key>", "API key for authentication").option("--org-id <id>", "Organization ID").option("--base-url <url>", "API base URL", "https://api.smoo.ai").action(async (opts) => {
1534
+ const { runLogin: runLogin2 } = await Promise.resolve().then(() => (init_login(), login_exports));
1535
+ runLogin2({ ...opts, json: program.opts().json ?? opts.json });
1536
+ });
1537
+ program.command("push").description("Push local config schema to the remote platform").option("--schema-name <name>", "Schema name (default: project directory name)").option("--description <desc>", "Change description for this version").option("--yes", "Skip confirmation prompt").action(async (opts) => {
1538
+ const { runPush: runPush2 } = await Promise.resolve().then(() => (init_push(), push_exports));
1539
+ runPush2({ ...opts, json: program.opts().json ?? opts.json });
1540
+ });
1541
+ program.command("pull").description("Pull remote config values to local files").option("--environment <env>", "Environment name", "development").action(async (opts) => {
1542
+ const { runPull: runPull2 } = await Promise.resolve().then(() => (init_pull(), pull_exports));
1543
+ runPull2({ ...opts, json: program.opts().json ?? opts.json });
1544
+ });
1545
+ program.command("set <key> <value>").description("Set a config value on the remote platform").option("--environment <env>", "Environment name", "development").option("--tier <tier>", "Value tier: public, secret, feature_flag", "public").option("--schema-name <name>", "Schema name to use for validation").action(async (key, value, opts) => {
1546
+ const { runSet: runSet2 } = await Promise.resolve().then(() => (init_set(), set_exports));
1547
+ runSet2(key, value, { ...opts, json: program.opts().json ?? opts.json });
1548
+ });
1549
+ program.command("get <key>").description("Get a config value from the remote platform").option("--environment <env>", "Environment name", "development").action(async (key, opts) => {
1550
+ const { runGet: runGet2 } = await Promise.resolve().then(() => (init_get(), get_exports));
1551
+ runGet2(key, { ...opts, json: program.opts().json ?? opts.json });
1552
+ });
1553
+ program.command("list").description("List all config values for an environment").option("--environment <env>", "Environment name", "development").action(async (opts) => {
1554
+ const { runList: runList2 } = await Promise.resolve().then(() => (init_list(), list_exports));
1555
+ runList2({ ...opts, json: program.opts().json ?? opts.json });
1556
+ });
1557
+ program.command("diff").description("Compare local config schema vs remote").option("--schema-name <name>", "Schema name to compare against").action(async (opts) => {
1558
+ const { runDiff: runDiff2 } = await Promise.resolve().then(() => (init_diff(), diff_exports));
1559
+ runDiff2({ ...opts, json: program.opts().json ?? opts.json });
1560
+ });
1561
+ program.parse();
1562
+ //# sourceMappingURL=cli.mjs.map