@nodeint/migent 0.0.0-stage → 0.1.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Migent contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,207 @@
1
- # Temporary Holding Version
1
+ # Migent
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Compose AI coding agents into repeatable engineering workflows.**
4
+
5
+ Use the right model for each stage of the job.
6
+
7
+ Migent connects coding-agent CLIs from different providers through explicit,
8
+ repository-defined workflows. One model can plan, another can review, and the
9
+ first can revise—while Migent carries artifacts between them and remembers
10
+ where the process is.
11
+
12
+ ## Contents
13
+
14
+ - [Migent](#migent)
15
+ - [Contents](#contents)
16
+ - [Why Migent?](#why-migent)
17
+ - [Supported CLIs](#supported-clis)
18
+ - [Quickstart](#quickstart)
19
+ - [Install](#install)
20
+ - [Upgrade](#upgrade)
21
+ - [Create a project](#create-a-project)
22
+ - [Run](#run)
23
+ - [Concepts](#concepts)
24
+ - [Current scope](#current-scope)
25
+ - [Documentation](#documentation)
26
+ - [Development](#development)
27
+ - [License](#license)
28
+
29
+ ## Why Migent?
30
+
31
+ Calling two agent CLIs from a shell script is easy. Reliably coordinating them
32
+ across reviews, revisions, failures, and resumed sessions is not.
33
+
34
+ Migent is built around three ideas:
35
+
36
+ - **Use models for what they do best.** Assign each role to a provider and model
37
+ suited to the work, rather than asking one agent to do everything.
38
+ - **Treat AI engineering process as code.** Keep stages, handoffs, review gates,
39
+ and revision policies in version control beside the project they govern.
40
+ - **Keep orchestration explicit.** The team defines the process; models execute
41
+ roles inside it. A supervisor model does not invent or dynamically control
42
+ the workflow.
43
+
44
+ **Models describe execution. Roles describe intent.** Changing the model behind
45
+ a role does not require rewriting the workflow.
46
+
47
+ **Common workflow model, native provider capabilities.** Migent coordinates
48
+ the process, while each provider CLI remains responsible for authentication,
49
+ agent execution, and its own tools and options.
50
+
51
+ ```mermaid
52
+ flowchart LR
53
+ A[Task] --> B[Planner - Codex]
54
+ B -->|plan.md| C[Reviewer - Grok]
55
+ C -->|revise| B
56
+ C -->|approved| D[Complete]
57
+ ```
58
+
59
+ ## Supported CLIs
60
+
61
+ Migent drives each provider through its headless CLI. Install and sign in to the
62
+ ones your configuration names.
63
+
64
+ | Provider | CLI |
65
+ | -------- | -------- |
66
+ | Claude | `claude` |
67
+ | Codex | `codex` |
68
+ | Grok | `grok` |
69
+
70
+ ## Quickstart
71
+
72
+ Node.js 22+ on macOS or Linux, and authenticated provider CLIs named by your
73
+ configuration.
74
+
75
+ ### Install
76
+
77
+ ```bash
78
+ npm install -g @nodeint/migent
79
+ ```
80
+
81
+ Verify with `migent --version`.
82
+
83
+ ### Upgrade
84
+
85
+ ```bash
86
+ npm install -g @nodeint/migent@latest
87
+ ```
88
+
89
+ ### Create a project
90
+
91
+ From the project where agents will work:
92
+
93
+ ```bash
94
+ migent init --preset plan
95
+ ```
96
+
97
+ `init` writes the config, a plan-and-review workflow, and a gitignore for local
98
+ session state:
99
+
100
+ ```text
101
+ .migent/
102
+ ├── config.yaml
103
+ ├── .gitignore
104
+ └── workflows/
105
+ └── plan.yaml
106
+ ```
107
+
108
+ In a terminal, pick the provider, model, and prompted options from the lists.
109
+ Pass `--provider` and `--model` together when input is not a terminal. Commit
110
+ `config.yaml` and `workflows/`. Leave `.migent/sessions/` untracked.
111
+
112
+ Model and role shape is in [Providers and model configuration](https://github.com/nodeint/migent/blob/main/docs/providers.md).
113
+ A full plan workflow is in [Writing workflows](https://github.com/nodeint/migent/blob/main/docs/workflows.md#complete-example).
114
+
115
+ ### Run
116
+
117
+ From that project or any of its subdirectories:
118
+
119
+ ```bash
120
+ migent start plan --task "Plan the account settings redesign"
121
+ ```
122
+
123
+ Migent runs the next eligible stage until the workflow completes or stops.
124
+ Progress goes to stderr. Stdout is one JSON result.
125
+
126
+ ```bash
127
+ migent sessions
128
+ migent watch <session-id>
129
+ migent continue <session-id>
130
+ ```
131
+
132
+ Command fields and exit codes are in
133
+ [CLI commands and execution controls](https://github.com/nodeint/migent/blob/main/docs/cli.md). Session files are in
134
+ [Sessions and workflow composition](https://github.com/nodeint/migent/blob/main/docs/sessions.md).
135
+
136
+ ## Concepts
137
+
138
+ A workflow connects stages through dependencies and explicit decision routes.
139
+
140
+ - A **model** identifies a provider model and its execution options.
141
+ - A **role** names a kind of work and selects its default model.
142
+ - A **stage** assigns work to a role and may declare dependencies, an artifact,
143
+ a decision, or both.
144
+ - An **artifact** is a named file produced by a successful stage and stored with
145
+ the workflow session.
146
+ - A **decision** selects the next route, including a route back for revision.
147
+ - A **session** records executions, events, decisions, and artifacts so work can
148
+ be inspected or resumed.
149
+
150
+ Use `depends_on` to give a stage upstream artifacts. Use `session.resume_from`
151
+ when the stage must also continue a provider's prior conversational session.
152
+
153
+ ## Current scope
154
+
155
+ Migent is a local, file-backed orchestration layer for provider CLIs. It does
156
+ not replace their agent runtimes, and it does not hide their distinctive
157
+ capabilities behind a lowest-common-denominator API.
158
+
159
+ Today, Migent supports explicit stage routing, review loops, local session
160
+ history, provider-session resume, prerequisite workflows, and standalone role
161
+ execution. A machine-local registry service records workspaces
162
+ so another tool can ask which projects exist.
163
+
164
+ ## Documentation
165
+
166
+ - [Writing workflows](https://github.com/nodeint/migent/blob/main/docs/workflows.md)
167
+ - [Providers and model configuration](https://github.com/nodeint/migent/blob/main/docs/providers.md)
168
+ - [Sessions and workflow composition](https://github.com/nodeint/migent/blob/main/docs/sessions.md)
169
+ - [CLI commands and execution controls](https://github.com/nodeint/migent/blob/main/docs/cli.md)
170
+
171
+ Run `migent <command> --help` for the exact command contract, output fields,
172
+ and exit codes.
173
+
174
+ ## Development
175
+
176
+ The pnpm workspace contains four packages: the `@nodeint/migent` CLI and its
177
+ internal libraries `@nodeint/migent-kernel`, `@nodeint/migent-adapters`, and
178
+ `@nodeint/migent-registry`. The libraries have no stable API; depend on
179
+ `@nodeint/migent`.
180
+
181
+ ```bash
182
+ pnpm install
183
+ pnpm build
184
+ pnpm test
185
+ pnpm migent --help # run the local build
186
+ ```
187
+
188
+ ### Releasing
189
+
190
+ All four packages share one version. Bump it, commit, and push a matching tag:
191
+
192
+ ```bash
193
+ pnpm -r exec npm pkg set version=0.2.0
194
+ pnpm install
195
+ git commit -am "Release 0.2.0"
196
+ git tag v0.2.0
197
+ git push origin main v0.2.0
198
+ ```
199
+
200
+ The tag runs `.github/workflows/release.yml`, which builds, tests, packs, and
201
+ stages each package through npm trusted publishing. Nothing goes live until a
202
+ maintainer approves the staged versions on npmjs.com (Staged Packages tab) or
203
+ with `npm stage approve`, kernel first and `@nodeint/migent` last.
204
+
205
+ ## License
206
+
207
+ Migent is licensed under the [MIT License](https://github.com/nodeint/migent/blob/main/LICENSE).
@@ -0,0 +1,14 @@
1
+ import { AgentToolRunner } from "@nodeint/migent-kernel";
2
+ export declare function dispatchAgent(workspace: string, args: {
3
+ role: string;
4
+ task?: string | null;
5
+ sessionId?: string | null;
6
+ provider?: string | null;
7
+ model?: string | null;
8
+ options?: readonly string[];
9
+ prompt?: string | null;
10
+ promptFile?: string | null;
11
+ promptStdin?: boolean;
12
+ asJson?: boolean;
13
+ runner?: AgentToolRunner | null;
14
+ }): Promise<number>;
@@ -0,0 +1,97 @@
1
+ import { AgentToolRunner, CancellationRequested, ConfigurationError, createAgentSession, log, raiseCancellation, requireAgentSession, resolveRoleTarget, SessionStore, } from "@nodeint/migent-kernel";
2
+ import { printAgent, printError, printNotice } from "../display.js";
3
+ import { cliHooks } from "../hooks.js";
4
+ import { requireCurrentSchema } from "../migrate.js";
5
+ import { adapterMap, parseOptions } from "../provider.js";
6
+ import { resolvePrompt } from "../workspace.js";
7
+ export async function dispatchAgent(workspace, args) {
8
+ requireCurrentSchema(workspace);
9
+ const parsed = parseOptions(args.options ?? []);
10
+ const target = resolveRoleTarget(workspace, args.role, {
11
+ provider: args.provider ?? null,
12
+ model: args.model ?? null,
13
+ options: Object.keys(parsed).length > 0 ? parsed : null,
14
+ });
15
+ const [resolvedSessionId, createdSession] = resolveSession(workspace, args.sessionId ?? null, args.role, args.task ?? null);
16
+ let resumeExecutionId = null;
17
+ if (!createdSession) {
18
+ const previous = new SessionStore(workspace).latestExecution(resolvedSessionId);
19
+ if (previous !== null)
20
+ resumeExecutionId = previous.executionId;
21
+ }
22
+ const optionLabel = Object.entries(target.options)
23
+ .map(([key, value]) => `${key}: ${value}`)
24
+ .join(", ") || "default";
25
+ printNotice(`agent ${args.role} · ${target.provider}/${target.model} (${optionLabel}).`);
26
+ const onSigint = () => {
27
+ try {
28
+ raiseCancellation(2);
29
+ }
30
+ catch {
31
+ // The runner observes the pending cancellation.
32
+ }
33
+ };
34
+ const onSigterm = () => {
35
+ try {
36
+ raiseCancellation(15);
37
+ }
38
+ catch {
39
+ // The runner observes the pending cancellation.
40
+ }
41
+ };
42
+ process.on("SIGINT", onSigint);
43
+ process.on("SIGTERM", onSigterm);
44
+ let result;
45
+ try {
46
+ const runner = args.runner ?? cliHooks.runner ?? new AgentToolRunner(adapterMap());
47
+ result = await runner.run({
48
+ provider: target.provider,
49
+ model: target.model,
50
+ options: { ...target.options },
51
+ prompt: resolvePrompt({
52
+ prompt: args.prompt ?? null,
53
+ promptFile: args.promptFile ?? null,
54
+ promptStdin: args.promptStdin ?? false,
55
+ }),
56
+ workspace,
57
+ sessionId: resolvedSessionId,
58
+ resumeExecutionId,
59
+ stageId: args.role,
60
+ });
61
+ }
62
+ catch (error) {
63
+ if (error instanceof CancellationRequested) {
64
+ log(error.message);
65
+ return 130;
66
+ }
67
+ if (error instanceof ConfigurationError)
68
+ throw error;
69
+ if (error instanceof Error) {
70
+ printError(error.message);
71
+ return 2;
72
+ }
73
+ throw error;
74
+ }
75
+ finally {
76
+ process.off("SIGINT", onSigint);
77
+ process.off("SIGTERM", onSigterm);
78
+ }
79
+ if (createdSession)
80
+ printNotice(`session_id: ${result.session_id}`);
81
+ if (args.asJson)
82
+ process.stdout.write(`${JSON.stringify(result)}\n`);
83
+ else
84
+ printAgent({ ...result }, args.role, target.provider, target.model);
85
+ return result.outcome_status === "complete" ? 0 : 1;
86
+ }
87
+ function resolveSession(workspace, sessionId, role, task) {
88
+ if (sessionId !== null && typeof task === "string" && task.trim() !== "") {
89
+ throw new ConfigurationError("--task cannot be combined with a session.");
90
+ }
91
+ if (sessionId !== null) {
92
+ requireAgentSession(workspace, sessionId);
93
+ return [sessionId, false];
94
+ }
95
+ const taskSummary = (task ?? role).trim();
96
+ return [createAgentSession(workspace, role, taskSummary), true];
97
+ }
@@ -0,0 +1,35 @@
1
+ import { type AgentAdapter } from "@nodeint/migent-kernel";
2
+ import { type RunCommand, type Which } from "../provider.js";
3
+ export interface ConfigPrompter {
4
+ select(message: string, choices: ReadonlyArray<readonly [string, string]>, defaultValue?: string | null): string | Promise<string>;
5
+ confirm(message: string): boolean | Promise<boolean>;
6
+ text(message: string, defaultValue?: string): string | Promise<string>;
7
+ }
8
+ export declare function runConfigShow(workspace: string): number;
9
+ export declare function runConfigModel(workspace: string, options?: {
10
+ key?: string | null;
11
+ provider?: string | null;
12
+ model?: string | null;
13
+ options?: readonly string[];
14
+ clearOptions?: readonly string[];
15
+ asJson?: boolean;
16
+ interactive?: boolean;
17
+ adapters?: Record<string, AgentAdapter> | null;
18
+ which?: Which | null;
19
+ prompter?: ConfigPrompter | null;
20
+ runCommand?: RunCommand | null;
21
+ }): Promise<number>;
22
+ export declare function runConfigRole(workspace: string, options?: {
23
+ roles?: readonly string[];
24
+ modelName?: string | null;
25
+ provider?: string | null;
26
+ model?: string | null;
27
+ options?: readonly string[];
28
+ clearOptions?: readonly string[];
29
+ asJson?: boolean;
30
+ interactive?: boolean;
31
+ adapters?: Record<string, AgentAdapter> | null;
32
+ which?: Which | null;
33
+ prompter?: ConfigPrompter | null;
34
+ runCommand?: RunCommand | null;
35
+ }): Promise<number>;