@nodeint/migent 0.1.4 → 0.1.6

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.
Files changed (48) hide show
  1. package/README.md +194 -138
  2. package/dist/commands/agent.d.ts +8 -1
  3. package/dist/commands/agent.js +381 -56
  4. package/dist/commands/config.js +23 -9
  5. package/dist/commands/execute.d.ts +6 -1
  6. package/dist/commands/execute.js +105 -20
  7. package/dist/commands/init.d.ts +1 -0
  8. package/dist/commands/init.js +70 -63
  9. package/dist/commands/prepare.d.ts +1 -0
  10. package/dist/commands/prepare.js +14 -0
  11. package/dist/commands/repair.d.ts +1 -0
  12. package/dist/commands/repair.js +22 -0
  13. package/dist/commands/service.js +5 -4
  14. package/dist/commands/sessions.d.ts +24 -1
  15. package/dist/commands/sessions.js +165 -13
  16. package/dist/commands/skill.js +58 -32
  17. package/dist/commands/watch.d.ts +2 -1
  18. package/dist/commands/watch.js +130 -67
  19. package/dist/commands/workspace-registry.js +10 -1
  20. package/dist/display.d.ts +1 -0
  21. package/dist/display.js +24 -9
  22. package/dist/errors.d.ts +3 -0
  23. package/dist/errors.js +6 -0
  24. package/dist/exits.d.ts +12 -0
  25. package/dist/exits.js +33 -0
  26. package/dist/follow-log.d.ts +29 -0
  27. package/dist/follow-log.js +172 -0
  28. package/dist/fs-utils.d.ts +3 -0
  29. package/dist/fs-utils.js +26 -0
  30. package/dist/index.js +5 -1
  31. package/dist/migrate.js +2 -17
  32. package/dist/program.js +429 -177
  33. package/dist/session-row.d.ts +20 -0
  34. package/dist/session-row.js +21 -0
  35. package/dist/signals.d.ts +3 -0
  36. package/dist/signals.js +56 -0
  37. package/dist/templates/migent/SKILL.md +163 -56
  38. package/dist/templates/migent/references/config.md +52 -0
  39. package/dist/templates/migent/references/inspect.md +32 -0
  40. package/dist/templates/migent/references/schema-config.yaml +35 -0
  41. package/dist/templates/migent/references/schema-workflow.yaml +71 -0
  42. package/dist/templates/migent/references/sessions.md +65 -0
  43. package/dist/text.d.ts +4 -0
  44. package/dist/text.js +13 -0
  45. package/dist/version.d.ts +1 -0
  46. package/dist/version.js +3 -0
  47. package/dist/workspace.js +5 -12
  48. package/package.json +4 -4
@@ -0,0 +1,20 @@
1
+ export declare const SESSION_COLUMN: {
2
+ readonly updatedAt: 0;
3
+ readonly session: 1;
4
+ readonly workflow: 2;
5
+ readonly status: 3;
6
+ readonly execution: 4;
7
+ readonly decision: 5;
8
+ readonly outputs: 6;
9
+ readonly task: 7;
10
+ };
11
+ export interface SessionFields {
12
+ session: string;
13
+ workflow: string;
14
+ status: string;
15
+ execution: string;
16
+ decision: string;
17
+ outputs: string;
18
+ task: string;
19
+ }
20
+ export declare function sessionFields(row: readonly string[]): SessionFields;
@@ -0,0 +1,21 @@
1
+ export const SESSION_COLUMN = {
2
+ updatedAt: 0,
3
+ session: 1,
4
+ workflow: 2,
5
+ status: 3,
6
+ execution: 4,
7
+ decision: 5,
8
+ outputs: 6,
9
+ task: 7,
10
+ };
11
+ export function sessionFields(row) {
12
+ return {
13
+ session: row[SESSION_COLUMN.session] ?? "",
14
+ workflow: row[SESSION_COLUMN.workflow] ?? "",
15
+ status: row[SESSION_COLUMN.status] ?? "",
16
+ execution: row[SESSION_COLUMN.execution] ?? "",
17
+ decision: row[SESSION_COLUMN.decision] ?? "",
18
+ outputs: row[SESSION_COLUMN.outputs] ?? "",
19
+ task: row[SESSION_COLUMN.task] ?? "",
20
+ };
21
+ }
@@ -0,0 +1,3 @@
1
+ export declare function bindCancellationSignals(): () => void;
2
+ export declare function throwIfCliCancelled(): void;
3
+ export declare function delay(ms: number): Promise<void>;
@@ -0,0 +1,56 @@
1
+ import { CancellationRequested, raiseCancellation, resetCancellation } from "@nodeint/migent-kernel";
2
+ let pending = null;
3
+ const waiters = new Set();
4
+ function note(signalNumber) {
5
+ pending = new CancellationRequested(signalNumber);
6
+ for (const waiter of waiters)
7
+ waiter();
8
+ try {
9
+ raiseCancellation(signalNumber);
10
+ }
11
+ catch {
12
+ // The pending flag is what the follow loop and provider runner observe.
13
+ }
14
+ }
15
+ export function bindCancellationSignals() {
16
+ const onSigint = () => note(2);
17
+ const onSigterm = () => note(15);
18
+ process.on("SIGINT", onSigint);
19
+ process.on("SIGTERM", onSigterm);
20
+ return () => {
21
+ process.off("SIGINT", onSigint);
22
+ process.off("SIGTERM", onSigterm);
23
+ pending = null;
24
+ resetCancellation();
25
+ };
26
+ }
27
+ export function throwIfCliCancelled() {
28
+ const error = pending;
29
+ if (error === null)
30
+ return;
31
+ pending = null;
32
+ throw error;
33
+ }
34
+ export function delay(ms) {
35
+ throwIfCliCancelled();
36
+ return new Promise((resolve, reject) => {
37
+ let settled = false;
38
+ const finish = () => {
39
+ if (settled)
40
+ return;
41
+ settled = true;
42
+ clearTimeout(timer);
43
+ waiters.delete(wake);
44
+ try {
45
+ throwIfCliCancelled();
46
+ resolve();
47
+ }
48
+ catch (error) {
49
+ reject(error);
50
+ }
51
+ };
52
+ const timer = setTimeout(finish, ms);
53
+ const wake = () => finish();
54
+ waiters.add(wake);
55
+ });
56
+ }
@@ -1,62 +1,169 @@
1
1
  ---
2
2
  name: migent
3
- description: Set up Migent in a project, or configure, run, inspect, and resume its workflows. Use when the user asks about Migent configuration, workflows, sessions, stages, or published outputs.
3
+ description: Set up Migent in a project, or configure, run, inspect, and resume its workflows with the migent CLI. Use when the user asks about Migent, .migent/ configuration, workflows, roles, models, sessions, stages, doctor, or published outputs.
4
4
  ---
5
5
 
6
6
  # Migent
7
7
 
8
- Use Migent as the control plane for the project's multi-stage agent workflows.
9
-
10
- ## Working rules
11
-
12
- - For an existing project, work from the root containing
13
- `.migent/config.yaml`. To set up a new project, run `migent init` from
14
- its root and follow the CLI's provider and model prompts or flags.
15
- - Read `.migent/config.yaml` and the relevant file under
16
- `.migent/workflows/` before changing or running a workflow.
17
- - Run `migent doctor` after editing configuration or workflows.
18
- `migent config model` and `migent config role` run it after a write.
19
- - Treat `.migent/sessions/` as generated, resumable state. Do not edit its
20
- files directly.
21
- - Preserve the user's task wording when passing `--task`.
22
- - Before continuing a stopped session, inspect the command's `stop_reason` and
23
- latest execution. Fix the cause before retrying.
24
-
25
- ## Choose the command
26
-
27
- - Start a workflow: `migent start <workflow> --task "<task>"`. `<workflow>`
28
- is the workflow id, or a path to a workflow file. An omitted `id` uses the
29
- file name. If its
30
- `requires` block names a prerequisite workflow and decision, find a matching
31
- completed session and add `--prior <session-id>`.
32
- - Resume an active session: `migent continue <session-id>`.
33
- - Advance exactly one eligible stage: `migent stage <session-id>`.
34
- - List recorded sessions: `migent sessions` or `migent sessions --json`.
35
- - Inspect a snapshot: `migent watch <session-id> --once --json`.
36
- - Follow new events: `migent watch <session-id>`.
37
- - Run a configured role outside a workflow only when the user asks for ad hoc
38
- role execution: `migent agent start --role <role> --prompt "<prompt>"`.
39
- - Read `.migent/config.yaml`: `migent config show`.
40
- - Change a model entry: `migent config model <name> --provider <provider> --model <model-id>`.
41
- This updates every role and stage that uses the name.
42
- - Point one role at a model without changing a shared entry:
43
- `migent config role <role> --provider <provider> --model <model-id>`.
44
- `migent config role <role> --model-name <name>` points it at a name that
45
- already exists. Add `--json` to read the result.
46
-
47
- Workflow commands emit progress on stderr and one result object on stdout.
48
- Report the session ID, session status, stop reason, decisions, and published
49
- outputs that matter to the user. A stopped active session is resumable; do not
50
- describe it as completed.
51
-
52
- `retry_exhausted` means the stage has used its total failed-attempt allowance;
53
- `--attempts` on `continue` sets a new total, not extra retries.
54
- `revisions_exhausted` leaves the session active. `continue` resets revision
55
- counts for the existing session, allowing another batch up to `max_revisions`.
56
- `dispatch_limit` applies to the current command; continue the same session if
57
- further stages are appropriate. Do not start a replacement session to reset
58
- these limits.
59
-
60
- Published output paths are relative to
61
- `.migent/sessions/<session-id>/`. Prefer the paths reported by Migent over
62
- guessing artifact locations.
8
+ Migent runs a project's multi-stage agent workflows from the `migent` CLI.
9
+ A workflow is a set of stages. A stage runs a role, or runs `verify` alone when `role` is omitted. A role uses a model name
10
+ defined in `.migent/config.yaml`. Each run is a session, stored under
11
+ `.migent/sessions/<session-id>/`.
12
+
13
+ This skill is already in the prompt. Do not open its file again.
14
+
15
+ ## Rules
16
+
17
+ - Work from the project root, the directory containing `.migent/config.yaml`.
18
+ - Read `.migent/config.yaml` and the relevant `.migent/workflows/` file before
19
+ running a workflow.
20
+ - Before writing either, read `.agents/skills/migent/references/schema-config.yaml`
21
+ and `schema-workflow.yaml` in the same folder. A key absent from them is
22
+ ignored. Then run `migent doctor --json`; if it reports an outdated schema,
23
+ run `migent migrate --yes`.
24
+ - You have no terminal for prompts. Pass `--no-input` (or set
25
+ `MIGENT_NO_INPUT=1`) to `init`, `config model`, and `config role`, and give
26
+ every value as a flag.
27
+ - Do not edit generated session state: `manifest.yaml`, `status.json`,
28
+ `events.jsonl`, `metrics.json`, or anything under `executions/`.
29
+ - Keep the user's task wording. Do not read `task.md` or the documents it
30
+ names; the stage agent does.
31
+ - Never start a replacement session to reset limits or get past `blocked`.
32
+ Resume the same one.
33
+
34
+ ## Run a task
35
+
36
+ `<workflow>` is a workflow id or a path to a workflow file.
37
+
38
+ One-line task. The command runs until the session stops:
39
+
40
+ ```
41
+ migent session run --workflow <workflow> --task "<task>"
42
+ ```
43
+
44
+ Longer task. `<some-id>` is a lowercase slug such as `wave-3`:
45
+
46
+ ```
47
+ migent session prepare <some-id> --workflow <workflow>
48
+ ```
49
+
50
+ Write the task, unchanged, to `.migent/sessions/<some-id>/task.md` (plus any
51
+ files next to it). Do not edit `task.md` once the first stage has started.
52
+ Then:
53
+
54
+ ```
55
+ migent session run --session <some-id> --workflow <workflow>
56
+ ```
57
+
58
+ Dispatch only one stage: add `--once`.
59
+
60
+ ### Read the result
61
+
62
+ A workflow run prints plain lines on stderr and leaves stdout empty. It does
63
+ not print JSON, and it does not print the stage report.
64
+
65
+ - `session_id: <id>` when the session is created.
66
+ - `stage <id> · attempt <n> · <HH:MM:SS> · <provider>/<model> (<options>).` when a stage starts. A description follows the model when the stage has one.
67
+ - `stage <id> · attempt <n> · <duration> · <outcome>.` when it finishes. A decision is `decision=<value>` on that line.
68
+ - A completed session adds `completed · <duration>` and one `artifact: <absolute-path>` line per published file. The path starts at the filesystem root and names the published file, so the suffix stays, such as `plan.md`. Report those paths.
69
+ - Exit 1, 3, 6, and 8 also print `response: executions/<id>/response.md`. Read that file to see why it stopped.
70
+ - Exit 7 prints `verify: executions/<id>/turns/01/verify.md`.
71
+ - A session that stops before it is completed ends with `Resume with:` and `migent session continue <session-id>`.
72
+
73
+ - Do not pass `--verbose` or `--progress`. Do not use `session follow`.
74
+ - If the command runs in the background, wait for its completion notice. Do not
75
+ add a watcher that waits on the same exit.
76
+
77
+ ### Exit codes
78
+
79
+ Read the exit code first. Exit 0 with `completed ·` is a completed session.
80
+ Exit 0 without that line is `--once` after a complete stage.
81
+
82
+ | Exit | Meaning | What to do |
83
+ | --- | --- | --- |
84
+ | 0 | Completed, or with `--once` the stage is complete | Report each `artifact:` path when the session completed. |
85
+ | 1 | Blocked, or with `--once` the stage is not complete | If the stage line says `blocked`: read the `response:` path, then resume with the user's answer (below), or plain `session continue` once the blocker is fixed in the workspace. Otherwise `session continue` keeps going. |
86
+ | 2 | Configuration error | Run `migent doctor --json`, fix config. |
87
+ | 3 | A stage failed and the command did not wait | Read the `response:` path, fix the cause, `session continue`. Continue runs the stage and does not sleep until an old `retry_at`. |
88
+ | 4 | A route would exceed `max_revisions` | Review why the stage keeps being revised, then `session continue` for another batch. |
89
+ | 5 | `--max-dispatches` spent | `session continue` if more stages are appropriate. |
90
+ | 6 | A stage's `verify` stayed red | Read the `response:` path, fix the cause, `session continue`. |
91
+ | 7 | A stage with no role failed `verify` | Read the `verify:` path, fix the tree, `session continue`. That reruns the commands and does not open a provider. |
92
+ | 8 | `--once` or `--stage` hit a provider quota and did not wait | Read the `response:` path. `session continue` runs the stage and does not sleep until the recorded `retry_at`. |
93
+ | 130 | Cancelled, including a wait that was disarmed | Ask the user before resuming. Continue does not sleep until an old `retry_at`. |
94
+
95
+ A stopped session that is not `completed` is resumable. Do not call it done.
96
+
97
+ ### Resume
98
+
99
+ ```
100
+ migent session continue <session-id>
101
+ ```
102
+
103
+ Same command for a workflow session and a role session. Read `session_status`, then use one row.
104
+
105
+ | Kind | When | What to run |
106
+ | --- | --- | --- |
107
+ | Workflow | Not `completed`, including a blocker already fixed in the workspace | The command above. Runs until the session stops and resets revision counts. A blocked stage runs again. |
108
+ | Workflow | The user answered a blocked stage | Add `--reply "<reply>"`. That text is the whole prompt body. |
109
+ | Workflow | One stage, then stop | Add `--once`. Revision counts stay. |
110
+ | Role | `cancelled` | The command above. The cut-off turn resumes in the same execution. Omit `--reply`. |
111
+ | Role | `active` | The command above. The last prompt is sent again. |
112
+ | Role | `blocked` | Add `--reply "<reply>"`. That is the next user turn. With no reply, the agent is only told to continue. |
113
+ | Role | `completed` | Leave it stopped. Add `--reply` only to give a new turn. |
114
+
115
+ `--reply-file <path>` is a longer reply. Pass only one of `--reply` and `--reply-file`. Do not pass `--once` or `--stage` on a role session.
116
+
117
+ ## Check a session
118
+
119
+ ```
120
+ migent session show <session-id> --json
121
+ migent session list --latest --json
122
+ ```
123
+
124
+ `show` gives status, latest execution, decision, and outputs. `list --latest`
125
+ is the newest session, or `null`. Report the session ID, status, stop reason,
126
+ decisions, and the outputs that matter. Output paths are relative to
127
+ `.migent/sessions/<session-id>/`; use the paths Migent reports.
128
+
129
+ ## Set up a project
130
+
131
+ ```
132
+ migent init --no-input --provider <provider> --model <model-id> [--preset implement|plan] [--skill]
133
+ migent doctor --json
134
+ ```
135
+
136
+ `--provider` and `--model` go together. The default preset is `implement`.
137
+ `--skill` installs this skill; `migent skill update` refreshes it.
138
+
139
+ ## Change models
140
+
141
+ Edit a model name (updates every role and stage that uses it):
142
+
143
+ ```
144
+ migent config model <name> --provider <provider> --model <model-id> --no-input --json
145
+ ```
146
+
147
+ Show the config with `migent config`, `migent config model --json`, or
148
+ `migent config role --json`.
149
+
150
+ ## Look up anything else
151
+
152
+ This skill covers the common path. Every command takes `--help`; use it before
153
+ guessing a flag:
154
+
155
+ ```
156
+ migent --help
157
+ migent session run --help
158
+ ```
159
+
160
+ References, read only when the task needs them:
161
+
162
+ | File | Read when |
163
+ | --- | --- |
164
+ | `references/schema-config.yaml`, `references/schema-workflow.yaml` | Writing config or a workflow. |
165
+ | `references/sessions.md` | Prerequisite session (`--prior`), several blocked stages (`--stage`), resuming a cancelled session, raising limits, adopting workflow edits (`--refresh-workflow`). |
166
+ | `references/config.md` | Running one role, pointing roles at another model, overriding one role, role instructions. |
167
+ | `references/inspect.md` | Filtering `session list`, comparing runs with `session metrics`, `session follow`. |
168
+
169
+ All paths are under `.agents/skills/migent/`.
@@ -0,0 +1,52 @@
1
+ # Roles and model configuration
2
+
3
+ Write commands take `--no-input --json`. The JSON includes the doctor result.
4
+
5
+ ## Run one role
6
+
7
+ Without `--workflow`, `session run` runs a single role:
8
+
9
+ ```
10
+ migent session run --role <role> --prompt "<prompt>"
11
+ ```
12
+
13
+ | Flag | Meaning |
14
+ | --- | --- |
15
+ | `--file <path>`, `--stdin` | Supply a long prompt. |
16
+ | `--task` | Labels a new role session. Cannot be combined with `--session`. |
17
+ | `--session <session-id>` | Sends a new prompt to an earlier role session. `session continue <session-id>` resumes a stopped role session. |
18
+ | `--provider`, `--model` | Override the role for this turn. Pass together. |
19
+ | `--option KEY=VALUE` | Override a provider option for this turn. |
20
+ | `--json` | Print one result object (the role result, with `outcome_status`; not the workflow result). |
21
+
22
+ Without `--json` it prints a table. Exit 0 means the outcome is complete, 1
23
+ not complete. `roles.<role>.instructions`, when set, is prepended to the prompt.
24
+
25
+ ## Model names
26
+
27
+ Provider options on a model name: `--option KEY=VALUE` to set,
28
+ `--clear-option KEY` to remove.
29
+
30
+ ```
31
+ migent config model <name> --provider <provider> --model <model-id> --no-input --json
32
+ ```
33
+
34
+ ## Point roles at an existing model name
35
+
36
+ The value is a name from `models`, not a provider model id.
37
+
38
+ ```
39
+ migent config role <role>... --model-name <name> --no-input --json
40
+ ```
41
+
42
+ ## Override one role without touching the shared name
43
+
44
+ ```
45
+ migent config role <role> --provider <provider> --model <model-id> --no-input --json
46
+ ```
47
+
48
+ ## Role instructions
49
+
50
+ `roles.<name>.instructions` is an optional list of strings. A stage prompt
51
+ includes it before that stage's instructions. A role run prepends it to the
52
+ prompt.
@@ -0,0 +1,32 @@
1
+ # Inspecting many sessions
2
+
3
+ For one session use `migent session show <session-id> --json` (SKILL.md).
4
+
5
+ ## List
6
+
7
+ ```
8
+ migent session list --workflow <id> --status completed --limit 5 --json
9
+ ```
10
+
11
+ - Output is a JSON array. `--latest` gives one object, or `null`; do not
12
+ combine it with `--limit`.
13
+ - `--status` is one of `active|prepared|completed|blocked|cancelled|corrupt`.
14
+ A session whose `status.json` does not parse is listed as `corrupt`.
15
+ - JSON rows omit the task text.
16
+
17
+ ## Metrics
18
+
19
+ ```
20
+ migent session metrics --json
21
+ ```
22
+
23
+ - One session prints its `metrics.json`. Several print one object per
24
+ line, newest first. Only a completed session has this file. `--workflow`,
25
+ `--status`, and `--limit` filter those rows.
26
+ - Read `usage_missing` and `uncaptured_turns` before comparing totals.
27
+ - `stage_attempt` is not a retry count.
28
+
29
+ ## Follow
30
+
31
+ `session follow` streams the event trace for a person at a terminal. Do not use
32
+ it or `--cursor` to coordinate a run.
@@ -0,0 +1,35 @@
1
+ # A missing schema_version is 0. Commands refuse the file while it is older than this Migent.
2
+ schema_version: 2
3
+
4
+ # models.<name>.model is the provider model id.
5
+ # roles.<name>.default_model and a stage model are this name.
6
+ # Options merge in order: model, then role, then stage.
7
+ # Only keys the adapter marks overridable are stored on the provider session.
8
+ models:
9
+ planner:
10
+ provider: grok
11
+ model: grok-4.7
12
+ # grok accepts reasoning-effort (overridable), max_turns, tools, disallowed_tools,
13
+ # permission_mode (default, acceptEdits, auto, dontAsk, bypassPermissions, plan),
14
+ # rules, allow, deny, and sandbox.
15
+ # agy accepts effort (low, medium, high, xhigh, max; overridable), mode (accept-edits, auto, plan),
16
+ # agent, sandbox (true or false), and skip_permissions (true or false).
17
+ # claude accepts effort (low, medium, high, xhigh, max; overridable), permission_mode
18
+ # (acceptEdits, auto, bypassPermissions, manual, dontAsk, plan), tools, allowed_tools,
19
+ # disallowed_tools, max_budget_usd, fallback_model, and append_system_prompt.
20
+ # codex accepts model_reasoning_effort (overridable). Any other key of letters, digits,
21
+ # dots, underscores, and hyphens is passed through as codex exec -c.
22
+ options:
23
+ reasoning-effort: high
24
+
25
+ roles:
26
+ planner:
27
+ default_model: planner
28
+ # Included in every prompt for this role, before stage instructions.
29
+ # A role run prepends the same list to the prompt.
30
+ instructions:
31
+ - Break the task into a reviewable plan.
32
+ options:
33
+ reasoning-effort: medium
34
+ reviewer:
35
+ default_model: planner
@@ -0,0 +1,71 @@
1
+ # A missing schema_version is 0. Commands refuse the file while it is older than this Migent.
2
+ schema_version: 2
3
+ concurrency: 1
4
+
5
+ # When id is omitted, the id is the file name without .yaml.
6
+ id: reference
7
+
8
+ constraints:
9
+ - Stay within the task.
10
+
11
+ # requires.workflow names another file in .migent/workflows.
12
+ requires:
13
+ workflow: plan
14
+
15
+ stages:
16
+ - id: prepare
17
+ description: Check the tree before the draft.
18
+ # No role: Migent runs verify and does not start an agent.
19
+ verify:
20
+ - pnpm build
21
+ verify_timeout: 1800
22
+ depends_on: []
23
+
24
+ - id: draft
25
+ description: Write the draft.
26
+ role: planner
27
+ # model is a name under models in config.yaml, not a provider model id.
28
+ model: planner
29
+ # Options merge in order: model, then role, then stage.
30
+ # Only keys the adapter marks overridable are stored on the provider session.
31
+ options:
32
+ reasoning-effort: high
33
+ depends_on:
34
+ - prepare
35
+ # max_revisions is allowed only when a route returns to this stage.
36
+ max_revisions: 2
37
+ instructions:
38
+ - Write the draft.
39
+ produces:
40
+ artifact: draft.md
41
+
42
+ - id: review
43
+ role: reviewer
44
+ depends_on:
45
+ - draft
46
+ # resume_from must be one entry in depends_on. It continues that stage's provider session.
47
+ session:
48
+ resume_from: draft
49
+ instructions:
50
+ - Review the draft.
51
+ # verify runs after status complete and must sit on every path to complete.
52
+ # A stage artifact cannot be named verify.md.
53
+ verify:
54
+ - pnpm test
55
+ # max_verify defaults to 3. verify_timeout is seconds for the whole list. Both require verify.
56
+ max_verify: 3
57
+ verify_timeout: 900
58
+ # Route keys must match decision.values. A destination is a stage id, complete, or a non-empty list of stage ids.
59
+ decision:
60
+ values:
61
+ - approved
62
+ - revise
63
+ routes:
64
+ approved: complete
65
+ revise: draft
66
+
67
+ # An output artifact must match produces.artifact on from_stage.
68
+ outputs:
69
+ - name: draft
70
+ from_stage: draft
71
+ artifact: draft.md
@@ -0,0 +1,65 @@
1
+ # Sessions: uncommon run and resume cases
2
+
3
+ The everyday commands are in SKILL.md. This file covers the rest.
4
+
5
+ ## Prerequisite session (`--prior`)
6
+
7
+ If the workflow's `requires` block names a prerequisite workflow and decision,
8
+ find the session:
9
+
10
+ ```
11
+ migent session list --workflow <workflow-id> --status completed --json
12
+ ```
13
+
14
+ Then pass its id with `--prior <session-id>`. `session continue` accepts
15
+ `--prior` too.
16
+
17
+ ## Several blocked stages
18
+
19
+ When more than one stage is blocked, `session continue` needs the stage:
20
+
21
+ ```
22
+ migent session continue <session-id> --stage <stage> --reply "<reply>"
23
+ ```
24
+
25
+ The other stages stay blocked.
26
+
27
+ ## Cancelled session (exit 130)
28
+
29
+ Ask the user first. `session continue <session-id>` resumes that same
30
+ execution. A cut-off verify runs again. A cancelled stage with no role
31
+ reruns its verify list in place and does not open a provider. Role status
32
+ and `--reply` are in the skill's Resume section.
33
+
34
+ ## Limits
35
+
36
+ Accepted by workflow `session run` and by `session continue`.
37
+
38
+ | Flag | Meaning |
39
+ | --- | --- |
40
+ | `--max-dispatches <n>` | Stage dispatches allowed in this command (default 20). |
41
+ | `--unlimited-dispatches` | Removes the dispatch ceiling. Use only if the user agrees. |
42
+
43
+ A failed stage stays stopped until `session continue`. That command runs the
44
+ stage and does not sleep until an old `retry_at`. Exit 3 is `stage_failed`.
45
+ Exit 8 is `quota` for `--once` and `--stage`, which do not wait. Exit 130
46
+ during a wait disarms the timer. A single role result uses 0, 1, and 130.
47
+ Exit 6 remains only the path that reopened more than one role execution.
48
+
49
+ ## `--once` and revision counts
50
+
51
+ `session continue <id>` resets revision counts. `session continue <id> --once`
52
+ advances one stage and does not.
53
+
54
+ ## Config changed during a session
55
+
56
+ A session keeps the workflow, models, and role instructions it started with.
57
+ Later edits warn on stderr and do not change it. Run `migent doctor --json`
58
+ and tell the user. To adopt the current versions:
59
+
60
+ ```
61
+ migent session continue <session-id> --refresh-workflow
62
+ migent session run --session <session-id> --workflow <workflow> --refresh-workflow
63
+ ```
64
+
65
+ The second form is for starting a prepared session.
package/dist/text.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export declare function text(value: string | null | undefined): string | null;
2
+ export declare function optionalText(value: unknown): string | null;
3
+ /** Keep leading and trailing breaks so a one-line task check sees them. */
4
+ export declare function rawText(value: unknown): string | null;
package/dist/text.js ADDED
@@ -0,0 +1,13 @@
1
+ export function text(value) {
2
+ if (typeof value !== "string")
3
+ return null;
4
+ const stripped = value.trim();
5
+ return stripped === "" ? null : stripped;
6
+ }
7
+ export function optionalText(value) {
8
+ return text(typeof value === "string" ? value : null);
9
+ }
10
+ /** Keep leading and trailing breaks so a one-line task check sees them. */
11
+ export function rawText(value) {
12
+ return typeof value === "string" ? value : null;
13
+ }
@@ -0,0 +1 @@
1
+ export declare const PACKAGE_VERSION: string;
@@ -0,0 +1,3 @@
1
+ import { createRequire } from "node:module";
2
+ const { version } = createRequire(import.meta.url)("../package.json");
3
+ export const PACKAGE_VERSION = version;
package/dist/workspace.js CHANGED
@@ -1,6 +1,7 @@
1
- import { readFileSync, statSync } from "node:fs";
1
+ import { readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { ConfigurationError } from "@nodeint/migent-kernel";
4
+ import { isFile } from "./fs-utils.js";
4
5
  let invocationCwd = null;
5
6
  export function setInvocationCwd(cwd) {
6
7
  invocationCwd = cwd === undefined ? null : path.resolve(cwd);
@@ -24,12 +25,12 @@ export function resolvePrompt(args) {
24
25
  if (args.promptStdin) {
25
26
  const text = readFileSync(0, "utf8");
26
27
  if (text === "")
27
- throw new Error("Prompt from stdin is empty.");
28
+ throw new ConfigurationError("Prompt from stdin is empty.");
28
29
  return text;
29
30
  }
30
31
  if (args.promptFile == null) {
31
32
  if (args.prompt == null)
32
- throw new Error("Pass one of --prompt, --file, or --stdin.");
33
+ throw new ConfigurationError("Pass one of --prompt, --file, or --stdin.");
33
34
  return args.prompt;
34
35
  }
35
36
  try {
@@ -37,14 +38,6 @@ export function resolvePrompt(args) {
37
38
  }
38
39
  catch (error) {
39
40
  const reason = error instanceof Error ? error.message : String(error);
40
- throw new Error(`Unable to read prompt file: ${args.promptFile} (${reason})`);
41
- }
42
- }
43
- function isFile(filePath) {
44
- try {
45
- return statSync(filePath).isFile();
46
- }
47
- catch {
48
- return false;
41
+ throw new ConfigurationError(`Unable to read prompt file: ${args.promptFile} (${reason})`);
49
42
  }
50
43
  }