@vgai/live 0.5.32 → 0.5.35

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 (55) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{vgai-live/src/session.js → session.js} +1 -2
  3. package/package.json +4 -4
  4. package/src/session.ts +1 -1
  5. package/dist/vgai-sdk/src/editor/session-registry-format.d.ts +0 -81
  6. package/dist/vgai-sdk/src/editor/session-registry-format.js +0 -158
  7. /package/dist/{vgai-live/src/editor-document.d.ts → editor-document.d.ts} +0 -0
  8. /package/dist/{vgai-live/src/editor-document.js → editor-document.js} +0 -0
  9. /package/dist/{vgai-live/src/editor.d.ts → editor.d.ts} +0 -0
  10. /package/dist/{vgai-live/src/editor.js → editor.js} +0 -0
  11. /package/dist/{vgai-live/src/game-client → game-client}/bridge-heartbeat.d.ts +0 -0
  12. /package/dist/{vgai-live/src/game-client → game-client}/bridge-heartbeat.js +0 -0
  13. /package/dist/{vgai-live/src/game-client → game-client}/bridge-transport.d.ts +0 -0
  14. /package/dist/{vgai-live/src/game-client → game-client}/bridge-transport.js +0 -0
  15. /package/dist/{vgai-live/src/game-client → game-client}/capture-notes.d.ts +0 -0
  16. /package/dist/{vgai-live/src/game-client → game-client}/capture-notes.js +0 -0
  17. /package/dist/{vgai-live/src/game-client → game-client}/client.d.ts +0 -0
  18. /package/dist/{vgai-live/src/game-client → game-client}/client.js +0 -0
  19. /package/dist/{vgai-live/src/game-client → game-client}/errors.d.ts +0 -0
  20. /package/dist/{vgai-live/src/game-client → game-client}/errors.js +0 -0
  21. /package/dist/{vgai-live/src/game-client → game-client}/events-matcher.d.ts +0 -0
  22. /package/dist/{vgai-live/src/game-client → game-client}/events-matcher.js +0 -0
  23. /package/dist/{vgai-live/src/game-client → game-client}/failure-block.d.ts +0 -0
  24. /package/dist/{vgai-live/src/game-client → game-client}/failure-block.js +0 -0
  25. /package/dist/{vgai-live/src/game-client → game-client}/fast-forward.d.ts +0 -0
  26. /package/dist/{vgai-live/src/game-client → game-client}/fast-forward.js +0 -0
  27. /package/dist/{vgai-live/src/game-client → game-client}/hidden-recovery.d.ts +0 -0
  28. /package/dist/{vgai-live/src/game-client → game-client}/hidden-recovery.js +0 -0
  29. /package/dist/{vgai-live/src/game-client → game-client}/index.d.ts +0 -0
  30. /package/dist/{vgai-live/src/game-client → game-client}/index.js +0 -0
  31. /package/dist/{vgai-live/src/game-client → game-client}/perf-sampling.d.ts +0 -0
  32. /package/dist/{vgai-live/src/game-client → game-client}/perf-sampling.js +0 -0
  33. /package/dist/{vgai-live/src/game-client → game-client}/relay-transport.d.ts +0 -0
  34. /package/dist/{vgai-live/src/game-client → game-client}/relay-transport.js +0 -0
  35. /package/dist/{vgai-live/src/game-client → game-client}/screenshot-target.d.ts +0 -0
  36. /package/dist/{vgai-live/src/game-client → game-client}/screenshot-target.js +0 -0
  37. /package/dist/{vgai-live/src/game-client → game-client}/state-cap.d.ts +0 -0
  38. /package/dist/{vgai-live/src/game-client → game-client}/state-cap.js +0 -0
  39. /package/dist/{vgai-live/src/game-client → game-client}/types.d.ts +0 -0
  40. /package/dist/{vgai-live/src/game-client → game-client}/types.js +0 -0
  41. /package/dist/{vgai-live/src/game-client → game-client}/wait-for.d.ts +0 -0
  42. /package/dist/{vgai-live/src/game-client → game-client}/wait-for.js +0 -0
  43. /package/dist/{vgai-live/src/game.d.ts → game.d.ts} +0 -0
  44. /package/dist/{vgai-live/src/game.js → game.js} +0 -0
  45. /package/dist/{vgai-live/src/index.d.ts → index.d.ts} +0 -0
  46. /package/dist/{vgai-live/src/index.js → index.js} +0 -0
  47. /package/dist/{vgai-live/src/lazy-proxy.d.ts → lazy-proxy.d.ts} +0 -0
  48. /package/dist/{vgai-live/src/lazy-proxy.js → lazy-proxy.js} +0 -0
  49. /package/dist/{vgai-live/src/recording.d.ts → recording.d.ts} +0 -0
  50. /package/dist/{vgai-live/src/recording.js → recording.js} +0 -0
  51. /package/dist/{vgai-live/src/session.d.ts → session.d.ts} +0 -0
  52. /package/dist/{vgai-live/src/singleton.d.ts → singleton.d.ts} +0 -0
  53. /package/dist/{vgai-live/src/singleton.js → singleton.js} +0 -0
  54. /package/dist/{vgai-live/src/tools.d.ts → tools.d.ts} +0 -0
  55. /package/dist/{vgai-live/src/tools.js → tools.js} +0 -0
@@ -46,8 +46,7 @@
46
46
  */
47
47
  import { existsSync, readFileSync, realpathSync } from 'node:fs';
48
48
  import { dirname, join, resolve } from 'node:path';
49
- import { EDITOR_SESSION_DISCOVERY_TIMEOUT_MS, HttpEditorTransport, withTimeout, } from '@vgai/sdk';
50
- import { servedProjectAnswer } from '../../vgai-sdk/src/editor/session-registry-format';
49
+ import { EDITOR_SESSION_DISCOVERY_TIMEOUT_MS, HttpEditorTransport, servedProjectAnswer, withTimeout, } from '@vgai/sdk';
51
50
  /**
52
51
  * Lifted verbatim from `packages/vgai-cli/src/project-root.ts` (see this
53
52
  * module's doc comment above for why it's duplicated rather than imported).
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@vgai/live",
3
3
  "author": "Volter AI, Inc.",
4
4
  "license": "Apache-2.0",
5
- "version": "0.5.32",
5
+ "version": "0.5.35",
6
6
  "type": "module",
7
7
  "repository": {
8
8
  "type": "git",
@@ -27,13 +27,13 @@
27
27
  "node": ">=22.0.0"
28
28
  },
29
29
  "scripts": {
30
- "build": "tsc -p tsconfig.build.json",
30
+ "build": "tsc -p tsconfig.build.json && node ../../scripts/check-live-build-output.mjs",
31
31
  "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput",
32
32
  "prepack": "npm run build"
33
33
  },
34
34
  "dependencies": {
35
- "@vgai/editor-sdk": "0.5.32",
36
- "@vgai/sdk": "0.5.32"
35
+ "@vgai/editor-sdk": "0.5.35",
36
+ "@vgai/sdk": "0.5.35"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@playwright/test": ">=1.58.2 <2"
package/src/session.ts CHANGED
@@ -52,9 +52,9 @@ import {
52
52
  type EditorSessionInfo,
53
53
  type EditorTransport,
54
54
  HttpEditorTransport,
55
+ servedProjectAnswer,
55
56
  withTimeout,
56
57
  } from '@vgai/sdk';
57
- import { servedProjectAnswer } from '../../vgai-sdk/src/editor/session-registry-format';
58
58
 
59
59
  /**
60
60
  * Lifted verbatim from `packages/vgai-cli/src/project-root.ts` (see this
@@ -1,81 +0,0 @@
1
- /**
2
- * `~/.vgai/editor-sessions.json` — the ONE spelling of the editor-session
3
- * registry contract, and the shared machinery every reader was hand-copying.
4
- *
5
- * The registry's WRITE half stays with its owner
6
- * (`packages/editor/server/session-registry.ts`); this module owns the
7
- * FORMAT: the entry shape, the shape guards, the file path, the
8
- * liveness-filtered read, the `/__editor/project` answer parser, and the
9
- * deterministic session-selection core. It existed as FOUR drifting copies
10
- * (server registry, the CLI, and both vgai-sdk transports) held together by
11
- * a "the CLI has no editor dependency" premise that had stopped being true —
12
- * and the drift was already real: one copy's `/__editor/project` parser
13
- * dropped `manifestError`, reporting a degraded session as belonging to no
14
- * project.
15
- */
16
- /** One registry entry, exactly as the server's write half records it. */
17
- export interface EditorSessionEntry {
18
- /** Canonical project root currently open, or null when none. */
19
- project: string | null;
20
- port: number;
21
- /** PID of the dev-server process. */
22
- pid: number;
23
- /** ISO timestamp of server start. */
24
- startedAt: string;
25
- sessionId: string | null;
26
- /** Private loopback control credential — never returned by an editor HTTP
27
- * route; exists only in this user-private registry. */
28
- controlSecret?: string | null;
29
- repositoryId: string | null;
30
- worktreeId: string | null;
31
- worktreeRoot: string | null;
32
- projectRelativePath: string | null;
33
- branch: string | null;
34
- headCommit: string | null;
35
- baseCommit: string | null;
36
- }
37
- export declare const EDITOR_SESSIONS_REGISTRY_FILE: string;
38
- export declare function isEditorSessionEntry(v: unknown): v is EditorSessionEntry;
39
- export declare function normalizeEditorSessionEntry(session: EditorSessionEntry): EditorSessionEntry;
40
- export declare function pidAlive(pid: number): boolean;
41
- /** The registry's live entries — shape-validated and PID-liveness-filtered. */
42
- export declare function readLiveRegisteredSessions(): EditorSessionEntry[];
43
- /**
44
- * WHICH PROJECT a `/__editor/project` body says its server is serving.
45
- *
46
- * `serving` is that server's own statement of "I AM serving this project, I
47
- * just cannot describe it" (its manifest is unparseable or fails strict
48
- * validation) — added to the route precisely because a bare
49
- * `{ project: null }` is indistinguishable from "no project open". Reading
50
- * only `project.path` collapses the two, and the cost is that every
51
- * project-matched command loses a live session the moment a save breaks its
52
- * manifest, reporting it as belonging to no project rather than as this
53
- * project's degraded session.
54
- */
55
- export declare function servedProjectAnswer(body: unknown): {
56
- path: string | null;
57
- manifestError: string | null;
58
- };
59
- /**
60
- * Deterministic session selection — the ONE precedence order every surface
61
- * follows: explicit `ctx.editorUrl` probe > port match against the listing >
62
- * `ctx.projectRoot` match > lowest live port > not-running. Generic over the
63
- * session shape so the editor and play transports (whose probe results
64
- * differ) share the algorithm rather than a copy of it.
65
- */
66
- export declare function resolveRegisteredSession<T extends {
67
- port: number;
68
- project: string | null;
69
- url?: string;
70
- }>(ctx: {
71
- editorUrl?: string | undefined;
72
- projectRoot?: string | undefined;
73
- }, transport: {
74
- listSessions(timeoutMs: number): Promise<T[]>;
75
- probeSessionUrl?: ((url: string, timeoutMs: number) => Promise<T | null | undefined>) | undefined;
76
- }, options: {
77
- probeTimeoutMs: number;
78
- discoveryTimeoutMs: number;
79
- withTimeout: <V>(work: Promise<V>, timeoutMs: number, what: string) => Promise<V>;
80
- notRunning: () => never;
81
- }): Promise<T>;
@@ -1,158 +0,0 @@
1
- /**
2
- * `~/.vgai/editor-sessions.json` — the ONE spelling of the editor-session
3
- * registry contract, and the shared machinery every reader was hand-copying.
4
- *
5
- * The registry's WRITE half stays with its owner
6
- * (`packages/editor/server/session-registry.ts`); this module owns the
7
- * FORMAT: the entry shape, the shape guards, the file path, the
8
- * liveness-filtered read, the `/__editor/project` answer parser, and the
9
- * deterministic session-selection core. It existed as FOUR drifting copies
10
- * (server registry, the CLI, and both vgai-sdk transports) held together by
11
- * a "the CLI has no editor dependency" premise that had stopped being true —
12
- * and the drift was already real: one copy's `/__editor/project` parser
13
- * dropped `manifestError`, reporting a degraded session as belonging to no
14
- * project.
15
- */
16
- import { readFileSync, realpathSync } from 'node:fs';
17
- import { homedir } from 'node:os';
18
- import { join, resolve } from 'node:path';
19
- export const EDITOR_SESSIONS_REGISTRY_FILE = join(homedir(), '.vgai', 'editor-sessions.json');
20
- export function isEditorSessionEntry(v) {
21
- if (typeof v !== 'object' || v === null)
22
- return false;
23
- const s = v;
24
- const optionalIdentity = (value) => value === undefined || value === null || typeof value === 'string';
25
- return ((typeof s['project'] === 'string' || s['project'] === null) &&
26
- typeof s['port'] === 'number' &&
27
- typeof s['pid'] === 'number' &&
28
- typeof s['startedAt'] === 'string' &&
29
- optionalIdentity(s['sessionId']) &&
30
- optionalIdentity(s['controlSecret']) &&
31
- optionalIdentity(s['repositoryId']) &&
32
- optionalIdentity(s['worktreeId']) &&
33
- optionalIdentity(s['worktreeRoot']) &&
34
- optionalIdentity(s['projectRelativePath']) &&
35
- optionalIdentity(s['branch']) &&
36
- optionalIdentity(s['headCommit']) &&
37
- optionalIdentity(s['baseCommit']));
38
- }
39
- export function normalizeEditorSessionEntry(session) {
40
- return {
41
- ...session,
42
- sessionId: session.sessionId ?? null,
43
- controlSecret: session.controlSecret ?? null,
44
- repositoryId: session.repositoryId ?? null,
45
- worktreeId: session.worktreeId ?? null,
46
- worktreeRoot: session.worktreeRoot ?? null,
47
- projectRelativePath: session.projectRelativePath ?? null,
48
- branch: session.branch ?? null,
49
- headCommit: session.headCommit ?? null,
50
- baseCommit: session.baseCommit ?? null,
51
- };
52
- }
53
- export function pidAlive(pid) {
54
- try {
55
- process.kill(pid, 0);
56
- return true;
57
- }
58
- catch {
59
- return false;
60
- }
61
- }
62
- /** The registry's live entries — shape-validated and PID-liveness-filtered. */
63
- export function readLiveRegisteredSessions() {
64
- try {
65
- const raw = JSON.parse(readFileSync(EDITOR_SESSIONS_REGISTRY_FILE, 'utf8'));
66
- return Array.isArray(raw)
67
- ? raw
68
- .filter(isEditorSessionEntry)
69
- .map(normalizeEditorSessionEntry)
70
- .filter((s) => pidAlive(s.pid))
71
- : [];
72
- }
73
- catch {
74
- return [];
75
- }
76
- }
77
- /**
78
- * WHICH PROJECT a `/__editor/project` body says its server is serving.
79
- *
80
- * `serving` is that server's own statement of "I AM serving this project, I
81
- * just cannot describe it" (its manifest is unparseable or fails strict
82
- * validation) — added to the route precisely because a bare
83
- * `{ project: null }` is indistinguishable from "no project open". Reading
84
- * only `project.path` collapses the two, and the cost is that every
85
- * project-matched command loses a live session the moment a save breaks its
86
- * manifest, reporting it as belonging to no project rather than as this
87
- * project's degraded session.
88
- */
89
- export function servedProjectAnswer(body) {
90
- const b = body;
91
- return {
92
- path: b.project?.path ?? b.serving?.path ?? null,
93
- manifestError: b.project ? null : (b.serving?.error ?? null),
94
- };
95
- }
96
- /** Canonical (realpathed when possible) absolute form of a project path. */
97
- function canonicalizeProjectPath(p) {
98
- const absolute = resolve(p);
99
- try {
100
- return realpathSync(absolute);
101
- }
102
- catch {
103
- return absolute;
104
- }
105
- }
106
- /** Extract the port from an `http(s)://host:port` URL, or undefined if unparseable. */
107
- function portOfUrl(url) {
108
- try {
109
- const port = new URL(url).port;
110
- return port ? Number(port) : undefined;
111
- }
112
- catch {
113
- return undefined;
114
- }
115
- }
116
- /**
117
- * Deterministic session selection — the ONE precedence order every surface
118
- * follows: explicit `ctx.editorUrl` probe > port match against the listing >
119
- * `ctx.projectRoot` match > lowest live port > not-running. Generic over the
120
- * session shape so the editor and play transports (whose probe results
121
- * differ) share the algorithm rather than a copy of it.
122
- */
123
- export async function resolveRegisteredSession(ctx, transport, options) {
124
- const editorUrl = ctx.editorUrl;
125
- if (editorUrl !== undefined && transport.probeSessionUrl) {
126
- try {
127
- const session = await options.withTimeout(transport.probeSessionUrl(editorUrl, options.probeTimeoutMs), options.probeTimeoutMs, 'explicit editor URL probe');
128
- if (session)
129
- return session;
130
- }
131
- catch { }
132
- return options.notRunning();
133
- }
134
- let sessions;
135
- try {
136
- sessions = await options.withTimeout(transport.listSessions(options.discoveryTimeoutMs), options.discoveryTimeoutMs, 'editor session discovery');
137
- }
138
- catch {
139
- return options.notRunning();
140
- }
141
- if (sessions.length === 0)
142
- return options.notRunning();
143
- if (editorUrl !== undefined) {
144
- const port = portOfUrl(editorUrl);
145
- const match = sessions.find((s) => s.port === port);
146
- if (!match)
147
- return options.notRunning();
148
- return { ...match, url: editorUrl.replace(/\/+$/, '') };
149
- }
150
- if (ctx.projectRoot !== undefined) {
151
- const canon = canonicalizeProjectPath(ctx.projectRoot);
152
- const match = sessions.find((s) => s.project !== null && canonicalizeProjectPath(s.project) === canon);
153
- if (!match)
154
- return options.notRunning();
155
- return match;
156
- }
157
- return [...sessions].sort((a, b) => a.port - b.port)[0];
158
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes