@unispechq/unispec-platform 0.1.4 → 0.2.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.
package/README.md CHANGED
@@ -92,12 +92,27 @@ Options:
92
92
  ### `unispec dev`
93
93
  Local orchestrator mode.
94
94
 
95
+ Serves:
96
+
97
+ - `GET /` — embedded UI (reads `/unispec.json` in the browser)
98
+ - `GET /unispec.json` — aggregated snapshot
99
+ - `GET /health` — healthcheck
100
+ - `GET /workspace.json` — workspace info (enabled when config path is known)
101
+ - `GET /workspace/state` — workspace state (stored in `.unispec/workspace.json`)
102
+ - `PUT /workspace/state` — replace workspace state
103
+ - `POST /tests/run` — run workspace tests (suite/flow)
104
+
95
105
  Options:
96
106
 
97
107
  - `--config <path>` — path to config file (default: `unispec.config.json|yaml|yml`)
98
108
  - `--host <host>` — bind host (default: `127.0.0.1`)
99
109
  - `--port <port>` — bind port (default: `4141`)
100
110
  - `--watch` — watch config/spec files and refresh aggregated snapshot
111
+ - `--ui` / `--no-ui` — enable/disable embedded UI at `/` (default: enabled)
112
+ - `--ui-dev <url>` — proxy UI requests to an external dev server (e.g. Next.js) for HMR
113
+ - `--portal` — spawn portal server from an installed dependency and proxy UI to it
114
+ - `--portal-port <port>` — port for portal server (default: `3000`)
115
+ - `--portal-package <name>` — portal package name (default: `@unispechq/unispec-portal`)
101
116
 
102
117
  Planned responsibilities:
103
118
 
@@ -121,6 +136,10 @@ Endpoints:
121
136
 
122
137
  - `GET /health` -> `OK`
123
138
  - `GET /unispec.json` -> aggregated JSON
139
+ - `GET /workspace.json` -> workspace info (paths + API URLs)
140
+ - `GET /workspace/state` -> workspace state
141
+ - `PUT /workspace/state` -> save workspace state
142
+ - `POST /tests/run` -> run tests (suite flow)
124
143
 
125
144
  Aggregation format (A):
126
145
 
@@ -143,12 +162,6 @@ If at least one service is invalid, `/unispec.json` responds with status `422` a
143
162
 
144
163
  ### Example
145
164
 
146
- Create `unispec.config.json` (see `unispec.config.example.json`):
147
-
148
- ```bash
149
- cp unispec.config.example.json unispec.config.json
150
- ```
151
-
152
165
  Start the server:
153
166
 
154
167
  ```bash
@@ -165,6 +178,129 @@ Then open:
165
178
 
166
179
  - `http://127.0.0.1:4141/health`
167
180
  - `http://127.0.0.1:4141/unispec.json`
181
+ - `http://127.0.0.1:4141/`
182
+
183
+ ### `unispec start`
184
+ Production-like server mode.
185
+
186
+ `unispec start` runs the same HTTP surface as `unispec dev`, but is intended for long-running use.
187
+
188
+ Options:
189
+
190
+ - `--config <path>` — path to config file
191
+ - `--host <host>` — bind host (default: `127.0.0.1`)
192
+ - `--port <port>` — bind port (default: `4141`)
193
+ - `--ui` / `--no-ui` — enable/disable embedded UI
194
+ - `--ui-url <url>` — proxy UI requests to an external UI server
195
+ - `--portal` — spawn portal server (SSR) from an installed dependency and proxy UI to it
196
+ - `--portal-port <port>` — port for portal server (default: `3000`)
197
+ - `--portal-package <name>` — portal package name (default: `@unispechq/unispec-portal`)
198
+
199
+ ### Portal package contract
200
+
201
+ When using `--portal`, the portal package is expected to provide a single runnable `bin` entry which supports:
202
+
203
+ - `--port <port>`
204
+ - `--mode dev|start`
205
+
206
+ Example:
207
+
208
+ ```bash
209
+ unispec-portal --mode dev --port 3000
210
+ unispec-portal --mode start --port 3000
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Workspace layer
216
+
217
+ Workspace data is stored in `.unispec/workspace.json` next to your config file. This file is not part of UniSpec.
218
+
219
+ ### Workspace endpoints
220
+
221
+ - `GET /workspace.json` — info for clients (mode, configPath, storage paths, and API URLs)
222
+ - `GET /workspace/state` — workspace state JSON
223
+ - `PUT /workspace/state` — replace workspace state JSON (atomic write)
224
+
225
+ ### Endpoint IDs
226
+
227
+ Workspace entities reference endpoints using:
228
+
229
+ ```
230
+ {serviceName}:{METHOD}:{path}
231
+ ```
232
+
233
+ Example:
234
+
235
+ ```
236
+ users:GET:/users
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Workspace tests
242
+
243
+ Tests are stored in workspace state as YAML or JSON strings and can be run through:
244
+
245
+ - `POST /tests/run` with `{ "suiteId": "..." }` or `{ "testIds": ["..."] }`
246
+
247
+ ### YAML/JSON test format (single request)
248
+
249
+ ```yaml
250
+ request:
251
+ method: GET
252
+ url: "http://127.0.0.1:4141/health"
253
+ expect:
254
+ status: 200
255
+ bodyContains: "OK"
256
+ ```
257
+
258
+ ### Multi-step tests (flow)
259
+
260
+ ```yaml
261
+ steps:
262
+ - name: health
263
+ request:
264
+ method: GET
265
+ url: "http://127.0.0.1:4141/health"
266
+ expect:
267
+ status: 200
268
+ bodyContains: "OK"
269
+ extract:
270
+ st:
271
+ from: status
272
+
273
+ - name: unispec
274
+ request:
275
+ method: GET
276
+ url: "http://127.0.0.1:4141/unispec.json"
277
+ expect:
278
+ status: 200
279
+ jsonContains:
280
+ version: 1
281
+ ```
282
+
283
+ ### Variables and interpolation
284
+
285
+ You can extract variables and use them with `{{var}}` in URL/headers/body:
286
+
287
+ ```yaml
288
+ steps:
289
+ - request:
290
+ method: GET
291
+ url: "https://example.com/api/session"
292
+ extract:
293
+ token:
294
+ from: json
295
+ path: "$.token"
296
+ - request:
297
+ method: GET
298
+ url: "https://example.com/api/me"
299
+ headers:
300
+ authorization: "Bearer {{token}}"
301
+ expect:
302
+ status: 200
303
+ ```
168
304
 
169
305
  ---
170
306
 
@@ -215,8 +351,6 @@ npm run start -- --help
215
351
 
216
352
  Contributions are welcome.
217
353
 
218
- Please read `windsurfrules.yml` before making changes.
219
-
220
354
  ---
221
355
 
222
356
  ## License
package/dist/cli.js CHANGED
@@ -1,12 +1,34 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
- import { registerConvertCommand, registerDevCommand, registerDiffCommand, registerNormalizeCommand, registerValidateCommand, } from "./commands/index.js";
3
+ import { registerConvertCommand, registerDevCommand, registerDiffCommand, registerNormalizeCommand, registerStartCommand, registerValidateCommand, } from "./commands/index.js";
4
4
  function errorToJson(err, includeStack) {
5
5
  const message = err instanceof Error ? err.message : String(err);
6
6
  const code = err instanceof Error && "code" in err ? String(err.code) : undefined;
7
7
  const stack = includeStack && err instanceof Error ? err.stack : undefined;
8
8
  return { error: { message, ...(code ? { code } : {}), ...(stack ? { stack } : {}) } };
9
9
  }
10
+ function normalizeGlobalOptionsArgv(argv) {
11
+ if (argv.length <= 2)
12
+ return argv;
13
+ const head = argv.slice(0, 2);
14
+ const rest = argv.slice(2);
15
+ const globalNoValue = new Set(["--verbose", "--json-errors", "--quiet", "-q"]);
16
+ const extracted = [];
17
+ const remaining = [];
18
+ for (let i = 0; i < rest.length; i++) {
19
+ const a = rest[i];
20
+ if (a === "--") {
21
+ remaining.push(...rest.slice(i));
22
+ break;
23
+ }
24
+ if (globalNoValue.has(a)) {
25
+ extracted.push(a);
26
+ continue;
27
+ }
28
+ remaining.push(a);
29
+ }
30
+ return [...head, ...extracted, ...remaining];
31
+ }
10
32
  const program = new Command();
11
33
  program
12
34
  .name("unispec")
@@ -20,7 +42,8 @@ registerNormalizeCommand(program);
20
42
  registerDiffCommand(program);
21
43
  registerConvertCommand(program);
22
44
  registerDevCommand(program);
23
- program.parseAsync(process.argv).catch((err) => {
45
+ registerStartCommand(program);
46
+ program.parseAsync(normalizeGlobalOptionsArgv(process.argv)).catch((err) => {
24
47
  const opts = program.opts();
25
48
  const verbose = opts.verbose ?? false;
26
49
  const jsonErrors = opts["jsonErrors"] ?? opts["json-errors"] ?? false;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,SAAS,WAAW,CAAC,GAAY,EAAE,YAAqB;IACtD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAE,GAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3F,MAAM,KAAK,GAAG,YAAY,IAAI,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3E,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;AACxF,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,oCAAoC,CAAC;KACjD,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,aAAa,EAAE,+BAA+B,CAAC;KACtD,MAAM,CAAC,WAAW,EAAE,2CAA2C,CAAC;KAChE,MAAM,CAAC,eAAe,EAAE,iCAAiC,CAAC,CAAC;AAE9D,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAClC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAE5B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAiD,CAAC;IAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACtC,MAAM,UAAU,GAAI,IAAY,CAAC,YAAY,CAAC,IAAK,IAAY,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;IAExF,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAClF,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+GzD"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiFzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgLzD"}
@@ -1,9 +1,64 @@
1
+ import { spawn } from "node:child_process";
1
2
  import { watch } from "node:fs";
2
- import { resolve } from "node:path";
3
+ import { dirname, isAbsolute, join, resolve } from "node:path";
4
+ import { createRequire } from "node:module";
5
+ import { readFile } from "node:fs/promises";
3
6
  import { loadConfig } from "../config/loadConfig.js";
4
7
  import { findConfigPath } from "../config/loadConfig.js";
5
8
  import { aggregateFromConfig } from "../dev/aggregate.js";
6
9
  import { startDevServer } from "../dev/server.js";
10
+ function resolveConfigSpecPaths(config, baseDir) {
11
+ if (!baseDir)
12
+ return config;
13
+ const services = Array.isArray(config.services) ? config.services : [];
14
+ return {
15
+ ...config,
16
+ services: services.map((s) => {
17
+ const spec = String(s?.spec ?? "");
18
+ const resolvedSpec = spec && !isAbsolute(spec) ? resolve(baseDir, spec) : spec;
19
+ return {
20
+ ...s,
21
+ spec: resolvedSpec,
22
+ };
23
+ }),
24
+ };
25
+ }
26
+ async function resolvePortalBin(portalPackage) {
27
+ const require = createRequire(import.meta.url);
28
+ const pkgJsonPath = require.resolve(`${portalPackage}/package.json`);
29
+ const pkgDir = dirname(pkgJsonPath);
30
+ const pkgRaw = await readFile(pkgJsonPath, "utf8");
31
+ const pkg = JSON.parse(pkgRaw);
32
+ if (!pkg.bin) {
33
+ return null;
34
+ }
35
+ if (typeof pkg.bin === "string") {
36
+ return { binPath: join(pkgDir, pkg.bin), binName: portalPackage };
37
+ }
38
+ const entries = Object.entries(pkg.bin);
39
+ if (entries.length === 0) {
40
+ return null;
41
+ }
42
+ const preferred = entries.find(([name]) => name.includes("dev")) ?? entries[0];
43
+ return { binPath: join(pkgDir, preferred[1]), binName: preferred[0] };
44
+ }
45
+ async function spawnPortalDevServer(options) {
46
+ const resolved = await resolvePortalBin(options.portalPackage);
47
+ if (!resolved) {
48
+ throw new Error(`Portal package '${options.portalPackage}' does not expose a runnable bin. Expected a package.json "bin" entry.`);
49
+ }
50
+ const args = [resolved.binPath, "--port", String(options.port)];
51
+ const child = spawn(process.execPath, args, {
52
+ stdio: options.verbose ? "inherit" : "ignore",
53
+ env: { ...process.env, PORT: String(options.port) },
54
+ });
55
+ child.once("exit", (code) => {
56
+ if (options.verbose) {
57
+ process.stderr.write(`Portal dev server exited with code ${code ?? "null"}\n`);
58
+ }
59
+ });
60
+ return child;
61
+ }
7
62
  export function registerDevCommand(program) {
8
63
  program
9
64
  .command("dev")
@@ -12,6 +67,14 @@ export function registerDevCommand(program) {
12
67
  .option("--host <host>", "Host to bind", "127.0.0.1")
13
68
  .option("--port <port>", "Port to bind", "4141")
14
69
  .option("--watch", "Watch config/spec files and refresh aggregated snapshot")
70
+ .option("--ui", "Serve embedded UI at /", true)
71
+ .option("--no-ui", "Disable embedded UI")
72
+ .option("--ui-dev <url>", "Proxy UI requests to an external dev server (e.g. Next.js)")
73
+ .option("--portal", "Spawn portal server and proxy UI to it")
74
+ .option("--portal-port <port>", "Port for portal server", "3000")
75
+ .option("--portal-dev", "Spawn portal dev server from an installed dependency and proxy UI to it")
76
+ .option("--portal-dev-port <port>", "Port for portal dev server")
77
+ .option("--portal-package <name>", "Portal package name", "@unispechq/unispec-portal")
15
78
  .action(async function (options) {
16
79
  const parentOpts = this.parent?.opts?.();
17
80
  const verbose = parentOpts?.verbose ?? false;
@@ -19,9 +82,12 @@ export function registerDevCommand(program) {
19
82
  const port = Number(options.port ?? 4141);
20
83
  let snapshot;
21
84
  let snapshotError;
85
+ const configPath = await findConfigPath({ explicitPath: options.config });
86
+ const configDir = configPath ? dirname(configPath) : undefined;
87
+ const workspaceDir = configDir ? join(configDir, ".unispec") : undefined;
22
88
  const loadAndAggregate = async () => {
23
89
  const config = await loadConfig({ explicitPath: options.config });
24
- const cfg = config ?? { version: 1, services: [] };
90
+ const cfg = resolveConfigSpecPaths(config ?? { version: 1, services: [] }, configDir);
25
91
  return aggregateFromConfig(cfg);
26
92
  };
27
93
  const refreshSnapshot = async () => {
@@ -43,7 +109,7 @@ export function registerDevCommand(program) {
43
109
  await refreshSnapshot();
44
110
  const getConfig = async () => {
45
111
  const config = await loadConfig({ explicitPath: options.config });
46
- return config ?? { version: 1, services: [] };
112
+ return resolveConfigSpecPaths(config ?? { version: 1, services: [] }, configDir);
47
113
  };
48
114
  const getAggregated = async () => {
49
115
  if (snapshot) {
@@ -65,13 +131,45 @@ export function registerDevCommand(program) {
65
131
  }
66
132
  return loadAndAggregate();
67
133
  };
134
+ let portalChild;
135
+ let uiDevUrl = options.uiDev;
136
+ const portalEnabled = options.portalDev || options.portal;
137
+ const portalPortRaw = options.portalDevPort ?? options.portalPort;
138
+ if (portalEnabled) {
139
+ if (uiDevUrl) {
140
+ throw new Error("--portal cannot be used together with --ui-dev");
141
+ }
142
+ const portalPort = Number(portalPortRaw ?? 3000);
143
+ const portalPackage = String(options.portalPackage ?? "@unispechq/unispec-portal");
144
+ uiDevUrl = `http://127.0.0.1:${portalPort}`;
145
+ try {
146
+ portalChild = await spawnPortalDevServer({ portalPackage, port: portalPort, verbose });
147
+ const stop = () => {
148
+ try {
149
+ portalChild?.kill("SIGINT");
150
+ }
151
+ catch {
152
+ // ignore
153
+ }
154
+ };
155
+ process.once("SIGINT", stop);
156
+ process.once("SIGTERM", stop);
157
+ process.once("exit", stop);
158
+ if (verbose) {
159
+ process.stderr.write(`Spawned portal server (${portalPackage}) at ${uiDevUrl}\n`);
160
+ }
161
+ }
162
+ catch (err) {
163
+ const message = err instanceof Error ? err.message : String(err);
164
+ throw new Error(`Failed to start portal dev server: ${message}`);
165
+ }
166
+ }
68
167
  if (options.watch) {
69
- const configPath = await findConfigPath({ explicitPath: options.config });
70
168
  const cfg = await getConfig();
71
169
  const serviceSpecs = Array.isArray(cfg.services) ? cfg.services.map((s) => String(s.spec ?? "")) : [];
72
170
  const watchTargets = [
73
171
  ...(configPath ? [configPath] : []),
74
- ...serviceSpecs.filter(Boolean).map((p) => resolve(process.cwd(), p)),
172
+ ...serviceSpecs.filter(Boolean).map((p) => (isAbsolute(p) ? p : resolve(process.cwd(), p))),
75
173
  ];
76
174
  let timer;
77
175
  const scheduleRefresh = () => {
@@ -102,6 +200,11 @@ export function registerDevCommand(program) {
102
200
  getConfig,
103
201
  getAggregated,
104
202
  verbose,
203
+ mode: "dev",
204
+ configPath,
205
+ workspaceDir,
206
+ ui: options.ui,
207
+ uiDevUrl,
105
208
  });
106
209
  });
107
210
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
@@ -3,4 +3,5 @@ export * from "./normalize.js";
3
3
  export * from "./diff.js";
4
4
  export * from "./convert.js";
5
5
  export * from "./dev.js";
6
+ export * from "./start.js";
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
@@ -3,4 +3,5 @@ export * from "./normalize.js";
3
3
  export * from "./diff.js";
4
4
  export * from "./convert.js";
5
5
  export * from "./dev.js";
6
+ export * from "./start.js";
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerStartCommand(program: Command): void;
3
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0EzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwF3D"}
@@ -0,0 +1,125 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createRequire } from "node:module";
3
+ import { readFile } from "node:fs/promises";
4
+ import { dirname, isAbsolute, join, resolve } from "node:path";
5
+ import { loadConfig, findConfigPath } from "../config/loadConfig.js";
6
+ import { startDevServer } from "../dev/server.js";
7
+ function resolveConfigSpecPaths(config, baseDir) {
8
+ if (!baseDir)
9
+ return config;
10
+ const services = Array.isArray(config.services) ? config.services : [];
11
+ return {
12
+ ...config,
13
+ services: services.map((s) => {
14
+ const spec = String(s?.spec ?? "");
15
+ const resolvedSpec = spec && !isAbsolute(spec) ? resolve(baseDir, spec) : spec;
16
+ return {
17
+ ...s,
18
+ spec: resolvedSpec,
19
+ };
20
+ }),
21
+ };
22
+ }
23
+ async function resolvePortalBin(portalPackage, kind) {
24
+ const require = createRequire(import.meta.url);
25
+ const pkgJsonPath = require.resolve(`${portalPackage}/package.json`);
26
+ const pkgDir = dirname(pkgJsonPath);
27
+ const pkgRaw = await readFile(pkgJsonPath, "utf8");
28
+ const pkg = JSON.parse(pkgRaw);
29
+ if (!pkg.bin)
30
+ return null;
31
+ if (typeof pkg.bin === "string") {
32
+ return join(pkgDir, pkg.bin);
33
+ }
34
+ const entries = Object.entries(pkg.bin);
35
+ if (entries.length === 0)
36
+ return null;
37
+ const preferred = entries.find(([name]) => name.includes(kind)) ?? entries[0];
38
+ return join(pkgDir, preferred[1]);
39
+ }
40
+ async function spawnPortalServer(options) {
41
+ const binPath = await resolvePortalBin(options.portalPackage, options.mode);
42
+ if (!binPath) {
43
+ throw new Error(`Portal package '${options.portalPackage}' does not expose a runnable bin. Expected a package.json "bin" entry.`);
44
+ }
45
+ const args = [binPath, "--port", String(options.port), "--mode", options.mode];
46
+ const child = spawn(process.execPath, args, {
47
+ stdio: options.verbose ? "inherit" : "ignore",
48
+ env: { ...process.env, PORT: String(options.port) },
49
+ });
50
+ child.once("exit", (code) => {
51
+ if (options.verbose) {
52
+ process.stderr.write(`Portal server exited with code ${code ?? "null"}\n`);
53
+ }
54
+ });
55
+ return child;
56
+ }
57
+ export function registerStartCommand(program) {
58
+ program
59
+ .command("start")
60
+ .description("Start a local server (UI + /unispec.json)")
61
+ .option("--config <path>", "Path to unispec config file")
62
+ .option("--host <host>", "Host to bind", "127.0.0.1")
63
+ .option("--port <port>", "Port to bind", "4141")
64
+ .option("--ui", "Serve embedded UI at /", true)
65
+ .option("--no-ui", "Disable embedded UI")
66
+ .option("--ui-url <url>", "Proxy UI requests to an external UI server")
67
+ .option("--portal", "Spawn portal server (SSR) from an installed dependency and proxy UI to it")
68
+ .option("--portal-port <port>", "Port for portal server", "3000")
69
+ .option("--portal-package <name>", "Portal package name", "@unispechq/unispec-portal")
70
+ .action(async function (options) {
71
+ const parentOpts = this.parent?.opts?.();
72
+ const verbose = parentOpts?.verbose ?? false;
73
+ const host = String(options.host ?? "127.0.0.1");
74
+ const port = Number(options.port ?? 4141);
75
+ const configPath = await findConfigPath({ explicitPath: options.config });
76
+ const configDir = configPath ? dirname(configPath) : undefined;
77
+ const workspaceDir = configDir ? join(configDir, ".unispec") : undefined;
78
+ const getConfig = async () => {
79
+ const config = await loadConfig({ explicitPath: options.config });
80
+ return resolveConfigSpecPaths(config ?? { version: 1, services: [] }, configDir);
81
+ };
82
+ let portalChild;
83
+ let uiDevUrl = options.uiUrl;
84
+ if (options.portal) {
85
+ if (uiDevUrl) {
86
+ throw new Error("--portal cannot be used together with --ui-url");
87
+ }
88
+ const portalPort = Number(options.portalPort ?? 3000);
89
+ const portalPackage = String(options.portalPackage ?? "@unispechq/unispec-portal");
90
+ uiDevUrl = `http://127.0.0.1:${portalPort}`;
91
+ portalChild = await spawnPortalServer({
92
+ portalPackage,
93
+ port: portalPort,
94
+ mode: "start",
95
+ verbose,
96
+ });
97
+ const stop = () => {
98
+ try {
99
+ portalChild?.kill("SIGINT");
100
+ }
101
+ catch {
102
+ // ignore
103
+ }
104
+ };
105
+ process.once("SIGINT", stop);
106
+ process.once("SIGTERM", stop);
107
+ process.once("exit", stop);
108
+ if (verbose) {
109
+ process.stderr.write(`Spawned portal server (${portalPackage}) at ${uiDevUrl}\n`);
110
+ }
111
+ }
112
+ await startDevServer({
113
+ host,
114
+ port,
115
+ getConfig,
116
+ verbose,
117
+ mode: "start",
118
+ configPath,
119
+ workspaceDir,
120
+ ui: options.ui,
121
+ uiDevUrl: uiDevUrl,
122
+ });
123
+ });
124
+ }
125
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,11 @@ export interface DevServerOptions {
7
7
  getConfig: () => Promise<UniSpecPlatformConfig>;
8
8
  getAggregated?: () => Promise<AggregateResult>;
9
9
  verbose?: boolean;
10
+ ui?: boolean;
11
+ uiDevUrl?: string;
12
+ mode?: "dev" | "start";
13
+ workspaceDir?: string;
14
+ configPath?: string;
10
15
  }
11
16
  export declare function startDevServer(options: DevServerOptions): Promise<http.Server>;
12
17
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AASD,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAuCpF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAKrE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAwcD,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CA+KpF"}