wicked-crew 0.1.0 → 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/dist/api/gate-cache.d.ts +38 -0
- package/dist/api/gate-cache.d.ts.map +1 -0
- package/dist/api/gate-cache.js +58 -0
- package/dist/api/gate-cache.js.map +1 -0
- package/dist/api/routes.d.ts +9 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +257 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/api/server.d.ts +20 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +121 -0
- package/dist/api/server.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +134 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/adapter.d.ts +66 -0
- package/dist/core/adapter.d.ts.map +1 -0
- package/dist/core/adapter.js +145 -0
- package/dist/core/adapter.js.map +1 -0
- package/dist/core/types.d.ts +129 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +15 -0
- package/dist/core/types.js.map +1 -0
- package/dist/events/bus.d.ts +10 -0
- package/dist/events/bus.d.ts.map +1 -0
- package/dist/events/bus.js +48 -0
- package/dist/events/bus.js.map +1 -0
- package/dist/events/terminals.d.ts +42 -0
- package/dist/events/terminals.d.ts.map +1 -0
- package/dist/events/terminals.js +106 -0
- package/dist/events/terminals.js.map +1 -0
- package/dist/studio/assets/index-BJ07BOyt.js +50 -0
- package/dist/studio/assets/index-BptfbKLC.css +32 -0
- package/dist/studio/index.html +13 -0
- package/package.json +4 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CoreEvent, SessionView } from '../core/types.js';
|
|
2
|
+
/** A cached open human gate for a run. */
|
|
3
|
+
export interface GateCacheEntry {
|
|
4
|
+
/** The unit `ord` the run paused before. */
|
|
5
|
+
ord: number;
|
|
6
|
+
/** The gate prompt (lives only on the transient event — core does not persist it). */
|
|
7
|
+
prompt: string;
|
|
8
|
+
/** Lifecycle state. Only `open` in this foundation increment (see the class note). */
|
|
9
|
+
lifecycle: 'open';
|
|
10
|
+
/** When the daemon observed the gate. */
|
|
11
|
+
receivedAt: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Self-healing gate-prompt cache (DES-STUDIO-001 §3.3).
|
|
15
|
+
*
|
|
16
|
+
* Core does NOT persist the gate prompt — it exists only on the transient
|
|
17
|
+
* `awaitingHuman` CoreEvent (`AgentSession` has no prompt field). So the daemon
|
|
18
|
+
* event-sources it here, keyed by runId (a paused run has exactly one open gate,
|
|
19
|
+
* before `unit_ix`). Entries are pruned on any resumed/terminal event for the
|
|
20
|
+
* run, and re-checked against `sessionsDetail()` on every list reconcile so the
|
|
21
|
+
* cache can neither leak nor go stale ("re-merged on reconcile, pruned to
|
|
22
|
+
* still-paused — can't leak or blank").
|
|
23
|
+
*
|
|
24
|
+
* NOTE: the full HITL lifecycle from §3.3 (advisory / hard-expiry timers,
|
|
25
|
+
* append-only message log, auto-cancel-on-expiry, synthesized `gateLifecycle`
|
|
26
|
+
* frames) is a deliberate follow-on. This increment caches only the prompt so a
|
|
27
|
+
* late-joining browser can render the gate; `lifecycle` is always `open`.
|
|
28
|
+
*/
|
|
29
|
+
export declare class GateCache {
|
|
30
|
+
private readonly entries;
|
|
31
|
+
/** Fold one CoreEvent into the cache. */
|
|
32
|
+
ingest(event: CoreEvent): void;
|
|
33
|
+
/** The cached open gate for a run, if any. */
|
|
34
|
+
get(runId: string): GateCacheEntry | undefined;
|
|
35
|
+
/** Drop cache entries whose run is no longer `awaiting_human` (self-healing on reconcile). */
|
|
36
|
+
reconcile(views: SessionView[]): void;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=gate-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-cache.d.ts","sourceRoot":"","sources":["../../src/api/gate-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/D,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAE7D,yCAAyC;IACzC,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAyB9B,8CAA8C;IAC9C,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI9C,8FAA8F;IAC9F,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI;CAQtC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-healing gate-prompt cache (DES-STUDIO-001 §3.3).
|
|
3
|
+
*
|
|
4
|
+
* Core does NOT persist the gate prompt — it exists only on the transient
|
|
5
|
+
* `awaitingHuman` CoreEvent (`AgentSession` has no prompt field). So the daemon
|
|
6
|
+
* event-sources it here, keyed by runId (a paused run has exactly one open gate,
|
|
7
|
+
* before `unit_ix`). Entries are pruned on any resumed/terminal event for the
|
|
8
|
+
* run, and re-checked against `sessionsDetail()` on every list reconcile so the
|
|
9
|
+
* cache can neither leak nor go stale ("re-merged on reconcile, pruned to
|
|
10
|
+
* still-paused — can't leak or blank").
|
|
11
|
+
*
|
|
12
|
+
* NOTE: the full HITL lifecycle from §3.3 (advisory / hard-expiry timers,
|
|
13
|
+
* append-only message log, auto-cancel-on-expiry, synthesized `gateLifecycle`
|
|
14
|
+
* frames) is a deliberate follow-on. This increment caches only the prompt so a
|
|
15
|
+
* late-joining browser can render the gate; `lifecycle` is always `open`.
|
|
16
|
+
*/
|
|
17
|
+
export class GateCache {
|
|
18
|
+
entries = new Map();
|
|
19
|
+
/** Fold one CoreEvent into the cache. */
|
|
20
|
+
ingest(event) {
|
|
21
|
+
const session = typeof event.session === 'string' ? event.session : undefined;
|
|
22
|
+
if (session === undefined)
|
|
23
|
+
return;
|
|
24
|
+
switch (event.type) {
|
|
25
|
+
case 'awaitingHuman':
|
|
26
|
+
if (typeof event.ord === 'number' && typeof event.prompt === 'string') {
|
|
27
|
+
this.entries.set(session, {
|
|
28
|
+
ord: event.ord,
|
|
29
|
+
prompt: event.prompt,
|
|
30
|
+
lifecycle: 'open',
|
|
31
|
+
receivedAt: new Date().toISOString(),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
case 'resumed':
|
|
36
|
+
case 'sessionCompleted':
|
|
37
|
+
case 'runCancelled':
|
|
38
|
+
case 'sessionFailed':
|
|
39
|
+
this.entries.delete(session);
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** The cached open gate for a run, if any. */
|
|
46
|
+
get(runId) {
|
|
47
|
+
return this.entries.get(runId);
|
|
48
|
+
}
|
|
49
|
+
/** Drop cache entries whose run is no longer `awaiting_human` (self-healing on reconcile). */
|
|
50
|
+
reconcile(views) {
|
|
51
|
+
const awaiting = new Set(views.filter((v) => v.session.status === 'awaiting_human').map((v) => v.session.id));
|
|
52
|
+
for (const id of [...this.entries.keys()]) {
|
|
53
|
+
if (!awaiting.has(id))
|
|
54
|
+
this.entries.delete(id);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=gate-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-cache.js","sourceRoot":"","sources":["../../src/api/gate-cache.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,SAAS;IACH,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAE7D,yCAAyC;IACzC,MAAM,CAAC,KAAgB;QACrB,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9E,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO;QAClC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,eAAe;gBAClB,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBACtE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE;wBACxB,GAAG,EAAE,KAAK,CAAC,GAAG;wBACd,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,SAAS,EAAE,MAAM;wBACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBACrC,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC;YACf,KAAK,kBAAkB,CAAC;YACxB,KAAK,cAAc,CAAC;YACpB,KAAK,eAAe;gBAClB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC7B,MAAM;YACR;gBACE,MAAM;QACV,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,GAAG,CAAC,KAAa;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,8FAA8F;IAC9F,SAAS,CAAC,KAAoB;QAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CACpF,CAAC;QACF,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import { CoreAdapter } from '../core/adapter.js';
|
|
3
|
+
import type { GateCache } from './gate-cache.js';
|
|
4
|
+
/**
|
|
5
|
+
* The daemon REST surface. Every endpoint is a thin wrapper over one adapter /
|
|
6
|
+
* core-ts call (DES-STUDIO-001 §2). `session`/`phase` nouns are now `run`/`unit`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function registerRoutes(app: FastifyInstance, adapter: CoreAdapter, gateCache: GateCache): void;
|
|
9
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAuEjD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAkMrG"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { CoreAdapter } from '../core/adapter.js';
|
|
6
|
+
const V = '/api/v1';
|
|
7
|
+
// Daemon version reported by /health — read from package.json so it never drifts
|
|
8
|
+
// from the shipped version across releases. Resolves the package root from the
|
|
9
|
+
// compiled module location (dist/api/routes.js → ../../package.json) and works the
|
|
10
|
+
// same under the src layout (src/api/routes.ts → ../../package.json).
|
|
11
|
+
const PKG_VERSION = JSON.parse(readFileSync(fileURLToPath(new URL('../../package.json', import.meta.url)), 'utf8')).version;
|
|
12
|
+
// Actionable-first ordering for the run list (DES-STUDIO-001 §11.6): a run
|
|
13
|
+
// awaiting a human sorts to the top; terminal runs sink.
|
|
14
|
+
const STATUS_ORDER = {
|
|
15
|
+
awaiting_human: 0,
|
|
16
|
+
executing: 1,
|
|
17
|
+
distributing: 2,
|
|
18
|
+
planning: 3,
|
|
19
|
+
failed: 4,
|
|
20
|
+
completed: 5,
|
|
21
|
+
cancelled: 6,
|
|
22
|
+
};
|
|
23
|
+
function sortActionableFirst(views) {
|
|
24
|
+
return [...views].sort((a, b) => (STATUS_ORDER[a.session.status] ?? 9) - (STATUS_ORDER[b.session.status] ?? 9));
|
|
25
|
+
}
|
|
26
|
+
function message(err) {
|
|
27
|
+
return err instanceof Error ? err.message : String(err);
|
|
28
|
+
}
|
|
29
|
+
const RegisterRepoSchema = z.object({
|
|
30
|
+
name: z.string().min(1),
|
|
31
|
+
rootPath: z.string().min(1),
|
|
32
|
+
});
|
|
33
|
+
const LaunchSchema = z.object({
|
|
34
|
+
problem: z.string().min(1),
|
|
35
|
+
sessionId: z.string().min(1).optional(),
|
|
36
|
+
clisJson: z.string().min(1).optional(),
|
|
37
|
+
entityMode: z.enum(['shared', 'isolated']).optional(),
|
|
38
|
+
humanConfirm: z.string().min(1).optional(),
|
|
39
|
+
repoRef: z.string().min(1).optional(),
|
|
40
|
+
});
|
|
41
|
+
const GateSchema = z.object({
|
|
42
|
+
approve: z.boolean(),
|
|
43
|
+
amend: z.string().optional(),
|
|
44
|
+
});
|
|
45
|
+
const OpenTerminalSchema = z.object({
|
|
46
|
+
cwd: z.string().min(1),
|
|
47
|
+
cmd: z.array(z.string().min(1)).min(1).optional(),
|
|
48
|
+
cols: z.number().int().positive(),
|
|
49
|
+
rows: z.number().int().positive(),
|
|
50
|
+
// Optional so omission is the SAFE governed default (§7 — `false` is never a
|
|
51
|
+
// default; the ungoverned operator shell must opt in explicitly).
|
|
52
|
+
governed: z.boolean().optional(),
|
|
53
|
+
});
|
|
54
|
+
const ResizeTerminalSchema = z.object({
|
|
55
|
+
cols: z.number().int().positive(),
|
|
56
|
+
rows: z.number().int().positive(),
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* The daemon REST surface. Every endpoint is a thin wrapper over one adapter /
|
|
60
|
+
* core-ts call (DES-STUDIO-001 §2). `session`/`phase` nouns are now `run`/`unit`.
|
|
61
|
+
*/
|
|
62
|
+
export function registerRoutes(app, adapter, gateCache) {
|
|
63
|
+
// Liveness — also proves the actor + event pump are up.
|
|
64
|
+
app.get(`${V}/health`, async () => {
|
|
65
|
+
const ping = await adapter.ping();
|
|
66
|
+
return { status: 'ok', version: PKG_VERSION, ping };
|
|
67
|
+
});
|
|
68
|
+
// Report the actually-bound port/host (honours --port / CREW_PORT / port 0).
|
|
69
|
+
app.get(`${V}/config`, async () => {
|
|
70
|
+
const addr = app.server.address();
|
|
71
|
+
const port = typeof addr === 'object' && addr ? addr.port : 7701;
|
|
72
|
+
const host = typeof addr === 'object' && addr ? addr.address : '127.0.0.1';
|
|
73
|
+
return { port, host };
|
|
74
|
+
});
|
|
75
|
+
// The council seats for the launch form (static production roster).
|
|
76
|
+
app.get(`${V}/roster`, async () => ({ roster: CoreAdapter.roster() }));
|
|
77
|
+
// Registered repos → target-repo picker.
|
|
78
|
+
app.get(`${V}/repos`, async () => ({ repos: await adapter.listRepos() }));
|
|
79
|
+
app.post(`${V}/repos`, async (req, reply) => {
|
|
80
|
+
const parsed = RegisterRepoSchema.safeParse(req.body);
|
|
81
|
+
if (!parsed.success) {
|
|
82
|
+
return reply.code(400).send({ error: 'Invalid request body', details: parsed.error.issues });
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const repo = await adapter.registerRepo(parsed.data.name, parsed.data.rootPath);
|
|
86
|
+
return reply.code(201).send({ repo });
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
// Core rejects a non-git / zero-commit path — a client error, not a 500.
|
|
90
|
+
return reply.code(400).send({ error: message(err) });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// Launch a run (replaces POST /sessions). `clisJson` defaults to the roster;
|
|
94
|
+
// `sessionId` is minted if the client omits it.
|
|
95
|
+
app.post(`${V}/runs`, async (req, reply) => {
|
|
96
|
+
const parsed = LaunchSchema.safeParse(req.body);
|
|
97
|
+
if (!parsed.success) {
|
|
98
|
+
return reply.code(400).send({ error: 'Invalid request body', details: parsed.error.issues });
|
|
99
|
+
}
|
|
100
|
+
const b = parsed.data;
|
|
101
|
+
const input = {
|
|
102
|
+
problem: b.problem,
|
|
103
|
+
sessionId: b.sessionId ?? randomUUID(),
|
|
104
|
+
clisJson: b.clisJson ?? JSON.stringify(CoreAdapter.roster()),
|
|
105
|
+
};
|
|
106
|
+
if (b.entityMode !== undefined)
|
|
107
|
+
input.entityMode = b.entityMode;
|
|
108
|
+
if (b.humanConfirm !== undefined)
|
|
109
|
+
input.humanConfirm = b.humanConfirm;
|
|
110
|
+
if (b.repoRef !== undefined)
|
|
111
|
+
input.repoRef = b.repoRef;
|
|
112
|
+
try {
|
|
113
|
+
const runId = await adapter.launchRun(input);
|
|
114
|
+
return reply.code(201).send({ runId });
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
const msg = message(err);
|
|
118
|
+
const busy = /busy|in flight|already/i.test(msg);
|
|
119
|
+
return reply.code(busy ? 409 : 400).send({ error: msg });
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
// Run list (replaces GET /sessions). Actionable-first; reconciles the gate cache.
|
|
123
|
+
app.get(`${V}/runs`, async () => {
|
|
124
|
+
const views = await adapter.sessionsDetail();
|
|
125
|
+
gateCache.reconcile(views);
|
|
126
|
+
return { runs: sortActionableFirst(views) };
|
|
127
|
+
});
|
|
128
|
+
// One run's detail.
|
|
129
|
+
app.get(`${V}/runs/:id`, async (req, reply) => {
|
|
130
|
+
const { id } = req.params;
|
|
131
|
+
const views = await adapter.sessionsDetail();
|
|
132
|
+
const run = views.find((v) => v.session.id === id);
|
|
133
|
+
if (!run)
|
|
134
|
+
return reply.code(404).send({ error: 'Run not found' });
|
|
135
|
+
return { run };
|
|
136
|
+
});
|
|
137
|
+
// A unit's captured transcript. Unit id convention: `<run>:u<ord>`.
|
|
138
|
+
app.get(`${V}/runs/:id/units/:ord/output`, async (req, reply) => {
|
|
139
|
+
const { id, ord } = req.params;
|
|
140
|
+
const output = await adapter.workOutput(`${id}:u${ord}`);
|
|
141
|
+
return reply.send({ output });
|
|
142
|
+
});
|
|
143
|
+
// The steering gate (§11.1). approve+amend = approve-with-steer; approve:false = reject (cancels).
|
|
144
|
+
app.post(`${V}/runs/:id/gate`, async (req, reply) => {
|
|
145
|
+
const { id } = req.params;
|
|
146
|
+
const parsed = GateSchema.safeParse(req.body);
|
|
147
|
+
if (!parsed.success) {
|
|
148
|
+
return reply.code(400).send({ error: 'Invalid request body', details: parsed.error.issues });
|
|
149
|
+
}
|
|
150
|
+
const views = await adapter.sessionsDetail();
|
|
151
|
+
const run = views.find((v) => v.session.id === id);
|
|
152
|
+
if (!run)
|
|
153
|
+
return reply.code(404).send({ error: 'Run not found' });
|
|
154
|
+
if (run.session.status !== 'awaiting_human') {
|
|
155
|
+
return reply
|
|
156
|
+
.code(409)
|
|
157
|
+
.send({ error: `Run is not awaiting a human gate (status: ${run.session.status})` });
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const status = await adapter.confirmGate(id, parsed.data.approve, parsed.data.amend);
|
|
161
|
+
return reply.send({ status });
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
return reply.code(409).send({ error: message(err) });
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
// Cancel a running or paused run (distinct third action, §11.1).
|
|
168
|
+
app.post(`${V}/runs/:id/cancel`, async (req, reply) => {
|
|
169
|
+
const { id } = req.params;
|
|
170
|
+
const views = await adapter.sessionsDetail();
|
|
171
|
+
const run = views.find((v) => v.session.id === id);
|
|
172
|
+
if (!run)
|
|
173
|
+
return reply.code(404).send({ error: 'Run not found' });
|
|
174
|
+
try {
|
|
175
|
+
const status = await adapter.cancelRun(id);
|
|
176
|
+
return reply.send({ status });
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
return reply.code(409).send({ error: message(err) });
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
// Advance semantics (§11.8): a gated run advances via confirmGate; otherwise
|
|
183
|
+
// resumeRun re-enters the cursor. Never resumeRun a gated run (it would re-pause).
|
|
184
|
+
app.post(`${V}/runs/:id/resume`, async (req, reply) => {
|
|
185
|
+
const { id } = req.params;
|
|
186
|
+
const views = await adapter.sessionsDetail();
|
|
187
|
+
const run = views.find((v) => v.session.id === id);
|
|
188
|
+
if (!run)
|
|
189
|
+
return reply.code(404).send({ error: 'Run not found' });
|
|
190
|
+
try {
|
|
191
|
+
const status = run.session.status === 'awaiting_human'
|
|
192
|
+
? await adapter.confirmGate(id, true)
|
|
193
|
+
: await adapter.resumeRun(id);
|
|
194
|
+
return reply.send({ status });
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
return reply.code(409).send({ error: message(err) });
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
// The daemon-cached gate prompt for a paused run (not a core call) so a fresh
|
|
201
|
+
// browser can render the gate after a late join.
|
|
202
|
+
app.get(`${V}/runs/:id/gate`, async (req, reply) => {
|
|
203
|
+
const { id } = req.params;
|
|
204
|
+
const entry = gateCache.get(id);
|
|
205
|
+
if (!entry)
|
|
206
|
+
return reply.code(404).send({ error: 'No open gate for this run' });
|
|
207
|
+
return { runId: id, ...entry };
|
|
208
|
+
});
|
|
209
|
+
// ── PTY terminal sessions (DES-TERMINAL-001 §6) ────────────────────────────
|
|
210
|
+
// Open a PTY → its id. Drive it over the per-terminal WS `/ws/terminals/:id`;
|
|
211
|
+
// raw output arrives there. `governed` defaults to `true` (the gate-hook-routed
|
|
212
|
+
// default, §7) — an ungoverned operator shell must pass `governed:false` EXPLICITLY.
|
|
213
|
+
app.post(`${V}/terminals`, async (req, reply) => {
|
|
214
|
+
const parsed = OpenTerminalSchema.safeParse(req.body);
|
|
215
|
+
if (!parsed.success) {
|
|
216
|
+
return reply.code(400).send({ error: 'Invalid request body', details: parsed.error.issues });
|
|
217
|
+
}
|
|
218
|
+
const b = parsed.data;
|
|
219
|
+
try {
|
|
220
|
+
const id = await adapter.openTerminal(b.cwd, b.cmd, b.cols, b.rows, b.governed ?? true);
|
|
221
|
+
return reply.code(201).send({ id });
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
// Core rejects a bad cwd / spawn failure — a client error, not a 500.
|
|
225
|
+
return reply.code(400).send({ error: message(err) });
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// Resize a live terminal's PTY.
|
|
229
|
+
app.post(`${V}/terminals/:id/resize`, async (req, reply) => {
|
|
230
|
+
const { id } = req.params;
|
|
231
|
+
const parsed = ResizeTerminalSchema.safeParse(req.body);
|
|
232
|
+
if (!parsed.success) {
|
|
233
|
+
return reply.code(400).send({ error: 'Invalid request body', details: parsed.error.issues });
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
const status = await adapter.resizeTerminal(id, parsed.data.cols, parsed.data.rows);
|
|
237
|
+
return reply.send({ status });
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
// Unknown / already-closed terminal id → 404, not 500.
|
|
241
|
+
return reply.code(404).send({ error: message(err) });
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
// Close a live terminal (kill child, join reader). A second close of an
|
|
245
|
+
// already-gone terminal 404s rather than 500s.
|
|
246
|
+
app.post(`${V}/terminals/:id/close`, async (req, reply) => {
|
|
247
|
+
const { id } = req.params;
|
|
248
|
+
try {
|
|
249
|
+
const status = await adapter.closeTerminal(id);
|
|
250
|
+
return reply.send({ status });
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
return reply.code(404).send({ error: message(err) });
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Fastify from 'fastify';
|
|
2
|
+
import type { CoreAdapter } from '../core/adapter.js';
|
|
3
|
+
/**
|
|
4
|
+
* The bundled studio SPA lives at `dist/studio` next to the compiled server
|
|
5
|
+
* (`dist/api/server.js` → `../studio`). See DES-STUDIO-SERVING-001 §2.3/§3.1
|
|
6
|
+
* and `scripts/bundle-studio.mjs` which copies `packages/studio/dist` there.
|
|
7
|
+
*/
|
|
8
|
+
export declare function defaultStudioRoot(): string;
|
|
9
|
+
export interface CreateServerOptions {
|
|
10
|
+
/** Override the studio asset root (tests point this at a temp fixture dir). */
|
|
11
|
+
studioRoot?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function createServer(adapter: CoreAdapter, options?: CreateServerOptions): Promise<ReturnType<typeof Fastify>>;
|
|
14
|
+
export interface StartedServer {
|
|
15
|
+
app: ReturnType<typeof Fastify>;
|
|
16
|
+
port: number;
|
|
17
|
+
host: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function startServer(adapter: CoreAdapter, port?: number, host?: string): Promise<StartedServer>;
|
|
20
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAU9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOtD;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAmGrC;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,IAAI,SAAO,EACX,IAAI,SAAc,GACjB,OAAO,CAAC,aAAa,CAAC,CAQxB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import Fastify from 'fastify';
|
|
2
|
+
import fastifyWebsocket from '@fastify/websocket';
|
|
3
|
+
import fastifyStatic from '@fastify/static';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { registerRoutes } from './routes.js';
|
|
7
|
+
import { GateCache } from './gate-cache.js';
|
|
8
|
+
import { registerClient, broadcast } from '../events/bus.js';
|
|
9
|
+
import { TerminalHub, registerTerminalWs } from '../events/terminals.js';
|
|
10
|
+
// Allow the studio (a separate localhost origin, e.g. :4200) to call the
|
|
11
|
+
// daemon's REST API. Restricted to loopback origins — the daemon only binds
|
|
12
|
+
// 127.0.0.1, so this never widens exposure beyond the local machine.
|
|
13
|
+
const LOOPBACK_ORIGIN = /^http:\/\/(127\.0\.0\.1|localhost):\d+$/;
|
|
14
|
+
/**
|
|
15
|
+
* The bundled studio SPA lives at `dist/studio` next to the compiled server
|
|
16
|
+
* (`dist/api/server.js` → `../studio`). See DES-STUDIO-SERVING-001 §2.3/§3.1
|
|
17
|
+
* and `scripts/bundle-studio.mjs` which copies `packages/studio/dist` there.
|
|
18
|
+
*/
|
|
19
|
+
export function defaultStudioRoot() {
|
|
20
|
+
return fileURLToPath(new URL('../studio', import.meta.url));
|
|
21
|
+
}
|
|
22
|
+
export async function createServer(adapter, options) {
|
|
23
|
+
const app = Fastify({ logger: { level: process.env['LOG_LEVEL'] ?? 'info' } });
|
|
24
|
+
const gateCache = new GateCache();
|
|
25
|
+
const terminals = new TerminalHub();
|
|
26
|
+
// The daemon's single CoreEvent subscription fans out here: cache gate prompts
|
|
27
|
+
// (§3.3), route terminal frames to their owning per-terminal socket (by id,
|
|
28
|
+
// DES-TERMINAL-001 §6), then forward every frame verbatim to all `/ws` clients (§2.1).
|
|
29
|
+
adapter.onEvent((event) => {
|
|
30
|
+
gateCache.ingest(event);
|
|
31
|
+
terminals.route(event);
|
|
32
|
+
broadcast(event);
|
|
33
|
+
});
|
|
34
|
+
app.addHook('onRequest', async (req, reply) => {
|
|
35
|
+
const origin = req.headers.origin;
|
|
36
|
+
if (origin && LOOPBACK_ORIGIN.test(origin)) {
|
|
37
|
+
reply.header('Access-Control-Allow-Origin', origin);
|
|
38
|
+
reply.header('Vary', 'Origin');
|
|
39
|
+
reply.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
|
|
40
|
+
reply.header('Access-Control-Allow-Headers', 'Content-Type');
|
|
41
|
+
}
|
|
42
|
+
if (req.method === 'OPTIONS') {
|
|
43
|
+
await reply.code(204).send();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
// Tolerate an empty body on application/json POSTs (some actions take no body).
|
|
47
|
+
// Default Fastify v5 rejects "" with FST_ERR_CTP_EMPTY_JSON_BODY.
|
|
48
|
+
app.addContentTypeParser('application/json', { parseAs: 'string' }, (_req, body, done) => {
|
|
49
|
+
if (body === '' || body === undefined || body === null)
|
|
50
|
+
return done(null, undefined);
|
|
51
|
+
try {
|
|
52
|
+
done(null, JSON.parse(body));
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
done(err);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
await app.register(fastifyWebsocket);
|
|
59
|
+
app.get('/ws', { websocket: true }, (socket) => {
|
|
60
|
+
// Late-join gets no replay; the studio reconciles with a one-shot GET /runs.
|
|
61
|
+
registerClient(socket);
|
|
62
|
+
});
|
|
63
|
+
// One dedicated WS channel per PTY: /ws/terminals/:id (DES-TERMINAL-001 §6).
|
|
64
|
+
registerTerminalWs(app, adapter, terminals);
|
|
65
|
+
registerRoutes(app, adapter, gateCache);
|
|
66
|
+
// Serve the bundled studio SPA same-origin (DES-STUDIO-SERVING-001 §3). The
|
|
67
|
+
// API routes, `/ws`, and terminal WS are registered ABOVE and keep winning:
|
|
68
|
+
// static uses `wildcard: false` (only serves files that physically exist),
|
|
69
|
+
// and the SPA fallback below explicitly excludes `/api/` and `/ws`.
|
|
70
|
+
const studioRoot = options?.studioRoot ?? defaultStudioRoot();
|
|
71
|
+
if (existsSync(studioRoot)) {
|
|
72
|
+
await app.register(fastifyStatic, {
|
|
73
|
+
root: studioRoot,
|
|
74
|
+
wildcard: false,
|
|
75
|
+
// We own every Cache-Control value via setHeaders (§4.3) — disable the
|
|
76
|
+
// plugin's automatic header so it can't override us.
|
|
77
|
+
cacheControl: false,
|
|
78
|
+
index: ['index.html'],
|
|
79
|
+
setHeaders: (res, pathName) => {
|
|
80
|
+
const p = pathName.replace(/\\/g, '/');
|
|
81
|
+
if (p.endsWith('/index.html')) {
|
|
82
|
+
// HTML must revalidate so a redeploy's new asset hashes are picked up.
|
|
83
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
84
|
+
}
|
|
85
|
+
else if (p.includes('/assets/')) {
|
|
86
|
+
// Content-addressed (hashed) assets are immutable.
|
|
87
|
+
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
// SPA deep-link fallback (§3.2): a GET that is NOT under /api/ or /ws and
|
|
92
|
+
// matched no static file returns the index.html shell (200) so client-side
|
|
93
|
+
// routes resolve. Everything else keeps normal 404/JSON behavior.
|
|
94
|
+
app.setNotFoundHandler((req, reply) => {
|
|
95
|
+
if (req.method === 'GET' &&
|
|
96
|
+
!req.url.startsWith('/api/') &&
|
|
97
|
+
!req.url.startsWith('/ws')) {
|
|
98
|
+
reply.header('Cache-Control', 'no-cache');
|
|
99
|
+
// `root` is dist/studio, so the shell is at 'index.html' (not
|
|
100
|
+
// 'studio/index.html'): sendFile resolves relative to root.
|
|
101
|
+
return reply.type('text/html').sendFile('index.html');
|
|
102
|
+
}
|
|
103
|
+
return reply.code(404).send({ error: 'not found' });
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Dev / headless run without a built bundle: degrade gracefully (§3.1).
|
|
108
|
+
app.log.warn(`studio bundle not found at ${studioRoot} — serving API + WS only (headless)`);
|
|
109
|
+
}
|
|
110
|
+
return app;
|
|
111
|
+
}
|
|
112
|
+
export async function startServer(adapter, port = 7701, host = '127.0.0.1') {
|
|
113
|
+
const app = await createServer(adapter);
|
|
114
|
+
await app.listen({ port, host });
|
|
115
|
+
const addr = app.server.address();
|
|
116
|
+
const boundPort = typeof addr === 'object' && addr ? addr.port : port;
|
|
117
|
+
const boundHost = typeof addr === 'object' && addr ? addr.address : host;
|
|
118
|
+
app.log.info(`wicked-crew daemon listening on ${boundHost}:${boundPort}`);
|
|
119
|
+
return { app, port: boundPort, host: boundHost };
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGzE,yEAAyE;AACzE,4EAA4E;AAC5E,qEAAqE;AACrE,MAAM,eAAe,GAAG,yCAAyC,CAAC;AAElE;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9D,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAoB,EACpB,OAA6B;IAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/E,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC;IAEpC,+EAA+E;IAC/E,4EAA4E;IAC5E,uFAAuF;IACvF,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvB,SAAS,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAClC,IAAI,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,KAAK,CAAC,MAAM,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;YACpD,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC/B,KAAK,CAAC,MAAM,CAAC,8BAA8B,EAAE,kBAAkB,CAAC,CAAC;YACjE,KAAK,CAAC,MAAM,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,kEAAkE;IAClE,GAAG,CAAC,oBAAoB,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACvF,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACrF,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAc,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAY,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAErC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE;QAC7C,6EAA6E;QAC7E,cAAc,CAAC,MAA8B,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAE5C,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAExC,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,CAAC;IAC9D,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE;YAChC,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,KAAK;YACf,uEAAuE;YACvE,qDAAqD;YACrD,YAAY,EAAE,KAAK;YACnB,KAAK,EAAE,CAAC,YAAY,CAAC;YACrB,UAAU,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;gBAC5B,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBACvC,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;oBAC9B,uEAAuE;oBACvE,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;gBAC7C,CAAC;qBAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBAClC,mDAAmD;oBACnD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAAC;gBACxE,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,0EAA0E;QAC1E,2EAA2E;QAC3E,kEAAkE;QAClE,GAAG,CAAC,kBAAkB,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACpC,IACE,GAAG,CAAC,MAAM,KAAK,KAAK;gBACpB,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC5B,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAC1B,CAAC;gBACD,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;gBAC1C,8DAA8D;gBAC9D,4DAA4D;gBAC5D,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,wEAAwE;QACxE,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,8BAA8B,UAAU,qCAAqC,CAC9E,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAoB,EACpB,IAAI,GAAG,IAAI,EACX,IAAI,GAAG,WAAW;IAElB,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,MAAM,SAAS,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACzE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,SAAS,IAAI,SAAS,EAAE,CAAC,CAAC;IAC1E,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|