@studio-foundation/cli 0.3.0-beta.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 (277) hide show
  1. package/ARCHITECTURE.md +40 -0
  2. package/LICENSE +663 -0
  3. package/README.md +165 -0
  4. package/dist/commands/api.d.ts +16 -0
  5. package/dist/commands/api.d.ts.map +1 -0
  6. package/dist/commands/api.js +118 -0
  7. package/dist/commands/api.js.map +1 -0
  8. package/dist/commands/config.d.ts +32 -0
  9. package/dist/commands/config.d.ts.map +1 -0
  10. package/dist/commands/config.js +390 -0
  11. package/dist/commands/config.js.map +1 -0
  12. package/dist/commands/init.d.ts +93 -0
  13. package/dist/commands/init.d.ts.map +1 -0
  14. package/dist/commands/init.js +728 -0
  15. package/dist/commands/init.js.map +1 -0
  16. package/dist/commands/install.d.ts +2 -0
  17. package/dist/commands/install.d.ts.map +1 -0
  18. package/dist/commands/install.js +22 -0
  19. package/dist/commands/install.js.map +1 -0
  20. package/dist/commands/integrations.d.ts +14 -0
  21. package/dist/commands/integrations.d.ts.map +1 -0
  22. package/dist/commands/integrations.js +282 -0
  23. package/dist/commands/integrations.js.map +1 -0
  24. package/dist/commands/list.d.ts +9 -0
  25. package/dist/commands/list.d.ts.map +1 -0
  26. package/dist/commands/list.js +161 -0
  27. package/dist/commands/list.js.map +1 -0
  28. package/dist/commands/logs.d.ts +7 -0
  29. package/dist/commands/logs.d.ts.map +1 -0
  30. package/dist/commands/logs.js +98 -0
  31. package/dist/commands/logs.js.map +1 -0
  32. package/dist/commands/ollama.d.ts +6 -0
  33. package/dist/commands/ollama.d.ts.map +1 -0
  34. package/dist/commands/ollama.js +161 -0
  35. package/dist/commands/ollama.js.map +1 -0
  36. package/dist/commands/project.d.ts +38 -0
  37. package/dist/commands/project.d.ts.map +1 -0
  38. package/dist/commands/project.js +137 -0
  39. package/dist/commands/project.js.map +1 -0
  40. package/dist/commands/registry/audit.d.ts +13 -0
  41. package/dist/commands/registry/audit.d.ts.map +1 -0
  42. package/dist/commands/registry/audit.js +65 -0
  43. package/dist/commands/registry/audit.js.map +1 -0
  44. package/dist/commands/registry/index.d.ts +3 -0
  45. package/dist/commands/registry/index.d.ts.map +1 -0
  46. package/dist/commands/registry/index.js +53 -0
  47. package/dist/commands/registry/index.js.map +1 -0
  48. package/dist/commands/registry/install.d.ts +17 -0
  49. package/dist/commands/registry/install.d.ts.map +1 -0
  50. package/dist/commands/registry/install.js +153 -0
  51. package/dist/commands/registry/install.js.map +1 -0
  52. package/dist/commands/registry/publish.d.ts +8 -0
  53. package/dist/commands/registry/publish.d.ts.map +1 -0
  54. package/dist/commands/registry/publish.js +94 -0
  55. package/dist/commands/registry/publish.js.map +1 -0
  56. package/dist/commands/registry/remove.d.ts +8 -0
  57. package/dist/commands/registry/remove.d.ts.map +1 -0
  58. package/dist/commands/registry/remove.js +82 -0
  59. package/dist/commands/registry/remove.js.map +1 -0
  60. package/dist/commands/registry/search.d.ts +9 -0
  61. package/dist/commands/registry/search.d.ts.map +1 -0
  62. package/dist/commands/registry/search.js +68 -0
  63. package/dist/commands/registry/search.js.map +1 -0
  64. package/dist/commands/registry/sync.d.ts +8 -0
  65. package/dist/commands/registry/sync.d.ts.map +1 -0
  66. package/dist/commands/registry/sync.js +19 -0
  67. package/dist/commands/registry/sync.js.map +1 -0
  68. package/dist/commands/registry/update.d.ts +15 -0
  69. package/dist/commands/registry/update.d.ts.map +1 -0
  70. package/dist/commands/registry/update.js +48 -0
  71. package/dist/commands/registry/update.js.map +1 -0
  72. package/dist/commands/replay.d.ts +36 -0
  73. package/dist/commands/replay.d.ts.map +1 -0
  74. package/dist/commands/replay.js +453 -0
  75. package/dist/commands/replay.js.map +1 -0
  76. package/dist/commands/run.d.ts +18 -0
  77. package/dist/commands/run.d.ts.map +1 -0
  78. package/dist/commands/run.js +406 -0
  79. package/dist/commands/run.js.map +1 -0
  80. package/dist/commands/status.d.ts +6 -0
  81. package/dist/commands/status.d.ts.map +1 -0
  82. package/dist/commands/status.js +144 -0
  83. package/dist/commands/status.js.map +1 -0
  84. package/dist/commands/template/index.d.ts +2 -0
  85. package/dist/commands/template/index.d.ts.map +1 -0
  86. package/dist/commands/template/index.js +57 -0
  87. package/dist/commands/template/index.js.map +1 -0
  88. package/dist/commands/template/validate.d.ts +8 -0
  89. package/dist/commands/template/validate.d.ts.map +1 -0
  90. package/dist/commands/template/validate.js +135 -0
  91. package/dist/commands/template/validate.js.map +1 -0
  92. package/dist/commands/templates.d.ts +14 -0
  93. package/dist/commands/templates.d.ts.map +1 -0
  94. package/dist/commands/templates.js +86 -0
  95. package/dist/commands/templates.js.map +1 -0
  96. package/dist/commands/tools.d.ts +12 -0
  97. package/dist/commands/tools.d.ts.map +1 -0
  98. package/dist/commands/tools.js +200 -0
  99. package/dist/commands/tools.js.map +1 -0
  100. package/dist/commands/users.d.ts +4 -0
  101. package/dist/commands/users.d.ts.map +1 -0
  102. package/dist/commands/users.js +123 -0
  103. package/dist/commands/users.js.map +1 -0
  104. package/dist/commands/validate.d.ts +2 -0
  105. package/dist/commands/validate.d.ts.map +1 -0
  106. package/dist/commands/validate.js +39 -0
  107. package/dist/commands/validate.js.map +1 -0
  108. package/dist/config.d.ts +36 -0
  109. package/dist/config.d.ts.map +1 -0
  110. package/dist/config.js +64 -0
  111. package/dist/config.js.map +1 -0
  112. package/dist/index.d.ts +3 -0
  113. package/dist/index.d.ts.map +1 -0
  114. package/dist/index.js +178 -0
  115. package/dist/index.js.map +1 -0
  116. package/dist/models-cache.d.ts +13 -0
  117. package/dist/models-cache.d.ts.map +1 -0
  118. package/dist/models-cache.js +106 -0
  119. package/dist/models-cache.js.map +1 -0
  120. package/dist/output/file-changes.d.ts +15 -0
  121. package/dist/output/file-changes.d.ts.map +1 -0
  122. package/dist/output/file-changes.js +77 -0
  123. package/dist/output/file-changes.js.map +1 -0
  124. package/dist/output/formatter.d.ts +6 -0
  125. package/dist/output/formatter.d.ts.map +1 -0
  126. package/dist/output/formatter.js +70 -0
  127. package/dist/output/formatter.js.map +1 -0
  128. package/dist/output/formatters.d.ts +42 -0
  129. package/dist/output/formatters.d.ts.map +1 -0
  130. package/dist/output/formatters.js +280 -0
  131. package/dist/output/formatters.js.map +1 -0
  132. package/dist/output/logger.d.ts +3 -0
  133. package/dist/output/logger.d.ts.map +1 -0
  134. package/dist/output/logger.js +15 -0
  135. package/dist/output/logger.js.map +1 -0
  136. package/dist/output/parallel-progress.d.ts +33 -0
  137. package/dist/output/parallel-progress.d.ts.map +1 -0
  138. package/dist/output/parallel-progress.js +85 -0
  139. package/dist/output/parallel-progress.js.map +1 -0
  140. package/dist/output/progress.d.ts +32 -0
  141. package/dist/output/progress.d.ts.map +1 -0
  142. package/dist/output/progress.js +393 -0
  143. package/dist/output/progress.js.map +1 -0
  144. package/dist/provider-validator.d.ts +15 -0
  145. package/dist/provider-validator.d.ts.map +1 -0
  146. package/dist/provider-validator.js +85 -0
  147. package/dist/provider-validator.js.map +1 -0
  148. package/dist/registry/cache.d.ts +10 -0
  149. package/dist/registry/cache.d.ts.map +1 -0
  150. package/dist/registry/cache.js +36 -0
  151. package/dist/registry/cache.js.map +1 -0
  152. package/dist/registry/client.d.ts +19 -0
  153. package/dist/registry/client.d.ts.map +1 -0
  154. package/dist/registry/client.js +63 -0
  155. package/dist/registry/client.js.map +1 -0
  156. package/dist/registry/lockfile.d.ts +17 -0
  157. package/dist/registry/lockfile.d.ts.map +1 -0
  158. package/dist/registry/lockfile.js +61 -0
  159. package/dist/registry/lockfile.js.map +1 -0
  160. package/dist/registry/resolver.d.ts +13 -0
  161. package/dist/registry/resolver.d.ts.map +1 -0
  162. package/dist/registry/resolver.js +79 -0
  163. package/dist/registry/resolver.js.map +1 -0
  164. package/dist/registry/types.d.ts +59 -0
  165. package/dist/registry/types.d.ts.map +1 -0
  166. package/dist/registry/types.js +14 -0
  167. package/dist/registry/types.js.map +1 -0
  168. package/dist/run-logger.d.ts +8 -0
  169. package/dist/run-logger.d.ts.map +1 -0
  170. package/dist/run-logger.js +53 -0
  171. package/dist/run-logger.js.map +1 -0
  172. package/dist/run-store-factory.d.ts +9 -0
  173. package/dist/run-store-factory.d.ts.map +1 -0
  174. package/dist/run-store-factory.js +26 -0
  175. package/dist/run-store-factory.js.map +1 -0
  176. package/dist/studio-dir.d.ts +7 -0
  177. package/dist/studio-dir.d.ts.map +1 -0
  178. package/dist/studio-dir.js +27 -0
  179. package/dist/studio-dir.js.map +1 -0
  180. package/dist/utils/input-wizard.d.ts +4 -0
  181. package/dist/utils/input-wizard.d.ts.map +1 -0
  182. package/dist/utils/input-wizard.js +56 -0
  183. package/dist/utils/input-wizard.js.map +1 -0
  184. package/dist/utils/placeholders.d.ts +6 -0
  185. package/dist/utils/placeholders.d.ts.map +1 -0
  186. package/dist/utils/placeholders.js +12 -0
  187. package/dist/utils/placeholders.js.map +1 -0
  188. package/package.json +43 -0
  189. package/src/commands/api.ts +126 -0
  190. package/src/commands/config.ts +433 -0
  191. package/src/commands/init.ts +879 -0
  192. package/src/commands/install.ts +23 -0
  193. package/src/commands/integrations.ts +332 -0
  194. package/src/commands/list.ts +197 -0
  195. package/src/commands/logs.ts +119 -0
  196. package/src/commands/ollama.ts +168 -0
  197. package/src/commands/project.ts +167 -0
  198. package/src/commands/registry/audit.ts +87 -0
  199. package/src/commands/registry/index.ts +63 -0
  200. package/src/commands/registry/install.ts +222 -0
  201. package/src/commands/registry/publish.ts +112 -0
  202. package/src/commands/registry/remove.ts +89 -0
  203. package/src/commands/registry/search.ts +93 -0
  204. package/src/commands/registry/sync.ts +24 -0
  205. package/src/commands/registry/update.ts +63 -0
  206. package/src/commands/replay.ts +559 -0
  207. package/src/commands/run.ts +454 -0
  208. package/src/commands/status.ts +163 -0
  209. package/src/commands/template/index.ts +59 -0
  210. package/src/commands/template/validate.ts +175 -0
  211. package/src/commands/templates.ts +99 -0
  212. package/src/commands/tools.ts +227 -0
  213. package/src/commands/users.ts +127 -0
  214. package/src/commands/validate.ts +46 -0
  215. package/src/config.ts +101 -0
  216. package/src/index.ts +201 -0
  217. package/src/models-cache.ts +127 -0
  218. package/src/output/file-changes.ts +97 -0
  219. package/src/output/formatter.ts +85 -0
  220. package/src/output/formatters.ts +303 -0
  221. package/src/output/logger.ts +18 -0
  222. package/src/output/parallel-progress.ts +103 -0
  223. package/src/output/progress.ts +414 -0
  224. package/src/provider-validator.ts +109 -0
  225. package/src/registry/cache.ts +46 -0
  226. package/src/registry/client.ts +84 -0
  227. package/src/registry/lockfile.ts +68 -0
  228. package/src/registry/resolver.ts +113 -0
  229. package/src/registry/types.ts +66 -0
  230. package/src/run-logger.ts +66 -0
  231. package/src/run-store-factory.ts +30 -0
  232. package/src/studio-dir.ts +28 -0
  233. package/src/utils/input-wizard.ts +73 -0
  234. package/src/utils/placeholders.ts +10 -0
  235. package/templates/.studiorc.yaml +16 -0
  236. package/templates/projects/blank/metadata.json +7 -0
  237. package/templates/studio-config.yaml +14 -0
  238. package/tests/__stubs__/studio-runner.ts +104 -0
  239. package/tests/commands/api.test.ts +110 -0
  240. package/tests/commands/config.test.ts +221 -0
  241. package/tests/commands/init.test.ts +919 -0
  242. package/tests/commands/install.test.ts +52 -0
  243. package/tests/commands/integrations.test.ts +158 -0
  244. package/tests/commands/ollama.test.ts +139 -0
  245. package/tests/commands/project.test.ts +179 -0
  246. package/tests/commands/registry/audit.test.ts +56 -0
  247. package/tests/commands/registry/install.test.ts +200 -0
  248. package/tests/commands/registry/publish.test.ts +56 -0
  249. package/tests/commands/registry/remove.test.ts +103 -0
  250. package/tests/commands/registry/search.test.ts +44 -0
  251. package/tests/commands/registry/sync.test.ts +37 -0
  252. package/tests/commands/registry/update.test.ts +62 -0
  253. package/tests/commands/replay.test.ts +283 -0
  254. package/tests/commands/template/validate.test.ts +150 -0
  255. package/tests/commands/templates.test.ts +42 -0
  256. package/tests/commands/tools.test.ts +106 -0
  257. package/tests/config.test.ts +142 -0
  258. package/tests/formatter.test.ts +158 -0
  259. package/tests/integration/sigint.test.ts +188 -0
  260. package/tests/models-cache.test.ts +250 -0
  261. package/tests/output/file-changes.test.ts +178 -0
  262. package/tests/output/formatters.test.ts +448 -0
  263. package/tests/output/progress-spinner.test.ts +232 -0
  264. package/tests/output/progress-timer.test.ts +230 -0
  265. package/tests/provider-validator.test.ts +182 -0
  266. package/tests/registry/cache.test.ts +66 -0
  267. package/tests/registry/client.test.ts +70 -0
  268. package/tests/registry/lockfile.test.ts +87 -0
  269. package/tests/registry/resolver.test.ts +122 -0
  270. package/tests/run-logger-events.test.ts +326 -0
  271. package/tests/run-logger.test.ts +64 -0
  272. package/tests/run-store-factory.test.ts +51 -0
  273. package/tests/studio-dir.test.ts +31 -0
  274. package/tests/utils/input-wizard.test.ts +153 -0
  275. package/tests/utils/placeholders.test.ts +36 -0
  276. package/tsconfig.json +24 -0
  277. package/vitest.config.ts +20 -0
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # @studio-foundation/cli
2
+
3
+ The terminal interface for Studio. `studio run`, `studio init`, `studio config`, and more.
4
+
5
+ ## Role
6
+
7
+ cli is the human-facing layer. It reads user input, loads config from `.studio/config.yaml`, wires up the provider and tool registries, delegates to engine, and renders progress output to the terminal.
8
+
9
+ ```
10
+ user → studio run feature-builder --input "..." → cli → engine → ...
11
+ ```
12
+
13
+ ## Commands
14
+
15
+ ```bash
16
+ # Daily use
17
+ studio run <pipeline> --input "..." # Run a pipeline
18
+ studio run <pipeline> --input-file input.yaml # Run with YAML input file
19
+ studio run <pipeline> --live # Stream tool calls in real-time
20
+ studio run <pipeline> --provider mock # Run with mock provider (no API calls)
21
+ studio run <pipeline> --anonymize # Anonymize PII before sending to LLM
22
+ studio status [run-id] # Check run status (latest run if no ID given)
23
+ studio logs [run-id] # View JSONL logs for a run
24
+ studio replay [run-id] # Replay a completed run
25
+ studio list projects # List available projects
26
+ studio list pipelines # List available pipelines
27
+
28
+ # Init (interactive wizard)
29
+ studio init # Full interactive wizard: template, provider, tools
30
+ studio init --template software --name my-app # Direct mode (CI/CD-friendly)
31
+ studio init --force # Re-initialize (backup + recreate)
32
+
33
+ # Config
34
+ studio config add-provider # Add an LLM provider (wizard)
35
+ studio config set provider anthropic --api-key $KEY
36
+ studio config set default.model claude-haiku-4-20250514
37
+ studio config list # Show config (API keys masked)
38
+
39
+ # Tools
40
+ studio tools list # List tools in current project
41
+ studio tools add # Add tools (interactive wizard)
42
+ studio tools add git # Add specific tool
43
+ studio tools remove nutrition # Remove a tool
44
+ studio tools info git # Show tool details
45
+
46
+ # Registry
47
+ studio registry install <name> # Install a tool from the registry
48
+ studio registry remove <name> # Remove a registry-installed tool
49
+ studio registry search <query> # Search available tools in the registry
50
+ studio registry publish <path> # Publish a tool to the registry
51
+ studio registry audit # Audit installed tools for updates/issues
52
+ studio registry sync # Sync registry.lock.json with installed tools
53
+ studio registry update [name] # Update installed tools (all or specific)
54
+
55
+ # Templates
56
+ studio templates # List available templates
57
+ studio template validate <path> # Validate a template structure
58
+
59
+ # Integrations
60
+ studio integrations # Manage integrations (Linear, etc.)
61
+
62
+ # Project
63
+ studio project # Project management
64
+
65
+ # API server
66
+ studio api start # Start the HTTP REST API server
67
+
68
+ # Validation
69
+ studio validate <contract> <output.json> # Validate output against contract without LLM
70
+ ```
71
+
72
+ ## Config resolution
73
+
74
+ cli looks for `.studio/config.yaml` by walking up the directory tree from the current working directory (via `findStudioDir()`). This is how running `studio run` from inside a user project finds its configuration — same mechanism as `git` finding `.git/`.
75
+
76
+ Format of `.studio/config.yaml`:
77
+
78
+ ```yaml
79
+ providers:
80
+ anthropic:
81
+ apiKey: ${ANTHROPIC_API_KEY} # Env var substitution supported
82
+ openai:
83
+ apiKey: ${OPENAI_API_KEY}
84
+
85
+ defaults:
86
+ provider: anthropic
87
+ model: claude-sonnet-4-20250514
88
+ ```
89
+
90
+ This file is gitignored — never commit API keys.
91
+
92
+ ## `studio init` wizard flow
93
+
94
+ ```
95
+ $ studio init
96
+
97
+ What type of app are you building?
98
+ ❯ software — Code generation, git operations
99
+ finance — Transaction analysis, budget management
100
+ analysis — Content extraction, entity recognition
101
+ data — Validation, transformation, compliance
102
+ conversation — Dialogue management, memory systems
103
+
104
+ Project name? my-code-builder
105
+
106
+ Which LLM provider?
107
+ ❯ Anthropic (Claude)
108
+ OpenAI (GPT)
109
+
110
+ Anthropic API Key: sk-ant-... ✓ Valid
111
+
112
+ Install default tools for this template?
113
+ ❯ ☑ repo-manager (file operations)
114
+ ☑ shell (run commands)
115
+ ☑ git (version control)
116
+ ☑ search (codebase search)
117
+
118
+ ✓ Created my-code-builder/.studio/
119
+ ✓ Copied software template
120
+ ✓ Installed 4 tools
121
+ ✓ Configured Anthropic provider
122
+ ```
123
+
124
+ ## `studio run --live` output
125
+
126
+ ```
127
+ [1/4] Analyzing brief...
128
+ ✔ 🔍 repo_manager-list_files(src/pages) → 3 files
129
+ ✔ 📖 repo_manager-read_file(src/pages/about.tsx) → 247 lines
130
+ ✓ (1 attempt, 8s)
131
+
132
+ [2/4] Creating implementation plan...
133
+ ✓ (1 attempt, 12s)
134
+
135
+ [3/4] Generating code...
136
+ ✔ 📖 repo_manager-read_file(src/pages/about.tsx) → 247 lines
137
+ ✔ ✏️ repo_manager-write_file(src/pages/about.tsx) → written
138
+ ↺ Retry 2/5 — TypeScript error: Property 'items' does not exist
139
+ ✔ ✏️ repo_manager-write_file(src/pages/about.tsx) → written
140
+ ✓ (2 attempts, 38s)
141
+
142
+ [4/4] QA review...
143
+ ✓ approved (1 attempt, 15s)
144
+
145
+ Pipeline completed in 1m13s
146
+ ```
147
+
148
+ ## Development
149
+
150
+ ```bash
151
+ # From Studio monorepo root
152
+ pnpm build # Build all packages including cli
153
+ node cli/dist/index.js run ... # Run directly
154
+
155
+ # Or link globally
156
+ cd cli && npm link
157
+ studio --version
158
+ ```
159
+
160
+ ## Rules
161
+
162
+ - cli is the composition root — it imports from engine, runner (ToolRegistry, ProviderRegistry, MCPClient), and api (for `studio api start`). This is a documented exception to the package DAG (see INVARIANTS.md).
163
+ - cli never contains business logic — it wires up dependencies and delegates.
164
+ - All output rendering is in `output/` — keep display logic separate from command logic.
165
+ - `findStudioDir()` walks up the directory tree — tests must use `/tmp` as base, never a subdirectory of the Studio repo (the repo itself has `.studio/` at its root).
@@ -0,0 +1,16 @@
1
+ interface ApiOptions {
2
+ port?: string;
3
+ config?: string;
4
+ }
5
+ export declare function writePid(port: number): Promise<void>;
6
+ export declare function readPid(): Promise<{
7
+ pid: number;
8
+ port: number;
9
+ } | null>;
10
+ export declare function clearPid(): Promise<void>;
11
+ export declare function isProcessAlive(pid: number): boolean;
12
+ export declare function apiStartCommand(options: ApiOptions): Promise<void>;
13
+ export declare function apiStopCommand(): Promise<void>;
14
+ export declare function apiStatusCommand(options: ApiOptions): Promise<void>;
15
+ export {};
16
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/commands/api.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1D;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAW7E;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAE9C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOnD;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCxE;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAcpD;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBzE"}
@@ -0,0 +1,118 @@
1
+ import { writeFile, readFile, unlink, mkdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { loadConfig } from '../config.js';
5
+ function pidFilePath() {
6
+ return join(homedir(), '.studio', 'api.pid');
7
+ }
8
+ export async function writePid(port) {
9
+ await mkdir(join(homedir(), '.studio'), { recursive: true });
10
+ await writeFile(pidFilePath(), `${process.pid}:${port}`, 'utf-8');
11
+ }
12
+ export async function readPid() {
13
+ try {
14
+ const content = await readFile(pidFilePath(), 'utf-8');
15
+ const [pidStr, portStr] = content.trim().split(':');
16
+ const pid = parseInt(pidStr ?? '', 10);
17
+ const port = parseInt(portStr ?? '', 10);
18
+ if (isNaN(pid) || isNaN(port))
19
+ return null;
20
+ return { pid, port };
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ export async function clearPid() {
27
+ try {
28
+ await unlink(pidFilePath());
29
+ }
30
+ catch { }
31
+ }
32
+ export function isProcessAlive(pid) {
33
+ try {
34
+ process.kill(pid, 0);
35
+ return true;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ export async function apiStartCommand(options) {
42
+ let apiModule;
43
+ try {
44
+ apiModule = await import('@studio-foundation/api');
45
+ }
46
+ catch {
47
+ console.error('API not installed. Run: studio install api');
48
+ process.exit(1);
49
+ }
50
+ const { bootstrap, buildServer } = apiModule;
51
+ const config = await loadConfig(options.config);
52
+ const cwd = config.resolvedStudioDir
53
+ ? config.resolvedStudioDir.replace(/\/.studio$/, '')
54
+ : process.cwd();
55
+ let result;
56
+ try {
57
+ result = await bootstrap(cwd);
58
+ }
59
+ catch (err) {
60
+ console.error('Error:', err instanceof Error ? err.message : String(err));
61
+ process.exit(1);
62
+ }
63
+ const { store, launcher, configsDir, projectName, apiConfig, cleanup, studioVersion, maskedConfig, webhookStore, integrationStore, integrationRuntime } = result;
64
+ const port = options.port ? parseInt(options.port, 10) : (apiConfig.port ?? 3700);
65
+ const server = buildServer({ store, launcher, configsDir, projectName, apiConfig, studioVersion, maskedConfig, webhookStore, integrationStore, integrationRuntime });
66
+ await writePid(port);
67
+ const shutdown = async () => {
68
+ await server.close();
69
+ await cleanup();
70
+ await clearPid();
71
+ process.exit(0);
72
+ };
73
+ process.on('SIGTERM', () => void shutdown());
74
+ process.on('SIGINT', () => void shutdown());
75
+ await server.listen({ port, host: '0.0.0.0' });
76
+ console.log(`Studio API running on http://localhost:${port}`);
77
+ }
78
+ export async function apiStopCommand() {
79
+ const entry = await readPid();
80
+ if (!entry) {
81
+ console.log('Studio API is not running.');
82
+ return;
83
+ }
84
+ if (!isProcessAlive(entry.pid)) {
85
+ await clearPid();
86
+ console.log('Studio API is not running (stale PID file removed).');
87
+ return;
88
+ }
89
+ process.kill(entry.pid, 'SIGTERM');
90
+ await clearPid();
91
+ console.log('Studio API stopped.');
92
+ }
93
+ export async function apiStatusCommand(options) {
94
+ const entry = await readPid();
95
+ if (!entry) {
96
+ console.log('Studio API: not running');
97
+ return;
98
+ }
99
+ if (!isProcessAlive(entry.pid)) {
100
+ await clearPid();
101
+ console.log('Studio API: not running (stale PID file removed)');
102
+ return;
103
+ }
104
+ const port = options.port ? parseInt(options.port, 10) : entry.port;
105
+ try {
106
+ const response = await fetch(`http://localhost:${port}/api/health`);
107
+ if (response.ok) {
108
+ console.log(`Studio API: running on port ${port} (PID ${entry.pid})`);
109
+ }
110
+ else {
111
+ console.log(`Studio API: process alive (PID ${entry.pid}) but not responding on port ${port}`);
112
+ }
113
+ }
114
+ catch {
115
+ console.log(`Studio API: process alive (PID ${entry.pid}) but port ${port} not responding`);
116
+ }
117
+ }
118
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/commands/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export declare const PROVIDERS: readonly [{
2
+ readonly id: "anthropic";
3
+ readonly label: "Anthropic (Claude)";
4
+ readonly defaultModel: "claude-sonnet-4-20250514";
5
+ }, {
6
+ readonly id: "openai";
7
+ readonly label: "OpenAI (GPT)";
8
+ readonly defaultModel: "gpt-4o";
9
+ }, {
10
+ readonly id: "google";
11
+ readonly label: "Google (Gemini)";
12
+ readonly defaultModel: "gemini-1.5-pro";
13
+ }, {
14
+ readonly id: "ollama";
15
+ readonly label: "Ollama (local)";
16
+ readonly defaultModel: "llama3.2";
17
+ }];
18
+ export type ProviderId = (typeof PROVIDERS)[number]['id'];
19
+ export declare function validateApiKeyForProvider(provider: string, key: string): true | string;
20
+ export declare function addProviderConfig(configFile: string, provider: string, apiKey: string, setDefault: boolean, model?: string): Promise<void>;
21
+ export declare function isProviderConfigured(configFile: string, provider: string): Promise<boolean>;
22
+ export declare function getConfigValue(config: Record<string, unknown>, path: string): unknown;
23
+ export declare function setConfigValue(config: Record<string, unknown>, path: string, value: string): void;
24
+ export declare function maskSecrets(obj: unknown): unknown;
25
+ interface ConfigOptions {
26
+ apiKey?: string;
27
+ project?: string;
28
+ setDefault?: boolean;
29
+ }
30
+ export declare function configCommand(action: string, args: string[], options: ConfigOptions): Promise<void>;
31
+ export {};
32
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;EAKZ,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAE1D,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAWtF;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,OAAO,EACnB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAIjG;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQrF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAWjG;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAcjD;AA0BD,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAgHD,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CAqLf"}