@junoflow/cli 0.14.0 → 0.17.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 +310 -117
- package/app-client.js +95 -9
- package/package.json +2 -2
- package/src/api.js +154 -15
- package/src/authoring-skills.js +2 -6
- package/src/commands/app-init.js +1 -1
- package/src/commands/approval-wait.js +215 -0
- package/src/commands/flow-init.js +1 -1
- package/src/commands/init.js +1 -1
- package/src/commands/permissions.js +47 -0
- package/src/commands/run-follow.js +68 -0
- package/src/commands/session-approve.js +22 -3
- package/src/commands/session.js +103 -0
- package/src/commands/skill.js +28 -19
- package/src/commands/{job-run.js → task-run.js} +36 -31
- package/src/commands/tool.js +23 -5
- package/src/commands/whoami.js +38 -0
- package/src/exit.js +6 -2
- package/src/help.js +143 -22
- package/src/index.js +127 -60
- package/src/prompt.js +9 -0
- package/src/verbs.js +6 -1
- package/verbs.json +435 -13
- package/src/commands/agent-skill-install.js +0 -64
- package/src/installed-skill.js +0 -55
package/README.md
CHANGED
|
@@ -45,11 +45,24 @@ writes the descriptions and classifies each command's effect.
|
|
|
45
45
|
|
|
46
46
|
### Help
|
|
47
47
|
|
|
48
|
-
| Command | Shows
|
|
49
|
-
| ---------------------------- |
|
|
50
|
-
| `juno --help`
|
|
51
|
-
| `juno <group> --help` | the group's commands, each with its effect and the first sentence of its description. Offline, it lists the commands alone. |
|
|
52
|
-
| `juno <group> <verb> --help` | the tool's full description, its effect, its input schema, and what the positional and flags fill in. Needs the instance.
|
|
48
|
+
| Command | Shows |
|
|
49
|
+
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
50
|
+
| `juno --help` (or `juno`) | the guide to working with Juno, every group and top-level command, and the skill index. See below. |
|
|
51
|
+
| `juno <group> --help` | the skills to read first, then the group's commands, each with its effect and the first sentence of its description. Offline, it lists the commands alone. |
|
|
52
|
+
| `juno <group> <verb> --help` | the skills to read first, the tool's full description, its effect, its input schema, and what the positional and flags fill in. Needs the instance. |
|
|
53
|
+
|
|
54
|
+
`juno --help` is where an agent starts, with nothing installed: after the usage
|
|
55
|
+
lines comes the instance's guide (what Juno is made of, how to work with it from
|
|
56
|
+
the CLI, what only the user does), then each group and top-level command by one
|
|
57
|
+
line (the working-copy commands are in their group's help), and the skills
|
|
58
|
+
`juno skill <name>` prints, each by its first sentence. The guide and the skills
|
|
59
|
+
come from the instance; offline the rest is still printed, with one line on how
|
|
60
|
+
to connect and the reason on stderr. Bare `juno` prints the same and exits 0.
|
|
61
|
+
|
|
62
|
+
A group's or a command's help starts with a `Read first:` line when the instance
|
|
63
|
+
names skills for it — `Read first: juno skill diagnose state` above
|
|
64
|
+
`juno state --help`'s commands. Run it before the command: one call prints them
|
|
65
|
+
all.
|
|
53
66
|
|
|
54
67
|
`juno <group>` on its own prints the group's help and exits 2. An unknown
|
|
55
68
|
command suggests the closest one: `juno stat get` answers
|
|
@@ -65,9 +78,9 @@ Every command has one effect:
|
|
|
65
78
|
- **act** does something now (calls a service, presses a button, sets a value,
|
|
66
79
|
starts a run, executes code), with nothing to roll back to.
|
|
67
80
|
|
|
68
|
-
`config set`
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
`config set` is **local**: it writes a file on your machine and changes nothing
|
|
82
|
+
on the instance. So is `app dev`, which serves an app working copy on localhost
|
|
83
|
+
and never connects to an instance.
|
|
71
84
|
|
|
72
85
|
No command of a lower effect is a string prefix of a command of a higher one.
|
|
73
86
|
Claude Code matches a Bash permission rule by prefix, so an allowlist can list
|
|
@@ -86,27 +99,32 @@ positional; its input is a whole document (`device write`) or has no id
|
|
|
86
99
|
| --------------------------------------- | ------------- | ----------------------------------- | ------ |
|
|
87
100
|
| `juno discover <query> [--kind k]…` | `discover` | `query`; `--kind` → `kinds` | read |
|
|
88
101
|
| `juno related <kind>:<id> [--degree n]` | `get_related` | `kind`, `id`; `--degree` → `degree` | read |
|
|
89
|
-
| `juno skill [<name
|
|
102
|
+
| `juno skill [<name>...] [--json]` | none | skill name | read |
|
|
90
103
|
| `juno ask ["<prompt>"]` | none | the prompt | act |
|
|
91
|
-
| `juno
|
|
104
|
+
| `juno whoami` | none | none | read |
|
|
105
|
+
| `juno version` | none | none | read |
|
|
106
|
+
| `juno permissions` | none | none | read |
|
|
92
107
|
|
|
93
108
|
`related` splits its positional on the first `:` only, so
|
|
94
109
|
`endpoint:ha:light.hallway` is kind `endpoint`, id `ha:light.hallway`.
|
|
95
110
|
|
|
96
111
|
**`state`**
|
|
97
112
|
|
|
98
|
-
| Command
|
|
99
|
-
|
|
|
100
|
-
| `juno state get`
|
|
101
|
-
| `juno state get-history`
|
|
102
|
-
| `juno state get-layers`
|
|
103
|
-
| `juno state evaluate-level`
|
|
104
|
-
| `juno state preview-layers`
|
|
105
|
-
| `juno state
|
|
106
|
-
| `juno state
|
|
107
|
-
| `juno state
|
|
108
|
-
| `juno state
|
|
109
|
-
| `juno state
|
|
113
|
+
| Command | Tool | Positional | Effect |
|
|
114
|
+
| -------------------------------- | ------------------------------------- | ---------- | ------ |
|
|
115
|
+
| `juno state get` | `get_state` | `id` | read |
|
|
116
|
+
| `juno state get-history` | `get_state_history` | `id` | read |
|
|
117
|
+
| `juno state get-layers` | `get_state_layers` | `id` | read |
|
|
118
|
+
| `juno state evaluate-level` | `evaluate_level` | — | read |
|
|
119
|
+
| `juno state preview-layers` | `edit_state_layers`, `dry_run: true` | `id` | read |
|
|
120
|
+
| `juno state list-layer-versions` | `list_state_layer_versions` | `id` | read |
|
|
121
|
+
| `juno state create` | `create_state` | `id` | change |
|
|
122
|
+
| `juno state edit-layers` | `edit_state_layers`, `dry_run: false` | `id` | change |
|
|
123
|
+
| `juno state restore-layers` | `restore_state_layers` | `id` | change |
|
|
124
|
+
| `juno state set-value` | `set_state_value` | `id` | act |
|
|
125
|
+
| `juno state claim` | `claim_state` | `id` | act |
|
|
126
|
+
| `juno state release` | `release_state` | `id` | act |
|
|
127
|
+
| `juno state delete` | `delete_state` | `id` | act |
|
|
110
128
|
|
|
111
129
|
`preview-layers` and `edit-layers` call the same tool. The preview always sends
|
|
112
130
|
`dry_run: true`, so a permission rule can allow the preview and not the edit; an
|
|
@@ -114,12 +132,23 @@ positional; its input is a whole document (`device write`) or has no id
|
|
|
114
132
|
|
|
115
133
|
**`flow`**
|
|
116
134
|
|
|
117
|
-
| Command
|
|
118
|
-
|
|
|
119
|
-
| `juno flow get`
|
|
120
|
-
| `juno flow
|
|
121
|
-
| `juno flow
|
|
122
|
-
| `juno flow
|
|
135
|
+
| Command | Tool | Positional | Effect |
|
|
136
|
+
| --------------------------- | ---------------------- | ---------- | ------ |
|
|
137
|
+
| `juno flow get` | `get_flow` | `id` | read |
|
|
138
|
+
| `juno flow list-versions` | `list_flow_versions` | `id` | read |
|
|
139
|
+
| `juno flow get-next-fire` | `get_next_fire` | `flow_id` | read |
|
|
140
|
+
| `juno flow restore-version` | `restore_flow_version` | `id` | change |
|
|
141
|
+
| `juno flow set-enabled` | `set_flow_enabled` | `flow_id` | change |
|
|
142
|
+
| `juno flow rename` | `rename_flow` | `id` | change |
|
|
143
|
+
| `juno flow trigger` | `trigger_flow` | `flow_id` | act |
|
|
144
|
+
| `juno flow fire-trigger` | `fire_trigger` | `flow_id` | act |
|
|
145
|
+
| `juno flow delete` | `delete_flow` | `id` | act |
|
|
146
|
+
|
|
147
|
+
Every `restore-version` row, and `state restore-layers`, takes the version as
|
|
148
|
+
`--version N`, numbered as its `list-versions` row lists them. `flow rename`
|
|
149
|
+
takes `--slug` (the new id) and `--name`, either or both, and answers the flows
|
|
150
|
+
whose targets named the old id as `broken_callers`. `get-next-fire` takes
|
|
151
|
+
`--trigger` to answer one schedule trigger rather than all of the flow's.
|
|
123
152
|
|
|
124
153
|
The group's working-copy commands (`flow init`, `gen-types`, `check`, `deploy`,
|
|
125
154
|
`pull`) are in [Flows as files](#flows-as-files).
|
|
@@ -131,14 +160,47 @@ The group's working-copy commands (`flow init`, `gen-types`, `check`, `deploy`,
|
|
|
131
160
|
| `juno run list` | `list_runs` | — | read |
|
|
132
161
|
| `juno run get` | `get_run` | `run_id` | read |
|
|
133
162
|
|
|
163
|
+
`run get --follow` streams the run's steps to stderr as they finish, then prints
|
|
164
|
+
the run as `run get` does once it has ended. Ctrl-C stops following (exit 130);
|
|
165
|
+
the run goes on.
|
|
166
|
+
|
|
167
|
+
**`timer`** and **`activity`**
|
|
168
|
+
|
|
169
|
+
| Command | Tool | Positional | Effect |
|
|
170
|
+
| -------------------- | --------------- | ---------- | ------ |
|
|
171
|
+
| `juno timer list` | `list_timers` | — | read |
|
|
172
|
+
| `juno activity list` | `list_activity` | — | read |
|
|
173
|
+
|
|
174
|
+
`timer list` is the Upcoming page: every flow schedule trigger and integration
|
|
175
|
+
schedule, soonest first. `activity list` is the dashboard's run timeline, the
|
|
176
|
+
last `--hours` (24), of every flow or `--flow <id>`, the newest `--limit` (200).
|
|
177
|
+
|
|
134
178
|
**`integration`**
|
|
135
179
|
|
|
136
|
-
| Command
|
|
137
|
-
|
|
|
138
|
-
| `juno integration get`
|
|
139
|
-
| `juno integration
|
|
140
|
-
| `juno integration
|
|
141
|
-
| `juno integration
|
|
180
|
+
| Command | Tool | Positional | Effect |
|
|
181
|
+
| ----------------------------------- | ------------------------------ | ------------- | ------ |
|
|
182
|
+
| `juno integration get` | `get_integration` | `id` | read |
|
|
183
|
+
| `juno integration list-versions` | `list_integration_versions` | `id` | read |
|
|
184
|
+
| `juno integration preview` | `preview_integration` | — | read |
|
|
185
|
+
| `juno integration list-invocations` | `list_integration_invocations` | `id` | read |
|
|
186
|
+
| `juno integration get-deliveries` | `get_integration_deliveries` | `id` | read |
|
|
187
|
+
| `juno integration get-usage` | `get_integration_usage` | `id` | read |
|
|
188
|
+
| `juno integration list-registry` | `list_registry` | — | read |
|
|
189
|
+
| `juno integration configure` | `configure_integration` | `id` | change |
|
|
190
|
+
| `juno integration restore-version` | `restore_integration_version` | `id` | change |
|
|
191
|
+
| `juno integration set-enabled` | `set_integration_enabled` | `id` | change |
|
|
192
|
+
| `juno integration bind-webhook` | `bind_integration_webhook` | `id` | change |
|
|
193
|
+
| `juno integration install` | `install_integration` | — | act |
|
|
194
|
+
| `juno integration invoke-action` | `invoke_integration_action` | `id` | act |
|
|
195
|
+
| `juno integration run-schedule` | `run_integration_schedule` | `integration` | act |
|
|
196
|
+
| `juno integration upgrade` | `upgrade_integration` | `id` | act |
|
|
197
|
+
| `juno integration uninstall` | `uninstall_integration` | `id` | act |
|
|
198
|
+
|
|
199
|
+
`upgrade` takes the new tag or commit as `--ref`; `preview` and `install` take
|
|
200
|
+
their `{url, ref?, path?}` as `--input`. `invoke-action` takes the action as
|
|
201
|
+
`--action` and its params as `--input '{"params": {…}}'`; `bind-webhook` takes
|
|
202
|
+
`--slot` and `--webhook`; `list-invocations` and `get-deliveries` take
|
|
203
|
+
`--limit`.
|
|
142
204
|
|
|
143
205
|
The group's working-copy commands (`integration init`, `gen-types`,
|
|
144
206
|
`verify-types`, `check`, `deploy`, `pull`) are in
|
|
@@ -146,28 +208,68 @@ The group's working-copy commands (`integration init`, `gen-types`,
|
|
|
146
208
|
|
|
147
209
|
**`device`**
|
|
148
210
|
|
|
149
|
-
| Command
|
|
150
|
-
|
|
|
151
|
-
| `juno device list`
|
|
152
|
-
| `juno device get`
|
|
153
|
-
| `juno device preview`
|
|
154
|
-
| `juno device
|
|
155
|
-
| `juno device
|
|
156
|
-
| `juno device
|
|
211
|
+
| Command | Tool | Positional | Effect |
|
|
212
|
+
| ----------------------------- | ------------------------ | ---------- | ------ |
|
|
213
|
+
| `juno device list` | `list_devices` | — | read |
|
|
214
|
+
| `juno device get` | `get_device` | `id` | read |
|
|
215
|
+
| `juno device preview` | `preview_device` | — | read |
|
|
216
|
+
| `juno device list-versions` | `list_device_versions` | `id` | read |
|
|
217
|
+
| `juno device write` | `write_device` | — | change |
|
|
218
|
+
| `juno device restore-version` | `restore_device_version` | `id` | change |
|
|
219
|
+
| `juno device suspend` | `suspend_device` | `id` | act |
|
|
220
|
+
| `juno device release` | `release_device` | `id` | act |
|
|
221
|
+
| `juno device delete` | `delete_device` | `id` | act |
|
|
157
222
|
|
|
158
223
|
**`control`**
|
|
159
224
|
|
|
160
|
-
| Command
|
|
161
|
-
|
|
|
162
|
-
| `juno control
|
|
163
|
-
| `juno control
|
|
164
|
-
| `juno control
|
|
225
|
+
| Command | Tool | Positional | Effect |
|
|
226
|
+
| ------------------------------ | ------------------------- | ---------- | ------ |
|
|
227
|
+
| `juno control get` | `get_control` | `id` | read |
|
|
228
|
+
| `juno control list` | `list_controls` | — | read |
|
|
229
|
+
| `juno control get-history` | `get_control_history` | `id` | read |
|
|
230
|
+
| `juno control get-activity` | `get_control_activity` | `id` | read |
|
|
231
|
+
| `juno control list-versions` | `list_control_versions` | `id` | read |
|
|
232
|
+
| `juno control write` | `write_control` | — | change |
|
|
233
|
+
| `juno control restore-version` | `restore_control_version` | `id` | change |
|
|
234
|
+
| `juno control use` | `use_control` | `id` | act |
|
|
235
|
+
| `juno control extend` | `extend_control` | `id` | act |
|
|
236
|
+
| `juno control release` | `release_control` | `id` | act |
|
|
237
|
+
| `juno control delete` | `delete_control` | `id` | act |
|
|
238
|
+
|
|
239
|
+
**`app`**
|
|
240
|
+
|
|
241
|
+
| Command | Tool | Positional | Effect |
|
|
242
|
+
| --------------------------- | ---------------------- | ---------- | ------ |
|
|
243
|
+
| `juno app get` | `get_app` | `id` | read |
|
|
244
|
+
| `juno app list-invocations` | `list_app_invocations` | `id` | read |
|
|
245
|
+
| `juno app list-versions` | `list_app_versions` | `id` | read |
|
|
246
|
+
| `juno app list-links` | `list_app_links` | `id` | read |
|
|
247
|
+
| `juno app restore-version` | `restore_app_version` | `id` | change |
|
|
248
|
+
| `juno app set-enabled` | `set_app_enabled` | `id` | change |
|
|
249
|
+
| `juno app create-link` | `create_app_link` | `id` | act |
|
|
250
|
+
| `juno app revoke-link` | `revoke_app_link` | `id` | act |
|
|
251
|
+
| `juno app delete` | `delete_app` | `id` | act |
|
|
252
|
+
|
|
253
|
+
An app link lets whoever holds it use the app without logging in. `create-link`
|
|
254
|
+
takes `--name` and `--expires-at` (RFC 3339); `revoke-link` takes `--link <id>`
|
|
255
|
+
and waits for a person, as a delete does. Each link is answered with its `url`,
|
|
256
|
+
never its bare token. The working-copy commands are in
|
|
257
|
+
[Working copies](#working-copies).
|
|
165
258
|
|
|
166
259
|
**`finding`**
|
|
167
260
|
|
|
168
|
-
| Command
|
|
169
|
-
|
|
|
170
|
-
| `juno finding
|
|
261
|
+
| Command | Tool | Positional | Effect |
|
|
262
|
+
| -------------------------- | --------------------- | ---------- | ------ |
|
|
263
|
+
| `juno finding list` | `list_findings` | — | read |
|
|
264
|
+
| `juno finding get` | `get_finding` | `slug` | read |
|
|
265
|
+
| `juno finding get-history` | `get_finding_history` | `slug` | read |
|
|
266
|
+
| `juno finding dismiss` | `dismiss_finding` | `slug` | act |
|
|
267
|
+
|
|
268
|
+
`finding list` shows open findings of every owner — flows, integrations,
|
|
269
|
+
devices, states and tasks — each naming its source as `owner_kind`, `owner` and
|
|
270
|
+
`owner_name`; `--status all` adds cleared ones, and `--owner-kind`, `--owner`
|
|
271
|
+
and `--severity` (a floor) narrow it. `get-history` and `dismiss` take `--key`
|
|
272
|
+
for a keyed finding; `get-history` also takes `--limit`.
|
|
171
273
|
|
|
172
274
|
**`webhook`**
|
|
173
275
|
|
|
@@ -177,32 +279,73 @@ The group's working-copy commands (`integration init`, `gen-types`,
|
|
|
177
279
|
| `juno webhook get-deliveries` | `get_webhook_deliveries` | `id` | read |
|
|
178
280
|
| `juno webhook write` | `write_webhook` | `id` | change |
|
|
179
281
|
| `juno webhook fire` | `fire_webhook` | `id` | act |
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
|
186
|
-
|
|
|
187
|
-
| `juno
|
|
188
|
-
| `juno
|
|
189
|
-
| `juno
|
|
190
|
-
| `juno
|
|
282
|
+
| `juno webhook delete` | `delete_webhook` | `id` | act |
|
|
283
|
+
| `juno webhook rotate-token` | `rotate_webhook_token` | `id` | act |
|
|
284
|
+
|
|
285
|
+
**`task`** (tasks)
|
|
286
|
+
|
|
287
|
+
| Command | Tool | Positional | Effect |
|
|
288
|
+
| ------------------------------------- | --------------------- | ---------- | ------ |
|
|
289
|
+
| `juno task list` | `list_tasks` | — | read |
|
|
290
|
+
| `juno task get-runs` | `get_task_runs` | `id` | read |
|
|
291
|
+
| `juno task get-occurrence` | `get_task_occurrence` | `id` | read |
|
|
292
|
+
| `juno task inbox` | `list_task_inbox` | — | read |
|
|
293
|
+
| `juno task write` | `write_task` | `id` | change |
|
|
294
|
+
| `juno task delete` | `delete_task` | `id` | act |
|
|
295
|
+
| `juno task rotate-token` | `rotate_task_token` | `id` | act |
|
|
296
|
+
| `juno task open` | `command_task` | `id` | act |
|
|
297
|
+
| `juno task snooze` | `command_task` | `id` | act |
|
|
298
|
+
| `juno task set-due` | `command_task` | `id` | act |
|
|
299
|
+
| `juno task complete` | `command_task` | `id` | act |
|
|
300
|
+
| `juno task skip` | `command_task` | `id` | act |
|
|
301
|
+
| `juno task cancel` | `command_task` | `id` | act |
|
|
302
|
+
| `juno task run [<url>] -- <command>…` | none | ping URL | act |
|
|
303
|
+
| `juno task ping [<url>]` | none | ping URL | act |
|
|
304
|
+
|
|
305
|
+
The six verb commands name the work with `--key` (the schedule's when omitted)
|
|
306
|
+
and take their verb's fields as flags: `open` `--at` `--within` `--reason`,
|
|
307
|
+
`snooze` `--until`, `set-due` `--at`, `complete` `--outcome` `--note` and
|
|
308
|
+
`--check <n>` (repeatable; the checklist numbers `get-occurrence` shows), `skip`
|
|
309
|
+
`--note`, `cancel` `--reason`. `inbox` is the people's due work, `mine` only for
|
|
310
|
+
a signed-in user linked to a person.
|
|
311
|
+
|
|
312
|
+
**`series`**
|
|
313
|
+
|
|
314
|
+
| Command | Tool | Positional | Effect |
|
|
315
|
+
| ----------------- | ------------ | ---------- | ------ |
|
|
316
|
+
| `juno series get` | `get_series` | `id` | read |
|
|
191
317
|
|
|
192
318
|
**`credential`**
|
|
193
319
|
|
|
194
|
-
| Command | Tool
|
|
195
|
-
| -------------------------- |
|
|
196
|
-
| `juno credential list` | `list_credentials`
|
|
197
|
-
| `juno credential
|
|
320
|
+
| Command | Tool | Positional | Effect |
|
|
321
|
+
| -------------------------- | ------------------- | ------------- | ------ |
|
|
322
|
+
| `juno credential list` | `list_credentials` | — | read |
|
|
323
|
+
| `juno credential delete` | `delete_credential` | `id` | act |
|
|
324
|
+
| `juno credential set <id>` | none | credential id | act |
|
|
198
325
|
|
|
199
326
|
**`person`**
|
|
200
327
|
|
|
201
|
-
| Command
|
|
202
|
-
|
|
|
203
|
-
| `juno person list`
|
|
204
|
-
| `juno person get`
|
|
205
|
-
| `juno person write`
|
|
328
|
+
| Command | Tool | Positional | Effect |
|
|
329
|
+
| -------------------------- | --------------- | ---------- | ------ |
|
|
330
|
+
| `juno person list` | `list_people` | — | read |
|
|
331
|
+
| `juno person get` | `get_person` | `id` | read |
|
|
332
|
+
| `juno person write` | `write_person` | `id` | change |
|
|
333
|
+
| `juno person test-contact` | `test_contact` | `id` | act |
|
|
334
|
+
| `juno person delete` | `delete_person` | `id` | act |
|
|
335
|
+
|
|
336
|
+
`test-contact` takes `--contact <id>` and really sends the test message.
|
|
337
|
+
|
|
338
|
+
**`approval`**
|
|
339
|
+
|
|
340
|
+
| Command | Tool | Positional | Effect |
|
|
341
|
+
| ------------------------- | ---------------- | ----------- | ------ |
|
|
342
|
+
| `juno approval list` | `list_approvals` | — | read |
|
|
343
|
+
| `juno approval get` | `get_approval` | `id` | read |
|
|
344
|
+
| `juno approval wait <id>` | none | approval id | read |
|
|
345
|
+
|
|
346
|
+
`list` takes `--status` (`pending`, `executed`, `denied`, …). There is no
|
|
347
|
+
command that approves one: see
|
|
348
|
+
[Destructive commands wait for a person](#destructive-commands-wait-for-a-person).
|
|
206
349
|
|
|
207
350
|
**`ha`** (Home Assistant)
|
|
208
351
|
|
|
@@ -211,8 +354,22 @@ The group's working-copy commands (`integration init`, `gen-types`,
|
|
|
211
354
|
| `juno ha get-entity` | `get_entity` | `entity_id` | read |
|
|
212
355
|
| `juno ha get-entity-history` | `get_entity_history` | `entity_id` | read |
|
|
213
356
|
| `juno ha list-services` | `list_services` | — | read |
|
|
357
|
+
| `juno ha list-entities` | `list_entities` | — | read |
|
|
358
|
+
| `juno ha get-diagnostics` | `get_ha_diagnostics` | — | read |
|
|
214
359
|
| `juno ha call-service` | `call_service` | — | act |
|
|
215
360
|
|
|
361
|
+
`list-entities` takes `--query` and `--limit`.
|
|
362
|
+
|
|
363
|
+
**`mqtt`**
|
|
364
|
+
|
|
365
|
+
| Command | Tool | Positional | Effect |
|
|
366
|
+
| --------------------------- | ---------------------- | ---------- | ------ |
|
|
367
|
+
| `juno mqtt list-topics` | `list_topics` | — | read |
|
|
368
|
+
| `juno mqtt get-diagnostics` | `get_mqtt_diagnostics` | — | read |
|
|
369
|
+
|
|
370
|
+
`list-topics` takes `--query` (a topic filter with `+`/`#`, or a substring),
|
|
371
|
+
`--sort` (`recent`, `topic`, `count`) and `--limit`.
|
|
372
|
+
|
|
216
373
|
**`script`**
|
|
217
374
|
|
|
218
375
|
| Command | Tool | Positional | Effect |
|
|
@@ -226,10 +383,18 @@ under `files` by its basename and makes it the `entry`.
|
|
|
226
383
|
|
|
227
384
|
| Command | Tool | Positional | Effect |
|
|
228
385
|
| ----------------------------- | ---- | ------------- | ------ |
|
|
386
|
+
| `juno session list` | none | none | read |
|
|
387
|
+
| `juno session get <id>` | none | session id | read |
|
|
388
|
+
| `juno session export <id>` | none | session id | read |
|
|
389
|
+
| `juno session rate <id>` | none | session id | change |
|
|
229
390
|
| `juno session approve <id>` | none | session id | act |
|
|
391
|
+
| `juno session cancel <id>` | none | session id | act |
|
|
230
392
|
| `juno config set url <url>` | none | `url <url>` | local |
|
|
231
393
|
| `juno config set token <key>` | none | `token <key>` | local |
|
|
232
394
|
|
|
395
|
+
`session list` takes `--rating`, `--profile` and `--limit`; `session get` takes
|
|
396
|
+
`--transcript`; `session rate` takes `--rating up|down|addressed|none`.
|
|
397
|
+
|
|
233
398
|
There is no command that calls a tool by name. One permission rule for such a
|
|
234
399
|
command would allow every act, so each tool has its own command instead, and a
|
|
235
400
|
tool added to the server needs a CLI release to reach.
|
|
@@ -268,6 +433,10 @@ the same bytes. A tool that fails in its own terms answers `{"error": "…"}`;
|
|
|
268
433
|
that is printed on stdout like any answer, and the exit code is 1. Warnings,
|
|
269
434
|
progress and notes go to standard error.
|
|
270
435
|
|
|
436
|
+
When the instance refuses a call — that `{"error": "…"}`, or input the tool
|
|
437
|
+
rejects (exit 2) — and a skill explains the tool, the last line on standard
|
|
438
|
+
error names it: `see: juno skill state`. Read it before trying again.
|
|
439
|
+
|
|
271
440
|
`--jq <expr>` runs the answer through [`jq`](https://jqlang.org), which must be
|
|
272
441
|
on `PATH` (`jq -c` off a terminal, plain `jq` on one). A filter given this way
|
|
273
442
|
stays inside the command's own permission rule, where a pipe to `jq` would need
|
|
@@ -277,19 +446,44 @@ its own. A missing `jq` or an expression `jq` rejects exits 2.
|
|
|
277
446
|
|
|
278
447
|
One table for the whole CLI, the working-copy commands included:
|
|
279
448
|
|
|
280
|
-
| Code | When
|
|
281
|
-
| ---- |
|
|
282
|
-
| 0 | Success
|
|
283
|
-
| 1 | A tool answer with a top-level string `error`, a failed check or deploy, or any other failure
|
|
284
|
-
| 2 | Usage: an unknown command or flag, bad `--input`, input the instance rejects, a bad `--jq`
|
|
285
|
-
| 3 | The instance is unreachable
|
|
286
|
-
| 4 | A working-copy `deploy` or `check`, any kind: the instance changed since the working copy was pulled
|
|
287
|
-
| 5 | `juno ask` / `session approve`: the turn is still running
|
|
288
|
-
| 6 | `juno ask` / `session approve`: the assistant is waiting for an answer or an approval
|
|
449
|
+
| Code | When |
|
|
450
|
+
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
451
|
+
| 0 | Success |
|
|
452
|
+
| 1 | A tool answer with a top-level string `error`, a failed check or deploy, or any other failure |
|
|
453
|
+
| 2 | Usage: an unknown command or flag, bad `--input`, input the instance rejects, a bad `--jq` |
|
|
454
|
+
| 3 | The instance is unreachable |
|
|
455
|
+
| 4 | A working-copy `deploy` or `check`, any kind: the instance changed since the working copy was pulled |
|
|
456
|
+
| 5 | `juno ask` / `session approve`: the turn is still running; a destructive command or `approval wait`: nobody decided the approval within `--wait` |
|
|
457
|
+
| 6 | `juno ask` / `session approve`: the assistant is waiting for an answer or an approval |
|
|
458
|
+
| 130 | Ctrl-C while a destructive command waits for its approval (the request stays open), or while `run get --follow` follows (the run goes on) |
|
|
289
459
|
|
|
290
460
|
An instance that does not serve a tool the CLI names is older than the CLI; that
|
|
291
461
|
is also exit 2, and the message says so.
|
|
292
462
|
|
|
463
|
+
### Destructive commands wait for a person
|
|
464
|
+
|
|
465
|
+
A command that deletes something, rotates a token or revokes an app link (every
|
|
466
|
+
`delete` command, `juno integration uninstall`, both `rotate-token` commands,
|
|
467
|
+
`juno app revoke-link`, and any tool the instance marks `destructive`) runs
|
|
468
|
+
nothing by itself. The instance holds the request until a person approves it in
|
|
469
|
+
Juno, in the browser; no command, tool or API key can approve it. The command
|
|
470
|
+
prints what needs approving and where on stderr, then waits for the decision:
|
|
471
|
+
|
|
472
|
+
```
|
|
473
|
+
$ juno task delete smoke
|
|
474
|
+
Approval needed: delete task "smoke" (Smoke test).
|
|
475
|
+
Approve or deny in Juno: https://juno.example/approvals/apr_7Kq2…
|
|
476
|
+
waiting up to 300s… (Ctrl-C leaves the request open: juno approval wait apr_7Kq2…)
|
|
477
|
+
{"deleted":true,"id":"smoke","ok":true,"approval":{"id":"apr_7Kq2…","approved_by":"user:victor"}}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Approved, it prints the action's result with `approval` beside it and exits as
|
|
481
|
+
the action would (0, or 1 on an `error`). Denied, expired, or failed when it
|
|
482
|
+
ran: `{"error": "denied by user:victor"}` and the like, exit 1.
|
|
483
|
+
`--wait <seconds>` (default 300; 0 does not wait) bounds the wait; when it runs
|
|
484
|
+
out the request stays open, the `approval_required` answer is printed and the
|
|
485
|
+
exit code is 5. `juno approval wait <id>` picks the wait up again.
|
|
486
|
+
|
|
293
487
|
### `juno ask` and `juno session approve`
|
|
294
488
|
|
|
295
489
|
`juno ask` sends a prompt to Juno's in-app assistant through the
|
|
@@ -338,15 +532,15 @@ exits 1 without sending anything otherwise. Any other message sent to a session
|
|
|
338
532
|
waiting for an approval denies it, and the assistant sees the message as the
|
|
339
533
|
reason.
|
|
340
534
|
|
|
341
|
-
### `juno
|
|
535
|
+
### `juno task run`
|
|
342
536
|
|
|
343
|
-
Wraps a scheduled command so its runs are reported to
|
|
344
|
-
(`juno
|
|
537
|
+
Wraps a scheduled command so its runs are reported to a task's ping URL
|
|
538
|
+
(`juno task write` answers it as `url`):
|
|
345
539
|
|
|
346
540
|
```bash
|
|
347
|
-
juno
|
|
348
|
-
juno
|
|
349
|
-
|
|
541
|
+
juno task run https://juno.example/ping/<token> -- ./backup.sh --full
|
|
542
|
+
juno task run --url-file .secrets/juno-tasks/backup -- ./backup.sh --full
|
|
543
|
+
JUNO_TASK_URL=https://juno.example/ping/<token> juno task run -- python3 check.py
|
|
350
544
|
```
|
|
351
545
|
|
|
352
546
|
The command runs exactly as it would unwrapped: same stdin, the same stdout and
|
|
@@ -355,33 +549,33 @@ signal `N`; 127, or 126 for a file that is not executable, when it cannot be
|
|
|
355
549
|
started). Everything after `--` is the command's, flags included. Juno gets a
|
|
356
550
|
`start`, then the exit status with the last 64 KiB of stdout and stderr, paired
|
|
357
551
|
by a run id. The URL comes from the argument, else `--url-file` (keeps the token
|
|
358
|
-
out of `ps`), else `$
|
|
552
|
+
out of `ps`), else `$JUNO_TASK_URL`; nothing else is read — no instance config,
|
|
359
553
|
no API key. A report that fails is retried once and then dropped silently
|
|
360
554
|
(`--verbose` prints one line): Juno turns a run it never heard about into an
|
|
361
555
|
overdue finding by itself. `SIGINT`, `SIGTERM` and `SIGHUP` are passed on to the
|
|
362
556
|
command.
|
|
363
557
|
|
|
364
|
-
The wrapper never times a command out: a run that hangs stays open, and the
|
|
558
|
+
The wrapper never times a command out: a run that hangs stays open, and the task
|
|
365
559
|
goes down once its start plus grace has passed. A wrapper killed outright leaves
|
|
366
560
|
the run open the same way.
|
|
367
561
|
|
|
368
|
-
### `juno
|
|
562
|
+
### `juno task ping`
|
|
369
563
|
|
|
370
564
|
Sends one report, for a task with no command to wrap:
|
|
371
565
|
|
|
372
566
|
```bash
|
|
373
|
-
juno
|
|
374
|
-
juno
|
|
375
|
-
juno
|
|
376
|
-
juno
|
|
567
|
+
juno task ping --url-file .secrets/juno-tasks/digest # success
|
|
568
|
+
juno task ping --url-file .secrets/juno-tasks/digest --start --rid r1
|
|
569
|
+
juno task ping --url-file .secrets/juno-tasks/digest --exit 3 --rid r1
|
|
570
|
+
juno task ping --url-file .secrets/juno-tasks/digest --fail
|
|
377
571
|
```
|
|
378
572
|
|
|
379
|
-
The URL comes from the same three places as `juno
|
|
573
|
+
The URL comes from the same three places as `juno task run`'s. `--log` sends a
|
|
380
574
|
log report, and `--rid` pairs a start with its finish. A report that still fails
|
|
381
575
|
after one retry exits 1 with the reason.
|
|
382
576
|
|
|
383
|
-
See [
|
|
384
|
-
|
|
577
|
+
See [Tasks](https://boivie.github.io/juno/tasks/) for creating the task, the
|
|
578
|
+
ping protocol, and systemd and crontab examples.
|
|
385
579
|
|
|
386
580
|
### `juno credential set`
|
|
387
581
|
|
|
@@ -402,26 +596,30 @@ Claude Code. For the same reason there is no tool that writes a credential.
|
|
|
402
596
|
### `juno skill`
|
|
403
597
|
|
|
404
598
|
`juno skill` lists the skills the assistant can load, one
|
|
405
|
-
`<name> — <description>` line each
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
599
|
+
`<name> — <description>` line each; a description starts with when to load the
|
|
600
|
+
skill. `juno skill <name>` prints one skill's body, and `juno skill <a> <b> …`
|
|
601
|
+
several, each under a `===== <name> =====` line. `--json` prints the instance's
|
|
602
|
+
JSON instead (an array for several names). An unknown name fails the call with
|
|
603
|
+
nothing printed. The skills are the in-app assistant's, rendered for a reader
|
|
604
|
+
outside Juno: where the assistant reads a tool name (`edit_state_layers`), you
|
|
605
|
+
read the command in front of it (`juno state edit-layers`), or what to do in a
|
|
606
|
+
working copy instead (`npm run deploy` for `submit_code`).
|
|
411
607
|
|
|
412
|
-
### `juno
|
|
608
|
+
### `juno permissions`
|
|
413
609
|
|
|
414
610
|
```bash
|
|
415
|
-
juno
|
|
416
|
-
juno
|
|
417
|
-
juno
|
|
418
|
-
juno agent-skill install --working-copy # + the npm scripts (run it in a working copy)
|
|
419
|
-
juno agent-skill install --agents-md >> AGENTS.md # for a harness that reads AGENTS.md
|
|
611
|
+
juno permissions # every read command
|
|
612
|
+
juno permissions --allow-change # + every change command
|
|
613
|
+
juno permissions --working-copy # + the npm scripts (run it in a working copy)
|
|
420
614
|
```
|
|
421
615
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
616
|
+
There is nothing to install for a coding agent: `juno --help` is the primer,
|
|
617
|
+
served live by the instance, and `juno skill` the topic skills. A line in your
|
|
618
|
+
`AGENTS.md` or `CLAUDE.md` such as "Juno home automation is operated with the
|
|
619
|
+
`juno` CLI; run `juno --help` first" is all an agent needs to find it.
|
|
620
|
+
|
|
621
|
+
`juno permissions` prints a Claude Code permission block on stdout, rendered by
|
|
622
|
+
the instance (`GET /api/agent-permissions`):
|
|
425
623
|
|
|
426
624
|
```json
|
|
427
625
|
{"permissions":{"allow":["Bash(juno discover:*)","Bash(juno related:*)","Bash(juno state get:*)",…]}}
|
|
@@ -437,13 +635,8 @@ trust whatever that `package.json` says the script runs, so put them in the
|
|
|
437
635
|
working copy's `.claude/settings.json`, never in user-wide settings. **An `act`
|
|
438
636
|
command is never in the block**: it always prompts. Add one by hand if you want
|
|
439
637
|
to, for example, let the agent press a test button. A command added in a later
|
|
440
|
-
version prompts until you regenerate the block.
|
|
441
|
-
|
|
442
|
-
The skill is short and stable; what changes per instance comes from `juno skill`
|
|
443
|
-
and `--help` at run time. It records the version it was rendered at, and
|
|
444
|
-
`juno skill`, `juno flow init` and `juno integration init` say on stderr when
|
|
445
|
-
the instance serves a newer one. `--agents-md` prints the same text as an
|
|
446
|
-
`AGENTS.md` section and writes nothing; `--json` prints the instance's answer.
|
|
638
|
+
version prompts until you regenerate the block. `--json` prints the instance's
|
|
639
|
+
answer.
|
|
447
640
|
|
|
448
641
|
## Choosing an instance
|
|
449
642
|
|