@nodeint/migent 0.1.4 → 0.1.5
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 +30 -14
- package/dist/commands/agent.js +111 -59
- package/dist/commands/config.js +20 -8
- package/dist/commands/execute.d.ts +6 -0
- package/dist/commands/execute.js +30 -14
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +70 -63
- package/dist/commands/prepare.d.ts +1 -0
- package/dist/commands/prepare.js +14 -0
- package/dist/commands/repair.d.ts +1 -0
- package/dist/commands/repair.js +22 -0
- package/dist/commands/service.js +5 -4
- package/dist/commands/sessions.d.ts +24 -1
- package/dist/commands/sessions.js +165 -13
- package/dist/commands/skill.js +51 -32
- package/dist/commands/watch.d.ts +2 -1
- package/dist/commands/watch.js +130 -67
- package/dist/commands/workspace-registry.js +10 -1
- package/dist/display.js +21 -9
- package/dist/errors.d.ts +3 -0
- package/dist/errors.js +6 -0
- package/dist/exits.d.ts +10 -0
- package/dist/exits.js +26 -0
- package/dist/follow-log.d.ts +29 -0
- package/dist/follow-log.js +172 -0
- package/dist/fs-utils.d.ts +3 -0
- package/dist/fs-utils.js +26 -0
- package/dist/index.js +5 -1
- package/dist/migrate.js +2 -17
- package/dist/program.js +386 -168
- package/dist/session-row.d.ts +20 -0
- package/dist/session-row.js +21 -0
- package/dist/signals.d.ts +3 -0
- package/dist/signals.js +56 -0
- package/dist/templates/migent/SKILL.md +159 -50
- package/dist/templates/migent/references/schema-config.yaml +35 -0
- package/dist/templates/migent/references/schema-workflow.yaml +61 -0
- package/dist/text.d.ts +4 -0
- package/dist/text.js +13 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/workspace.js +5 -12
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ the process, while each provider CLI remains responsible for authentication,
|
|
|
49
49
|
agent execution, and its own tools and options.
|
|
50
50
|
|
|
51
51
|
```mermaid
|
|
52
|
-
flowchart
|
|
52
|
+
flowchart TD
|
|
53
53
|
A[Task] --> B[Planner - Codex]
|
|
54
54
|
B -->|plan.md| C[Reviewer - Grok]
|
|
55
55
|
C -->|revise| B
|
|
@@ -61,11 +61,12 @@ flowchart LR
|
|
|
61
61
|
Migent drives each provider through its headless CLI. Install and sign in to the
|
|
62
62
|
ones your configuration names.
|
|
63
63
|
|
|
64
|
-
| Provider
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
64
|
+
| Provider | CLI |
|
|
65
|
+
| -------------------| -------- |
|
|
66
|
+
| Google Antigravity | `agy` |
|
|
67
|
+
| Claude | `claude` |
|
|
68
|
+
| Codex | `codex` |
|
|
69
|
+
| Grok | `grok` |
|
|
69
70
|
|
|
70
71
|
## Quickstart
|
|
71
72
|
|
|
@@ -114,18 +115,32 @@ Commit `config.yaml` and `workflows/`. To add the skill later, run
|
|
|
114
115
|
From the project or any subdirectory:
|
|
115
116
|
|
|
116
117
|
```bash
|
|
117
|
-
migent
|
|
118
|
+
migent session run --workflow plan --task "Plan the account settings redesign"
|
|
118
119
|
```
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
`--task` is one line and is stored in the session as `task.md`. For a longer
|
|
122
|
+
task, create the session first, write the file, then start it:
|
|
122
123
|
|
|
123
124
|
```bash
|
|
124
|
-
migent
|
|
125
|
-
migent
|
|
126
|
-
migent continue <session-id>
|
|
125
|
+
migent session prepare wave-3 --workflow plan
|
|
126
|
+
migent session run --session wave-3 --workflow plan
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
+
Migent runs each eligible stage until the workflow completes or stops. Omit
|
|
130
|
+
`--workflow` and pass `--role` to run one role instead. A workflow run prints
|
|
131
|
+
one JSON result with the session id, status, stop reason, decision, and output
|
|
132
|
+
paths. A role run prints a table unless `--json`. Stderr prints one line when
|
|
133
|
+
a stage starts and one when it finishes. Then inspect or resume:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
migent session list
|
|
137
|
+
migent session list --latest --json
|
|
138
|
+
migent session follow <session-id>
|
|
139
|
+
migent session continue <session-id>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`session list --json` and a JSON snapshot omit the task text.
|
|
143
|
+
|
|
129
144
|
### Next
|
|
130
145
|
|
|
131
146
|
- [Providers and model configuration](https://github.com/nodeint/migent/blob/main/docs/providers.md)
|
|
@@ -147,8 +162,9 @@ A workflow connects stages through dependencies and explicit decision routes.
|
|
|
147
162
|
- A **session** records executions, events, decisions, and artifacts so work can
|
|
148
163
|
be inspected or resumed.
|
|
149
164
|
|
|
150
|
-
Use `depends_on` to give a stage upstream artifacts.
|
|
151
|
-
|
|
165
|
+
Use `depends_on` to give a stage upstream artifacts. Every visit of a stage
|
|
166
|
+
continues that stage's provider agent. Use `session.resume_from` when a stage
|
|
167
|
+
must continue a different stage's provider session.
|
|
152
168
|
|
|
153
169
|
## Current scope
|
|
154
170
|
|
package/dist/commands/agent.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { AgentToolRunner, CancellationRequested, ConfigurationError, createAgentSession, loadRoleInstructions, loadYamlMapping, log, prependRoleInstructions, requireAgentSession, isSessionLockLost, repairSessionUnlocked, SessionLock, resolveRoleTarget, SessionStore, } from "@nodeint/migent-kernel";
|
|
2
3
|
import { printAgent, printError, printNotice } from "../display.js";
|
|
3
4
|
import { cliHooks } from "../hooks.js";
|
|
4
5
|
import { requireCurrentSchema } from "../migrate.js";
|
|
6
|
+
import { bindCancellationSignals } from "../signals.js";
|
|
5
7
|
import { adapterMap, parseOptions } from "../provider.js";
|
|
6
8
|
import { resolvePrompt } from "../workspace.js";
|
|
7
9
|
export async function dispatchAgent(workspace, args) {
|
|
@@ -13,76 +15,126 @@ export async function dispatchAgent(workspace, args) {
|
|
|
13
15
|
options: Object.keys(parsed).length > 0 ? parsed : null,
|
|
14
16
|
});
|
|
15
17
|
const [resolvedSessionId, createdSession] = resolveSession(workspace, args.sessionId ?? null, args.role, args.task ?? null);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
if (createdSession)
|
|
19
|
+
log(`session_id: ${resolvedSessionId}`);
|
|
20
|
+
let lock;
|
|
21
|
+
try {
|
|
22
|
+
lock = SessionLock.acquire(path.join(workspace, ".migent", "sessions", resolvedSessionId));
|
|
21
23
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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.
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error instanceof Error) {
|
|
26
|
+
printError(error.message);
|
|
27
|
+
return 2;
|
|
40
28
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
process.on("SIGTERM", onSigterm);
|
|
44
|
-
let result;
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
45
31
|
try {
|
|
46
|
-
|
|
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
|
-
});
|
|
32
|
+
return await runLocked();
|
|
61
33
|
}
|
|
62
34
|
catch (error) {
|
|
63
|
-
if (error
|
|
64
|
-
log(error.message);
|
|
65
|
-
return 130;
|
|
66
|
-
}
|
|
67
|
-
if (error instanceof ConfigurationError)
|
|
68
|
-
throw error;
|
|
69
|
-
if (error instanceof Error) {
|
|
35
|
+
if (isSessionLockLost(error)) {
|
|
70
36
|
printError(error.message);
|
|
71
37
|
return 2;
|
|
72
38
|
}
|
|
73
39
|
throw error;
|
|
74
40
|
}
|
|
75
41
|
finally {
|
|
76
|
-
|
|
77
|
-
|
|
42
|
+
lock.release();
|
|
43
|
+
}
|
|
44
|
+
async function runLocked() {
|
|
45
|
+
let resumeExecutionId = null;
|
|
46
|
+
let resumeCancelled = false;
|
|
47
|
+
if (!createdSession) {
|
|
48
|
+
repairSessionUnlocked(workspace, resolvedSessionId);
|
|
49
|
+
const store = new SessionStore(workspace);
|
|
50
|
+
if (store.readSessionStatus(resolvedSessionId).status === "cancelled") {
|
|
51
|
+
resumeCancelled = true;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const previous = store.latestExecution(resolvedSessionId);
|
|
55
|
+
if (previous !== null)
|
|
56
|
+
resumeExecutionId = previous.executionId;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const optionLabel = Object.entries(target.options)
|
|
60
|
+
.map(([key, value]) => `${key}: ${value}`)
|
|
61
|
+
.join(", ") || "default";
|
|
62
|
+
printNotice(`agent ${args.role} · ${target.provider}/${target.model} (${optionLabel}).`);
|
|
63
|
+
const unbind = bindCancellationSignals();
|
|
64
|
+
let result;
|
|
65
|
+
let resumedMany = null;
|
|
66
|
+
try {
|
|
67
|
+
const runner = args.runner ?? cliHooks.runner ?? new AgentToolRunner(adapterMap());
|
|
68
|
+
if (resumeCancelled) {
|
|
69
|
+
const reopened = new SessionStore(workspace).reopenCancelledExecutions(resolvedSessionId);
|
|
70
|
+
for (const item of reopened) {
|
|
71
|
+
log(`session ${resolvedSessionId} was cancelled during ${item.executionId}. Resuming that execution.`);
|
|
72
|
+
}
|
|
73
|
+
const settled = await Promise.allSettled(reopened.map((item) => runner.continueCancelled(workspace, resolvedSessionId, item.executionId)));
|
|
74
|
+
const rejected = settled.find((item) => item.status === "rejected");
|
|
75
|
+
if (rejected && rejected.status === "rejected")
|
|
76
|
+
throw rejected.reason;
|
|
77
|
+
const continued = settled.flatMap((item) => (item.status === "fulfilled" ? [item.value] : []));
|
|
78
|
+
if (continued.length === 0) {
|
|
79
|
+
throw new ConfigurationError(`Session ${resolvedSessionId} is cancelled without an execution.`);
|
|
80
|
+
}
|
|
81
|
+
if (continued.length === 1)
|
|
82
|
+
result = continued[0];
|
|
83
|
+
else
|
|
84
|
+
resumedMany = continued;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
result = await runner.run({
|
|
88
|
+
provider: target.provider,
|
|
89
|
+
model: target.model,
|
|
90
|
+
options: { ...target.options },
|
|
91
|
+
prompt: prependRoleInstructions(loadRoleInstructions(loadYamlMapping(path.join(workspace, ".migent", "config.yaml")), args.role), resolvePrompt({
|
|
92
|
+
prompt: args.prompt ?? null,
|
|
93
|
+
promptFile: args.promptFile ?? null,
|
|
94
|
+
promptStdin: args.promptStdin ?? false,
|
|
95
|
+
})),
|
|
96
|
+
workspace,
|
|
97
|
+
sessionId: resolvedSessionId,
|
|
98
|
+
resumeExecutionId,
|
|
99
|
+
stageId: args.role,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (error instanceof CancellationRequested) {
|
|
105
|
+
log(error.message);
|
|
106
|
+
return 130;
|
|
107
|
+
}
|
|
108
|
+
if (error instanceof ConfigurationError)
|
|
109
|
+
throw error;
|
|
110
|
+
if (error instanceof Error) {
|
|
111
|
+
printError(error.message);
|
|
112
|
+
return 2;
|
|
113
|
+
}
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
unbind();
|
|
118
|
+
}
|
|
119
|
+
if (resumedMany !== null) {
|
|
120
|
+
if (args.asJson)
|
|
121
|
+
process.stdout.write(`${JSON.stringify(resumedMany)}\n`);
|
|
122
|
+
else {
|
|
123
|
+
for (const item of resumedMany)
|
|
124
|
+
printAgent({ ...item }, args.role, target.provider, target.model);
|
|
125
|
+
}
|
|
126
|
+
if (resumedMany.some((item) => item.failure_reason === "verify_exhausted"))
|
|
127
|
+
return 6;
|
|
128
|
+
return resumedMany.every((item) => item.outcome_status === "complete") ? 0 : 1;
|
|
129
|
+
}
|
|
130
|
+
if (result === undefined)
|
|
131
|
+
throw new Error("Agent run produced no result.");
|
|
132
|
+
if (args.asJson)
|
|
133
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
134
|
+
else
|
|
135
|
+
printAgent({ ...result }, args.role, target.provider, target.model);
|
|
136
|
+
return result.outcome_status === "complete" ? 0 : 1;
|
|
78
137
|
}
|
|
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
138
|
}
|
|
87
139
|
function resolveSession(workspace, sessionId, role, task) {
|
|
88
140
|
if (sessionId !== null && typeof task === "string" && task.trim() !== "") {
|
package/dist/commands/config.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { confirm as clackConfirm, isCancel, select as clackSelect, text as clackText } from "@clack/prompts";
|
|
4
4
|
import { ConfigEditError, ConfigurationError, assignRoles, describeChange, diagnose, inspectConfig, loadModelTarget, loadWorkflowCatalog, loadYamlMapping, matchingModelName, patchConfigText, placeRoleModel, resolveStageSpec, setRoleOptions, upsertModel, whichSync, } from "@nodeint/migent-kernel";
|
|
5
5
|
import { printError } from "../display.js";
|
|
6
|
+
import { PromptCancelled } from "../errors.js";
|
|
6
7
|
import { cliHooks } from "../hooks.js";
|
|
7
8
|
import { requireCurrentSchema } from "../migrate.js";
|
|
8
9
|
import { acceptedOptions, adapterMap, asCatalog, detected, knownModel, loadCatalog, loadOptionValues, parseOptions, requireAdapter, runProviderCommand, } from "../provider.js";
|
|
@@ -25,6 +26,8 @@ export async function runConfigModel(workspace, options = {}) {
|
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
28
|
catch (error) {
|
|
29
|
+
if (error instanceof PromptCancelled)
|
|
30
|
+
throw error;
|
|
28
31
|
if (error instanceof ConfigurationError || error instanceof ConfigEditError || error instanceof Error) {
|
|
29
32
|
printError(error.message);
|
|
30
33
|
return 2;
|
|
@@ -43,6 +46,8 @@ export async function runConfigRole(workspace, options = {}) {
|
|
|
43
46
|
});
|
|
44
47
|
}
|
|
45
48
|
catch (error) {
|
|
49
|
+
if (error instanceof PromptCancelled)
|
|
50
|
+
throw error;
|
|
46
51
|
if (error instanceof ConfigurationError || error instanceof ConfigEditError || error instanceof Error) {
|
|
47
52
|
printError(error.message);
|
|
48
53
|
return 2;
|
|
@@ -382,7 +387,7 @@ function optionUpdatesOf(options, clearOptions) {
|
|
|
382
387
|
async function selectProvider(prompter, adapters, which, message, defaultValue) {
|
|
383
388
|
const rows = detected(adapters, which);
|
|
384
389
|
if (rows.length === 0)
|
|
385
|
-
throw new
|
|
390
|
+
throw new ConfigurationError("No providers are available.");
|
|
386
391
|
const names = new Set(rows.map(([name]) => name));
|
|
387
392
|
return prompter.select(message, rows.map(([name, found]) => [`${name} ${found ?? "not found"}`, name]), defaultValue !== null && names.has(defaultValue) ? defaultValue : rows[0]?.[0]);
|
|
388
393
|
}
|
|
@@ -486,6 +491,7 @@ function roleJson(role) {
|
|
|
486
491
|
provider: role.provider,
|
|
487
492
|
model: role.model,
|
|
488
493
|
options: { ...role.options },
|
|
494
|
+
instructions: [...role.instructions],
|
|
489
495
|
shared_with: [...role.sharedWith],
|
|
490
496
|
stages: role.stages.map((stage) => ({
|
|
491
497
|
workflow: stage.workflow,
|
|
@@ -586,7 +592,7 @@ function isRecord(value) {
|
|
|
586
592
|
class ClackConfigPrompter {
|
|
587
593
|
async select(message, choices, defaultValue) {
|
|
588
594
|
if (choices.length === 0)
|
|
589
|
-
throw new
|
|
595
|
+
throw new ConfigurationError("Choose a value.");
|
|
590
596
|
const values = new Set(choices.map(([, value]) => value));
|
|
591
597
|
const initial = defaultValue != null && values.has(defaultValue) ? defaultValue : choices[0]?.[1];
|
|
592
598
|
const result = await clackSelect({
|
|
@@ -594,20 +600,26 @@ class ClackConfigPrompter {
|
|
|
594
600
|
options: choices.map(([label, value]) => ({ label, value })),
|
|
595
601
|
initialValue: initial,
|
|
596
602
|
});
|
|
597
|
-
if (isCancel(result)
|
|
598
|
-
throw new
|
|
603
|
+
if (isCancel(result))
|
|
604
|
+
throw new PromptCancelled();
|
|
605
|
+
if (typeof result !== "string" || !values.has(result))
|
|
606
|
+
throw new ConfigurationError("Choose a value.");
|
|
599
607
|
return result;
|
|
600
608
|
}
|
|
601
609
|
async confirm(message) {
|
|
602
610
|
const result = await clackConfirm({ message, initialValue: true });
|
|
603
|
-
if (isCancel(result)
|
|
604
|
-
throw new
|
|
611
|
+
if (isCancel(result))
|
|
612
|
+
throw new PromptCancelled();
|
|
613
|
+
if (typeof result !== "boolean")
|
|
614
|
+
throw new ConfigurationError("Answer yes or no.");
|
|
605
615
|
return result;
|
|
606
616
|
}
|
|
607
617
|
async text(message, defaultValue = "") {
|
|
608
618
|
const result = await clackText({ message, initialValue: defaultValue });
|
|
609
|
-
if (isCancel(result)
|
|
610
|
-
throw new
|
|
619
|
+
if (isCancel(result))
|
|
620
|
+
throw new PromptCancelled();
|
|
621
|
+
if (typeof result !== "string")
|
|
622
|
+
throw new ConfigurationError("Enter a value.");
|
|
611
623
|
return result;
|
|
612
624
|
}
|
|
613
625
|
}
|
|
@@ -7,6 +7,12 @@ export interface ExecuteWorkflowOptions {
|
|
|
7
7
|
priorSessionId?: string | null;
|
|
8
8
|
maxAttempts?: number | null;
|
|
9
9
|
maxDispatches?: number | null;
|
|
10
|
+
stageId?: string | null;
|
|
10
11
|
runner?: AgentToolRunner | null;
|
|
12
|
+
verbose?: boolean;
|
|
13
|
+
itemProgress?: boolean;
|
|
14
|
+
startPrepared?: boolean;
|
|
15
|
+
refreshWorkflow?: boolean;
|
|
16
|
+
reply?: string | null;
|
|
11
17
|
}
|
|
12
18
|
export declare function executeWorkflow(workspace: string, options: ExecuteWorkflowOptions): Promise<number>;
|
package/dist/commands/execute.js
CHANGED
|
@@ -2,38 +2,54 @@ import { AgentToolRunner, DEFAULT_MAX_DISPATCHES, executeNamedWorkflow, } from "
|
|
|
2
2
|
import { cliHooks } from "../hooks.js";
|
|
3
3
|
import { requireCurrentSchema } from "../migrate.js";
|
|
4
4
|
import { adapterMap } from "../provider.js";
|
|
5
|
+
import { text } from "../text.js";
|
|
5
6
|
export async function executeWorkflow(workspace, options) {
|
|
6
7
|
requireCurrentSchema(workspace);
|
|
7
8
|
const once = options.action === "stage";
|
|
8
|
-
const
|
|
9
|
+
const startPrepared = options.startPrepared === true;
|
|
10
|
+
const sessionId = text(options.sessionId);
|
|
11
|
+
const creating = !startPrepared && (options.action === "start" || (once && sessionId === null));
|
|
9
12
|
const maxAttempts = options.maxAttempts === undefined ? 3 : options.maxAttempts;
|
|
10
13
|
const maxDispatches = options.maxDispatches === undefined ? DEFAULT_MAX_DISPATCHES : options.maxDispatches;
|
|
11
14
|
const runner = options.runner ?? cliHooks.runner ?? new AgentToolRunner(adapterMap());
|
|
15
|
+
runner.itemProgress = options.itemProgress === true;
|
|
12
16
|
const result = await executeNamedWorkflow(workspace, {
|
|
13
|
-
workflowId: creating ? (options.workflowId ?? null) : null,
|
|
17
|
+
workflowId: creating || startPrepared ? (options.workflowId ?? null) : null,
|
|
14
18
|
task: creating ? (options.task ?? null) : null,
|
|
15
|
-
sessionId: creating ? null :
|
|
19
|
+
sessionId: creating ? null : sessionId,
|
|
16
20
|
priorSessionId: options.priorSessionId ?? null,
|
|
21
|
+
startPrepared,
|
|
17
22
|
maxAttempts: once ? null : maxAttempts,
|
|
18
23
|
maxDispatches: once ? null : maxDispatches,
|
|
24
|
+
stageId: options.stageId ?? null,
|
|
19
25
|
once,
|
|
20
26
|
resetRevisions: options.action === "continue",
|
|
27
|
+
refreshWorkflow: options.refreshWorkflow === true,
|
|
28
|
+
reply: options.reply ?? null,
|
|
21
29
|
}, runner);
|
|
22
|
-
printResult(result);
|
|
30
|
+
printResult(result, options.verbose === true);
|
|
31
|
+
if (result.stopReason === "retry_exhausted" ||
|
|
32
|
+
result.stopReason === "revisions_exhausted" ||
|
|
33
|
+
result.stopReason === "dispatch_limit" ||
|
|
34
|
+
result.stopReason === "verify_exhausted") {
|
|
35
|
+
process.stderr.write(`Resume with: migent session continue ${result.sessionId}\n`);
|
|
36
|
+
}
|
|
23
37
|
return result.code;
|
|
24
38
|
}
|
|
25
|
-
|
|
26
|
-
|
|
39
|
+
const INSPECT_EXIT_CODES = new Set([1, 3, 6]);
|
|
40
|
+
function printResult(result, verbose) {
|
|
41
|
+
const payload = {
|
|
27
42
|
session_id: result.sessionId,
|
|
28
43
|
session_status: result.status,
|
|
29
44
|
stop_reason: result.stopReason,
|
|
45
|
+
latest_decision: result.latestDecision,
|
|
30
46
|
outputs: result.outputs,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
};
|
|
48
|
+
if (INSPECT_EXIT_CODES.has(result.code) && result.latestExecutionId) {
|
|
49
|
+
payload.latest_execution_id = result.latestExecutionId;
|
|
50
|
+
payload.response_path = `executions/${result.latestExecutionId}/response.md`;
|
|
51
|
+
}
|
|
52
|
+
if (verbose)
|
|
53
|
+
payload.stages = result.stages;
|
|
54
|
+
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
39
55
|
}
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare function runInit(workspace: string, options?: {
|
|
|
18
18
|
model?: string | null;
|
|
19
19
|
options?: readonly string[];
|
|
20
20
|
preset?: string;
|
|
21
|
+
presetExplicit?: boolean;
|
|
21
22
|
skill?: boolean;
|
|
22
23
|
interactive?: boolean;
|
|
23
24
|
adapters?: Record<string, AgentAdapter> | null;
|