@interf/compiler 0.9.5 → 0.13.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 +96 -92
- package/TRADEMARKS.md +2 -13
- package/agent-skills/interf-actions/SKILL.md +95 -36
- package/agent-skills/interf-actions/references/cli.md +118 -51
- package/builtin-methods/interf-default/README.md +3 -4
- package/builtin-methods/interf-default/compile/stages/shape/SKILL.md +2 -2
- package/builtin-methods/interf-default/compile/stages/summarize/SKILL.md +2 -1
- package/builtin-methods/interf-default/improve/SKILL.md +1 -1
- package/builtin-methods/interf-default/method.json +10 -4
- package/builtin-methods/interf-default/method.schema.json +0 -9
- package/builtin-methods/interf-default/use/query/SKILL.md +5 -5
- package/dist/cli/commands/compile.d.ts +8 -25
- package/dist/cli/commands/compile.js +75 -360
- package/dist/cli/commands/doctor.js +1 -1
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.js +39 -0
- package/dist/cli/commands/logout.d.ts +2 -0
- package/dist/cli/commands/logout.js +16 -0
- package/dist/cli/commands/method.d.ts +2 -0
- package/dist/cli/commands/method.js +113 -0
- package/dist/cli/commands/prep.d.ts +2 -0
- package/dist/cli/commands/prep.js +134 -0
- package/dist/cli/commands/reset.d.ts +8 -1
- package/dist/cli/commands/reset.js +47 -26
- package/dist/cli/commands/runs.d.ts +2 -0
- package/dist/cli/commands/runs.js +120 -0
- package/dist/cli/commands/status.d.ts +6 -1
- package/dist/cli/commands/status.js +68 -111
- package/dist/cli/commands/test.d.ts +6 -14
- package/dist/cli/commands/test.js +65 -181
- package/dist/cli/commands/web.d.ts +0 -9
- package/dist/cli/commands/web.js +147 -120
- package/dist/cli/commands/wizard.d.ts +9 -0
- package/dist/cli/commands/wizard.js +442 -0
- package/dist/cli/index.d.ts +7 -6
- package/dist/cli/index.js +13 -10
- package/dist/compiler-ui/404.html +1 -1
- package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
- package/dist/compiler-ui/__next._full.txt +3 -3
- package/dist/compiler-ui/__next._head.txt +1 -1
- package/dist/compiler-ui/__next._index.txt +2 -2
- package/dist/compiler-ui/__next._tree.txt +2 -2
- package/dist/compiler-ui/_next/static/chunks/{18a8f2jkv3z.c.css → 045gole2ojo3g.css} +1 -1
- package/dist/compiler-ui/_next/static/chunks/{177mvn4rse235.js → 17t-lulmyawg5.js} +9 -9
- package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
- package/dist/compiler-ui/_not-found.html +1 -1
- package/dist/compiler-ui/_not-found.txt +2 -2
- package/dist/compiler-ui/index.html +1 -1
- package/dist/compiler-ui/index.txt +3 -3
- package/dist/packages/agents/lib/shells.d.ts +1 -1
- package/dist/packages/agents/lib/shells.js +111 -52
- package/dist/packages/agents/lib/user-config.d.ts +4 -2
- package/dist/packages/agents/lib/user-config.js +15 -7
- package/dist/packages/compiler/compiled-paths.d.ts +9 -2
- package/dist/packages/compiler/compiled-paths.js +30 -15
- package/dist/packages/compiler/compiled-pipeline.js +23 -3
- package/dist/packages/compiler/compiled-stage-plan.js +4 -0
- package/dist/packages/compiler/compiled-target.d.ts +1 -1
- package/dist/packages/compiler/compiled-target.js +1 -1
- package/dist/packages/compiler/index.d.ts +1 -0
- package/dist/packages/compiler/index.js +1 -0
- package/dist/packages/compiler/lib/schema.d.ts +26 -31
- package/dist/packages/compiler/lib/schema.js +1 -12
- package/dist/packages/compiler/method-runs.d.ts +2 -3
- package/dist/packages/compiler/method-runs.js +2 -3
- package/dist/packages/compiler/reset.js +3 -1
- package/dist/packages/compiler/runtime-contracts.js +0 -3
- package/dist/packages/compiler/runtime-prompt.js +1 -1
- package/dist/packages/compiler/source-files.d.ts +46 -0
- package/dist/packages/compiler/source-files.js +149 -0
- package/dist/packages/compiler/state-artifacts.d.ts +3 -2
- package/dist/packages/compiler/state-artifacts.js +4 -3
- package/dist/packages/compiler/state-io.d.ts +3 -2
- package/dist/packages/compiler/state-io.js +11 -5
- package/dist/packages/compiler/state-paths.d.ts +2 -1
- package/dist/packages/compiler/state-paths.js +6 -3
- package/dist/packages/compiler/state-view.d.ts +3 -2
- package/dist/packages/compiler/state-view.js +18 -28
- package/dist/packages/compiler/state.d.ts +4 -4
- package/dist/packages/compiler/state.js +3 -3
- package/dist/packages/contracts/index.d.ts +1 -1
- package/dist/packages/contracts/lib/preparation-paths.d.ts +117 -0
- package/dist/packages/contracts/lib/preparation-paths.js +177 -0
- package/dist/packages/contracts/lib/schema.d.ts +85 -5
- package/dist/packages/contracts/lib/schema.js +46 -1
- package/dist/packages/execution/lib/schema.d.ts +50 -50
- package/dist/packages/execution/lib/schema.js +1 -1
- package/dist/packages/local-service/action-definitions.d.ts +14 -14
- package/dist/packages/local-service/action-definitions.js +27 -28
- package/dist/packages/local-service/action-planner.js +2 -1
- package/dist/packages/local-service/client.d.ts +51 -52
- package/dist/packages/local-service/client.js +132 -140
- package/dist/packages/local-service/connection-config.d.ts +38 -0
- package/dist/packages/local-service/connection-config.js +75 -0
- package/dist/packages/local-service/index.d.ts +11 -7
- package/dist/packages/local-service/index.js +6 -4
- package/dist/packages/local-service/instance-paths.d.ts +100 -0
- package/dist/packages/local-service/instance-paths.js +165 -0
- package/dist/packages/local-service/lib/schema.d.ts +405 -2297
- package/dist/packages/local-service/lib/schema.js +146 -62
- package/dist/packages/local-service/native-run-handlers.js +3 -3
- package/dist/packages/local-service/preparation-store.d.ts +92 -0
- package/dist/packages/local-service/preparation-store.js +171 -0
- package/dist/packages/local-service/routes.d.ts +33 -16
- package/dist/packages/local-service/routes.js +44 -20
- package/dist/packages/local-service/run-observability.js +11 -11
- package/dist/packages/local-service/runtime-caches.d.ts +76 -0
- package/dist/packages/local-service/runtime-caches.js +191 -0
- package/dist/packages/local-service/runtime-event-applier.d.ts +12 -0
- package/dist/packages/local-service/runtime-event-applier.js +177 -0
- package/dist/packages/local-service/runtime-persistence.d.ts +47 -0
- package/dist/packages/local-service/runtime-persistence.js +137 -0
- package/dist/packages/local-service/runtime-proposal-helpers.d.ts +35 -0
- package/dist/packages/local-service/runtime-proposal-helpers.js +251 -0
- package/dist/packages/local-service/runtime-resource-builders.d.ts +52 -0
- package/dist/packages/local-service/runtime-resource-builders.js +149 -0
- package/dist/packages/local-service/runtime.d.ts +197 -43
- package/dist/packages/local-service/runtime.js +800 -974
- package/dist/packages/local-service/server.d.ts +15 -0
- package/dist/packages/local-service/server.js +641 -273
- package/dist/packages/local-service/service-registry.d.ts +47 -0
- package/dist/packages/local-service/service-registry.js +137 -0
- package/dist/packages/method-authoring/method-authoring.d.ts +1 -1
- package/dist/packages/method-authoring/method-authoring.js +2 -2
- package/dist/packages/method-authoring/method-improvement.js +1 -1
- package/dist/packages/method-package/builtin-compiled-method.d.ts +4 -5
- package/dist/packages/method-package/builtin-compiled-method.js +8 -14
- package/dist/packages/method-package/context-interface.d.ts +4 -40
- package/dist/packages/method-package/context-interface.js +1 -23
- package/dist/packages/method-package/interf-method-package.d.ts +4 -4
- package/dist/packages/method-package/interf-method-package.js +21 -33
- package/dist/packages/method-package/local-methods.d.ts +10 -6
- package/dist/packages/method-package/local-methods.js +57 -39
- package/dist/packages/method-package/method-definitions.d.ts +8 -34
- package/dist/packages/method-package/method-definitions.js +49 -37
- package/dist/packages/method-package/method-helpers.d.ts +1 -13
- package/dist/packages/method-package/method-helpers.js +8 -42
- package/dist/packages/method-package/method-stage-runner.js +2 -2
- package/dist/packages/method-package/user-methods.d.ts +17 -0
- package/dist/packages/method-package/user-methods.js +77 -0
- package/dist/packages/project-model/index.d.ts +0 -1
- package/dist/packages/project-model/index.js +0 -1
- package/dist/packages/project-model/interf-detect.d.ts +8 -3
- package/dist/packages/project-model/interf-detect.js +34 -34
- package/dist/packages/project-model/interf-scaffold.d.ts +3 -3
- package/dist/packages/project-model/interf-scaffold.js +23 -32
- package/dist/packages/project-model/lib/schema.js +38 -1
- package/dist/packages/project-model/preparation-entries.d.ts +5 -5
- package/dist/packages/project-model/preparation-entries.js +14 -14
- package/dist/packages/project-model/source-config.d.ts +11 -11
- package/dist/packages/project-model/source-config.js +74 -46
- package/dist/packages/project-model/source-folders.d.ts +5 -5
- package/dist/packages/project-model/source-folders.js +14 -14
- package/dist/packages/shared/filesystem.d.ts +7 -0
- package/dist/packages/shared/filesystem.js +97 -10
- package/dist/packages/testing/lib/schema.d.ts +10 -10
- package/dist/packages/testing/lib/schema.js +2 -2
- package/dist/packages/testing/readiness-check-run.d.ts +4 -4
- package/dist/packages/testing/readiness-check-run.js +36 -36
- package/dist/packages/testing/test-execution.js +6 -6
- package/dist/packages/testing/test-paths.js +4 -3
- package/dist/packages/testing/test-sandbox.d.ts +0 -1
- package/dist/packages/testing/test-sandbox.js +14 -30
- package/dist/packages/testing/test-targets.d.ts +1 -1
- package/dist/packages/testing/test-targets.js +6 -6
- package/dist/packages/testing/test.d.ts +1 -1
- package/dist/packages/testing/test.js +1 -1
- package/package.json +3 -4
- package/CHANGELOG.md +0 -93
- package/LICENSE +0 -183
- package/dist/cli/commands/action-input-cli.d.ts +0 -25
- package/dist/cli/commands/action-input-cli.js +0 -73
- package/dist/cli/commands/control-path.d.ts +0 -11
- package/dist/cli/commands/control-path.js +0 -72
- package/dist/cli/commands/create-method-wizard.d.ts +0 -64
- package/dist/cli/commands/create-method-wizard.js +0 -434
- package/dist/cli/commands/create.d.ts +0 -6
- package/dist/cli/commands/create.js +0 -183
- package/dist/cli/commands/default.d.ts +0 -2
- package/dist/cli/commands/default.js +0 -39
- package/dist/cli/commands/executor-flow.d.ts +0 -29
- package/dist/cli/commands/executor-flow.js +0 -163
- package/dist/cli/commands/init.d.ts +0 -26
- package/dist/cli/commands/init.js +0 -771
- package/dist/cli/commands/list.d.ts +0 -2
- package/dist/cli/commands/list.js +0 -30
- package/dist/cli/commands/preparation-action.d.ts +0 -8
- package/dist/cli/commands/preparation-action.js +0 -29
- package/dist/cli/commands/preparation-picker.d.ts +0 -5
- package/dist/cli/commands/preparation-picker.js +0 -36
- package/dist/cli/commands/preparation-selection.d.ts +0 -6
- package/dist/cli/commands/preparation-selection.js +0 -11
- package/dist/cli/commands/service-action-flow.d.ts +0 -9
- package/dist/cli/commands/service-action-flow.js +0 -19
- package/dist/cli/commands/source-config-wizard.d.ts +0 -51
- package/dist/cli/commands/source-config-wizard.js +0 -670
- package/dist/cli/commands/verify.d.ts +0 -2
- package/dist/cli/commands/verify.js +0 -94
- package/dist/packages/compiler/raw-snapshot.d.ts +0 -49
- package/dist/packages/compiler/raw-snapshot.js +0 -101
- package/dist/packages/method-package/index.d.ts +0 -11
- package/dist/packages/method-package/index.js +0 -11
- package/dist/packages/method-package/method-stage-policy.d.ts +0 -5
- package/dist/packages/method-package/method-stage-policy.js +0 -31
- package/dist/packages/project-model/project-paths.d.ts +0 -12
- package/dist/packages/project-model/project-paths.js +0 -33
- /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_buildManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_clientMiddlewareManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_ssgManifest.js +0 -0
|
@@ -1,367 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `interf compile <prep-id>` — start a compile run for a preparation.
|
|
3
|
+
*
|
|
4
|
+
* interf compile bristol
|
|
5
|
+
* interf compile bristol --quiet # only the locator on stdout (scripting)
|
|
6
|
+
* interf compile bristol --watch # stream events
|
|
7
|
+
*
|
|
8
|
+
* Requires an active connection. Hits POST /v1/preparations/<id>/compile-runs.
|
|
9
|
+
*/
|
|
1
10
|
import chalk from "chalk";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
command: "compile",
|
|
14
|
-
describe: "Prepare files and write Portable Context agents can use",
|
|
15
|
-
builder: (yargs) => yargs.option("preparation", {
|
|
16
|
-
type: "string",
|
|
17
|
-
describe: "Preparation id to compile when this Source Folder has more than one Preparation",
|
|
18
|
-
}).option("max-attempts", {
|
|
19
|
-
type: "number",
|
|
20
|
-
describe: "Retry the prepare run and run saved readiness checks with the same Method until the Preparation is ready or reaches this total attempt limit",
|
|
21
|
-
}).option("max-loops", {
|
|
22
|
-
type: "number",
|
|
23
|
-
describe: "After retries fail, let Interf edit the Method and run saved readiness checks on new Method variations for this Preparation up to this loop limit",
|
|
24
|
-
}).option("keep-stage-shells", {
|
|
25
|
-
type: "boolean",
|
|
26
|
-
default: false,
|
|
27
|
-
describe: "Keep every executed stage shell under .interf/runtime/execution-shells for review instead of pruning successful shells",
|
|
28
|
-
}),
|
|
29
|
-
handler: async (argv) => {
|
|
30
|
-
await runCompileCommand(argv);
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
const defaultCompileCommandDeps = {
|
|
34
|
-
choosePreparationConfig,
|
|
35
|
-
confirm: p.confirm,
|
|
36
|
-
detectInterf,
|
|
37
|
-
resolveInteractiveCompileLoopOverrides,
|
|
38
|
-
};
|
|
39
|
-
function readHintedSourcePath(argv) {
|
|
40
|
-
return typeof argv.sourcePath === "string" && argv.sourcePath.trim().length > 0
|
|
41
|
-
? argv.sourcePath.trim()
|
|
42
|
-
: null;
|
|
43
|
-
}
|
|
44
|
-
function readRequestedPreparationName(argv) {
|
|
45
|
-
const raw = argv.preparation;
|
|
46
|
-
return typeof raw === "string" && raw.trim().length > 0
|
|
47
|
-
? raw.trim()
|
|
48
|
-
: null;
|
|
49
|
-
}
|
|
50
|
-
function shouldSkipCompileConfirm(argv) {
|
|
51
|
-
return argv.skipConfirm === true;
|
|
52
|
-
}
|
|
53
|
-
function shouldSkipPreparationBanner(argv) {
|
|
54
|
-
return argv.skipPreparationBanner === true;
|
|
55
|
-
}
|
|
56
|
-
function compileRunTests(options) {
|
|
57
|
-
const checks = options.compiledConfig?.checks ?? [];
|
|
58
|
-
if (checks.length === 0)
|
|
59
|
-
return false;
|
|
60
|
-
const configuredMaxAttempts = resolvePreparationCompileMaxAttempts(options.compiledConfig ?? { max_attempts: undefined }, options.maxAttemptsOverride);
|
|
61
|
-
const maxLoops = resolvePreparationCompileMaxLoops(options.compiledConfig ?? { max_loops: undefined }, options.maxLoopsOverride);
|
|
62
|
-
const maxAttempts = configuredMaxAttempts ?? (maxLoops != null ? 1 : null);
|
|
63
|
-
return maxAttempts != null;
|
|
11
|
+
import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/local-service/connection-config.js";
|
|
12
|
+
function resolveConnection(args) {
|
|
13
|
+
const conn = readActiveConnection({
|
|
14
|
+
urlOverride: args.url,
|
|
15
|
+
authTokenOverride: args.token,
|
|
16
|
+
});
|
|
17
|
+
if (!conn) {
|
|
18
|
+
console.error(CONNECT_OR_ERROR_HINT);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
|
|
64
22
|
}
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
let
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const skipConfirm = shouldSkipCompileConfirm(argv);
|
|
78
|
-
const skipPreparationBanner = shouldSkipPreparationBanner(argv);
|
|
79
|
-
if (detected) {
|
|
80
|
-
compiledPath = detected.path;
|
|
81
|
-
sourcePath = resolveSourceControlPath(detected.path);
|
|
82
|
-
compiledConfig = loadCompiledPreparationConfig(detected.path)
|
|
83
|
-
?? sourcePreparationConfigFromInterfConfig(detected.config);
|
|
84
|
-
if (!skipConfirm && process.stdin.isTTY && process.stdout.isTTY) {
|
|
85
|
-
const confirmed = await helpers.confirm({
|
|
86
|
-
message: `Prepare files for Preparation "${detected.config.name}" now?`,
|
|
87
|
-
initialValue: true,
|
|
88
|
-
});
|
|
89
|
-
if (p.isCancel(confirmed) || !confirmed)
|
|
90
|
-
return null;
|
|
23
|
+
async function callJson(url, token, init = {}) {
|
|
24
|
+
const headers = new Headers(init.headers ?? {});
|
|
25
|
+
if (token)
|
|
26
|
+
headers.set("authorization", `Bearer ${token}`);
|
|
27
|
+
if (init.body && !headers.has("content-type"))
|
|
28
|
+
headers.set("content-type", "application/json");
|
|
29
|
+
const response = await fetch(url, { ...init, headers });
|
|
30
|
+
const raw = await response.text();
|
|
31
|
+
let body = null;
|
|
32
|
+
if (raw.length > 0) {
|
|
33
|
+
try {
|
|
34
|
+
body = JSON.parse(raw);
|
|
91
35
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const selectedCompiled = requestedPreparationName || hintedPreparationConfig
|
|
95
|
-
? resolveConfiguredPreparationSelection({
|
|
96
|
-
sourcePath,
|
|
97
|
-
requestedPreparationName,
|
|
98
|
-
hintedPreparationConfig,
|
|
99
|
-
})
|
|
100
|
-
: await helpers.choosePreparationConfig({
|
|
101
|
-
sourcePath,
|
|
102
|
-
selectMessage: "Which saved Preparation do you want to compile?",
|
|
103
|
-
});
|
|
104
|
-
if (selectedCompiled === undefined)
|
|
105
|
-
return null;
|
|
106
|
-
if (!selectedCompiled) {
|
|
107
|
-
process.exitCode = 1;
|
|
108
|
-
if (requestedPreparationName) {
|
|
109
|
-
console.log(chalk.red(` Preparation "${requestedPreparationName}" is not saved in this Source Folder.`));
|
|
110
|
-
console.log(chalk.dim(" Run `interf list` to see the saved Preparations."));
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
console.log(chalk.red(" No saved Preparations are configured for this Source Folder yet."));
|
|
114
|
-
console.log(chalk.dim(" Start with `interf` or `interf init` to set up this folder."));
|
|
115
|
-
}
|
|
116
|
-
return null;
|
|
36
|
+
catch {
|
|
37
|
+
body = null;
|
|
117
38
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
39
|
+
}
|
|
40
|
+
return { status: response.status, body, raw };
|
|
41
|
+
}
|
|
42
|
+
export const compileCommand = {
|
|
43
|
+
command: "compile <prep-id>",
|
|
44
|
+
describe: "Start a compile run for a preparation",
|
|
45
|
+
builder: (yargs) => yargs
|
|
46
|
+
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
47
|
+
.option("watch", { type: "boolean", default: false, describe: "Stream run events" })
|
|
48
|
+
.option("quiet", { type: "boolean", default: false, describe: "Print only the portable-context locator on success" })
|
|
49
|
+
.option("idempotency-key", { type: "string", describe: "Client-supplied dedupe key" })
|
|
50
|
+
.option("url", { type: "string", describe: "Override the active connection URL" })
|
|
51
|
+
.option("token", { type: "string", describe: "Override the active bearer token" }),
|
|
52
|
+
handler: async (args) => {
|
|
53
|
+
const { url, token } = resolveConnection(args);
|
|
54
|
+
const headers = {};
|
|
55
|
+
if (args.idempotencyKey)
|
|
56
|
+
headers["x-interf-idempotency-key"] = args.idempotencyKey;
|
|
57
|
+
const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/compile-runs`, token, { method: "POST", headers, body: JSON.stringify({}) });
|
|
58
|
+
if (status !== 201 && status !== 200 && status !== 202) {
|
|
59
|
+
console.error(chalk.red(`Failed to start compile run for ${args.prepId} (HTTP ${status}).`));
|
|
60
|
+
if (raw)
|
|
61
|
+
console.error(raw);
|
|
62
|
+
process.exit(1);
|
|
125
63
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
64
|
+
const run = body?.run;
|
|
65
|
+
const runId = run?.run_id ?? "(unknown run)";
|
|
66
|
+
const locator = run?.portable_context_path ?? "(no locator)";
|
|
67
|
+
if (args.quiet) {
|
|
68
|
+
console.log(locator);
|
|
69
|
+
return;
|
|
130
70
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
process.exitCode = 1;
|
|
140
|
-
console.log(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
const interactiveOverrides = await helpers.resolveInteractiveCompileLoopOverrides({
|
|
144
|
-
compiledPath,
|
|
145
|
-
compiledConfig,
|
|
146
|
-
maxAttemptsOverride,
|
|
147
|
-
maxLoopsOverride,
|
|
148
|
-
});
|
|
149
|
-
if (!interactiveOverrides)
|
|
150
|
-
return null;
|
|
151
|
-
compiledConfig = interactiveOverrides.compiledConfig;
|
|
152
|
-
maxAttemptsOverride = interactiveOverrides.maxAttemptsOverride;
|
|
153
|
-
maxLoopsOverride = interactiveOverrides.maxLoopsOverride;
|
|
154
|
-
const testedDuringCompile = compileRunTests({
|
|
155
|
-
compiledConfig,
|
|
156
|
-
maxAttemptsOverride,
|
|
157
|
-
maxLoopsOverride,
|
|
158
|
-
});
|
|
159
|
-
if (compiledConfig) {
|
|
160
|
-
const submitted = await submitCompileRunToLocalService({
|
|
161
|
-
projectPath: sourcePath,
|
|
162
|
-
request: {
|
|
163
|
-
preparation: compiledConfig.name,
|
|
164
|
-
...(compiledConfig.method ? { method: compiledConfig.method } : {}),
|
|
165
|
-
...(maxAttemptsOverride != null ? { max_attempts: maxAttemptsOverride } : {}),
|
|
166
|
-
...(maxLoopsOverride != null ? { max_loops: maxLoopsOverride } : {}),
|
|
167
|
-
preserve_stage_shells: readStageShellRetentionMode(argv),
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
if (submitted) {
|
|
171
|
-
console.log(chalk.dim(` Visible in Interf: ${submitted.serviceUrl}/`));
|
|
172
|
-
let lastStatus = "";
|
|
173
|
-
let lastStage = "";
|
|
174
|
-
const completed = await waitForLocalCompileRun({
|
|
175
|
-
serviceUrl: submitted.serviceUrl,
|
|
176
|
-
runId: submitted.resource.run.run_id,
|
|
177
|
-
onUpdate(resource) {
|
|
178
|
-
const activeStage = resource.run.stages.find((stage) => stage.status === "running")
|
|
179
|
-
?? [...resource.run.stages].reverse().find((stage) => stage.status === "succeeded" || stage.status === "failed")
|
|
180
|
-
?? null;
|
|
181
|
-
const statusKey = `${resource.run.status}:${activeStage?.stage_id ?? ""}:${activeStage?.status ?? ""}`;
|
|
182
|
-
if (statusKey === `${lastStatus}:${lastStage}`)
|
|
183
|
-
return;
|
|
184
|
-
lastStatus = resource.run.status;
|
|
185
|
-
lastStage = `${activeStage?.stage_id ?? ""}:${activeStage?.status ?? ""}`;
|
|
186
|
-
if (activeStage) {
|
|
187
|
-
console.log(chalk.dim(` ${activeStage.stage_label ?? activeStage.stage_id}: ${activeStage.status}`));
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
console.log(chalk.dim(` Prepare run: ${resource.run.status}`));
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
if (completed.run.status !== "succeeded") {
|
|
195
|
-
process.exitCode = 1;
|
|
196
|
-
const failure = completed.run.stages.find((stage) => stage.status === "failed");
|
|
197
|
-
console.log(chalk.red(` Prepare run ${completed.run.status}.`));
|
|
198
|
-
if (failure?.failure)
|
|
199
|
-
console.log(chalk.red(` ${failure.failure}`));
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
console.log(chalk.green(" Portable Context ready."));
|
|
203
|
-
return {
|
|
204
|
-
compiledPath: completed.run.portable_context_path,
|
|
205
|
-
testedDuringCompile,
|
|
206
|
-
};
|
|
71
|
+
console.log();
|
|
72
|
+
console.log(` Run ${chalk.bold(runId)} ${chalk.dim(`(${run?.status ?? "started"})`)}`);
|
|
73
|
+
console.log(` Portable context: ${locator}`);
|
|
74
|
+
if (run?.status === "succeeded" || run?.finished_at) {
|
|
75
|
+
const prepResp = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}`, token);
|
|
76
|
+
const readiness = prepResp.body?.readiness?.status;
|
|
77
|
+
if (readiness)
|
|
78
|
+
console.log(` Readiness: ${readiness}`);
|
|
207
79
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
process.exitCode = 1;
|
|
214
|
-
console.log(chalk.red(" Interf could not resolve a saved Preparation for this prepare run."));
|
|
215
|
-
console.log(chalk.dim(" Run `interf list` to inspect saved Preparations, then rerun `interf compile --preparation <id>`."));
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
export async function resolveInteractiveCompileLoopOverrides(options) {
|
|
219
|
-
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
220
|
-
return {
|
|
221
|
-
compiledConfig: options.compiledConfig,
|
|
222
|
-
maxAttemptsOverride: options.maxAttemptsOverride,
|
|
223
|
-
maxLoopsOverride: options.maxLoopsOverride,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
if (options.maxAttemptsOverride != null || options.maxLoopsOverride != null) {
|
|
227
|
-
return {
|
|
228
|
-
compiledConfig: options.compiledConfig,
|
|
229
|
-
maxAttemptsOverride: options.maxAttemptsOverride,
|
|
230
|
-
maxLoopsOverride: options.maxLoopsOverride,
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
const currentConfig = readInterfConfig(options.compiledPath);
|
|
234
|
-
const checks = options.compiledConfig?.checks.length
|
|
235
|
-
? options.compiledConfig.checks
|
|
236
|
-
: (currentConfig?.checks ?? []);
|
|
237
|
-
if (checks.length === 0) {
|
|
238
|
-
return {
|
|
239
|
-
compiledConfig: options.compiledConfig,
|
|
240
|
-
maxAttemptsOverride: options.maxAttemptsOverride,
|
|
241
|
-
maxLoopsOverride: options.maxLoopsOverride,
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
const savedCompiledConfig = options.compiledConfig
|
|
245
|
-
?? (currentConfig
|
|
246
|
-
? (loadCompiledPreparationConfig(options.compiledPath)
|
|
247
|
-
?? sourcePreparationConfigFromInterfConfig(currentConfig))
|
|
248
|
-
: null);
|
|
249
|
-
if (!savedCompiledConfig) {
|
|
250
|
-
return {
|
|
251
|
-
compiledConfig: options.compiledConfig,
|
|
252
|
-
maxAttemptsOverride: options.maxAttemptsOverride,
|
|
253
|
-
maxLoopsOverride: options.maxLoopsOverride,
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
const hasSavedPolicy = typeof savedCompiledConfig.max_attempts === "number" ||
|
|
257
|
-
typeof savedCompiledConfig.max_loops === "number";
|
|
258
|
-
if (!hasSavedPolicy) {
|
|
259
|
-
const overrideSelection = await promptCompileLoopSelection({
|
|
260
|
-
hasChecks: true,
|
|
261
|
-
initialMaxAttempts: savedCompiledConfig.max_attempts,
|
|
262
|
-
initialMaxLoops: savedCompiledConfig.max_loops,
|
|
263
|
-
intro: [
|
|
264
|
-
`Method: ${resolveMethodId(savedCompiledConfig, resolveMethodId(currentConfig))}`,
|
|
265
|
-
"This selection applies to this prepare run only. It does not change the saved Preparation.",
|
|
266
|
-
],
|
|
267
|
-
message: "How should this prepare run work?",
|
|
268
|
-
});
|
|
269
|
-
if (overrideSelection === null)
|
|
270
|
-
return null;
|
|
271
|
-
return {
|
|
272
|
-
compiledConfig: {
|
|
273
|
-
...savedCompiledConfig,
|
|
274
|
-
max_attempts: undefined,
|
|
275
|
-
max_loops: undefined,
|
|
276
|
-
},
|
|
277
|
-
maxAttemptsOverride: overrideSelection.max_attempts ?? null,
|
|
278
|
-
maxLoopsOverride: overrideSelection.max_loops ?? null,
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
const savedMode = await p.select({
|
|
282
|
-
message: "Which prepare mode should this run use?",
|
|
283
|
-
options: [
|
|
284
|
-
{
|
|
285
|
-
value: "saved",
|
|
286
|
-
label: "Use saved prepare mode (Recommended)",
|
|
287
|
-
hint: `${savedCompiledConfig.max_loops ? "Self-improving" : savedCompiledConfig.max_attempts && savedCompiledConfig.max_attempts > 1 ? "Retry" : "Single attempt"} · ${formatCompileModeHint(savedCompiledConfig)}`,
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
value: "override",
|
|
291
|
-
label: "Change it for this run only",
|
|
292
|
-
hint: "Keep the saved Preparation unchanged",
|
|
293
|
-
},
|
|
294
|
-
],
|
|
295
|
-
});
|
|
296
|
-
if (p.isCancel(savedMode))
|
|
297
|
-
return null;
|
|
298
|
-
if (savedMode === "saved") {
|
|
299
|
-
return {
|
|
300
|
-
compiledConfig: savedCompiledConfig,
|
|
301
|
-
maxAttemptsOverride: null,
|
|
302
|
-
maxLoopsOverride: null,
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
const selection = await promptCompileLoopSelection({
|
|
306
|
-
hasChecks: true,
|
|
307
|
-
initialMaxAttempts: savedCompiledConfig.max_attempts,
|
|
308
|
-
initialMaxLoops: savedCompiledConfig.max_loops,
|
|
309
|
-
intro: [
|
|
310
|
-
`Method: ${resolveMethodId(savedCompiledConfig, resolveMethodId(currentConfig))}`,
|
|
311
|
-
"This applies to this prepare run only. It does not change the saved Preparation.",
|
|
312
|
-
],
|
|
313
|
-
message: "Override the prepare mode for this run",
|
|
314
|
-
});
|
|
315
|
-
if (selection === null)
|
|
316
|
-
return null;
|
|
317
|
-
return {
|
|
318
|
-
...savedCompiledConfig,
|
|
319
|
-
compiledConfig: {
|
|
320
|
-
...savedCompiledConfig,
|
|
321
|
-
max_attempts: undefined,
|
|
322
|
-
max_loops: undefined,
|
|
323
|
-
},
|
|
324
|
-
maxAttemptsOverride: selection.max_attempts ?? null,
|
|
325
|
-
maxLoopsOverride: selection.max_loops ?? null,
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
function formatCompileModeHint(compiledConfig) {
|
|
329
|
-
if (typeof compiledConfig.max_loops === "number" && compiledConfig.max_loops > 0) {
|
|
330
|
-
const attempts = compiledConfig.max_attempts ?? 1;
|
|
331
|
-
return `${attempts} attempt${attempts === 1 ? "" : "s"} per variation, ${compiledConfig.max_loops} loop${compiledConfig.max_loops === 1 ? "" : "s"}`;
|
|
332
|
-
}
|
|
333
|
-
if (typeof compiledConfig.max_attempts === "number" && compiledConfig.max_attempts > 1) {
|
|
334
|
-
return `${compiledConfig.max_attempts} attempts`;
|
|
335
|
-
}
|
|
336
|
-
return "1 attempt";
|
|
337
|
-
}
|
|
338
|
-
function readCompileMaxAttemptsOverride(argv) {
|
|
339
|
-
const raw = argv["max-attempts"] ??
|
|
340
|
-
argv.maxAttempts ??
|
|
341
|
-
argv["max-retries"] ??
|
|
342
|
-
argv.maxRetries;
|
|
343
|
-
if (raw == null)
|
|
344
|
-
return null;
|
|
345
|
-
const parsed = Number.parseInt(String(raw), 10);
|
|
346
|
-
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 5) {
|
|
347
|
-
throw new Error("`--max-attempts` must be a whole number from 1 to 5.");
|
|
348
|
-
}
|
|
349
|
-
return parsed;
|
|
350
|
-
}
|
|
351
|
-
function readStageShellRetentionMode(argv) {
|
|
352
|
-
const enabled = argv["keep-stage-shells"] ??
|
|
353
|
-
argv.keepStageShells ??
|
|
354
|
-
false;
|
|
355
|
-
return enabled ? "always" : "on-failure";
|
|
356
|
-
}
|
|
357
|
-
function readCompileMaxLoopsOverride(argv) {
|
|
358
|
-
const raw = argv["max-loops"] ??
|
|
359
|
-
argv.maxLoops;
|
|
360
|
-
if (raw == null)
|
|
361
|
-
return null;
|
|
362
|
-
const parsed = Number.parseInt(String(raw), 10);
|
|
363
|
-
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 3) {
|
|
364
|
-
throw new Error("`--max-loops` must be a whole number from 1 to 3.");
|
|
365
|
-
}
|
|
366
|
-
return parsed;
|
|
367
|
-
}
|
|
80
|
+
console.log();
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -97,7 +97,7 @@ export const doctorCommand = {
|
|
|
97
97
|
id: "live",
|
|
98
98
|
label: "Live executor preflight",
|
|
99
99
|
status: "skipped",
|
|
100
|
-
message: "Skipped. Run `interf doctor --live` to exercise the real local agent before drafting readiness checks, Method authoring, a readiness check, or a
|
|
100
|
+
message: "Skipped. Run `interf doctor --live` to exercise the real local agent before drafting readiness checks, Method authoring, a readiness check, or a compile run.",
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
103
|
const ok = checks.every((check) => check.status !== "fail");
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `interf login` — set the active connection record.
|
|
3
|
+
*
|
|
4
|
+
* interf login --url <url> [--token <token>]
|
|
5
|
+
*
|
|
6
|
+
* Writes `~/.interf/connection.json` so subsequent CLI commands target the
|
|
7
|
+
* remote (or alternate local) URL. There is no remote backend in 0.13 — this
|
|
8
|
+
* is the on-disk config layer that the cloud product will consume. Equivalent
|
|
9
|
+
* to running `interf web` (which writes a local connection record on
|
|
10
|
+
* startup).
|
|
11
|
+
*/
|
|
12
|
+
import chalk from "chalk";
|
|
13
|
+
import { ConnectionRecordSchema, writeConnection, } from "../../packages/local-service/connection-config.js";
|
|
14
|
+
export const loginCommand = {
|
|
15
|
+
command: "login",
|
|
16
|
+
describe: "Set the active Interf instance connection (URL + optional bearer token)",
|
|
17
|
+
builder: (yargs) => yargs
|
|
18
|
+
.option("url", {
|
|
19
|
+
type: "string",
|
|
20
|
+
demandOption: true,
|
|
21
|
+
describe: "Engine URL, e.g. https://api.interf.cloud or http://127.0.0.1:4873",
|
|
22
|
+
})
|
|
23
|
+
.option("token", {
|
|
24
|
+
type: "string",
|
|
25
|
+
describe: "Bearer token for non-loopback connections",
|
|
26
|
+
}),
|
|
27
|
+
handler: (args) => {
|
|
28
|
+
const url = args.url.trim();
|
|
29
|
+
const token = args.token?.trim();
|
|
30
|
+
const record = ConnectionRecordSchema.parse({
|
|
31
|
+
url,
|
|
32
|
+
auth_token: token && token.length > 0 ? token : null,
|
|
33
|
+
});
|
|
34
|
+
writeConnection(record);
|
|
35
|
+
console.log(chalk.green(`Connection saved.`));
|
|
36
|
+
console.log(chalk.dim(` url: ${record.url}`));
|
|
37
|
+
console.log(chalk.dim(` auth: ${record.auth_token ? "(token set)" : "(loopback / no token)"}`));
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `interf logout` — clear the active connection record.
|
|
3
|
+
*
|
|
4
|
+
* Removes `~/.interf/connection.json`. Subsequent CLI commands will exit
|
|
5
|
+
* non-zero with the connect-or-error hint until a new connection is set.
|
|
6
|
+
*/
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { clearConnection } from "../../packages/local-service/connection-config.js";
|
|
9
|
+
export const logoutCommand = {
|
|
10
|
+
command: "logout",
|
|
11
|
+
describe: "Clear the active Interf instance connection",
|
|
12
|
+
handler: () => {
|
|
13
|
+
clearConnection();
|
|
14
|
+
console.log(chalk.green("Connection cleared."));
|
|
15
|
+
},
|
|
16
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `interf method` — manage methods on the connected instance.
|
|
3
|
+
*
|
|
4
|
+
* interf method ls # list methods (instance-wide)
|
|
5
|
+
* interf method install <path> # install a method package
|
|
6
|
+
* interf method draft <prep-id> # start a method-authoring run
|
|
7
|
+
* interf method improve <prep-id> # start a method-improvement run
|
|
8
|
+
*/
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
import { resolve } from "node:path";
|
|
11
|
+
import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/local-service/connection-config.js";
|
|
12
|
+
function resolveConnection(args) {
|
|
13
|
+
const conn = readActiveConnection({
|
|
14
|
+
urlOverride: args.url,
|
|
15
|
+
authTokenOverride: args.token,
|
|
16
|
+
});
|
|
17
|
+
if (!conn) {
|
|
18
|
+
console.error(CONNECT_OR_ERROR_HINT);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
|
|
22
|
+
}
|
|
23
|
+
async function callJson(url, token, init = {}) {
|
|
24
|
+
const headers = new Headers(init.headers ?? {});
|
|
25
|
+
if (token)
|
|
26
|
+
headers.set("authorization", `Bearer ${token}`);
|
|
27
|
+
if (init.body && !headers.has("content-type"))
|
|
28
|
+
headers.set("content-type", "application/json");
|
|
29
|
+
const response = await fetch(url, { ...init, headers });
|
|
30
|
+
const raw = await response.text();
|
|
31
|
+
let body = null;
|
|
32
|
+
if (raw) {
|
|
33
|
+
try {
|
|
34
|
+
body = JSON.parse(raw);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
body = null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return { status: response.status, body, raw };
|
|
41
|
+
}
|
|
42
|
+
export const methodCommand = {
|
|
43
|
+
command: "method <subcommand>",
|
|
44
|
+
describe: "Manage methods on the connected instance",
|
|
45
|
+
builder: (yargs) => yargs
|
|
46
|
+
.option("url", { type: "string", describe: "Override the active connection URL" })
|
|
47
|
+
.option("token", { type: "string", describe: "Override the active bearer token" })
|
|
48
|
+
.command("ls", "List methods on the instance", (y) => y, async (args) => {
|
|
49
|
+
const { url, token } = resolveConnection(args);
|
|
50
|
+
const { status, body, raw } = await callJson(`${url}/v1/methods`, token);
|
|
51
|
+
if (status !== 200) {
|
|
52
|
+
console.error(chalk.red(`Failed to list methods (HTTP ${status}).`));
|
|
53
|
+
if (raw)
|
|
54
|
+
console.error(raw);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
const methods = body?.methods ?? [];
|
|
58
|
+
if (methods.length === 0) {
|
|
59
|
+
console.log(chalk.dim(" No methods on this instance."));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
console.log();
|
|
63
|
+
for (const m of methods) {
|
|
64
|
+
const id = m.method_id ?? m.id ?? "(?)";
|
|
65
|
+
const label = m.label ? ` ${chalk.dim(m.label)}` : "";
|
|
66
|
+
const kind = m.source_kind ? chalk.dim(`[${m.source_kind}]`) : "";
|
|
67
|
+
console.log(` ${chalk.bold(id)} ${kind}${label}`);
|
|
68
|
+
if (m.active_for_preparations?.length) {
|
|
69
|
+
console.log(chalk.dim(` used by: ${m.active_for_preparations.join(", ")}`));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
console.log();
|
|
73
|
+
})
|
|
74
|
+
.command("install <path>", "Install a method package from a local folder", (y) => y.positional("path", { type: "string", demandOption: true, describe: "Path to the method package" }), async (args) => {
|
|
75
|
+
const { url, token } = resolveConnection(args);
|
|
76
|
+
const absolute = resolve(process.cwd(), args.path);
|
|
77
|
+
const { status, raw } = await callJson(`${url}/v1/methods`, token, { method: "POST", body: JSON.stringify({ source_path: absolute }) });
|
|
78
|
+
if (status !== 201 && status !== 200) {
|
|
79
|
+
console.error(chalk.red(`Failed to install method (HTTP ${status}).`));
|
|
80
|
+
if (raw)
|
|
81
|
+
console.error(raw);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
console.log(chalk.green(`Installed method from ${absolute}.`));
|
|
85
|
+
})
|
|
86
|
+
.command("draft <prep-id>", "Start a method-authoring run for a preparation", (y) => y.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" }), async (args) => {
|
|
87
|
+
const { url, token } = resolveConnection(args);
|
|
88
|
+
const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/method-authoring-runs`, token, { method: "POST", body: JSON.stringify({}) });
|
|
89
|
+
if (status !== 201 && status !== 200) {
|
|
90
|
+
console.error(chalk.red(`Failed to start method-authoring run (HTTP ${status}).`));
|
|
91
|
+
if (raw)
|
|
92
|
+
console.error(raw);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
console.log(chalk.green(`Method-authoring run ${chalk.bold(body?.run_id ?? "(?)")} started.`));
|
|
96
|
+
})
|
|
97
|
+
.command("improve <prep-id>", "Start a method-improvement run for a preparation", (y) => y.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" }), async (args) => {
|
|
98
|
+
const { url, token } = resolveConnection(args);
|
|
99
|
+
const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/method-improvement-runs`, token, { method: "POST", body: JSON.stringify({}) });
|
|
100
|
+
if (status !== 201 && status !== 200) {
|
|
101
|
+
console.error(chalk.red(`Failed to start method-improvement run (HTTP ${status}).`));
|
|
102
|
+
if (raw)
|
|
103
|
+
console.error(raw);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
console.log(chalk.green(`Method-improvement run ${chalk.bold(body?.run_id ?? "(?)")} started.`));
|
|
107
|
+
})
|
|
108
|
+
.demandCommand(1)
|
|
109
|
+
.strict(),
|
|
110
|
+
handler: () => {
|
|
111
|
+
/* yargs subcommand handlers do the work */
|
|
112
|
+
},
|
|
113
|
+
};
|