@hagicode/cli 0.8.0 → 0.9.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 +6 -2
- package/dist/chunks/main-GxA0gS86.js +271 -0
- package/dist/cli.js +1 -1
- package/dist/main.js +1 -1
- package/package.json +1 -1
- package/resources/saga/manifest.json +2 -2
- package/resources/saga/prompts/plan.md +22 -2
- package/resources/saga/prompts/run.md +15 -6
- package/skills/hagi/SKILL.md +1 -1
- package/skills/hagi/references/cli-usage.md +3 -2
- package/skills/hagi/references/saga.md +20 -1
- package/dist/chunks/main-BUHthS3C.js +0 -266
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./chunks/main-
|
|
2
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./chunks/main-GxA0gS86.js");s.runCli().then(e=>{e!==0&&(process.exitCode=e)}).catch(e=>{const n=e instanceof Error?e.stack??e.message:String(e);process.stderr.write(`${n}
|
|
3
3
|
`),process.exitCode=s.EXIT_CODES.UNKNOWN});
|
package/dist/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./chunks/main-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./chunks/main-GxA0gS86.js");exports.createCliApp=e.createCliApp;exports.runCli=e.runCli;
|
package/package.json
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"goal": "a545b01c9f6010df661f02cf62ef9bcae527ccf329f304ea82ffdda239b118df",
|
|
8
8
|
"research": "2504283ea845440c7909ff1da20bfb70f846d55ca16565740168848cfb8060b1",
|
|
9
9
|
"acceptance": "11ca06794d0ec19e87d1a4e883a67014563e9750b9fa62a8bedd43a69d52ca65",
|
|
10
|
-
"plan": "
|
|
11
|
-
"run": "
|
|
10
|
+
"plan": "6573a02a36ab2d6995c2e4740d2c8771a41e77e5179145d0a2b8e30023816916",
|
|
11
|
+
"run": "3a3ae5bc64ab66faefda08fabe97c41b990266740fe749aee4ea29d822d5c131",
|
|
12
12
|
"amend": "be621d1221a85656851548aee1e9e9d78480288bd856baf1bdbf50cb3317f49b"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -3,14 +3,34 @@
|
|
|
3
3
|
## Instruction
|
|
4
4
|
List the work items, one line each: `- [ ] <ID> <name> | `. The evidence path is added when an item is ticked.
|
|
5
5
|
|
|
6
|
-
- Items are small enough to verify with one command,
|
|
6
|
+
- Items are small enough to verify with one command, and ordered so that earlier items do not depend on later ones.
|
|
7
7
|
- Keep the list short enough to review (roughly 3 to 15 items). Use the user's work items as a start; add or split items only when needed.
|
|
8
8
|
- Do not add items for committing, pushing, opening a pull request, releasing or archiving: they are outside the contract.
|
|
9
9
|
- IDs match the headings of `acceptance.md`.
|
|
10
|
-
- In a revision an item may be added or superseded, never deleted. A superseded item is written without brackets: `- ~ <ID> <name> | superseded in r<N>: <reason>`.
|
|
10
|
+
- In a revision an item may be added or superseded, never deleted. A superseded item is written without brackets: `- ~ <ID> <name> | superseded in r<N>: <reason>`. A superseded item is not active: it has no node in the graph and no edges.
|
|
11
11
|
- Planning ends here. Do not run `freeze`, do not start the run, do not edit project code.
|
|
12
12
|
|
|
13
|
+
## Dependency graph
|
|
14
|
+
`progress.md` holds exactly one Mermaid `flowchart` that describes every dependency between the active items. Write it in its own section, outside the item rows. It is the only place dependencies are declared.
|
|
15
|
+
|
|
16
|
+
- Each active item is one node. The node ID equals the item ID, and the node label holds the item's name in quotes.
|
|
17
|
+
- An edge `A --> B` means B cannot start until A is ticked. Write an edge only when that order is required.
|
|
18
|
+
- Two items with no path between them are independent and may run together. Independence is expressed only by the absence of a path.
|
|
19
|
+
- Group nodes with one `subgraph` per module, repository or area the item changes, titled in quotes (for example `subgraph CLI["repos/cli"]`). A subgraph states ownership only. Two items in one subgraph are not dependent because of it, and items in different subgraphs are not dependent because of it either.
|
|
20
|
+
- Item IDs must be valid Mermaid node IDs: start with a letter and use only letters, digits and underscores (`T1`, `CLI_2`; not `1.2`, not `T-1`). Never use the word `end`. Put the readable name in the node label, not in the ID.
|
|
21
|
+
- Keep every dependency in this one graph. Do not declare a dependency in prose, in the note column after `|` of an item row (that text is evidence only), in a separate list, or in a second diagram.
|
|
22
|
+
- Item rows keep their format `- [ ] <ID> <name> | <evidence>` unchanged, and the graph lines are never edited by ticking an item.
|
|
23
|
+
|
|
13
24
|
## Template
|
|
14
25
|
```
|
|
15
26
|
- [ ] <ID> <name> |
|
|
16
27
|
```
|
|
28
|
+
|
|
29
|
+
```mermaid
|
|
30
|
+
flowchart TD
|
|
31
|
+
subgraph <MODULE>["<module or repository>"]
|
|
32
|
+
<ID>["<ID> <name>"]
|
|
33
|
+
end
|
|
34
|
+
<ID> --> <ID>
|
|
35
|
+
```
|
|
36
|
+
</content>
|
|
@@ -11,7 +11,7 @@ The run's options may name these, with the defaults shown:
|
|
|
11
11
|
|
|
12
12
|
0. **Claim first.** `hagi saga claim <saga> --session <your session id> --path <root> --json`. Keep the printed token for every later command. If it refuses because another owner holds the Saga, stop and report it. Never take over by age, and never write a paused snapshot over another owner's progress.
|
|
13
13
|
1. **Freeze.** `hagi saga freeze <saga> --path <root> --token <token>`. If it refuses (open questions, open amendments, a changed contract), run `hagi saga set-status <saga> --state paused --note "<reason>" --path <root> --token <token>`, stop and report the reasons. Do not edit contract files and do not decide open questions. A first freeze writes revision 1. After an amendment was merged it writes the next revision, chained to the previous one, and reopens the items whose acceptance command changed.
|
|
14
|
-
2. **Check before every
|
|
14
|
+
2. **Check before every dispatch and at every heartbeat.** `hagi saga assert-owner <saga> --path <root> --token <token>` before each dispatch, then `hagi saga check <saga> --phase run --path <root>`. If a check fails, pause the same way and report. An open amendment also means: pause.
|
|
15
15
|
- **Quota before every Worker.** Before you create any Worker (step 3, and a tuning worker in step 4), resolve the provider that Worker spends, in this order, and use the first that applies:
|
|
16
16
|
1. the hint for the Worker's hero id, when the run input names the hero that Worker runs;
|
|
17
17
|
2. the hint for the Worker's role;
|
|
@@ -23,15 +23,24 @@ The run's options may name these, with the defaults shown:
|
|
|
23
23
|
- exit `34`, no usable figure: dispatch the Worker, log `quota unknown` with the provider in `orchestrator-log.md`, and read again before the next Worker.
|
|
24
24
|
- Any other exit code: pause the same way as a failed check, and report it.
|
|
25
25
|
- The JSON output's `windows` lists each window with `remainingPercent` and `resetsAtUtc`. Record the provider, the remaining percent and the reset time for every dispatch and every held dispatch (step 6).
|
|
26
|
-
|
|
26
|
+
- **Concurrent Workers.** Each Worker that runs alongside others gets its own ownership assert, its own check, its own quota check and its own logged reading (step 6), in that order, before it is created. A held dispatch (exit `0`, `guard.state` `low`) holds only that Worker: the Workers already running keep running, and between two runs of the held quota check you handle their reports, ticks and archiving. A held dispatch never stops a running Worker; only the wait total of that dispatch can pause the Saga.
|
|
27
|
+
3. **Dispatch by the dependency graph.** Read the Mermaid flowchart in `<root>/.hagicode/sagas/<saga>/progress.md` and the items (`hagi saga items <saga> --path <root>` lists them with their commands). Then:
|
|
28
|
+
- **Ready set.** An item is ready when it is unticked, not blocked, and every predecessor of it in the graph (every node with an edge `P --> <ITEM>`) is ticked. Compute the ready set from the graph and the Saga record, not from memory, and recompute it after every tick or block.
|
|
29
|
+
- **No graph, serial.** If `progress.md` holds no Mermaid flowchart, the Saga runs serially: one item at a time, in the listed order, with no inferred parallelism.
|
|
30
|
+
- **Graph problems pause.** If an unticked active item has no node in the graph, or an edge names a node that is not an active item, pause the Saga with that reason (step 9). Do not guess an order.
|
|
31
|
+
- **Goal forces serial.** If the goal says items run one at a time, dispatch one item at a time regardless of the graph.
|
|
32
|
+
- **Hold back overlap.** Among ready items, do not run two at once when they share a subgraph module or are likely to edit the same files, judged from the subgraph, the item name and its acceptance command. Dispatch one of them and hold the others until the running item is ticked or blocked. Ready items in disjoint modules with no shared files are not held back.
|
|
33
|
+
- **Cap.** At most 3 Workers run at once by default, counting implementation and verification Workers together. The goal may name a different cap; never exceed it. When more items are ready than there are free slots, start the rest as Workers settle.
|
|
34
|
+
- **Fan out.** Dispatch each remaining ready item by creating its implementation Worker, one after another, each behind its own quota check (step 2). Workers never tick or block items themselves: the orchestrator is the only writer of the Saga record.
|
|
35
|
+
For each Worker:
|
|
27
36
|
- Before each implementation, verification and tuning Worker, not once per item, run the quota check of step 2 for the provider that Worker spends.
|
|
28
|
-
- Create each Worker with `hagi saga session create --saga <saga> --path <root> --title "<ITEM> <role>" --role <role> --master <your session id> --item <ITEM>`, where `<role>` is `implementation` or `verification`. This command takes the token from `SAGA_EXECUTION_TOKEN`, set to the token that `claim` printed, and refuses `--token`. It creates the chat session with its Saga metadata and records it in `sessions.md`. Then give the Worker its instructions below.
|
|
37
|
+
- Create each Worker with `hagi saga session create --saga <saga> --path <root> --title "<ITEM> <role>" --role <role> --master <your session id> --item <ITEM>`, plus `--hero <hero>` when the run input names the hero that Worker runs, where `<role>` is `implementation` or `verification`. This command takes the token from `SAGA_EXECUTION_TOKEN`, set to the token that `claim` printed, and refuses `--token`. It creates the chat session with its Saga metadata and records it in `sessions.md`. Then give the Worker its instructions below.
|
|
29
38
|
- An implementation worker writes code and tests only. Give it the goal, the item, the scope and the safety rules, the project root and its report path.
|
|
30
39
|
- A separate verification worker runs the item's command from `acceptance.md` in the project root, writes the output to `<root>/.hagicode/sagas/<saga>/runtime/evidence/<ITEM>.log`, and writes `<root>/.hagicode/sagas/<saga>/runtime/reports/<ITEM>.md` with the line `Status: PASS` (or `状态: PASS`) only if the exit code is 0. It changes no files.
|
|
31
40
|
- Only `hagi saga tick <saga> <ITEM> --path <root> --token <token>` ticks an item. It refuses without a PASS report and an evidence file.
|
|
32
|
-
4. **On a failed verification, classify it.** An environment fault (missing module, port in use) does not count. A quota fault does not count either: a worker that stopped because its provider's quota was exhausted is not given to a tuning worker and is not counted. Re-dispatch the same Worker role with the same instructions, unchanged, once the step-2 quota check for that Worker's own provider (the provider it used, not the default) returns exit `0` with `guard.state` `ready`. A real failure counts: give a tuning worker the failure log path, then verify again. After 3 real failures run `hagi saga block <saga> <ITEM> "<reason>" --path <root> --token <token>` and move on.
|
|
41
|
+
4. **On a failed verification, classify it.** An environment fault (missing module, port in use) does not count. A quota fault does not count either: a worker that stopped because its provider's quota was exhausted is not given to a tuning worker and is not counted. Re-dispatch the same Worker role with the same instructions, unchanged, once the step-2 quota check for that Worker's own provider (the provider it used, not the default) returns exit `0` with `guard.state` `ready`. A real failure counts: give a tuning worker the failure log path, then verify again. After 3 real failures run `hagi saga block <saga> <ITEM> "<reason>" --path <root> --token <token>` and move on. A blocked item blocks everything downstream of it: every item reachable from it in the graph is never dispatched and is reported as waiting on that item. Items with no path from the blocked item continue as in step 3.
|
|
33
42
|
5. **After a revision reopened items,** also re-verify any item whose command is the full regression: its own command did not change, so it was not reopened.
|
|
34
|
-
6. **Keep the record.** Append a line to `<root>/.hagicode/sagas/<saga>/runtime/orchestrator-log.md` after every dispatch, held dispatch, verification and tick. Every dispatch line and every held dispatch line carries the quota reading it was made on: the provider, the remaining percent, the `resetsAtUtc` and the seconds waited. `hagi saga session create` records each Worker session it creates in `<root>/.hagicode/sagas/<saga>/runtime/sessions.md`, so do not append those sessions to that file by hand. Run `hagi saga set-status <saga> --state running --note "<heartbeat>" --path <root> --token <token>` at every heartbeat, and put the latest quota reading (provider, remaining percent, reset time and seconds waited) in that note. Run `hagi saga status <saga> --path <root> --json` to read the projection at the end.
|
|
43
|
+
6. **Keep the record.** Append a line to `<root>/.hagicode/sagas/<saga>/runtime/orchestrator-log.md` after every dispatch, held dispatch, verification and tick. Every dispatch line and every held dispatch line carries the quota reading it was made on: the provider, the remaining percent, the `resetsAtUtc` and the seconds waited. `hagi saga session create` records each Worker session it creates in `<root>/.hagicode/sagas/<saga>/runtime/sessions.md`, so do not append those sessions to that file by hand. Run `hagi saga set-status <saga> --state running --note "<heartbeat>" --path <root> --token <token>` at every heartbeat, and put the latest quota reading (provider, remaining percent, reset time and seconds waited) in that note. While several Workers run, heartbeat at every check of a running Worker and name the running items in the note. Run `hagi saga status <saga> --path <root> --json` to read the projection at the end.
|
|
35
44
|
7. **Archive each settled item's sessions.** Once an item is ticked or blocked and its workers have stopped, archive the worker sessions you created for it: `hagi chat archive --session-id <session id> --json`. Take the IDs from `<root>/.hagicode/sagas/<saga>/runtime/sessions.md`. Archive only sessions you created in this run: never your own orchestrator session, a session that is still running, a session you did not create, or the Saga itself (`hagi saga archive` is not part of a run). Archiving leaves the reports, evidence and `sessions.md` record in `runtime/` untouched. Log each archived ID in `orchestrator-log.md`. If an archive call fails, log the error and go on: do not retry in a loop and do not pause for it.
|
|
36
45
|
8. **Never leave a command hanging.** Every shell command must end on its own: never read from standard input, and give waits a limit. If something does not answer, report it instead of waiting forever. Every quota check is bounded as in step 2, and a dispatch that has waited six hours in total on quota pauses the Saga.
|
|
37
|
-
9. **Stop** when every item is ticked or blocked, when a pause condition appears, or when the human's run options say so. Write the terminal snapshot first (`set-status --state done` only when every active item is verified, otherwise `paused` with the reason; a quota pause names the provider, the remaining percent and the reset time). Once every worker has stopped, archive any remaining worker sessions as in step 7, then run `hagi saga release <saga> --path <root> --token <token> --workers-settled`. Never archive the Saga itself and do not commit. Report the revision, every item with its state and evidence path, the blocked items with reasons, the sessions you created and which of them you archived, and the next step for a human.
|
|
46
|
+
9. **Stop** when every item is ticked, blocked or waiting on a blocked item, when a pause condition appears (including an item missing from the graph or an unknown node, as in step 3), or when the human's run options say so. Write the terminal snapshot first (`set-status --state done` only when every active item is verified, otherwise `paused` with the reason; a quota pause names the provider, the remaining percent and the reset time). Once every worker has stopped, archive any remaining worker sessions as in step 7, then run `hagi saga release <saga> --path <root> --token <token> --workers-settled`. Never archive the Saga itself and do not commit. Report the revision, every item with its state and evidence path, the blocked items with reasons, the items waiting on a blocked item with the blocked item each one waits on, the sessions you created and which of them you archived, and the next step for a human.
|
package/skills/hagi/SKILL.md
CHANGED
|
@@ -90,7 +90,7 @@ The current top-level command families are:
|
|
|
90
90
|
- `agent`
|
|
91
91
|
- `saga`
|
|
92
92
|
|
|
93
|
-
`hagi saga` provides `init`, `new`, `list`, `status`, and `items`, plus the write and check commands `claim`, `assert-owner`, `release`, `freeze`, `check`, `tick`, `block`, `set-status`, `amend`, and `archive`,
|
|
93
|
+
`hagi saga` provides `init`, `new`, `list`, `status`, and `items`, plus the write and check commands `claim`, `assert-owner`, `release`, `freeze`, `check`, `tick`, `block`, `set-status`, `amend`, and `archive`, `session create`, which creates a Saga Worker chat session and records it; `session list`, which reads the Worker records without a token; and `log append`, which appends one line to the orchestrator log under the execution token. Mutating commands take `--token` or `SAGA_EXECUTION_TOKEN`; `session create` takes only `SAGA_EXECUTION_TOKEN`. With `--path`, these operate on host-local files without reading backend configuration or calling the API, except `session create`, which calls the backend to find the registered project; `--project-id` resolves a project through the backend. Creating a Worker changes state, so run `session create` only when the user or a Saga run explicitly asks for it. See [`references/saga.md`](references/saga.md) for initialization, creation, offline behavior, and read-only query guarantees.
|
|
94
94
|
|
|
95
95
|
`project repositories --id <project-id>` is read-only. It lists one project's repositories with each path relative to the project root (for example `repos/cli`). Those paths are the values a proposal's `Repository scope` names; see [`references/proposal-flow.md`](references/proposal-flow.md#repository-scope).
|
|
96
96
|
|
|
@@ -92,7 +92,7 @@ hagi
|
|
|
92
92
|
|-- project list | repositories | create | update | delete
|
|
93
93
|
| `-- monospecs show | init | set | validate | reload | clone | remove-checkout
|
|
94
94
|
|-- proposal list | create | optimize-description | generate | annotate | execute | archive | status | complete | send | get | messages
|
|
95
|
-
|-- saga init | new | list | status | items | claim | assert-owner | release | freeze | check | tick | block | set-status | amend | archive | session create
|
|
95
|
+
|-- saga init | new | list | status | items | claim | assert-owner | release | freeze | check | tick | block | set-status | amend | archive | session create | session list | log append
|
|
96
96
|
|-- vault list | create | update | delete
|
|
97
97
|
| `-- files list | preview
|
|
98
98
|
|-- chat list | create | archive | delete | send
|
|
@@ -225,7 +225,8 @@ Start one only when the user asked for it. See [super-commit.md](super-commit.md
|
|
|
225
225
|
|
|
226
226
|
- `schema` (human view) lists the target scope, commands and parameters, with each required parameter marked `yes`, then the requirements, scenes, endpoint and an example command. `--json` adds the input JSON Schema and the example request body.
|
|
227
227
|
- `create` needs `--title`, `--project-id`, and either `--task-id` or `--prompt-id`. `--input <file|->` needs `--task-id`. The input must be a JSON object. The CLI does not check its keys; the backend does, and it rejects a key that the schema does not list and a missing required value. A rejection is printed unchanged and no session is reported.
|
|
228
|
-
- `create --json` prints `{ session, presetTaskId, promptId, requested }`. Read the session id from `session.sessionId`.
|
|
228
|
+
- `create --json` prints `{ session, presetTaskId, promptId, requested }`. Read the session id from `session.sessionId`. `requested` carries `heroId` or `heroName` when a Hero was given, and `session.chatHero` names the Hero the backend bound when it returns one.
|
|
229
|
+
- `create --hero <name-or-id>` picks the Hero. A GUID is sent as `heroId`; any other value is sent as `heroName` (trimmed, matched without regard to case). Give `--hero` or `--hero-id`, not both: that is a usage error (exit `2`) and sends nothing. A blank value is also exit `2`. An unknown name, or both fields in one request, fails with the backend's message and creates no session. Needs a backend that includes the `hero_name` field; an older backend ignores the name and runs its default Hero.
|
|
229
230
|
|
|
230
231
|
Example `input.json` for a task with one required input:
|
|
231
232
|
|
|
@@ -184,6 +184,12 @@ Set `SAGA_EXECUTION_TOKEN` to the token that `claim` printed, then create a Work
|
|
|
184
184
|
hagi saga session create --saga demo --path "./My Project" --title "T1 implementation" --role implementation --master orchestrator-1 --item T1 --json
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
+
To bind the Worker to a Hero, add `--hero <name-or-id>`, for example `--hero Nova` or a Hero ID:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
hagi saga session create --saga demo --path "./My Project" --title "T1 implementation" --role implementation --master orchestrator-1 --item T1 --hero Nova --json
|
|
191
|
+
```
|
|
192
|
+
|
|
187
193
|
- The command creates one ordinary chat session in the project and appends one line to `runtime/sessions.md`. It sends
|
|
188
194
|
no message and does not archive the session; `hagi chat archive --session-id <id>` stays a separate step.
|
|
189
195
|
- Required and nonblank: `--saga <id>`, `--title <title>`, `--role implementation|verification`, and `--master <session-id>`
|
|
@@ -198,6 +204,12 @@ hagi saga session create --saga demo --path "./My Project" --title "T1 implement
|
|
|
198
204
|
names the path or the matching IDs, and creates nothing. `--project-id` looks the project up directly.
|
|
199
205
|
- After the project and the Saga are resolved, the owner check of `assert-owner` runs with the token. A Saga without a lock
|
|
200
206
|
still passes once a token is set. A wrong token is a refusal (code `1`), and an unknown Saga is code `24`.
|
|
207
|
+
- `--hero <name-or-id>` is optional. A GUID is sent as `heroId`; any other nonblank value is sent as `heroName`, matched
|
|
208
|
+
like Hero names (trimmed, case-insensitive). A blank value is a usage error (code `2`), and no file is touched. Without
|
|
209
|
+
`--hero` the request is the same as before. The Hero is never written to `userMetadata` or `sessions.md`. A Hero the
|
|
210
|
+
backend rejects (an unknown name, a name and an ID together, or a disabled Hero) fails with the backend's message, the
|
|
211
|
+
record line is not written, and no Worker is recorded. With `--json` the `session.chatHero` object names the Hero the
|
|
212
|
+
backend bound, and the human result shows it on a `hero` line. An older backend ignores the name and runs its default Hero.
|
|
201
213
|
- The new session's `userMetadata` holds `saga.id` (the Saga), `saga.role` (always `worker`), `saga.worker` (the `--role`
|
|
202
214
|
value), `saga.master` (the `--master` value), and `saga.item` only when `--item` is given. The backend checks the key
|
|
203
215
|
format (`^[a-z][a-z0-9._-]{0,63}$`), at most 16 entries, and value length (1 to 512 characters). The metadata is
|
|
@@ -210,7 +222,14 @@ hagi saga session create --saga demo --path "./My Project" --title "T1 implement
|
|
|
210
222
|
- If the append fails after the session was created, the command exits `1` and names the created session ID, in the
|
|
211
223
|
human output and as `session.sessionId` in `--json` with `ok` false.
|
|
212
224
|
- `--json` success is one object: `{ "sagaId": "demo", "command": "session create", "ok": true, "session": { "sessionId": "...", "userMetadata": { ... } }, "record": "<path to sessions.md>" }`.
|
|
213
|
-
- Exit codes: `0` created and recorded; `1` refused, or the record failed after creation; `2` usage error; `24` Saga not found.
|
|
225
|
+
- Exit codes: `0` created and recorded; `1` refused, or the record failed after creation; `2` usage error; `20` the backend rejected the request, as with a Hero it cannot bind; `24` Saga not found.
|
|
226
|
+
|
|
227
|
+
### Run records
|
|
228
|
+
|
|
229
|
+
Two commands replace the hand-written steps of the run prompt. Both take the Saga's path, as the other local Saga commands do.
|
|
230
|
+
|
|
231
|
+
- `hagi saga session list <saga-id> --path <root> [--json]` lists the Worker records in `runtime/sessions.md`: session ID, UTC creation time, role, item (`null` for `-`) and title, in file order. It is read-only and needs no token. A Saga with no `sessions.md` lists nothing and exits `0`. An unknown Saga exits `24`. `--json` returns `{ "sagaId", "command": "session list", "ok": true, "sessions": [...] }`.
|
|
232
|
+
- `hagi saga log append <saga-id> --message <text> --path <root>` appends one line, `- <UTC time> | <message>`, to `runtime/orchestrator-log.md`. It needs the execution token of the Saga owner, from `SAGA_EXECUTION_TOKEN` or `--token`, and refuses a token that does not match the lock with exit `1`. Whitespace and line breaks in the message collapse to one line. A blank message is a usage error (exit `2`) before any file or token check. The runtime directory is created when missing, and a redirected log file is refused before any byte is written.
|
|
214
233
|
|
|
215
234
|
## Items, amendments, and archive
|
|
216
235
|
|