@studio-foundation/api 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.
- package/ARCHITECTURE.md +52 -0
- package/LICENSE +663 -0
- package/README.md +161 -0
- package/dist/api.d.ts +8 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +6 -0
- package/dist/api.js.map +1 -0
- package/dist/bootstrap.d.ts +66 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +193 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/event-bus.d.ts +16 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +37 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/integration-runtime.d.ts +22 -0
- package/dist/integration-runtime.d.ts.map +1 -0
- package/dist/integration-runtime.js +150 -0
- package/dist/integration-runtime.js.map +1 -0
- package/dist/integration-store.d.ts +26 -0
- package/dist/integration-store.d.ts.map +1 -0
- package/dist/integration-store.js +80 -0
- package/dist/integration-store.js.map +1 -0
- package/dist/integrations/linear/failure-handler.d.ts +5 -0
- package/dist/integrations/linear/failure-handler.d.ts.map +1 -0
- package/dist/integrations/linear/failure-handler.js +73 -0
- package/dist/integrations/linear/failure-handler.js.map +1 -0
- package/dist/integrations/linear/webhook-handler.d.ts +6 -0
- package/dist/integrations/linear/webhook-handler.d.ts.map +1 -0
- package/dist/integrations/linear/webhook-handler.js +131 -0
- package/dist/integrations/linear/webhook-handler.js.map +1 -0
- package/dist/integrations/registry.d.ts +4 -0
- package/dist/integrations/registry.d.ts.map +1 -0
- package/dist/integrations/registry.js +9 -0
- package/dist/integrations/registry.js.map +1 -0
- package/dist/integrations/types.d.ts +33 -0
- package/dist/integrations/types.d.ts.map +1 -0
- package/dist/integrations/types.js +2 -0
- package/dist/integrations/types.js.map +1 -0
- package/dist/launcher.d.ts +45 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +149 -0
- package/dist/launcher.js.map +1 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +37 -0
- package/dist/logger.js.map +1 -0
- package/dist/plans.d.ts +13 -0
- package/dist/plans.d.ts.map +1 -0
- package/dist/plans.js +33 -0
- package/dist/plans.js.map +1 -0
- package/dist/routes/agents.d.ts +6 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +118 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/config.d.ts +6 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +129 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/contracts.d.ts +6 -0
- package/dist/routes/contracts.d.ts.map +1 -0
- package/dist/routes/contracts.js +188 -0
- package/dist/routes/contracts.js.map +1 -0
- package/dist/routes/pipelines.d.ts +6 -0
- package/dist/routes/pipelines.d.ts.map +1 -0
- package/dist/routes/pipelines.js +133 -0
- package/dist/routes/pipelines.js.map +1 -0
- package/dist/routes/projects.d.ts +6 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +220 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/runs.d.ts +6 -0
- package/dist/routes/runs.d.ts.map +1 -0
- package/dist/routes/runs.js +427 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/skills.d.ts +6 -0
- package/dist/routes/skills.d.ts.map +1 -0
- package/dist/routes/skills.js +123 -0
- package/dist/routes/skills.js.map +1 -0
- package/dist/routes/tools.d.ts +6 -0
- package/dist/routes/tools.d.ts.map +1 -0
- package/dist/routes/tools.js +193 -0
- package/dist/routes/tools.js.map +1 -0
- package/dist/routes/users.d.ts +6 -0
- package/dist/routes/users.d.ts.map +1 -0
- package/dist/routes/users.js +152 -0
- package/dist/routes/users.js.map +1 -0
- package/dist/routes/validate.d.ts +6 -0
- package/dist/routes/validate.d.ts.map +1 -0
- package/dist/routes/validate.js +171 -0
- package/dist/routes/validate.js.map +1 -0
- package/dist/routes/webhooks.d.ts +8 -0
- package/dist/routes/webhooks.d.ts.map +1 -0
- package/dist/routes/webhooks.js +102 -0
- package/dist/routes/webhooks.js.map +1 -0
- package/dist/server.d.ts +46 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +101 -0
- package/dist/server.js.map +1 -0
- package/dist/spawners/http-api-spawner.d.ts +10 -0
- package/dist/spawners/http-api-spawner.d.ts.map +1 -0
- package/dist/spawners/http-api-spawner.js +88 -0
- package/dist/spawners/http-api-spawner.js.map +1 -0
- package/dist/user-store-pg.d.ts +21 -0
- package/dist/user-store-pg.d.ts.map +1 -0
- package/dist/user-store-pg.js +97 -0
- package/dist/user-store-pg.js.map +1 -0
- package/dist/user-store.d.ts +29 -0
- package/dist/user-store.d.ts.map +1 -0
- package/dist/user-store.js +97 -0
- package/dist/user-store.js.map +1 -0
- package/dist/utils/repo-resolver.d.ts +3 -0
- package/dist/utils/repo-resolver.d.ts.map +1 -0
- package/dist/utils/repo-resolver.js +3 -0
- package/dist/utils/repo-resolver.js.map +1 -0
- package/dist/webhook-dispatcher.d.ts +13 -0
- package/dist/webhook-dispatcher.d.ts.map +1 -0
- package/dist/webhook-dispatcher.js +108 -0
- package/dist/webhook-dispatcher.js.map +1 -0
- package/dist/webhook-store.d.ts +31 -0
- package/dist/webhook-store.d.ts.map +1 -0
- package/dist/webhook-store.js +91 -0
- package/dist/webhook-store.js.map +1 -0
- package/package.json +59 -0
- package/src/.gitkeep +0 -0
- package/src/api.ts +8 -0
- package/src/bootstrap.ts +259 -0
- package/src/event-bus.ts +64 -0
- package/src/index.ts +58 -0
- package/src/integration-runtime.ts +180 -0
- package/src/integration-store.ts +125 -0
- package/src/integrations/linear/failure-handler.ts +93 -0
- package/src/integrations/linear/webhook-handler.ts +156 -0
- package/src/integrations/registry.ts +12 -0
- package/src/integrations/types.ts +37 -0
- package/src/launcher.ts +214 -0
- package/src/logger.ts +50 -0
- package/src/plans.ts +43 -0
- package/src/routes/agents.ts +131 -0
- package/src/routes/config.ts +154 -0
- package/src/routes/contracts.ts +205 -0
- package/src/routes/pipelines.ts +146 -0
- package/src/routes/projects.ts +237 -0
- package/src/routes/runs.ts +468 -0
- package/src/routes/skills.ts +136 -0
- package/src/routes/tools.ts +222 -0
- package/src/routes/users.ts +169 -0
- package/src/routes/validate.ts +196 -0
- package/src/routes/webhooks.ts +120 -0
- package/src/server.ts +155 -0
- package/src/spawners/http-api-spawner.ts +96 -0
- package/src/user-store-pg.ts +138 -0
- package/src/user-store.ts +125 -0
- package/src/utils/repo-resolver.ts +3 -0
- package/src/webhook-dispatcher.ts +142 -0
- package/src/webhook-store.ts +141 -0
- package/tests/agents.test.ts +164 -0
- package/tests/cancel.test.ts +120 -0
- package/tests/config.test.ts +196 -0
- package/tests/contracts.test.ts +302 -0
- package/tests/event-bus.test.ts +53 -0
- package/tests/http-api-spawner.test.ts +158 -0
- package/tests/integration-runtime.test.ts +199 -0
- package/tests/integration-store.test.ts +66 -0
- package/tests/integrations/linear/failure-handler.test.ts +113 -0
- package/tests/integrations/linear/webhook-handler.test.ts +191 -0
- package/tests/launcher.test.ts +380 -0
- package/tests/linear-webhook.test.ts +390 -0
- package/tests/pipelines.test.ts +166 -0
- package/tests/projects.test.ts +283 -0
- package/tests/runs.test.ts +379 -0
- package/tests/server.test.ts +208 -0
- package/tests/skills.test.ts +149 -0
- package/tests/sse.test.ts +129 -0
- package/tests/tools.test.ts +233 -0
- package/tests/user-store.test.ts +93 -0
- package/tests/users.test.ts +189 -0
- package/tests/utils/repo-resolver.test.ts +105 -0
- package/tests/validate.test.ts +233 -0
- package/tests/webhook-dispatcher.test.ts +214 -0
- package/tests/webhook-store.test.ts +98 -0
- package/tests/webhooks.test.ts +176 -0
- package/tsconfig.json +24 -0
- package/vitest.config.ts +7 -0
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @studio-foundation/api
|
|
2
|
+
|
|
3
|
+
HTTP REST API for Studio. Same engine as the CLI, machine-to-machine interface. Like GitHub is to `git`.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
api wraps the engine in a Fastify server. It handles fire-and-forget pipeline launches, real-time SSE streaming, webhook dispatch, and integration lifecycle (Linear, etc.). The CLI (`studio api start`) is the primary way to run it, but it can also be imported programmatically.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Linear webhook → POST /api/runs → launcher → engine → pipeline run → webhook dispatch
|
|
11
|
+
Slack bot → POST /api/runs ↗
|
|
12
|
+
CI/CD → POST /api/runs ↗
|
|
13
|
+
Dashboard → GET /api/runs/:id/stream (SSE)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Starting the server
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Via CLI (recommended)
|
|
20
|
+
studio api start
|
|
21
|
+
|
|
22
|
+
# Standalone (PM2/systemd)
|
|
23
|
+
STUDIO_CWD=/path/to/project node node_modules/.bin/studio-api
|
|
24
|
+
|
|
25
|
+
# Programmatic
|
|
26
|
+
import { createApi } from '@studio-foundation/api';
|
|
27
|
+
const { server, cleanup } = await createApi({ cwd: '/path/to/project' });
|
|
28
|
+
await server.listen({ port: 3700 });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Configuration
|
|
32
|
+
|
|
33
|
+
The server reads `.studio/config.yaml` from the project directory (or the first `.studio/` found walking up from `STUDIO_CWD`):
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
api:
|
|
37
|
+
key: my-secret-key # Optional — enables Bearer auth. Omit for open local use.
|
|
38
|
+
port: 3700 # Default: 3700
|
|
39
|
+
|
|
40
|
+
db:
|
|
41
|
+
type: postgres # 'sqlite' | 'postgres' | 'inmemory'. Default: 'sqlite'
|
|
42
|
+
url: ${DATABASE_URL} # Required if type is postgres
|
|
43
|
+
|
|
44
|
+
providers:
|
|
45
|
+
anthropic:
|
|
46
|
+
apiKey: ${ANTHROPIC_API_KEY}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Authentication:** If `api.key` is set, all routes require `Authorization: Bearer <key>`. Without a key, the API is open (local use only).
|
|
50
|
+
|
|
51
|
+
## Endpoints
|
|
52
|
+
|
|
53
|
+
### Runs
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
POST /api/runs → Launch a pipeline (fire-and-forget). Returns run ID immediately.
|
|
57
|
+
GET /api/runs → List runs (?status=&limit=)
|
|
58
|
+
GET /api/runs/:id → Run detail
|
|
59
|
+
GET /api/runs/:id/logs → Raw JSONL logs
|
|
60
|
+
GET /api/runs/:id/stream → SSE — live events (?events=csv filter)
|
|
61
|
+
DELETE /api/runs/:id → Cancel a running pipeline
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Project
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
GET /api/projects → Current project (name, id, pipelines_dir)
|
|
68
|
+
GET /api/projects/:id/pipelines → Pipelines for a project
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### CRUD (Pipelines, Agents, Contracts, Skills)
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
GET /api/pipelines → List pipeline names
|
|
75
|
+
GET /api/pipelines/:name → Parsed pipeline (YAML → JSON)
|
|
76
|
+
PUT /api/pipelines/:name → Create or update a pipeline (body: YAML or JSON)
|
|
77
|
+
DELETE /api/pipelines/:name → Delete a pipeline
|
|
78
|
+
|
|
79
|
+
GET /api/agents → List agent names
|
|
80
|
+
GET /api/agents/:name → Parsed agent
|
|
81
|
+
PUT /api/agents/:name → Create or update an agent
|
|
82
|
+
DELETE /api/agents/:name → Delete an agent
|
|
83
|
+
|
|
84
|
+
GET /api/contracts → List contract names
|
|
85
|
+
GET /api/contracts/:name → Parsed contract
|
|
86
|
+
PUT /api/contracts/:name → Create or update a contract
|
|
87
|
+
DELETE /api/contracts/:name → Delete a contract
|
|
88
|
+
|
|
89
|
+
GET /api/skills → List skill names
|
|
90
|
+
GET /api/skills/:name → Skill content (.skill.md)
|
|
91
|
+
PUT /api/skills/:name → Create or update a skill (body: markdown)
|
|
92
|
+
DELETE /api/skills/:name → Delete a skill
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Tools, Config, Validation
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
GET /api/tools → Available tools (YAML plugins + builtins)
|
|
99
|
+
|
|
100
|
+
GET /api/config → Current config (API keys masked)
|
|
101
|
+
PUT /api/config → Update config
|
|
102
|
+
|
|
103
|
+
POST /api/validate → Validate a JSON output against a contract
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Webhooks
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
POST /api/webhooks → Register a webhook (url + events filter)
|
|
110
|
+
GET /api/webhooks → List webhooks
|
|
111
|
+
DELETE /api/webhooks/:id → Delete a webhook
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Swagger UI
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
GET /api/docs → Swagger UI (dev only — disabled in NODE_ENV=production)
|
|
118
|
+
GET /api/docs/json → OpenAPI spec (for client generation)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## SSE streaming
|
|
122
|
+
|
|
123
|
+
Connect to `/api/runs/:id/stream` to receive live events:
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
const es = new EventSource('/api/runs/run-123/stream');
|
|
127
|
+
es.addEventListener('stage_complete', (e) => console.log(JSON.parse(e.data)));
|
|
128
|
+
es.addEventListener('pipeline_complete', (e) => { es.close(); });
|
|
129
|
+
|
|
130
|
+
// Filter to specific event types:
|
|
131
|
+
// GET /api/runs/:id/stream?events=stage_complete,tool_call_complete
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Integrations
|
|
135
|
+
|
|
136
|
+
The API manages integration lifecycle (webhook routing, failure handling). Integrations are configured via `.studio/config.yaml` and declared via `.integration.yaml` files in `.studio/integrations/`.
|
|
137
|
+
|
|
138
|
+
**Linear integration** — drag an issue to "In Progress" → Studio receives the webhook → auto-launches the matching pipeline → posts results as a comment → moves the issue to "Done" on success.
|
|
139
|
+
|
|
140
|
+
## Sub-pipeline spawning
|
|
141
|
+
|
|
142
|
+
The API uses `HttpApiSpawner` — a self-referential `RunSpawner` that calls back into the same API to spawn child runs. This is how `studio_run` tool calls work when the engine is running behind the API.
|
|
143
|
+
|
|
144
|
+
## Bootstrap internals
|
|
145
|
+
|
|
146
|
+
`bootstrap(cwd)` is the composition root:
|
|
147
|
+
1. Finds `.studio/` by walking up from `cwd`
|
|
148
|
+
2. Loads `config.yaml` (with `${ENV_VAR}` substitution)
|
|
149
|
+
3. Creates `RunStore` based on `db.type` (`SQLiteRunStore` | `PgRunStore` | `InMemoryRunStore`)
|
|
150
|
+
4. Creates `ProviderRegistry`, `ToolRegistry` (loads `.tool.yaml` plugins)
|
|
151
|
+
5. Loads Claude Code plugins (`MCPClient` per server)
|
|
152
|
+
6. Creates `HttpApiSpawner`, `PipelineEngine`, `InProcessLauncher`
|
|
153
|
+
7. Creates `WebhookStore`, `IntegrationStore`, `IntegrationRuntime`
|
|
154
|
+
8. Returns `BootstrapResult` passed to `buildServer()`
|
|
155
|
+
|
|
156
|
+
## Rules
|
|
157
|
+
|
|
158
|
+
- **api depends on engine + runner.** It is a composition root, same as cli.
|
|
159
|
+
- **Routes must have complete Swagger schemas** — tags, summary, params, response codes. Without this, routes don't appear in Swagger UI.
|
|
160
|
+
- **The engine is the same.** The API doesn't bypass or wrap the engine — it delegates to `InProcessLauncher`, which calls `PipelineEngine.run()` directly.
|
|
161
|
+
- `studio api start` calls `bootstrap()` then `buildServer()`. The two steps are separate so programmatic users can customize between them.
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { bootstrap } from './bootstrap.js';
|
|
2
|
+
export { buildServer } from './server.js';
|
|
3
|
+
export type { ServerDeps, ApiConfig } from './server.js';
|
|
4
|
+
export type { RunLauncher, LaunchConfig } from './launcher.js';
|
|
5
|
+
export { InProcessLauncher, generateRunId } from './launcher.js';
|
|
6
|
+
export { cloneRepo, resolveRepoPath } from './utils/repo-resolver.js';
|
|
7
|
+
export type { RepoResolveOptions } from './utils/repo-resolver.js';
|
|
8
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Named exports for programmatic use (CLI, tests)
|
|
2
|
+
export { bootstrap } from './bootstrap.js';
|
|
3
|
+
export { buildServer } from './server.js';
|
|
4
|
+
export { InProcessLauncher, generateRunId } from './launcher.js';
|
|
5
|
+
export { cloneRepo, resolveRepoPath } from './utils/repo-resolver.js';
|
|
6
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type AnyRunStore } from '@studio-foundation/engine';
|
|
2
|
+
import { type RunLauncher } from './launcher.js';
|
|
3
|
+
import type { MaskedConfig } from './server.js';
|
|
4
|
+
import { WebhookStore } from './webhook-store.js';
|
|
5
|
+
import { IntegrationStore } from './integration-store.js';
|
|
6
|
+
import { IntegrationRuntime } from './integration-runtime.js';
|
|
7
|
+
import { type PlansConfig } from './plans.js';
|
|
8
|
+
import { UserStore } from './user-store.js';
|
|
9
|
+
import { PgUserStore } from './user-store-pg.js';
|
|
10
|
+
export interface StudioApiConfig {
|
|
11
|
+
providers?: {
|
|
12
|
+
openai?: {
|
|
13
|
+
apiKey: string;
|
|
14
|
+
};
|
|
15
|
+
anthropic?: {
|
|
16
|
+
apiKey: string;
|
|
17
|
+
};
|
|
18
|
+
ollama?: {
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
paths?: {
|
|
23
|
+
projects_dir?: string;
|
|
24
|
+
};
|
|
25
|
+
defaults?: {
|
|
26
|
+
provider?: string;
|
|
27
|
+
model?: string;
|
|
28
|
+
};
|
|
29
|
+
api?: {
|
|
30
|
+
key?: string;
|
|
31
|
+
port?: number;
|
|
32
|
+
};
|
|
33
|
+
integrations?: Record<string, Record<string, unknown>>;
|
|
34
|
+
db?: {
|
|
35
|
+
type?: 'sqlite' | 'postgres' | 'inmemory';
|
|
36
|
+
url?: string;
|
|
37
|
+
};
|
|
38
|
+
plans?: Record<string, {
|
|
39
|
+
runs_per_day?: number;
|
|
40
|
+
max_concurrent?: number;
|
|
41
|
+
max_tokens_per_run?: number;
|
|
42
|
+
rate_limit_per_minute?: number;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
export interface BootstrapResult {
|
|
46
|
+
store: AnyRunStore;
|
|
47
|
+
launcher: RunLauncher;
|
|
48
|
+
configsDir: string;
|
|
49
|
+
/** Raw projects_dir from config (may contain ~). Used by route handlers for repo cloning. */
|
|
50
|
+
projectsDir?: string;
|
|
51
|
+
projectName: string;
|
|
52
|
+
apiConfig: {
|
|
53
|
+
key?: string;
|
|
54
|
+
port?: number;
|
|
55
|
+
};
|
|
56
|
+
cleanup: () => Promise<void>;
|
|
57
|
+
studioVersion: string;
|
|
58
|
+
maskedConfig: MaskedConfig;
|
|
59
|
+
webhookStore: WebhookStore;
|
|
60
|
+
integrationStore: IntegrationStore;
|
|
61
|
+
integrationRuntime: IntegrationRuntime;
|
|
62
|
+
userStore: UserStore | PgUserStore;
|
|
63
|
+
plans: PlansConfig;
|
|
64
|
+
}
|
|
65
|
+
export declare function bootstrap(cwd?: string): Promise<BootstrapResult>;
|
|
66
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AAUnC,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5B,SAAS,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/B,MAAM,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/B,CAAC;IACF,KAAK,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,GAAG,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,EAAE,CAAC,EAAE;QACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;QAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,SAAS,EAAE,SAAS,GAAG,WAAW,CAAC;IACnC,KAAK,EAAE,WAAW,CAAC;CACpB;AAkBD,wBAAsB,SAAS,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuKrF"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// Bootstrap — finds .studio/, loads config, creates engine + store + launcher
|
|
2
|
+
// Same pattern as CLI but without terminal output
|
|
3
|
+
import { resolve, join, dirname } from 'node:path';
|
|
4
|
+
import { access, readFile } from 'node:fs/promises';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import yaml from 'js-yaml';
|
|
7
|
+
import { SQLiteRunStore, InMemoryRunStore, PgRunStore, } from '@studio-foundation/engine';
|
|
8
|
+
import { createDefaultRegistry, ToolRegistry, loadProjectTools, loadPlugins, loadProjectIntegrations, MCPClient, } from '@studio-foundation/runner';
|
|
9
|
+
import { InProcessLauncher } from './launcher.js';
|
|
10
|
+
import { RunEventBus } from './event-bus.js';
|
|
11
|
+
import { WebhookStore } from './webhook-store.js';
|
|
12
|
+
import { WebhookDispatcher } from './webhook-dispatcher.js';
|
|
13
|
+
import { IntegrationStore } from './integration-store.js';
|
|
14
|
+
import { IntegrationRuntime } from './integration-runtime.js';
|
|
15
|
+
import { HttpApiSpawner } from './spawners/http-api-spawner.js';
|
|
16
|
+
import { resolvePlans } from './plans.js';
|
|
17
|
+
import { UserStore } from './user-store.js';
|
|
18
|
+
import { PgUserStore } from './user-store-pg.js';
|
|
19
|
+
async function findStudioDir(startDir) {
|
|
20
|
+
let current = resolve(startDir);
|
|
21
|
+
while (true) {
|
|
22
|
+
const candidate = join(current, '.studio');
|
|
23
|
+
try {
|
|
24
|
+
await access(candidate);
|
|
25
|
+
return candidate;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// not here, go up
|
|
29
|
+
}
|
|
30
|
+
const parent = dirname(current);
|
|
31
|
+
if (parent === current)
|
|
32
|
+
return null;
|
|
33
|
+
current = parent;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function bootstrap(cwd = process.cwd()) {
|
|
37
|
+
const studioDir = await findStudioDir(cwd);
|
|
38
|
+
if (!studioDir) {
|
|
39
|
+
throw new Error(`No .studio/ directory found from ${cwd}. Run 'studio init' first.`);
|
|
40
|
+
}
|
|
41
|
+
// Load config
|
|
42
|
+
let config = {};
|
|
43
|
+
try {
|
|
44
|
+
const raw = await readFile(join(studioDir, 'config.yaml'), 'utf-8');
|
|
45
|
+
// Resolve env vars
|
|
46
|
+
const resolved = raw.replace(/\$\{([^}]+)\}/g, (_m, v) => process.env[v.trim()] ?? '');
|
|
47
|
+
config = yaml.load(resolved) ?? {};
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// No config.yaml — use defaults
|
|
51
|
+
}
|
|
52
|
+
// Read studio version from api/package.json
|
|
53
|
+
const pkgPath = fileURLToPath(new URL('../package.json', import.meta.url));
|
|
54
|
+
const pkgRaw = await readFile(pkgPath, 'utf-8');
|
|
55
|
+
const studioVersion = JSON.parse(pkgRaw).version;
|
|
56
|
+
// Build masked config — provider names only, no API keys
|
|
57
|
+
const maskedConfig = {
|
|
58
|
+
defaults: config.defaults,
|
|
59
|
+
providers: Object.keys(config.providers ?? {}),
|
|
60
|
+
};
|
|
61
|
+
const runsDir = join(studioDir, 'runs');
|
|
62
|
+
const dbType = config.db?.type ?? 'sqlite';
|
|
63
|
+
// WebhookStore and IntegrationStore are always SQLite — they are separate from RunStore
|
|
64
|
+
const dbPath = join(studioDir, 'runs', 'runs.db');
|
|
65
|
+
let store;
|
|
66
|
+
if (dbType === 'postgres') {
|
|
67
|
+
const url = config.db?.url;
|
|
68
|
+
if (!url)
|
|
69
|
+
throw new Error('db.url is required when db.type is postgres');
|
|
70
|
+
store = new PgRunStore(url);
|
|
71
|
+
}
|
|
72
|
+
else if (dbType === 'inmemory') {
|
|
73
|
+
store = new InMemoryRunStore();
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
store = new SQLiteRunStore(dbPath);
|
|
77
|
+
}
|
|
78
|
+
// UserStore — same DB as run store
|
|
79
|
+
let userStore;
|
|
80
|
+
if (dbType === 'postgres') {
|
|
81
|
+
const url = config.db?.url;
|
|
82
|
+
if (!url)
|
|
83
|
+
throw new Error('db.url is required when db.type is postgres');
|
|
84
|
+
userStore = new PgUserStore(url);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
userStore = new UserStore(dbPath);
|
|
88
|
+
}
|
|
89
|
+
const plans = resolvePlans(config.plans);
|
|
90
|
+
const providerRegistry = createDefaultRegistry({
|
|
91
|
+
openai: config.providers?.openai ? { apiKey: config.providers.openai.apiKey } : undefined,
|
|
92
|
+
anthropic: config.providers?.anthropic ? { apiKey: config.providers.anthropic.apiKey } : undefined,
|
|
93
|
+
ollama: config.providers?.ollama ? { baseUrl: config.providers.ollama.baseUrl } : undefined,
|
|
94
|
+
});
|
|
95
|
+
const toolsDir = join(studioDir, 'tools');
|
|
96
|
+
const loadedPlugins = await loadProjectTools(toolsDir, cwd);
|
|
97
|
+
const toolRegistry = new ToolRegistry();
|
|
98
|
+
for (const plugin of loadedPlugins) {
|
|
99
|
+
toolRegistry.registerPlugin(plugin.name, plugin.tools, plugin.promptSnippet);
|
|
100
|
+
}
|
|
101
|
+
// Load MCP plugins
|
|
102
|
+
const pluginsDir = join(studioDir, 'plugins');
|
|
103
|
+
const pluginManifests = await loadPlugins(pluginsDir);
|
|
104
|
+
const mcpClients = [];
|
|
105
|
+
const pluginSkills = {};
|
|
106
|
+
for (const manifest of pluginManifests) {
|
|
107
|
+
for (const [serverName, serverDef] of Object.entries(manifest.mcpServers)) {
|
|
108
|
+
const client = new MCPClient(manifest.name, serverName, serverDef);
|
|
109
|
+
try {
|
|
110
|
+
await client.start();
|
|
111
|
+
const mcpTools = await client.getTools();
|
|
112
|
+
toolRegistry.registerPlugin(`${manifest.name}-${serverName}`, mcpTools);
|
|
113
|
+
mcpClients.push(client);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Plugin failed to start — skip silently for API
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (manifest.skills.length > 0) {
|
|
120
|
+
pluginSkills[manifest.name] = manifest.skills.map((s) => `## Skill: ${s.name}\n\n${s.content}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Self-referential spawner: allows pipelines to spawn child runs via the API
|
|
124
|
+
// Must match DEFAULT_PORT in index.ts (3700) — was 3000 which collides with common dev servers
|
|
125
|
+
const apiPort = config.api?.port ?? 3700;
|
|
126
|
+
const spawner = new HttpApiSpawner(`http://localhost:${apiPort}`, config.api?.key);
|
|
127
|
+
const engineConfig = {
|
|
128
|
+
configsDir: studioDir,
|
|
129
|
+
providerRegistry,
|
|
130
|
+
toolRegistry,
|
|
131
|
+
db: store,
|
|
132
|
+
pluginSkills,
|
|
133
|
+
spawner,
|
|
134
|
+
maxDepth: 3,
|
|
135
|
+
defaultProvider: config.defaults?.provider,
|
|
136
|
+
defaultModel: config.defaults?.model,
|
|
137
|
+
};
|
|
138
|
+
const bus = new RunEventBus();
|
|
139
|
+
const launcher = new InProcessLauncher(engineConfig, store, runsDir, bus);
|
|
140
|
+
// Derive project name from the directory containing .studio/
|
|
141
|
+
const projectName = studioDir.split('/').slice(-2, -1)[0] ?? 'studio-project';
|
|
142
|
+
const webhookStore = new WebhookStore(dbPath);
|
|
143
|
+
const integrationStore = new IntegrationStore(dbPath);
|
|
144
|
+
const integrationsDir = join(studioDir, 'integrations');
|
|
145
|
+
const loadedIntegrations = await loadProjectIntegrations(integrationsDir);
|
|
146
|
+
const integrationConfigs = (config.integrations ?? {});
|
|
147
|
+
const integrationRuntime = new IntegrationRuntime({
|
|
148
|
+
integrations: loadedIntegrations,
|
|
149
|
+
store: integrationStore,
|
|
150
|
+
launcher,
|
|
151
|
+
configsDir: studioDir,
|
|
152
|
+
projectsDir: config.paths?.projects_dir,
|
|
153
|
+
apiConfig: config.api ?? {},
|
|
154
|
+
integrationConfigs,
|
|
155
|
+
});
|
|
156
|
+
integrationRuntime.setupEventBus(bus);
|
|
157
|
+
const webhookDispatcher = new WebhookDispatcher(webhookStore, projectName);
|
|
158
|
+
bus.subscribeAll((runId, event) => {
|
|
159
|
+
void webhookDispatcher.handleBusEvent(runId, event.type, event.data);
|
|
160
|
+
});
|
|
161
|
+
return {
|
|
162
|
+
store,
|
|
163
|
+
launcher,
|
|
164
|
+
configsDir: studioDir,
|
|
165
|
+
projectsDir: config.paths?.projects_dir,
|
|
166
|
+
projectName,
|
|
167
|
+
apiConfig: config.api ?? {},
|
|
168
|
+
studioVersion,
|
|
169
|
+
maskedConfig,
|
|
170
|
+
webhookStore,
|
|
171
|
+
integrationStore,
|
|
172
|
+
integrationRuntime,
|
|
173
|
+
userStore,
|
|
174
|
+
plans,
|
|
175
|
+
cleanup: async () => {
|
|
176
|
+
for (const client of mcpClients) {
|
|
177
|
+
try {
|
|
178
|
+
await client.close();
|
|
179
|
+
}
|
|
180
|
+
catch { /* ignore */ }
|
|
181
|
+
}
|
|
182
|
+
if ('close' in store && typeof store.close === 'function') {
|
|
183
|
+
await store.close();
|
|
184
|
+
}
|
|
185
|
+
if (userStore && 'close' in userStore && typeof userStore.close === 'function') {
|
|
186
|
+
await userStore.close();
|
|
187
|
+
}
|
|
188
|
+
webhookStore.close();
|
|
189
|
+
integrationStore.close();
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kDAAkD;AAElD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAEL,cAAc,EACd,gBAAgB,EAChB,UAAU,GAEX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,SAAS,GAEV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAoB,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAoB,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA0CjD,KAAK,UAAU,aAAa,CAAC,QAAgB;IAC3C,IAAI,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;YACxB,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACzD,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,4BAA4B,CAAC,CAAC;IACvF,CAAC;IAED,cAAc;IACd,IAAI,MAAM,GAAoB,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;QACpE,mBAAmB;QACnB,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACvG,MAAM,GAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAqB,IAAI,EAAE,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;IAED,4CAA4C;IAC5C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAyB,CAAC,OAAO,CAAC;IAE1E,yDAAyD;IACzD,MAAM,YAAY,GAAG;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;KAC/C,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,IAAI,IAAI,QAAQ,CAAC;IAE3C,wFAAwF;IACxF,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAElD,IAAI,KAAkB,CAAC;IACvB,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACzE,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;SAAM,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,KAAK,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,mCAAmC;IACnC,IAAI,SAAkC,CAAC;IACvC,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACzE,SAAS,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,KAAoE,CAAC,CAAC;IAExG,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;QAC7C,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;QACzF,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;QAClG,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS;KAC5F,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACxC,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,YAAY,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAC/E,CAAC;IAED,mBAAmB;IACnB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,UAAU,GAAqC,EAAE,CAAC;IACxD,MAAM,YAAY,GAA6B,EAAE,CAAC;IAElD,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YACnE,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBACrB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACzC,YAAY,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAC;gBACxE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACP,iDAAiD;YACnD,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAC/C,CAAC,CAAe,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,CAC3D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,+FAA+F;IAC/F,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,oBAAoB,OAAO,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAEnF,MAAM,YAAY,GAAiB;QACjC,UAAU,EAAE,SAAS;QACrB,gBAAgB;QAChB,YAAY;QACZ,EAAE,EAAE,KAAK;QACT,YAAY;QACZ,OAAO;QACP,QAAQ,EAAE,CAAC;QACX,eAAe,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ;QAC1C,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK;KACrC,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAE1E,6DAA6D;IAC7D,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC;IAE9E,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACxD,MAAM,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,eAAe,CAAC,CAAC;IAC1E,MAAM,kBAAkB,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAA4C,CAAC;IAClG,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,CAAC;QAChD,YAAY,EAAE,kBAAkB;QAChC,KAAK,EAAE,gBAAgB;QACvB,QAAQ;QACR,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,MAAM,CAAC,KAAK,EAAE,YAAY;QACvC,SAAS,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;QAC3B,kBAAkB;KACnB,CAAC,CAAC;IACH,kBAAkB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAC3E,GAAG,CAAC,YAAY,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAChC,KAAK,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK;QACL,QAAQ;QACR,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,MAAM,CAAC,KAAK,EAAE,YAAY;QACvC,WAAW;QACX,SAAS,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;QAC3B,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,gBAAgB;QAChB,kBAAkB;QAClB,SAAS;QACT,KAAK;QACL,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;gBAChC,IAAI,CAAC;oBAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YACtD,CAAC;YACD,IAAI,OAAO,IAAI,KAAK,IAAI,OAAQ,KAAiD,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;gBACvG,MAAO,KAAyD,CAAC,KAAK,EAAE,CAAC;YAC3E,CAAC;YACD,IAAI,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;gBAC/E,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YAC1B,CAAC;YACD,YAAY,CAAC,KAAK,EAAE,CAAC;YACrB,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type SseEventType = 'pipeline_start' | 'stage_start' | 'stage_complete' | 'stage_retry' | 'group_start' | 'group_iteration' | 'group_feedback' | 'group_complete' | 'pipeline_complete' | 'pipeline_cancelled' | 'stage_context' | 'tool_call_start' | 'tool_call_complete' | 'done';
|
|
2
|
+
export interface BusEvent {
|
|
3
|
+
type: SseEventType;
|
|
4
|
+
data: unknown;
|
|
5
|
+
}
|
|
6
|
+
export type BusListener = (event: BusEvent) => void;
|
|
7
|
+
export type GlobalBusListener = (runId: string, event: BusEvent) => void;
|
|
8
|
+
export declare class RunEventBus {
|
|
9
|
+
private subs;
|
|
10
|
+
private globalListeners;
|
|
11
|
+
subscribe(runId: string, listener: BusListener): () => void;
|
|
12
|
+
subscribeAll(listener: GlobalBusListener): () => void;
|
|
13
|
+
emit(runId: string, type: SseEventType, data: unknown): void;
|
|
14
|
+
close(runId: string): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=event-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,eAAe,GACf,iBAAiB,GACjB,oBAAoB,GACpB,MAAM,CAAC;AAEX,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;AACpD,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;AAEzE,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAuC;IACnD,OAAO,CAAC,eAAe,CAAgC;IAEvD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,MAAM,IAAI;IAW3D,YAAY,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAOrD,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAa5D,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAI3B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export class RunEventBus {
|
|
2
|
+
subs = new Map();
|
|
3
|
+
globalListeners = new Set();
|
|
4
|
+
subscribe(runId, listener) {
|
|
5
|
+
if (!this.subs.has(runId)) {
|
|
6
|
+
this.subs.set(runId, new Set());
|
|
7
|
+
}
|
|
8
|
+
this.subs.get(runId).add(listener);
|
|
9
|
+
return () => {
|
|
10
|
+
this.subs.get(runId)?.delete(listener);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
// Global subscription — receives all events across all runs
|
|
14
|
+
subscribeAll(listener) {
|
|
15
|
+
this.globalListeners.add(listener);
|
|
16
|
+
return () => {
|
|
17
|
+
this.globalListeners.delete(listener);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
emit(runId, type, data) {
|
|
21
|
+
const event = { type, data };
|
|
22
|
+
const listeners = this.subs.get(runId);
|
|
23
|
+
if (listeners) {
|
|
24
|
+
for (const listener of listeners) {
|
|
25
|
+
listener(event);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (const listener of this.globalListeners) {
|
|
29
|
+
listener(runId, event);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
close(runId) {
|
|
33
|
+
this.emit(runId, 'done', {});
|
|
34
|
+
this.subs.delete(runId);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=event-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAwBA,MAAM,OAAO,WAAW;IACd,IAAI,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC3C,eAAe,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEvD,SAAS,CAAC,KAAa,EAAE,QAAqB;QAC5C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC,CAAC;IACJ,CAAC;IAED,4DAA4D;IAC5D,YAAY,CAAC,QAA2B;QACtC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAa,EAAE,IAAkB,EAAE,IAAa;QACnD,MAAM,KAAK,GAAa,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QACD,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Standalone entrypoint for @studio/api
|
|
3
|
+
// PM2: pm2 start node_modules/.bin/studio-api --env STUDIO_CWD=/path/to/project
|
|
4
|
+
// systemd: ExecStart=/usr/bin/node /path/to/api/dist/index.js
|
|
5
|
+
import { bootstrap } from './bootstrap.js';
|
|
6
|
+
import { buildServer } from './server.js';
|
|
7
|
+
const DEFAULT_PORT = 3700;
|
|
8
|
+
async function main() {
|
|
9
|
+
const cwd = process.env['STUDIO_CWD'] ?? process.cwd();
|
|
10
|
+
let result;
|
|
11
|
+
try {
|
|
12
|
+
result = await bootstrap(cwd);
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error('Bootstrap failed:', err instanceof Error ? err.message : String(err));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const { store, launcher, configsDir, projectName, apiConfig, cleanup, studioVersion, maskedConfig, webhookStore, integrationStore, integrationRuntime, userStore, plans } = result;
|
|
19
|
+
const port = apiConfig.port ?? DEFAULT_PORT;
|
|
20
|
+
let hasUsers = false;
|
|
21
|
+
try {
|
|
22
|
+
// listUsers() is sync on UserStore and async on PgUserStore; await handles both
|
|
23
|
+
const users = await userStore.listUsers();
|
|
24
|
+
hasUsers = users.length > 0;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// DB unavailable at startup — default to open/dev mode
|
|
28
|
+
}
|
|
29
|
+
const server = buildServer({ store, launcher, configsDir, projectName, apiConfig, studioVersion, maskedConfig, webhookStore, integrationStore, integrationRuntime, userStore, plans, hasUsers });
|
|
30
|
+
// Graceful shutdown
|
|
31
|
+
const shutdown = async () => {
|
|
32
|
+
await server.close();
|
|
33
|
+
await cleanup();
|
|
34
|
+
process.exit(0);
|
|
35
|
+
};
|
|
36
|
+
process.on('SIGTERM', () => void shutdown());
|
|
37
|
+
process.on('SIGINT', () => void shutdown());
|
|
38
|
+
try {
|
|
39
|
+
await server.listen({ port, host: '0.0.0.0' });
|
|
40
|
+
console.log(`Studio API listening on port ${port}`);
|
|
41
|
+
if (!apiConfig.key) {
|
|
42
|
+
console.log('Warning: no api.key configured — running without auth');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error('Failed to start server:', err);
|
|
47
|
+
await cleanup();
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
void main();
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,wCAAwC;AACxC,gFAAgF;AAChF,8DAA8D;AAE9D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEvD,IAAI,MAA6C,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IACnL,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,YAAY,CAAC;IAE5C,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC;QACH,gFAAgF;QAChF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,EAAE,CAAC;QAC1C,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEjM,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,OAAO,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;QAC9C,MAAM,OAAO,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type { IntegrationPluginDef } from '@studio-foundation/contracts';
|
|
3
|
+
import type { IntegrationStore } from './integration-store.js';
|
|
4
|
+
import type { RunLauncher } from './launcher.js';
|
|
5
|
+
import type { RunEventBus } from './event-bus.js';
|
|
6
|
+
import type { ApiConfig } from './server.js';
|
|
7
|
+
export interface IntegrationRuntimeDeps {
|
|
8
|
+
integrations: IntegrationPluginDef[];
|
|
9
|
+
store: IntegrationStore;
|
|
10
|
+
launcher: RunLauncher;
|
|
11
|
+
configsDir: string;
|
|
12
|
+
projectsDir?: string;
|
|
13
|
+
apiConfig: ApiConfig;
|
|
14
|
+
integrationConfigs: Record<string, Record<string, unknown>>;
|
|
15
|
+
}
|
|
16
|
+
export declare class IntegrationRuntime {
|
|
17
|
+
private deps;
|
|
18
|
+
constructor(deps: IntegrationRuntimeDeps);
|
|
19
|
+
setupEventBus(bus: RunEventBus): void;
|
|
20
|
+
registerRoutes(fastify: FastifyInstance, prefix: string): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=integration-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-runtime.d.ts","sourceRoot":"","sources":["../src/integration-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC7D;AAED,qBAAa,kBAAkB;IACjB,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,sBAAsB;IAEhD,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAiCrC,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CA0H/D"}
|