@hagicode/cli 0.1.0-dev.3.1.074a0f9 → 0.1.0-dev.31.1.bcd050b
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 +504 -113
- package/dist/chunks/main-BoZml4AL.js +161 -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,589 @@
|
|
|
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
|
|
55
|
+
|
|
56
|
+
If you are integrating Hagi CLI into an agent workflow, start from the embedded skill package in this repository:
|
|
57
|
+
|
|
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
|
|
61
|
+
|
|
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.
|
|
63
|
+
|
|
64
|
+
## Shared Runtime Flags
|
|
65
|
+
|
|
66
|
+
Every command family supports the same global runtime flags:
|
|
67
|
+
|
|
68
|
+
- `--base-url <url>`
|
|
69
|
+
- `--token <token>`
|
|
70
|
+
- `--lang <lang>`
|
|
71
|
+
- `--json`
|
|
72
|
+
|
|
73
|
+
Example:
|
|
39
74
|
|
|
40
|
-
|
|
41
|
-
|
|
75
|
+
```bash
|
|
76
|
+
hagi --base-url https://api.example.com --token "$HAGI_TOKEN" project list --json
|
|
77
|
+
```
|
|
42
78
|
|
|
43
|
-
|
|
44
|
-
- only published GitHub Releases for strict `vX.Y.Z` tags publish the stable package under the npm `latest` dist-tag
|
|
79
|
+
## Connection Setup
|
|
45
80
|
|
|
46
|
-
|
|
81
|
+
Every operation command resolves the backend base URL on each invocation, in this order:
|
|
47
82
|
|
|
48
|
-
1.
|
|
49
|
-
2.
|
|
50
|
-
|
|
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.
|
|
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
|
|
59
86
|
|
|
60
|
-
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"baseUrl": "https://hagicode.example.com"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
61
92
|
|
|
62
|
-
|
|
93
|
+
If none of the three is set, the command exits with code `2` and sends no backend request.
|
|
63
94
|
|
|
64
|
-
|
|
65
|
-
The following planned release labels were still missing and should be created before maintainers rely on the full contract:
|
|
95
|
+
Operation commands send requests without a credential by default. Pass `--token` (or set `HAGI_API_TOKEN`) only when your backend requires one.
|
|
66
96
|
|
|
67
|
-
-
|
|
68
|
-
- `minor`
|
|
69
|
-
- `patch`
|
|
70
|
-
- `breaking-change`
|
|
71
|
-
- `feature`
|
|
72
|
-
- `docs`
|
|
73
|
-
- `chore`
|
|
74
|
-
- `dependencies`
|
|
75
|
-
- `skip-changelog`
|
|
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.
|
|
76
98
|
|
|
77
|
-
|
|
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.
|
|
78
102
|
|
|
79
|
-
|
|
103
|
+
$ echo $?
|
|
104
|
+
60
|
|
105
|
+
```
|
|
80
106
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
107
|
+
## Command Overview
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
hagi
|
|
111
|
+
|-- project list | repositories | create | update | delete
|
|
112
|
+
| `-- monospecs show | init | set | validate | reload | clone | remove-checkout
|
|
113
|
+
|-- proposal list | create | optimize-description | generate | annotate | execute | archive | status | complete | send
|
|
114
|
+
|-- vault list | create | update | delete
|
|
115
|
+
| `-- files list | preview
|
|
116
|
+
|-- chat list | create | archive | delete | send
|
|
117
|
+
|-- hagitask list | schema | create | send
|
|
118
|
+
|-- plan list | get | create | update | enable | disable | delete | run
|
|
119
|
+
`-- skills local list | enable | disable | uninstall
|
|
120
|
+
gallery search | detail | install
|
|
121
|
+
trusted list | upsert | delete | reset
|
|
122
|
+
```
|
|
85
123
|
|
|
86
|
-
|
|
124
|
+
## Example Setup
|
|
87
125
|
|
|
88
|
-
|
|
126
|
+
The examples in the family sections run in order against a local backend. They assume:
|
|
89
127
|
|
|
90
|
-
|
|
128
|
+
- the backend listens on `http://127.0.0.1:35167`
|
|
129
|
+
- `hagi` is on `PATH`
|
|
130
|
+
- `json_field` reads one field from `--json` output
|
|
91
131
|
|
|
92
132
|
```bash
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
npm test
|
|
99
|
-
npm run pack:check
|
|
133
|
+
export HAGI_API_BASE_URL=http://127.0.0.1:35167
|
|
134
|
+
json_field() { node -pe "JSON.parse(require('node:fs').readFileSync(0, 'utf8'))$1"; }
|
|
135
|
+
|
|
136
|
+
mkdir -p /tmp/cli-examples/repos/cli
|
|
137
|
+
PROJECT_ID=$(hagi project create --name "CLI Examples" --path /tmp/cli-examples --json | json_field '.project.id')
|
|
100
138
|
```
|
|
101
139
|
|
|
102
|
-
|
|
103
|
-
`pack:check` runs `npm pack --dry-run --json` and rejects missing bundled entrypoints, `.map` files, and legacy source-mirrored output such as `dist/runtime/**` or `dist/generated/api/models/**`.
|
|
104
|
-
`publish:resolve-dev-version` derives the CI-only prerelease version used for `main` branch publishes, for example `0.1.0-dev.<run>.<attempt>.<sha>`.
|
|
140
|
+
## Project Commands
|
|
105
141
|
|
|
106
|
-
|
|
142
|
+
List projects through the aggregation endpoint:
|
|
107
143
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
5. Confirm the GitHub Actions summary shows build, typecheck, test, package inspection, version stamping, and `npm publish --tag latest --provenance --access public`.
|
|
144
|
+
```bash
|
|
145
|
+
hagi project list
|
|
146
|
+
hagi project list --json
|
|
147
|
+
```
|
|
113
148
|
|
|
114
|
-
|
|
149
|
+
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:
|
|
115
150
|
|
|
116
|
-
|
|
151
|
+
```bash
|
|
152
|
+
hagi project repositories --id "$PROJECT_ID"
|
|
153
|
+
hagi project repositories --id "$PROJECT_ID" --json
|
|
154
|
+
```
|
|
117
155
|
|
|
118
|
-
|
|
119
|
-
| --- | --- |
|
|
120
|
-
| `HAGI_API_BASE_URL` | Backend base URL. Defaults to `http://127.0.0.1:35168` when unset. |
|
|
121
|
-
| `HAGI_API_TOKEN` | Bearer token attached as `Authorization: Bearer <token>`. |
|
|
122
|
-
| `HAGI_API_LANG` | Shared `Accept-Language` header value. |
|
|
156
|
+
Create a project. The backend creates the directory if it does not exist. The new id is read from `project.id`:
|
|
123
157
|
|
|
124
|
-
|
|
158
|
+
```bash
|
|
159
|
+
DEMO_PROJECT_ID=$(hagi project create \
|
|
160
|
+
--name "CLI Demo" \
|
|
161
|
+
--path /tmp/cli-demo \
|
|
162
|
+
--description "Automation sandbox" \
|
|
163
|
+
--json | json_field '.project.id')
|
|
164
|
+
```
|
|
125
165
|
|
|
126
|
-
|
|
127
|
-
- `--token <token>`
|
|
128
|
-
- `--lang <lang>`
|
|
129
|
-
- `--json`
|
|
166
|
+
Update only part of a project record. The CLI resolves current project data first so omitted fields are preserved:
|
|
130
167
|
|
|
131
|
-
|
|
168
|
+
```bash
|
|
169
|
+
hagi project update --id "$DEMO_PROJECT_ID" --description "Updated description"
|
|
170
|
+
hagi project update --id "$DEMO_PROJECT_ID" --name "CLI Demo renamed"
|
|
171
|
+
```
|
|
132
172
|
|
|
133
|
-
|
|
173
|
+
Delete the demo project:
|
|
134
174
|
|
|
135
175
|
```bash
|
|
136
|
-
|
|
137
|
-
npm run generate:api
|
|
138
|
-
npm run generate:api:once
|
|
176
|
+
hagi project delete --id "$DEMO_PROJECT_ID"
|
|
139
177
|
```
|
|
140
178
|
|
|
141
|
-
|
|
179
|
+
## MonoSpecs Commands
|
|
180
|
+
|
|
181
|
+
`project monospecs` manages a project's MonoSpecs configuration (`monospecs.yaml`) and the local checkouts of its repositories. The CLI only sends requests: the backend reads and writes the files and runs Git on its own host, so `--base-url` may point at a remote backend.
|
|
182
|
+
|
|
183
|
+
| Command | Purpose |
|
|
184
|
+
| --- | --- |
|
|
185
|
+
| `show --id <id>` | Print the version, repo directory, config path, commit-when-archive flag and one row per repository with its local Git state. `--yaml` adds the YAML preview. |
|
|
186
|
+
| `init --id <id>` | Initialize the configuration. An initialized project returns its existing document. |
|
|
187
|
+
| `set --id <id>` | Change metadata or repositories. Options: `--version`, `--repo-directory`, `--commit-when-archive <true\|false>`, repeatable `--add-repository <path>` and `--remove-repository <path>`, and `--clone`. `--url`, `--name`, `--display-name` and `--type` apply to a single `--add-repository`. |
|
|
188
|
+
| `validate --id <id>` | Validate the configuration. Exits `30` and still prints every error when it is invalid. |
|
|
189
|
+
| `reload --id <id>` | Reread `monospecs.yaml` on the backend host and refresh the Git state. |
|
|
190
|
+
| `clone --id <id>` | Clone configured repositories that are missing. Repeatable `--path <path>` selects repositories; `--include-optional` adds optional ones when no `--path` is given. |
|
|
191
|
+
| `remove-checkout --id <id> --path <path>` | Delete the local checkout of one configured repository. `--force` allows a checkout with uncommitted changes, unpushed commits or no upstream branch. |
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
hagi project monospecs show --id "$PROJECT_ID"
|
|
195
|
+
hagi project monospecs set --id "$PROJECT_ID" --commit-when-archive true
|
|
196
|
+
hagi project monospecs set --id "$PROJECT_ID" --add-repository repos/api --url https://github.com/example/api.git --clone
|
|
197
|
+
hagi project monospecs set --id "$PROJECT_ID" --remove-repository repos/api
|
|
198
|
+
hagi project monospecs validate --id "$PROJECT_ID" --json
|
|
199
|
+
hagi project monospecs clone --id "$PROJECT_ID" --path repos/web
|
|
200
|
+
hagi project monospecs remove-checkout --id "$PROJECT_ID" --path repos/web
|
|
201
|
+
```
|
|
142
202
|
|
|
143
|
-
|
|
203
|
+
Safety rules:
|
|
144
204
|
|
|
145
|
-
|
|
205
|
+
- `set` reads the current document, applies only the options given and saves the complete document. Local Git state (branch, sync state and similar) is never written back; `code` and `metadata` are kept.
|
|
206
|
+
- `set` rejects a duplicate `--add-repository`, a `--remove-repository` that is not configured, and companion options with more than one addition, before anything is saved. With `--clone`, the configuration is saved first; a failed clone leaves it saved and exits `30`.
|
|
207
|
+
- `clone` and `remove-checkout` act only on repositories listed in the configuration. The backend confines paths to the project root and clones only over `https`, `http`, `ssh` and `git`, so a `file://` URL or a plain path is reported as `failed`.
|
|
208
|
+
- `remove-checkout` refuses a checkout with uncommitted changes, unpushed commits or no upstream unless `--force` is given, and it never removes a path that is not a standalone repository root. It deletes a directory on the backend host and leaves `monospecs.yaml` unchanged.
|
|
146
209
|
|
|
147
|
-
|
|
210
|
+
Exit codes for these commands: `2` usage error (no request was sent), `20` backend validation error (every field error is listed), `24` project not found, `29` another clone or removal is running or a checkout is blocked, `30` invalid configuration or a failed clone.
|
|
148
211
|
|
|
149
212
|
## Proposal Commands
|
|
150
213
|
|
|
151
|
-
|
|
214
|
+
List proposal sessions for the example project:
|
|
152
215
|
|
|
153
216
|
```bash
|
|
154
|
-
hagi proposal list --project-id
|
|
217
|
+
hagi proposal list --project-id "$PROJECT_ID"
|
|
155
218
|
hagi proposal list --include-archived --json
|
|
156
219
|
```
|
|
157
220
|
|
|
158
|
-
|
|
221
|
+
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).
|
|
222
|
+
|
|
223
|
+
Create a proposal session only. The new id is read from `session.sessionId`:
|
|
159
224
|
|
|
160
225
|
```bash
|
|
161
|
-
hagi proposal create \
|
|
162
|
-
--project-id
|
|
163
|
-
--chief-complaint "
|
|
164
|
-
|
|
226
|
+
PROPOSAL_ID=$(hagi proposal create \
|
|
227
|
+
--project-id "$PROJECT_ID" \
|
|
228
|
+
--chief-complaint "Repository scope
|
|
229
|
+
Writable repositories:
|
|
230
|
+
- repos/cli
|
|
231
|
+
Read-only repositories:
|
|
232
|
+
- none
|
|
233
|
+
|
|
234
|
+
Add CLI completion for session workflows" \
|
|
235
|
+
--default-title \
|
|
236
|
+
--json | json_field '.session.sessionId')
|
|
165
237
|
```
|
|
166
238
|
|
|
167
|
-
|
|
239
|
+
Update status and send a follow-up message:
|
|
168
240
|
|
|
169
241
|
```bash
|
|
170
|
-
hagi proposal
|
|
242
|
+
hagi proposal status --session-id "$PROPOSAL_ID" --status Reviewing
|
|
243
|
+
hagi proposal send --session-id "$PROPOSAL_ID" --content "Please continue"
|
|
171
244
|
```
|
|
172
245
|
|
|
173
|
-
`proposal generate`
|
|
246
|
+
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:
|
|
174
247
|
|
|
175
248
|
```bash
|
|
176
|
-
hagi proposal
|
|
177
|
-
hagi proposal generate --session-id
|
|
249
|
+
hagi proposal optimize-description --session-id "$PROPOSAL_ID" --description "Add CLI completion for session workflows" --default-title
|
|
250
|
+
hagi proposal generate --session-id "$PROPOSAL_ID" --proposal-content-language en-US --enable-explore-mode
|
|
251
|
+
|
|
252
|
+
cat > annotations.json <<'EOF'
|
|
253
|
+
{"files":[{"fileName":"proposal.md","filePath":"proposal.md"}]}
|
|
254
|
+
EOF
|
|
255
|
+
hagi proposal annotate --session-id "$PROPOSAL_ID" --input annotations.json
|
|
256
|
+
cat annotations.json | hagi proposal annotate --session-id "$PROPOSAL_ID" --input - --json
|
|
257
|
+
|
|
258
|
+
hagi proposal execute --session-id "$PROPOSAL_ID"
|
|
259
|
+
hagi proposal complete --session-id "$PROPOSAL_ID"
|
|
260
|
+
hagi proposal archive --session-id "$PROPOSAL_ID"
|
|
178
261
|
```
|
|
179
262
|
|
|
180
|
-
|
|
263
|
+
### Explicit Lifecycle Sequence
|
|
264
|
+
|
|
265
|
+
The CLI keeps proposal lifecycle actions explicit and non-interactive. Each command maps to one backend action:
|
|
266
|
+
|
|
267
|
+
1. `hagi proposal list`
|
|
268
|
+
2. `hagi proposal create`
|
|
269
|
+
3. `hagi proposal optimize-description --session-id <session-id> --description <text>` (sets the title, description, and proposal name)
|
|
270
|
+
4. `hagi proposal generate --session-id <session-id> --proposal-content-language <language>` (optionally `--enable-explore-mode`)
|
|
271
|
+
5. `hagi proposal annotate --session-id <session-id> --input <file>` (optional review loop)
|
|
272
|
+
6. `hagi proposal execute --session-id <session-id>`
|
|
273
|
+
7. `hagi proposal complete --session-id <session-id>`
|
|
274
|
+
8. `hagi proposal archive --session-id <session-id>`
|
|
275
|
+
|
|
276
|
+
The CLI may suggest a next command, but it never chains later lifecycle APIs automatically.
|
|
277
|
+
|
|
278
|
+
Each command maps to one backend action. The CLI may suggest a next command, but it never chains later lifecycle APIs automatically.
|
|
279
|
+
|
|
280
|
+
## Vault Commands
|
|
281
|
+
|
|
282
|
+
Create a vault with a local folder to browse. The new id is read from `vault.id`:
|
|
181
283
|
|
|
182
284
|
```bash
|
|
183
|
-
|
|
285
|
+
mkdir -p /tmp/cli-vault-notes/docs
|
|
286
|
+
printf '# Notes\n' > /tmp/cli-vault-notes/docs/readme.md
|
|
287
|
+
|
|
288
|
+
VAULT_ID=$(hagi vault create \
|
|
289
|
+
--name "Main Notes" \
|
|
290
|
+
--type folder \
|
|
291
|
+
--physical-path /tmp/cli-vault-notes \
|
|
292
|
+
--json | json_field '.vault.id')
|
|
184
293
|
```
|
|
185
294
|
|
|
186
|
-
|
|
295
|
+
List registered vaults:
|
|
187
296
|
|
|
188
|
-
|
|
297
|
+
```bash
|
|
298
|
+
hagi vault list
|
|
299
|
+
hagi vault list --json
|
|
300
|
+
```
|
|
189
301
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
302
|
+
Update only part of a vault record. The CLI resolves the current vault snapshot first so omitted fields are preserved:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
hagi vault update --id "$VAULT_ID" --name "Renamed Vault"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Browse vault files and preview supported content:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
hagi vault files list --id "$VAULT_ID"
|
|
312
|
+
hagi vault files list --id "$VAULT_ID" --path docs --json
|
|
313
|
+
hagi vault files preview --id "$VAULT_ID" --path docs/readme.md
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Delete a vault and request backend cleanup of its local files:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
hagi vault delete --id "$VAULT_ID" --delete-local-files --json
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Chat Commands
|
|
323
|
+
|
|
324
|
+
Create a chat session. The new id is read from `session.sessionId`:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
CHAT_ID=$(hagi chat create \
|
|
328
|
+
--title "Repository Q&A" \
|
|
329
|
+
--project-id "$PROJECT_ID" \
|
|
330
|
+
--json | json_field '.session.sessionId')
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
List chat sessions:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
hagi chat list --active-only
|
|
337
|
+
hagi chat list --include-archived --json
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Send a message, archive, and delete:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
hagi chat send --session-id "$CHAT_ID" --content "Summarize the current diff"
|
|
344
|
+
hagi chat archive --session-id "$CHAT_ID"
|
|
345
|
+
hagi chat delete --session-id "$CHAT_ID"
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## HagiTask Commands
|
|
349
|
+
|
|
350
|
+
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:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
hagi hagitask list
|
|
354
|
+
hagi hagitask list --json
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
`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:
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
hagi hagitask schema --task-id compose-commit
|
|
361
|
+
hagi hagitask schema --task-id compose-commit --json
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
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:
|
|
195
365
|
|
|
196
|
-
|
|
366
|
+
```json
|
|
367
|
+
{
|
|
368
|
+
"inputs": {
|
|
369
|
+
"commitScope": "cli"
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Create the session from that task and input. The new id is read from `session.sessionId`:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
HAGITASK_ID=$(hagi hagitask create \
|
|
378
|
+
--title "Auto compose commit" \
|
|
379
|
+
--project-id "$PROJECT_ID" \
|
|
380
|
+
--task-id compose-commit \
|
|
381
|
+
--input input.json \
|
|
382
|
+
--repository-path repos/cli \
|
|
383
|
+
--need-push \
|
|
384
|
+
--target-branch-mode new-custom \
|
|
385
|
+
--target-branch-name feature/cli-completion \
|
|
386
|
+
--json | json_field '.session.sessionId')
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
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`.
|
|
390
|
+
|
|
391
|
+
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`.
|
|
392
|
+
|
|
393
|
+
Send a follow-up message to the HagiTask session:
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
hagi hagitask send --session-id "$HAGITASK_ID" --content "Retry with a smaller diff"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**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.
|
|
400
|
+
|
|
401
|
+
## Plan Commands
|
|
402
|
+
|
|
403
|
+
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:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
hagi plan list
|
|
407
|
+
hagi plan list --json
|
|
408
|
+
hagi plan get --id "$PLAN_ID"
|
|
409
|
+
hagi plan get --id "$PLAN_ID" --json | jq .plan
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
`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.
|
|
413
|
+
|
|
414
|
+
### Create a plan
|
|
415
|
+
|
|
416
|
+
`plan create` reads a plan document with `--input <file>` or `--input -` for stdin. A recurring HagiTask plan:
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
{
|
|
420
|
+
"type": "hagitask",
|
|
421
|
+
"name": "Nightly review",
|
|
422
|
+
"enabled": true,
|
|
423
|
+
"schedule": {
|
|
424
|
+
"mode": "recurring",
|
|
425
|
+
"timeZone": "Asia/Shanghai",
|
|
426
|
+
"startDate": "2026-05-01",
|
|
427
|
+
"endDate": "2026-05-31",
|
|
428
|
+
"timeOfDay": "02:00",
|
|
429
|
+
"repeat": { "rule": "daily", "weekdays": [] }
|
|
430
|
+
},
|
|
431
|
+
"agentPool": { "strategy": "random", "agents": [ { "heroId": "5de02573-0000-4000-8000-000000000001" } ] },
|
|
432
|
+
"payload": {
|
|
433
|
+
"projectId": "11111111-2222-3333-4444-555555555555",
|
|
434
|
+
"presetTaskId": "nightly-review"
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
A one-time proposal plan runs once at `runAt` and has no time zone or repeat fields:
|
|
440
|
+
|
|
441
|
+
```json
|
|
442
|
+
{
|
|
443
|
+
"type": "proposal",
|
|
444
|
+
"name": "Weekly triage",
|
|
445
|
+
"schedule": { "mode": "once", "runAt": "2026-06-12T10:30:00Z" },
|
|
446
|
+
"payload": {
|
|
447
|
+
"title": "Weekly triage",
|
|
448
|
+
"chiefComplaint": "Triage the open issues and propose the next sprint",
|
|
449
|
+
"projectId": "11111111-2222-3333-4444-555555555555"
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
hagi plan create --input nightly-review.json
|
|
456
|
+
hagi plan create --input weekly-triage.json --disabled
|
|
457
|
+
PLAN_ID=$(hagi plan create --input nightly-review.json --json | json_field '.plan.id')
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
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.
|
|
461
|
+
|
|
462
|
+
### Update, enable, disable and delete
|
|
463
|
+
|
|
464
|
+
`plan update` reads the current plan, applies your changes and sends the full plan back, so fields you do not mention keep their values:
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
hagi plan update --id "$PLAN_ID" --name "Nightly review (EU)"
|
|
468
|
+
hagi plan update --id "$PLAN_ID" --input changes.json
|
|
469
|
+
hagi plan update --id "$PLAN_ID" --hero-id 5de02573-0000-4000-8000-000000000002 --enabled
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
`--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.
|
|
473
|
+
|
|
474
|
+
`enable` and `disable` change only the enabled flag. When the plan already has that flag, nothing is sent and the output says so:
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
hagi plan disable --id "$PLAN_ID"
|
|
478
|
+
hagi plan enable --id "$PLAN_ID" --json
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Delete a plan. It never runs again:
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
hagi plan delete --id "$PLAN_ID"
|
|
485
|
+
hagi plan delete --id "$PLAN_ID" --json
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
To change a plan with a text editor, take the current document, edit it and feed it back. Server-owned fields are dropped automatically:
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
hagi plan get --id "$PLAN_ID" --json | jq .plan > plan.json
|
|
492
|
+
# edit plan.json, then:
|
|
493
|
+
hagi plan update --id "$PLAN_ID" --input plan.json
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
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:
|
|
497
|
+
|
|
498
|
+
```text
|
|
499
|
+
Scheduled plan is invalid. (status=400)
|
|
500
|
+
- agentPool: A HagiTask plan needs an agent pool with one agent.
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Use `--json` to get the full backend body under `error.details`.
|
|
504
|
+
|
|
505
|
+
### Run a plan now
|
|
506
|
+
|
|
507
|
+
`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`:
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
hagi plan run --id "$PLAN_ID"
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
`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:
|
|
514
|
+
|
|
515
|
+
```bash
|
|
516
|
+
hagi plan run --id "$PLAN_ID" --background --json
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
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.
|
|
520
|
+
|
|
521
|
+
## Skills Commands
|
|
522
|
+
|
|
523
|
+
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:
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
hagi skills local list
|
|
527
|
+
hagi skills local list --json
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
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:
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
hagi skills local enable --skill-name hagi
|
|
534
|
+
hagi skills local disable --skill-name hagi --json
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Built-in skills cannot be uninstalled. Use `skills local disable` to stop one from loading. Remove a user skill by name:
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
SKILL_NAME=demo-skill
|
|
541
|
+
hagi skills local uninstall --skill-name "$SKILL_NAME"
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
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.
|
|
545
|
+
|
|
546
|
+
Skill recommendation and install progress streaming are not part of the CLI. `skills gallery search`, `detail` and `install` are the discovery and install path.
|
|
547
|
+
|
|
548
|
+
Search the gallery and read one skill:
|
|
549
|
+
|
|
550
|
+
```bash
|
|
551
|
+
hagi skills gallery search --query react
|
|
552
|
+
hagi skills gallery search --query react --json
|
|
553
|
+
hagi skills gallery detail --id vercel-react-best-practices --source vercel-labs/agent-skills
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
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:
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
hagi skills gallery install \
|
|
560
|
+
--id vercel-react-best-practices \
|
|
561
|
+
--source vercel-labs/agent-skills \
|
|
562
|
+
--skill-slug vercel-react-best-practices
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
Manage the trusted provider directory. `upsert` reads a JSON document from `--input <file>` or `--input -`:
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
hagi skills trusted list
|
|
569
|
+
cat > provider.json <<'EOF'
|
|
570
|
+
{"providerId":"example-provider","displayName":"Example","isEnabled":true,"sortOrder":50,"matchRules":[{"matchType":"owner","value":"example"}]}
|
|
571
|
+
EOF
|
|
572
|
+
hagi skills trusted upsert --input provider.json
|
|
573
|
+
cat provider.json | hagi skills trusted upsert --input - --json
|
|
574
|
+
hagi skills trusted delete --provider-id example-provider
|
|
575
|
+
hagi skills trusted reset
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
## Environment Variables
|
|
579
|
+
|
|
580
|
+
The CLI resolves runtime settings centrally before every command. Explicit flags always override environment variables.
|
|
581
|
+
|
|
582
|
+
| Variable | Purpose |
|
|
583
|
+
| --- | --- |
|
|
584
|
+
| `HAGI_API_BASE_URL` | Backend base URL, used when `--base-url` is not given. Overrides the config file. Required when neither is set. |
|
|
585
|
+
| `HAGI_API_TOKEN` | Bearer token attached as `Authorization: Bearer <token>`. |
|
|
586
|
+
| `HAGI_API_LANG` | Shared `Accept-Language` header value. |
|
|
197
587
|
|
|
198
588
|
## Exit Codes
|
|
199
589
|
|
|
@@ -207,6 +597,7 @@ Stable non-zero exits used by the CLI:
|
|
|
207
597
|
| `23` | HTTP 403 |
|
|
208
598
|
| `24` | HTTP 404 |
|
|
209
599
|
| `29` | HTTP 409 |
|
|
600
|
+
| `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, an invalid MonoSpecs configuration from `project monospecs validate`, or a failed clone from `project monospecs clone` or `set --clone` |
|
|
210
601
|
| `40` | Other HTTP 4xx |
|
|
211
602
|
| `50` | HTTP 5xx |
|
|
212
603
|
| `60` | Transport or connection failure |
|