@autopo/mcp 0.0.0-stage → 0.1.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -2
  3. package/dist/api.d.ts +51 -0
  4. package/dist/api.js +107 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/apps.d.ts +10 -0
  7. package/dist/apps.js +146 -0
  8. package/dist/apps.js.map +1 -0
  9. package/dist/cli.d.ts +2 -0
  10. package/dist/cli.js +63 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/guides.d.ts +3 -0
  13. package/dist/guides.js +52 -0
  14. package/dist/guides.js.map +1 -0
  15. package/dist/http.d.ts +20 -0
  16. package/dist/http.js +119 -0
  17. package/dist/http.js.map +1 -0
  18. package/dist/index.d.ts +4 -0
  19. package/dist/index.js +5 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/kit.d.ts +149 -0
  22. package/dist/kit.js +206 -0
  23. package/dist/kit.js.map +1 -0
  24. package/dist/prompts.d.ts +3 -0
  25. package/dist/prompts.js +44 -0
  26. package/dist/prompts.js.map +1 -0
  27. package/dist/resources.d.ts +4 -0
  28. package/dist/resources.js +40 -0
  29. package/dist/resources.js.map +1 -0
  30. package/dist/server.d.ts +24 -0
  31. package/dist/server.js +40 -0
  32. package/dist/server.js.map +1 -0
  33. package/dist/tools/company.d.ts +4 -0
  34. package/dist/tools/company.js +431 -0
  35. package/dist/tools/company.js.map +1 -0
  36. package/dist/tools/marketing.d.ts +4 -0
  37. package/dist/tools/marketing.js +214 -0
  38. package/dist/tools/marketing.js.map +1 -0
  39. package/dist/tools/studio.d.ts +9 -0
  40. package/dist/tools/studio.js +363 -0
  41. package/dist/tools/studio.js.map +1 -0
  42. package/dist/ui/gallery.html +124 -0
  43. package/dist/ui/home.html +124 -0
  44. package/dist/ui/inbox.html +124 -0
  45. package/dist/ui/money.html +124 -0
  46. package/dist/ui/storyboard.html +124 -0
  47. package/package.json +71 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Autopoiesis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,120 @@
1
- # Temporary Holding Version
1
+ <p align="center">
2
+ <img src="https://autopoiesis.app/favicon.svg" width="56" alt="" />
3
+ </p>
4
+ <h1 align="center">Autopoiesis MCP</h1>
5
+ <p align="center">Run your AI-run company from Claude Code, Codex, Cursor, Claude Desktop or ChatGPT.<br/>
6
+ Briefings, the Board inbox, tasks, the team, the Studio, marketing, money: as you, with your permissions.</p>
2
7
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/@autopo/mcp"><img src="https://img.shields.io/npm/v/%40autopo%2Fmcp?color=B8F36B&label=npm" alt="npm" /></a>
10
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-black" alt="MIT" /></a>
11
+ </p>
12
+
13
+ ```text
14
+ you › make a 20-second teaser for our launch
15
+ › brand_brain · create_video · ask_agent creative · video_keyframes (confirm $0.09) · critique_video
16
+ › make_video_media (confirm $1.20) · wait_for_video · render_video · open_in_app
17
+ you › approve the hosting card and tell Kaveh to go
18
+ ```
19
+
20
+ ## Connect in a minute
21
+
22
+ 1. In the app: **Connectors → MCP → Make the token**. Copy it; it is shown once.
23
+ 2. Paste one line into your tool.
24
+
25
+ **Claude Code**
26
+
27
+ ```sh
28
+ claude mcp add --transport http autopoiesis https://autopoiesis-api-267405155162.us-west1.run.app/mcp --header "Authorization: Bearer apk_…"
29
+ ```
30
+
31
+ **Codex** (`~/.codex/config.toml`, then `export AUTOPOIESIS_TOKEN=apk_…`)
32
+
33
+ ```toml
34
+ [mcp_servers.autopoiesis]
35
+ url = "https://autopoiesis-api-267405155162.us-west1.run.app/mcp"
36
+ bearer_token_env_var = "AUTOPOIESIS_TOKEN"
37
+ ```
38
+
39
+ **Cursor** (`~/.cursor/mcp.json`, or the *Add to Cursor* button on the Connectors page)
40
+
41
+ ```json
42
+ { "mcpServers": { "autopoiesis": { "url": "https://autopoiesis-api-267405155162.us-west1.run.app/mcp", "headers": { "Authorization": "Bearer apk_…" } } } }
43
+ ```
44
+
45
+ **Claude Desktop** (`claude_desktop_config.json`): inline views render here.
46
+
47
+ ```json
48
+ { "mcpServers": { "autopoiesis": { "command": "npx", "args": ["-y", "@autopo/mcp"], "env": { "AUTOPOIESIS_TOKEN": "apk_…" } } } }
49
+ ```
50
+
51
+ Prefer to run the server on your machine with any tool? `npx -y @autopo/mcp` with `AUTOPOIESIS_TOKEN` set is the whole install.
52
+
53
+ ## What it does
54
+
55
+ | | |
56
+ |---|---|
57
+ | **63 tools** | the company at a glance, briefings, the inbox, tasks, the team's chats, runs, knowledge, the Studio, marketing, money, and `api_request` for every other endpoint of the REST API with `api_reference` as the manual |
58
+ | **Asks before it spends** | anything that spends credits or cannot be undone opens a confirmation dialog in your tool, with the cost: generate media, keyframes, clips, decide a card, post, cancel, delete |
59
+ | **Inline views** | the inbox, a video's storyboard, the media library, your home and the money page render inside Cursor, Claude Desktop and ChatGPT ([MCP Apps](https://modelcontextprotocol.io/extensions/apps/overview)); Claude Code and Codex CLI get the same results as text |
60
+ | **Docs** | [docs.autopoiesis.app](https://docs.autopoiesis.app): quickstart per client, guides, the tool reference, the REST API |
61
+ | **Prompts** | `/autopoiesis:make_a_teaser`, `morning_review`, `decide_inbox`, `studio_status`, `weekly_marketing` |
62
+ | **Resources** | the Studio guide, the teaser guide, a company's home and brand brain, the API's OpenAPI document |
63
+ | **Both protocol eras** | the stateless 2026-07-28 revision and the 2025 `initialize` handshake today's clients speak, from one endpoint |
64
+
65
+ Everything happens as you: your permissions, member access areas, limits and billing hold exactly as in the app, and it all shows in the app as you did it. A token can be scoped to one company and revoked at any time; it can never make tokens, delete the account or hand a company over.
66
+
67
+ ## The teaser loop
68
+
69
+ ```text
70
+ brand_brain → create_video {title, brief, seconds: 20}
71
+ → get_video → ask_agent {agent: "creative", production: <id>, message: "tighten the shots"} → apply_chat_action
72
+ → studio_overview → update_video {style: {models}} (only if the defaults don't fit)
73
+ → video_keyframes (you confirm the cents) → wait_for_video → critique_video {stage: "keyframes"}
74
+ → make_video_media (you confirm the cost) → wait_for_video → critique_video {stage: "clips"}
75
+ → render_video (free) → wait_for_video → the render link, or open_in_app {what: "video", id}
76
+ ```
77
+
78
+ The `make_a_teaser` prompt runs this for you, step by step, stopping at every dialog.
79
+
80
+ ## Run it yourself
81
+
82
+ ```sh
83
+ npx -y @autopo/mcp # stdio, for a tool on this machine (AUTOPOIESIS_TOKEN)
84
+ npx -y @autopo/mcp --http # Streamable HTTP on PORT, one token per request (Authorization: Bearer)
85
+ ```
86
+
87
+ | Variable | What it is |
88
+ |---|---|
89
+ | `AUTOPOIESIS_TOKEN` | your personal access token (stdio only; HTTP takes it per request) |
90
+ | `AUTOPOIESIS_API_URL` | the platform API (default: the production API) |
91
+ | `AUTOPOIESIS_APP_URL` | the web app, for links (default `https://app.autopoiesis.app`) |
92
+ | `AUTOPOIESIS_MCP_URL` | this server's public address when hosted (names the Claude sandbox domain for the views) |
93
+ | `AUTOPOIESIS_MEDIA_DOMAINS` | extra origins the views may load media from, comma separated |
94
+
95
+ A `Dockerfile` builds the hosted server (Cloud Run: `PORT` is set for you; turn on session affinity so 2025-era clients keep their session on one instance).
96
+
97
+ ## Develop
98
+
99
+ The source lives in Autopoiesis' repository; this package ships the built server and views.
100
+
101
+ ```sh
102
+ npm install
103
+ npm run typecheck # server + views
104
+ npm test # the server against an in-memory API, both protocol eras
105
+ npm run build # dist/ (server) and dist/ui/*.html (the views, one file each)
106
+ npm run docs:tools # docs/tools/*.mdx from the server's own tool list
107
+ npm run dev # the stdio server from source (tsx)
108
+ npx @modelcontextprotocol/inspector node dist/cli.js
109
+ ```
110
+
111
+ Layout: `src/tools/*` (the tools, grouped the way the app is), `src/kit.ts` (sessions, elicitation, the `define()` wrapper), `src/apps.ts` (the inline views' resources and the app-only tools their buttons call), `src/http.ts` (the hosted server, both protocol legs), `ui/*` (the views, React, built to one HTML file each), `docs/` (the documentation site, Mintlify), `test/` (an in-memory API and the end-to-end tests).
112
+
113
+ ## Security
114
+
115
+ - The token is a hashed secret the platform checks on every call; this server forwards it and never stores it.
116
+ - Every tool is a thin wrapper over the public REST API, so nothing here can do what you could not do in the app.
117
+ - Confirmations are host-enforced dialogs (MCP elicitation), not instructions the model may skip. Hosts that cannot show them get a refusal, never a silent spend.
118
+ - Report a vulnerability to security@autopoiesis.app.
119
+
120
+ MIT © Autopoiesis. Questions: support@autopoiesis.app
package/dist/api.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The platform's REST API, called as the person whose token this is. Every MCP tool is a thin wrapper over these
3
+ * endpoints, so permissions, member access areas, limits, billing and the user action log hold exactly as in the app:
4
+ * the server never sees anything the person could not do themselves.
5
+ */
6
+ export interface ApiErrorBody {
7
+ error?: {
8
+ code?: string;
9
+ message?: string;
10
+ fields?: Record<string, string[]>;
11
+ };
12
+ raw?: string;
13
+ }
14
+ export declare class ApiError extends Error {
15
+ readonly status: number;
16
+ readonly code: string | undefined;
17
+ readonly body: ApiErrorBody;
18
+ constructor(status: number, body: ApiErrorBody);
19
+ }
20
+ export type Query = Record<string, string | number | boolean | null | undefined>;
21
+ export interface ApiOptions {
22
+ /** The API's origin, e.g. https://api.example.com (no trailing slash). */
23
+ baseUrl: string;
24
+ /** The person's token: a personal access token (apk_…) made on the Connectors page, or the app's own JWT. */
25
+ token: string;
26
+ fetch?: typeof fetch;
27
+ userAgent?: string;
28
+ }
29
+ export declare class Api {
30
+ readonly baseUrl: string;
31
+ private readonly token;
32
+ private readonly fetchImpl;
33
+ private readonly userAgent;
34
+ constructor(options: ApiOptions);
35
+ request<T = unknown>(method: string, path: string, body?: unknown, query?: Query): Promise<T>;
36
+ get<T = unknown>(path: string, query?: Query): Promise<T>;
37
+ post<T = unknown>(path: string, body?: unknown, query?: Query): Promise<T>;
38
+ patch<T = unknown>(path: string, body: unknown): Promise<T>;
39
+ put<T = unknown>(path: string, body: unknown): Promise<T>;
40
+ delete<T = unknown>(path: string): Promise<T>;
41
+ }
42
+ /** A list endpoint's rows, whether it paginates (`{results, count, next}`) or returns a bare list. */
43
+ export declare function rows<T = Record<string, unknown>>(data: unknown): T[];
44
+ /** Trim a list result so it never floods the model: `count` and `more` say what was left out. */
45
+ export declare function trimmed<T = Record<string, unknown>>(data: unknown, limit?: number): {
46
+ results: T[];
47
+ count: number;
48
+ more: boolean;
49
+ };
50
+ /** Keep only some keys of an object (for the brief forms of rows). */
51
+ export declare function pick<T extends Record<string, unknown>>(row: T, keys: readonly string[]): Record<string, unknown>;
package/dist/api.js ADDED
@@ -0,0 +1,107 @@
1
+ /**
2
+ * The platform's REST API, called as the person whose token this is. Every MCP tool is a thin wrapper over these
3
+ * endpoints, so permissions, member access areas, limits, billing and the user action log hold exactly as in the app:
4
+ * the server never sees anything the person could not do themselves.
5
+ */
6
+ export class ApiError extends Error {
7
+ status;
8
+ code;
9
+ body;
10
+ constructor(status, body) {
11
+ const message = body.error?.message ?? (status === 401 ? 'The token is unknown or revoked.' : `HTTP ${status}`);
12
+ super(message);
13
+ this.name = 'ApiError';
14
+ this.status = status;
15
+ this.code = body.error?.code;
16
+ this.body = body;
17
+ }
18
+ }
19
+ export class Api {
20
+ baseUrl;
21
+ token;
22
+ fetchImpl;
23
+ userAgent;
24
+ constructor(options) {
25
+ this.baseUrl = options.baseUrl.replace(/\/+$/, '');
26
+ this.token = options.token;
27
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
28
+ this.userAgent = options.userAgent ?? 'autopoiesis-mcp';
29
+ }
30
+ async request(method, path, body, query) {
31
+ if (!path.startsWith('/api/')) {
32
+ throw new ApiError(400, { error: { code: 'validation_error', message: 'Paths start with /api/ (see the API reference).' } });
33
+ }
34
+ const url = new URL(this.baseUrl + path);
35
+ for (const [key, value] of Object.entries(query ?? {})) {
36
+ if (value === undefined || value === null || value === '')
37
+ continue;
38
+ url.searchParams.set(key, String(value));
39
+ }
40
+ const headers = {
41
+ Authorization: `Bearer ${this.token}`,
42
+ Accept: 'application/json',
43
+ 'User-Agent': this.userAgent,
44
+ 'X-Client': 'mcp',
45
+ };
46
+ if (body !== undefined)
47
+ headers['Content-Type'] = 'application/json';
48
+ const init = { method, headers };
49
+ if (body !== undefined)
50
+ init.body = JSON.stringify(body);
51
+ const response = await this.fetchImpl(url, init);
52
+ const text = await response.text();
53
+ let data = null;
54
+ if (text) {
55
+ try {
56
+ data = JSON.parse(text);
57
+ }
58
+ catch {
59
+ data = { raw: text.slice(0, 2000) };
60
+ }
61
+ }
62
+ if (!response.ok) {
63
+ const errorBody = data && typeof data === 'object' && !Array.isArray(data) ? data : { error: { message: String(data).slice(0, 300) } };
64
+ throw new ApiError(response.status, errorBody);
65
+ }
66
+ return data;
67
+ }
68
+ get(path, query) {
69
+ return this.request('GET', path, undefined, query);
70
+ }
71
+ post(path, body = {}, query) {
72
+ return this.request('POST', path, body, query);
73
+ }
74
+ patch(path, body) {
75
+ return this.request('PATCH', path, body);
76
+ }
77
+ put(path, body) {
78
+ return this.request('PUT', path, body);
79
+ }
80
+ delete(path) {
81
+ return this.request('DELETE', path);
82
+ }
83
+ }
84
+ /** A list endpoint's rows, whether it paginates (`{results, count, next}`) or returns a bare list. */
85
+ export function rows(data) {
86
+ if (Array.isArray(data))
87
+ return data;
88
+ if (data && typeof data === 'object' && Array.isArray(data.results))
89
+ return data.results;
90
+ return [];
91
+ }
92
+ /** Trim a list result so it never floods the model: `count` and `more` say what was left out. */
93
+ export function trimmed(data, limit = 50) {
94
+ const all = rows(data);
95
+ const count = data && typeof data === 'object' && typeof data.count === 'number' ? data.count : all.length;
96
+ const next = Boolean(data && typeof data === 'object' && data.next);
97
+ return { results: all.slice(0, limit), count, more: all.length > limit || next };
98
+ }
99
+ /** Keep only some keys of an object (for the brief forms of rows). */
100
+ export function pick(row, keys) {
101
+ const out = {};
102
+ for (const key of keys)
103
+ if (key in row)
104
+ out[key] = row[key];
105
+ return out;
106
+ }
107
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,MAAM,CAAQ;IACd,IAAI,CAAoB;IACxB,IAAI,CAAc;IAE3B,YAAY,MAAc,EAAE,IAAkB;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAA;QAC/G,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,UAAU,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAA;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAaD,MAAM,OAAO,GAAG;IACL,OAAO,CAAQ;IACP,KAAK,CAAQ;IACb,SAAS,CAAc;IACvB,SAAS,CAAQ;IAElC,YAAY,OAAmB;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAClD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAA;QAClD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IACzD,CAAC;IAED,KAAK,CAAC,OAAO,CAAc,MAAc,EAAE,IAAY,EAAE,IAAc,EAAE,KAAa;QACpF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,iDAAiD,EAAE,EAAE,CAAC,CAAA;QAC9H,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;QACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;YACvD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;gBAAE,SAAQ;YACnE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QAC1C,CAAC;QACD,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;YACrC,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,IAAI,CAAC,SAAS;YAC5B,UAAU,EAAE,KAAK;SAClB,CAAA;QACD,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAA;QACpE,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;QAC7C,IAAI,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,IAAI,IAAI,GAAY,IAAI,CAAA;QACxB,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAA;YACrC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAqB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAA;YACxJ,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QAChD,CAAC;QACD,OAAO,IAAS,CAAA;IAClB,CAAC;IAED,GAAG,CAAc,IAAY,EAAE,KAAa;QAC1C,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;IACvD,CAAC;IACD,IAAI,CAAc,IAAY,EAAE,IAAI,GAAY,EAAE,EAAE,KAAa;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;IACnD,CAAC;IACD,KAAK,CAAc,IAAY,EAAE,IAAa;QAC5C,OAAO,IAAI,CAAC,OAAO,CAAI,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IAC7C,CAAC;IACD,GAAG,CAAc,IAAY,EAAE,IAAa;QAC1C,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IAC3C,CAAC;IACD,MAAM,CAAc,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAI,QAAQ,EAAE,IAAI,CAAC,CAAA;IACxC,CAAC;CACF;AAED,sGAAsG;AACtG,MAAM,UAAU,IAAI,CAA8B,IAAa;IAC7D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAW,CAAA;IAC3C,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAE,IAA8B,CAAC,OAAO,CAAC;QAAE,OAAQ,IAAyB,CAAC,OAAO,CAAA;IACzI,OAAO,EAAE,CAAA;AACX,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,OAAO,CAA8B,IAAa,EAAE,KAAK,GAAG,EAAE;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAI,IAAI,CAAC,CAAA;IACzB,MAAM,KAAK,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAQ,IAA4B,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAE,IAA0B,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAA;IAC1J,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAK,IAA2B,CAAC,IAAI,CAAC,CAAA;IAC3F,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,GAAG,KAAK,IAAI,IAAI,EAAE,CAAA;AAClF,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,IAAI,CAAoC,GAAM,EAAE,IAAuB;IACrF,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,IAAI,GAAG,IAAI,GAAG;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3D,OAAO,GAAG,CAAA;AACZ,CAAC"}
package/dist/apps.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { McpServer } from '@modelcontextprotocol/server';
2
+ import type { Session } from './kit.js';
3
+ export declare const VIEWS: readonly ['inbox', 'storyboard', 'gallery', 'home', 'money'];
4
+ export type View = (typeof VIEWS)[number];
5
+ export declare const viewUri: (view: View) => string;
6
+ /** The built HTML of a view, wherever this module runs from (dist/, or src/ under tsx). */
7
+ export declare function viewHtml(view: View): string | null;
8
+ /** Claude's sandbox origin for a hosted server: the first 32 hex characters of the SHA-256 of the server URL. */
9
+ export declare function claudeDomain(publicUrl: string | undefined): string | undefined;
10
+ export declare function registerApps(server: McpServer, s: Session): void;
package/dist/apps.js ADDED
@@ -0,0 +1,146 @@
1
+ /**
2
+ * MCP Apps (the `io.modelcontextprotocol/ui` extension): views a host renders inline for some tools' results. Each view
3
+ * is one self-contained HTML file built from ui/<name>/ into dist/ui/<name>.html. Hosts that don't render apps (Claude
4
+ * Code, Codex CLI) still get the full text result: the views are an extra, never the only answer.
5
+ *
6
+ * Buttons in a view call app-only tools (hidden from the model): the click is the person's confirmation, so those skip
7
+ * the elicitation their model-facing twins ask for.
8
+ */
9
+ import { readFileSync, existsSync } from 'node:fs';
10
+ import { createHash } from 'node:crypto';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { dirname, join } from 'node:path';
13
+ import { RESOURCE_MIME_TYPE, registerAppResource, registerAppTool } from '@modelcontextprotocol/ext-apps/server';
14
+ import { z } from 'zod';
15
+ export const VIEWS = ['inbox', 'storyboard', 'gallery', 'home', 'money'];
16
+ export const viewUri = (view) => `ui://autopoiesis/${view}.html`;
17
+ const here = dirname(fileURLToPath(import.meta.url));
18
+ /** The built HTML of a view, wherever this module runs from (dist/, or src/ under tsx). */
19
+ export function viewHtml(view) {
20
+ for (const dir of [join(here, 'ui'), join(here, '..', 'dist', 'ui')]) {
21
+ const file = join(dir, `${view}.html`);
22
+ if (existsSync(file))
23
+ return readFileSync(file, 'utf8');
24
+ }
25
+ return null;
26
+ }
27
+ /** Claude's sandbox origin for a hosted server: the first 32 hex characters of the SHA-256 of the server URL. */
28
+ export function claudeDomain(publicUrl) {
29
+ if (!publicUrl)
30
+ return undefined;
31
+ return `${createHash('sha256').update(publicUrl).digest('hex').slice(0, 32)}.claudemcpcontent.com`;
32
+ }
33
+ export function registerApps(server, s) {
34
+ const apiOrigin = new URL(s.api.baseUrl).origin;
35
+ const resourceDomains = Array.from(new Set([apiOrigin, s.appUrl, 'https://fonts.googleapis.com', 'https://fonts.gstatic.com', ...s.mediaDomains]));
36
+ const domain = claudeDomain(s.publicUrl);
37
+ for (const view of VIEWS) {
38
+ const html = viewHtml(view);
39
+ if (!html)
40
+ continue; // not built (tests, a source checkout): the tools still work, without the view
41
+ const uri = viewUri(view);
42
+ registerAppResource(server, `${view}-view`, uri, {
43
+ title: `${view[0].toUpperCase()}${view.slice(1)} view`,
44
+ description: `The ${view} as an inline view.`,
45
+ mimeType: RESOURCE_MIME_TYPE,
46
+ _meta: { ui: { prefersBorder: false } },
47
+ }, async () => ({
48
+ contents: [{
49
+ uri,
50
+ mimeType: RESOURCE_MIME_TYPE,
51
+ text: html,
52
+ _meta: {
53
+ ui: {
54
+ csp: { connectDomains: [], resourceDomains, frameDomains: [], baseUriDomains: [] },
55
+ prefersBorder: false,
56
+ permissions: { clipboardWrite: {} },
57
+ ...(domain ? { domain } : {}),
58
+ },
59
+ },
60
+ }],
61
+ }));
62
+ }
63
+ // --- app-only tools: what the buttons call -------------------------------------------------------------------------
64
+ const appOnly = { visibility: ['app'] };
65
+ registerAppTool(server, 'app_decide', {
66
+ title: 'Decide (from the inbox view)',
67
+ description: 'Decide a card from the inbox view. Hidden from the model: the click is the confirmation.',
68
+ inputSchema: z.object({ decision: z.string(), choice: z.enum(['approve', 'reject', 'cancel']), note: z.string().optional(), answer: z.unknown().optional() }),
69
+ annotations: { destructiveHint: true },
70
+ _meta: { ui: { resourceUri: viewUri('inbox'), ...appOnly } },
71
+ }, async ({ decision, choice, note, answer }) => {
72
+ try {
73
+ const body = { decision: choice };
74
+ if (note)
75
+ body.note = note;
76
+ if (answer !== undefined)
77
+ body.answer = answer;
78
+ const out = (await s.api.post(`/api/approvals/${decision}/decide`, body));
79
+ return { content: [{ type: 'text', text: `${choice} ${decision}` }], structuredContent: out };
80
+ }
81
+ catch (error) {
82
+ return { isError: true, content: [{ type: 'text', text: error.message }] };
83
+ }
84
+ });
85
+ registerAppTool(server, 'app_refresh_inbox', {
86
+ title: 'Refresh the inbox view',
87
+ description: 'Reload the pending cards for the inbox view.',
88
+ inputSchema: z.object({ company: z.string(), status: z.string().optional() }),
89
+ annotations: { readOnlyHint: true },
90
+ _meta: { ui: { resourceUri: viewUri('inbox'), ...appOnly } },
91
+ }, async ({ company, status }) => {
92
+ const data = (await s.api.get(`/api/companies/${company}/approvals`, { status: status ?? 'pending' }));
93
+ const results = Array.isArray(data) ? data : (data.results ?? []);
94
+ return { content: [{ type: 'text', text: `${results.length} cards` }], structuredContent: { company, results, count: results.length, more: false } };
95
+ });
96
+ registerAppTool(server, 'app_video', {
97
+ title: 'Video (from the storyboard view)',
98
+ description: 'Reload a video, or act on it: keyframes, make media, critique, render. The click is the confirmation.',
99
+ inputSchema: z.object({ video: z.string(), action: z.enum(['refresh', 'keyframes', 'make', 'critique_keyframes', 'critique_clips', 'render']).optional() }),
100
+ annotations: { destructiveHint: false },
101
+ _meta: { ui: { resourceUri: viewUri('storyboard'), ...appOnly } },
102
+ }, async ({ video, action }) => {
103
+ try {
104
+ if (action === 'keyframes')
105
+ await s.api.post(`/api/studio/productions/${video}/keyframes`, {});
106
+ else if (action === 'make')
107
+ await s.api.post(`/api/studio/productions/${video}/generate`, { what: 'all' });
108
+ else if (action === 'critique_keyframes')
109
+ await s.api.post(`/api/studio/productions/${video}/critique`, { stage: 'keyframes' });
110
+ else if (action === 'critique_clips')
111
+ await s.api.post(`/api/studio/productions/${video}/critique`, { stage: 'clips' });
112
+ else if (action === 'render')
113
+ await s.api.post(`/api/studio/productions/${video}/render`);
114
+ const fresh = (await s.api.get(`/api/studio/productions/${video}`));
115
+ return { content: [{ type: 'text', text: `${action ?? 'refresh'} ${video}` }], structuredContent: fresh };
116
+ }
117
+ catch (error) {
118
+ return { isError: true, content: [{ type: 'text', text: error.message }] };
119
+ }
120
+ });
121
+ registerAppTool(server, 'app_media', {
122
+ title: 'Media (from the gallery view)',
123
+ description: 'Star, retry or reload media from the gallery view.',
124
+ inputSchema: z.object({ company: z.string().optional(), media: z.string().optional(), action: z.enum(['refresh', 'star', 'unstar', 'retry']).optional(), kind: z.string().optional() }),
125
+ annotations: { destructiveHint: false },
126
+ _meta: { ui: { resourceUri: viewUri('gallery'), ...appOnly } },
127
+ }, async ({ company, media, action, kind }) => {
128
+ try {
129
+ if (media && action === 'star')
130
+ await s.api.patch(`/api/studio/media/${media}`, { starred: true });
131
+ if (media && action === 'unstar')
132
+ await s.api.patch(`/api/studio/media/${media}`, { starred: false });
133
+ if (media && action === 'retry')
134
+ await s.api.post(`/api/studio/media/${media}/retry`);
135
+ if (!company)
136
+ return { content: [{ type: 'text', text: 'ok' }], structuredContent: { ok: true } };
137
+ const data = (await s.api.get(`/api/companies/${company}/studio/media`, { kind }));
138
+ const results = Array.isArray(data) ? data : (data.results ?? []);
139
+ return { content: [{ type: 'text', text: `${results.length} media` }], structuredContent: { company, results: results.slice(0, 60), count: results.length, more: results.length > 60 } };
140
+ }
141
+ catch (error) {
142
+ return { isError: true, content: [{ type: 'text', text: error.message }] };
143
+ }
144
+ });
145
+ }
146
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `autopoiesis-mcp`: the server on stdio for a tool on this machine (Claude Code, Codex, Cursor, Claude Desktop), or
4
+ * `--http` to host it. The token comes from AUTOPOIESIS_TOKEN (or --token); make one on Connectors → MCP in the app.
5
+ */
6
+ import { serveStdio } from '@modelcontextprotocol/server/stdio';
7
+ import { createServer, DEFAULT_API_URL, DEFAULT_APP_URL, VERSION } from './server.js';
8
+ import { serveHttp } from './http.js';
9
+ const HELP = `autopoiesis-mcp ${VERSION}
10
+
11
+ Run your Autopoiesis company from your own AI tool, over MCP.
12
+
13
+ Usage
14
+ autopoiesis-mcp stdio server (what Claude Code, Codex, Cursor and Claude Desktop launch)
15
+ autopoiesis-mcp --http Streamable HTTP server on PORT (default 8080), one token per request
16
+
17
+ Options
18
+ --token <apk_…> your personal access token (or AUTOPOIESIS_TOKEN)
19
+ --api-url <url> the platform API (or AUTOPOIESIS_API_URL; default ${DEFAULT_API_URL})
20
+ --app-url <url> the web app, for links (or AUTOPOIESIS_APP_URL; default ${DEFAULT_APP_URL})
21
+ --public-url <url> this server's public address when hosted (or AUTOPOIESIS_MCP_URL)
22
+ --port <n> --http only (or PORT)
23
+ --host <addr> --http only (default 0.0.0.0)
24
+ --version, --help
25
+
26
+ Get a token: open the app → Connectors → MCP → Make the token. Docs: https://docs.autopoiesis.app
27
+ `;
28
+ function arg(name) {
29
+ const i = process.argv.indexOf(name);
30
+ return i >= 0 ? process.argv[i + 1] : undefined;
31
+ }
32
+ const env = process.env;
33
+ const apiUrl = arg('--api-url') ?? env.AUTOPOIESIS_API_URL ?? DEFAULT_API_URL;
34
+ const appUrl = arg('--app-url') ?? env.AUTOPOIESIS_APP_URL ?? DEFAULT_APP_URL;
35
+ const publicUrl = arg('--public-url') ?? env.AUTOPOIESIS_MCP_URL;
36
+ const mediaDomains = (env.AUTOPOIESIS_MEDIA_DOMAINS ?? '').split(',').map((d) => d.trim()).filter(Boolean);
37
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
38
+ process.stdout.write(HELP);
39
+ }
40
+ else if (process.argv.includes('--version') || process.argv.includes('-v')) {
41
+ process.stdout.write(`${VERSION}\n`);
42
+ }
43
+ else if (process.argv.includes('--http')) {
44
+ const port = Number(arg('--port') ?? env.PORT ?? 8080);
45
+ const host = arg('--host') ?? env.HOST ?? '0.0.0.0';
46
+ serveHttp({ port, host, apiUrl, appUrl, ...(publicUrl ? { publicUrl } : {}), mediaDomains });
47
+ }
48
+ else {
49
+ const token = arg('--token') ?? env.AUTOPOIESIS_TOKEN;
50
+ if (!token) {
51
+ process.stderr.write('autopoiesis-mcp: no token. Set AUTOPOIESIS_TOKEN (make one in the app: Connectors → MCP) or pass --token.\n');
52
+ process.exit(1);
53
+ }
54
+ const handle = serveStdio(() => createServer({ token, apiUrl, appUrl, mediaDomains, ...(publicUrl ? { publicUrl } : {}) }), {
55
+ legacy: 'serve',
56
+ onerror: (error) => process.stderr.write(`autopoiesis-mcp: ${error.message}\n`),
57
+ });
58
+ process.stderr.write(`autopoiesis-mcp ${VERSION} on stdio → ${apiUrl}\n`);
59
+ const stop = () => void handle.close().then(() => process.exit(0));
60
+ process.on('SIGINT', stop);
61
+ process.on('SIGTERM', stop);
62
+ }
63
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Guides served as resources and read by the prompts: short, in plain words, the way the platform writes. */
2
+ export declare const STUDIO_GUIDE = "# The Studio, in short\n\nThe Studio makes images, clips, voice lines and music, and cuts them into videos. A video is a storyboard: shots in\norder, each with a picture (generated, footage you have, a title card, or a presenter), a line of voice-over, text on\nscreen, a length in seconds, and direction for the critic.\n\n## Who does what\n- **You** say what the video is for and how it should feel. One paragraph is enough: who it is for, what it must show,\n the one thing to feel.\n- **The platform** drafts the storyboard from that brief for free (create_video with draft on).\n- **Rose, the Creative Director** (ask_agent creative, with production set to the video id) tightens shots, writes\n better lines, picks looks and models, and proposes changes you apply with apply_chat_action.\n- **The critic** (critique_video) judges takes against each shot's direction and keeps the best.\n\n## Models and money\nstudio_overview lists every model the company can run with its price per image, per second of clip, per voice line or\nper track. update_video {style: {models: {clip, keyframe, voice, music}}} picks them for one video; studio_settings\nsets the defaults. Keyframes (one still per shot) cost cents and lock the look before clips, which cost the most. Every\ntool that spends asks you first, through your tool's own dialog, with the amount.\n\n## The order that works\n1. create_video \u2192 2. get_video, read the shots \u2192 3. ask_agent creative to tighten \u2192 4. update_video models if needed \u2192\n5. video_keyframes \u2192 wait_for_video \u2192 critique_video keyframes \u2192 6. make_video_media all \u2192 wait_for_video \u2192\ncritique_video clips \u2192 7. render_video \u2192 wait_for_video \u2192 the render link, or open_in_app video.\n\n## Shapes and lengths\n16:9 for the web and decks, 9:16 for Reels, Shorts and TikTok, 1:1 and 4:5 for feeds. Teasers run 15 to 30 seconds;\na product walkthrough 60 to 90. Fewer, longer shots read better than many short ones.\n\n## When something is missing\nget_video and wait_for_video list what still blocks a render: a shot without media, a voice line not made, music not\ncomposed. make_video_media takes a `what` (visuals, voice, music or all) to fill only that gap. A failed generation can\nbe retried with update_media {action: retry}.\n";
3
+ export declare const TEASER_GUIDE = "# Making a teaser from a terminal\n\nThe loop, tool by tool (the make_a_teaser prompt runs it for you):\n\n1. brand_brain: the voice, the audience, the enemy.\n2. create_video {title, brief, aspect_ratio, seconds: 20}: a storyboard is drafted for free.\n3. get_video: read the shots. ask_agent {agent: \"creative\", production: <video id>, message: ...}: Rose tightens them;\n apply_chat_action on her proposals, or set_video_shots to write them yourself.\n4. studio_overview, then update_video {style: {models}} only if the defaults don't fit.\n5. video_keyframes: cents per shot, you confirm. wait_for_video. critique_video {stage: \"keyframes\"}.\n6. make_video_media {what: \"all\"}: the clips and voice lines, you confirm the cost. wait_for_video until nothing is\n generating. critique_video {stage: \"clips\"}.\n7. render_video (free). wait_for_video. The render link is in the result; open_in_app {what: \"video\", id} shows it.\n\nNothing is spent without the dialog. wait_for_video returns what is still missing when it cannot go on.\n";
package/dist/guides.js ADDED
@@ -0,0 +1,52 @@
1
+ /** Guides served as resources and read by the prompts: short, in plain words, the way the platform writes. */
2
+ export const STUDIO_GUIDE = `# The Studio, in short
3
+
4
+ The Studio makes images, clips, voice lines and music, and cuts them into videos. A video is a storyboard: shots in
5
+ order, each with a picture (generated, footage you have, a title card, or a presenter), a line of voice-over, text on
6
+ screen, a length in seconds, and direction for the critic.
7
+
8
+ ## Who does what
9
+ - **You** say what the video is for and how it should feel. One paragraph is enough: who it is for, what it must show,
10
+ the one thing to feel.
11
+ - **The platform** drafts the storyboard from that brief for free (create_video with draft on).
12
+ - **Rose, the Creative Director** (ask_agent creative, with production set to the video id) tightens shots, writes
13
+ better lines, picks looks and models, and proposes changes you apply with apply_chat_action.
14
+ - **The critic** (critique_video) judges takes against each shot's direction and keeps the best.
15
+
16
+ ## Models and money
17
+ studio_overview lists every model the company can run with its price per image, per second of clip, per voice line or
18
+ per track. update_video {style: {models: {clip, keyframe, voice, music}}} picks them for one video; studio_settings
19
+ sets the defaults. Keyframes (one still per shot) cost cents and lock the look before clips, which cost the most. Every
20
+ tool that spends asks you first, through your tool's own dialog, with the amount.
21
+
22
+ ## The order that works
23
+ 1. create_video → 2. get_video, read the shots → 3. ask_agent creative to tighten → 4. update_video models if needed →
24
+ 5. video_keyframes → wait_for_video → critique_video keyframes → 6. make_video_media all → wait_for_video →
25
+ critique_video clips → 7. render_video → wait_for_video → the render link, or open_in_app video.
26
+
27
+ ## Shapes and lengths
28
+ 16:9 for the web and decks, 9:16 for Reels, Shorts and TikTok, 1:1 and 4:5 for feeds. Teasers run 15 to 30 seconds;
29
+ a product walkthrough 60 to 90. Fewer, longer shots read better than many short ones.
30
+
31
+ ## When something is missing
32
+ get_video and wait_for_video list what still blocks a render: a shot without media, a voice line not made, music not
33
+ composed. make_video_media takes a \`what\` (visuals, voice, music or all) to fill only that gap. A failed generation can
34
+ be retried with update_media {action: retry}.
35
+ `;
36
+ export const TEASER_GUIDE = `# Making a teaser from a terminal
37
+
38
+ The loop, tool by tool (the make_a_teaser prompt runs it for you):
39
+
40
+ 1. brand_brain: the voice, the audience, the enemy.
41
+ 2. create_video {title, brief, aspect_ratio, seconds: 20}: a storyboard is drafted for free.
42
+ 3. get_video: read the shots. ask_agent {agent: "creative", production: <video id>, message: ...}: Rose tightens them;
43
+ apply_chat_action on her proposals, or set_video_shots to write them yourself.
44
+ 4. studio_overview, then update_video {style: {models}} only if the defaults don't fit.
45
+ 5. video_keyframes: cents per shot, you confirm. wait_for_video. critique_video {stage: "keyframes"}.
46
+ 6. make_video_media {what: "all"}: the clips and voice lines, you confirm the cost. wait_for_video until nothing is
47
+ generating. critique_video {stage: "clips"}.
48
+ 7. render_video (free). wait_for_video. The render link is in the result; open_in_app {what: "video", id} shows it.
49
+
50
+ Nothing is spent without the dialog. wait_for_video returns what is still missing when it cannot go on.
51
+ `;
52
+ //# sourceMappingURL=guides.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guides.js","sourceRoot":"","sources":["../src/guides.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAE9G,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiC3B,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;CAe3B,CAAA"}