@impractical-ai/motion 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/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Impractical Motion CLI
2
+
3
+ Connect Claude Code to Impractical Motion through its MCP server.
4
+
5
+ ## Requirements
6
+
7
+ - Node.js 22 or newer
8
+ - Claude Code installed and signed in
9
+ - Google Chrome or Chromium for frame inspection
10
+
11
+ ## Setup
12
+
13
+ ```sh
14
+ npx --yes @impractical-ai/motion setup --claude
15
+ ```
16
+
17
+ Approve the device code in the browser, then run `/reload-plugins` in Claude Code and type
18
+ `continue`. Re-running setup verifies and reuses a working credential, refreshes the user-scoped
19
+ plugin, and does not require another browser authorization.
20
+
21
+ Setup writes the API credential to `~/.impractical/config.json` with mode `0600`. Environment
22
+ variables `IMPRACTICAL_API_KEY`, `IMPRACTICAL_SUPABASE_URL`, and `IMPRACTICAL_APP_URL` take
23
+ precedence over that file.
24
+
25
+ ## MCP server
26
+
27
+ The installed Claude plugin launches the server automatically. Other MCP clients can run:
28
+
29
+ ```sh
30
+ npx --yes @impractical-ai/motion mcp
31
+ ```
32
+
33
+ Check the connection with:
34
+
35
+ ```sh
36
+ npx --yes --package @impractical-ai/motion impractical whoami
37
+ ```
38
+
39
+ A healthy result prints the workspace org and plan. `claude mcp list` only proves that the MCP
40
+ process starts; it does not verify the Impractical credential.
41
+
42
+ If authorization is rejected, rerun the setup command. If the configuration file is malformed,
43
+ the CLI reports its exact path instead of silently ignoring it.
@@ -65,7 +65,7 @@ export type TextUnit = 'chars' | 'words' | 'lines'
65
65
  export type RevealEffect =
66
66
  | 'rise' // masked characters rise in from below (the house classic)
67
67
  | 'fall' // masked characters drop in from above
68
- | 'blur' // words de-blur and fade in
68
+ | 'blur' // special effect only: never default readable text to word-by-word de-blur
69
69
  | 'wave' // characters bob up with an overshoot, heavily overlapped
70
70
  | 'flip' // characters flip up from flat (3D rotationX)
71
71
  | 'pop' // characters scale in with a springy overshoot
@@ -708,6 +708,12 @@ export type SceneInspection = {
708
708
  tweens: TweenInfo[]
709
709
  cameraSets: CameraSetInfo[]
710
710
  overrides: SceneOverrides
711
+ /**
712
+ * Non-fatal build complaints — a step whose element is gone, a text effect
713
+ * with nothing left to split. The scene still plays; these say what silently
714
+ * does nothing so a stale selector can't rot unnoticed.
715
+ */
716
+ warnings: string[]
711
717
  }
712
718
 
713
719
  export type DirectionContext = {
@@ -53,6 +53,7 @@ If they gave a brand URL and no kit exists yet:
53
53
 
54
54
  brand_list
55
55
  brand_extract { url: "https://example.com" }
56
+ brand_extract { jobId: "<returned run id>", wait: true }
56
57
 
57
58
  Then scaffold the project:
58
59
 
@@ -72,8 +73,9 @@ A scene is two files, and both must exist for the preview to build:
72
73
 
73
74
  Write them with `write_draft_files` (whole files) or `edit_draft_file` (exact
74
75
  string replacement — prefer this for revisions). Every save rebuilds the
75
- preview and **returns the build error if your code does not compile** — that is
76
- your compile loop, so read it and fix rather than guessing.
76
+ preview and returns the committed revision plus its build job id immediately.
77
+ Follow that id with `job_status { jobIds: ["..."], wait: true }`; that result is
78
+ your compile loop, so read and fix any build error rather than guessing.
77
79
 
78
80
  Rules that matter:
79
81
 
@@ -168,11 +170,32 @@ again. This is the difference between shipping a video and shipping a guess.
168
170
  ## 5. Export and hand off
169
171
 
170
172
  export_video { draftId: "..." }
173
+ job_status { jobIds: ["<returned job id>"], wait: true }
171
174
  studio_link { projectId: "...", slug: "..." }
172
175
 
173
176
  Always give the user the studio link — that is where they watch the cuts and
174
177
  tweak visually. The export URL expires, so only export once they are happy.
175
178
 
179
+ ## Timeouts and lost acknowledgements
180
+
181
+ Build, export, and brand-extraction calls return their job or run id before
182
+ waiting. Continue build/export ids with `job_status`, and continue a brand run
183
+ with `brand_extract { jobId, wait: true }` (never the URL again). If the MCP
184
+ client kills any call and shows only a timeout, the mutation may still have
185
+ committed even though its acknowledgement was lost.
186
+ **Never blindly retry a mutating or metered call.** Verify state first:
187
+
188
+ - After `write_draft_files` / `edit_draft_file`, use `list_draft_files` and
189
+ `read_draft_file` to confirm the intended revision and source.
190
+ - After an export or other project mutation, use `get_project` / `list_projects`
191
+ to check whether it already started or completed.
192
+ - After `brand_extract`, continue its returned id with `brand_extract { jobId, wait: true }`. If the
193
+ start acknowledgement was lost, check `brand_list` / `brand_get` before
194
+ starting another extraction, especially when `reextract: true`.
195
+
196
+ Retry only when those reads prove the mutation did not commit. Otherwise
197
+ continue from the state you observed; a duplicate edit or export wastes quota.
198
+
176
199
  ## The personal motion profile
177
200
 
178
201
  The `motion_profile` tool manages what Impractical remembers about this user's