@vgai/live 0.5.2 → 0.5.3
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/.tsbuildinfo +1 -0
- package/dist/editor.d.ts +78 -55
- package/dist/editor.js +129 -76
- package/dist/game-client/bridge-heartbeat.d.ts +49 -0
- package/dist/game-client/bridge-heartbeat.js +46 -0
- package/dist/game-client/bridge-transport.d.ts +75 -0
- package/dist/game-client/bridge-transport.js +19 -0
- package/dist/game-client/client.d.ts +293 -0
- package/dist/game-client/client.js +706 -0
- package/dist/game-client/errors.d.ts +57 -0
- package/dist/game-client/errors.js +76 -0
- package/dist/game-client/events-matcher.d.ts +41 -0
- package/dist/game-client/events-matcher.js +68 -0
- package/dist/game-client/failure-block.d.ts +93 -0
- package/dist/game-client/failure-block.js +97 -0
- package/dist/game-client/fast-forward.d.ts +125 -0
- package/dist/game-client/fast-forward.js +122 -0
- package/dist/game-client/hidden-recovery.d.ts +85 -0
- package/dist/game-client/hidden-recovery.js +105 -0
- package/dist/game-client/index.d.ts +40 -0
- package/dist/game-client/index.js +26 -0
- package/dist/game-client/perf-sampling.d.ts +56 -0
- package/dist/game-client/perf-sampling.js +85 -0
- package/dist/game-client/relay-transport.d.ts +100 -0
- package/dist/game-client/relay-transport.js +237 -0
- package/dist/game-client/screenshot-target.d.ts +60 -0
- package/dist/game-client/screenshot-target.js +68 -0
- package/dist/game-client/state-cap.d.ts +7 -0
- package/dist/game-client/state-cap.js +21 -0
- package/dist/game-client/types.d.ts +128 -0
- package/dist/game-client/types.js +15 -0
- package/dist/game-client/wait-for.d.ts +155 -0
- package/dist/game-client/wait-for.js +229 -0
- package/dist/game.d.ts +47 -18
- package/dist/game.js +59 -16
- package/dist/index.d.ts +46 -21
- package/dist/index.js +51 -20
- package/dist/session.d.ts +4 -4
- package/dist/session.js +7 -7
- package/dist/tools.d.ts +12 -3
- package/dist/tools.js +15 -6
- package/package.json +10 -5
- package/src/editor.ts +142 -96
- package/src/game-client/bridge-heartbeat.ts +61 -0
- package/src/game-client/bridge-transport.ts +73 -0
- package/src/game-client/client.ts +836 -0
- package/src/game-client/errors.ts +96 -0
- package/src/game-client/events-matcher.ts +106 -0
- package/src/game-client/failure-block.ts +199 -0
- package/src/game-client/fast-forward.ts +175 -0
- package/src/game-client/hidden-recovery.ts +149 -0
- package/src/game-client/index.ts +98 -0
- package/src/game-client/perf-sampling.ts +94 -0
- package/src/game-client/relay-transport.ts +311 -0
- package/src/game-client/screenshot-target.ts +91 -0
- package/src/game-client/state-cap.ts +29 -0
- package/src/game-client/types.ts +137 -0
- package/src/game-client/wait-for.ts +327 -0
- package/src/game.ts +96 -16
- package/src/index.ts +68 -31
- package/src/session.ts +8 -10
- package/src/tools.ts +19 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `@vgai/live` — `{ editor, game, page, tools }` over the session wire
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* CLI usage text.
|
|
2
|
+
* `@vgai/live` — `{ editor, game, page, tools }` over the session wire.
|
|
3
|
+
* Editor control consolidates HERE from the ~19 `vgai` CLI verbs: a plain
|
|
4
|
+
* node/tsx script gets `import { editor, game, page } from '@vgai/live'`
|
|
5
|
+
* instead of shelling out to the CLI — semantics are discoverable from THIS
|
|
6
|
+
* module's types, not from CLI usage text.
|
|
8
7
|
*
|
|
9
8
|
* `@vgai/live` never starts or stops a session — the CLI keeps that
|
|
10
9
|
* (`create`/`edit`/`sessions`/`close`). `connect()` (and the lazy
|
|
@@ -30,22 +29,23 @@
|
|
|
30
29
|
*
|
|
31
30
|
* `page(step)` = `GameClient.page(step)` (Wave-2's playwright-shim surface,
|
|
32
31
|
* PR #166) — write `step` as a literal `async (page) => {...}` and inline
|
|
33
|
-
* every value it needs. KNOWN WIRE LIMITATION: under the relay transport
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
32
|
+
* every value it needs. KNOWN WIRE LIMITATION: under the relay transport this
|
|
33
|
+
* binds to, `step` is shipped to the editor dev server as `step.toString()`
|
|
34
|
+
* and reconstructed there — closures over outer variables do NOT survive that
|
|
35
|
+
* trip. See `game-client/bridge-transport.ts` (`runPageScript`'s doc comment)
|
|
36
|
+
* and `game-client/relay-transport.ts` for the full honesty-boundary contract
|
|
37
|
+
* this wraps.
|
|
39
38
|
*/
|
|
40
|
-
import type { GameClient } from '@vgai/e2e';
|
|
41
39
|
import { LiveEditor } from './editor.js';
|
|
40
|
+
import { type LiveGame } from './game.js';
|
|
41
|
+
import type { GameClient } from './game-client/index.js';
|
|
42
42
|
import { type ResolvedSession, type SessionResolutionDeps } from './session.js';
|
|
43
43
|
import { LiveTools } from './tools.js';
|
|
44
|
-
export type { GameClient } from '@vgai/e2e';
|
|
45
44
|
export type { ActiveDocumentCapture, EditorClient, EditorView, EditorViewDocument, PresentedEditorView, } from '@vgai/editor-sdk';
|
|
46
|
-
export type {
|
|
45
|
+
export type { PanelName } from './editor.js';
|
|
47
46
|
export { inferAssetKind, LiveEditor } from './editor.js';
|
|
48
|
-
export { createGameClient } from './game.js';
|
|
47
|
+
export { createGameClient, createLiveGame, type LiveGame } from './game.js';
|
|
48
|
+
export * from './game-client/index.js';
|
|
49
49
|
export type { ProjectSessionHint, ResolvedSession, SessionListingTransport, SessionResolutionDeps, } from './session.js';
|
|
50
50
|
export { findProjectRootFrom, resolveSession } from './session.js';
|
|
51
51
|
export type { LazySession } from './singleton.js';
|
|
@@ -53,16 +53,41 @@ export { createLazySession } from './singleton.js';
|
|
|
53
53
|
export { LiveTools } from './tools.js';
|
|
54
54
|
/** A `game.page(step)`-shaped call — see this module's doc comment for the closure-capture limitation. */
|
|
55
55
|
export type PageStep = GameClient['page'];
|
|
56
|
-
export interface LiveSession {
|
|
56
|
+
export interface LiveSession extends LiveBindings {
|
|
57
|
+
/** The resolved session this is bound to — useful for logging/debugging which port/project a script attached to. */
|
|
58
|
+
session: ResolvedSession;
|
|
59
|
+
}
|
|
60
|
+
/** The callable half of a session: everything `vgai eval` binds except `session` itself. */
|
|
61
|
+
export interface LiveBindings {
|
|
57
62
|
editor: LiveEditor;
|
|
58
|
-
game
|
|
63
|
+
/** The game client, plus `instances()`/`instance(id)` for addressing one of
|
|
64
|
+
* several mounted instances (multiplayer authoring). A bare `game` call
|
|
65
|
+
* targets the sole instance and refuses when several are live. */
|
|
66
|
+
game: LiveGame;
|
|
59
67
|
/** `GameClient.page` bound to `game` — see this module's own doc comment for the wire limitation. */
|
|
60
68
|
page: PageStep;
|
|
61
69
|
/** Registered project callables: enumerate, inspect, and invoke. */
|
|
62
70
|
tools: LiveTools;
|
|
63
|
-
/** The resolved session this is bound to — useful for logging/debugging which port/project a script attached to. */
|
|
64
|
-
session: ResolvedSession;
|
|
65
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* The SAME `{ editor, game, page, tools }` objects `connect()` returns —
|
|
74
|
+
* real classes, real instance fields — bound to a port nothing listens on.
|
|
75
|
+
*
|
|
76
|
+
* This exists for INTROSPECTION, and specifically for `vgai eval --list`
|
|
77
|
+
* (`packages/vgai-cli/src/eval-surface.ts`), which must answer "what could I
|
|
78
|
+
* call?" before `vgai edit` is running. Reading a CLASS instead is what
|
|
79
|
+
* shipped first, and it silently omitted `game.input` and `game.events`:
|
|
80
|
+
* those are instance fields the constructor assigns, so they exist on no
|
|
81
|
+
* prototype and a class walk cannot see them — an agent reading the listing
|
|
82
|
+
* concluded there was no honest input door. Objects, not classes, is the fix,
|
|
83
|
+
* and going through `bindTo` is what keeps it honest: the probe is assembled
|
|
84
|
+
* by the same function `connect()` uses, so a binding added there is listed
|
|
85
|
+
* here with no second place to remember.
|
|
86
|
+
*
|
|
87
|
+
* Awaiting any method on these objects will fail (connection refused). Use
|
|
88
|
+
* `connect()` for that.
|
|
89
|
+
*/
|
|
90
|
+
export declare function unconnectedBindings(): LiveBindings;
|
|
66
91
|
/**
|
|
67
92
|
* Resolve `projectDir` (default `process.cwd()`) to its live `vgai edit`
|
|
68
93
|
* session and bind `{ editor, game, page }` to it. `deps` is an advanced/
|
|
@@ -73,6 +98,6 @@ export declare function connect(projectDir?: string, deps?: SessionResolutionDep
|
|
|
73
98
|
/** Test-only reset of the lazy top-level singletons' memo — NOT part of the documented public surface (real callers never need to reconnect mid-process). */
|
|
74
99
|
export declare function __resetLiveSingletonForTests(): void;
|
|
75
100
|
export declare const editor: LiveEditor;
|
|
76
|
-
export declare const game:
|
|
101
|
+
export declare const game: LiveGame;
|
|
77
102
|
export declare const page: PageStep;
|
|
78
103
|
export declare const tools: LiveTools;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `@vgai/live` — `{ editor, game, page, tools }` over the session wire
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* CLI usage text.
|
|
2
|
+
* `@vgai/live` — `{ editor, game, page, tools }` over the session wire.
|
|
3
|
+
* Editor control consolidates HERE from the ~19 `vgai` CLI verbs: a plain
|
|
4
|
+
* node/tsx script gets `import { editor, game, page } from '@vgai/live'`
|
|
5
|
+
* instead of shelling out to the CLI — semantics are discoverable from THIS
|
|
6
|
+
* module's types, not from CLI usage text.
|
|
8
7
|
*
|
|
9
8
|
* `@vgai/live` never starts or stops a session — the CLI keeps that
|
|
10
9
|
* (`create`/`edit`/`sessions`/`close`). `connect()` (and the lazy
|
|
@@ -30,26 +29,63 @@
|
|
|
30
29
|
*
|
|
31
30
|
* `page(step)` = `GameClient.page(step)` (Wave-2's playwright-shim surface,
|
|
32
31
|
* PR #166) — write `step` as a literal `async (page) => {...}` and inline
|
|
33
|
-
* every value it needs. KNOWN WIRE LIMITATION: under the relay transport
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
32
|
+
* every value it needs. KNOWN WIRE LIMITATION: under the relay transport this
|
|
33
|
+
* binds to, `step` is shipped to the editor dev server as `step.toString()`
|
|
34
|
+
* and reconstructed there — closures over outer variables do NOT survive that
|
|
35
|
+
* trip. See `game-client/bridge-transport.ts` (`runPageScript`'s doc comment)
|
|
36
|
+
* and `game-client/relay-transport.ts` for the full honesty-boundary contract
|
|
37
|
+
* this wraps.
|
|
39
38
|
*/
|
|
40
39
|
import { join } from 'node:path';
|
|
41
40
|
import { EditorClient } from '@vgai/editor-sdk';
|
|
42
41
|
import { LiveEditor } from './editor.js';
|
|
43
|
-
import {
|
|
42
|
+
import { createLiveGame } from './game.js';
|
|
44
43
|
import { lazyChainProxy } from './lazy-proxy.js';
|
|
45
44
|
import { resolveSession } from './session.js';
|
|
46
45
|
import { createLazySession } from './singleton.js';
|
|
47
46
|
import { LiveTools } from './tools.js';
|
|
48
47
|
export { inferAssetKind, LiveEditor } from './editor.js';
|
|
49
|
-
export { createGameClient } from './game.js';
|
|
48
|
+
export { createGameClient, createLiveGame } from './game.js';
|
|
49
|
+
export * from './game-client/index.js';
|
|
50
50
|
export { findProjectRootFrom, resolveSession } from './session.js';
|
|
51
51
|
export { createLazySession } from './singleton.js';
|
|
52
52
|
export { LiveTools } from './tools.js';
|
|
53
|
+
/**
|
|
54
|
+
* Construct the binding graph for an editor on `port`. Pure — every object
|
|
55
|
+
* here is built from a URL/port and contacts nothing until a method is
|
|
56
|
+
* awaited, which is what lets `unconnectedBindings()` below reuse it.
|
|
57
|
+
*/
|
|
58
|
+
function bindTo(port, projectRoot) {
|
|
59
|
+
const client = new EditorClient({ url: `http://127.0.0.1:${port}` });
|
|
60
|
+
const editor = new LiveEditor(client);
|
|
61
|
+
const game = createLiveGame(port, join(projectRoot, '.vgai', 'last-run'));
|
|
62
|
+
const page = (step) => game.page(step);
|
|
63
|
+
const tools = new LiveTools(client);
|
|
64
|
+
return { editor, game, page, tools };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The SAME `{ editor, game, page, tools }` objects `connect()` returns —
|
|
68
|
+
* real classes, real instance fields — bound to a port nothing listens on.
|
|
69
|
+
*
|
|
70
|
+
* This exists for INTROSPECTION, and specifically for `vgai eval --list`
|
|
71
|
+
* (`packages/vgai-cli/src/eval-surface.ts`), which must answer "what could I
|
|
72
|
+
* call?" before `vgai edit` is running. Reading a CLASS instead is what
|
|
73
|
+
* shipped first, and it silently omitted `game.input` and `game.events`:
|
|
74
|
+
* those are instance fields the constructor assigns, so they exist on no
|
|
75
|
+
* prototype and a class walk cannot see them — an agent reading the listing
|
|
76
|
+
* concluded there was no honest input door. Objects, not classes, is the fix,
|
|
77
|
+
* and going through `bindTo` is what keeps it honest: the probe is assembled
|
|
78
|
+
* by the same function `connect()` uses, so a binding added there is listed
|
|
79
|
+
* here with no second place to remember.
|
|
80
|
+
*
|
|
81
|
+
* Awaiting any method on these objects will fail (connection refused). Use
|
|
82
|
+
* `connect()` for that.
|
|
83
|
+
*/
|
|
84
|
+
export function unconnectedBindings() {
|
|
85
|
+
return bindTo(UNCONNECTED_PORT, process.cwd());
|
|
86
|
+
}
|
|
87
|
+
/** Port 0 is never a listening editor — an accidental call fails loudly rather than reaching a stranger's server. */
|
|
88
|
+
const UNCONNECTED_PORT = 0;
|
|
53
89
|
/**
|
|
54
90
|
* Resolve `projectDir` (default `process.cwd()`) to its live `vgai edit`
|
|
55
91
|
* session and bind `{ editor, game, page }` to it. `deps` is an advanced/
|
|
@@ -58,12 +94,7 @@ export { LiveTools } from './tools.js';
|
|
|
58
94
|
*/
|
|
59
95
|
export async function connect(projectDir, deps) {
|
|
60
96
|
const resolved = await resolveSession(projectDir, deps);
|
|
61
|
-
|
|
62
|
-
const editor = new LiveEditor(client, resolved.projectRoot);
|
|
63
|
-
const game = createGameClient(resolved.port, join(resolved.projectRoot, '.vgai', 'e2e', 'last-run'));
|
|
64
|
-
const page = (step) => game.page(step);
|
|
65
|
-
const tools = new LiveTools(client);
|
|
66
|
-
return { editor, game, page, tools, session: resolved };
|
|
97
|
+
return { ...bindTo(resolved.port, resolved.projectRoot), session: resolved };
|
|
67
98
|
}
|
|
68
99
|
// ---------------------------------------------------------------------------
|
|
69
100
|
// Lazy top-level singletons (usage form B above) — thin proxies over an
|
package/dist/session.d.ts
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* 3. Project-root discovery (`findProjectRootFrom` below) — LIFTED (not
|
|
24
24
|
* imported) from `packages/vgai-cli/src/project-root.ts`. `@vgai/sdk`'s
|
|
25
25
|
* `resolveEditorSession` takes an already-known `ctx.projectRoot`; it has
|
|
26
|
-
* no "walk up from an arbitrary cwd to find the nearest vgai.
|
|
26
|
+
* no "walk up from an arbitrary cwd to find the nearest vgai.project.json"
|
|
27
27
|
* step of its own, which `connect(projectDir?)` needs. `@vgai/cli` is
|
|
28
28
|
* `"private": true` with no `exports` field to import through (and
|
|
29
29
|
* depending on it from here would invert the intended CLI -> SDK ->
|
|
@@ -48,7 +48,7 @@ import { type EditorTransport } from '@vgai/sdk';
|
|
|
48
48
|
/**
|
|
49
49
|
* Lifted verbatim from `packages/vgai-cli/src/project-root.ts` (see this
|
|
50
50
|
* module's doc comment above for why it's duplicated rather than imported).
|
|
51
|
-
* Nearest ancestor of `dir` (inclusive) containing a `vgai.
|
|
51
|
+
* Nearest ancestor of `dir` (inclusive) containing a `vgai.project.json`, or
|
|
52
52
|
* `null` if none.
|
|
53
53
|
*/
|
|
54
54
|
export declare function findProjectRootFrom(dir: string): string | null;
|
|
@@ -57,7 +57,7 @@ export type SessionListingTransport = Pick<EditorTransport, 'listSessions'>;
|
|
|
57
57
|
export interface ResolvedSession {
|
|
58
58
|
/** Editor dev-server port the resolved session is listening on. */
|
|
59
59
|
port: number;
|
|
60
|
-
/** Absolute project root — the nearest ancestor of the requested directory containing `vgai.
|
|
60
|
+
/** Absolute project root — the nearest ancestor of the requested directory containing `vgai.project.json`. */
|
|
61
61
|
projectRoot: string;
|
|
62
62
|
}
|
|
63
63
|
export interface SessionResolutionDeps {
|
|
@@ -81,6 +81,6 @@ export interface ProjectSessionHint {
|
|
|
81
81
|
* running `vgai edit` session. Throws a descriptive error (never hangs
|
|
82
82
|
* indefinitely — bounded by `EDITOR_SESSION_DISCOVERY_TIMEOUT_MS`, and never
|
|
83
83
|
* silently attaches to an unrelated project's session — see the module doc
|
|
84
|
-
* above) when no vgai.
|
|
84
|
+
* above) when no vgai.project.json is found, or no live session covers it.
|
|
85
85
|
*/
|
|
86
86
|
export declare function resolveSession(projectDir?: string, deps?: SessionResolutionDeps): Promise<ResolvedSession>;
|
package/dist/session.js
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* 3. Project-root discovery (`findProjectRootFrom` below) — LIFTED (not
|
|
24
24
|
* imported) from `packages/vgai-cli/src/project-root.ts`. `@vgai/sdk`'s
|
|
25
25
|
* `resolveEditorSession` takes an already-known `ctx.projectRoot`; it has
|
|
26
|
-
* no "walk up from an arbitrary cwd to find the nearest vgai.
|
|
26
|
+
* no "walk up from an arbitrary cwd to find the nearest vgai.project.json"
|
|
27
27
|
* step of its own, which `connect(projectDir?)` needs. `@vgai/cli` is
|
|
28
28
|
* `"private": true` with no `exports` field to import through (and
|
|
29
29
|
* depending on it from here would invert the intended CLI -> SDK ->
|
|
@@ -50,13 +50,13 @@ import { EDITOR_SESSION_DISCOVERY_TIMEOUT_MS, HttpEditorTransport, withTimeout,
|
|
|
50
50
|
/**
|
|
51
51
|
* Lifted verbatim from `packages/vgai-cli/src/project-root.ts` (see this
|
|
52
52
|
* module's doc comment above for why it's duplicated rather than imported).
|
|
53
|
-
* Nearest ancestor of `dir` (inclusive) containing a `vgai.
|
|
53
|
+
* Nearest ancestor of `dir` (inclusive) containing a `vgai.project.json`, or
|
|
54
54
|
* `null` if none.
|
|
55
55
|
*/
|
|
56
56
|
export function findProjectRootFrom(dir) {
|
|
57
57
|
let cur = resolve(dir);
|
|
58
58
|
for (;;) {
|
|
59
|
-
if (existsSync(join(cur, 'vgai.
|
|
59
|
+
if (existsSync(join(cur, 'vgai.project.json')))
|
|
60
60
|
return cur;
|
|
61
61
|
const parent = dirname(cur);
|
|
62
62
|
if (parent === cur)
|
|
@@ -94,7 +94,7 @@ function readProjectSession(projectRoot) {
|
|
|
94
94
|
}
|
|
95
95
|
async function verifyProjectSession(hint, projectRoot) {
|
|
96
96
|
try {
|
|
97
|
-
const response = await fetch(`http://
|
|
97
|
+
const response = await fetch(`http://127.0.0.1:${hint.port}/__editor/project`, {
|
|
98
98
|
signal: AbortSignal.timeout(EDITOR_SESSION_DISCOVERY_TIMEOUT_MS),
|
|
99
99
|
});
|
|
100
100
|
if (!response.ok)
|
|
@@ -112,14 +112,14 @@ async function verifyProjectSession(hint, projectRoot) {
|
|
|
112
112
|
* running `vgai edit` session. Throws a descriptive error (never hangs
|
|
113
113
|
* indefinitely — bounded by `EDITOR_SESSION_DISCOVERY_TIMEOUT_MS`, and never
|
|
114
114
|
* silently attaches to an unrelated project's session — see the module doc
|
|
115
|
-
* above) when no vgai.
|
|
115
|
+
* above) when no vgai.project.json is found, or no live session covers it.
|
|
116
116
|
*/
|
|
117
117
|
export async function resolveSession(projectDir = process.cwd(), deps = {}) {
|
|
118
118
|
const findRoot = deps.findProjectRootFrom ?? findProjectRootFrom;
|
|
119
119
|
const transport = deps.transport ?? new HttpEditorTransport();
|
|
120
120
|
const projectRoot = findRoot(projectDir);
|
|
121
121
|
if (projectRoot === null) {
|
|
122
|
-
throw new Error(`@vgai/live: no vgai.
|
|
122
|
+
throw new Error(`@vgai/live: no vgai.project.json found in ${projectDir} or any parent directory — is this a vgai project?`);
|
|
123
123
|
}
|
|
124
124
|
// The editor writes this exact-project hint at boot and removes it on
|
|
125
125
|
// shutdown. Prefer it over a global all-session scan: it is both faster and
|
|
@@ -139,7 +139,7 @@ export async function resolveSession(projectDir = process.cwd(), deps = {}) {
|
|
|
139
139
|
sessions = [];
|
|
140
140
|
}
|
|
141
141
|
const canon = canonicalPath(projectRoot);
|
|
142
|
-
const match = sessions.find((s) => s.
|
|
142
|
+
const match = sessions.find((s) => s.project !== null && canonicalPath(s.project) === canon);
|
|
143
143
|
if (!match) {
|
|
144
144
|
const otherCount = sessions.length;
|
|
145
145
|
throw new Error(`@vgai/live: no live editor session found for ${projectRoot}. @vgai/live only attaches to ` +
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
/** Registered project tools over the current shared editor session. */
|
|
2
2
|
import type { EditorClient, ProjectToolCatalog, ProjectToolCatalogEntry, ProjectToolOutcome } from '@vgai/editor-sdk';
|
|
3
3
|
export declare class LiveTools {
|
|
4
|
-
private
|
|
4
|
+
#private;
|
|
5
5
|
constructor(client: EditorClient);
|
|
6
6
|
/** Enumerate the exact `package.json#vgai.tools` catalog without executing it. */
|
|
7
7
|
list(): Promise<ProjectToolCatalog>;
|
|
8
8
|
/** Return one tool's discoverable metadata, or `null` when it is not registered. */
|
|
9
9
|
describe(name: string): Promise<ProjectToolCatalogEntry | null>;
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Invoke the same validated callable used by the editor and CLI.
|
|
12
|
+
*
|
|
13
|
+
* `instance` names WHICH mounted instance the tool should drive when several
|
|
14
|
+
* are live (multiplayer authoring) — it reaches the tool as `ctx.instance`,
|
|
15
|
+
* and a tool that drives the game (e.g. `project.autoplay`) binds
|
|
16
|
+
* `game.instance(ctx.instance)` from it. Omitted is the single-instance case;
|
|
17
|
+
* the tool then targets the sole live instance, exactly as before.
|
|
18
|
+
*/
|
|
19
|
+
run(name: string, input?: unknown, options?: {
|
|
12
20
|
confirm?: boolean;
|
|
21
|
+
instance?: string;
|
|
13
22
|
}): Promise<ProjectToolOutcome>;
|
|
14
23
|
}
|
package/dist/tools.js
CHANGED
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
/** Registered project tools over the current shared editor session. */
|
|
2
2
|
export class LiveTools {
|
|
3
|
-
client
|
|
3
|
+
/** `#`-private for the same reason `LiveEditor.#client` is. */
|
|
4
|
+
#client;
|
|
4
5
|
constructor(client) {
|
|
5
|
-
this
|
|
6
|
+
this.#client = client;
|
|
6
7
|
}
|
|
7
8
|
/** Enumerate the exact `package.json#vgai.tools` catalog without executing it. */
|
|
8
9
|
async list() {
|
|
9
|
-
return this
|
|
10
|
+
return this.#client.listProjectTools();
|
|
10
11
|
}
|
|
11
12
|
/** Return one tool's discoverable metadata, or `null` when it is not registered. */
|
|
12
13
|
async describe(name) {
|
|
13
14
|
const catalog = await this.list();
|
|
14
15
|
return catalog.tools.find((tool) => tool.name === name) ?? null;
|
|
15
16
|
}
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Invoke the same validated callable used by the editor and CLI.
|
|
19
|
+
*
|
|
20
|
+
* `instance` names WHICH mounted instance the tool should drive when several
|
|
21
|
+
* are live (multiplayer authoring) — it reaches the tool as `ctx.instance`,
|
|
22
|
+
* and a tool that drives the game (e.g. `project.autoplay`) binds
|
|
23
|
+
* `game.instance(ctx.instance)` from it. Omitted is the single-instance case;
|
|
24
|
+
* the tool then targets the sole live instance, exactly as before.
|
|
25
|
+
*/
|
|
26
|
+
async run(name, input = {}, options = {}) {
|
|
27
|
+
return this.#client.runProjectTool(name, input, options);
|
|
19
28
|
}
|
|
20
29
|
}
|
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.
|
|
5
|
+
"version": "0.5.3",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -30,9 +30,8 @@
|
|
|
30
30
|
"build": "tsc -p tsconfig.build.json"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@vgai/editor-sdk": "0.5.
|
|
34
|
-
"@vgai/
|
|
35
|
-
"@vgai/sdk": "0.5.2"
|
|
33
|
+
"@vgai/editor-sdk": "0.5.3",
|
|
34
|
+
"@vgai/sdk": "0.5.3"
|
|
36
35
|
},
|
|
37
36
|
"peerDependencies": {
|
|
38
37
|
"@playwright/test": ">=1.58.2 <2"
|
|
@@ -41,5 +40,11 @@
|
|
|
41
40
|
"@playwright/test": "^1.58.2",
|
|
42
41
|
"@types/node": "^25.3.0",
|
|
43
42
|
"typescript": "^5.6.0"
|
|
44
|
-
}
|
|
43
|
+
},
|
|
44
|
+
"description": "Live-session client for VGAI projects: { editor, game, page, tools } over the vgai edit session wire.",
|
|
45
|
+
"keywords": [
|
|
46
|
+
"game-engine",
|
|
47
|
+
"ai-agents",
|
|
48
|
+
"game-testing"
|
|
49
|
+
]
|
|
45
50
|
}
|