recess-cli 1.4.0 → 1.6.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.
@@ -1,28 +0,0 @@
1
- # MAP Growth report uploads
2
-
3
- Read [`../SKILL.md`](../SKILL.md) first — the safety model and escalation discipline there govern everything below.
4
-
5
- Resolve the kid with `users search`, then preview the exact local PDF before uploading it:
6
-
7
- ```bash
8
- recess --json students upload-map-scores --student <kid-id> --file /path/to/map-report.pdf
9
- ```
10
-
11
- The command accepts one non-empty PDF up to 15 MB (validated locally — wrong extension, missing file, empty file, and oversize all fail before any network call). Its no-write preview includes the resolved absolute path, filename, byte count, content type, and SHA-256; show all of that to the human so approval identifies the exact student and file. Only after explicit approval, rerun the unchanged command with `--confirm`.
12
-
13
- ## Two valid outcomes
14
-
15
- The confirmed upload runs the existing tutor-dashboard AI extraction pipeline, so it can take **materially longer** than other admin writes — do not treat a slow response as a hang. The response distinguishes:
16
-
17
- - `kind: "scores"` — the route inserted measured MAP rows; report `inserted` and `scoreIds`.
18
- - `kind: "learning_statements"` — the PDF was a narrative NWEA Learning Statements/Continuum report with no measured RIT rows; **zero inserted scores is expected and is a success**, and `learningStatementFiles` names the Mesa files created for the tutor.
19
-
20
- ## Verify
21
-
22
- For a score upload, verify the resulting rows through the allowed read-only escape hatch:
23
-
24
- ```bash
25
- recess --json request get /tutor/students/<kid-id>/map-test-scores
26
- ```
27
-
28
- Do not call the multipart route by hand, and do not treat a narrative report's zero inserted rows as failure.
@@ -1,79 +0,0 @@
1
- # Onboarding (family stage, account state, attestations, parent intake)
2
-
3
- Read [`../SKILL.md`](../SKILL.md) first — the safety model, escalation discipline, and input conventions there govern everything below.
4
-
5
- Onboarding tracks a family from provisioned kid accounts to a fully set-up, cohort-ready household. Each family carries an `onboardingStage`, an `accountState`, a four-condition attestation checklist, and a parent intake session that structured setup data is collected into. All nine commands are keyed on the **familyId** (not a kid or user id) — resolve it with `users search` first.
6
-
7
- ## Resolve the family and read its state
8
-
9
- ```bash
10
- recess --json users search "parent or kid name"
11
- recess --json onboarding status <family-id>
12
- ```
13
-
14
- `onboarding status` is a read (no confirmation gate). It returns the current `onboardingStage`, `accountState`, `stageUpdatedAt`, the attestation `checklist` (each of `app_downloaded` / `tutor_met` / `goals_loaded` / `ma_diagnostic` with who attested and when), and per-kid setup signals (`activeGoalCount`, `appOpened`). Read it before any onboarding write so approvals name the exact starting state.
15
-
16
- ```bash
17
- recess --json onboarding kids [--time-period-days N] [--cohort <id>] [--limit N] \
18
- [--stage-filter all|scheduled|oriented|course|converted|lost]
19
- ```
20
-
21
- `onboarding kids` is the legacy funnel list — recently-onboarding kids with their parent, engagement counts, membership/enrollment status, and highest funnel stage. It is a read; the flags map one-to-one onto the endpoint's query (`timePeriodDays`, `cohortId`, `limit`, `stageFilter`). The `stageFilter` funnel values (`scheduled`/`oriented`/`course`/`converted`/`lost`) are the legacy per-kid funnel, distinct from the family `onboardingStage` enum below.
22
-
23
- ## The end-to-end order
24
-
25
- A family moves through setup roughly in this order; the attestation checklist mirrors it:
26
-
27
- 1. **App downloaded** on the kid's device → `attest --condition app_downloaded`.
28
- 2. **Tutor + guide met** the family (intro call / orientation) → `attest --condition tutor_met`, and the parent-intake session is where that call's notes get captured (`intake-session`, then `intake-session-create` if absent → `set-intake` / `extract`).
29
- 3. **Goals loaded** for each kid → `attest --condition goals_loaded`.
30
- 4. **Math Academy diagnostic** taken → `attest --condition ma_diagnostic`.
31
-
32
- The family `onboardingStage` is the coarse gate that advances alongside this:
33
- `LEGACY → PROVISIONED → PARENT_CONFIRMED → CLEARED_FOR_COHORT → COMPLETE`. `CLEARED_FOR_COHORT` is the one with a live capability effect — it unlocks cohort registration for school-partner families (`apps/web-server/src/libs/capabilities.ts`). `PARENT_CONFIRMED` reflects the parent confirming setup in-app.
34
-
35
- ## Parent intake session (read/create → fill → confirm)
36
-
37
- ```bash
38
- recess --json onboarding intake-session <family-id>
39
- recess --json onboarding intake-session-create <family-id> [--confirm]
40
- recess --json onboarding set-intake <family-id> --session <session-id> --data '<json>' [--expected-updated-at <iso>] [--confirm]
41
- recess --json onboarding extract <family-id> --session <session-id> \
42
- (--transcript-file <path> | --granola <ref>) [--confirm]
43
- ```
44
-
45
- - `intake-session` is a **read-only GET**: it returns the family's existing IN_PROGRESS session, or a clean "none yet" result when the route returns 404. It never creates a session (`get.family-intake-session.ts`).
46
- - `intake-session-create` is the explicit **confirmed write**: its POST returns the current IN_PROGRESS session or creates a fresh one when none exists (`post.family-intake-session.ts`). Run it only when the read reports no session, then use its `sessionId` for the fill commands.
47
- - `set-intake` **writes** the structured `collectedData` object for the session (PUT). `--data` is raw JSON — this is an agent-driven path (`--json`); a human rarely hand-writes the object. Invalid JSON fails locally as `invalid_arguments` before any network call; the preview shows the parsed object and does **zero** network I/O. The optimistic-concurrency token resolves only on `--confirm`, in two modes: pass `--expected-updated-at <iso>` (the `updatedAt` from an `intake-session` read) for **strict CAS** — a stale token 409s (surfaced as a non-zero-exit error) if a parent's confirm-flow autosave bumped the session since; **omit it** and the CLI fetches the current token at confirm time and prints a stderr warning that edits made since your preview are not protected. Use strict mode whenever you previewed against a specific read.
48
- - `extract` **writes** by running the intake transcript through Claude and merging the result into the session. Pass **exactly one** source — `--transcript-file <path>` (read locally into `transcript`) or `--granola <ref>` — both or neither fails as `invalid_arguments` before any network call. It is LLM-bound and can take ~30s; do not treat a slow response as a hang. A `503` means Granola is not configured server-side.
49
-
50
- The relationship: `intake-session` (read) → `intake-session-create` when absent → `set-intake` or `extract` (populate it) → the parent confirms setup in-app (which moves the stage toward `PARENT_CONFIRMED`).
51
-
52
- ## Stage and account-state writes
53
-
54
- ```bash
55
- recess --json onboarding set-stage <family-id> \
56
- --stage LEGACY|PROVISIONED|PARENT_CONFIRMED|CLEARED_FOR_COHORT|COMPLETE [--confirm]
57
- recess --json onboarding set-account-state <family-id> \
58
- --state ACTIVE|PENDING_PAYMENT|PAUSED|BOOTED [--note TEXT] [--confirm]
59
- ```
60
-
61
- - `set-stage` reads the current stage first (one GET before the confirmation gate) so the preview names the transition (`target.from`) and warns when the move goes **backward** — a lower stage re-locks progress the family already passed, and the action string is prefixed `MOVE BACKWARD — re-locks progress`. Confirm backward moves deliberately; `CLEARED_FOR_COHORT` gating cohort registration means dropping below it removes that access.
62
- - `set-account-state` sets the family's billing/access posture. `PAUSED` and `BOOTED` **lock the family out of paid capabilities** — the preview spells this out; call it out in the approval request. `--note` is analytics-only (recorded, not shown to the family).
63
-
64
- ## Attestations
65
-
66
- ```bash
67
- recess --json onboarding attest <family-id> \
68
- --condition app_downloaded|tutor_met|goals_loaded|ma_diagnostic [--revoke] [--note TEXT] [--confirm]
69
- ```
70
-
71
- Marks (or, with `--revoke`, clears) one checklist condition. The preview action reads `attest <condition>` or `REVOKE attestation <condition>`. `--note` is passed through. Read `onboarding status` first to see which conditions are already attested and by whom.
72
-
73
- ## Batch and verify
74
-
75
- Same discipline as the other domains: collect every planned write's preview without `--confirm`, present one batched approval that names the side effects (stage backward moves, PAUSED/BOOTED lockout, the ~30s LLM extract), rerun unchanged with `--confirm`, then re-read `onboarding status` to confirm the new stage / checklist / account state.
76
-
77
- ## Out of scope
78
-
79
- There is no `mcp serve` mode and no server-side PAT path for these endpoints yet — the CLI drives them over the normal admin cookie session only. Kid provisioning, device pairing, and the in-app parent-confirmation UI stay in the product surfaces that own them.
@@ -1,74 +0,0 @@
1
- # Guide payout ops (biweekly changes)
2
-
3
- Read [`../SKILL.md`](../SKILL.md) first — the safety model, escalation discipline, and input conventions there govern everything below.
4
-
5
- Guides and program partners are paid through payout invoices: a biweekly pay run spawns one invoice per payout recipient account, most line items are generated automatically from Stripe payments or taught sessions, and the operations team applies a short instruction of manual changes each cycle ("CHANGES TO MAKE EVERY 2WKS: Add for X … Delete Y …"). Your job is to translate that instruction into exact CLI writes.
6
-
7
- ## 1. Identify the pay cycle
8
-
9
- ```bash
10
- recess --json payout payruns list --status IN_REVIEW,DRAFT,UPCOMING
11
- ```
12
-
13
- Pay runs are named like "Biweekly: Jun 28, 2026 - Jul 12, 2026". Valid `--status` values: `UPCOMING, DRAFT, IN_REVIEW, APPROVED, PAID, CANCELED`. A recurring-changes instruction targets the run currently being prepared (usually IN_REVIEW or DRAFT) unless it names dates. If more than one run is plausible, ask the human which cycle they mean.
14
-
15
- ## 2. Resolve each recipient
16
-
17
- ```bash
18
- recess --json payout recipients list --search "Tom Bickmore"
19
- ```
20
-
21
- - Instructions name people or programs. A person maps to an account like "Tom B.'s Payout Account"; a program ("Guild of Imagination") maps to a program account with no linked user.
22
- - A guide can have TWO accounts (a TAKE_RATE account and an HOURLY account), which means two invoices in the same run. When a search returns more than one account, inspect both invoices' line items to determine which one the instruction targets, and state which account you chose in the approval request.
23
- - Zero matches: stop and ask the human; never guess a similar name.
24
-
25
- ## 3. Find and inspect the invoice before writing
26
-
27
- ```bash
28
- recess --json payout invoices list --payrun <payrun-id> --recipient <account-id>
29
- recess --json payout invoices get <invoice-id>
30
- ```
31
-
32
- `payout invoices list` requires at least one filter (`--payrun`, `--recipient`, `--user`, or `--status`). Check before every write:
33
-
34
- - The invoice status permits the operation: adding items requires DRAFT or IN_REVIEW; editing allows DRAFT, IN_REVIEW, or OPEN; deleting items requires DRAFT or IN_REVIEW.
35
- - `mayHaveDuplicates: true` means a Stripe payment already appears on another invoice — flag it to the human instead of ignoring it.
36
-
37
- ## 4. Apply the changes
38
-
39
- ```bash
40
- recess --json payout items add --invoice <id> --amount-cents 28800 \
41
- --description "Recess+ for 8 kids at $18 2wks 2x$144" --confirm
42
- recess --json payout items edit <item-id> --amount-cents 4000 --confirm
43
- recess --json payout items delete <item-id> --confirm
44
- recess --json payout invoices set-status <invoice-id> --status CANCELED --confirm
45
- ```
46
-
47
- Conventions that make the changes correct:
48
-
49
- - **Amounts are integer cents.** Parse dollar expressions yourself and cross-check any stated total: "2x$144 = $288" is one line item of 28800 cents unless the instruction clearly means separate items. If your arithmetic disagrees with a stated "= $X", surface the discrepancy instead of picking one.
50
- - **Descriptions**: reuse the instruction's wording, minus trailing arithmetic ("… 2x$53.20 = $106.40" → "… 2x$53.20"). The same items recur every cycle, and stable wording lets the next cycle's operator match them.
51
- - **Item date**: when the instruction gives no date, omit `--date`; the CLI defaults to the penultimate day of the invoice cycle (endDate minus one day) and shows the computed date in the preview (this default requires one read of the invoice before the confirmation gate — expected). Confirm it looks right. An explicit `--date` takes bare `YYYY-MM-DD` (anchored to UTC noon) or a full ISO timestamp.
52
- - **Edits only touch custom items.** `payout items edit` sets net = total (custom line items carry no platform fee); auto-generated Stripe/session items have different net semantics — don't edit them, flag them to the human.
53
- - **Recurring instructions**: "EVERY 2WKS" items are re-added fresh each cycle; there is no copy-forward mechanism. When an instruction is terse, read the previous run's invoice for the same recipient and mirror its amounts and descriptions.
54
- - **"Delete <person>"** means take the person off this cycle's payroll: cancel their invoice with `set-status --status CANCELED` (for example, a guide who moved to Deel). **"Delete <line item>"** means soft-delete one item with `payout items delete`. "Delete the first one" is ambiguous — list the invoice's items in order and confirm the target with the human before deleting.
55
-
56
- ## 5. Status changes carry side effects
57
-
58
- `payout invoices set-status` previews spell these out; repeat them in the approval request:
59
-
60
- - `IN_REVIEW` moves the invoice into review.
61
- - `OPEN` finalizes: adds the invoice total to the recipient's running account balance.
62
- - `PAID` marks paid and deducts the total from the account balance.
63
- - `CANCELED` cancels the invoice and reverses balance items carried on it.
64
- - The guide email on `IN_REVIEW`/`OPEN` fires **only with `--send-email`** (default: no email). Follow the instruction: "finalize and notify" needs the flag; a quiet finalize omits it.
65
- - A `PAID` or `CANCELED` invoice is terminal — the server rejects any further status change (400).
66
- - Never finalize, mark paid, or cancel without an explicit instruction to do so.
67
-
68
- ## 6. Batch the escalation, verify after
69
-
70
- For a multi-recipient instruction, first run every read, then run every write WITHOUT `--confirm` to collect previews, and present the complete per-recipient change plan (every add, edit, delete, and cancel with its preview) as ONE approval request. After approval, run each command unchanged with `--confirm`, then re-read each touched invoice with `payout invoices get` and verify the new `totalAmountCents` matches your arithmetic.
71
-
72
- ## Out of scope
73
-
74
- Money movement and bulk pay-run lifecycle are deliberately not in the CLI: initiating Mercury payouts, advancing whole pay runs, and generating or regenerating invoices happen in the web admin at `/admin/payout`. If asked, direct the human there.