remixx-cli
v0.10.1
Published
Portable creator client for turning an AI work session into a Remixx review revision
Maintainers
Readme
remixx-cli
remixx-cli is the agent-facing Remixx creator client. It validates a versioned report request, submits a
new report or revision to Remixx with an idempotency key, and returns the stable review result. It is intended
for an AI workspace to invoke on the creator's behalf; the creator does not need to install it globally.
Run it
Authenticate once with Node.js 20 or newer. On a workstation with a browser:
npx --yes remixx-cli@latest login --jsonThe browser uses OAuth 2.1 authorization-code PKCE and returns to the fixed loopback callback
http://127.0.0.1:45454/auth/callback. The CLI is a public client: it has a public client ID and no client
secret. For an SSH session or container, the creator creates a developer token on the Remixx Account page and
passes it over stdin from a password manager or other secret-safe source:
password-manager read remixx/developer-token | \
npx --yes remixx-cli@latest login --token-stdin --jsonDo not put the developer token in an argument, request file, shell history, or environment variable. It is shown once in the browser, stored only as a hash by Remixx, expires within 90 days, rotates silently before expiry, and can be individually revoked on the Account page.
Resolve continuity before capture, including from a fresh terminal with no Remixx environment variables. Pass the intent document on standard input; do not create an intent file in the Project:
printf '%s' "$INTENT_JSON" | \
npx --yes remixx-cli@latest report context \
--intent-stdin \
--workspace "$PWD" \
--jsonThe server decides new versus existing and returns recent public outcomes plus an opaque resolution. The
client indexes an opaque continuity receipt by the canonical workspace path locally; the path never leaves
the machine and no .remixx identity file is written.
The returned resolution token is short-lived and consumed by report create. Keep the intent in memory, not
in the Project, and request fresh context again immediately before create—after the creator-side proposal is
ready. The earlier context still supplies the continuity facts needed to author the capture request.
After preparing the destination-safe v4 proof-of-change request (or a legacy v3 request) as an in-memory
document, let the client execute and probe capture. V4 may contain one stable or motion-only scene with
narrationMode: "none"; it does not require a click or drag. The result contains an opaque captureId; it
never contains a filesystem path.
printf '%s' "$REQUEST_JSON" | \
npx --yes remixx-cli@latest report capture \
--request-stdin \
--jsonThen create the resolved draft with that ID. The client reuses the saved request and evidence privately:
For a V4 capture, first prepare the creator-side director package. This is the
only command that reveals the two private working-state paths needed by the
creator's coding agent: a de-identified DirectorVisibleEvidence catalog plus
structured capture facts, and a locally rendered contact sheet. It does not
send either to Remixx.
npx --yes remixx-cli@latest report direct \
--capture-id "$CAPTURE_ID" \
--jsonThe client reads the public schema index first, so the package names the exact server-selected director contract instead of guessing a version. The creator's agent reads the returned paths, follows the package's embedded instructions, and writes that proposal. Under the current v2 contract, the first card is the evidence hero and each later card is one sanitized authored-slide still. Store the proposal back into the same private capture state before creating:
printf '%s' "$DIRECTOR_PROPOSAL_JSON" | \
npx --yes remixx-cli@latest report direct \
--capture-id "$CAPTURE_ID" \
--proposal-stdin \
--jsonreport create then carries that proposal with the final evidence receipt;
the server materializes only its evidence_* handles, verifies it, and binds
the accepted plan before enqueueing a render.
Refresh context with the same intent immediately before this command and use the new resolutionToken. This
keeps its short TTL on the machine mutation rather than on the directing step; it does not re-record evidence.
npx --yes remixx-cli@latest report create \
--capture-id "$CAPTURE_ID" \
--resolution-token "$RESOLUTION" \
--workspace "$PWD" \
--idempotency-key "$KEY" \
--wait \
--jsonFor v2 proposals, report direct runs authored-slide HTML through the shared
sanitizer, records the exact sanitized bytes and SHA-256, and stores only that
canonical proposal. The server verifies it independently and the worker
sanitizes again before rasterizing each still.
The agent chooses truthful selectors and actions; the client owns browser execution,
byte-derived manifest metadata, hashing, object-scoped signed grants, resumable TUS upload, finalization, and
render polling. For an edit, use report revise with a remixx-report-revision-request.v2 request and the
opaque capture ID returned by report capture. Revision custody comes from the Run and cannot be redirected.
Repeat an identical mutation with the same idempotency key. requestHash identifies the create or revision
request; a creator-side proposal is separately identified by proposalHash. Changing either while reusing a
key returns idempotency_conflict. An idempotency key must contain 8 to 200 characters.
If the verifier rejects the proposal, stdout is a
remixx-editorial-plan-rejection.v1 object with the exact codes, JSON paths,
and messages. The client saves that response privately for the creator's
agent. It also saves an accepted outcome and its advisory findings. Store a
different proposal with report direct --proposal-stdin, then run report
revise --capture-id "$CAPTURE_ID" --wait with a fresh idempotency key. This
creates a successor revision at the same review URL; it never mutates the
predecessor.
For a retryable render_failed, retry the identical command only while the
proposal is unchanged. To correct the proposal, store the corrected plan and
use report revise with a fresh key; the retained evidence and review URL are
inherited. Do not retry report create with a new key and the old resolution
token. If a genuinely new Run is needed, run report context again for a
fresh token and use a new key.
report capture writes manifest.json only inside the client's private capture state after probing the
recorded bytes. The agent receives a remixx-capture-result.v2 with an opaque captureId, the evidence IDs,
and any skipped capture details; it never receives the evidence root or manifest path. The private manifest's
versioned shape is:
{
"schemaVersion": "remixx-evidence-manifest.v1",
"assets": [
{
"evidenceId": "capture:result",
"relativePath": "result.webm",
"clientAssetId": "capture_result",
"kind": "capture_video",
"role": "evidence_capture",
"ordinal": 0,
"sceneId": "export_result",
"mimeType": "video/webm",
"codec": "vp8",
"width": 1440,
"height": 900,
"durationMs": 8200,
"rightsDeclaration": "creator_owned",
"disclosure": "Creator-owned localhost product capture."
}
]
}For a create request, manifest evidenceId values must exactly match
privacy.allowedEvidenceIds, and every claim reference must be allowed. Paths are always relative: absolute
paths, .. traversal, missing/non-file targets, and symlinks escaping the evidence root are rejected before
any network mutation. The client hashes the actual bytes and supplies byte length itself; neither belongs in
the manifest. Each asset and the whole capture bundle are checked against the 32 MiB client limit and the
request's smaller capture budget before transfer. A revision finalizes the manifest's new assets together
with inheritAssetHashes; an inheritance-only revision uses an empty manifest.
Process contract
- stdout contains exactly one JSON object: a command receipt,
remixx-client-result.v1on normal Report success,remixx-client-error.v1on runtime failure, orremixx-editorial-plan-rejection.v1when the plan verifier requests a reproposal. - stderr contains human-readable progress and diagnostics. Agents must never parse it to determine state.
- A failure exits nonzero. Read its stable
code,message, andretryablefields from stdout. - The client stores its credential only in
credentials.jsonwith mode0600, inside a state directory with mode0700. Idempotency receipts never contain the credential. The state directory is--state-dir, thenREMIXX_STATE_DIR, then$XDG_STATE_HOME/remixx, then~/.local/state/remixx. - Capture request documents, evidence, and manifests live only under the client-owned
work/captures/<opaque-id>state area. Failed capture state is removed immediately. A completed capture is retained for up to 24 hours so an interrupted create can resume, then reclaimed by the next capture or create operation. The client never prints that path or accepts an agent-selected evidence directory. - It does not write
.env.local,.remixx-session, credentials, evidence, request documents, or generated report machinery into the Project, and it never edits the Project's.gitignore. Credential refresh and atomic replacement are protected by a cross-process lock, so simultaneous agents perform one refresh. - Interrupted
--waitjourneys keep a mode-0600receipt beside the idempotency result. It binds the key to requestHash, the evidence manifest hash, and proposalHash, and records only run identity, completed assets, and TUS resume URLs—never a credential or signed upload token. Re-run the identical command to resume or no-op.
A success includes operation, runId, revisionId, revisionNumber, status, reviewUrl,
idempotencyKey, requestHash, and any structured warnings.
projectId is present for an existing destination and intentionally absent for a first-post draft until the
creator presses Post in review.
Failure codes
The remixx-client-error.v1 code is one of:
- Client and control plane:
client_request_invalid,control_plane_unavailable,control_plane_response_invalid,authentication_required,client_revoked,idempotency_conflict,idempotency_in_progress,project_binding_missing,project_confirmation_required,project_resolution_ambiguous,project_resolution_failed,resolution_token_expired,resolution_token_conflict,workspace_continuity_mismatch,project_context_stale,materially_repeats_recent_post,request_schema_invalid. - Capture and disclosure:
unsafe_capture_target,unsupported_capture_target,capture_precondition_failed,capture_step_failed,capture_postcondition_failed,capture_blank_or_frozen,no_visible_change,evidence_disclosure_blocked. - Assets and upload:
asset_hash_mismatch,asset_metadata_mismatch,upload_grant_expired,upload_incomplete. - Narration, rendering, and publication state:
narration_provider_unavailable,narration_alignment_invalid,editorial_plan_required,render_failed,render_output_invalid,revision_superseded,publication_hash_mismatch.
Authentication
remixx login, remixx whoami, and remixx logout all require --json. whoami reports the actor and
credential kind without exposing a token. logout revokes the current server credential and removes the local
file. Browser sessions refresh through the OAuth token endpoint; developer tokens rotate through Remixx and
are revalidated on every request. Neither path uses a service-role key in the published package.
Without a usable credential, stdout contains remixx-client-error.v1 with code authentication_required and
the single-action message Run remixx login. There is no interactive prompt when input/output is redirected.
The public package bundles its protocol and resumable-upload code and declares Playwright plus Sharp for
client-owned capture and media probing. Publication is never a CLI authority.
V3 and V4 accept unauthenticated localhost web capture requests only. Hosted sites, native applications, the OAuth device authorization grant, MCP, and publication are outside this package.
