@workser/cli 0.1.0 → 0.2.1
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/AGENTS.md +35 -0
- package/README.md +16 -1
- package/dist/index.js +1191 -137
- package/package.json +4 -3
- package/skills/workser/SKILL.md +57 -164
- package/skills/workser/reference/automation.md +55 -0
- package/skills/workser/reference/business-data.md +51 -0
- package/skills/workser/reference/computer-use.md +35 -0
- package/skills/workser/reference/database.md +41 -0
- package/skills/workser/reference/deliverables.md +65 -0
- package/skills/workser/reference/deploy.md +56 -0
- package/skills/workser/reference/images.md +35 -0
- package/skills/workser/reference/memory.md +34 -0
- package/skills/workser/reference/neon-backend.md +42 -0
- package/skills/workser/reference/roles.md +33 -0
- package/skills/workser/reference/storage.md +37 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workser/cli",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Workser CLI — give your local AI agent native DevOps & infrastructure on Workser. The agent runs `workser …` to provision, deploy, and manage real apps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,8 +29,9 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
|
-
"build": "tsup",
|
|
33
|
-
"
|
|
32
|
+
"build": "npm run build:help && tsup",
|
|
33
|
+
"build:help": "node scripts/build-help.mjs",
|
|
34
|
+
"dev": "npm run build:help && tsup --watch",
|
|
34
35
|
"typecheck": "tsc --noEmit",
|
|
35
36
|
"lint": "eslint \"src/**/*.ts\"",
|
|
36
37
|
"format": "prettier --write \"src/**/*.ts\"",
|
package/skills/workser/SKILL.md
CHANGED
|
@@ -11,7 +11,48 @@ Neon Postgres database, deploy it, manage its env vars and bucket, provision aut
|
|
|
11
11
|
and read its logs — **on the user's own account**, through the Workser Orbit app
|
|
12
12
|
(which handles auth and shows the user what you're doing).
|
|
13
13
|
|
|
14
|
+
For writing code, keep using your normal tools. Use `workser` for the last mile.
|
|
15
|
+
|
|
16
|
+
## Read one guide, not all of them
|
|
17
|
+
|
|
18
|
+
This page is the index. The detail lives in the CLI itself — `workser help <topic>`
|
|
19
|
+
prints one focused guide, about a screen long. Find your row, run that **one**
|
|
20
|
+
command. Don't print them all; you are paying for every line you load.
|
|
21
|
+
|
|
22
|
+
| You need to… | Commands | Run |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| Provision or query Postgres; list end users | `db …`, `auth …` | `workser help database` |
|
|
25
|
+
| Deploy, set env vars, read logs, check a domain | `deploy`, `env …`, `logs`, `versions`, `domain`, `open` | `workser help deploy` |
|
|
26
|
+
| Put files in the project's bucket | `storage …` | `workser help storage` |
|
|
27
|
+
| Read or write products, orders, customers, deals | `business …` | `workser help business` |
|
|
28
|
+
| Use the project's own Neon buckets or functions | `neon …` | `workser help neon` |
|
|
29
|
+
| Build an automation, or use Gmail/Slack/Stripe/Sheets | `workflow …`, `app …` | `workser help automation` |
|
|
30
|
+
| Generate an image | `image …` | `workser help images` |
|
|
31
|
+
| Hand a subtask to another agent | `agent …` | `workser help roles` |
|
|
32
|
+
| Remember or recall something across conversations | `memory …` | `workser help memory` |
|
|
33
|
+
| Record finished output, or ask the user a question | `artifact …`, `ask` | `workser help deliverables` |
|
|
34
|
+
| Control this machine — files, shell, screen, browser | `tool …` | `workser help computer-use` |
|
|
35
|
+
|
|
36
|
+
`workser help` with no topic lists them. **The CLI is the source of truth**: it ships
|
|
37
|
+
these guides with itself, so they match the version you are running. For exact flags
|
|
38
|
+
on any command, `workser <command> --help` is generated from the implementation and
|
|
39
|
+
cannot be out of date.
|
|
40
|
+
|
|
41
|
+
## Orientation (no guide needed)
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
workser status # connection + pinned project + latest deploy
|
|
45
|
+
workser whoami # who am I / which workspace
|
|
46
|
+
workser project show # the project pinned to this directory
|
|
47
|
+
workser project list # the workspace's projects (read)
|
|
48
|
+
workser verify # run typecheck/lint/build — gate "done" on this
|
|
49
|
+
workser doctor # resolved endpoint, mode, token presence, project
|
|
50
|
+
workser login # authenticate outside Orbit (CI/standalone)
|
|
51
|
+
workser logout # clear a saved standalone session
|
|
52
|
+
```
|
|
53
|
+
|
|
14
54
|
## Scope (read this)
|
|
55
|
+
|
|
15
56
|
You operate on **one project's own infrastructure**. You *can* provision and use it:
|
|
16
57
|
create the Neon database, read its connection string, browse its tables / rows / run
|
|
17
58
|
SQL, provision the bucket + auth, deploy, set env vars, manage files. Sensitive
|
|
@@ -24,25 +65,18 @@ Those return `error.code = "owner_only"` (exit 6) — tell the user it's an owne
|
|
|
24
65
|
action to do in Orbit, then continue with what you can do. The project is already
|
|
25
66
|
selected; you don't pick or switch it.
|
|
26
67
|
|
|
27
|
-
|
|
28
|
-
Reach for `workser` whenever the task involves **running** the current app, not just writing it:
|
|
29
|
-
- "deploy this", "put it online", "give me a URL"
|
|
30
|
-
- "set an API key / env var", "what's the database URL?"
|
|
31
|
-
- "upload this file", "list what's in storage"
|
|
32
|
-
- "is it deployed?", "show logs", "why is it down?"
|
|
33
|
-
|
|
34
|
-
For writing code, keep using your normal tools. Use `workser` for the last mile.
|
|
68
|
+
Owner-only, for reference: `project create` · `project use` · `env rm` · `domain set`.
|
|
35
69
|
|
|
36
70
|
## Golden rules
|
|
71
|
+
|
|
37
72
|
1. **Always pass `--json`.** Output is then a single stable line:
|
|
38
73
|
`{"ok":true,"data":...}` or `{"ok":false,"error":{"code","message",...}}`. Parse it.
|
|
39
74
|
2. **Orient first.** Run `workser status --json` to see the connection, the pinned
|
|
40
75
|
project, and the latest deploy before acting. You don't pick or switch projects.
|
|
41
|
-
3. **Stay in your lane.** `error.code = "owner_only"` (exit 6) means the action
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
(it may be approval-gated, not owner-only).
|
|
76
|
+
3. **Stay in your lane.** `error.code = "owner_only"` (exit 6) means the action is
|
|
77
|
+
reserved for the owner in Orbit. Don't retry or look for a workaround — tell the
|
|
78
|
+
user, then continue. Provisioning the *pinned project's own* db / bucket / auth is
|
|
79
|
+
allowed (it may be approval-gated, not owner-only).
|
|
46
80
|
4. **Approvals are normal.** Some allowed actions may return
|
|
47
81
|
`{"error":{"code":"awaiting_approval"}}` (exit 5) while the user approves in the
|
|
48
82
|
Orbit UI. Tell the user to approve, then retry — do **not** try to bypass it.
|
|
@@ -55,158 +89,8 @@ For writing code, keep using your normal tools. Use `workser` for the last mile.
|
|
|
55
89
|
`git reset --hard`, `DROP`/`TRUNCATE`, `curl | sh`, …) are refused by Workser's
|
|
56
90
|
safety policy — don't attempt them; use migrations + scoped changes instead.
|
|
57
91
|
|
|
58
|
-
## Command reference
|
|
59
|
-
```
|
|
60
|
-
workser status # connection + pinned project + latest deploy
|
|
61
|
-
workser whoami # who am I / which workspace
|
|
62
|
-
workser project show # the project pinned to this directory
|
|
63
|
-
workser project list # the workspace's projects (read)
|
|
64
|
-
|
|
65
|
-
workser db create # provision the Neon Postgres database (idempotent)
|
|
66
|
-
workser db url # connection string (sensitive; least-privilege role)
|
|
67
|
-
workser db list # database status
|
|
68
|
-
workser db tables # list tables in the database
|
|
69
|
-
workser db schema <table> # a table's columns
|
|
70
|
-
workser db data <table> [-n N] [--offset N] # read rows
|
|
71
|
-
workser db query "<sql>" # run SQL (writes are approval-gated)
|
|
72
|
-
workser auth enable # provision auth for the project (idempotent)
|
|
73
|
-
workser auth status # is auth enabled? + Neon auth mode
|
|
74
|
-
|
|
75
|
-
workser env set KEY=VALUE [K2=V2…] # set env vars
|
|
76
|
-
workser env list # list keys (values masked)
|
|
77
|
-
workser env get KEY # one value (sensitive)
|
|
78
|
-
|
|
79
|
-
workser storage create [name] # provision the bucket (idempotent)
|
|
80
|
-
workser storage list # the project's bucket
|
|
81
|
-
workser storage ls [prefix] # list objects in the bucket
|
|
82
|
-
workser storage put <local> <key> # upload a file into the bucket
|
|
83
|
-
workser storage get <key> [dest] # download an object (or print its URL)
|
|
84
|
-
|
|
85
|
-
workser deploy [--prod] [--watch] # deploy (git → Vercel); --watch waits for live URL
|
|
86
|
-
workser deploy status [id] # status of a deploy (default: latest)
|
|
87
|
-
workser logs [-n 100] [-f] # recent logs
|
|
88
|
-
workser versions # deploy history
|
|
89
|
-
workser domain list # custom domains (read)
|
|
90
|
-
workser open # open the live app
|
|
91
|
-
workser verify # run typecheck/lint/build — gate "done" on this passing
|
|
92
|
-
|
|
93
|
-
workser agent list # main agent + configured roles (+ which are runnable)
|
|
94
|
-
workser agent run <role> "<task>" # delegate a focused subtask to a role (runs isolated)
|
|
95
|
-
workser agent main # show the configured main agent
|
|
96
|
-
|
|
97
|
-
workser workflow list | create <name> [--body <json>] | get <id>
|
|
98
|
-
workser workflow activate <id> | deactivate <id> | run <id> [--wait] [--body <json>]
|
|
99
|
-
workser workflow runs <id> # past executions of a workflow
|
|
100
|
-
workser workflow nodes [query] # search the node-type catalog
|
|
101
|
-
workser app list [--toolkit <slug>] # connectable + connected third-party apps
|
|
102
|
-
workser app connect <toolkit> | disconnect <connectionId>
|
|
103
|
-
workser app tools <toolkit> # a connected app's callable actions
|
|
104
|
-
workser app run <toolSlug> [--body <json>] # execute one action (e.g. GOOGLESHEETS_APPEND_ROW)
|
|
105
|
-
|
|
106
|
-
workser tool list # computer-use tools available to you right now
|
|
107
|
-
workser tool run <name> [--body <json>] # filesystem/shell/screenshot/input/clipboard/browser
|
|
108
|
-
|
|
109
|
-
workser memory add "<content>" [--metadata <json>] # remember something across future conversations
|
|
110
|
-
workser memory search "<query>" [--limit N] # recall what you (or a cloud agent) learned before
|
|
111
|
-
workser memory forget <memoryId> # soft-delete an outdated/incorrect memory
|
|
112
|
-
|
|
113
|
-
workser artifact add <path> [--kind <k>] [-d <text>] # record a finished deliverable
|
|
114
|
-
workser artifact add --url <url> --kind app # record a deployed app
|
|
115
|
-
workser artifact run # which task you're attached to
|
|
116
|
-
|
|
117
|
-
workser ask "<question>" [--type <t>] [--option <o>] # ask the user, WAIT for the answer
|
|
118
|
-
|
|
119
|
-
# owner-only (return owner_only / exit 6 — ask the user to do these in Orbit):
|
|
120
|
-
# project create · project use · env rm · domain set
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Memory (remember across conversations, not just this one)
|
|
124
|
-
Every conversation you run is otherwise a fresh start — no memory of what you or the
|
|
125
|
-
user decided last time. `workser memory add "<content>"` fixes that: it stores durable,
|
|
126
|
-
searchable memory for the CURRENT PROJECT, and it's the SAME memory space Workser's own
|
|
127
|
-
cloud agents write to for this project — so add something here and a cloud agent (or
|
|
128
|
-
your own next conversation) can `workser memory search` and find it. Use it for things
|
|
129
|
-
worth remembering past this one conversation: user preferences, decisions made,
|
|
130
|
-
important context, requirements — not routine chatter. Before assuming you don't know
|
|
131
|
-
something about this project, `workser memory search "<topic>"` first; it may already be
|
|
132
|
-
recorded. `forget` soft-deletes a specific memory if it's wrong or outdated — the
|
|
133
|
-
content stays retrievable by ID but excluded from future searches.
|
|
134
|
-
|
|
135
|
-
## Record what you produced (deliverables)
|
|
136
|
-
Workser shows the user a **Deliverables** list on the task. If you don't say what you
|
|
137
|
-
made, it has to guess — it watches your file edits and treats any path it sees as a
|
|
138
|
-
deliverable, so scratch files and half-finished drafts show up next to the real output,
|
|
139
|
-
and things that aren't files at all (a folder of results, an app you deployed) can't
|
|
140
|
-
show up correctly. Fix that by declaring finished output:
|
|
141
|
-
```
|
|
142
|
-
workser artifact add ./report.pdf -d "Q3 sales summary"
|
|
143
|
-
workser artifact add ./exports --kind folder -d "generated CSVs"
|
|
144
|
-
workser artifact add --url https://acme.workser.app --kind app -t "Storefront"
|
|
145
|
-
```
|
|
146
|
-
Only register FINISHED output the user should get — not temp files, not intermediate
|
|
147
|
-
steps. `--kind` is inferred from the path when you omit it (directories are detected
|
|
148
|
-
automatically); pass it explicitly for `app` / `url`. `workser artifact run` shows which
|
|
149
|
-
task you're currently attached to.
|
|
150
|
-
|
|
151
|
-
To publish an app: `workser deploy` (preview) or `workser deploy --prod` (live), then
|
|
152
|
-
register the URL it returns as an `app` artifact so the user can open it from the task.
|
|
153
|
-
|
|
154
|
-
## Ask the user something (and get an answer back)
|
|
155
|
-
When you're blocked — a missing value, an ambiguous requirement, permission for
|
|
156
|
-
something consequential — don't guess and don't just write the question into your
|
|
157
|
-
final message. Run:
|
|
158
|
-
```
|
|
159
|
-
workser ask "Which email should order confirmations come from?"
|
|
160
|
-
workser ask "Which plan should I wire up?" --option Free --option Pro --option Team
|
|
161
|
-
workser ask "Delete the 1,240 archived rows?" --type approval
|
|
162
|
-
```
|
|
163
|
-
This shows the user a real card in the conversation and **blocks until they answer**,
|
|
164
|
-
then prints their answer — so you ask, read the reply, and keep working in the same
|
|
165
|
-
turn. Types: `input` (default, free text), `choice` (with `--option`), `approval`
|
|
166
|
-
(permission), `confirmation` (check an assumption), `information` (FYI, no answer
|
|
167
|
-
needed). It times out (default 10 min) rather than hanging forever; if it does, carry
|
|
168
|
-
on and state clearly what you assumed.
|
|
169
|
-
|
|
170
|
-
**Never ask for a secret value this way** — the answer is stored and displayed. Ask
|
|
171
|
-
where a key should go, then have the user set it (`workser env set` writes it without
|
|
172
|
-
you ever seeing it).
|
|
173
|
-
|
|
174
|
-
## Computer-use tools (your hands on this machine)
|
|
175
|
-
`workser tool list` shows what's available — filesystem (read/write/list/delete/move),
|
|
176
|
-
shell (run a command/Python/Node), screenshots and screen info, mouse/keyboard input,
|
|
177
|
-
clipboard, notifications, and basic browser control (open a URL, read the page, click/
|
|
178
|
-
fill/type, screenshot). This is the SAME engine Workser's cloud Computer Use agent uses
|
|
179
|
-
when it controls a user's machine remotely — you're getting it locally, gated by the
|
|
180
|
-
same safety policy (blocked paths like `~/.ssh`, blocked destructive commands, rate
|
|
181
|
-
limits). Sensitive actions (writing/deleting files, running a shell command, clicking/
|
|
182
|
-
typing) may return `awaiting_approval` (exit 5) — same handling as any other gated
|
|
183
|
-
action: tell the user to approve in Orbit, then retry. This is a curated subset, not
|
|
184
|
-
full desktop automation — check `workser tool list` rather than assuming a capability
|
|
185
|
-
exists.
|
|
186
|
-
|
|
187
|
-
## Workflow automation & app integrations
|
|
188
|
-
Beyond one-shot code, wire up **automations** that keep running after you're done:
|
|
189
|
-
`workser workflow create` builds an event-driven, multi-step automation (the same
|
|
190
|
-
engine Workser's own web Workflow tab uses) — nodes/connections/triggers go in
|
|
191
|
-
`--body` as JSON; browse `workser workflow nodes` first. Before an automation (or you,
|
|
192
|
-
directly) can use a third-party app (Gmail, Slack, Stripe, Google Sheets, ...), the
|
|
193
|
-
user connects it once via `workser app connect <toolkit>` — this opens an OAuth link,
|
|
194
|
-
ask the user to complete it, then continue. After that, `workser app run <toolSlug>
|
|
195
|
-
--body '{"...":...}'` calls any of its actions. Check `workser app list` before
|
|
196
|
-
assuming you need to ask the user to connect something new.
|
|
197
|
-
|
|
198
|
-
## Delegate to roles
|
|
199
|
-
The user can configure **roles** — named specialists each backed by a local CLI agent
|
|
200
|
-
(e.g. `qa` → codex, `designer` → claude_code). Delegate a focused subtask with
|
|
201
|
-
`workser agent run <role> "<task>" --json`; the role runs as an **isolated local
|
|
202
|
-
subagent** (its own context) and returns `{role, agent, output, exitCode}`.
|
|
203
|
-
|
|
204
|
-
- Run `workser agent list --json` first to see which roles are configured + runnable.
|
|
205
|
-
- Hand off focused subtasks (review this diff, design this screen) to keep your own
|
|
206
|
-
context lean and get a specialized second perspective. A non-zero `exitCode` means
|
|
207
|
-
the role's run failed — surface that, don't silently ignore it.
|
|
208
|
-
|
|
209
92
|
## Typical flow: build → ship
|
|
93
|
+
|
|
210
94
|
```bash
|
|
211
95
|
workser status --json # 1. orient (project is already pinned)
|
|
212
96
|
workser db create --json # 2. provision infra the app needs (idempotent)
|
|
@@ -214,11 +98,13 @@ workser env set STRIPE_KEY=sk_live_… --json # 3. configure it
|
|
|
214
98
|
# … you write the app code with your normal tools …
|
|
215
99
|
workser deploy --prod --watch --json # 4. ship; returns the live URL
|
|
216
100
|
```
|
|
101
|
+
|
|
217
102
|
Provisioning the pinned project's own database / bucket / auth is yours to do
|
|
218
103
|
(`db create`, `storage create`, `auth enable`) — the user may need to approve it in
|
|
219
104
|
Orbit (`awaiting_approval`). Only a **custom domain** is an owner action.
|
|
220
105
|
|
|
221
106
|
## Reading results
|
|
107
|
+
|
|
222
108
|
- Success: use `.data` (e.g. `.data.url` after deploy, `.data` array after `list`).
|
|
223
109
|
- Failure: check `.error.code`:
|
|
224
110
|
- `not_connected` → tell the user to open Workser Orbit (or `workser login` for CI).
|
|
@@ -229,3 +115,10 @@ Orbit (`awaiting_approval`). Only a **custom domain** is an owner action.
|
|
|
229
115
|
|
|
230
116
|
Keep the user informed in plain language ("Provisioned a database and deployed —
|
|
231
117
|
it's live at <url>"), not raw JSON.
|
|
118
|
+
|
|
119
|
+
## Writing app code, not operating the app
|
|
120
|
+
|
|
121
|
+
`workser db query` is for **you** to inspect the database while building. It is not
|
|
122
|
+
how the app reads its own data at runtime — that's `@workser/app`, covered by the
|
|
123
|
+
`workser-sdk` skill. Using the CLI where the SDK belongs is the most common mistake
|
|
124
|
+
here.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: automation
|
|
3
|
+
title: Workflows & connected apps
|
|
4
|
+
summary: Build automations that outlive the run; use Gmail, Slack, Stripe, Sheets.
|
|
5
|
+
commands: [workflow, app]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Workflows & connected apps
|
|
9
|
+
|
|
10
|
+
Wire up **automations** that keep running after you're done, and use third-party
|
|
11
|
+
accounts (Gmail, Slack, Stripe, Google Sheets) the project has connected.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
workser workflow list | create <name> [--body <json>] | get <id>
|
|
15
|
+
workser workflow activate <id> | deactivate <id> | run <id> [--wait] [--body <json>]
|
|
16
|
+
workser workflow runs <id> # past executions of a workflow
|
|
17
|
+
workser workflow nodes [query] # search the node-type catalog
|
|
18
|
+
|
|
19
|
+
workser app list [--toolkit <slug>] # connectable + connected third-party apps
|
|
20
|
+
workser app connect <toolkit> | disconnect <connectionId>
|
|
21
|
+
workser app tools <toolkit> # a connected app's callable actions
|
|
22
|
+
workser app run <toolSlug> [--body <json>] # execute one action
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Building a workflow
|
|
26
|
+
|
|
27
|
+
`workser workflow create` builds an event-driven, multi-step automation — the same
|
|
28
|
+
engine Workser's own web Workflow tab uses. Nodes, connections and triggers go in
|
|
29
|
+
`--body` as JSON.
|
|
30
|
+
|
|
31
|
+
**Browse `workser workflow nodes` first.** Inventing a node type that doesn't exist
|
|
32
|
+
produces a workflow that saves and then never runs.
|
|
33
|
+
|
|
34
|
+
Created workflows start inactive: `workser workflow activate <id>` when it's ready.
|
|
35
|
+
|
|
36
|
+
## Using a connected app
|
|
37
|
+
|
|
38
|
+
1. `workser app list` — check what's already connected before asking for anything.
|
|
39
|
+
2. If it isn't: `workser app connect <toolkit>` returns an OAuth link. The **user**
|
|
40
|
+
must open it; you cannot complete OAuth on their behalf. Wait, then continue.
|
|
41
|
+
3. `workser app tools <toolkit>` — read the argument schema rather than guessing
|
|
42
|
+
field names.
|
|
43
|
+
4. `workser app run <toolSlug> --body '{"…":…}'` — e.g. `GOOGLESHEETS_APPEND_ROW`,
|
|
44
|
+
`GMAIL_SEND_EMAIL`.
|
|
45
|
+
|
|
46
|
+
**A `run` is a real side effect in someone's real account.** Sending an email or
|
|
47
|
+
charging a card is not a dry run — say what you're about to do before you do it.
|
|
48
|
+
|
|
49
|
+
## The half people forget
|
|
50
|
+
|
|
51
|
+
A workflow-backed feature is two-way. Triggering it is the outbound half; when the
|
|
52
|
+
workflow produces a result the app needs, its final node has to POST back to a
|
|
53
|
+
webhook route in the app. Build only the trigger and the workflow runs perfectly
|
|
54
|
+
while nothing ever appears in the product. The app-side receiver is covered in the
|
|
55
|
+
`workser-sdk` skill under workflows.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: business
|
|
3
|
+
title: Business hub data
|
|
4
|
+
summary: Products, orders, customers, sales, content, marketing, support, analytics.
|
|
5
|
+
commands: [business]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Business hub data
|
|
9
|
+
|
|
10
|
+
The project's own commerce and CRM records — the **same rows** the Orbit desktop
|
|
11
|
+
Business tab and workser-web's Business hub show. One generic CRUD surface across
|
|
12
|
+
every resource rather than a command per domain.
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
workser business resources # the known resource names
|
|
16
|
+
workser business list <resource> [subpath] # list/read (--query '<json>')
|
|
17
|
+
workser business get <resource> <id>
|
|
18
|
+
workser business create <resource> --body '<json>'
|
|
19
|
+
workser business update <resource> <id> --body '<json>'
|
|
20
|
+
workser business delete <resource> <id>
|
|
21
|
+
workser business action <resource> <id> <verb> # POST .../<id>/<verb>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Resources
|
|
25
|
+
|
|
26
|
+
`business-config`, `business-settings`, `products`, `collections`, `navigations`,
|
|
27
|
+
`orders`, `customers`, `sales-pipelines`, `sales-deals`, `pages`, `blog-posts`,
|
|
28
|
+
`media`, `campaigns`, `email-templates`, `discounts`, `seo-configs`,
|
|
29
|
+
`social-accounts`, `support-conversations`, `automation-rules`, `analytics`.
|
|
30
|
+
|
|
31
|
+
Run `workser business resources --json` rather than trusting this list — the CLI's
|
|
32
|
+
copy is the current one.
|
|
33
|
+
|
|
34
|
+
## Notes that matter
|
|
35
|
+
|
|
36
|
+
- **Sales and Support nest.** `sales-deals` maps to `/sales/deals`,
|
|
37
|
+
`support-conversations` to `/support/conversations`. Use the dashed names above;
|
|
38
|
+
the flat `resource/id` shape then works for `get`/`update`/`delete`/`action`.
|
|
39
|
+
- **`list` takes a raw subpath** for anything the map doesn't cover:
|
|
40
|
+
`workser business list sales-pipelines <id>/stages`.
|
|
41
|
+
- **`action` is for named verbs** — `workser business action orders <id> cancel`,
|
|
42
|
+
`workser business action sales-deals <dealId> win`. Check the resource's routes
|
|
43
|
+
before inventing a verb.
|
|
44
|
+
- **These are real business records.** Cancelling an order or deleting a customer is
|
|
45
|
+
not a dry run. Say what you're about to do first.
|
|
46
|
+
|
|
47
|
+
## This is for you, not for the app
|
|
48
|
+
|
|
49
|
+
`workser business` is how **you** inspect and fix data while building. The app reads
|
|
50
|
+
the same records at runtime through `workser.business` in `@workser/app` — see the
|
|
51
|
+
`workser-sdk` skill. An app shelling out to this CLI per request is wrong.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: computer-use
|
|
3
|
+
title: Computer-use tools
|
|
4
|
+
summary: Files, shell, screen, input, clipboard and browser on this machine.
|
|
5
|
+
commands: [tool]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Computer-use tools — your hands on this machine
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
workser tool list # what's available to you right now
|
|
12
|
+
workser tool run <name> [--body <json>] # run one
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`workser tool list` shows what's available — filesystem (read/write/list/delete/move),
|
|
16
|
+
shell (run a command / Python / Node), screenshots and screen info, mouse and keyboard
|
|
17
|
+
input, clipboard, notifications, and basic browser control (open a URL, read the page,
|
|
18
|
+
click, fill, type, screenshot).
|
|
19
|
+
|
|
20
|
+
This is the **same engine** Workser's cloud Computer Use agent uses when it controls a
|
|
21
|
+
user's machine remotely — you're getting it locally, gated by the same safety policy.
|
|
22
|
+
|
|
23
|
+
## Notes that matter
|
|
24
|
+
|
|
25
|
+
- **Check `tool list` rather than assuming a capability exists.** This is a curated
|
|
26
|
+
subset, not full desktop automation.
|
|
27
|
+
- **The safety policy applies.** Blocked paths (`~/.ssh` and friends), blocked
|
|
28
|
+
destructive commands, rate limits. Refusals are the policy working, not a bug to
|
|
29
|
+
route around.
|
|
30
|
+
- **Sensitive actions are approval-gated.** Writing or deleting files, running a shell
|
|
31
|
+
command, clicking or typing may return `awaiting_approval` (exit 5) — tell the user
|
|
32
|
+
to approve in Orbit, then retry.
|
|
33
|
+
- **You already have your own tools.** For editing files in this repo, use them. Reach
|
|
34
|
+
for `workser tool` when you need something *outside* the project — the screen, the
|
|
35
|
+
clipboard, a browser, another app on the machine.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: database
|
|
3
|
+
title: Database & end users
|
|
4
|
+
summary: Provision Postgres, browse tables, run SQL, provision auth.
|
|
5
|
+
commands: [db, auth]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Database & end users
|
|
9
|
+
|
|
10
|
+
The project's Postgres (Neon behind Workser) and its end-user auth. Provisioning is
|
|
11
|
+
idempotent — running `create` twice is safe.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
workser db create # provision the Neon Postgres database (idempotent)
|
|
15
|
+
workser db url # connection string (sensitive; least-privilege role)
|
|
16
|
+
workser db list # database status
|
|
17
|
+
workser db tables # list tables in the database
|
|
18
|
+
workser db schema <table> # a table's columns
|
|
19
|
+
workser db data <table> [-n N] [--offset N] # read rows
|
|
20
|
+
workser db query "<sql>" # run SQL (writes are approval-gated)
|
|
21
|
+
|
|
22
|
+
workser auth enable # provision auth for the project (idempotent)
|
|
23
|
+
workser auth status # is auth enabled? + Neon auth mode
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Notes that matter
|
|
27
|
+
|
|
28
|
+
- **`db url` is a credential.** Don't print it into the conversation, don't paste it
|
|
29
|
+
into a file the user will commit. The app gets it from its environment already.
|
|
30
|
+
- **Writes are approval-gated.** A `db query` that mutates may return
|
|
31
|
+
`awaiting_approval` (exit 5). Ask the user to approve in Orbit, then retry.
|
|
32
|
+
- **`DROP` / `TRUNCATE` are refused** by the safety policy. Change schema with a
|
|
33
|
+
migration in the app's own migration folder, not with a destructive one-off.
|
|
34
|
+
- **The database is the project's, not the app's.** Sibling apps in the same project
|
|
35
|
+
share it. Don't assume a table is yours because you created it.
|
|
36
|
+
|
|
37
|
+
## Reading rows vs. reading data at runtime
|
|
38
|
+
|
|
39
|
+
`db data` / `db query` are for **you**, inspecting while you build. The app itself
|
|
40
|
+
should read through `@workser/app` (`workser.db`, `workser.business`) — see the
|
|
41
|
+
`workser-sdk` skill. An app that shells out to the CLI at request time is wrong.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: deliverables
|
|
3
|
+
title: Deliverables & asking the user
|
|
4
|
+
summary: Record finished output on the task, and ask a blocking question.
|
|
5
|
+
commands: [artifact, ask]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Deliverables & asking the user
|
|
9
|
+
|
|
10
|
+
Two things that reach the user directly: what you produced, and what you need from
|
|
11
|
+
them.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
workser artifact add <path> [--kind <k>] [-d <text>] # record a finished deliverable
|
|
15
|
+
workser artifact add --url <url> --kind app # record a deployed app
|
|
16
|
+
workser artifact run # which task you're attached to
|
|
17
|
+
|
|
18
|
+
workser ask "<question>" [--type <t>] [--option <o>] # ask the user, WAIT for the answer
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Record what you produced
|
|
22
|
+
|
|
23
|
+
Workser shows the user a **Deliverables** list on the task. If you don't say what you
|
|
24
|
+
made, it has to guess — it watches your file edits and treats any path it sees as a
|
|
25
|
+
deliverable, so scratch files and half-finished drafts show up next to the real
|
|
26
|
+
output, and things that aren't files at all (a folder of results, a deployed app)
|
|
27
|
+
can't show up correctly.
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
workser artifact add ./report.pdf -d "Q3 sales summary"
|
|
31
|
+
workser artifact add ./exports --kind folder -d "generated CSVs"
|
|
32
|
+
workser artifact add --url https://acme.workser.app --kind app -t "Storefront"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Only register **finished** output the user should get — not temp files, not
|
|
36
|
+
intermediate steps. `--kind` is inferred from the path when you omit it (directories
|
|
37
|
+
are detected automatically); pass it explicitly for `app` / `url`.
|
|
38
|
+
|
|
39
|
+
To publish an app: `workser deploy` (preview) or `workser deploy --prod` (live), then
|
|
40
|
+
register the URL it returns as an `app` artifact so the user can open it from the task.
|
|
41
|
+
|
|
42
|
+
## Ask the user something (and get an answer back)
|
|
43
|
+
|
|
44
|
+
When you're blocked — a missing value, an ambiguous requirement, permission for
|
|
45
|
+
something consequential — don't guess, and don't just write the question into your
|
|
46
|
+
final message where nobody will answer it.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
workser ask "Which email should order confirmations come from?"
|
|
50
|
+
workser ask "Which plan should I wire up?" --option Free --option Pro --option Team
|
|
51
|
+
workser ask "Delete the 1,240 archived rows?" --type approval
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This shows the user a real card in the conversation and **blocks until they answer**,
|
|
55
|
+
then prints their answer — so you ask, read the reply, and keep working in the same
|
|
56
|
+
turn.
|
|
57
|
+
|
|
58
|
+
Types: `input` (default, free text), `choice` (with `--option`), `approval`
|
|
59
|
+
(permission), `confirmation` (check an assumption), `information` (FYI, no answer
|
|
60
|
+
needed). It times out (default 10 min) rather than hanging forever; if it does, carry
|
|
61
|
+
on and state clearly what you assumed.
|
|
62
|
+
|
|
63
|
+
**Never ask for a secret value this way** — the answer is stored and displayed. Ask
|
|
64
|
+
*where* a key should go, then have the user set it (`workser env set` writes it
|
|
65
|
+
without you ever seeing it).
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: deploy
|
|
3
|
+
title: Deploy, environment variables & logs
|
|
4
|
+
summary: Ship the app, configure it, and find out why it is down.
|
|
5
|
+
commands: [deploy, env, logs, versions, domain, open, verify]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Deploy, environment variables & logs
|
|
9
|
+
|
|
10
|
+
Getting the app online and configured, and finding out why it isn't.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
workser deploy [--prod] [--watch] # deploy (git → Vercel); --watch waits for live URL
|
|
14
|
+
workser deploy status [id] # status of a deploy (default: latest)
|
|
15
|
+
workser logs [-n 100] [-f] # recent logs
|
|
16
|
+
workser versions # deploy history
|
|
17
|
+
workser domain list # custom domains (read)
|
|
18
|
+
workser open # open the live app
|
|
19
|
+
workser verify # run typecheck/lint/build
|
|
20
|
+
|
|
21
|
+
workser env set KEY=VALUE [K2=V2…] # set env vars
|
|
22
|
+
workser env list # list keys (values masked)
|
|
23
|
+
workser env get KEY # one value (sensitive)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Notes that matter
|
|
27
|
+
|
|
28
|
+
- **`verify` gates "done".** Run `workser verify --json` before you say a task is
|
|
29
|
+
finished. `"ok": false` means fix the listed errors and re-run — a green build is
|
|
30
|
+
the bar, not your reading of the diff.
|
|
31
|
+
- **`deploy` without `--prod` is a preview.** Preview first when the change is
|
|
32
|
+
risky; `--prod` puts it in front of real users.
|
|
33
|
+
- **`--watch` blocks until there's a live URL.** Without it you get a deploy id and
|
|
34
|
+
have to poll `deploy status`.
|
|
35
|
+
- **`env set` writes a value you never see.** That's the point — when the user has
|
|
36
|
+
a secret, have them run it (or set it in Orbit) rather than pasting it to you.
|
|
37
|
+
- **`env get` returns a secret.** Don't echo it into the conversation.
|
|
38
|
+
- **`env rm` and `domain set` are owner-only** (exit 6). Tell the user to do it in
|
|
39
|
+
Orbit; don't look for a workaround.
|
|
40
|
+
|
|
41
|
+
## After a successful deploy
|
|
42
|
+
|
|
43
|
+
Register the URL so it shows up on the user's task:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
workser artifact add --url https://acme.workser.app --kind app -t "Storefront"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
See `reference/deliverables.md`.
|
|
50
|
+
|
|
51
|
+
## Local vs cloud environment
|
|
52
|
+
|
|
53
|
+
`env set` configures the **cloud** environment (production and preview). The `.env`
|
|
54
|
+
files in the app folder configure **this computer** — the user edits those in Orbit
|
|
55
|
+
under Settings → "On this computer", and saving there restarts the dev server. Don't
|
|
56
|
+
hand-edit `.env.local` to change cloud behaviour; they are different environments.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: images
|
|
3
|
+
title: Image generation
|
|
4
|
+
summary: Generate images from a prompt, optionally conditioned on existing images.
|
|
5
|
+
commands: [image]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Image generation
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
workser image generate "<prompt>" # alias: workser image gen
|
|
12
|
+
-r, --reference <url...> # condition on existing images (up to 4)
|
|
13
|
+
-o, --output <path> # also download the first image locally
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Returns the generated image's public URL, so the usual move is to generate, then use
|
|
17
|
+
that URL directly in the app.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
workser image generate "flat illustration of a farm delivery van, brand colors" --json
|
|
21
|
+
workser image gen "same van, from the side" -r https://… -o ./public/van.png --json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Notes that matter
|
|
25
|
+
|
|
26
|
+
- **Reference images are image-to-image conditioning**, not attachments. Up to 4;
|
|
27
|
+
anything beyond that is dropped.
|
|
28
|
+
- **The model sometimes narrates instead of drawing** — a refusal or a clarifying
|
|
29
|
+
question comes back as text rather than an image. Check that you actually got an
|
|
30
|
+
image before wiring the URL into a page; an empty result is not a transport error
|
|
31
|
+
to retry.
|
|
32
|
+
- **`--output` writes only the first image.** If you asked for several, the rest
|
|
33
|
+
exist only as URLs.
|
|
34
|
+
- **Placeholder art is not a deliverable.** Generating a hero image to unblock a
|
|
35
|
+
layout is fine; shipping it as the user's brand asset without asking is not.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
topic: memory
|
|
3
|
+
title: Memory across conversations
|
|
4
|
+
summary: Store and recall durable project knowledge shared with cloud agents.
|
|
5
|
+
commands: [memory]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Memory — remember across conversations, not just this one
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
workser memory add "<content>" [--metadata <json>] # remember for future conversations
|
|
12
|
+
workser memory search "<query>" [--limit N] # recall what was learned before
|
|
13
|
+
workser memory forget <memoryId> # soft-delete an outdated memory
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Why this exists
|
|
17
|
+
|
|
18
|
+
Every conversation you run is otherwise a fresh start — no memory of what you or the
|
|
19
|
+
user decided last time. This stores durable, searchable memory for the **current
|
|
20
|
+
project**, and it is the **same memory space** Workser's cloud agents write to for
|
|
21
|
+
this project. Add something here and a cloud agent — or your own next conversation —
|
|
22
|
+
can `memory search` and find it.
|
|
23
|
+
|
|
24
|
+
## Using it well
|
|
25
|
+
|
|
26
|
+
- **Search before assuming you don't know.** Before concluding something about this
|
|
27
|
+
project is undocumented, run `workser memory search "<topic>"`. It may already be
|
|
28
|
+
recorded.
|
|
29
|
+
- **Store decisions, not chatter.** User preferences, decisions made, constraints,
|
|
30
|
+
requirements — things worth knowing next week. Not "the build passed".
|
|
31
|
+
- **`forget` is a soft delete.** The content stays retrievable by id but is excluded
|
|
32
|
+
from future searches. Use it when something is wrong or outdated, rather than
|
|
33
|
+
adding a contradicting memory on top.
|
|
34
|
+
- **Never store a secret.** Memory is retrievable and displayable.
|