@dodi-education/cli 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # dodi CLI
2
2
 
3
- Let your own AI agent build learning games, companion avatars and accessories
4
- for your family on [dodi](https://app.dodi.app). Works with any agent that can
5
- run shell commands (Claude Code, Cursor, Codex, a local model) or speak MCP.
3
+ Let your own AI agent make learning games for your family on
4
+ [dodi](https://app.dodi.app), the way you would in Game Studio: your agent
5
+ describes the game and reviews it, and dodi's own game agent builds it with
6
+ your AI providers (background and preview pictures, a visual check and
7
+ translations included). Works with any agent that can run shell commands
8
+ (Claude Code, Cursor, Codex, a local model) or speak MCP.
6
9
 
7
10
  Everything the agent uploads is sealed on its machine under your family's
8
11
  vault key. The dodi server never sees your games or your kids' details.
@@ -12,23 +15,24 @@ vault key. The dodi server never sees your games or your kids' details.
12
15
  Tell your agent:
13
16
 
14
17
  > Build a learning game for my kid on dodi.app with the dodi CLI (needs Node
15
- > 20+). Install it with `npm install -g @dodi-education/cli`, run `dodi login` and send
16
- > me the link it prints so I can allow access, then read `dodi docs` and
17
- > follow it.
18
+ > 20+). Install it with `npm install -g @dodi-education/cli`, run `dodi login`
19
+ > and send me the link it prints so I can allow access, then read `dodi docs`
20
+ > and follow it: you brief dodi's game agent and review what it builds.
18
21
 
19
22
  The link opens **Allow access** in the dodi app. Check that the fingerprint
20
23
  matches what your agent shows, choose what it may do and for how long, and
21
- confirm with your password. **Settings > Access** lists every browser, app,
24
+ allow it. **Settings > Access** lists every browser, app,
22
25
  robot and agent that can open your family's data; revoke any of them there.
23
26
 
24
27
  Scopes you can grant:
25
28
 
26
29
  | Scope | Lets the agent |
27
30
  |---|---|
31
+ | `studio` | build with your AI providers: your keys for the game, image and thinking models are handed to the agent's machine (never the voice key), and builds are charged to those accounts |
28
32
  | `games` | create and edit your family's games |
29
33
  | `games:publish` | submit games to dodi Discover (reviewed before they go live) |
30
34
  | `kids:basic` | see your kids' first names and ages |
31
- | `kids:memory` | read a kid's memory dossier (off by default: the agent's AI provider reads it) |
35
+ | `kids:memory` | read a kid's memory and your notes, so games fit (off by default: the agent's AI provider reads them) |
32
36
  | `assets` | create custom companion avatars and accessories |
33
37
  | `assets:publish` | share avatars and accessories on dodi Discover |
34
38
 
@@ -39,26 +43,28 @@ Access and give it to the agent as `DODI_TOKEN` (or `dodi login --token`).
39
43
 
40
44
  ```sh
41
45
  npm install -g @dodi-education/cli
42
- dodi login # prints the approval link; exit 3 = still pending
43
- dodi login --resume # after the parent approved
44
- dodi docs # the workflow; `dodi docs games` before writing a game
45
- dodi kids # who you build for
46
- dodi games new dino-count # a working starter game
47
- dodi games check dino-count # validator + headless run + screenshots
48
- dodi games push dino-count # seal and upload
49
- dodi games publish dino-count # optional: dodi Discover
50
- dodi assets new crown --kind accessory
51
- dodi assets check crown && dodi assets push crown
52
- dodi assets publish crown # optional: share it on dodi Discover
53
- dodi mcp # the same commands as an MCP server (stdio)
46
+ dodi login # prints the approval link; exit 3 = still pending
47
+ dodi login --resume # after the parent approved
48
+ dodi docs # the workflow; `dodi docs studio` before your first brief
49
+ dodi kids # who you make the game for
50
+ dodi studio new "<brief>" # plan it with dodi
51
+ dodi studio plan "<answer>" # until the plan is right
52
+ dodi studio build # dodi builds it in the background
53
+ dodi studio wait # dodi's reply and screenshots to review (exit 3 = still building)
54
+ dodi studio send "<feedback>" # a change round, then wait again
55
+ dodi games publish # only when the parent asks: dodi Discover (translated, reviewed)
56
+ dodi assets new crown --kind accessory # custom companion looks (3D, see `dodi docs assets`)
57
+ dodi mcp # the same commands as an MCP server (stdio)
54
58
  ```
55
59
 
56
60
  Every command takes `--json`. Exit codes: 0 ok, 1 error, 2 usage, 3 waiting
57
- for approval, 4 check failed, 5 not connected, 6 missing scope.
61
+ (approval or a running build), 4 check failed, 5 not connected, 6 missing
62
+ scope.
58
63
 
59
- `dodi games check --local` runs the game in Playwright on your machine
60
- (`npx playwright install chromium`); without it, the dodi screenshot service
61
- renders it.
64
+ Builds run dodi's own game agent on the agent's machine. Its visual check
65
+ renders the game with Playwright when it is installed
66
+ (`npx playwright install chromium-headless-shell`), otherwise through dodi's
67
+ screenshot service.
62
68
 
63
69
  ### MCP
64
70
 
@@ -84,8 +90,10 @@ pnpm --filter @dodi-education/cli build # bundles to dist/dodi.js
84
90
  NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" pnpm --filter @dodi-education/cli exec tsx scripts/e2e-local.ts
85
91
  ```
86
92
 
87
- `scripts/e2e-local.ts` runs the whole flow (login, approval, kids, games,
88
- assets, scopes, logout) against a local platform on :3001 and its dev
89
- database. `E2E_PUBLISH_GAME=1` adds an access-key agent that publishes the
90
- game to Discover (this sends the operator notification email when the local
91
- platform has one configured).
93
+ Against a local platform on :3001 and its dev database:
94
+ - `scripts/e2e-local.ts`: login, approval, kids, manual game edits, assets,
95
+ scopes, access keys, the Access list, logout.
96
+ - `scripts/e2e-studio-local.ts`: the studio flow (plan, build, review, a
97
+ change round) with a stand-in model (`scripts/stub-anthropic.ts`), so no
98
+ real AI is called. `E2E_PUBLISH_GAME=1` also publishes (this sends the
99
+ operator notification email when the local platform has one configured).
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  __export
4
- } from "./chunk-2ZK44UVJ.js";
4
+ } from "./chunk-LMSPDGSC.js";
5
5
 
6
6
  // ../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
7
7
  var external_exports = {};
@@ -19224,16 +19224,24 @@ var GameScreenshotServiceSettingsSchema = external_exports.object({
19224
19224
  message: "custom mode requires customUrlEnc",
19225
19225
  path: ["customUrlEnc"]
19226
19226
  });
19227
+ var DEFAULT_GAME_SCREENSHOT_SERVICE = {
19228
+ mode: "dodi"
19229
+ };
19230
+ function parseGameScreenshotServiceSettings(value) {
19231
+ const parsed = GameScreenshotServiceSettingsSchema.safeParse(value);
19232
+ return parsed.success ? parsed.data : DEFAULT_GAME_SCREENSHOT_SERVICE;
19233
+ }
19227
19234
 
19228
19235
  export {
19229
19236
  external_exports,
19230
19237
  SuccessCriteriaSchema,
19231
19238
  SUCCESS_SYSTEM_TEMPLATE,
19232
- GAME_CANVAS_TEMPLATE,
19233
19239
  createBridgeToken,
19240
+ STAGE,
19241
+ GAME_CANVAS_TEMPLATE,
19234
19242
  SCREENSHOT_CONTRACT_VERSION,
19235
19243
  SCREENSHOT_LIMITS,
19236
- ScreenshotStepSchema,
19237
19244
  DEFAULT_SCREENSHOT_VIEWPORT,
19238
- ScreenshotResponseSchema
19245
+ ScreenshotResponseSchema,
19246
+ parseGameScreenshotServiceSettings
19239
19247
  };
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ try {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ } catch (e) {
12
+ throw mod = 0, e;
13
+ }
14
+ };
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
28
+ // If the importer is in node compatibility mode or this is not an ESM
29
+ // file that has been converted to a CommonJS file using a Babel-
30
+ // compatible transform (i.e. "__esModule" has not been set), then set
31
+ // "default" to the CommonJS "module.exports" for node compatibility.
32
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
33
+ mod
34
+ ));
35
+
36
+ export {
37
+ __commonJS,
38
+ __export,
39
+ __toESM
40
+ };