- name
- core
- description
- Operate remote Workspace Resources with uvw. Use for authentication, Space Node discovery and organization, per-task Worktree creation, existing-Univer-Resource staging, Unit authoring, verification, review handoff, rework, and export. Start every new editable-content task in a new Worktree; continue an existing Worktree only for rework on that same task.
# Univer Workspace CLI Core
Use `uvw` for remote Workspace content. If it is unavailable, stop and report that
the Workspace CLI is not installed. Do not substitute a local office writer because that bypasses
the remote Worktree and review lifecycle.
## Bind shared operations to the CLI
Other Skills name operations without `uvw`. Each is the `uvw` command of the same name, with flags defined by `uvw <command> --help`. Load a Skill with `uvw skills get <name>` and a reference with `uvw skills read <name> <path>`. Use `uvw skills get <name> --full` only when all references are needed; `uvw skills path <name> --json` locates installed files.
For local inputs, output paths, structured JSON, overwrite controls, browser setup, and file-backed sources, read [CLI files and sources](references/files-and-sources.md). It covers Office exchange, screenshots and PDFs, Slide SVG assets and resources, Typst bundles, Markdown maps and assets, Blob transfer, and HTML View sources.
## SVG resources
When a Unit needs icons, logos, emoji, or illustrations, use the built-in SVG resource library:
```bash
uvw resources registries
uvw resources find <query> [<query>...]
uvw resources export <handle> [<handle>...] --out <directory>
```
## Concepts
Understand these identities before running a mutation:
- **Workspace origin**: the remote Workspace service address of the user's own deployment.
Point the CLI at it with `uvw config set workspace.origin <origin>` before
connecting.
- **Space** (a _repository_): the container whose visible tree is made of Nodes. A Team Space is named
`<owner>/<slug>`; every Personal Space is `<owner>/personal`. Pass that name as `-R <owner>/<slug>`
(or set `UVW_REPO`); a Space ID, a Workspace URL, or a bare slug that uniquely matches
`uvw repo list` is accepted wherever a repository is expected. Unknown or ambiguous slugs
require owner/slug; the error lists matching candidates.
A Team Space created before slugs existed may have no name; use its Space ID.
- **Personal Space**: the authenticated user's own Space. Files here are personal Workspace files.
A Personal Space is not a Worktree. Its repository name is `<username>/personal`.
- **Team Space**: a Space shared by a team. Access depends on current team membership and role.
- **Issue**: a Team Space discussion item addressed by Space and number (`#12`), with a Markdown
body, comments, labels, assignees, and referenced Nodes. Personal Spaces have no Issues. An Issue
is a request, not a Worktree: reading or commenting on it never changes Space files.
- **Node**: one tree position addressed by `nodeId`. Every Node may have children. A pure
organizational Node has `resource: null`; a Node with a Resource may still have children.
- **Resource**: the product content identity attached to a Node, discriminated by `kind`.
- **Univer Resource**: `kind: "univer"`, with one Sheet, Doc, Slide, Base, or Board `unitType`.
Use its `resourceId` to add existing editable content to a Worktree.
- **Blob Resource**: `kind: "blob"`, with MIME, byte size, and availability but no `unitType` or
`unitId`. Upload/download it directly; never add it to a Worktree.
- **Unit**: the Collaboration content identity inside one Worktree. Use its `unitId` for execute,
inspect, screenshot, export, snapshot, and changeset operations.
- **Worktree**: one task's isolated Agent workspace and draft/review boundary. Changes remain
isolated from the normal Space file until the Worktree is merged. The CLI calls it a **pull
request** (`uvw pr ...`); `uvw worktree ...` is an equivalent spelling with the same options and
output. This Skill uses `pr`. A Team Worktree shares its `#N` number sequence with the Space's Issues;
a Worktree created before numbering existed has `number: null` and is addressed by its `id`.
- **User-scoped Worktree**: a private Worktree owned by the authenticated user, created with `-R <username>/personal`. It can contain Units
the user may edit from Personal or Team Spaces. It is not a Personal Space.
- **Space-scoped Worktree**: a Worktree belonging to one Team Space, created with `-R <owner>/<slug>`. It can contain only Units from
that Space and may be private or visible to that Space.
- **Worktree-local Unit**: a new Unit created inside a Worktree. The server allocates its
`unitId`, `resourceId`, and `nodeId`; merge activates the target Node/Resource.
Never interchange `spaceId`, `nodeId`, `resourceId`, `unitId`, Worktree `id`, pull request number, or
display name. Content commands (`execute`, `inspect`, `screenshot`, `unit`, `import`, `export`, ...) take
`--worktree <id>`: the `id` field of `uvw pr view <n> -R <repo> --json id`, not the `#N` number.
Use display names and `path` only for discovery and disambiguation; use stable ids for commands.
`space browse` and `space find` discover Nodes and Resources before they enter a Worktree. `unit list` only lists
Units already staged in one explicit Worktree. The separate `resources` command is an SVG asset
catalog, not Workspace file discovery.
Filter discovery by Resource kind and, independently, Univer Unit type:
```bash
uvw space browse <space-id> --resource-kind blob --json
uvw space find <name> --space <space-id> --resource-kind univer --unit-type doc --json
uvw space browse <space-id> --resource-kind none --json
```
`--unit-type` may be combined only with `--resource-kind univer`. Filters change returned results,
not recursive reachability; a Blob Resource Node may still have children.
## Blob files
For original-file upload, download and replacement, read the [Blob Skill](../blob/SKILL.md)
with `uvw skills get blob`.
## HTML Views
For live HTML pages backed by Sheet data, read the [HTML View Skill](../html-view/SKILL.md)
with `uvw skills get html-view`.
## Manage Space Nodes
Create a root organizational Node by naming the target Space:
```bash
uvw space node create \
<space-id> --name <node-name> --json
```
Create a direct child by passing the stable Node ID returned by the first command. A Resource Node
may also be the parent when its capabilities allow child creation:
```bash
uvw space node create \
<space-id> --name <child-node-name> --parent <node-id> --json
```
Use that returned Node ID as `--parent <node-id>` when creating a Unit at that location. Do not
derive a parent from a display path or Node name.
Node creation is a direct Space write. It is not isolated in a Worktree, and Worktree
discard cannot undo it. The first version is non-idempotent: if the command reports
`workspace-result-unknown`, the Node may already exist. Do not retry blindly. First run
`space browse <space-id> --parent <parent-node-id> --json`, or omit `--parent` when the target was
the Space root, then decide whether to retry. Because sibling Nodes may share a name, never assume
an arbitrary same-name result is the Node created by the interrupted request.
Rename an organizational or Resource Node by stable Node ID:
```bash
uvw space node rename \
<node-id> --name <new-name> --json
```
Move a Node by choosing exactly one destination form. Use `--root` only when the intended
destination is the current Space root:
```bash
uvw space node move \
<node-id> --parent <destination-node-id> --json
uvw space node move <node-id> --root --json
```
Rename and move are direct desired-state Space writes. If their write response is interrupted, the
CLI reads the same stable Node ID and reports success only when current metadata matches the requested
name or parent. If it still returns `workspace-result-unknown`, inspect the relevant directory before
deciding whether to issue another write.
Trash is a user-authorized recursive lifecycle action. Run it only when the user explicitly asks to
remove that Node subtree from its Space location:
```bash
uvw space node trash <node-id> --json
```
Read and retain the returned `trashBatchId` and `nodeCount`. Trash creates a new batch and is not
blindly retryable: after `workspace-result-unknown`, do not issue the command again because the first
request may already have moved the subtree and the batch identity was not confirmed. The current CLI
does not restore or permanently remove Trash Batches.
## Worktree rule
**Start every new task in a new Worktree.** Do not select or reuse an active Worktree merely because
its name, Space, or Unit looks suitable. `pr list` is diagnostic; it is not permission to
continue someone else's or another task's draft.
Continue an existing Worktree only when all of these are true:
1. The current request is rework or a correction for the same task.
2. This Agent already worked on that task in a known Worktree. Resolve that same Worktree from
retained task context or from an id the user supplies specifically for this rework.
3. The Worktree is still `draft` or `ready`.
For rework, continue a `draft` Worktree directly. Reopen a `ready` Worktree before editing. Never
reuse a `merged` or `discarded` Worktree; start a new Worktree instead. If task-to-Worktree identity
is uncertain, start a new Worktree rather than guessing.
## Connect
Point the CLI at the user's Workspace deployment before connecting, then use the
two-command browser approval protocol below. Never ask the user for a password.
```bash
# Point the CLI at the user's Workspace deployment:
uvw config set workspace.origin https://workspace.example.com
# Step 1: create an approval request. This command exits immediately.
uvw auth login --json
# Step 2: relay verificationUrl and userCode to the user, then STOP.
# Do not poll, do not run --complete, and do not continue the Workspace task.
# Wait until the user explicitly says that they approved the request.
# Step 3: only after that user confirmation, exchange the approval once.
uvw auth login --complete --json
# Compatibility only, when the caller already owns a password secret:
printf '%s\n' "$WORKSPACE_PASSWORD" | uvw auth login --username <name> --password-stdin
uvw auth status --json
uvw repo list --json
```
`repo list` shows repositories you own or have joined. Open another public repository with
`uvw repo view <owner>/<slug>`.
Exit code 4 means sign-in is required: run `uvw auth login`, do not retry the failed command.
`--json` prints the bare object or array (no `{ issue }` or `{ worktree }` wrapper); `--json id,number`
keeps only those top-level fields.
The first command returns `status: "authorization_required"`, `verificationUrl`, `userCode`,
`expiresAt`, and `nextCommand`. The completion command also exits immediately: it returns
`status: "authenticated"` on success or `status: "authorization_pending"` if the browser approval
has not finished. If it is still pending, show the same URL/code to the user and wait for their
reply; do not create a polling loop. Password, GitHub, and Discord browser accounts all use this
same handoff.
## Work from an Issue
When the user asks you to handle an Issue ("work on #12"), the Issue is the brief. Do not ask the user
to restate it.
1. Resolve an owned or joined repository with `repo list`, or a public repository with
`uvw repo view <owner>/<slug>`, and read the Issue with its whole discussion:
```bash
uvw issue view 12 -R <owner>/<slug> -c --json
```
The newest comments may change or narrow the request; read them before acting. Without a
repository, `uvw search issues -a @me --json` shows the work assigned to the user across Team Spaces.
2. `references[]` lists the files the Issue points at. Use `resource.id` as the
`resourceId` and `nodeId` to stage them. A reference with `available: false` was trashed or
became unreadable; say so instead of guessing which file was meant.
3. Follow "Start a new task" in a **new** Space-scoped pull request titled `#12 <Issue title>`. The
Worktree does not link to the Issue itself, so that name is what ties them together for reviewers.
4. Verify and hand off as usual, then report on the Issue. Post the review URL with what you changed;
write multi-line Markdown through stdin so nothing needs shell escaping:
```bash
uvw issue comment 12 -R <owner>/<slug> -F - --json <<'MD'
Updated `Budget!B12` to include the East region.
Review: <review-url>
_Posted by an agent on the user's behalf._
MD
```
5. Leave the Issue open. Closing it (`issue close`) or merging the Worktree is the user's decision;
do either only when they ask.
Issue writes are not idempotent. If a create or comment fails with `workspace-result-unknown`,
read `issue view ... -c` before repeating it, or the discussion may end up with a duplicate.
Labels and assignees need triage rights; when the CLI reports `FORBIDDEN`, tell the user rather than
working around it. Use `issue create` to record follow-up work you found but were not asked to do.
## Start a new task
### Modify an existing file
1. Resolve an owned or joined repository with `repo list`, or a public repository with
`uvw repo view <owner>/<slug>`.
2. Find the Resource Node. Prefer `space find`; use `space browse` when tree context matters.
3. If multiple candidates match, compare `path`, `spaceId`, `nodeId`, `resourceId`, and Unit type. Ask the user
when the target remains ambiguous; never pick one by name alone.
4. Create a new pull request (Worktree), then stage the exact `resourceId`.
5. Read the returned `id` and `number` (the `--worktree` value is the `id`), then run `unit list` to confirm the staged Unit.
For a Personal Space file, use a new user-scoped Worktree:
```bash
uvw space find <document-name> --space <username>/personal --unit-type doc --json
uvw pr create -R <username>/personal -t <task-name> --json
uvw unit add \
--worktree <new-worktree-id> --resource <resource-id> --json
uvw unit list --worktree <new-worktree-id> --json
```
For a Team Space file, choose scope deliberately:
- Use `-R <username>/personal` for a private Agent task.
- Use `-R <owner>/<slug>` of the Team Space when the task itself belongs to that Team Space.
Add `--visibility space` only when Space members should see the Worktree.
After creating the Worktree, add the Resource with
`unit add --worktree <new-worktree-id> --resource <resource-id>`. Use the returned `unitId` for
all subsequent content commands; do not continue with the Node or Resource ID.
### Create a new file
Create a new Worktree first, then create or import one Worktree-local Unit:
```bash
uvw pr create -R <owner>/<slug> -t <task-name> --json
uvw unit create \
--worktree <new-worktree-id> --space <team-space-id> \
--type sheet --name <file-name> [--parent <node-id>] [--idempotency-key <key>] --json
```
Use `unit create` for an empty Unit. Use `compile-markdown --apply` for a generated Modern Doc
without creating a placeholder; load the Doc Skill first. Use `import --file` when an office file
supplies the initial content. Do not add an unrelated Unit to an existing task Worktree.
`unit create`, `import`, `compile-markdown --apply`, and `compile-typst --apply` allocate all three
identities on the server.
They accept `--idempotency-key <key>`. Normally omit it and let the CLI generate one. If a final
`workspace-result-unknown` diagnostic returns a key, reuse that exact key only to retry the same
logical operation; use a new or omitted key for an intentional second copy.
## Continue same-task rework
Use only the already-known Worktree:
```bash
uvw pr view <n|worktree-id> -R <owner>/<slug> --json
uvw unit list --worktree <worktree-id> --json
```
If it is `ready`, reopen it before editing:
```bash
uvw pr ready <n> -R <owner>/<slug> --undo --json
```
If it is `merged` or `discarded`, start a new Worktree and stage the current Space file again.
## Edit one Unit
Before writing Facade code, load the matching versioned Skill:
- Doc: `uvw skills get doc` (Modern Docs use `compile-markdown`; export selected current native
blocks with `export-markdown` before partial updates)
- Sheet: `uvw skills get sheet`
- Slide: `uvw skills get slide`
- Base: `uvw skills get base`
- Board: `uvw skills get board`
For cross-Unit composition, also load the matching Topic Skill after the Host and Source Skills:
- Embed: `uvw skills get embed`
- Cross-Unit formula in a Sheet cell or formula-driven Shape:
`uvw skills get cross-unit-formula`
- Chart backed by another Unit's Sheet or Base data:
`uvw skills get embed` (see "Referencing another Unit's data from a Chart")
Both Topic Skills persist the stable Source `unitId` in Host metadata and load Source data on demand;
they do not resolve identity from a display name or require staging a read-only Source into the task
Worktree.
Every content command requires the full remote address:
```bash
uvw execute \
--worktree <worktree-id> --unit <unit-id> -e '…' --json
uvw inspect range A1:C9 \
--worksheet name:<sheet-name> \
--worktree <worktree-id> --unit <unit-id> --json
```
There is no implicit Unit and no separate save command. `execute` commits captured mutations as one
revision; read-only code creates no revision. `inspect` is always read-only.
### Embedded image commit behavior
Use the public Facade with the original image source. The system automatically converts supported
BASE64 images to Workspace FileIds and stores their bytes separately, which keeps collaboration
snapshots smaller and improves loading performance; browser clients load those images automatically.
No manual image upload, format conversion, or mutation-storage handling is needed. This applies to
`execute`; Docs created by `compile-markdown`, `compile-typst` or `import` keep their images inline, so
readback returns BASE64 data URIs that already contain the bytes.
When Facade readback returns a UUID and the original asset bytes are needed, download them through
the managed CLI path:
```bash
uvw asset download <output> --id <uuid> --worktree <worktree-id>
```
### Facade API lookup
- When no relevant class or API symbol is known, use
`uvw api find <query...>` with API-name keywords or identifier fragments.
- When a class is known, use `uvw api show <Class>` to inspect its supported APIs.
- When a type or exact `Class.member` symbol is known, use
`uvw api show <symbol>` for its authoritative signature, documentation,
referenced types, and examples.
View on GitHub