@ggui-ai/dev-stack 0.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +63 -0
  3. package/dist/dev-server/auth.d.ts +44 -0
  4. package/dist/dev-server/auth.d.ts.map +1 -0
  5. package/dist/dev-server/auth.js +176 -0
  6. package/dist/dev-server/events.d.ts +43 -0
  7. package/dist/dev-server/events.d.ts.map +1 -0
  8. package/dist/dev-server/events.js +61 -0
  9. package/dist/dev-server/http.d.ts +79 -0
  10. package/dist/dev-server/http.d.ts.map +1 -0
  11. package/dist/dev-server/http.js +277 -0
  12. package/dist/dev-server/hub-preview.d.ts +56 -0
  13. package/dist/dev-server/hub-preview.d.ts.map +1 -0
  14. package/dist/dev-server/hub-preview.js +237 -0
  15. package/dist/dev-server/hub.d.ts +59 -0
  16. package/dist/dev-server/hub.d.ts.map +1 -0
  17. package/dist/dev-server/hub.js +723 -0
  18. package/dist/hub-preview/client.js +52346 -0
  19. package/dist/index.d.ts +34 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +49 -0
  22. package/dist/local-registry/compile-ui.d.ts +67 -0
  23. package/dist/local-registry/compile-ui.d.ts.map +1 -0
  24. package/dist/local-registry/compile-ui.js +148 -0
  25. package/dist/local-registry/local-registry.d.ts +93 -0
  26. package/dist/local-registry/local-registry.d.ts.map +1 -0
  27. package/dist/local-registry/local-registry.js +272 -0
  28. package/dist/local-registry/watcher.d.ts +42 -0
  29. package/dist/local-registry/watcher.d.ts.map +1 -0
  30. package/dist/local-registry/watcher.js +208 -0
  31. package/dist/run-dev.d.ts +147 -0
  32. package/dist/run-dev.d.ts.map +1 -0
  33. package/dist/run-dev.js +216 -0
  34. package/dist/runtime-supervisor.d.ts +140 -0
  35. package/dist/runtime-supervisor.d.ts.map +1 -0
  36. package/dist/runtime-supervisor.js +91 -0
  37. package/package.json +72 -0
@@ -0,0 +1,140 @@
1
+ /**
2
+ * `RuntimeSupervisor` — owns the live view of a supervised agent
3
+ * runtime inside `@ggui-ai/dev-stack`.
4
+ *
5
+ * Responsibilities:
6
+ *
7
+ * 1. Subscribe to the adapter's event stream on construction.
8
+ * 2. Keep a bounded ring buffer of recent events (status + logs +
9
+ * errors) so hosts that missed the live stream (the CLI banner,
10
+ * the future hub, an HTTP snapshot endpoint) can still render a
11
+ * consistent "recent state" view.
12
+ * 3. Expose a cheap, GC-friendly {@link RuntimeStateSnapshot} for
13
+ * point-in-time reads without forcing callers to subscribe.
14
+ * 4. Dispose cleanly — the `close()` method unsubscribes the
15
+ * internal listener and forwards unsubscribe to observers.
16
+ *
17
+ * The supervisor intentionally does NOT:
18
+ *
19
+ * - Own the handle's lifecycle. Whoever constructed the adapter
20
+ * and called `start()` still owns `stop()`. Supervisor is a
21
+ * read-plus-buffer layer, not a controller.
22
+ * - Implement restart-on-crash. That's a higher-layer policy
23
+ * needing a second adapter to validate the abstraction.
24
+ * - Persist events beyond the in-memory ring. The hub's eventual
25
+ * log panel is snapshot-and-tail, not full-history.
26
+ * - Fan events out to multiple subscribers. The `onEvent` callback
27
+ * is a single pipe — `runDev` uses it to forward into the CLI
28
+ * log stream; if a future host needs multi-subscriber fanout it
29
+ * wraps an `EventEmitter` around the same pipe.
30
+ */
31
+ import type { AgentRuntimeAdapter, AgentRuntimeCapabilities, AgentRuntimeEvent, AgentRuntimeHandle, AgentRuntimeStatus } from '@ggui-ai/agent-runtime';
32
+ /** Default ring-buffer depth. Chosen to render cleanly in a CLI +
33
+ * hub panel while staying bounded in memory (~200 entries × ~1 KiB
34
+ * worst case ≈ 200 KiB). */
35
+ export declare const DEFAULT_RUNTIME_BUFFER_SIZE = 200;
36
+ /**
37
+ * A ring-buffered event — identical to the adapter's
38
+ * `AgentRuntimeEvent` with an appended monotonic `sequence` so
39
+ * consumers can detect gaps without parsing timestamps.
40
+ */
41
+ export type RuntimeEventRecord = ({
42
+ sequence: number;
43
+ } & Extract<AgentRuntimeEvent, {
44
+ type: 'status';
45
+ }>) | ({
46
+ sequence: number;
47
+ } & Extract<AgentRuntimeEvent, {
48
+ type: 'log';
49
+ }>) | ({
50
+ sequence: number;
51
+ } & Extract<AgentRuntimeEvent, {
52
+ type: 'error';
53
+ }>);
54
+ /**
55
+ * Point-in-time snapshot. The HTTP surface serializes this verbatim;
56
+ * the CLI uses it for banner refresh; tests assert on its shape
57
+ * directly.
58
+ */
59
+ export interface RuntimeStateSnapshot {
60
+ /** `true` when a runtime is currently supervised. Always `true`
61
+ * on a snapshot produced by a supervisor (supervisor exists iff
62
+ * a runtime was started). Included for HTTP parity with the
63
+ * "no runtime" case. */
64
+ readonly present: true;
65
+ /** Adapter name (e.g. `'node-process'`). */
66
+ readonly name: string;
67
+ /** Handle's `runId`. */
68
+ readonly runId: string;
69
+ /** Current status — matches the declarative handle snapshot. */
70
+ readonly status: AgentRuntimeStatus;
71
+ /** Adapter capabilities. */
72
+ readonly capabilities: AgentRuntimeCapabilities;
73
+ /** Timestamp (ms) the supervisor was created. Fixed per run. */
74
+ readonly startedAt: number;
75
+ /** Timestamp (ms) of the most recent event the supervisor saw,
76
+ * or `null` if no events have arrived yet. */
77
+ readonly lastEventAt: number | null;
78
+ /** Recent events, oldest-first. Capped at the supervisor's
79
+ * buffer size (default 200). */
80
+ readonly recentEvents: readonly RuntimeEventRecord[];
81
+ }
82
+ export interface RuntimeSupervisorOptions {
83
+ /** Adapter that produced {@link handle}. */
84
+ readonly adapter: AgentRuntimeAdapter;
85
+ /** Running handle the supervisor observes. */
86
+ readonly handle: AgentRuntimeHandle;
87
+ /** Ring-buffer capacity. Defaults to
88
+ * {@link DEFAULT_RUNTIME_BUFFER_SIZE}. Must be ≥ 1. */
89
+ readonly bufferSize?: number;
90
+ /** Optional forward pipe — the supervisor calls this for every
91
+ * event after the ring buffer is updated. `runDev` uses it to
92
+ * forward formatted lines into the CLI log stream. */
93
+ readonly onEvent?: (event: RuntimeEventRecord) => void;
94
+ }
95
+ /**
96
+ * Attach a supervisor to a running handle. Call `close()` when the
97
+ * runtime is torn down to release the subscription.
98
+ */
99
+ export declare class RuntimeSupervisor {
100
+ readonly adapter: AgentRuntimeAdapter;
101
+ readonly handle: AgentRuntimeHandle;
102
+ private readonly bufferSize;
103
+ private readonly buffer;
104
+ private readonly startedAt;
105
+ private readonly onEvent?;
106
+ private readonly unsubscribe;
107
+ private sequence;
108
+ private lastEventAt;
109
+ constructor(options: RuntimeSupervisorOptions);
110
+ /** Point-in-time snapshot — shallow-immutable view of the buffer. */
111
+ snapshot(): RuntimeStateSnapshot;
112
+ /** Stop observing the handle. Safe to call repeatedly. */
113
+ close(): void;
114
+ private record;
115
+ }
116
+ /**
117
+ * The "no runtime" snapshot shape. Kept here so HTTP surfaces can
118
+ * serialize a consistent shape whether or not a runtime is being
119
+ * supervised.
120
+ */
121
+ export interface EmptyRuntimeStateSnapshot {
122
+ readonly present: false;
123
+ }
124
+ /** Union over present + absent, for HTTP / CLI consumption. */
125
+ export type AnyRuntimeStateSnapshot = RuntimeStateSnapshot | EmptyRuntimeStateSnapshot;
126
+ /** Convenience helper for the "no runtime" case. */
127
+ export declare function emptyRuntimeSnapshot(): EmptyRuntimeStateSnapshot;
128
+ /**
129
+ * Format an event as a single log line — used by
130
+ * {@link RuntimeSupervisor} consumers that want to forward events
131
+ * into an existing text log stream (the CLI banner log, a test
132
+ * collector, …). Stable format:
133
+ *
134
+ * [runtime status] ready
135
+ * [runtime stdout] hello
136
+ * [runtime stderr] oops
137
+ * [runtime error] boot failure
138
+ */
139
+ export declare function formatRuntimeEventLine(event: RuntimeEventRecord): string;
140
+ //# sourceMappingURL=runtime-supervisor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-supervisor.d.ts","sourceRoot":"","sources":["../src/runtime-supervisor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /** Default ring-buffer depth. Chosen to render cleanly in a CLI +
2
+ * hub panel while staying bounded in memory (~200 entries × ~1 KiB
3
+ * worst case ≈ 200 KiB). */
4
+ export const DEFAULT_RUNTIME_BUFFER_SIZE = 200;
5
+ /**
6
+ * Attach a supervisor to a running handle. Call `close()` when the
7
+ * runtime is torn down to release the subscription.
8
+ */
9
+ export class RuntimeSupervisor {
10
+ adapter;
11
+ handle;
12
+ bufferSize;
13
+ buffer = [];
14
+ startedAt;
15
+ onEvent;
16
+ unsubscribe;
17
+ sequence = 0;
18
+ lastEventAt = null;
19
+ constructor(options) {
20
+ this.adapter = options.adapter;
21
+ this.handle = options.handle;
22
+ this.bufferSize = Math.max(1, options.bufferSize ?? DEFAULT_RUNTIME_BUFFER_SIZE);
23
+ this.onEvent = options.onEvent;
24
+ this.startedAt = Date.now();
25
+ this.unsubscribe = this.handle.subscribe((event) => this.record(event));
26
+ }
27
+ /** Point-in-time snapshot — shallow-immutable view of the buffer. */
28
+ snapshot() {
29
+ return {
30
+ present: true,
31
+ name: this.adapter.name,
32
+ runId: this.handle.runId,
33
+ status: this.handle.status,
34
+ capabilities: this.adapter.capabilities,
35
+ startedAt: this.startedAt,
36
+ lastEventAt: this.lastEventAt,
37
+ // Slice so callers can't mutate the internal ring.
38
+ recentEvents: this.buffer.slice(),
39
+ };
40
+ }
41
+ /** Stop observing the handle. Safe to call repeatedly. */
42
+ close() {
43
+ this.unsubscribe();
44
+ }
45
+ record(event) {
46
+ this.sequence += 1;
47
+ const record = { ...event, sequence: this.sequence };
48
+ this.buffer.push(record);
49
+ if (this.buffer.length > this.bufferSize) {
50
+ // Drop the oldest to keep memory bounded. Ring behaviour
51
+ // without the wrap — `recentEvents` always reads
52
+ // oldest-first with monotonic `sequence` so gaps (if a buffer
53
+ // roll happened) are observable.
54
+ this.buffer.shift();
55
+ }
56
+ this.lastEventAt = event.timestamp;
57
+ try {
58
+ this.onEvent?.(record);
59
+ }
60
+ catch {
61
+ // A broken forward pipe MUST NOT break the supervisor itself
62
+ // — the snapshot would still be correct. Consumers that need
63
+ // tighter error surfacing subscribe directly to the handle.
64
+ }
65
+ }
66
+ }
67
+ /** Convenience helper for the "no runtime" case. */
68
+ export function emptyRuntimeSnapshot() {
69
+ return { present: false };
70
+ }
71
+ /**
72
+ * Format an event as a single log line — used by
73
+ * {@link RuntimeSupervisor} consumers that want to forward events
74
+ * into an existing text log stream (the CLI banner log, a test
75
+ * collector, …). Stable format:
76
+ *
77
+ * [runtime status] ready
78
+ * [runtime stdout] hello
79
+ * [runtime stderr] oops
80
+ * [runtime error] boot failure
81
+ */
82
+ export function formatRuntimeEventLine(event) {
83
+ switch (event.type) {
84
+ case 'status':
85
+ return `[runtime status] ${event.status}`;
86
+ case 'log':
87
+ return `[runtime ${event.stream}] ${event.line}`;
88
+ case 'error':
89
+ return `[runtime error] ${event.message}`;
90
+ }
91
+ }
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@ggui-ai/dev-stack",
3
+ "version": "0.1.0-rc.1",
4
+ "description": "Shared local dev engine for the ggui protocol: local UI registry discovery, compile-on-demand, filesystem watcher with SSE, and a read-only HTTP surface for dev tooling. Framework-neutral — agent runtime supervision plugs in via an adapter seam, so no agent SDK is hardcoded.",
5
+ "keywords": [
6
+ "ggui",
7
+ "dev-server",
8
+ "mcp",
9
+ "ui-registry",
10
+ "esbuild",
11
+ "generative-ui"
12
+ ],
13
+ "license": "Apache-2.0",
14
+ "type": "module",
15
+ "main": "dist/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js",
25
+ "default": "./dist/index.js"
26
+ }
27
+ },
28
+ "dependencies": {
29
+ "chokidar": "^4.0.3",
30
+ "esbuild": "^0.25.12",
31
+ "tinyglobby": "^0.2.16",
32
+ "@ggui-ai/agent-runtime": "0.1.0-rc.1",
33
+ "@ggui-ai/ui-registry": "0.1.0-rc.1",
34
+ "@ggui-ai/project-config": "0.1.0-rc.1"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^24.0.0",
38
+ "@types/react": "^19.0.0",
39
+ "@types/react-dom": "^19.0.0",
40
+ "react": "^19.0.0",
41
+ "react-dom": "^19.0.0",
42
+ "typescript": "^5.0.0",
43
+ "vitest": "^3.0.0",
44
+ "@ggui-ai/react": "0.1.0-rc.1",
45
+ "@ggui-ai/design": "0.1.0-rc.1",
46
+ "@ggui-ai/wire": "0.1.0-rc.1"
47
+ },
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/ggui-ai/ggui.git",
51
+ "directory": "packages/dev-stack"
52
+ },
53
+ "homepage": "https://github.com/ggui-ai/ggui/tree/main/packages/dev-stack",
54
+ "bugs": {
55
+ "url": "https://github.com/ggui-ai/ggui/issues"
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
60
+ "engines": {
61
+ "node": ">=20.0.0"
62
+ },
63
+ "author": "ggui contributors <hello@ggui.ai>",
64
+ "scripts": {
65
+ "build": "tsc -p tsconfig.build.json && node scripts/build-hub-preview.mjs",
66
+ "build:hub-preview": "node scripts/build-hub-preview.mjs",
67
+ "dev": "tsc --watch",
68
+ "typecheck": "tsc --noEmit && tsc -p hub-preview-client/tsconfig.json --noEmit",
69
+ "test": "vitest run",
70
+ "test:watch": "vitest"
71
+ }
72
+ }