Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,19 @@ agent workflow.
https://screenrig.ai/pricing/. Write in a feature-complete voice.
- Teach local compose (`compose catalog`, `compose render`) for copy and
chrome. Do not teach emitting native `text`, `box`, or `line` on the
playlist wire. Wire families are static (`image`), motion (`video`),
and web (`iframe`, `application`). Compose is local and not billed.
playlist wire. Compose is local and not billed.
- The category word is **primitive**, never placement, kind, or type. Four
wire primitives exist: static (`image`), motion (`video`), and web
(`iframe`, `application`). A page carries `pages[].primitives`, and each
entry is flat: a `primitive` field naming the family, that family's own
fields, then `rect`, `layer`, `content_fit`, and optional `enter`. There is
no nested content object. Image and video primitives take a `selector`
(`by` is `id`, `ids`, `all`, or `tag`); iframe and application do not.
`media list` filters with `--primitive`, the API parameter is `primitive`,
and the event field is `primitive_id`. MIME `--content-type`, `feedback
--kind`, and transition/enter/advance `type` are unrelated and stay. Teach
the primitive wire alone: no placement compat shim and no dual-read of the
retired vocabulary.
- Screenshotting is in v1. `screen screenshot <id>` blocks on a still WebP and
writes a file. Do not print pixels.
- Human `events list` and `events follow` print logfmt. `--json events list`
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,20 @@ code.

## Four primitives

Four wire kinds: `image`, `video`, `iframe`, and `application`.
A playlist page carries `primitives`, and every one of them names its family in
a `primitive` field. There are four:

- `image` — a still the native Player paints on the glass.
- `video` — H.264, native decode. No codec fallback.
- `iframe` — a page already on the web.
- `application` — a static directory packed by the CLI. Players sync, then
paint from disk.

A scene places these four on one canvas. Copy and chrome compose locally on the
`image` and `video` primitives pick their media with a `selector`, whose `by`
is `id`, `ids`, `all`, or `tag`. `iframe` and `application` take no selector:
an iframe carries its `src`, and an application pins a `release_id`.

A scene puts these four on one canvas. Copy and chrome compose locally on the
agent machine with `compose catalog` and `compose render`: the agent renders a
PNG, looks at it, iterates, then publishes the still. Local compose is not
billed. The agent can also screenshot a live screen to check its own work.
Expand Down
4 changes: 2 additions & 2 deletions components.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"state": "resolved",
"cli": {
"repository": "screenrig/cli",
"commit": "b2370125765cfbb4911f0a78c69ae37e92a34702",
"commit": "a0890d226d3ec92916e314eeca094ec2edc1bf1e",
"artifact": {
"file": "screenrig-cli.tgz",
"sha256": "d736da238eddfab35b5a6ad86339f8c956b4ca393d7a5908b0fbe14e2bc4ae71"
"sha256": "8ca6feca8e9c8053fe16e033d68d6c5feef00de995923d59c8d19205f51c5e03"
}
}
}
9 changes: 7 additions & 2 deletions plugins/screenrig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,20 @@ code.

## Four primitives

Four wire kinds: `image`, `video`, `iframe`, and `application`.
A playlist page carries `primitives`, and every one of them names its family in
a `primitive` field. There are four:

- `image` — a still the native Player paints on the glass.
- `video` — H.264, native decode. No codec fallback.
- `iframe` — a page already on the web.
- `application` — a static directory packed by the CLI. Players sync, then
paint from disk.

A scene places these four on one canvas. Copy and chrome compose locally on the
`image` and `video` primitives pick their media with a `selector`, whose `by`
is `id`, `ids`, `all`, or `tag`. `iframe` and `application` take no selector:
an iframe carries its `src`, and an application pins a `release_id`.

A scene puts these four on one canvas. Copy and chrome compose locally on the
agent machine with `compose catalog` and `compose render`: the agent renders a
PNG, looks at it, iterates, then publishes the still. Local compose is not
billed. The agent can also screenshot a live screen to check its own work.
Expand Down
43 changes: 22 additions & 21 deletions plugins/screenrig/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,41 +164,41 @@ ScreenRig content has three families: static images, including stills produced
by local compose; motion video; and web content delivered as an `iframe` or
`application`.

Playlist pages on the wire use `image`, `video`, `iframe`, and `application`
only. Copy and chrome are composed locally, uploaded as `image`, then placed
as one image. `playlist templates` is a local catalog of slide ids; templates
that would emit native `text`, `box`, or `line` fail with a pointer at
Four wire primitives are supported: `image`, `video`, `iframe`, and
`application`. Copy and chrome are composed locally, uploaded as `image`,
then used as one image primitive. `playlist templates` is a local catalog of
slide ids; templates that would emit native `text`, `box`, or `line` fail with a pointer at
`compose catalog` and `compose render`. Picture-only templates still expand
to image or video placements with selectors. A page without `template` is
forwarded unchanged when its placements are those wire kinds.
to image or video primitives with selectors. A page without `template` is
forwarded unchanged when its `primitives` use those four wire primitives.
`canvas.background` is a solid uppercase `#RRGGBBAA` or a top-to-bottom
linear gradient (`type` `linear`, 2 through 8 strictly increasing stops,
first `at` 0, last `at` 1, no angle). Image and video placements write a
first `at` 0, last `at` 1, no angle). Image and video primitives write a
`selector` (`by` is `id`, `ids`, `all`, or `tag`). Do not put `media_id` on
the content object, and do not send server-resolved `items`. Page advance
uses `duration`, `application`, or `media_end`. There is no `video_end`
mode.
the primitive itself; it belongs inside the selector. Iframe and application
primitives do not take a selector. Page advance uses `duration`, `application`,
or `media_end`. There is no `video_end` mode.

Default pages use `{ "type": "crossfade", "duration_ms": 200 }` and put no
`enter` on placements. `transition.type` may also be `swipe-left`,
`enter` on objects. `transition.type` may also be `swipe-left`,
`swipe-right`, `swipe-up`, or `swipe-down`. `duration_ms` is required and
runs from 0 through 60000. When a swipe type is chosen, write
`duration_ms: 600`. That is the authoring default for swipe, not a schema
default, and it does not change the template default. Swipe is the incoming
page's type. The outgoing page follows so the edges stay touching. The name
is motion direction: `swipe-left` moves content left.

Optional placement `enter` is `{ "type": "..." }` with that same object
name on playlist JSON. There is no snake_case rename inside it. Types are
Optional object `enter` is `{ "type": "..." }` with that same object name on
playlist JSON. There is no snake_case rename inside it. Types are
`fade-up`, `fade-down`, `fade-left`, `fade-right`, `fade-in`, `zoom-in`,
and `zoom-out`. Absent means no object animation. Use swipe and `enter`
sparingly, for emphasis or a particular style, not on every page. If you
want object animation, layer the content and put the motion on the
top-layer text or images. Do not animate every placement. Object enter
want object animation, layer the primitives and put the motion on the
top-layer text or images. Do not animate every object. Object enter
starts invisible. It runs 500 ms after the page occupies the full
viewport, for 400 ms. Those delays are contract constants, not author
fields and not CLI flags. The pinned CLI implements these playlist document
fields, and the control plane accepts swipe types and placement `enter`. This
fields, and the control plane accepts swipe types and object `enter`. This
does not establish marketplace availability or deployment.

The ordinary pair command currently accepts six canonical characters:
Expand Down Expand Up @@ -405,7 +405,7 @@ renames it into place. The bundle contains `screenrig-bundle.json`,
`playlist.json`, and content-addressed `media/<sha256>.<canonical-ext>` files.
The manifest records `selector_policy: "snapshot"` and
`comments_policy: "excluded"`. Dynamic `all` and `tag` selectors become exact
`id` or `ids` snapshots. Iframes remain URLs. Application placements are
`id` or `ids` snapshots. Iframes remain URLs. Application primitives are
rejected before any media download because v1 has no application-package
export.

Expand Down Expand Up @@ -509,7 +509,7 @@ relative to the spec file. The CLI does not fetch URLs.
`--open` is only for viewing the still on this computer. Agent vision reads
the file path. Do not cat pixels into chat.

A playlist page for that still is one `image` placement whose `rect` is the
A playlist page for that still is one `image` primitive whose `rect` is the
canvas and whose `content_fit` is `fill`.

## Events
Expand All @@ -530,7 +530,7 @@ screenrig --json playback list --screen-id scr_01 --day 2026-08-14
```

A human line looks like
`at=2026-08-14T17:00:00.000Z type=application.event severity=info code=cta.pressed placement_id=weather`.
`at=2026-08-14T17:00:00.000Z type=application.event severity=info code=cta.pressed primitive_id=weather`.
It carries `at`, `type`, `severity`, optional resource fields, scalar
details, and a non-canned `message`. Canned server sentences are omitted. An
`application.event` or `runtime.reported` with no remaining data is silent. A
Expand Down Expand Up @@ -664,12 +664,13 @@ screenrig --json media upload ./clip.mov
screenrig --json media upload ./clip.mov --codec hevc
screenrig --json media upload ./poster.png --no-transcode
screenrig --json media upload ./lobby-welcome.png --tag lobby
screenrig --json media list --tag lobby --kind image
screenrig --json media list --tag lobby --primitive image
screenrig --json media update med_01 --tag lobby --if-match 1
screenrig --json media update med_01 --clear-tag --if-match 2
```

`media list` forwards `--tag` and `--kind image|video` as query filters.
`media list` forwards `--tag` and `--primitive image|video` to
`GET /api/v1/media` as `tag` and `primitive` parameters.
Untagged objects are omitted when `--tag` is present. `media update` patches
the tag only; `--clear-tag` sends `null`. There is no other media metadata
patch.
Expand Down
6 changes: 3 additions & 3 deletions plugins/screenrig/cli/dist/adapters/protocol.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export interface OperationAccepted {
id: string;
/**
* Release created by this upload. The server has always returned it and the
* contract now requires it. It is the only handle a playlist placement
* contract now requires it. It is the only handle an application primitive
* accepts, so report it rather than making the caller poll the operation.
*/
release_id: string;
Expand Down Expand Up @@ -197,11 +197,11 @@ export declare function limitsFromCapabilities(capabilities: Capabilities): Arch
/**
* Full playlist pages stay opaque: the CLI forwards author-supplied playlist
* JSON unchanged, including `transition.type` swipe variants and optional
* placement `enter`. Templated pages are the exception — the CLI expands
* object `enter`. Templated pages are the exception — the CLI expands
* `template` + `slots` into an ordinary write page in `playlist-templates.ts`
* and never sends `template` to the server. Omitted templated transitions stay
* `{ type: "crossfade", duration_ms: 200 }` with no `enter`. The contract's
* page, placement, and content schemas are still not mirrored here except for
* page and primitive schemas are still not mirrored here except for
* the fields that expander writes. Mirror a schema only when the CLI builds or
* reads its fields.
*
Expand Down
2 changes: 1 addition & 1 deletion plugins/screenrig/cli/dist/argv.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions plugins/screenrig/cli/dist/argv.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/screenrig/cli/dist/argv.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading