@idosgames/module-sdk 0.1.0 → 0.1.2

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/index.d.cts CHANGED
@@ -18,6 +18,66 @@ interface ModuleMeta {
18
18
  genre?: string;
19
19
  engine: ModuleEngine;
20
20
  }
21
+ /** A module's author, for catalog attribution. */
22
+ interface ModuleAuthor {
23
+ name: string;
24
+ url?: string;
25
+ }
26
+ /** Preview media for a module, as hosted URLs — modules never bundle binaries. */
27
+ interface ModuleMedia {
28
+ /** Cover / preview image URL. */
29
+ image?: string;
30
+ /** Short preview or demo video URL. */
31
+ video?: string;
32
+ }
33
+ /**
34
+ * Catalog metadata for a module, authored as `module.meta.json` next to the module's package.json.
35
+ *
36
+ * This is NOT part of the runtime contract (`Module` / `ModuleMeta`) — the host never reads it. It
37
+ * feeds three consumers: the Module & Skills Registry, the platform's module picker, and the AI
38
+ * Coder's available-modules catalog. The last one is the point: the agent matches a publisher's
39
+ * prompt against `provides` and reuses a ready module instead of rebuilding the same feature.
40
+ *
41
+ * A third-party author ships one by dropping this JSON into their module folder — no code, no build
42
+ * step. Only `id`, `summary` and `provides` are required; `name`/`type`/`engine` come from the
43
+ * runtime `ModuleMeta` in `module.ts` and need not be repeated here.
44
+ */
45
+ interface ModuleManifest {
46
+ /** Must equal the module's folder / registry id (e.g. "board-game"). */
47
+ id: string;
48
+ /**
49
+ * The module's catalog type: `"template"` is a complete, ready-to-run game/app you start FROM
50
+ * (e.g. voxelcraft — a full Minecraft-like sandbox); `"feature"` is a capability you ADD to a
51
+ * project (a HUD, a shop, an event system, …). This is the catalog-facing type and is distinct
52
+ * from the runtime `ModuleMeta.type` (`game | app | ai-app`) in `module.ts`. Defaults to
53
+ * `"feature"`.
54
+ */
55
+ type?: "template" | "feature";
56
+ /** Overrides the catalog display name; defaults to `ModuleMeta.name` from `module.ts`. */
57
+ name?: string;
58
+ /** One-line pitch shown on the catalog card. */
59
+ summary: string;
60
+ /** Longer description (Markdown allowed). */
61
+ description?: string;
62
+ /**
63
+ * What functionality this module already implements, as plain feature phrases. The AI Coder
64
+ * matches a user's request against these to decide whether to reuse the module rather than write
65
+ * new code — so phrase them the way a publisher describes a feature ("turn-based dice movement",
66
+ * "buy / upgrade tiles", "offline idle income"), not as file or API names.
67
+ */
68
+ provides: string[];
69
+ /** Free-form tags for search and filtering. */
70
+ tags?: string[];
71
+ /** Preview media (hosted URLs — modules do not bundle binaries). */
72
+ media?: ModuleMedia;
73
+ /** Live, playable demo of just this module. */
74
+ demoUrl?: string;
75
+ /** Documentation link. */
76
+ docsUrl?: string;
77
+ author?: ModuleAuthor;
78
+ /** Semver of the module content; defaults to the module's package.json `version`. */
79
+ version?: string;
80
+ }
21
81
  /**
22
82
  * The manifest a module exports. The host calls `setup` exactly once, passing shared services;
23
83
  * the module registers its scene/panels/routes and returns nothing.
@@ -32,6 +92,12 @@ interface Module {
32
92
  interface ModuleContext {
33
93
  /** The one shared, already-authenticated SDK client. Modules never create their own. */
34
94
  client: IDosGamesClient;
95
+ /**
96
+ * The Title the host resolved at startup. Always use this — never re-read the title from the
97
+ * URL inside a module: the host may have resolved it from the baked project config instead,
98
+ * and a module that disagrees with its host talks to a different title's data.
99
+ */
100
+ titleId: string;
35
101
  /** Cross-module bus — e.g. an idle module emits "gold:granted", a board module reacts. */
36
102
  events: SharedEventBus;
37
103
  /** Requests host-managed DOM surfaces (canvas hosts, HUD slots) when a module needs one directly. */
@@ -42,6 +108,47 @@ interface ModuleContext {
42
108
  registerPanel(panel: UiPanel): void;
43
109
  /** Register a nav / mode entry so the player can switch to this module. */
44
110
  registerRoute(entry: RouteEntry): void;
111
+ /**
112
+ * Publish a debug surface for the AI Coder's agent — what the module IS and what it can be told
113
+ * to DO. Optional: a module without it simply stays opaque to the agent.
114
+ *
115
+ * Why it exists: the agent inspects a running app by reading the DOM, and a rendered game has no
116
+ * DOM to read — a Three/Phaser module is a single `<canvas>`. Without this the agent is blind to
117
+ * everything that matters (where the player is, what the world looks like) and cannot act at all.
118
+ * Synthetic key/mouse events are not a substitute: an engine that gates input on Pointer Lock
119
+ * ignores them, and Pointer Lock is unavailable in the preview sandbox.
120
+ *
121
+ * @see ModuleAgentApi
122
+ */
123
+ exposeToAgent(api: ModuleAgentApi): void;
124
+ }
125
+ /**
126
+ * A module's debug surface for the agent: read its state, drive it with named actions.
127
+ *
128
+ * Keep both sides SMALL and STABLE. This is a debugging contract, not a public API for gameplay:
129
+ * the agent reads `state()` to answer "what is happening" and calls an action to reproduce a bug
130
+ * ("walk forward and check you did not fall through the floor"). Actions must go through the
131
+ * module's normal input path (intents/commands) — never a second movement implementation, which
132
+ * would drift from the real one and make the agent's checks meaningless.
133
+ */
134
+ interface ModuleAgentApi {
135
+ /**
136
+ * A snapshot of what matters right now: player position/health, current screen or turn, score,
137
+ * inventory size, fps. Must be cheap (it is called per request), JSON-serializable and free of
138
+ * secrets — it is sent verbatim into an LLM prompt.
139
+ */
140
+ state(): unknown;
141
+ /**
142
+ * Named actions the agent may perform, e.g. `move({ dir: "forward", ms: 500 })`, `jump()`,
143
+ * `endTurn()`. Return whatever is useful (usually nothing — the agent reads `state()` after).
144
+ * Anything destructive to the player's saved data does NOT belong here.
145
+ */
146
+ actions?: Record<string, (args?: Record<string, unknown>) => unknown | Promise<unknown>>;
147
+ /**
148
+ * One line per action explaining what it does and which args it takes. The agent sees these
149
+ * verbatim and has no other way to learn the calling convention.
150
+ */
151
+ describeActions?: Record<string, string>;
45
152
  }
46
153
  /** Where on screen a surface lives. The host's layout decides actual placement. */
47
154
  type SurfaceKind = "fullbleed-canvas" | "sidebar-panel" | "overlay" | "hud-slot";
@@ -115,4 +222,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
115
222
  /** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
116
223
  declare function defineModule(module: Module): Module;
117
224
 
118
- export { type EngineScene, type Module, type ModuleContext, type ModuleEngine, type ModuleMeta, type ModuleType, type PanelSlot, type RouteEntry, type SceneMountContext, type SharedEventBus, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, type UiPanel, defineModule };
225
+ export { type EngineScene, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleType, type PanelSlot, type RouteEntry, type SceneMountContext, type SharedEventBus, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, type UiPanel, defineModule };
package/dist/index.d.ts CHANGED
@@ -18,6 +18,66 @@ interface ModuleMeta {
18
18
  genre?: string;
19
19
  engine: ModuleEngine;
20
20
  }
21
+ /** A module's author, for catalog attribution. */
22
+ interface ModuleAuthor {
23
+ name: string;
24
+ url?: string;
25
+ }
26
+ /** Preview media for a module, as hosted URLs — modules never bundle binaries. */
27
+ interface ModuleMedia {
28
+ /** Cover / preview image URL. */
29
+ image?: string;
30
+ /** Short preview or demo video URL. */
31
+ video?: string;
32
+ }
33
+ /**
34
+ * Catalog metadata for a module, authored as `module.meta.json` next to the module's package.json.
35
+ *
36
+ * This is NOT part of the runtime contract (`Module` / `ModuleMeta`) — the host never reads it. It
37
+ * feeds three consumers: the Module & Skills Registry, the platform's module picker, and the AI
38
+ * Coder's available-modules catalog. The last one is the point: the agent matches a publisher's
39
+ * prompt against `provides` and reuses a ready module instead of rebuilding the same feature.
40
+ *
41
+ * A third-party author ships one by dropping this JSON into their module folder — no code, no build
42
+ * step. Only `id`, `summary` and `provides` are required; `name`/`type`/`engine` come from the
43
+ * runtime `ModuleMeta` in `module.ts` and need not be repeated here.
44
+ */
45
+ interface ModuleManifest {
46
+ /** Must equal the module's folder / registry id (e.g. "board-game"). */
47
+ id: string;
48
+ /**
49
+ * The module's catalog type: `"template"` is a complete, ready-to-run game/app you start FROM
50
+ * (e.g. voxelcraft — a full Minecraft-like sandbox); `"feature"` is a capability you ADD to a
51
+ * project (a HUD, a shop, an event system, …). This is the catalog-facing type and is distinct
52
+ * from the runtime `ModuleMeta.type` (`game | app | ai-app`) in `module.ts`. Defaults to
53
+ * `"feature"`.
54
+ */
55
+ type?: "template" | "feature";
56
+ /** Overrides the catalog display name; defaults to `ModuleMeta.name` from `module.ts`. */
57
+ name?: string;
58
+ /** One-line pitch shown on the catalog card. */
59
+ summary: string;
60
+ /** Longer description (Markdown allowed). */
61
+ description?: string;
62
+ /**
63
+ * What functionality this module already implements, as plain feature phrases. The AI Coder
64
+ * matches a user's request against these to decide whether to reuse the module rather than write
65
+ * new code — so phrase them the way a publisher describes a feature ("turn-based dice movement",
66
+ * "buy / upgrade tiles", "offline idle income"), not as file or API names.
67
+ */
68
+ provides: string[];
69
+ /** Free-form tags for search and filtering. */
70
+ tags?: string[];
71
+ /** Preview media (hosted URLs — modules do not bundle binaries). */
72
+ media?: ModuleMedia;
73
+ /** Live, playable demo of just this module. */
74
+ demoUrl?: string;
75
+ /** Documentation link. */
76
+ docsUrl?: string;
77
+ author?: ModuleAuthor;
78
+ /** Semver of the module content; defaults to the module's package.json `version`. */
79
+ version?: string;
80
+ }
21
81
  /**
22
82
  * The manifest a module exports. The host calls `setup` exactly once, passing shared services;
23
83
  * the module registers its scene/panels/routes and returns nothing.
@@ -32,6 +92,12 @@ interface Module {
32
92
  interface ModuleContext {
33
93
  /** The one shared, already-authenticated SDK client. Modules never create their own. */
34
94
  client: IDosGamesClient;
95
+ /**
96
+ * The Title the host resolved at startup. Always use this — never re-read the title from the
97
+ * URL inside a module: the host may have resolved it from the baked project config instead,
98
+ * and a module that disagrees with its host talks to a different title's data.
99
+ */
100
+ titleId: string;
35
101
  /** Cross-module bus — e.g. an idle module emits "gold:granted", a board module reacts. */
36
102
  events: SharedEventBus;
37
103
  /** Requests host-managed DOM surfaces (canvas hosts, HUD slots) when a module needs one directly. */
@@ -42,6 +108,47 @@ interface ModuleContext {
42
108
  registerPanel(panel: UiPanel): void;
43
109
  /** Register a nav / mode entry so the player can switch to this module. */
44
110
  registerRoute(entry: RouteEntry): void;
111
+ /**
112
+ * Publish a debug surface for the AI Coder's agent — what the module IS and what it can be told
113
+ * to DO. Optional: a module without it simply stays opaque to the agent.
114
+ *
115
+ * Why it exists: the agent inspects a running app by reading the DOM, and a rendered game has no
116
+ * DOM to read — a Three/Phaser module is a single `<canvas>`. Without this the agent is blind to
117
+ * everything that matters (where the player is, what the world looks like) and cannot act at all.
118
+ * Synthetic key/mouse events are not a substitute: an engine that gates input on Pointer Lock
119
+ * ignores them, and Pointer Lock is unavailable in the preview sandbox.
120
+ *
121
+ * @see ModuleAgentApi
122
+ */
123
+ exposeToAgent(api: ModuleAgentApi): void;
124
+ }
125
+ /**
126
+ * A module's debug surface for the agent: read its state, drive it with named actions.
127
+ *
128
+ * Keep both sides SMALL and STABLE. This is a debugging contract, not a public API for gameplay:
129
+ * the agent reads `state()` to answer "what is happening" and calls an action to reproduce a bug
130
+ * ("walk forward and check you did not fall through the floor"). Actions must go through the
131
+ * module's normal input path (intents/commands) — never a second movement implementation, which
132
+ * would drift from the real one and make the agent's checks meaningless.
133
+ */
134
+ interface ModuleAgentApi {
135
+ /**
136
+ * A snapshot of what matters right now: player position/health, current screen or turn, score,
137
+ * inventory size, fps. Must be cheap (it is called per request), JSON-serializable and free of
138
+ * secrets — it is sent verbatim into an LLM prompt.
139
+ */
140
+ state(): unknown;
141
+ /**
142
+ * Named actions the agent may perform, e.g. `move({ dir: "forward", ms: 500 })`, `jump()`,
143
+ * `endTurn()`. Return whatever is useful (usually nothing — the agent reads `state()` after).
144
+ * Anything destructive to the player's saved data does NOT belong here.
145
+ */
146
+ actions?: Record<string, (args?: Record<string, unknown>) => unknown | Promise<unknown>>;
147
+ /**
148
+ * One line per action explaining what it does and which args it takes. The agent sees these
149
+ * verbatim and has no other way to learn the calling convention.
150
+ */
151
+ describeActions?: Record<string, string>;
45
152
  }
46
153
  /** Where on screen a surface lives. The host's layout decides actual placement. */
47
154
  type SurfaceKind = "fullbleed-canvas" | "sidebar-panel" | "overlay" | "hud-slot";
@@ -115,4 +222,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
115
222
  /** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
116
223
  declare function defineModule(module: Module): Module;
117
224
 
118
- export { type EngineScene, type Module, type ModuleContext, type ModuleEngine, type ModuleMeta, type ModuleType, type PanelSlot, type RouteEntry, type SceneMountContext, type SharedEventBus, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, type UiPanel, defineModule };
225
+ export { type EngineScene, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleType, type PanelSlot, type RouteEntry, type SceneMountContext, type SharedEventBus, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, type UiPanel, defineModule };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idosgames/module-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "The composable-module contract for the iDosGames host shell: Module / ModuleContext types plus tiny authoring helpers. Framework-neutral at runtime — a module can be a game (Three/Phaser), a plain app, or an AI app.",
5
5
  "type": "module",
6
6
  "license": "MIT",