recess-cli 1.9.2 → 2.1.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 +94 -56
- package/dist/api.js +122 -10
- package/dist/args.js +12 -1
- package/dist/auth.js +11 -10
- package/dist/cli.js +1320 -859
- package/dist/command-schema.js +261 -0
- package/dist/commands/applications.js +336 -0
- package/dist/commands/onboarding.js +623 -0
- package/dist/commands/shared.js +100 -0
- package/dist/config.js +116 -19
- package/dist/delivery.js +26 -0
- package/dist/feedback.js +64 -0
- package/dist/help.js +376 -0
- package/dist/http.js +25 -0
- package/dist/index.js +15 -3
- package/dist/jobs.js +80 -0
- package/dist/skill-update.js +2 -1
- package/dist/ui/index.js +2 -1
- package/package.json +3 -3
- package/skill/recess-cli/SKILL.md +20 -8
- package/skill/recess-cli/agents/version.json +2 -2
package/dist/help.js
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
export const HELP = `recess — safe Recess administration and family AI tools
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
recess [--json] --version
|
|
5
|
+
recess [--json] agent-context
|
|
6
|
+
recess [--json] setup [--skill-only]
|
|
7
|
+
recess [--json] doctor
|
|
8
|
+
recess [--json] profile list
|
|
9
|
+
recess [--json] profile show <name>
|
|
10
|
+
recess [--json] profile save <name> [--api-origin URL] [--web-origin URL]
|
|
11
|
+
[--oauth-client-id ID]
|
|
12
|
+
recess [--json] profile use <name>
|
|
13
|
+
recess [--json] profile delete <name>
|
|
14
|
+
recess [--json] jobs list [--limit 20]
|
|
15
|
+
recess [--json] jobs get <operation-key>
|
|
16
|
+
recess [--json] jobs prune [--older-than-days 30]
|
|
17
|
+
recess [--json] feedback list [--limit 20]
|
|
18
|
+
recess [--json] feedback submit <text> [--confirm]
|
|
19
|
+
recess [--json] auth login [--client-id ID] [--callback-port 8765]
|
|
20
|
+
recess [--json] auth request [--label TEXT]
|
|
21
|
+
recess [--json] auth poll [--timeout 300]
|
|
22
|
+
recess [--json] auth status|logout
|
|
23
|
+
recess [--json] users search <name-or-id> [--limit 10]
|
|
24
|
+
recess [--json] users get <user-id>
|
|
25
|
+
recess [--json] users tier list-tiers
|
|
26
|
+
recess [--json] users tier get <kid-id>
|
|
27
|
+
recess [--json] users tier preview <kid-id> --tier social|academics|lite|complete|platform
|
|
28
|
+
[--slots N]
|
|
29
|
+
recess [--json] users tier set <kid-id> --tier social|academics|lite|complete|platform
|
|
30
|
+
[--slots N] --expected-updated-at <iso> [--allow-strand] [--confirm]
|
|
31
|
+
recess [--json] guides create --email <email> --first-name TEXT
|
|
32
|
+
[--last-name TEXT] [--no-invite] [--confirm]
|
|
33
|
+
recess [--json] guides invite --user <user-id> [--confirm]
|
|
34
|
+
recess [--json] guardians invite --family <family-id> --email <email>
|
|
35
|
+
--first-name TEXT [--last-name TEXT] [--no-invite] [--confirm]
|
|
36
|
+
recess [--json] students upload-map-scores --student <kid-id>
|
|
37
|
+
--file </path/to/map-report.pdf> [--confirm]
|
|
38
|
+
recess [--json] students list
|
|
39
|
+
recess [--json] students today --student <kid-id> [--date YYYY-MM-DD]
|
|
40
|
+
recess [--json] students schedule --student <kid-id> [--days 14]
|
|
41
|
+
recess [--json] students xp-history --student <kid-id>
|
|
42
|
+
[--range week|month|quarter|year]
|
|
43
|
+
recess [--json] enrollments list --user <user-id>
|
|
44
|
+
recess [--json] subscriptions list --family <family-id> [--kid <kid-id>]
|
|
45
|
+
recess [--json] invoices list --subscription <subscription-id>
|
|
46
|
+
recess [--json] billing pause --subscription <id> [--until ISO_DATE] [--confirm]
|
|
47
|
+
recess [--json] billing resume --subscription <id> [--confirm]
|
|
48
|
+
recess [--json] invoices refund --invoice <id> --line-item <id>
|
|
49
|
+
--method refund|credit|tokens [--full | --amount-cents N]
|
|
50
|
+
[--who-pays guide|recess] [--reason TEXT] [--confirm]
|
|
51
|
+
recess [--json] applications list [--status SUBMITTED|CLAIMED|ENROLLED|CLOSED]
|
|
52
|
+
[--status-scope active|closed] [--disposition READY_TO_ENROLL|TRIAL|PENDING_FUNDING|NO]
|
|
53
|
+
[--dispositioned true|false] [--quality QUALIFIED|NEEDS_NURTURE|UNKNOWN]
|
|
54
|
+
[--source PUBLIC|STAFF] [--limit 100] [--cursor <id>]
|
|
55
|
+
recess [--json] applications get <application-id>
|
|
56
|
+
recess [--json] applications quotes <application-id>
|
|
57
|
+
recess [--json] applications meetings <application-id>
|
|
58
|
+
recess [--json] applications call-notes <application-id>
|
|
59
|
+
recess [--json] applications create --data-file <application.json> [--confirm]
|
|
60
|
+
recess [--json] applications disposition <application-id>
|
|
61
|
+
--data-file <disposition.json> [--confirm]
|
|
62
|
+
recess [--json] applications qualify <application-id>
|
|
63
|
+
--quality QUALIFIED|NEEDS_NURTURE|UNKNOWN --reason TEXT [--confirm]
|
|
64
|
+
recess [--json] applications update-contact <application-id>
|
|
65
|
+
--data-file <contact.json> [--confirm]
|
|
66
|
+
recess [--json] applications claim-email|claim-link <application-id>
|
|
67
|
+
--intent-key <uuid> [--supersede] [--confirm]
|
|
68
|
+
recess [--json] applications revoke-claim <application-id> [--confirm]
|
|
69
|
+
recess [--json] applications link-family <application-id> --family <family-id> [--confirm]
|
|
70
|
+
recess [--json] applications close <application-id> --reason TEXT [--confirm]
|
|
71
|
+
recess [--json] applications add-call-note <application-id>
|
|
72
|
+
--data-file <call-note.json> [--confirm]
|
|
73
|
+
recess [--json] applications edit-call-note <application-id>
|
|
74
|
+
--note-id <note-id> --data-file <comment.json> [--confirm]
|
|
75
|
+
recess [--json] applications enroll <application-id> --quote <quote-id>
|
|
76
|
+
--school <institution-slug> --kid "<quoteLineId>:<firstName>[:<age>]" (repeat per line)
|
|
77
|
+
[--family <family-id>] [--unassign <kid-id>] (repeat) [--note TEXT] [--confirm]
|
|
78
|
+
recess [--json] quotes get <quote-id>
|
|
79
|
+
recess [--json] quotes preview --data-file <quote.json>
|
|
80
|
+
recess [--json] quotes create --data-file <quote.json> [--confirm]
|
|
81
|
+
recess [--json] quotes update <quote-id> --data-file <quote.json> [--confirm]
|
|
82
|
+
recess [--json] quotes send <quote-id> [--expected-revision <sha>] [--confirm]
|
|
83
|
+
recess [--json] quotes accept <quote-id> [--confirm]
|
|
84
|
+
recess [--json] quotes decline <quote-id> [--note TEXT] [--confirm]
|
|
85
|
+
recess [--json] cohorts search <query>
|
|
86
|
+
recess [--json] enrollments create --user <kid-id> --cohort <id>
|
|
87
|
+
[--first-charge-at ISO_DATETIME] [--send-email] [--force]
|
|
88
|
+
[--confirm --approval-token TOKEN]
|
|
89
|
+
recess [--json] enrollments register-cohort --enrollment <id>
|
|
90
|
+
--user <id> --cohort <id> [--confirm]
|
|
91
|
+
recess [--json] enrollments unregister-cohort --user <id>
|
|
92
|
+
--cohort <id> [--confirm]
|
|
93
|
+
recess [--json] enrollments get-for-subscription --subscription <id>
|
|
94
|
+
recess [--json] billing extend-trial --subscription <id>
|
|
95
|
+
--trial-end ISO_DATE [--confirm]
|
|
96
|
+
recess [--json] billing cancel-subscription --subscription <id>
|
|
97
|
+
[--immediate] [--reason TEXT] [--restore] [--confirm]
|
|
98
|
+
recess [--json] payout payruns list [--status A,B] [--schedule <id>]
|
|
99
|
+
recess [--json] payout recipients list [--search <name>] [--user <id>] [--id <id>]
|
|
100
|
+
[--limit 20] [--cursor <id>]
|
|
101
|
+
recess [--json] payout invoices list [--payrun <id>] [--recipient <account-id>]
|
|
102
|
+
[--user <id>] [--status A,B] (at least one filter)
|
|
103
|
+
recess [--json] payout invoices get <invoice-id>
|
|
104
|
+
recess [--json] payout invoices set-status <invoice-id>
|
|
105
|
+
--status IN_REVIEW|OPEN|PAID|CANCELED [--send-email] [--confirm]
|
|
106
|
+
recess [--json] payout items add --invoice <id> --amount-cents N
|
|
107
|
+
--description TEXT [--date YYYY-MM-DD] [--confirm]
|
|
108
|
+
recess [--json] payout items edit <item-id> [--amount-cents N]
|
|
109
|
+
[--description TEXT] [--date YYYY-MM-DD] [--confirm]
|
|
110
|
+
recess [--json] payout items delete <item-id> [--confirm]
|
|
111
|
+
recess [--json] cohorts get <cohort-id> [--events-tab ACTIVE|ENDED|CANCELED|ARCHIVED]
|
|
112
|
+
recess [--json] cohorts parent-emails <cohort-id>
|
|
113
|
+
recess [--json] cohorts end <cohort-id> [--cancel-subscriptions] [--confirm]
|
|
114
|
+
recess [--json] cohorts pause-billing <cohort-id> --weeks 1..6 [--confirm]
|
|
115
|
+
recess [--json] cohorts resume-billing <cohort-id> [--confirm]
|
|
116
|
+
recess [--json] cohorts email <cohort-id> --target ALL_PARENTS|ALL_PARENTS_GUIDES
|
|
117
|
+
--content TEXT [--confirm]
|
|
118
|
+
recess [--json] events get <event-id>
|
|
119
|
+
recess [--json] events take-attendance <event-id> --attended <id,id,...>
|
|
120
|
+
[--absent <id,id,...>] [--excused <id,id,...>] [--confirm]
|
|
121
|
+
recess [--json] events cancel <event-id> --reason TEXT [--confirm]
|
|
122
|
+
recess [--json] events set-status <event-id> --status ACTIVE|ENDED|CANCELED [--confirm]
|
|
123
|
+
recess [--json] events reschedule --cohort <id> --event <event-id>
|
|
124
|
+
--starts-at "YYYY-MM-DDTHH:MM" [--timezone <iana>] [--length-mins N] [--confirm]
|
|
125
|
+
recess [--json] events add --cohort <id> --starts-at "YYYY-MM-DDTHH:MM"
|
|
126
|
+
[--timezone <iana>] [--length-mins N] [--confirm]
|
|
127
|
+
recess [--json] registrations approve --registration <id> [--confirm]
|
|
128
|
+
recess [--json] registrations deny --cohort <id> --user <id> [--confirm]
|
|
129
|
+
recess [--json] request get </path?query=value>
|
|
130
|
+
recess [--json] onboarding status <family-id>
|
|
131
|
+
recess [--json] onboarding queue [--school <institution-slug>]
|
|
132
|
+
recess [--json] onboarding kids [--time-period-days N] [--cohort <id>]
|
|
133
|
+
[--limit N] [--stage-filter all|scheduled|oriented|course|converted|lost]
|
|
134
|
+
recess [--json] onboarding timeline <family-id>
|
|
135
|
+
recess [--json] onboarding readiness <family-id>
|
|
136
|
+
recess [--json] onboarding active-tutors <family-id>
|
|
137
|
+
recess [--json] onboarding meetings <family-id>
|
|
138
|
+
recess [--json] onboarding cohort-options <family-id> [--kid <kid-id>]
|
|
139
|
+
recess [--json] onboarding comms [--school <institution-slug>]
|
|
140
|
+
[--status RESERVED|SENT|FAILED] [--kind <kind>] [--limit 50] [--cursor <cursor>]
|
|
141
|
+
recess [--json] onboarding lifecycle-prompts
|
|
142
|
+
recess [--json] onboarding orientation-sessions
|
|
143
|
+
recess [--json] onboarding ixl-preview <family-id> --kid <kid-id>
|
|
144
|
+
recess [--json] onboarding intake-session <family-id>
|
|
145
|
+
recess [--json] onboarding intake-session-create <family-id> [--confirm]
|
|
146
|
+
recess [--json] onboarding set-stage <family-id>
|
|
147
|
+
--stage LEGACY|PROVISIONED|PARENT_CONFIRMED|CLEARED_FOR_COHORT|COMPLETE [--confirm]
|
|
148
|
+
recess [--json] onboarding set-account-state <family-id>
|
|
149
|
+
--state ACTIVE|PENDING_PAYMENT|PAUSED|BOOTED [--note TEXT] [--confirm]
|
|
150
|
+
recess [--json] onboarding set-primary-tutor <family-id>
|
|
151
|
+
[--tutor <user-id> | --clear] [--confirm]
|
|
152
|
+
recess [--json] onboarding attest <family-id>
|
|
153
|
+
--condition app_downloaded|tutor_met|goals_loaded|ma_diagnostic [--revoke]
|
|
154
|
+
[--note TEXT] [--confirm]
|
|
155
|
+
recess [--json] onboarding clear-for-cohort <family-id> [--confirm]
|
|
156
|
+
recess [--json] onboarding register-cohort <family-id>
|
|
157
|
+
--kid <kid-id> --cohort <event-series-id> [--confirm]
|
|
158
|
+
recess [--json] onboarding set-kid-grade <family-id>
|
|
159
|
+
--kid <kid-id> [--grade 1..12 | --clear] [--confirm]
|
|
160
|
+
recess [--json] onboarding seed-feed <family-id> --kid <kid-id> [--confirm]
|
|
161
|
+
recess [--json] onboarding generate-summaries <family-id> [--confirm]
|
|
162
|
+
recess [--json] onboarding provision-math-academy <family-id>
|
|
163
|
+
--kid <kid-id> [--grade 1..12] [--confirm]
|
|
164
|
+
recess [--json] onboarding provision-ixl <family-id>
|
|
165
|
+
--kid <kid-id> [--credentials-file <credentials.json>] [--confirm]
|
|
166
|
+
recess [--json] onboarding remove-ixl <family-id> --kid <kid-id> [--confirm]
|
|
167
|
+
recess [--json] onboarding ixl-sync [--apply] [--confirm]
|
|
168
|
+
recess [--json] onboarding send-comms --subject <family:id|invite:id>
|
|
169
|
+
--kind <kind> [--confirm]
|
|
170
|
+
recess [--json] onboarding send-welcome <family-id> [--resend] [--confirm]
|
|
171
|
+
recess [--json] onboarding send-payment-email <family-id> [--resend] [--confirm]
|
|
172
|
+
recess [--json] onboarding send-recommendations <family-id>
|
|
173
|
+
--courses <course-id,course-id> [--resend] [--confirm]
|
|
174
|
+
recess [--json] onboarding set-lifecycle-prompt <kind>
|
|
175
|
+
[--enabled true|false] [--delay-days N] [--window-days N]
|
|
176
|
+
[--snooze-days N] [--max-prompts N] [--confirm]
|
|
177
|
+
recess [--json] onboarding override-lifecycle-prompt <kind> <family-id>
|
|
178
|
+
--action delay|skip|clear [--days N] [--confirm]
|
|
179
|
+
recess [--json] onboarding orientation-create --starts-at <iso>
|
|
180
|
+
[--ends-at <iso>] [--capacity N] [--confirm]
|
|
181
|
+
recess [--json] onboarding orientation-set-status <session-id>
|
|
182
|
+
--status CANCELED|COMPLETED [--confirm]
|
|
183
|
+
recess [--json] onboarding orientation-attendance <session-id>
|
|
184
|
+
--family <family-id> --attended true|false [--confirm]
|
|
185
|
+
recess [--json] onboarding meeting-reschedule <meeting-id>
|
|
186
|
+
--starts-at <iso> [--note TEXT] [--confirm]
|
|
187
|
+
recess [--json] onboarding meeting-cancel <meeting-id> --reason TEXT [--confirm]
|
|
188
|
+
recess [--json] onboarding set-intake <family-id> --session <id>
|
|
189
|
+
--data <json> [--expected-updated-at <iso>] [--confirm]
|
|
190
|
+
recess [--json] onboarding extract <family-id> --session <id>
|
|
191
|
+
(--transcript-file <path> | --granola <ref>) [--confirm]
|
|
192
|
+
recess [--json] village models list [--world village-1] [--query TEXT] [--archived]
|
|
193
|
+
recess [--json] village models upload --file </path/model.glb>
|
|
194
|
+
[--world village-1] [--name TEXT] [--id ID] [--description TEXT] [--tags A,B]
|
|
195
|
+
[--visual-only] [--confirm]
|
|
196
|
+
recess [--json] village models publish|archive <model-id> [--world village-1] [--confirm]
|
|
197
|
+
recess [--json] village models place <model-id> --x N --z N
|
|
198
|
+
[--y N] [--rotation 0..3] [--mirrored] [--no-collision] [--batch ID]
|
|
199
|
+
[--world village-1] [--confirm]
|
|
200
|
+
recess [--json] village models move <placement-id> --x N --z N
|
|
201
|
+
[--y N] [--rotation 0..3] [--mirrored] [--world village-1] [--confirm]
|
|
202
|
+
recess [--json] village models remove <placement-id> [--world village-1] [--confirm]
|
|
203
|
+
recess [--json] village render --min-x N --min-z N --max-x N --max-z N
|
|
204
|
+
[--world village-1]
|
|
205
|
+
recess [--json] village library search [query] [--query TEXT] [--limit 20]
|
|
206
|
+
[--world home-USER_ID]
|
|
207
|
+
recess [--json] village library get <model-id> [--world home-USER_ID]
|
|
208
|
+
recess [--json] village objects list [--min-x -20] [--min-z -20]
|
|
209
|
+
[--max-x 20] [--max-z 20] [--world home-USER_ID]
|
|
210
|
+
recess [--json] village objects get <object-id> [--world home-USER_ID]
|
|
211
|
+
recess [--json] village build cmd '<command-json>' [--world home-USER_ID] [--confirm]
|
|
212
|
+
recess [--json] village build cmd --file <command.json> [--world home-USER_ID] [--confirm]
|
|
213
|
+
recess [--json] village worlds export <world-id> [--out <bundle.json>] [--confirm]
|
|
214
|
+
recess [--json] village worlds import <world-id> --file <bundle.json> [--confirm]
|
|
215
|
+
recess [--json] village worlds promote <mirror-or-archive-id> [--confirm]
|
|
216
|
+
recess [--json] store-items list [--search TEXT]
|
|
217
|
+
[--status ACTIVE|INACTIVE|COMING_SOON] [--item-type TYPE]
|
|
218
|
+
[--page 0] [--limit 20] [--sort-by name|price|createdAt|updatedAt|order]
|
|
219
|
+
[--sort-order asc|desc]
|
|
220
|
+
recess [--json] store-items set-status <village-store-item-id>
|
|
221
|
+
--status ACTIVE|INACTIVE|COMING_SOON [--confirm]
|
|
222
|
+
recess [--json] content-library search <query> [--limit 8]
|
|
223
|
+
recess [--json] content-library status <gem-id-or-url>
|
|
224
|
+
recess [--json] content-library set-stage <gem-id-or-url...> [--file <path>]
|
|
225
|
+
--stage review|polishing|live|archived [--wait] [--timeout 900] [--confirm]
|
|
226
|
+
recess [--json] content-library submit <url...> [--file <path>]
|
|
227
|
+
[--stage review|polish] [--title TEXT] [--summary TEXT]
|
|
228
|
+
[--lane web-toys|mechanics|explorables|data-stories|sims|maps-scale|sound-art|puzzles|wonder|idea-games]
|
|
229
|
+
[--wait] [--timeout 900] [--confirm]
|
|
230
|
+
recess [--json] skills guardian list [--query TEXT] [--category TEXT]
|
|
231
|
+
recess [--json] skills guardian get <skill-name>
|
|
232
|
+
[--reference NAME | --all-references] [--refresh]
|
|
233
|
+
recess [--json] skills admin list [--query TEXT] [--category TEXT]
|
|
234
|
+
recess [--json] skills admin get <skill-name>
|
|
235
|
+
[--reference NAME | --all-references]
|
|
236
|
+
[--refresh]
|
|
237
|
+
recess [--json] goal-templates list [--query TEXT] [--category TEXT]
|
|
238
|
+
[--kind SIMPLE|BLUEPRINT] [--starter-only] [--include-deleted]
|
|
239
|
+
[--limit 20] [--cursor <id>]
|
|
240
|
+
recess [--json] goal-templates get <template-id|slug> [--spec-only]
|
|
241
|
+
recess [--json] goal-templates versions <template-id> [--version N]
|
|
242
|
+
recess [--json] goal-templates validate-spec --file <path/template.json>
|
|
243
|
+
recess [--json] goal-templates create --file <path/template.json> [--confirm]
|
|
244
|
+
recess [--json] goal-templates patch-spec <template-id|slug> --expected-version N
|
|
245
|
+
--patches-file <path/patches.json> [--confirm --approval-token TOKEN]
|
|
246
|
+
[--confirm-destructive-changes --destructive-change-token TOKEN]
|
|
247
|
+
recess [--json] goal-templates set-metadata <template-id> --expected-version N
|
|
248
|
+
[--title TEXT] [--description TEXT] [--emoji X] [--category TEXT] [--tags A,B]
|
|
249
|
+
[--sort-order N] [--is-starter true|false]
|
|
250
|
+
[--setup-audience KID_FRIENDLY|PARENT_SETUP] [--kind SIMPLE|BLUEPRINT]
|
|
251
|
+
[--agent-instructions-file <path>]
|
|
252
|
+
[--output-template-file <path>] [--confirm]
|
|
253
|
+
recess [--json] goal-templates delete <template-id> --expected-version N [--confirm]
|
|
254
|
+
recess [--json] goal-templates snapshot-files <template-id> [--path P]
|
|
255
|
+
recess [--json] goal-templates capture-snapshot <template-id|slug>
|
|
256
|
+
(--source-goal <goal-id> | --source-draft <draft-slug> --student <goal-owner-id>
|
|
257
|
+
| --source-dir <local-checkout>)
|
|
258
|
+
[--dry-run] [--confirm --approval-token TOKEN]
|
|
259
|
+
recess [--json] goal-templates apply <template-id> --answers-file <path>
|
|
260
|
+
[--dry-run] [--confirm --approval-token TOKEN]
|
|
261
|
+
recess [--json] goal-templates apply-starter <template-id> --student <kid-id>
|
|
262
|
+
[--answers-file <path>] [--confirm]
|
|
263
|
+
recess [--json] goals list --student <kid-id>
|
|
264
|
+
recess [--json] goals create [--student <kid-id>] --title TEXT
|
|
265
|
+
(--description TEXT | --description-file <path>) [--target-date <iso>]
|
|
266
|
+
[--schedule TEXT] [(--draft <draft-slug> | --source-dir <local-checkout>)
|
|
267
|
+
(--enable-applet-follow-ups | --disable-applet-follow-ups)]
|
|
268
|
+
[--confirm --approval-token TOKEN]
|
|
269
|
+
recess [--json] goals edit <goal-id> --student <kid-id> --patch-file <path/patch.json>
|
|
270
|
+
--delta TEXT [--confirm --approval-token TOKEN]
|
|
271
|
+
recess [--json] goals delete <goal-id> --student <kid-id>
|
|
272
|
+
[--confirm --approval-token TOKEN]
|
|
273
|
+
recess [--json] goals queue get <goal-id> --student <kid-id>
|
|
274
|
+
recess [--json] goals queue set <goal-id> --student <kid-id>
|
|
275
|
+
--entries-file <path.json> --delta TEXT [--replace-description-pointer]
|
|
276
|
+
[--confirm --approval-token TOKEN]
|
|
277
|
+
recess [--json] todos create --student <kid-id> --title TEXT
|
|
278
|
+
[--due-date YYYY-MM-DD] [--estimated-minutes N] [--url URL] [--confirm]
|
|
279
|
+
recess [--json] todos edit <todo-id> --patch-file <path/patch.json>
|
|
280
|
+
[--confirm --approval-token TOKEN]
|
|
281
|
+
recess [--json] todos delete <todo-id>
|
|
282
|
+
[--confirm --approval-token TOKEN]
|
|
283
|
+
recess [--json] todos generate-applet <todo-id> --student <kid-id>
|
|
284
|
+
[--due-date YYYY-MM-DD] [--confirm --approval-token TOKEN]
|
|
285
|
+
recess [--json] memories context --student <kid-id>
|
|
286
|
+
recess [--json] memories log --student <kid-id> --date YYYY-MM-DD
|
|
287
|
+
recess [--json] rocky get --student <kid-id>
|
|
288
|
+
recess [--json] rocky set --student <kid-id> --patch-file <path/patch.json>
|
|
289
|
+
--expected-updated-at ISO|none [--confirm]
|
|
290
|
+
recess [--json] goals files list --student <goal-owner-id> --goal <goal-id>
|
|
291
|
+
recess [--json] goals files read --student <goal-owner-id> --goal <goal-id> --path P
|
|
292
|
+
recess [--json] goals files init --student <goal-owner-id> --draft <draft-slug>
|
|
293
|
+
--output-dir <local-dir>
|
|
294
|
+
recess [--json] goals files checkout --student <goal-owner-id>
|
|
295
|
+
(--goal <goal-id> | --draft <draft-slug>)
|
|
296
|
+
--output-dir <local-dir>
|
|
297
|
+
recess [--json] goals files push --source-dir <local-checkout>
|
|
298
|
+
[--message TEXT] [--confirm --approval-token TOKEN]
|
|
299
|
+
recess [--json] goals files write --student <goal-owner-id>
|
|
300
|
+
(--goal <goal-id> | --draft <draft-slug>)
|
|
301
|
+
(--source-dir <local-dir> | --source-file <local-file> --path P)
|
|
302
|
+
[--message TEXT] [--confirm --approval-token TOKEN]
|
|
303
|
+
recess [--json] goals pdf upload --student <goal-owner-id>
|
|
304
|
+
(--goal <goal-id> | --draft <draft-slug>) --source-file <local.pdf>
|
|
305
|
+
[--path uploads/name.pdf] [--message TEXT]
|
|
306
|
+
[--confirm --approval-token TOKEN]
|
|
307
|
+
|
|
308
|
+
Authoring notes: "skills" serves the in-product tutor skills (the private
|
|
309
|
+
packages/skills workspace package) read-only over your admin session — they are never
|
|
310
|
+
bundled into this npm package. Load os-v2-goal-template-builder and its
|
|
311
|
+
references/deterministic-workflow-setup.md BEFORE authoring a template; that is
|
|
312
|
+
the same guidance the recess.gg/ai agent follows, so there is exactly one
|
|
313
|
+
standard. Responses cache under ~/.recess-cli/skills-cache/ (--refresh re-fetches).
|
|
314
|
+
For goal workspace and PDF commands, --student names the goal owner. A
|
|
315
|
+
full_admin session may use a KID or ADMIN user id, including its own ADMIN id;
|
|
316
|
+
family_ai sessions remain limited to managed KID profiles.
|
|
317
|
+
"goals create --source-dir" materializes a clean, fully pushed draft checkout as
|
|
318
|
+
a personal module-backed goal and retargets that checkout to the resulting live
|
|
319
|
+
goal. It does not create or apply a reusable template. Its preview is bound to
|
|
320
|
+
the exact workspace revision, hash, module inventory, and applet follow-up choice.
|
|
321
|
+
Every template created here is setupMode DETERMINISTIC_WORKFLOW and CANNOT be
|
|
322
|
+
converted back, so "validate-spec" against the same file until it passes, then
|
|
323
|
+
"create". "create" runs a real server-side validation before its gate, so the
|
|
324
|
+
preview shows the handler/goalShape/step keys the SERVER resolved. "apply" runs
|
|
325
|
+
the backend's own dryRun before the gate and previews the per-student outcome.
|
|
326
|
+
"set-metadata" and "delete" require --expected-version (from "get"); a stale one
|
|
327
|
+
409s STALE_WRITE and writes nothing. The spec is unreachable from "set-metadata"
|
|
328
|
+
by design — an existing spec is edited only through the guarded /ai patch path.
|
|
329
|
+
|
|
330
|
+
Onboarding notes: "status" and "intake-session" are reads — "intake-session"
|
|
331
|
+
looks up the current IN_PROGRESS session without creating one (prints a "none
|
|
332
|
+
yet" result when absent). "intake-session-create" is the explicit write that
|
|
333
|
+
mints a blank session, so it is gated behind --confirm. "set-stage" reads the
|
|
334
|
+
current stage first and warns when a move re-locks progress; CLEARED_FOR_COHORT
|
|
335
|
+
unlocks cohort registration. "set-account-state" PAUSED/BOOTED lock the family out of paid
|
|
336
|
+
capabilities (--note is analytics-only). "set-intake --data" takes JSON (agents
|
|
337
|
+
drive it with --json; humans rarely will); the preview is offline. Its
|
|
338
|
+
optimistic-concurrency token resolves only on --confirm: pass
|
|
339
|
+
--expected-updated-at <iso> (from an intake-session read's updatedAt) for strict
|
|
340
|
+
CAS that 409s if a parent autosaved since; omit it and the CLI fetches the
|
|
341
|
+
current token at confirm time and warns that post-preview edits are unprotected.
|
|
342
|
+
"extract" is LLM-bound and can take ~30s; a 503 means Granola is not configured
|
|
343
|
+
server-side.
|
|
344
|
+
|
|
345
|
+
Class-ops notes: "events cancel" notifies families (chat + parent email blast +
|
|
346
|
+
credit notes + Slack); "events set-status --status CANCELED" is a silent status
|
|
347
|
+
change. Reschedule times are cohort-local wall-clock (zoneless).
|
|
348
|
+
|
|
349
|
+
Payout notes: amounts are integer cents. "payout items add" without --date
|
|
350
|
+
defaults the item date to the penultimate day of the invoice's cycle (its
|
|
351
|
+
endDate minus one day) and shows the computed date in the preview.
|
|
352
|
+
|
|
353
|
+
Auth notes: "auth login" runs the browser loopback flow for ADMIN, GUIDE, a GUARDIAN with
|
|
354
|
+
access:ai, or a KID using only Village home building. Guardian sessions are family-scoped and
|
|
355
|
+
cannot call /admin; KID sessions cannot call any non-Village API command. For a headless
|
|
356
|
+
cloud agent, the ADMIN-only "auth request" prints an approval URL to hand a Recess admin; after they
|
|
357
|
+
approve it in a browser, "auth poll" collects the 12h session. When it lapses, run
|
|
358
|
+
"auth request" again for a fresh link. Both paths yield the same session.
|
|
359
|
+
|
|
360
|
+
Skill notes: this CLI's own agent skill ships inside the npm package AND is served
|
|
361
|
+
by the server, so wording/Gotcha updates arrive without an npm release. "setup"
|
|
362
|
+
(or "setup --skill-only") installs the bundled copy, then upgrades it from the
|
|
363
|
+
server when the served bundle's minCliVersion allows — an older binary keeps the
|
|
364
|
+
bundled copy, and an unreachable server is not an error. "doctor" reports whether
|
|
365
|
+
a newer skill exists and names the command; it never writes.
|
|
366
|
+
|
|
367
|
+
Writes preview and exit 2 unless --confirm is supplied after explicit human approval.
|
|
368
|
+
Every preview includes an operationKey; confirmed writes must echo it with
|
|
369
|
+
--operation-key so an interrupted invocation can be retried without duplicating the write.
|
|
370
|
+
Environment overrides: RECESS_CLI_API_ORIGIN, RECESS_CLI_WEB_ORIGIN,
|
|
371
|
+
RECESS_CLI_OAUTH_CLIENT_ID, RECESS_CLI_COOKIE, RECESS_CLI_CONFIG,
|
|
372
|
+
RECESS_CLI_PROFILE, RECESS_CLI_FEEDBACK_ENDPOINT.
|
|
373
|
+
|
|
374
|
+
Every command that calls the Recess API, except auth commands, requires
|
|
375
|
+
--reason TEXT: a non-empty human-readable purpose of at most 1024 characters.`;
|
|
376
|
+
//# sourceMappingURL=help.js.map
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CliError } from "./errors.js";
|
|
2
|
+
export const RECESS_CLIENT_HEADER = "x-recess-client";
|
|
3
|
+
export const RECESS_CLIENT_CLI = "cli";
|
|
4
|
+
export const RECESS_CLIENT_CLI_UI = "cli-ui";
|
|
5
|
+
export const RECESS_REASON_HEADER = "x-recess-reason";
|
|
6
|
+
export function requireCliRequestReason(value) {
|
|
7
|
+
const reason = value?.trim();
|
|
8
|
+
if (!reason) {
|
|
9
|
+
throw new CliError("invalid_arguments", "Missing required --reason.");
|
|
10
|
+
}
|
|
11
|
+
if (reason.length > 1024) {
|
|
12
|
+
throw new CliError("invalid_arguments", "--reason must be 1024 characters or fewer.");
|
|
13
|
+
}
|
|
14
|
+
return reason;
|
|
15
|
+
}
|
|
16
|
+
export function markCliRequest(headers, reason, client = RECESS_CLIENT_CLI) {
|
|
17
|
+
headers.set(RECESS_CLIENT_HEADER, client);
|
|
18
|
+
if (reason)
|
|
19
|
+
headers.set(RECESS_REASON_HEADER, reason);
|
|
20
|
+
return headers;
|
|
21
|
+
}
|
|
22
|
+
export function cliRequestHeaders(init, reason, client = RECESS_CLIENT_CLI) {
|
|
23
|
+
return markCliRequest(new Headers(init), reason, client);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=http.js.map
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
3
|
import { parseArgs } from "./args.js";
|
|
4
4
|
import { runCommand } from "./cli.js";
|
|
5
|
+
import { deliverJson } from "./delivery.js";
|
|
5
6
|
import { CliError } from "./errors.js";
|
|
6
7
|
async function withInteractiveAdmissionStage(args) {
|
|
7
8
|
const parsed = parseArgs(args);
|
|
@@ -38,7 +39,8 @@ async function withInteractiveAdmissionStage(args) {
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
const argv = await withInteractiveAdmissionStage(process.argv.slice(2));
|
|
41
|
-
const
|
|
42
|
+
const parsedArgv = parseArgs(argv);
|
|
43
|
+
const json = parsedArgv.flags.has("json");
|
|
42
44
|
// The interactive console owns the terminal, so it runs before the JSON
|
|
43
45
|
// envelope machinery rather than through it.
|
|
44
46
|
if (argv[0] === "ui") {
|
|
@@ -57,11 +59,21 @@ if (argv[0] === "ui") {
|
|
|
57
59
|
}
|
|
58
60
|
try {
|
|
59
61
|
const data = await runCommand(argv);
|
|
60
|
-
|
|
62
|
+
const destination = parsedArgv.flags.get("deliver");
|
|
63
|
+
if (destination === true) {
|
|
64
|
+
throw new CliError("invalid_delivery", "--deliver requires a value.");
|
|
65
|
+
}
|
|
66
|
+
const envelope = { ok: true, data };
|
|
67
|
+
const delivery = await deliverJson(destination, envelope);
|
|
68
|
+
if (delivery.delivered) {
|
|
69
|
+
const acknowledgement = { ok: true, data: delivery };
|
|
70
|
+
process.stdout.write(`${json ? JSON.stringify(acknowledgement) : JSON.stringify(acknowledgement.data, null, 2)}\n`);
|
|
71
|
+
}
|
|
72
|
+
else if (typeof data === "object" && data && "help" in data && !json) {
|
|
61
73
|
process.stdout.write(`${String(data.help)}\n`);
|
|
62
74
|
}
|
|
63
75
|
else if (json) {
|
|
64
|
-
process.stdout.write(`${JSON.stringify(
|
|
76
|
+
process.stdout.write(`${JSON.stringify(envelope)}\n`);
|
|
65
77
|
}
|
|
66
78
|
else {
|
|
67
79
|
process.stdout.write(`${JSON.stringify(data, null, 2)}\n`);
|
package/dist/jobs.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
function jobsPath() {
|
|
5
|
+
return (process.env.RECESS_CLI_JOBS_PATH ??
|
|
6
|
+
path.join(os.homedir(), ".recess-cli", "jobs.jsonl"));
|
|
7
|
+
}
|
|
8
|
+
async function readEvents() {
|
|
9
|
+
try {
|
|
10
|
+
return (await fs.readFile(jobsPath(), "utf8"))
|
|
11
|
+
.split("\n")
|
|
12
|
+
.filter(Boolean)
|
|
13
|
+
.flatMap((line) => {
|
|
14
|
+
try {
|
|
15
|
+
return [JSON.parse(line)];
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (error.code === "ENOENT")
|
|
24
|
+
return [];
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function appendJobEvent(event) {
|
|
29
|
+
const file = jobsPath();
|
|
30
|
+
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
31
|
+
let stored = event;
|
|
32
|
+
const serialized = JSON.stringify(stored);
|
|
33
|
+
if (serialized.length > 64 * 1024 && event.result !== undefined) {
|
|
34
|
+
stored = {
|
|
35
|
+
...event,
|
|
36
|
+
result: {
|
|
37
|
+
omitted: true,
|
|
38
|
+
reason: "Result exceeded the 64 KiB local job-ledger limit.",
|
|
39
|
+
bytes: Buffer.byteLength(serialized),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
await fs.appendFile(file, `${JSON.stringify(stored)}\n`, { mode: 0o600 });
|
|
44
|
+
await fs.chmod(file, 0o600);
|
|
45
|
+
}
|
|
46
|
+
function foldJobs(events) {
|
|
47
|
+
const jobs = new Map();
|
|
48
|
+
for (const event of events) {
|
|
49
|
+
const prior = jobs.get(event.jobId);
|
|
50
|
+
jobs.set(event.jobId, { ...event, events: (prior?.events ?? 0) + 1 });
|
|
51
|
+
}
|
|
52
|
+
return Array.from(jobs.values()).sort((left, right) => right.timestamp.localeCompare(left.timestamp));
|
|
53
|
+
}
|
|
54
|
+
export async function listJobs(limit = 20) {
|
|
55
|
+
const jobs = foldJobs(await readEvents());
|
|
56
|
+
return {
|
|
57
|
+
jobs: jobs.slice(0, limit),
|
|
58
|
+
truncated: jobs.length > limit,
|
|
59
|
+
total: jobs.length,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export async function getJob(jobId) {
|
|
63
|
+
const history = (await readEvents()).filter((event) => event.jobId === jobId);
|
|
64
|
+
return { job: foldJobs(history)[0] ?? null, history };
|
|
65
|
+
}
|
|
66
|
+
export async function pruneJobs(olderThanDays) {
|
|
67
|
+
const events = await readEvents();
|
|
68
|
+
const cutoff = Date.now() - olderThanDays * 24 * 60 * 60 * 1000;
|
|
69
|
+
const kept = events.filter((event) => Date.parse(event.timestamp) >= cutoff);
|
|
70
|
+
const file = jobsPath();
|
|
71
|
+
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
72
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
73
|
+
await fs.writeFile(temporary, kept.length > 0
|
|
74
|
+
? `${kept.map((event) => JSON.stringify(event)).join("\n")}\n`
|
|
75
|
+
: "", { mode: 0o600 });
|
|
76
|
+
await fs.rename(temporary, file);
|
|
77
|
+
await fs.chmod(file, 0o600);
|
|
78
|
+
return { removed: events.length - kept.length, remaining: kept.length };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=jobs.js.map
|
package/dist/skill-update.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { cliRequestHeaders } from "./http.js";
|
|
3
4
|
import { skillDestinations } from "./setup.js";
|
|
4
5
|
/**
|
|
5
6
|
* Compare dotted numeric versions. Deliberately hand-rolled rather than adding a
|
|
@@ -88,7 +89,7 @@ export async function updateSkillFromServer(input) {
|
|
|
88
89
|
let bundle;
|
|
89
90
|
try {
|
|
90
91
|
const response = await fetch(new URL("/auth/admin-cli/skill/", input.apiOrigin), {
|
|
91
|
-
headers: input.sessionCookie ? { cookie: input.sessionCookie } :
|
|
92
|
+
headers: cliRequestHeaders(input.sessionCookie ? { cookie: input.sessionCookie } : undefined, input.reason),
|
|
92
93
|
signal: AbortSignal.timeout(10_000),
|
|
93
94
|
});
|
|
94
95
|
if (!response.ok) {
|
package/dist/ui/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { render } from "ink";
|
|
|
3
3
|
import { RecessAdminApi } from "../api.js";
|
|
4
4
|
import { resolveConfig } from "../config.js";
|
|
5
5
|
import { CliError } from "../errors.js";
|
|
6
|
+
import { RECESS_CLIENT_CLI_UI } from "../http.js";
|
|
6
7
|
import { App } from "./app.js";
|
|
7
8
|
/**
|
|
8
9
|
* The interactive console. Kept off the JSON path on purpose: agents parse
|
|
@@ -14,7 +15,7 @@ export async function runUi() {
|
|
|
14
15
|
if (!config.sessionCookie) {
|
|
15
16
|
throw new CliError("auth_required", "No Recess CLI session found. Run `recess auth login`.");
|
|
16
17
|
}
|
|
17
|
-
const api = new RecessAdminApi(config);
|
|
18
|
+
const api = new RecessAdminApi(config, undefined, RECESS_CLIENT_CLI_UI);
|
|
18
19
|
const instance = render(_jsx(App, { api: api }));
|
|
19
20
|
await instance.waitUntilExit();
|
|
20
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "recess-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Safe Recess administration and family AI tools from the command line.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"typecheck": "tsgo --noEmit",
|
|
49
49
|
"format": "oxfmt --ignore-path .oxfmtignore --check",
|
|
50
50
|
"format:fix": "oxfmt --ignore-path .oxfmtignore",
|
|
51
|
-
"lint": "oxlint --type-aware src/*.ts",
|
|
52
|
-
"lint:fix": "oxlint --type-aware --fix src/*.ts",
|
|
51
|
+
"lint": "oxlint --type-aware src/*.ts src/commands/*.ts",
|
|
52
|
+
"lint:fix": "oxlint --type-aware --fix src/*.ts src/commands/*.ts",
|
|
53
53
|
"test": "vitest run",
|
|
54
54
|
"install-local": "pnpm run build && make install-local",
|
|
55
55
|
"install-persistent": "pnpm run build && make install-persistent",
|
|
@@ -11,26 +11,30 @@ Use the installed `recess` command for Recess work. This small skill is shared b
|
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
command -v recess
|
|
14
|
-
recess --json doctor
|
|
14
|
+
recess --json doctor --reason "Verify CLI connectivity, identity, and scope"
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
`doctor` reports the active API origin, authenticated user, and CLI scope. Do not assume a role from the request. Use the scope returned by the server.
|
|
18
18
|
|
|
19
|
+
If the reported scope is `village_home`, use only `recess village build`, `village library`, `village objects`, and `village render`. That session is intentionally unable to fetch the guardian or admin skill catalogs or call ordinary Recess API routes; Village applies the user's own-home and object-ownership checks to every build or read.
|
|
20
|
+
|
|
19
21
|
Then load the guidance for the purpose of the work:
|
|
20
22
|
|
|
21
23
|
```bash
|
|
22
24
|
# Parent or guardian work: kids, schedules, goals, todos, progress, memory, Rocky
|
|
23
|
-
recess --json skills guardian get recess-family --all-references
|
|
25
|
+
recess --json skills guardian get recess-family --all-references --reason "Load family workflow guidance"
|
|
24
26
|
|
|
25
27
|
# Research, author, validate, or apply a goal or reusable goal template
|
|
26
|
-
recess --json skills guardian get recess-goal-authoring --all-references
|
|
28
|
+
recess --json skills guardian get recess-goal-authoring --all-references --reason "Load goal authoring guidance"
|
|
27
29
|
|
|
28
30
|
# Staff-only school operations
|
|
29
|
-
recess --json skills admin get recess-admin --all-references
|
|
31
|
+
recess --json skills admin get recess-admin --all-references --reason "Load staff operations guidance"
|
|
30
32
|
```
|
|
31
33
|
|
|
32
34
|
Use `skills guardian list` or `skills admin list` when the needed skill is not obvious. Never substitute one audience for the other. A guardian session cannot fetch the admin catalog; an admin may fetch either catalog.
|
|
33
35
|
|
|
36
|
+
For machine-readable discovery, use `recess --json agent-context`; for a smaller syntax surface, use `recess --json help <noun> [verb]`. Unknown commands, flags, duplicate non-repeatable flags, missing flag values, and extra positional arguments fail explicitly.
|
|
37
|
+
|
|
34
38
|
## Authentication
|
|
35
39
|
|
|
36
40
|
- Workstation: `recess --json auth login` opens Recess SSO.
|
|
@@ -49,23 +53,31 @@ Always pass `--json`. Stdout contains one object:
|
|
|
49
53
|
- Failure: `{"ok":false,"error":{"code":"...","message":"...","details":{...}}}`, exit 1.
|
|
50
54
|
- Write awaiting approval: `confirmation_required`, exit 2, with `details.preview` and `details.requiredFlag`.
|
|
51
55
|
|
|
56
|
+
Every command-driven Recess API call except `auth` requires `--reason "..."`: a specific,
|
|
57
|
+
human-readable purpose from 1 to 1024 characters. The server records it in the CLI request audit
|
|
58
|
+
ledger. Reuse the invocation's same reason across its preflight and execution requests. The
|
|
59
|
+
human-only `recess ui` console is exempt.
|
|
60
|
+
|
|
52
61
|
Every write is two-step:
|
|
53
62
|
|
|
54
63
|
1. Run without `--confirm`.
|
|
55
64
|
2. Show the human the complete preview, including `preview.details`.
|
|
56
65
|
3. Ask for explicit approval of that exact action.
|
|
57
|
-
4. Rerun the unchanged command with `--confirm
|
|
66
|
+
4. Rerun the unchanged command with `--confirm --operation-key <operationKey>`. If the preview includes an `approvalToken`, pass it unchanged too.
|
|
58
67
|
|
|
59
|
-
Any changed target, payload, local file, server revision, amount, recipient, or consequence requires a new preview and new approval. Never infer approval from the original request.
|
|
68
|
+
Any changed target, payload, local file, server revision, amount, recipient, or consequence requires a new preview and new approval. Never infer approval from the original request. If a confirmed invocation is interrupted, retry the unchanged command with the same operation key; never mint a new one for an uncertain write. Inspect recovery state with `recess --json jobs get <operation-key>`.
|
|
60
69
|
|
|
61
70
|
## Shared constraints
|
|
62
71
|
|
|
63
|
-
- Use high-level CLI commands. The raw escape hatch is GET-only:
|
|
72
|
+
- Use high-level CLI commands. The raw escape hatch is GET-only:
|
|
73
|
+
`recess --json request get /path --reason "Inspect the exact API resource needed for this task"`.
|
|
64
74
|
- Resolve names to exact IDs before writes. Stop on ambiguous matches.
|
|
65
75
|
- Money uses integer cents.
|
|
66
76
|
- Keep dates in the exact format required by command help.
|
|
67
77
|
- Treat a 401 or `auth_required` as an authentication problem. A transport-level `fetch failed` is a network/sandbox problem, not proof that the session expired.
|
|
68
|
-
-
|
|
78
|
+
- Use `profile list|save|use` or global `--profile` for named environments. `--deliver file:<path>` atomically stores one JSON envelope locally; authenticated webhook delivery is intentionally unavailable.
|
|
79
|
+
- `feedback submit` records CLI friction under an operation key and optionally forwards it when an upstream endpoint is configured.
|
|
80
|
+
- Run scoped help for syntax; load the audience skill for workflow meaning.
|
|
69
81
|
|
|
70
82
|
## Updating this shared skill
|
|
71
83
|
|