@impractical-ai/motion 0.1.16 → 0.1.18
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/assets/motion-standard.md +46 -0
- package/dist/{api-V7Q3PIWY.js → api-WSATRY3V.js} +2 -2
- package/dist/chunk-2GCSX3YN.js +71 -0
- package/dist/{chunk-CJLGKZMD.js → chunk-FTSZCIMV.js} +1 -1
- package/dist/{stdio-R4RCWJIS.js → chunk-JSEDAJHM.js} +37927 -70070
- package/dist/chunk-M6427SHW.js +97 -0
- package/dist/chunk-QQ6NYC74.js +14552 -0
- package/dist/{chunk-UEPY33MB.js → chunk-TETWFQPX.js} +8 -49
- package/dist/chunk-XWCSIM4L.js +51 -0
- package/dist/chunk-ZEVR6SM6.js +18083 -0
- package/dist/commands-Y723HSJI.js +468 -0
- package/dist/draft-check-BRVH77WB.js +53 -0
- package/dist/guidance-SMXXX463.js +113 -0
- package/dist/index.js +30 -10
- package/dist/stdio-N2RZGMBI.js +23 -0
- package/dist/template-source-KKAKXOHX.js +17 -0
- package/package.json +3 -3
- package/dist/chunk-AP27EKRR.js +0 -71
- package/dist/commands-6F7HITZN.js +0 -1683
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Arrival, hold and exit — house motion standard
|
|
2
|
+
|
|
3
|
+
Adopted by explicit user direction on 2026-10-19. It supersedes the 2026-09-26 "arrival and residual drift" rule (the Rox `ambientOffset` drift layer), which is withdrawn. Applies to newly authored or revised video, Atelier and reusable motion components.
|
|
4
|
+
|
|
5
|
+
## Default behavior
|
|
6
|
+
|
|
7
|
+
**Each foreground element follows one continuous trajectory: it arrives with energy, decelerates strongly to near-zero speed for the reading hold, then accelerates into its exit or its next authored move.**
|
|
8
|
+
|
|
9
|
+
- The entrance and exit eases carry the whole shape. There is no separate drift layer, no constant velocity floor and no perpetual creep.
|
|
10
|
+
- **Finish the visible travel quickly.** During the hold, the remaining travel of the entrance's ease tail must be under about 0.5 output px in total. The subject then reads as calm and still, not creeping. A long-tailed out-ease is fine as long as its last stretch covers less than half a pixel.
|
|
11
|
+
- **Exits accelerate out of the near-zero state** (an in or in-out ease). Nothing starts from a hard stop, and the tail of the arrival flows into the exit without a velocity discontinuity.
|
|
12
|
+
- **Whole entities, not every element.** Arrival, hold and exit apply to the larger entity on screen: a card, a product window, a headline block, a logo lockup. Its children (labels, icons, rows, words, buttons) ride with it inside the same transform. Do not recurse and give each child its own arrival, deceleration and exit: that reads as fidgeting and splits attention. Children may still have their own discrete actions inside the hold (text typing in, a toggle flipping, a row highlighting, a number counting), but not their own arrive/hold/exit motion.
|
|
13
|
+
- “Hold”, “settled”, “landed” and “reading time” mean visually still, stable and readable. If a long hold needs life, add a discrete event (a click, a reveal, a state change), not a drift.
|
|
14
|
+
|
|
15
|
+
### Why no creep
|
|
16
|
+
|
|
17
|
+
Exports render in headless Linux Chromium, which snaps slowly moving text and elements to whole pixels. A slow drift does not glide: the subject sits still for many frames, then jumps a full pixel in one frame. At about 1 px/s that is a visible 1 px tick every ~0.9 s. This was measured on 2026-10-19 on a Slack-agent export (text holding for ~50 frames, then jumping ~0.7 px, repeatedly) and reproduced in isolation in Linux Chromium (1.0 px single-frame snaps). Mac Chrome positions text at fractional pixels, so the Studio preview can look smooth while the export ticks.
|
|
18
|
+
|
|
19
|
+
## Ownership and grouping
|
|
20
|
+
|
|
21
|
+
- The component controls foreground objects only. The host composition owns its environment. Never animate, zoom, rotate, translate, retime, pulse or otherwise modify a background merely to give a foreground component motion. A host-authored background may have its own independent clock.
|
|
22
|
+
- Keep the environment outside the subject transform hierarchy. Prefer transparent reusable foreground exports; Atelier preview backgrounds are separate host layers.
|
|
23
|
+
- Move a semantic assembly as one group: object, attached text, controls, caret, connector endpoints and contact shadow. The group is what arrives, holds and exits; its parts don't each get their own entrance.
|
|
24
|
+
- Make things breathe: one primary focus at a time, with generous negative space and comfortable margins around it. Keep supporting context subordinate, and sequence competing text and actions so each lands and is read before the next. If crowded, remove or sequence content before shrinking it. Camera pushes and reframing may serve that focus; one focus does not require a locked camera. Do not use a generic card as the default container for every concept.
|
|
25
|
+
- Preserve 3D hierarchy, object identity and attached geometry.
|
|
26
|
+
|
|
27
|
+
## Determinism
|
|
28
|
+
|
|
29
|
+
Derive every pose from the existing seekable composition clock. No wall-clock timers, unseeded randomness, infinite animation loops or accumulated per-frame deltas. Rewinding must reproduce the same pose.
|
|
30
|
+
|
|
31
|
+
## Exceptions
|
|
32
|
+
|
|
33
|
+
Genuine continuous travel is authored motion, not a hold: a ticker, a river of cards, a footage scrub or a deliberate camera move. Keep it fast enough to read as motion (well above a few px/s), or make it a cut. Historical exports are reference evidence, not assets to rewrite merely because the standard changed.
|
|
34
|
+
|
|
35
|
+
## Review and acceptance
|
|
36
|
+
|
|
37
|
+
1. Inspect the moving foreground at entrance, deceleration, hold and exit, in an export (not only the Studio preview).
|
|
38
|
+
2. In a reading hold, sample two frames 0.3–0.5 s apart: the held subject should not have moved by a visible amount (under ~0.5 px).
|
|
39
|
+
3. Confirm the exit accelerates out of the hold rather than jumping from a dead stop.
|
|
40
|
+
4. Verify attached labels, controls, shadows and projected anchors keep their relationships, with safe margins and readability throughout.
|
|
41
|
+
5. Verify object animation does not change the host background's framing or state.
|
|
42
|
+
6. Check repeated, reverse and retimed seeks.
|
|
43
|
+
|
|
44
|
+
## Maintenance and distribution
|
|
45
|
+
|
|
46
|
+
This document is canonical. The director playbook and motion-direction skill carry the operative rule; AGENTS.md, CLAUDE.md, Atelier guidance and repository entry points link here. The CLI bootstrap skill includes a portable summary because installed agents may not have the repository. Its source is `cli/assets/impractical/SKILL.md`; `scripts/build-claude-plugin.mjs` synchronizes the repository skill and plugin copy. `scripts/build-motion-library.mjs` embeds the playbook and authoring skills into the served motion library. MCP initialization instructions also state the default.
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
waitForJobs,
|
|
18
18
|
withAdmissionReceipt,
|
|
19
19
|
withMeteredCall
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-FTSZCIMV.js";
|
|
21
|
+
import "./chunk-2GCSX3YN.js";
|
|
22
22
|
import "./chunk-77HVPD4G.js";
|
|
23
23
|
export {
|
|
24
24
|
AGENT_HEADER,
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// package.json
|
|
4
|
+
var package_default = {
|
|
5
|
+
name: "@impractical-ai/motion",
|
|
6
|
+
version: "0.1.18",
|
|
7
|
+
private: false,
|
|
8
|
+
description: "Create and refine Impractical Motion videos from coding agents and the terminal.",
|
|
9
|
+
homepage: "https://github.com/Openpod/impractical-motion#readme",
|
|
10
|
+
repository: {
|
|
11
|
+
type: "git",
|
|
12
|
+
url: "git+https://github.com/Openpod/impractical-motion.git"
|
|
13
|
+
},
|
|
14
|
+
bugs: {
|
|
15
|
+
url: "https://github.com/Openpod/impractical-motion/issues"
|
|
16
|
+
},
|
|
17
|
+
license: "UNLICENSED",
|
|
18
|
+
type: "module",
|
|
19
|
+
files: [
|
|
20
|
+
"dist",
|
|
21
|
+
"assets",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
bin: {
|
|
25
|
+
impractical: "dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
engines: {
|
|
28
|
+
node: ">=22"
|
|
29
|
+
},
|
|
30
|
+
scripts: {
|
|
31
|
+
build: 'node ../scripts/verify-locked-cli-install.mjs && node ../scripts/build-engine-dts.mjs --cli-only && rm -rf dist && ./node_modules/esbuild/bin/esbuild src/index.ts --define:__BUILD_COMMIT__=\\"$(git rev-parse --short HEAD 2>/dev/null || echo dev)\\" --bundle --platform=node --format=esm --target=node22 --splitting --outdir=dist --external:playwright-core --banner:js="#!/usr/bin/env node" && chmod +x dist/index.js',
|
|
32
|
+
typecheck: "tsc --noEmit",
|
|
33
|
+
test: "npm run typecheck && npm run build && esbuild tests/onboarding.test.ts tests/mcp-tools.test.ts tests/mcp-frames.test.ts tests/mcp-browser-pool.test.ts tests/mcp-frames-watchdog.test.ts tests/mcp-motion.test.ts tests/mcp-craft.test.ts tests/mcp-depthkit.test.ts tests/mcp-motion-score.test.ts tests/mcp-install-font.test.ts tests/mcp-metric-catalog.test.ts tests/mcp-text-census.test.ts tests/mcp-video-ui.test.ts tests/mcp-template-search.test.ts tests/mcp-phased-flow.test.ts tests/mcp-preflight.test.ts tests/engine-dts.test.ts tests/mcp-connect.test.ts tests/mcp-workspaces.test.ts tests/mcp-longpoll.test.ts tests/mcp-agent-timeout.test.ts tests/api-hardening.test.ts tests/guidance.test.ts tests/mcp-image-scale.test.ts --bundle --platform=node --format=esm --packages=external --outdir=dist --out-extension:.js=.mjs && node --test dist/onboarding.test.mjs dist/mcp-tools.test.mjs dist/mcp-frames.test.mjs dist/mcp-browser-pool.test.mjs dist/mcp-frames-watchdog.test.mjs dist/mcp-motion.test.mjs dist/mcp-craft.test.mjs dist/mcp-depthkit.test.mjs dist/mcp-motion-score.test.mjs dist/mcp-install-font.test.mjs dist/mcp-metric-catalog.test.mjs dist/mcp-text-census.test.mjs dist/mcp-video-ui.test.mjs dist/mcp-template-search.test.mjs dist/mcp-phased-flow.test.mjs dist/mcp-preflight.test.mjs dist/engine-dts.test.mjs dist/mcp-connect.test.mjs dist/mcp-workspaces.test.mjs dist/mcp-longpoll.test.mjs dist/mcp-agent-timeout.test.mjs dist/api-hardening.test.mjs dist/guidance.test.mjs dist/mcp-image-scale.test.mjs",
|
|
34
|
+
prepack: "npm run build",
|
|
35
|
+
"test:rig": "npm run typecheck && esbuild tests/engine-dts.test.ts tests/mcp-agent-timeout.test.ts tests/mcp-browser-pool.test.ts tests/mcp-frames-watchdog.test.ts tests/mcp-component-assertions.test.ts tests/mcp-components.test.ts tests/mcp-connect.test.ts tests/mcp-craft.test.ts tests/mcp-depthkit.test.ts tests/mcp-exposed-ground.test.ts tests/mcp-frames.test.ts tests/mcp-install-font.test.ts tests/mcp-legibility.test.ts tests/mcp-longpoll.test.ts tests/mcp-metric-catalog.test.ts tests/mcp-motion-score.test.ts tests/mcp-motion-slop.test.ts tests/mcp-motion.test.ts tests/mcp-phased-flow.test.ts tests/mcp-preflight.test.ts tests/mcp-ref-inject.test.ts tests/mcp-shot-list.test.ts tests/mcp-text-census.test.ts tests/mcp-tools.test.ts tests/mcp-video-ui.test.ts tests/review-modules.test.ts tests/rig-transplant.test.ts --bundle --platform=node --format=esm --packages=external --outdir=.rig-tests --out-extension:.js=.mjs && node --test .rig-tests/engine-dts.test.mjs .rig-tests/mcp-agent-timeout.test.mjs .rig-tests/mcp-browser-pool.test.mjs .rig-tests/mcp-frames-watchdog.test.mjs .rig-tests/mcp-component-assertions.test.mjs .rig-tests/mcp-components.test.mjs .rig-tests/mcp-connect.test.mjs .rig-tests/mcp-craft.test.mjs .rig-tests/mcp-depthkit.test.mjs .rig-tests/mcp-exposed-ground.test.mjs .rig-tests/mcp-frames.test.mjs .rig-tests/mcp-install-font.test.mjs .rig-tests/mcp-legibility.test.mjs .rig-tests/mcp-longpoll.test.mjs .rig-tests/mcp-metric-catalog.test.mjs .rig-tests/mcp-motion-score.test.mjs .rig-tests/mcp-motion-slop.test.mjs .rig-tests/mcp-motion.test.mjs .rig-tests/mcp-phased-flow.test.mjs .rig-tests/mcp-preflight.test.mjs .rig-tests/mcp-ref-inject.test.mjs .rig-tests/mcp-shot-list.test.mjs .rig-tests/mcp-text-census.test.mjs .rig-tests/mcp-tools.test.mjs .rig-tests/mcp-video-ui.test.mjs .rig-tests/review-modules.test.mjs .rig-tests/rig-transplant.test.mjs"
|
|
36
|
+
},
|
|
37
|
+
publishConfig: {
|
|
38
|
+
access: "public"
|
|
39
|
+
},
|
|
40
|
+
devDependencies: {
|
|
41
|
+
"@types/node": "^26.1.0",
|
|
42
|
+
esbuild: "^0.25.0",
|
|
43
|
+
typescript: "^5.6.3"
|
|
44
|
+
},
|
|
45
|
+
dependencies: {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
47
|
+
"playwright-core": "^1.55.1",
|
|
48
|
+
zod: "^4.4.3"
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// src/constants.ts
|
|
53
|
+
if (package_default.name !== "@impractical-ai/motion" || typeof package_default.version !== "string" || !package_default.version) {
|
|
54
|
+
throw new Error("The packaged CLI manifest is missing valid release metadata");
|
|
55
|
+
}
|
|
56
|
+
var PRODUCTION_APP_URL = "https://motion.impractical.ai";
|
|
57
|
+
var PRODUCTION_SUPABASE_URL = "https://uaxjweednprtbhbceify.supabase.co";
|
|
58
|
+
var PACKAGE_NAME = "@impractical-ai/motion";
|
|
59
|
+
var PACKAGE_VERSION = package_default.version;
|
|
60
|
+
var BUILD_COMMIT = "440f47f" ? "440f47f" : "dev";
|
|
61
|
+
var BUILD_ID = `${PACKAGE_VERSION}+${BUILD_COMMIT}`;
|
|
62
|
+
var PACKAGE_COMMAND = `npx --yes ${PACKAGE_NAME}`;
|
|
63
|
+
|
|
64
|
+
export {
|
|
65
|
+
PRODUCTION_APP_URL,
|
|
66
|
+
PRODUCTION_SUPABASE_URL,
|
|
67
|
+
PACKAGE_NAME,
|
|
68
|
+
PACKAGE_VERSION,
|
|
69
|
+
BUILD_COMMIT,
|
|
70
|
+
PACKAGE_COMMAND
|
|
71
|
+
};
|