@nodeint/migent 0.1.5 → 0.1.7
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 +195 -151
- package/dist/commands/agent.d.ts +8 -1
- package/dist/commands/agent.js +292 -19
- package/dist/commands/config.d.ts +3 -3
- package/dist/commands/config.js +57 -55
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/execute.d.ts +1 -2
- package/dist/commands/execute.js +95 -26
- package/dist/commands/init.d.ts +3 -3
- package/dist/commands/init.js +20 -20
- package/dist/commands/prepare.js +1 -0
- package/dist/commands/provider.d.ts +10 -0
- package/dist/commands/provider.js +77 -0
- package/dist/commands/sessions.js +11 -10
- package/dist/commands/skill.js +8 -1
- package/dist/display.d.ts +17 -0
- package/dist/display.js +43 -1
- package/dist/exits.d.ts +3 -1
- package/dist/exits.js +9 -2
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +1 -0
- package/dist/index.js +1 -0
- package/dist/migrate.d.ts +3 -3
- package/dist/migrate.js +26 -24
- package/dist/program.js +78 -31
- package/dist/provider.d.ts +13 -11
- package/dist/provider.js +38 -33
- package/dist/session-row.d.ts +2 -0
- package/dist/session-row.js +2 -0
- package/dist/templates/migent/SKILL.md +159 -157
- package/dist/templates/migent/references/config.md +56 -0
- package/dist/templates/migent/references/inspect.md +32 -0
- package/dist/templates/migent/references/schema-config.yaml +10 -1
- package/dist/templates/migent/references/schema-workflow.yaml +12 -2
- package/dist/templates/migent/references/sessions.md +65 -0
- package/package.json +4 -4
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { whichSync } from "@nodeint/migent-kernel";
|
|
2
|
+
import { printProviders } from "../display.js";
|
|
3
|
+
import { cliHooks } from "../hooks.js";
|
|
4
|
+
import { providerMap, loadCatalog, runProviderCommand, } from "../provider.js";
|
|
5
|
+
function mapProviderOption(opt) {
|
|
6
|
+
return {
|
|
7
|
+
name: opt.name,
|
|
8
|
+
prompt: opt.prompt === true,
|
|
9
|
+
allow_default: opt.allowDefault === true,
|
|
10
|
+
overridable: opt.overridable === true,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function getProviderOptions(provider) {
|
|
14
|
+
const candidate = provider;
|
|
15
|
+
if (typeof candidate.providerOptions === "function") {
|
|
16
|
+
return candidate.providerOptions().map(mapProviderOption);
|
|
17
|
+
}
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
export async function collectProviders(providers, which, runCommand) {
|
|
21
|
+
// A provider without a default client has no CLI of its own to probe.
|
|
22
|
+
const names = Object.keys(providers).filter((name) => providers[name].requiresClient !== true).sort();
|
|
23
|
+
const rows = [];
|
|
24
|
+
for (const name of names) {
|
|
25
|
+
const provider = providers[name];
|
|
26
|
+
const path = which(provider.command);
|
|
27
|
+
const options = getProviderOptions(provider);
|
|
28
|
+
const problems = [];
|
|
29
|
+
let models = [];
|
|
30
|
+
let default_model = null;
|
|
31
|
+
if (path === null) {
|
|
32
|
+
problems.push(`${provider.command} is not on PATH.`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
try {
|
|
36
|
+
const catalog = await loadCatalog(provider, which, runCommand);
|
|
37
|
+
models = [...catalog.ids];
|
|
38
|
+
default_model = catalog.defaultId;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42
|
+
problems.push(message);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
rows.push({
|
|
46
|
+
name,
|
|
47
|
+
command: provider.command,
|
|
48
|
+
path,
|
|
49
|
+
available: path !== null,
|
|
50
|
+
models,
|
|
51
|
+
default_model,
|
|
52
|
+
options,
|
|
53
|
+
problems,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return rows;
|
|
57
|
+
}
|
|
58
|
+
function providerPayload(rows) {
|
|
59
|
+
return {
|
|
60
|
+
ok: rows.every((row) => row.problems.length === 0),
|
|
61
|
+
providers: rows.map((row) => ({ ...row })),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export async function runProviderList(options = {}) {
|
|
65
|
+
const providers = options.providers ?? providerMap();
|
|
66
|
+
const which = options.which ?? cliHooks.which ?? whichSync;
|
|
67
|
+
const runCommand = options.runCommand ?? cliHooks.runCommand ?? runProviderCommand;
|
|
68
|
+
const rows = await collectProviders(providers, which, runCommand);
|
|
69
|
+
if (options.asJson) {
|
|
70
|
+
process.stdout.write(`${JSON.stringify(providerPayload(rows))}\n`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
printProviders(rows);
|
|
74
|
+
}
|
|
75
|
+
const hasAnyModels = rows.some((row) => row.models.length > 0);
|
|
76
|
+
return hasAnyModels ? 0 : 1;
|
|
77
|
+
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { listSessionMetrics, listSessionRows, sessionMetrics, ConfigurationError } from "@nodeint/migent-kernel";
|
|
1
|
+
import { listSealedMetrics, listSessionRows, readSealedMetrics, ConfigurationError } from "@nodeint/migent-kernel";
|
|
4
2
|
import { printError, printSessions } from "../display.js";
|
|
5
|
-
import { adapterMap } from "../provider.js";
|
|
6
3
|
import { SESSION_COLUMN, sessionFields } from "../session-row.js";
|
|
7
4
|
import { optionalText } from "../text.js";
|
|
8
5
|
import { followSession } from "./watch.js";
|
|
@@ -36,9 +33,8 @@ export function runSessionMetrics(workspace, session, options) {
|
|
|
36
33
|
printError("List filters cannot be combined with a session.");
|
|
37
34
|
return 2;
|
|
38
35
|
}
|
|
39
|
-
const adapters = adapterMap();
|
|
40
36
|
if (sessionId === null) {
|
|
41
|
-
const rows =
|
|
37
|
+
const rows = listSealedMetrics(workspace, {
|
|
42
38
|
workflow: selection.workflow ?? null,
|
|
43
39
|
status: selection.status ?? null,
|
|
44
40
|
limit: selection.limit ?? null,
|
|
@@ -47,12 +43,16 @@ export function runSessionMetrics(workspace, session, options) {
|
|
|
47
43
|
process.stdout.write(`${JSON.stringify(row)}\n`);
|
|
48
44
|
return 0;
|
|
49
45
|
}
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
52
|
-
printError(`No
|
|
46
|
+
const sealed = readSealedMetrics(workspace, sessionId);
|
|
47
|
+
if (sealed.state === "missing") {
|
|
48
|
+
printError(`No metrics for session: ${sessionId}. Metrics are recorded when a workflow session completes.`);
|
|
53
49
|
return 2;
|
|
54
50
|
}
|
|
55
|
-
|
|
51
|
+
if (sealed.state === "corrupt") {
|
|
52
|
+
printError(`metrics.json for session ${sessionId} is not valid JSON.`);
|
|
53
|
+
return 2;
|
|
54
|
+
}
|
|
55
|
+
process.stdout.write(`${JSON.stringify(sealed.metrics)}\n`);
|
|
56
56
|
return 0;
|
|
57
57
|
}
|
|
58
58
|
export async function runSessions(workspace, session, options) {
|
|
@@ -130,6 +130,7 @@ function sessionJson(row) {
|
|
|
130
130
|
const fields = sessionFields(row);
|
|
131
131
|
return {
|
|
132
132
|
session: fields.session,
|
|
133
|
+
title: fields.title,
|
|
133
134
|
workflow: fields.workflow,
|
|
134
135
|
status: fields.status,
|
|
135
136
|
execution: fields.execution,
|
package/dist/commands/skill.js
CHANGED
|
@@ -7,7 +7,14 @@ import { isDirectory, isFile } from "../fs-utils.js";
|
|
|
7
7
|
const SKILL_RELATIVE = path.join(".agents", "skills", "migent");
|
|
8
8
|
const STATE_FILENAME = ".migent-template.json";
|
|
9
9
|
const TEMPLATE_VERSION = 1;
|
|
10
|
-
const MANAGED = [
|
|
10
|
+
const MANAGED = [
|
|
11
|
+
"SKILL.md",
|
|
12
|
+
"references/schema-config.yaml",
|
|
13
|
+
"references/schema-workflow.yaml",
|
|
14
|
+
"references/sessions.md",
|
|
15
|
+
"references/inspect.md",
|
|
16
|
+
"references/config.md",
|
|
17
|
+
];
|
|
11
18
|
export function installSkill(workspace) {
|
|
12
19
|
const skillDirectory = path.join(workspace, SKILL_RELATIVE);
|
|
13
20
|
if (existsSync(skillDirectory)) {
|
package/dist/display.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Check } from "@nodeint/migent-kernel";
|
|
2
2
|
export declare function printError(message: string): void;
|
|
3
3
|
export declare function printNotice(message: string): void;
|
|
4
|
+
export declare function printResumeCommand(sessionId: string): void;
|
|
4
5
|
export declare function printCreated(paths: readonly string[], nextCommand: string): void;
|
|
5
6
|
export declare function printAlreadyInitialized(): void;
|
|
6
7
|
export declare function printInitConflicts(paths: readonly string[]): void;
|
|
@@ -10,3 +11,19 @@ export declare function printAgent(result: Record<string, unknown>, role: string
|
|
|
10
11
|
export declare function printWatchSnapshot(snapshot: Record<string, unknown>): void;
|
|
11
12
|
export declare function printWatchEvent(event: Record<string, unknown>): void;
|
|
12
13
|
export declare function formatWatchTimestamp(timestamp: unknown): string;
|
|
14
|
+
export interface ProviderRow {
|
|
15
|
+
name: string;
|
|
16
|
+
command: string;
|
|
17
|
+
path: string | null;
|
|
18
|
+
available: boolean;
|
|
19
|
+
models: string[];
|
|
20
|
+
default_model: string | null;
|
|
21
|
+
options: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
prompt: boolean;
|
|
24
|
+
allow_default: boolean;
|
|
25
|
+
overridable: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
problems: string[];
|
|
28
|
+
}
|
|
29
|
+
export declare function printProviders(rows: readonly ProviderRow[]): void;
|
package/dist/display.js
CHANGED
|
@@ -12,6 +12,9 @@ export function printNotice(message) {
|
|
|
12
12
|
const prefix = tty ? pc.cyan(pc.bold("[migent] ")) : "[migent] ";
|
|
13
13
|
process.stderr.write(`${prefix}${message}\n`);
|
|
14
14
|
}
|
|
15
|
+
export function printResumeCommand(sessionId) {
|
|
16
|
+
process.stderr.write(`Resume with:\nmigent session continue ${sessionId}\n`);
|
|
17
|
+
}
|
|
15
18
|
export function printCreated(paths, nextCommand) {
|
|
16
19
|
process.stdout.write("Created:\n");
|
|
17
20
|
for (const filePath of paths)
|
|
@@ -47,7 +50,8 @@ export function printSessions(rows) {
|
|
|
47
50
|
}
|
|
48
51
|
for (const row of rows) {
|
|
49
52
|
const fields = sessionFields(row);
|
|
50
|
-
|
|
53
|
+
const identity = fields.title !== "" && fields.title !== fields.session ? `${fields.title} ${fields.session}` : fields.session;
|
|
54
|
+
process.stdout.write(`${identity} ${fields.workflow} ${fields.status} ${fields.execution} ${fields.decision} ${fields.outputs} ${fields.task}\n`);
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
export function printAgent(result, role, provider, model) {
|
|
@@ -70,6 +74,10 @@ export function printWatchSnapshot(snapshot) {
|
|
|
70
74
|
["session_id", String(snapshot.session_id ?? "--")],
|
|
71
75
|
["status", String(snapshot.status ?? "unknown")],
|
|
72
76
|
];
|
|
77
|
+
const title = snapshot.title;
|
|
78
|
+
if (typeof title === "string" && title !== "" && title !== lines[0]?.[1]) {
|
|
79
|
+
lines.splice(1, 0, ["title", title]);
|
|
80
|
+
}
|
|
73
81
|
if (typeof snapshot.workflow_id === "string" && snapshot.workflow_id) {
|
|
74
82
|
lines.push(["workflow", snapshot.workflow_id]);
|
|
75
83
|
}
|
|
@@ -130,6 +138,40 @@ export function formatWatchTimestamp(timestamp) {
|
|
|
130
138
|
return timestamp.trim();
|
|
131
139
|
return parsed.toISOString().replace("T", " ").replace(/\.\d+Z$/, "+00:00").replace("Z", "+00:00");
|
|
132
140
|
}
|
|
141
|
+
export function printProviders(rows) {
|
|
142
|
+
const tty = Boolean(process.stdout.isTTY);
|
|
143
|
+
for (const row of rows) {
|
|
144
|
+
const ok = row.problems.length === 0 && row.models.length > 0;
|
|
145
|
+
const status = ok ? (tty ? pc.green("ok") : "ok") : tty ? pc.red("failed") : "failed";
|
|
146
|
+
process.stdout.write(`${row.name.padEnd(12)}${status}\n`);
|
|
147
|
+
if (row.path !== null) {
|
|
148
|
+
const line = ` path: ${row.path}`;
|
|
149
|
+
process.stdout.write(`${tty ? pc.dim(line) : line}\n`);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const line = ` path: not found`;
|
|
153
|
+
process.stdout.write(`${tty ? pc.dim(line) : line}\n`);
|
|
154
|
+
}
|
|
155
|
+
if (row.models.length > 0) {
|
|
156
|
+
process.stdout.write(` models:\n`);
|
|
157
|
+
for (const model of row.models) {
|
|
158
|
+
const marked = model === row.default_model ? `${model} (default)` : model;
|
|
159
|
+
const line = ` ${marked}`;
|
|
160
|
+
process.stdout.write(`${tty ? pc.dim(line) : line}\n`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (row.options.length > 0) {
|
|
164
|
+
process.stdout.write(` options:\n`);
|
|
165
|
+
for (const opt of row.options) {
|
|
166
|
+
const line = ` ${opt.name}`;
|
|
167
|
+
process.stdout.write(`${tty ? pc.dim(line) : line}\n`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
for (const problem of row.problems) {
|
|
171
|
+
process.stdout.write(` ${problem}\n`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
133
175
|
function isRecord(value) {
|
|
134
176
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
135
177
|
}
|
package/dist/exits.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export declare const EXIT_OK = 0;
|
|
2
2
|
export declare const EXIT_BLOCKED = 1;
|
|
3
3
|
export declare const EXIT_CONFIG = 2;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const EXIT_STAGE_FAILED = 3;
|
|
5
|
+
export declare const EXIT_QUOTA = 8;
|
|
5
6
|
export declare const EXIT_REVISIONS = 4;
|
|
6
7
|
export declare const EXIT_DISPATCHES = 5;
|
|
7
8
|
export declare const EXIT_VERIFY = 6;
|
|
9
|
+
export declare const EXIT_VERIFY_FAILED = 7;
|
|
8
10
|
export declare const EXIT_CANCELLED = 130;
|
|
9
11
|
export declare const LOOP_EXITS: string[];
|
|
10
12
|
export declare const STAGE_EXITS: string[];
|
package/dist/exits.js
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
export const EXIT_OK = 0;
|
|
2
2
|
export const EXIT_BLOCKED = 1;
|
|
3
3
|
export const EXIT_CONFIG = 2;
|
|
4
|
-
export const
|
|
4
|
+
export const EXIT_STAGE_FAILED = 3;
|
|
5
|
+
export const EXIT_QUOTA = 8;
|
|
5
6
|
export const EXIT_REVISIONS = 4;
|
|
6
7
|
export const EXIT_DISPATCHES = 5;
|
|
7
8
|
export const EXIT_VERIFY = 6;
|
|
9
|
+
export const EXIT_VERIFY_FAILED = 7;
|
|
8
10
|
export const EXIT_CANCELLED = 130;
|
|
9
11
|
export const LOOP_EXITS = [
|
|
10
12
|
`Exit ${EXIT_OK} when the session is completed.`,
|
|
11
13
|
`Exit ${EXIT_BLOCKED} when the session is blocked. session continue runs that stage again.`,
|
|
12
14
|
`Exit ${EXIT_CONFIG} on a configuration error.`,
|
|
13
|
-
`Exit ${
|
|
15
|
+
`Exit ${EXIT_STAGE_FAILED} when a stage fails and the command does not wait. The session stays active.`,
|
|
16
|
+
`Exit ${EXIT_QUOTA} when --once or --stage hits a provider quota and does not wait. The session stays active.`,
|
|
14
17
|
`Exit ${EXIT_REVISIONS} when a route would exceed max_revisions. The session stays active.`,
|
|
15
18
|
`Exit ${EXIT_DISPATCHES} when --max-dispatches is spent. The session stays active.`,
|
|
16
19
|
`Exit ${EXIT_VERIFY} when verify fails max_verify times. The session stays active.`,
|
|
20
|
+
`Exit ${EXIT_VERIFY_FAILED} when a stage with no role fails verify. The session stays active.`,
|
|
17
21
|
`Exit ${EXIT_CANCELLED} when cancelled. session continue resumes that execution.`,
|
|
18
22
|
];
|
|
19
23
|
export const STAGE_EXITS = [
|
|
20
24
|
`Exit ${EXIT_OK} when the stage outcome is complete, or the session is already completed.`,
|
|
21
25
|
`Exit ${EXIT_BLOCKED} when the stage is not complete, or the session is blocked.`,
|
|
22
26
|
`Exit ${EXIT_CONFIG} on a configuration error.`,
|
|
27
|
+
`Exit ${EXIT_STAGE_FAILED} when a non-continue --once or --stage finds a failed stage with no resume marker.`,
|
|
28
|
+
`Exit ${EXIT_QUOTA} when --once or --stage hits a provider quota and does not wait.`,
|
|
23
29
|
`Exit ${EXIT_REVISIONS} when a route would exceed max_revisions. The session stays active.`,
|
|
24
30
|
`Exit ${EXIT_VERIFY} when verify fails max_verify times. The session stays active.`,
|
|
31
|
+
`Exit ${EXIT_VERIFY_FAILED} when a stage with no role fails verify. The session stays active.`,
|
|
25
32
|
`Exit ${EXIT_CANCELLED} when cancelled. session continue resumes that execution.`,
|
|
26
33
|
];
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { AgentToolRunner } from "@nodeint/migent-kernel";
|
|
2
|
+
import type { RunCommand } from "./provider.js";
|
|
2
3
|
/** Test seams. Production leaves both null. */
|
|
3
4
|
export declare const cliHooks: {
|
|
4
5
|
which: ((command: string) => string | null) | null;
|
|
5
6
|
runner: AgentToolRunner | null;
|
|
7
|
+
runCommand: RunCommand | null;
|
|
6
8
|
};
|
package/dist/hooks.js
CHANGED
package/dist/index.js
CHANGED
package/dist/migrate.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type MigrationProvider } from "@nodeint/migent-kernel";
|
|
2
2
|
export declare function requireCurrentSchema(workspace: string): void;
|
|
3
3
|
export declare function runMigrate(workspace: string, options?: {
|
|
4
4
|
assumeYes?: boolean;
|
|
5
5
|
confirm?: ((message: string) => boolean | Promise<boolean>) | null;
|
|
6
|
-
|
|
6
|
+
providers?: Record<string, MigrationProvider> | null;
|
|
7
7
|
}): Promise<number>;
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function migrationProviders(providers?: Record<string, unknown>): Record<string, MigrationProvider>;
|
package/dist/migrate.js
CHANGED
|
@@ -4,29 +4,31 @@ import { confirm as clackConfirm, isCancel } from "@clack/prompts";
|
|
|
4
4
|
import { SCHEMA_VERSION, documentVersion, loadYamlMapping, migrateConfig, migrateWorkflow, patchConfigText, patchWorkflowText, workflowsDirectory, ConfigurationError, } from "@nodeint/migent-kernel";
|
|
5
5
|
import { printError, printNotice } from "./display.js";
|
|
6
6
|
import { isDirectory, isFile } from "./fs-utils.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import { providerMap } from "./provider.js";
|
|
8
|
+
function versionList(entries) {
|
|
9
|
+
const width = Math.max(...entries.map(([label]) => label.length));
|
|
10
|
+
return entries.map(([label, version]) => ` ${label.padEnd(width)} v${version}`).join("\n");
|
|
11
|
+
}
|
|
9
12
|
export function requireCurrentSchema(workspace) {
|
|
10
13
|
const newer = [];
|
|
11
|
-
|
|
14
|
+
const older = [];
|
|
12
15
|
for (const [label, filePath] of schemaFiles(workspace)) {
|
|
13
16
|
const version = storedVersion(filePath);
|
|
14
17
|
if (version === null || version === SCHEMA_VERSION)
|
|
15
18
|
continue;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
19
|
+
(version > SCHEMA_VERSION ? newer : older).push([label, version]);
|
|
20
|
+
}
|
|
21
|
+
if (older.length > 0) {
|
|
22
|
+
throw new ConfigurationError(`Schema is outdated (this Migent uses v${SCHEMA_VERSION}).\n${versionList(older)}\n\n` +
|
|
23
|
+
"Run `migent migrate` to update.");
|
|
24
|
+
}
|
|
25
|
+
if (newer.length > 0) {
|
|
26
|
+
throw new ConfigurationError(`Schema is newer than this Migent supports (v${SCHEMA_VERSION}).\n${versionList(newer)}`);
|
|
21
27
|
}
|
|
22
|
-
if (outdated)
|
|
23
|
-
throw new ConfigurationError(OUTDATED);
|
|
24
|
-
if (newer.length > 0)
|
|
25
|
-
throw new ConfigurationError(newer.join(" "));
|
|
26
28
|
}
|
|
27
29
|
export async function runMigrate(workspace, options = {}) {
|
|
28
|
-
const
|
|
29
|
-
const rewrites = pendingRewrites(workspace,
|
|
30
|
+
const providers = options.providers ?? migrationProviders();
|
|
31
|
+
const rewrites = pendingRewrites(workspace, providers);
|
|
30
32
|
if (rewrites.length === 0) {
|
|
31
33
|
process.stdout.write("Schema is current.\n");
|
|
32
34
|
return 0;
|
|
@@ -43,10 +45,10 @@ export async function runMigrate(workspace, options = {}) {
|
|
|
43
45
|
process.stdout.write(`Upgraded schema to version ${SCHEMA_VERSION}.\n`);
|
|
44
46
|
return 0;
|
|
45
47
|
}
|
|
46
|
-
export function
|
|
48
|
+
export function migrationProviders(providers = providerMap()) {
|
|
47
49
|
const mapped = {};
|
|
48
|
-
for (const [name,
|
|
49
|
-
const candidate =
|
|
50
|
+
for (const [name, provider] of Object.entries(providers)) {
|
|
51
|
+
const candidate = provider;
|
|
50
52
|
mapped[name] = {
|
|
51
53
|
modelMigrations: candidate.modelMigrations ?? {},
|
|
52
54
|
roleMigrations: candidate.roleMigrations ?? {},
|
|
@@ -74,17 +76,17 @@ async function accepted(confirm) {
|
|
|
74
76
|
}
|
|
75
77
|
return true;
|
|
76
78
|
}
|
|
77
|
-
function pendingRewrites(workspace,
|
|
79
|
+
function pendingRewrites(workspace, providers) {
|
|
78
80
|
const configPath = path.join(workspace, ".migent", "config.yaml");
|
|
79
81
|
if (!isFile(configPath))
|
|
80
82
|
return [];
|
|
81
|
-
const [config, configRewrite] = configRewriteOf(configPath,
|
|
83
|
+
const [config, configRewrite] = configRewriteOf(configPath, providers);
|
|
82
84
|
if (config === null)
|
|
83
85
|
return [];
|
|
84
86
|
const rewrites = [];
|
|
85
87
|
if (configRewrite !== null)
|
|
86
88
|
rewrites.push(configRewrite);
|
|
87
|
-
rewrites.push(...workflowRewrites(workspace, config,
|
|
89
|
+
rewrites.push(...workflowRewrites(workspace, config, providers));
|
|
88
90
|
return rewrites;
|
|
89
91
|
}
|
|
90
92
|
function schemaFiles(workspace) {
|
|
@@ -109,7 +111,7 @@ function storedVersion(filePath) {
|
|
|
109
111
|
return null;
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
|
-
function configRewriteOf(filePath,
|
|
114
|
+
function configRewriteOf(filePath, providers) {
|
|
113
115
|
const original = readFileSync(filePath, "utf8");
|
|
114
116
|
let parsed;
|
|
115
117
|
try {
|
|
@@ -121,7 +123,7 @@ function configRewriteOf(filePath, adapters) {
|
|
|
121
123
|
const updated = structuredClone(parsed);
|
|
122
124
|
let notes;
|
|
123
125
|
try {
|
|
124
|
-
notes = migrateConfig(updated,
|
|
126
|
+
notes = migrateConfig(updated, providers);
|
|
125
127
|
}
|
|
126
128
|
catch (error) {
|
|
127
129
|
if (error instanceof ConfigurationError)
|
|
@@ -136,7 +138,7 @@ function configRewriteOf(filePath, adapters) {
|
|
|
136
138
|
const labeled = notes.map((note) => note.startsWith("schema_version") ? `Migrated .migent/config.yaml ${note}` : note);
|
|
137
139
|
return [updated, { path: filePath, text: rewritten, notes: labeled }];
|
|
138
140
|
}
|
|
139
|
-
function workflowRewrites(workspace, config,
|
|
141
|
+
function workflowRewrites(workspace, config, providers) {
|
|
140
142
|
const directory = workflowsDirectory(workspace);
|
|
141
143
|
if (!isDirectory(directory))
|
|
142
144
|
return [];
|
|
@@ -156,7 +158,7 @@ function workflowRewrites(workspace, config, adapters) {
|
|
|
156
158
|
const updated = structuredClone(parsed);
|
|
157
159
|
let changed;
|
|
158
160
|
try {
|
|
159
|
-
changed = migrateWorkflow(updated, config,
|
|
161
|
+
changed = migrateWorkflow(updated, config, providers);
|
|
160
162
|
}
|
|
161
163
|
catch (error) {
|
|
162
164
|
if (error instanceof ConfigurationError)
|