@hagicode/cli 0.1.2 → 0.2.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 +471 -114
- package/dist/chunks/main-ESbnuxzK.js +138 -0
- package/dist/cli.js +1 -1
- package/dist/main.js +1 -1
- package/package.json +13 -8
- package/dist/chunks/main-BXoLU5FX.js +0 -47
package/README.md
CHANGED
|
@@ -1,199 +1,555 @@
|
|
|
1
1
|
# HagiCode CLI
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@hagicode/cli)
|
|
3
|
+
[](https://www.npmjs.com/package/@hagicode/cli)
|
|
4
|
+
[](https://www.npmjs.com/package/@hagicode/cli)
|
|
5
|
+
[](https://www.npmjs.com/package/@hagicode/cli)
|
|
6
|
+
[](https://nodejs.org/)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
`@hagicode/cli` provides the published `hagi` command, which lets you drive a HagiCode backend from a terminal, scripts, or an AI agent without opening the app. Manage projects, proposals (generate, execute, archive, and send), vaults and their files, chat sessions, HagiTasks, scheduled plans, and skills (local list, enable, disable and uninstall, gallery search and install, and trusted providers). Every command supports a shared `--json` output for scripting, and an embedded Hagi skill under [`skills/`](skills/) guides agent workflows.
|
|
6
9
|
|
|
7
10
|
## Requirements
|
|
8
11
|
|
|
9
|
-
- Node.js
|
|
10
|
-
- npm compatible with `10.9.2`
|
|
12
|
+
- Node.js 24+
|
|
11
13
|
- Access to a HagiCode backend API
|
|
12
14
|
|
|
13
15
|
## Installation
|
|
14
16
|
|
|
17
|
+
Use the published npm package for normal CLI usage. You do not need to clone this repository to run `hagi`.
|
|
18
|
+
|
|
19
|
+
### Zero-install usage
|
|
20
|
+
|
|
15
21
|
```bash
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
npm run build
|
|
22
|
+
npx @hagicode/cli --help
|
|
23
|
+
npx @hagicode/cli project list --json
|
|
19
24
|
```
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
### Project-local install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @hagicode/cli
|
|
30
|
+
npx @hagicode/cli proposal list --json
|
|
31
|
+
```
|
|
23
32
|
|
|
24
|
-
|
|
33
|
+
### Optional global install
|
|
25
34
|
|
|
26
35
|
```bash
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
npm install -g @hagicode/cli
|
|
37
|
+
hagi --help
|
|
29
38
|
```
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
The examples below use `hagi ...` after the package is available on your `PATH`. For one-off execution, replace `hagi` with `npx @hagicode/cli`.
|
|
32
43
|
|
|
33
44
|
```bash
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
hagi --help
|
|
46
|
+
hagi project list --json
|
|
47
|
+
hagi proposal list --json
|
|
48
|
+
hagi vault list --json
|
|
49
|
+
hagi chat list --json
|
|
50
|
+
hagi hagitask list
|
|
51
|
+
hagi hagitask create --title "Auto commit" --project-id <project-id> --prompt-id auto-compose-commit.en-US
|
|
36
52
|
```
|
|
37
53
|
|
|
38
|
-
##
|
|
54
|
+
## Embedded Skills
|
|
39
55
|
|
|
40
|
-
|
|
41
|
-
`repos/cli/.github/workflows/npm-publish.yml` now publishes two channels with GitHub Actions OIDC plus provenance:
|
|
56
|
+
If you are integrating Hagi CLI into an agent workflow, start from the embedded skill package in this repository:
|
|
42
57
|
|
|
43
|
-
-
|
|
44
|
-
-
|
|
58
|
+
- [`skills/README.md`](skills/README.md) - repository-level discovery entrypoint
|
|
59
|
+
- [`skills/hagi/SKILL.md`](skills/hagi/SKILL.md) - canonical Hagi skill contract
|
|
60
|
+
- [`skills/hagi/references/`](skills/hagi/references/) - focused package usage, session data, proposal flow, maintainer, and validation guidance
|
|
45
61
|
|
|
46
|
-
|
|
62
|
+
The same folder is also shipped as the HagiCode server's built-in skill `hagi`, so an agent running inside a HagiCode session can answer questions about the user's own projects, proposals, sessions, vaults and plans without setup. Edit `skills/hagi/` here; the built-in copy is recopied from it.
|
|
47
63
|
|
|
48
|
-
|
|
49
|
-
2. Add at least one release note category label:
|
|
50
|
-
- `breaking-change` for breaking release note callouts
|
|
51
|
-
- `feature` or `enhancement` for the `Features` section
|
|
52
|
-
- `bug` for the `Fixes` section
|
|
53
|
-
- `docs` or `documentation` for the `Documentation` section
|
|
54
|
-
- `chore` or `dependencies` for the `Maintenance` section
|
|
55
|
-
3. Add `skip-changelog` only when the PR should stay out of the draft notes entirely, such as pure CI noise or internal housekeeping.
|
|
56
|
-
4. Merge the labeled PR into `main`, or update the PR while it is open.
|
|
57
|
-
5. Let Release Drafter refresh the GitHub draft release name, tag, and categorized notes.
|
|
58
|
-
6. Review the draft release in GitHub before creating the next stable tag.
|
|
64
|
+
## Shared Runtime Flags
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
Every command family supports the same global runtime flags:
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
- `--base-url <url>`
|
|
69
|
+
- `--token <token>`
|
|
70
|
+
- `--lang <lang>`
|
|
71
|
+
- `--json`
|
|
63
72
|
|
|
64
|
-
|
|
65
|
-
The following planned release labels were still missing and should be created before maintainers rely on the full contract:
|
|
73
|
+
Example:
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
- `breaking-change`
|
|
71
|
-
- `feature`
|
|
72
|
-
- `docs`
|
|
73
|
-
- `chore`
|
|
74
|
-
- `dependencies`
|
|
75
|
-
- `skip-changelog`
|
|
75
|
+
```bash
|
|
76
|
+
hagi --base-url https://api.example.com --token "$HAGI_TOKEN" project list --json
|
|
77
|
+
```
|
|
76
78
|
|
|
77
|
-
|
|
79
|
+
## Connection Setup
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
Every operation command resolves the backend base URL on each invocation, in this order:
|
|
80
82
|
|
|
81
|
-
1.
|
|
82
|
-
2.
|
|
83
|
-
3.
|
|
84
|
-
4. Keep the package access level public so `npm publish --access public` can succeed.
|
|
83
|
+
1. `--base-url <url>` flag
|
|
84
|
+
2. `HAGI_API_BASE_URL` environment variable
|
|
85
|
+
3. `baseUrl` in the local config file: `$XDG_CONFIG_HOME/hagi/config.json`, or `~/.config/hagi/config.json` when `XDG_CONFIG_HOME` is unset
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"baseUrl": "https://hagicode.example.com"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
87
92
|
|
|
88
|
-
|
|
93
|
+
If none of the three is set, the command exits with code `2` and sends no backend request.
|
|
89
94
|
|
|
90
|
-
|
|
95
|
+
Operation commands send requests without a credential by default. Pass `--token` (or set `HAGI_API_TOKEN`) only when your backend requires one.
|
|
91
96
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
When the backend cannot be reached, the CLI names the base URL and exits with code `60`. A backend HTTP error is reported differently: it prints the HTTP status and the backend error message, and exits with a status-mapped code.
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
$ hagi --base-url http://127.0.0.1:1 project list
|
|
101
|
+
Cannot reach HagiCode backend at http://127.0.0.1:1. Check that the backend is running and the base URL is correct.
|
|
102
|
+
|
|
103
|
+
$ echo $?
|
|
104
|
+
60
|
|
100
105
|
```
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
## Command Overview
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
hagi
|
|
111
|
+
|-- project list | repositories | create | update | delete
|
|
112
|
+
|-- proposal list | create | optimize-description | generate | annotate | execute | archive | status | complete | send
|
|
113
|
+
|-- vault list | create | update | delete
|
|
114
|
+
| `-- files list | preview
|
|
115
|
+
|-- chat list | create | archive | delete | send
|
|
116
|
+
|-- hagitask list | schema | create | send
|
|
117
|
+
|-- plan list | get | create | update | enable | disable | delete | run
|
|
118
|
+
`-- skills local list | enable | disable | uninstall
|
|
119
|
+
gallery search | detail | install
|
|
120
|
+
trusted list | upsert | delete | reset
|
|
121
|
+
```
|
|
105
122
|
|
|
106
|
-
|
|
123
|
+
## Example Setup
|
|
107
124
|
|
|
108
|
-
|
|
109
|
-
2. Run the local verification commands above.
|
|
110
|
-
3. Commit and push the release-ready source tree.
|
|
111
|
-
4. Publish the matching GitHub draft release for the stable tag.
|
|
112
|
-
5. Confirm the GitHub Actions summary shows build, typecheck, test, package inspection, version stamping, and `npm publish --tag latest --provenance --access public`.
|
|
125
|
+
The examples in the family sections run in order against a local backend. They assume:
|
|
113
126
|
|
|
114
|
-
|
|
127
|
+
- the backend listens on `http://127.0.0.1:35167`
|
|
128
|
+
- `hagi` is on `PATH`
|
|
129
|
+
- `json_field` reads one field from `--json` output
|
|
115
130
|
|
|
116
|
-
|
|
131
|
+
```bash
|
|
132
|
+
export HAGI_API_BASE_URL=http://127.0.0.1:35167
|
|
133
|
+
json_field() { node -pe "JSON.parse(require('node:fs').readFileSync(0, 'utf8'))$1"; }
|
|
117
134
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
| `HAGI_API_TOKEN` | Bearer token attached as `Authorization: Bearer <token>`. |
|
|
122
|
-
| `HAGI_API_LANG` | Shared `Accept-Language` header value. |
|
|
135
|
+
mkdir -p /tmp/cli-examples/repos/cli
|
|
136
|
+
PROJECT_ID=$(hagi project create --name "CLI Examples" --path /tmp/cli-examples --json | json_field '.project.id')
|
|
137
|
+
```
|
|
123
138
|
|
|
124
|
-
|
|
139
|
+
## Project Commands
|
|
125
140
|
|
|
126
|
-
|
|
127
|
-
- `--token <token>`
|
|
128
|
-
- `--lang <lang>`
|
|
129
|
-
- `--json`
|
|
141
|
+
List projects through the aggregation endpoint:
|
|
130
142
|
|
|
131
|
-
|
|
143
|
+
```bash
|
|
144
|
+
hagi project list
|
|
145
|
+
hagi project list --json
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
List the repositories of one project. The read-only command prints each repository's name, path relative to the project root, display name, type and branch. These paths are the values a proposal's repository scope names:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
hagi project repositories --id "$PROJECT_ID"
|
|
152
|
+
hagi project repositories --id "$PROJECT_ID" --json
|
|
153
|
+
```
|
|
132
154
|
|
|
133
|
-
The
|
|
155
|
+
Create a project. The backend creates the directory if it does not exist. The new id is read from `project.id`:
|
|
134
156
|
|
|
135
157
|
```bash
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
158
|
+
DEMO_PROJECT_ID=$(hagi project create \
|
|
159
|
+
--name "CLI Demo" \
|
|
160
|
+
--path /tmp/cli-demo \
|
|
161
|
+
--description "Automation sandbox" \
|
|
162
|
+
--json | json_field '.project.id')
|
|
139
163
|
```
|
|
140
164
|
|
|
141
|
-
|
|
165
|
+
Update only part of a project record. The CLI resolves current project data first so omitted fields are preserved:
|
|
142
166
|
|
|
143
|
-
|
|
167
|
+
```bash
|
|
168
|
+
hagi project update --id "$DEMO_PROJECT_ID" --description "Updated description"
|
|
169
|
+
hagi project update --id "$DEMO_PROJECT_ID" --name "CLI Demo renamed"
|
|
170
|
+
```
|
|
144
171
|
|
|
145
|
-
|
|
172
|
+
Delete the demo project:
|
|
146
173
|
|
|
147
|
-
|
|
174
|
+
```bash
|
|
175
|
+
hagi project delete --id "$DEMO_PROJECT_ID"
|
|
176
|
+
```
|
|
148
177
|
|
|
149
178
|
## Proposal Commands
|
|
150
179
|
|
|
151
|
-
|
|
180
|
+
List proposal sessions for the example project:
|
|
152
181
|
|
|
153
182
|
```bash
|
|
154
|
-
hagi proposal list --project-id
|
|
183
|
+
hagi proposal list --project-id "$PROJECT_ID"
|
|
155
184
|
hagi proposal list --include-archived --json
|
|
156
185
|
```
|
|
157
186
|
|
|
158
|
-
|
|
187
|
+
Every proposal names its writable repositories and its read-only repositories. Take the paths from `hagi project repositories --id "$PROJECT_ID" --json`, and begin the chief complaint with a `Repository scope` section: a `Writable repositories:` list and a `Read-only repositories:` list, one `- <path>` entry per line, with `- none` for an empty list. The scope is a text convention in the chief complaint; `proposal create` has no scope flags. The format and a worked example are in [`skills/hagi/references/proposal-flow.md`](skills/hagi/references/proposal-flow.md#repository-scope).
|
|
188
|
+
|
|
189
|
+
Create a proposal session only. The new id is read from `session.sessionId`:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
PROPOSAL_ID=$(hagi proposal create \
|
|
193
|
+
--project-id "$PROJECT_ID" \
|
|
194
|
+
--chief-complaint "Repository scope
|
|
195
|
+
Writable repositories:
|
|
196
|
+
- repos/cli
|
|
197
|
+
Read-only repositories:
|
|
198
|
+
- none
|
|
199
|
+
|
|
200
|
+
Add CLI completion for session workflows" \
|
|
201
|
+
--default-title \
|
|
202
|
+
--json | json_field '.session.sessionId')
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Update status and send a follow-up message:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
hagi proposal status --session-id "$PROPOSAL_ID" --status Reviewing
|
|
209
|
+
hagi proposal send --session-id "$PROPOSAL_ID" --content "Please continue"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The next steps are AI lifecycle actions and need a backend with an AI executor. `optimize-description` writes the optimized title, description, and proposal name to the session in one backend step, and `generate` needs that name. Without the AI executor, or before the name exists, the backend answers with a 400 that names the missing state:
|
|
159
213
|
|
|
160
214
|
```bash
|
|
161
|
-
hagi proposal
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
215
|
+
hagi proposal optimize-description --session-id "$PROPOSAL_ID" --description "Add CLI completion for session workflows" --default-title
|
|
216
|
+
hagi proposal generate --session-id "$PROPOSAL_ID" --proposal-content-language en-US --enable-explore-mode
|
|
217
|
+
|
|
218
|
+
cat > annotations.json <<'EOF'
|
|
219
|
+
{"files":[{"fileName":"proposal.md","filePath":"proposal.md"}]}
|
|
220
|
+
EOF
|
|
221
|
+
hagi proposal annotate --session-id "$PROPOSAL_ID" --input annotations.json
|
|
222
|
+
cat annotations.json | hagi proposal annotate --session-id "$PROPOSAL_ID" --input - --json
|
|
223
|
+
|
|
224
|
+
hagi proposal execute --session-id "$PROPOSAL_ID"
|
|
225
|
+
hagi proposal complete --session-id "$PROPOSAL_ID"
|
|
226
|
+
hagi proposal archive --session-id "$PROPOSAL_ID"
|
|
165
227
|
```
|
|
166
228
|
|
|
167
|
-
|
|
229
|
+
### Explicit Lifecycle Sequence
|
|
230
|
+
|
|
231
|
+
The CLI keeps proposal lifecycle actions explicit and non-interactive. Each command maps to one backend action:
|
|
232
|
+
|
|
233
|
+
1. `hagi proposal list`
|
|
234
|
+
2. `hagi proposal create`
|
|
235
|
+
3. `hagi proposal optimize-description --session-id <session-id> --description <text>` (sets the title, description, and proposal name)
|
|
236
|
+
4. `hagi proposal generate --session-id <session-id> --proposal-content-language <language>` (optionally `--enable-explore-mode`)
|
|
237
|
+
5. `hagi proposal annotate --session-id <session-id> --input <file>` (optional review loop)
|
|
238
|
+
6. `hagi proposal execute --session-id <session-id>`
|
|
239
|
+
7. `hagi proposal complete --session-id <session-id>`
|
|
240
|
+
8. `hagi proposal archive --session-id <session-id>`
|
|
241
|
+
|
|
242
|
+
The CLI may suggest a next command, but it never chains later lifecycle APIs automatically.
|
|
243
|
+
|
|
244
|
+
Each command maps to one backend action. The CLI may suggest a next command, but it never chains later lifecycle APIs automatically.
|
|
245
|
+
|
|
246
|
+
## Vault Commands
|
|
247
|
+
|
|
248
|
+
Create a vault with a local folder to browse. The new id is read from `vault.id`:
|
|
168
249
|
|
|
169
250
|
```bash
|
|
170
|
-
|
|
251
|
+
mkdir -p /tmp/cli-vault-notes/docs
|
|
252
|
+
printf '# Notes\n' > /tmp/cli-vault-notes/docs/readme.md
|
|
253
|
+
|
|
254
|
+
VAULT_ID=$(hagi vault create \
|
|
255
|
+
--name "Main Notes" \
|
|
256
|
+
--type folder \
|
|
257
|
+
--physical-path /tmp/cli-vault-notes \
|
|
258
|
+
--json | json_field '.vault.id')
|
|
171
259
|
```
|
|
172
260
|
|
|
173
|
-
|
|
261
|
+
List registered vaults:
|
|
174
262
|
|
|
175
263
|
```bash
|
|
176
|
-
hagi
|
|
177
|
-
hagi
|
|
264
|
+
hagi vault list
|
|
265
|
+
hagi vault list --json
|
|
178
266
|
```
|
|
179
267
|
|
|
180
|
-
|
|
268
|
+
Update only part of a vault record. The CLI resolves the current vault snapshot first so omitted fields are preserved:
|
|
181
269
|
|
|
182
270
|
```bash
|
|
183
|
-
hagi
|
|
271
|
+
hagi vault update --id "$VAULT_ID" --name "Renamed Vault"
|
|
184
272
|
```
|
|
185
273
|
|
|
186
|
-
|
|
274
|
+
Browse vault files and preview supported content:
|
|
187
275
|
|
|
188
|
-
|
|
276
|
+
```bash
|
|
277
|
+
hagi vault files list --id "$VAULT_ID"
|
|
278
|
+
hagi vault files list --id "$VAULT_ID" --path docs --json
|
|
279
|
+
hagi vault files preview --id "$VAULT_ID" --path docs/readme.md
|
|
280
|
+
```
|
|
189
281
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
282
|
+
Delete a vault and request backend cleanup of its local files:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
hagi vault delete --id "$VAULT_ID" --delete-local-files --json
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Chat Commands
|
|
289
|
+
|
|
290
|
+
Create a chat session. The new id is read from `session.sessionId`:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
CHAT_ID=$(hagi chat create \
|
|
294
|
+
--title "Repository Q&A" \
|
|
295
|
+
--project-id "$PROJECT_ID" \
|
|
296
|
+
--json | json_field '.session.sessionId')
|
|
297
|
+
```
|
|
195
298
|
|
|
196
|
-
|
|
299
|
+
List chat sessions:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
hagi chat list --active-only
|
|
303
|
+
hagi chat list --include-archived --json
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Send a message, archive, and delete:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
hagi chat send --session-id "$CHAT_ID" --content "Summarize the current diff"
|
|
310
|
+
hagi chat archive --session-id "$CHAT_ID"
|
|
311
|
+
hagi chat delete --session-id "$CHAT_ID"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## HagiTask Commands
|
|
315
|
+
|
|
316
|
+
A HagiTask is a preset task with a structured input. Read its schema first, write the input from the schema, then create the session. `hagitask list` shows the active tasks:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
hagi hagitask list
|
|
320
|
+
hagi hagitask list --json
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
`hagitask schema` shows one task's target scope, commands, parameters, requirements and scenes. Each required parameter is marked `yes`. The `--json` output adds the input JSON Schema and an example request body:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
hagi hagitask schema --task-id compose-commit
|
|
327
|
+
hagi hagitask schema --task-id compose-commit --json
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Write the input file. Its keys are the parameter keys the schema lists under `inputs`, plus the `targets` and `targetScopes` keys when the schema's scope lists targets. For example, `input.json` for a task with one required input:
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"inputs": {
|
|
335
|
+
"commitScope": "cli"
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Create the session from that task and input. The new id is read from `session.sessionId`:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
HAGITASK_ID=$(hagi hagitask create \
|
|
344
|
+
--title "Auto compose commit" \
|
|
345
|
+
--project-id "$PROJECT_ID" \
|
|
346
|
+
--task-id compose-commit \
|
|
347
|
+
--input input.json \
|
|
348
|
+
--repository-path repos/cli \
|
|
349
|
+
--need-push \
|
|
350
|
+
--target-branch-mode new-custom \
|
|
351
|
+
--target-branch-name feature/cli-completion \
|
|
352
|
+
--json | json_field '.session.sessionId')
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Use `--prompt-id` instead of `--task-id` for a prompt template with no structured input. `--input` needs `--task-id`. Input is read from a file, or from stdin with `--input -`. The CLI only checks that the input is a JSON object. The backend checks the keys and values. It rejects a key that the schema does not list, and a missing required value. Its error is printed unchanged, and no session is reported as created. `--hero-selection-mode` takes `first` (the default) or `random`.
|
|
356
|
+
|
|
357
|
+
The backend must have a hero available for the task's script. Without one, `hagitask create` fails with a 400 whose error is `no-executable-hero`.
|
|
358
|
+
|
|
359
|
+
Send a follow-up message to the HagiTask session:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
hagi hagitask send --session-id "$HAGITASK_ID" --content "Retry with a smaller diff"
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**Migration from AutoTask:** `hagi hagitask create` and `hagi hagitask send` replace `hagi autotask create` and `hagi autotask send`. There is no `autotask` alias, so an `autotask` command now fails as an unknown command. Read the task schema with `hagitask schema` to find the input keys that replace the old flags.
|
|
366
|
+
|
|
367
|
+
## Plan Commands
|
|
368
|
+
|
|
369
|
+
A scheduled plan saves a proposal or HagiTask input with a schedule and an agent pool. The backend runs it on that schedule. `plan list` and `plan get` show the plans that exist:
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
hagi plan list
|
|
373
|
+
hagi plan list --json
|
|
374
|
+
hagi plan get --id "$PLAN_ID"
|
|
375
|
+
hagi plan get --id "$PLAN_ID" --json | jq .plan
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
`plan list` prints one row per plan with its schedule summary, and an explicit message when there are none. `--json` prints `{ "plans": [...] }`, where each entry carries `id`, `type`, `name`, `enabled`, `state`, `nextRunAt`, `schedule`, `agentPool` and `payload` exactly as the backend returns them. `plan get --json` prints `{ "plan": {...} }` with the same fields.
|
|
379
|
+
|
|
380
|
+
### Create a plan
|
|
381
|
+
|
|
382
|
+
`plan create` reads a plan document with `--input <file>` or `--input -` for stdin. A recurring HagiTask plan:
|
|
383
|
+
|
|
384
|
+
```json
|
|
385
|
+
{
|
|
386
|
+
"type": "hagitask",
|
|
387
|
+
"name": "Nightly review",
|
|
388
|
+
"enabled": true,
|
|
389
|
+
"schedule": {
|
|
390
|
+
"mode": "recurring",
|
|
391
|
+
"timeZone": "Asia/Shanghai",
|
|
392
|
+
"startDate": "2026-05-01",
|
|
393
|
+
"endDate": "2026-05-31",
|
|
394
|
+
"timeOfDay": "02:00",
|
|
395
|
+
"repeat": { "rule": "daily", "weekdays": [] }
|
|
396
|
+
},
|
|
397
|
+
"agentPool": { "strategy": "random", "agents": [ { "heroId": "5de02573-0000-4000-8000-000000000001" } ] },
|
|
398
|
+
"payload": {
|
|
399
|
+
"projectId": "11111111-2222-3333-4444-555555555555",
|
|
400
|
+
"presetTaskId": "nightly-review"
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
A one-time proposal plan runs once at `runAt` and has no time zone or repeat fields:
|
|
406
|
+
|
|
407
|
+
```json
|
|
408
|
+
{
|
|
409
|
+
"type": "proposal",
|
|
410
|
+
"name": "Weekly triage",
|
|
411
|
+
"schedule": { "mode": "once", "runAt": "2026-06-12T10:30:00Z" },
|
|
412
|
+
"payload": {
|
|
413
|
+
"title": "Weekly triage",
|
|
414
|
+
"chiefComplaint": "Triage the open issues and propose the next sprint",
|
|
415
|
+
"projectId": "11111111-2222-3333-4444-555555555555"
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
hagi plan create --input nightly-review.json
|
|
422
|
+
hagi plan create --input weekly-triage.json --disabled
|
|
423
|
+
PLAN_ID=$(hagi plan create --input nightly-review.json --json | json_field '.plan.id')
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
A plan is **enabled by default**. `create` sends `enabled: true` unless the document sets `enabled` or you pass `--disabled`. `--name` and `--hero-id` replace the document's `name` and agent pool, and `--hero-id` builds the single-agent `random` pool. Server-owned fields (`id`, `createdAt`, `updatedAt`, `state`, `nextRunAt`) in the document are ignored.
|
|
427
|
+
|
|
428
|
+
### Update, enable, disable and delete
|
|
429
|
+
|
|
430
|
+
`plan update` reads the current plan, applies your changes and sends the full plan back, so fields you do not mention keep their values:
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
hagi plan update --id "$PLAN_ID" --name "Nightly review (EU)"
|
|
434
|
+
hagi plan update --id "$PLAN_ID" --input changes.json
|
|
435
|
+
hagi plan update --id "$PLAN_ID" --hero-id 5de02573-0000-4000-8000-000000000002 --enabled
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
`--input` on update is a **shallow merge** over the top-level keys of the plan (`type`, `name`, `enabled`, `schedule`, `agentPool`, `payload`). Each key in the file replaces the current value as a whole, and keys missing from the file are kept. A `schedule` in the file replaces the whole current schedule, so write the complete object, without the fields you want removed (for example `endDate`). Passing `--enabled` and `--disabled` together is a usage error, and so is an update with no change.
|
|
439
|
+
|
|
440
|
+
`enable` and `disable` change only the enabled flag. When the plan already has that flag, nothing is sent and the output says so:
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
hagi plan disable --id "$PLAN_ID"
|
|
444
|
+
hagi plan enable --id "$PLAN_ID" --json
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Delete a plan. It never runs again:
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
hagi plan delete --id "$PLAN_ID"
|
|
451
|
+
hagi plan delete --id "$PLAN_ID" --json
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
To change a plan with a text editor, take the current document, edit it and feed it back. Server-owned fields are dropped automatically:
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
hagi plan get --id "$PLAN_ID" --json | jq .plan > plan.json
|
|
458
|
+
# edit plan.json, then:
|
|
459
|
+
hagi plan update --id "$PLAN_ID" --input plan.json
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
When the backend rejects a plan with 400 (exit code `20`), the CLI prints the summary and then one line per problem, naming its field:
|
|
463
|
+
|
|
464
|
+
```text
|
|
465
|
+
Scheduled plan is invalid. (status=400)
|
|
466
|
+
- agentPool: A HagiTask plan needs an agent pool with one agent.
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Use `--json` to get the full backend body under `error.details`.
|
|
470
|
+
|
|
471
|
+
### Run a plan now
|
|
472
|
+
|
|
473
|
+
`plan run` creates a session from the plan's stored inputs immediately, without waiting for the schedule. It waits for the session and prints its summary, or `{ "session": {...} }` with `--json`:
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
hagi plan run --id "$PLAN_ID"
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
`plan run --background` starts the same run and returns as soon as the backend accepts it, before the session exists. It prints the plan id and `accepted: true`. The session shows up in the normal session list:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
hagi plan run --id "$PLAN_ID" --background --json
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
A manual run does not change the plan's state or next run time. It works for disabled and completed plans, and the next automatic run still happens on the original schedule.
|
|
486
|
+
|
|
487
|
+
## Skills Commands
|
|
488
|
+
|
|
489
|
+
List installed local skills. The table shows each skill's origin (`user` or `built-in`), whether a built-in skill is enabled, its version, scope, agents and path. A user skill shows `-` in the Enabled column, because availability does not apply to it:
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
hagi skills local list
|
|
493
|
+
hagi skills local list --json
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Turn a built-in skill on or off by name. The change applies to agent runs that start afterwards; a run already in progress keeps its skills. A name that is not a built-in skill exits with code `30`, and the output carries the backend message:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
hagi skills local enable --skill-name hagi
|
|
500
|
+
hagi skills local disable --skill-name hagi --json
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Built-in skills cannot be uninstalled. Use `skills local disable` to stop one from loading. Remove a user skill by name:
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
SKILL_NAME=demo-skill
|
|
507
|
+
hagi skills local uninstall --skill-name "$SKILL_NAME"
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
The uninstall result reports a status such as `Succeeded` or `PrerequisiteMissing`, with the backend message. Passing a built-in skill's name returns the backend's refusal unchanged.
|
|
511
|
+
|
|
512
|
+
Skill recommendation and install progress streaming are not part of the CLI. `skills gallery search`, `detail` and `install` are the discovery and install path.
|
|
513
|
+
|
|
514
|
+
Search the gallery and read one skill:
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
hagi skills gallery search --query react
|
|
518
|
+
hagi skills gallery search --query react --json
|
|
519
|
+
hagi skills gallery detail --id vercel-react-best-practices --source vercel-labs/agent-skills
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Start a managed install of a gallery skill. This writes the skill into your local skill directories, so run it only when you intend to install it:
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
hagi skills gallery install \
|
|
526
|
+
--id vercel-react-best-practices \
|
|
527
|
+
--source vercel-labs/agent-skills \
|
|
528
|
+
--skill-slug vercel-react-best-practices
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
Manage the trusted provider directory. `upsert` reads a JSON document from `--input <file>` or `--input -`:
|
|
532
|
+
|
|
533
|
+
```bash
|
|
534
|
+
hagi skills trusted list
|
|
535
|
+
cat > provider.json <<'EOF'
|
|
536
|
+
{"providerId":"example-provider","displayName":"Example","isEnabled":true,"sortOrder":50,"matchRules":[{"matchType":"owner","value":"example"}]}
|
|
537
|
+
EOF
|
|
538
|
+
hagi skills trusted upsert --input provider.json
|
|
539
|
+
cat provider.json | hagi skills trusted upsert --input - --json
|
|
540
|
+
hagi skills trusted delete --provider-id example-provider
|
|
541
|
+
hagi skills trusted reset
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## Environment Variables
|
|
545
|
+
|
|
546
|
+
The CLI resolves runtime settings centrally before every command. Explicit flags always override environment variables.
|
|
547
|
+
|
|
548
|
+
| Variable | Purpose |
|
|
549
|
+
| --- | --- |
|
|
550
|
+
| `HAGI_API_BASE_URL` | Backend base URL, used when `--base-url` is not given. Overrides the config file. Required when neither is set. |
|
|
551
|
+
| `HAGI_API_TOKEN` | Bearer token attached as `Authorization: Bearer <token>`. |
|
|
552
|
+
| `HAGI_API_LANG` | Shared `Accept-Language` header value. |
|
|
197
553
|
|
|
198
554
|
## Exit Codes
|
|
199
555
|
|
|
@@ -207,6 +563,7 @@ Stable non-zero exits used by the CLI:
|
|
|
207
563
|
| `23` | HTTP 403 |
|
|
208
564
|
| `24` | HTTP 404 |
|
|
209
565
|
| `29` | HTTP 409 |
|
|
566
|
+
| `30` | Operation failed: the backend returned a refusal, for example `skills local enable` or `disable` on a name that is not a built-in skill |
|
|
210
567
|
| `40` | Other HTTP 4xx |
|
|
211
568
|
| `50` | HTTP 5xx |
|
|
212
569
|
| `60` | Transport or connection failure |
|