recess-cli 1.4.0 → 1.7.0
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/README.md +57 -26
- package/dist/api.js +1 -1
- package/dist/args.js +2 -0
- package/dist/auth.js +1 -1
- package/dist/cli.js +611 -70
- package/dist/safety.js +1 -1
- package/dist/setup.js +3 -5
- package/dist/skill-update.js +1 -1
- package/package.json +3 -3
- package/skill/recess-cli/SKILL.md +42 -484
- package/skill/recess-cli/agents/openai.yaml +2 -2
- package/skill/recess-cli/agents/version.json +4 -0
- package/skill/recess-cli/reference/billing.md +0 -146
- package/skill/recess-cli/reference/cancellation-credits.md +0 -53
- package/skill/recess-cli/reference/class-ops-reschedule.md +0 -41
- package/skill/recess-cli/reference/class-ops.md +0 -89
- package/skill/recess-cli/reference/goal-authoring.md +0 -274
- package/skill/recess-cli/reference/map-scores.md +0 -28
- package/skill/recess-cli/reference/onboarding.md +0 -79
- package/skill/recess-cli/reference/payout.md +0 -74
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Recess CLI
|
|
2
2
|
|
|
3
|
-
`recess-cli` is the typed, agent-friendly command layer for Recess staff
|
|
3
|
+
`recess-cli` is the typed, agent-friendly command layer for Recess operations. ADMIN accounts receive the full staff surface; GUARDIAN accounts with `access:ai` receive family-scoped class schedules, progress, goals, todos, memories, Rocky configuration, learning research, GoalTemplate, and goal-content commands. It uses the web-server OpenAPI document, authenticates through Recess SSO, emits stable JSON, and refuses live writes until the exact command is rerun with `--confirm` after human approval.
|
|
4
4
|
|
|
5
|
-
## Install (
|
|
5
|
+
## Install (no checkout needed)
|
|
6
6
|
|
|
7
7
|
Published to npm as [`recess-cli`](https://www.npmjs.com/package/recess-cli). On any machine with Node 20+:
|
|
8
8
|
|
|
@@ -25,7 +25,7 @@ pnpm --dir apps/admin-cli run client:generate
|
|
|
25
25
|
pnpm --dir apps/admin-cli run install-persistent
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
`install-persistent` copies a self-contained build (non-test `dist/` JS + the `openapi-fetch` runtime dep) to `~/.recess-cli/cli/` and points `~/.local/bin/recess` at it — the install keeps working after the checkout or worktree it was built from is deleted. Use it on any machine that operates on production. `install-local` instead symlinks `~/.local/bin/recess` straight to this checkout's `dist/index.js` so rebuilds are picked up live — use it only while actively developing the CLI, and expect the link to die with the worktree. Both targets install the
|
|
28
|
+
`install-persistent` copies a self-contained build (non-test `dist/` JS + the `openapi-fetch` runtime dep) to `~/.recess-cli/cli/` and points `~/.local/bin/recess` at it — the install keeps working after the checkout or worktree it was built from is deleted. Use it on any machine that operates on production. `install-local` instead symlinks `~/.local/bin/recess` straight to this checkout's `dist/index.js` so rebuilds are picked up live — use it only while actively developing the CLI, and expect the link to die with the worktree. Both targets install the small shared router at `${CODEX_HOME:-~/.codex}/skills/recess-cli` and `${CLAUDE_CONFIG_DIR:-~/.claude}/skills/recess-cli`. That public npm bundle contains only authentication, JSON, confirmation, and audience-routing guidance. Guardian learning skills and staff-only operational skills/gotchas are fetched after login from separate permission-checked catalogs; they are not shipped in the package.
|
|
29
29
|
|
|
30
30
|
## One-time SSO setup
|
|
31
31
|
|
|
@@ -40,7 +40,7 @@ Create an approved `OAuthClient` row in each Recess environment. This remains a
|
|
|
40
40
|
|
|
41
41
|
The production row ID (`c7e34138-18f9-45b1-a2fb-26a4e3a6d739`) is the CLI's built-in default, so production login needs no client-ID setup. `--client-id`, `RECESS_CLI_OAUTH_CLIENT_ID`, and a stored client ID remain overrides for local/staging clients. The web-server decodes the assertion audience, loads that exact `OAuthClient`, and requires both `approved` and `adminCliEnabled`; there is no separate server environment allowlist. Production redirect validation is exact, so a different callback port must also be explicitly registered.
|
|
42
42
|
|
|
43
|
-
The browser SSO assertion is exchanged once and discarded. The CLI stores a separate 12-hour signed Recess
|
|
43
|
+
The browser SSO assertion is exchanged once and discarded. The CLI stores a separate 12-hour signed Recess session at `~/.recess-cli/config.json` with mode `0600`. A guardian must hold the live `access:ai` permission; removing it immediately invalidates session checks. Guardian sessions cannot call `/admin` routes and every target is independently restricted to their family.
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
recess --json auth login
|
|
@@ -54,13 +54,20 @@ With `--json`, stdout contains only one JSON object.
|
|
|
54
54
|
Success:
|
|
55
55
|
|
|
56
56
|
```json
|
|
57
|
-
{"ok":true,"data":{"results":[]}}
|
|
57
|
+
{ "ok": true, "data": { "results": [] } }
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Error or write preview:
|
|
61
61
|
|
|
62
62
|
```json
|
|
63
|
-
{
|
|
63
|
+
{
|
|
64
|
+
"ok": false,
|
|
65
|
+
"error": {
|
|
66
|
+
"code": "confirmation_required",
|
|
67
|
+
"message": "...",
|
|
68
|
+
"details": { "preview": {}, "requiredFlag": "--confirm" }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
64
71
|
```
|
|
65
72
|
|
|
66
73
|
Exit code `0` means success, `1` means an input/auth/API failure, and `2` means a write is awaiting explicit human confirmation.
|
|
@@ -83,7 +90,7 @@ Preview a write by omitting `--confirm`:
|
|
|
83
90
|
recess --json billing pause --subscription <subscription-id> --until 2026-09-01
|
|
84
91
|
```
|
|
85
92
|
|
|
86
|
-
After a human approves that exact preview, rerun the unchanged command with `--confirm`.
|
|
93
|
+
After a human approves that exact preview, rerun the unchanged command with `--confirm`. File-backed family edits, deterministic template apply, and goal-content writes also return `details.approvalToken`; echo it with `--approval-token TOKEN`. The token covers the local bytes plus the server preflight/CAS state, so a changed file or goal produces a new preview instead of consuming stale approval.
|
|
87
94
|
|
|
88
95
|
School tier writes require the `updatedAt` token from `users tier get`. Their read-only preflight
|
|
89
96
|
shows `capabilitiesLockedNow`/`capabilitiesLockedAfter`, the resolved class allowance, current
|
|
@@ -110,19 +117,43 @@ separate `village models` commands edit the Village island's reusable models and
|
|
|
110
117
|
## Authoring learning content
|
|
111
118
|
|
|
112
119
|
```bash
|
|
113
|
-
recess --json skills get
|
|
120
|
+
recess --json skills guardian get recess-goal-authoring --all-references
|
|
114
121
|
recess --json content-library search "fractions through visual puzzles" --limit 8
|
|
115
122
|
recess --json goal-templates validate-spec --file ./template.json # iterate; writes nothing
|
|
116
123
|
recess --json goal-templates create --file ./template.json # preview, exit 2
|
|
117
124
|
recess --json goal-templates create --file ./template.json --confirm
|
|
118
125
|
recess --json goal-templates patch-spec <id-or-slug> --expected-version 7 --patches-file ./patches.json
|
|
119
|
-
recess --json
|
|
126
|
+
recess --json goals files write --student <kid-id> --draft <draft-slug> --source-dir ./goal-content
|
|
127
|
+
recess --json goals pdf upload --student <kid-id> --draft <draft-slug> --source-file ./textbook.pdf
|
|
120
128
|
recess --json goal-templates capture-snapshot <id-or-slug> --source-draft <draft-slug> --student <kid-id> --dry-run
|
|
121
129
|
recess --json goal-templates apply <id-or-slug> --answers-file ./answers.json --dry-run
|
|
122
130
|
recess --json goals create --student <kid-id> --title "..." --description-file ./goal.md
|
|
123
|
-
recess --json
|
|
131
|
+
recess --json goals create --student <kid-id> --draft <draft-slug> --title "..." \
|
|
132
|
+
--description-file ./goal.md --enable-applet-follow-ups
|
|
133
|
+
recess --json goals files list --student <kid-id> --goal <goal-id>
|
|
124
134
|
```
|
|
125
135
|
|
|
136
|
+
## Family AI operations
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
recess --json students list
|
|
140
|
+
recess --json students today --student <kid-id>
|
|
141
|
+
recess --json students schedule --student <kid-id> --days 30
|
|
142
|
+
recess --json students xp-history --student <kid-id> --range month
|
|
143
|
+
recess --json goals list --student <kid-id>
|
|
144
|
+
recess --json todos create --student <kid-id> --title "Read chapter 4"
|
|
145
|
+
recess --json memories context --student <kid-id>
|
|
146
|
+
recess --json memories log --student <kid-id> --date 2026-08-12
|
|
147
|
+
recess --json rocky get --student <kid-id>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
All family writes still preview first. Goal/todo/Rocky edits also carry the current server version
|
|
151
|
+
into the confirmed request. A guardian cannot target another family, inspect frozen/deleted
|
|
152
|
+
template history, choose todo rewards/completion/internal fields, or use the ADMIN-only
|
|
153
|
+
device-authorization flow. `memories context` and `memories log` read only the tutor repository's
|
|
154
|
+
spine, rules, reminders, and session logs; private guide remarks are never returned. The CLI does
|
|
155
|
+
not expose Postgres `UserMemory`.
|
|
156
|
+
|
|
126
157
|
## Keeping the agent skill current
|
|
127
158
|
|
|
128
159
|
```bash
|
|
@@ -131,34 +162,34 @@ recess --json doctor # .skill reports whether a newer bundle exists
|
|
|
131
162
|
recess --json setup --skill-only # bundled copy, then the served upgrade
|
|
132
163
|
```
|
|
133
164
|
|
|
134
|
-
The CLI's
|
|
135
|
-
`GET /admin/
|
|
165
|
+
The CLI's small shared router skill is **both** bundled in this package and served from
|
|
166
|
+
`GET /auth/admin-cli/skill/`. The bundled copy is the floor — it works offline, before a session exists,
|
|
136
167
|
and always matches the installed binary; `postinstall` refreshes it on every `npm install -g`. The
|
|
137
|
-
served copy is the upgrade: wording
|
|
138
|
-
of the next npm release, fenced by the bundle's `minCliVersion` so an older binary keeps its bundled
|
|
168
|
+
served copy is the upgrade: shared wording changes reach installed CLIs on the next deploy instead
|
|
169
|
+
of the next npm release, fenced by the bundle manifest's `minCliVersion` so an older binary keeps its bundled
|
|
139
170
|
copy rather than reading a skill written for a newer one. An unreachable server is never an error.
|
|
140
171
|
|
|
141
|
-
`skills
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
valid, not good. Responses cache under `~/.recess-cli/skills-cache/` (`--refresh` re-fetches).
|
|
172
|
+
`skills guardian list|get` serves family and goal-authoring guidance to `family_ai` and
|
|
173
|
+
`full_admin` sessions. `skills admin list|get` serves the staff operational skill plus the live
|
|
174
|
+
private tutor-skill registry and requires `full_admin`. The explicit audience is part of the command
|
|
175
|
+
contract; `skills get` by itself is not valid. Responses cache under
|
|
176
|
+
`~/.recess-cli/skills-cache/` (`--refresh` re-fetches).
|
|
147
177
|
|
|
148
178
|
Every template created here is `setupMode: DETERMINISTIC_WORKFLOW` and **cannot be converted back**,
|
|
149
179
|
so the confirmation gate is load-bearing. `create` runs a real server-side validation before the
|
|
150
180
|
gate, so `preview.details` carries the handler, goal shape, wizard step keys, and spec inventory the
|
|
151
|
-
|
|
181
|
+
_server_ resolved rather than a client-side guess; `apply` runs the backend's own `dryRun` and
|
|
152
182
|
previews the per-student outcome. `set-metadata` and `delete` require `--expected-version` from
|
|
153
183
|
`get`; a stale value 409s `STALE_WRITE` without writing. `set-metadata` cannot send a
|
|
154
184
|
`setupWorkflowSpec` at all. Use `patch-spec` with a JSON array of bounded JSON-Pointer operations;
|
|
155
185
|
it always runs the backend's guarded preview first and requires the preview's exact loss token in
|
|
156
186
|
addition to `--confirm` when protected template data would be removed.
|
|
157
187
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
`state/` writes
|
|
188
|
+
Module-backed content is authored as a local workspace tree and batch-upserted to a named goal
|
|
189
|
+
draft. For a personal one-off goal, `goals create --draft` validates and materializes that draft
|
|
190
|
+
directly. For reusable content, attach it to a BLUEPRINT with `capture-snapshot`. Every mutation
|
|
191
|
+
runs a server preview before the confirmation gate and is compare-and-set against the previewed
|
|
192
|
+
revision. Direct live-goal `modules/` and `state/` writes remain blocked because those files have
|
|
193
|
+
database projections.
|
|
163
194
|
|
|
164
195
|
See `recess --help` for the complete command surface. The raw escape hatch is intentionally read-only: `recess --json request get /path`.
|
package/dist/api.js
CHANGED
|
@@ -14,7 +14,7 @@ export class RecessAdminApi {
|
|
|
14
14
|
}
|
|
15
15
|
requireAuth() {
|
|
16
16
|
if (!this.config.sessionCookie) {
|
|
17
|
-
throw new CliError("auth_required", "No
|
|
17
|
+
throw new CliError("auth_required", "No Recess CLI session found. Run `recess auth login`.");
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
async rawGet(path) {
|
package/dist/args.js
CHANGED
package/dist/auth.js
CHANGED
|
@@ -79,7 +79,7 @@ export async function login(config, options) {
|
|
|
79
79
|
throw apiError(response.status, body);
|
|
80
80
|
const pair = response.headers.get("set-cookie")?.split(";", 1)[0];
|
|
81
81
|
if (!pair?.includes("=")) {
|
|
82
|
-
throw new CliError("auth_failed", "The Recess API did not return
|
|
82
|
+
throw new CliError("auth_failed", "The Recess API did not return a CLI session cookie.");
|
|
83
83
|
}
|
|
84
84
|
const exchange = body;
|
|
85
85
|
await updateStoredConfig({
|