@interf/compiler 0.16.0 → 0.21.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/LICENSE.md +1 -0
- package/README.md +90 -73
- package/TRADEMARKS.md +4 -4
- package/dist/cli/commands/mcp.d.ts +0 -34
- package/dist/cli/commands/mcp.js +246 -45
- package/dist/cli/commands/method.js +261 -15
- package/dist/cli/commands/prep.js +116 -15
- package/dist/cli/commands/runs.js +103 -9
- package/dist/cli/commands/status.js +4 -2
- package/dist/cli/commands/test.d.ts +10 -0
- package/dist/cli/commands/{verify.js → test.js} +24 -17
- package/dist/cli/commands/web.js +82 -8
- package/dist/cli/commands/wizard.js +158 -51
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +3 -3
- package/dist/compiler-ui/404.html +1 -1
- package/dist/compiler-ui/__next.__PAGE__.txt +5 -5
- package/dist/compiler-ui/__next._full.txt +13 -12
- package/dist/compiler-ui/__next._head.txt +3 -3
- package/dist/compiler-ui/__next._index.txt +5 -4
- package/dist/compiler-ui/__next._tree.txt +4 -3
- package/dist/compiler-ui/_next/static/chunks/01646j7yi.w5a.css +1 -0
- package/dist/compiler-ui/_next/static/chunks/{0n51hrfoufc7g.js → 02f_.8.ebn556.js} +1 -1
- package/dist/compiler-ui/_next/static/chunks/02r7siaw-_p5w.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/{08m7vf5asqlsm.js → 04d0ly-7xb~-j.js} +10 -10
- package/dist/compiler-ui/_next/static/chunks/0fhs9psnxqd8s.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/0mssmhpbifj15.css +2 -0
- package/dist/compiler-ui/_next/static/chunks/0nypu~ddwxari.js +116 -0
- package/dist/compiler-ui/_next/static/chunks/0p3s8iyhgcww2.js +31 -0
- package/dist/compiler-ui/_next/static/chunks/0tjf-vu_rz8s0.css +1 -0
- package/dist/compiler-ui/_next/static/chunks/0u6p3fpbbfgtl.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/0wpx5..8dnh0w.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/0y0uj160p0ts~.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/10t8l~_oenf.c.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/13gz9e7z~imx1.js +5 -0
- package/dist/compiler-ui/_next/static/chunks/156xed-b6czaw.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/{turbopack-0.uq1k8c0j4s..js → turbopack-02-3e_c-yz~5g.js} +1 -1
- package/dist/compiler-ui/_next/static/chunks/{turbopack-10e~t1yzi4svj.js → turbopack-0apv8vb-nczuy.js} +1 -1
- package/dist/compiler-ui/_not-found/__next._full.txt +10 -9
- package/dist/compiler-ui/_not-found/__next._head.txt +3 -3
- package/dist/compiler-ui/_not-found/__next._index.txt +5 -4
- package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._not-found.txt +3 -3
- package/dist/compiler-ui/_not-found/__next._tree.txt +3 -2
- package/dist/compiler-ui/_not-found.html +1 -1
- package/dist/compiler-ui/_not-found.txt +10 -9
- package/dist/compiler-ui/index.html +1 -1
- package/dist/compiler-ui/index.txt +13 -12
- package/dist/packages/contracts/index.d.ts +2 -2
- package/dist/packages/contracts/index.js +1 -1
- package/dist/packages/contracts/lib/schema.d.ts +275 -72
- package/dist/packages/contracts/lib/schema.js +244 -83
- package/dist/packages/engine/action-definitions.d.ts +174 -13
- package/dist/packages/engine/action-definitions.js +125 -122
- package/dist/packages/engine/action-planner.js +4 -11
- package/dist/packages/engine/agents/lib/shells.d.ts +15 -5
- package/dist/packages/engine/agents/lib/shells.js +134 -123
- package/dist/packages/engine/agents/role-executors.js +1 -1
- package/dist/packages/engine/cloud-seams.d.ts +115 -0
- package/dist/packages/engine/cloud-seams.js +84 -0
- package/dist/packages/engine/compile/artifact-counts.d.ts +1 -1
- package/dist/packages/engine/compile/artifact-counts.js +3 -3
- package/dist/packages/engine/compile/artifact-status.d.ts +41 -0
- package/dist/packages/engine/compile/artifact-status.js +166 -0
- package/dist/packages/engine/compile/billing-events.d.ts +89 -0
- package/dist/packages/engine/compile/billing-events.js +74 -0
- package/dist/packages/engine/compile/check-evaluator.d.ts +66 -0
- package/dist/packages/engine/compile/check-evaluator.js +298 -0
- package/dist/packages/engine/compile/compiled-paths.js +6 -6
- package/dist/packages/engine/compile/compiled-schema.d.ts +7 -17
- package/dist/packages/engine/compile/compiled-schema.js +55 -70
- package/dist/packages/engine/compile/compiled-stage-plan.d.ts +1 -0
- package/dist/packages/engine/compile/compiled-stage-plan.js +32 -15
- package/dist/packages/engine/compile/compiled-stage-runner.js +1 -1
- package/dist/packages/engine/compile/index.d.ts +0 -1
- package/dist/packages/engine/compile/index.js +0 -1
- package/dist/packages/engine/compile/lib/schema.d.ts +111 -92
- package/dist/packages/engine/compile/lib/schema.js +35 -39
- package/dist/packages/engine/compile/method-primitives.d.ts +2 -2
- package/dist/packages/engine/compile/method-primitives.js +1 -1
- package/dist/packages/engine/compile/reset.js +4 -4
- package/dist/packages/engine/compile/runtime-contracts.js +2 -1
- package/dist/packages/engine/compile/runtime-prompt.js +3 -2
- package/dist/packages/engine/compile/runtime-reconcile.js +35 -35
- package/dist/packages/engine/compile/runtime-runs.js +0 -1
- package/dist/packages/engine/compile/runtime-types.d.ts +7 -8
- package/dist/packages/engine/compile/runtime.d.ts +1 -2
- package/dist/packages/engine/compile/runtime.js +0 -1
- package/dist/packages/engine/compile/state-health.js +6 -6
- package/dist/packages/engine/compile/state-view.js +7 -6
- package/dist/packages/engine/compile/validate-compiled.js +61 -30
- package/dist/packages/engine/compile/validate.js +26 -24
- package/dist/packages/engine/connection-config.js +1 -1
- package/dist/packages/engine/execution/lib/schema.d.ts +89 -33
- package/dist/packages/engine/execution/lib/schema.js +13 -5
- package/dist/packages/engine/index.d.ts +2 -2
- package/dist/packages/engine/index.js +1 -1
- package/dist/packages/engine/instance-paths.d.ts +15 -9
- package/dist/packages/engine/instance-paths.js +15 -9
- package/dist/packages/engine/lib/schema.d.ts +1316 -351
- package/dist/packages/engine/lib/schema.js +99 -36
- package/dist/packages/engine/native-run-handlers.js +25 -15
- package/dist/packages/engine/preparation-store.d.ts +9 -7
- package/dist/packages/engine/preparation-store.js +20 -0
- package/dist/packages/engine/requested-artifacts.d.ts +5 -0
- package/dist/packages/engine/requested-artifacts.js +36 -0
- package/dist/packages/engine/routes.d.ts +7 -1
- package/dist/packages/engine/routes.js +7 -1
- package/dist/packages/engine/run-observability.js +4 -4
- package/dist/packages/engine/runtime-event-applier.js +7 -0
- package/dist/packages/engine/runtime-proposal-helpers.d.ts +2 -2
- package/dist/packages/engine/runtime-proposal-helpers.js +6 -8
- package/dist/packages/engine/runtime-resource-builders.d.ts +11 -6
- package/dist/packages/engine/runtime-resource-builders.js +18 -6
- package/dist/packages/engine/runtime.d.ts +70 -8
- package/dist/packages/engine/runtime.js +304 -49
- package/dist/packages/engine/server.d.ts +25 -0
- package/dist/packages/engine/server.js +161 -50
- package/dist/packages/engine/verify/index.d.ts +10 -10
- package/dist/packages/engine/verify/index.js +8 -8
- package/dist/packages/engine/verify/readiness-check-run.d.ts +27 -4
- package/dist/packages/engine/verify/readiness-check-run.js +92 -24
- package/dist/packages/engine/verify/{test-execution.d.ts → verify-execution.d.ts} +2 -2
- package/dist/packages/engine/verify/{test-execution.js → verify-execution.js} +3 -3
- package/dist/packages/engine/verify/{test-paths.d.ts → verify-paths.d.ts} +1 -1
- package/dist/packages/engine/verify/{test-sandbox.d.ts → verify-sandbox.d.ts} +1 -1
- package/dist/packages/engine/verify/{test-specs.d.ts → verify-specs.d.ts} +1 -1
- package/dist/packages/engine/verify/{test-specs.js → verify-specs.js} +1 -1
- package/dist/packages/engine/verify/{test-targets.d.ts → verify-targets.d.ts} +1 -1
- package/dist/packages/engine/verify/{test.d.ts → verify.d.ts} +4 -4
- package/dist/packages/engine/verify/{test.js → verify.js} +3 -3
- package/dist/packages/engine/wire-schemas.d.ts +549 -0
- package/dist/packages/engine/wire-schemas.js +59 -0
- package/dist/packages/methods/authoring/method-authoring.d.ts +5 -1
- package/dist/packages/methods/authoring/method-authoring.js +68 -18
- package/dist/packages/methods/authoring/method-edit-session.js +5 -5
- package/dist/packages/methods/authoring/method-improvement.js +1 -1
- package/dist/packages/methods/package/builtin-compiled-method.d.ts +12 -12
- package/dist/packages/methods/package/builtin-compiled-method.js +26 -23
- package/dist/packages/methods/package/context-interface.d.ts +39 -26
- package/dist/packages/methods/package/context-interface.js +48 -39
- package/dist/packages/methods/package/interf-method-package.js +28 -47
- package/dist/packages/methods/package/local-methods.d.ts +4 -4
- package/dist/packages/methods/package/local-methods.js +53 -66
- package/dist/packages/methods/package/method-definitions.d.ts +4 -6
- package/dist/packages/methods/package/method-definitions.js +1 -5
- package/dist/packages/methods/package/method-helpers.d.ts +0 -2
- package/dist/packages/methods/package/method-helpers.js +0 -4
- package/dist/packages/project/interf-detect.js +6 -6
- package/dist/packages/project/interf-scaffold.js +12 -12
- package/dist/packages/project/lib/schema.d.ts +193 -0
- package/dist/packages/project/lib/schema.js +46 -1
- package/dist/packages/project/source-config.js +6 -1
- package/dist/packages/project/source-folders.js +1 -1
- package/package.json +12 -23
- package/public-repo/CONTRIBUTING.md +47 -0
- package/public-repo/LICENSE.md +1 -0
- package/public-repo/README.md +325 -0
- package/public-repo/SECURITY.md +67 -0
- package/public-repo/TRADEMARKS.md +8 -0
- package/{builtin-methods → public-repo/methods}/interf-default/README.md +10 -7
- package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/shape/SKILL.md +4 -8
- package/{builtin-methods → public-repo/methods}/interf-default/method.json +8 -69
- package/public-repo/methods/interf-default/method.schema.json +75 -0
- package/public-repo/methods/interf-default/use/query/SKILL.md +23 -0
- package/public-repo/plugins/README.md +9 -0
- package/public-repo/plugins/interf/.claude-plugin/plugin.json +21 -0
- package/public-repo/plugins/interf/.mcp.json +12 -0
- package/public-repo/plugins/interf/README.md +29 -0
- package/public-repo/plugins/interf/skills/interf/SKILL.md +477 -0
- package/public-repo/skills/interf/SKILL.md +477 -0
- package/agent-skills/interf-actions/SKILL.md +0 -185
- package/agent-skills/interf-actions/references/cli.md +0 -243
- package/builtin-methods/interf-default/method.schema.json +0 -73
- package/builtin-methods/interf-default/use/query/SKILL.md +0 -28
- package/dist/cli/commands/verify.d.ts +0 -8
- package/dist/compiler-ui/_next/static/chunks/06yhdspx~ca5-.js +0 -5
- package/dist/compiler-ui/_next/static/chunks/06z~l3kwb891e.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/08g7lvje.te.u.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0_i-3_5l9t2qe.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0b-ywny_j0g~0.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0b52v41o1gixx.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0gpzgsv0w.q~m.js +0 -31
- package/dist/compiler-ui/_next/static/chunks/0ilwfezfvu6~-.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0jipmpez3_ehh.js +0 -89
- package/dist/compiler-ui/_next/static/chunks/0xxmf45eskdt~.css +0 -1
- package/dist/compiler-ui/_next/static/chunks/13awzu4tooflw.css +0 -3
- package/dist/compiler-ui/_next/static/chunks/14wtz~vq25~qq.js +0 -1
- package/dist/packages/engine/compile/runtime-acceptance.d.ts +0 -9
- package/dist/packages/engine/compile/runtime-acceptance.js +0 -265
- /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → tYHMLL9oKds1yDoNYgkPV}/_buildManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → tYHMLL9oKds1yDoNYgkPV}/_clientMiddlewareManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → tYHMLL9oKds1yDoNYgkPV}/_ssgManifest.js +0 -0
- /package/dist/packages/engine/verify/{test-paths.js → verify-paths.js} +0 -0
- /package/dist/packages/engine/verify/{test-profile-presets.d.ts → verify-profile-presets.d.ts} +0 -0
- /package/dist/packages/engine/verify/{test-profile-presets.js → verify-profile-presets.js} +0 -0
- /package/dist/packages/engine/verify/{test-sandbox.js → verify-sandbox.js} +0 -0
- /package/dist/packages/engine/verify/{test-targets.js → verify-targets.js} +0 -0
- /package/dist/packages/engine/verify/{test-types.d.ts → verify-types.d.ts} +0 -0
- /package/dist/packages/engine/verify/{test-types.js → verify-types.js} +0 -0
- /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/structure/SKILL.md +0 -0
- /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/summarize/SKILL.md +0 -0
- /package/{builtin-methods → public-repo/methods}/interf-default/improve/SKILL.md +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* `interf method` — manage methods on the connected instance.
|
|
3
3
|
*
|
|
4
4
|
* interf method ls # list methods (instance-wide)
|
|
5
|
+
* interf method show <method-id> # show a Build Plan summary
|
|
5
6
|
* interf method install <path> # install a method package
|
|
6
7
|
* interf method draft <prep-id> # start a method-authoring run
|
|
7
8
|
* interf method improve <prep-id> # start a method-improvement run
|
|
@@ -9,6 +10,10 @@
|
|
|
9
10
|
import chalk from "chalk";
|
|
10
11
|
import { resolve } from "node:path";
|
|
11
12
|
import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/engine/connection-config.js";
|
|
13
|
+
import { methodResourcePath, preparationResourcePath, preparationSubresourcePath, } from "../../packages/engine/routes.js";
|
|
14
|
+
import { MethodAuthoringArtifactRequirementSchema, } from "../../packages/engine/lib/schema.js";
|
|
15
|
+
import { artifactRequirementsFromRequestedArtifacts, formatRequestedArtifactsForPrompt, } from "../../packages/engine/requested-artifacts.js";
|
|
16
|
+
import { slugify } from "../../packages/contracts/utils/naming.js";
|
|
12
17
|
function resolveConnection(args) {
|
|
13
18
|
const conn = readActiveConnection({
|
|
14
19
|
urlOverride: args.url,
|
|
@@ -39,6 +44,220 @@ async function callJson(url, token, init = {}) {
|
|
|
39
44
|
}
|
|
40
45
|
return { status: response.status, body, raw };
|
|
41
46
|
}
|
|
47
|
+
function asArray(value) {
|
|
48
|
+
return Array.isArray(value) ? value : [];
|
|
49
|
+
}
|
|
50
|
+
const MethodAuthoringArtifactRequirementsCliSchema = MethodAuthoringArtifactRequirementSchema.array();
|
|
51
|
+
function parseJsonOption(label, value, parse) {
|
|
52
|
+
if (!value)
|
|
53
|
+
return undefined;
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(value);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(chalk.red(`Invalid JSON for ${label}.`));
|
|
60
|
+
console.error(chalk.dim(error instanceof Error ? error.message : String(error)));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
return parse(parsed);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(chalk.red(`Invalid ${label}.`));
|
|
68
|
+
console.error(chalk.dim(error instanceof Error ? error.message : String(error)));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function buildPreparationReviewUrl(url, prepId) {
|
|
73
|
+
return `${url}/?section=preparations&preparation=${encodeURIComponent(prepId)}&preparationTab=build-plan`;
|
|
74
|
+
}
|
|
75
|
+
function buildRunUrl(url, prepId, runId) {
|
|
76
|
+
if (!runId)
|
|
77
|
+
return null;
|
|
78
|
+
return `${url}/?section=preparations&preparation=${encodeURIComponent(prepId)}&preparationTab=runs&run=${encodeURIComponent(runId)}`;
|
|
79
|
+
}
|
|
80
|
+
function defaultMethodIdForPreparation(prepId) {
|
|
81
|
+
return slugify(`${prepId}-build-plan`) || "build-plan";
|
|
82
|
+
}
|
|
83
|
+
function labelFromMethodId(methodId) {
|
|
84
|
+
const label = methodId
|
|
85
|
+
.split("-")
|
|
86
|
+
.filter(Boolean)
|
|
87
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
88
|
+
.join(" ");
|
|
89
|
+
return label || "Build Plan";
|
|
90
|
+
}
|
|
91
|
+
function renderMethodSummary(method) {
|
|
92
|
+
const id = method.method_id ?? method.id ?? "(?)";
|
|
93
|
+
console.log();
|
|
94
|
+
console.log(` ${chalk.bold(method.label ?? id)}`);
|
|
95
|
+
console.log(chalk.dim(` id: ${id}`));
|
|
96
|
+
if (method.hint)
|
|
97
|
+
console.log(chalk.dim(` hint: ${method.hint}`));
|
|
98
|
+
if (method.purpose?.task_hint)
|
|
99
|
+
console.log(chalk.dim(` purpose: ${method.purpose.task_hint}`));
|
|
100
|
+
if (method.source_kind)
|
|
101
|
+
console.log(chalk.dim(` source: ${method.source_kind}`));
|
|
102
|
+
const artifacts = method.artifacts ?? [];
|
|
103
|
+
if (artifacts.length > 0) {
|
|
104
|
+
console.log();
|
|
105
|
+
console.log(chalk.bold(" Artifacts"));
|
|
106
|
+
for (const artifact of artifacts) {
|
|
107
|
+
const shape = artifact.shape?.path
|
|
108
|
+
? chalk.dim(` -> ${artifact.shape.path}`)
|
|
109
|
+
: "";
|
|
110
|
+
console.log(` ${chalk.bold(artifact.id)}${shape}`);
|
|
111
|
+
console.log(chalk.dim(` ${artifact.description}`));
|
|
112
|
+
const checks = artifact.checks ?? [];
|
|
113
|
+
for (const check of checks.slice(0, 3)) {
|
|
114
|
+
const required = check.required === false ? "soft" : "required";
|
|
115
|
+
console.log(chalk.dim(` - ${check.description ?? check.kind} (${required})`));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const stages = method.stages ?? [];
|
|
120
|
+
if (stages.length > 0) {
|
|
121
|
+
console.log();
|
|
122
|
+
console.log(chalk.bold(" Stages"));
|
|
123
|
+
for (const stage of stages) {
|
|
124
|
+
const role = stage.role ? chalk.dim(` [${stage.role}]`) : "";
|
|
125
|
+
console.log(` ${chalk.bold(stage.label)}${role}`);
|
|
126
|
+
if (stage.description)
|
|
127
|
+
console.log(chalk.dim(` ${stage.description}`));
|
|
128
|
+
const reads = stage.reads?.length ? stage.reads.join(", ") : "source";
|
|
129
|
+
const writes = stage.writes?.length ? stage.writes.join(", ") : "(none declared)";
|
|
130
|
+
console.log(chalk.dim(` reads: ${reads}`));
|
|
131
|
+
console.log(chalk.dim(` writes: ${writes}`));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (method.active_for_preparations?.length) {
|
|
135
|
+
console.log();
|
|
136
|
+
console.log(chalk.dim(` used by: ${method.active_for_preparations.join(", ")}`));
|
|
137
|
+
}
|
|
138
|
+
console.log();
|
|
139
|
+
console.log(chalk.dim(" Run with --json for the raw Build Plan record."));
|
|
140
|
+
console.log();
|
|
141
|
+
}
|
|
142
|
+
function preparationChecks(preparation) {
|
|
143
|
+
return asArray(preparation.checks).length
|
|
144
|
+
? asArray(preparation.checks)
|
|
145
|
+
: asArray(preparation.preparation?.checks);
|
|
146
|
+
}
|
|
147
|
+
function preparationRequestedArtifacts(preparation) {
|
|
148
|
+
return preparation.requested_artifacts?.length
|
|
149
|
+
? preparation.requested_artifacts
|
|
150
|
+
: preparation.preparation?.requested_artifacts ?? [];
|
|
151
|
+
}
|
|
152
|
+
function preparationSourceProfile(preparation) {
|
|
153
|
+
return preparation.source_profile ?? preparation.preparation?.source_profile ?? null;
|
|
154
|
+
}
|
|
155
|
+
function selectedMethodId(preparation) {
|
|
156
|
+
return preparation.method_id ?? preparation.preparation?.method ?? null;
|
|
157
|
+
}
|
|
158
|
+
function sourceFolderPathFromPreparation(preparation, sourceFiles) {
|
|
159
|
+
if (preparation.source?.kind === "local-folder" && preparation.source.locator)
|
|
160
|
+
return preparation.source.locator;
|
|
161
|
+
if (sourceFiles?.source_files?.[0]?.source_folder_path)
|
|
162
|
+
return sourceFiles.source_files[0].source_folder_path;
|
|
163
|
+
return preparation.source_path ?? null;
|
|
164
|
+
}
|
|
165
|
+
function buildTaskPrompt(args, preparation, prepId, mode) {
|
|
166
|
+
const about = (preparation.about ?? preparation.preparation?.about)?.trim();
|
|
167
|
+
const requestedArtifacts = formatRequestedArtifactsForPrompt(preparationRequestedArtifacts(preparation));
|
|
168
|
+
const sections = [
|
|
169
|
+
`${mode === "improve" ? "Improve" : "Draft"} a Build Plan for Preparation "${prepId}".`,
|
|
170
|
+
args.task?.trim() ? `Agent job:\n${args.task.trim()}` : null,
|
|
171
|
+
about ? `Preparation context:\n${about}` : null,
|
|
172
|
+
requestedArtifacts ? `Requested Artifacts saved on the Preparation:\n${requestedArtifacts}` : null,
|
|
173
|
+
args.artifacts?.trim() ? `Additional Artifact notes:\n${args.artifacts.trim()}` : null,
|
|
174
|
+
args.readyWhen?.trim() ? `Ready when:\n${args.readyWhen.trim()}` : null,
|
|
175
|
+
"Return a Method package that declares the verifiable Artifacts, the stages that build them, and the checks that prove the portable context is ready for agent work.",
|
|
176
|
+
].filter((section) => Boolean(section));
|
|
177
|
+
return sections.join("\n\n");
|
|
178
|
+
}
|
|
179
|
+
async function readPreparationContext(url, token, prepId) {
|
|
180
|
+
const fetched = await callJson(`${url}${preparationResourcePath(prepId)}`, token);
|
|
181
|
+
if (fetched.status !== 200 || !fetched.body) {
|
|
182
|
+
console.error(chalk.red(`Failed to read Preparation ${prepId} (HTTP ${fetched.status}).`));
|
|
183
|
+
if (fetched.raw)
|
|
184
|
+
console.error(fetched.raw);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
let sourceFiles = null;
|
|
188
|
+
const sourcePath = sourceFolderPathFromPreparation(fetched.body, sourceFiles);
|
|
189
|
+
if (!sourcePath) {
|
|
190
|
+
const listed = await callJson(`${url}${preparationSubresourcePath(prepId, "sourceFiles")}`, token);
|
|
191
|
+
if (listed.status === 200)
|
|
192
|
+
sourceFiles = listed.body;
|
|
193
|
+
}
|
|
194
|
+
const sourceFolderPath = sourceFolderPathFromPreparation(fetched.body, sourceFiles);
|
|
195
|
+
if (!sourceFolderPath) {
|
|
196
|
+
console.error(chalk.red(`Preparation ${prepId} has no readable local Source binding.`));
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
preparation: fetched.body,
|
|
201
|
+
sourceFolderPath,
|
|
202
|
+
checks: preparationChecks(fetched.body),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
async function startBuildPlanRun(args, mode) {
|
|
206
|
+
const { url, token } = resolveConnection(args);
|
|
207
|
+
const { preparation, sourceFolderPath, checks } = await readPreparationContext(url, token, args.prepId);
|
|
208
|
+
const existingMethod = selectedMethodId(preparation);
|
|
209
|
+
const methodId = args.method ?? (mode === "improve" ? existingMethod : defaultMethodIdForPreparation(args.prepId));
|
|
210
|
+
const requestedArtifacts = preparationRequestedArtifacts(preparation);
|
|
211
|
+
const explicitArtifactRequirements = parseJsonOption("--artifact-requirements-json", args.artifactRequirementsJson, (input) => MethodAuthoringArtifactRequirementsCliSchema.parse(input));
|
|
212
|
+
const artifactRequirements = explicitArtifactRequirements
|
|
213
|
+
?? artifactRequirementsFromRequestedArtifacts(requestedArtifacts);
|
|
214
|
+
if (!methodId) {
|
|
215
|
+
console.error(chalk.red(`Preparation ${args.prepId} has no selected Build Plan to improve.`));
|
|
216
|
+
console.error(chalk.dim(`Draft one first: interf method draft ${args.prepId} --task "..."`));
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
const body = {
|
|
220
|
+
preparation: args.prepId,
|
|
221
|
+
source_folder_path: sourceFolderPath,
|
|
222
|
+
...(args.baseMethod ? { base_method_id: args.baseMethod } : {}),
|
|
223
|
+
...(args.referenceMethod ? { reference_method_id: args.referenceMethod } : {}),
|
|
224
|
+
...(mode === "improve" && !args.referenceMethod && existingMethod ? { reference_method_id: existingMethod } : {}),
|
|
225
|
+
method_id: methodId,
|
|
226
|
+
label: args.label ?? labelFromMethodId(methodId),
|
|
227
|
+
hint: args.hint ?? `Build Plan for Preparation ${args.prepId}.`,
|
|
228
|
+
task_prompt: buildTaskPrompt(args, preparation, args.prepId, mode),
|
|
229
|
+
checks,
|
|
230
|
+
requested_artifacts: requestedArtifacts,
|
|
231
|
+
source_profile: preparationSourceProfile(preparation),
|
|
232
|
+
artifact_requirements: artifactRequirements,
|
|
233
|
+
};
|
|
234
|
+
const endpoint = mode === "improve" ? "methodImprovementRuns" : "methodAuthoringRuns";
|
|
235
|
+
const { status, body: run, raw } = await callJson(`${url}${preparationSubresourcePath(args.prepId, endpoint)}`, token, { method: "POST", body: JSON.stringify(body) });
|
|
236
|
+
if (status !== 202 && status !== 201 && status !== 200) {
|
|
237
|
+
console.error(chalk.red(`Failed to start Build Plan ${mode} run (HTTP ${status}).`));
|
|
238
|
+
if (raw)
|
|
239
|
+
console.error(raw);
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
const runUrl = buildRunUrl(url, args.prepId, run?.run_id);
|
|
243
|
+
const reviewUrl = buildPreparationReviewUrl(url, args.prepId);
|
|
244
|
+
if (args.json) {
|
|
245
|
+
console.log(JSON.stringify({
|
|
246
|
+
run_id: run?.run_id ?? null,
|
|
247
|
+
status: run?.status ?? null,
|
|
248
|
+
preparation: args.prepId,
|
|
249
|
+
method_id: methodId,
|
|
250
|
+
run_url: runUrl,
|
|
251
|
+
review_url: reviewUrl,
|
|
252
|
+
}, null, 2));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
console.log(chalk.green(`Build Plan ${mode} run ${chalk.bold(run?.run_id ?? "(?)")} started.`));
|
|
256
|
+
console.log(chalk.dim(` Build Plan: ${methodId}`));
|
|
257
|
+
if (runUrl)
|
|
258
|
+
console.log(chalk.dim(` watch: ${runUrl}`));
|
|
259
|
+
console.log(chalk.dim(` review after it finishes: ${reviewUrl}`));
|
|
260
|
+
}
|
|
42
261
|
export const methodCommand = {
|
|
43
262
|
command: "method <subcommand>",
|
|
44
263
|
describe: "Manage methods on the connected instance",
|
|
@@ -83,27 +302,54 @@ export const methodCommand = {
|
|
|
83
302
|
}
|
|
84
303
|
console.log(chalk.green(`Installed method from ${absolute}.`));
|
|
85
304
|
})
|
|
86
|
-
.command("
|
|
305
|
+
.command("show <method-id>", "Show a Build Plan / Method package", (y) => y
|
|
306
|
+
.positional("method-id", { type: "string", demandOption: true, describe: "Build Plan / Method package id" })
|
|
307
|
+
.option("json", {
|
|
308
|
+
type: "boolean",
|
|
309
|
+
default: false,
|
|
310
|
+
describe: "Print the raw JSON record instead of the formatted summary",
|
|
311
|
+
}), async (args) => {
|
|
87
312
|
const { url, token } = resolveConnection(args);
|
|
88
|
-
const { status, body, raw } = await callJson(`${url}
|
|
89
|
-
if (status !==
|
|
90
|
-
console.error(chalk.red(`Failed to
|
|
313
|
+
const { status, body, raw } = await callJson(`${url}${methodResourcePath(args.methodId)}`, token);
|
|
314
|
+
if (status !== 200 || !body) {
|
|
315
|
+
console.error(chalk.red(`Failed to read Build Plan ${args.methodId} (HTTP ${status}).`));
|
|
91
316
|
if (raw)
|
|
92
317
|
console.error(raw);
|
|
93
318
|
process.exit(1);
|
|
94
319
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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);
|
|
320
|
+
if (args.json) {
|
|
321
|
+
console.log(JSON.stringify(body, null, 2));
|
|
322
|
+
return;
|
|
105
323
|
}
|
|
106
|
-
|
|
324
|
+
renderMethodSummary(body);
|
|
325
|
+
})
|
|
326
|
+
.command("draft <prep-id>", "Start a Build Plan draft run for a preparation", (y) => y
|
|
327
|
+
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
328
|
+
.option("task", { type: "string", describe: "Agent job this Build Plan should support" })
|
|
329
|
+
.option("artifacts", { type: "string", describe: "Requested Artifacts and why the agent needs them" })
|
|
330
|
+
.option("artifact-requirements-json", { type: "string", describe: "JSON array of exact Artifact output requirements for the Build Plan" })
|
|
331
|
+
.option("ready-when", { type: "string", describe: "Proof or readiness expectations for the Build Plan" })
|
|
332
|
+
.option("method", { type: "string", describe: "Build Plan / Method id to write" })
|
|
333
|
+
.option("label", { type: "string", describe: "Human-readable Build Plan label" })
|
|
334
|
+
.option("hint", { type: "string", describe: "Short Build Plan hint for reviewers" })
|
|
335
|
+
.option("base-method", { type: "string", describe: "Existing Method id to use as a starting point" })
|
|
336
|
+
.option("reference-method", { type: "string", describe: "Existing Method id to reference while drafting" })
|
|
337
|
+
.option("json", { type: "boolean", default: false, describe: "Print machine-readable run metadata" }), async (args) => {
|
|
338
|
+
await startBuildPlanRun(args, "draft");
|
|
339
|
+
})
|
|
340
|
+
.command("improve <prep-id>", "Start a Build Plan improvement run for a preparation", (y) => y
|
|
341
|
+
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
342
|
+
.option("task", { type: "string", describe: "Change request for the selected Build Plan" })
|
|
343
|
+
.option("artifacts", { type: "string", describe: "Requested Artifact changes and why they matter" })
|
|
344
|
+
.option("artifact-requirements-json", { type: "string", describe: "JSON array of exact Artifact output requirements for the Build Plan" })
|
|
345
|
+
.option("ready-when", { type: "string", describe: "Proof or readiness expectations to add or change" })
|
|
346
|
+
.option("method", { type: "string", describe: "Build Plan / Method id to update" })
|
|
347
|
+
.option("label", { type: "string", describe: "Human-readable Build Plan label" })
|
|
348
|
+
.option("hint", { type: "string", describe: "Short Build Plan hint for reviewers" })
|
|
349
|
+
.option("base-method", { type: "string", describe: "Existing Method id to use as a starting point" })
|
|
350
|
+
.option("reference-method", { type: "string", describe: "Existing Method id to reference while improving" })
|
|
351
|
+
.option("json", { type: "boolean", default: false, describe: "Print machine-readable run metadata" }), async (args) => {
|
|
352
|
+
await startBuildPlanRun(args, "improve");
|
|
107
353
|
})
|
|
108
354
|
.demandCommand(1)
|
|
109
355
|
.strict(),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `interf prep` — preparation CRUD against a connected instance.
|
|
3
3
|
*
|
|
4
4
|
* interf prep ls
|
|
5
|
-
* interf prep create <id> --source <path> --method <id> [--about <text>]
|
|
5
|
+
* interf prep create <id> --source <path> [--method <id>] [--about <text>]
|
|
6
6
|
* interf prep show <id>
|
|
7
7
|
* interf prep rm <id>
|
|
8
8
|
*
|
|
@@ -14,6 +14,8 @@ import { resolve } from "node:path";
|
|
|
14
14
|
import chalk from "chalk";
|
|
15
15
|
import { CONNECT_OR_ERROR_HINT, readActiveConnection, } from "../../packages/engine/connection-config.js";
|
|
16
16
|
import { preparationResourcePath } from "../../packages/engine/routes.js";
|
|
17
|
+
import { requestedArtifactCheckLabel } from "../../packages/engine/requested-artifacts.js";
|
|
18
|
+
import { RequestedArtifactSchema, SourceProfileSchema, } from "../../packages/project/lib/schema.js";
|
|
17
19
|
function requireConnection(args) {
|
|
18
20
|
const conn = readActiveConnection({
|
|
19
21
|
urlOverride: args.url,
|
|
@@ -45,6 +47,87 @@ async function callJson(url, token, init = {}) {
|
|
|
45
47
|
}
|
|
46
48
|
return { status: response.status, body, raw };
|
|
47
49
|
}
|
|
50
|
+
const RequestedArtifactsCliSchema = RequestedArtifactSchema.array();
|
|
51
|
+
function parseJsonOption(label, value, parse) {
|
|
52
|
+
if (!value)
|
|
53
|
+
return undefined;
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(value);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(chalk.red(`Invalid JSON for ${label}.`));
|
|
60
|
+
console.error(chalk.dim(error instanceof Error ? error.message : String(error)));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
return parse(parsed);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(chalk.red(`Invalid ${label}.`));
|
|
68
|
+
console.error(chalk.dim(error instanceof Error ? error.message : String(error)));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function statusColor(status) {
|
|
73
|
+
if (status === "ready")
|
|
74
|
+
return chalk.green;
|
|
75
|
+
if (status === "failed")
|
|
76
|
+
return chalk.red;
|
|
77
|
+
if (status === "skipped")
|
|
78
|
+
return chalk.dim;
|
|
79
|
+
return chalk.yellow;
|
|
80
|
+
}
|
|
81
|
+
function renderPreparationSummary(prep) {
|
|
82
|
+
console.log();
|
|
83
|
+
console.log(` ${chalk.bold(prep.name)}`);
|
|
84
|
+
console.log(chalk.dim(` Build Plan: ${prep.method_id ?? "(not selected)"}`));
|
|
85
|
+
if (prep.source_path)
|
|
86
|
+
console.log(chalk.dim(` source: ${prep.source_path}`));
|
|
87
|
+
if (prep.portable_context_path) {
|
|
88
|
+
console.log(chalk.dim(` output: ${prep.portable_context_path}`));
|
|
89
|
+
}
|
|
90
|
+
if (prep.readiness?.status) {
|
|
91
|
+
const aggColor = prep.readiness.ready ? chalk.green : chalk.yellow;
|
|
92
|
+
console.log(` readiness: ${aggColor(prep.readiness.status)}${prep.readiness.summary ? chalk.dim(` (${prep.readiness.summary})`) : ""}`);
|
|
93
|
+
}
|
|
94
|
+
if (prep.artifacts && prep.artifacts.length > 0) {
|
|
95
|
+
console.log();
|
|
96
|
+
console.log(chalk.bold(" Artifacts"));
|
|
97
|
+
const idWidth = Math.max(...prep.artifacts.map((entry) => entry.artifact_id.length), 8);
|
|
98
|
+
for (const artifact of prep.artifacts) {
|
|
99
|
+
const colored = statusColor(artifact.status)(artifact.status);
|
|
100
|
+
const stages = artifact.built_by_stages && artifact.built_by_stages.length > 0
|
|
101
|
+
? chalk.dim(` ← ${artifact.built_by_stages.join(", ")}`)
|
|
102
|
+
: "";
|
|
103
|
+
console.log(` ${artifact.artifact_id.padEnd(idWidth)} ${colored}${stages}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (prep.requested_artifacts && prep.requested_artifacts.length > 0) {
|
|
107
|
+
console.log();
|
|
108
|
+
console.log(chalk.bold(" Requested Artifacts"));
|
|
109
|
+
for (const artifact of prep.requested_artifacts) {
|
|
110
|
+
console.log(` ${chalk.bold(artifact.title)}`);
|
|
111
|
+
if (artifact.purpose ?? artifact.description) {
|
|
112
|
+
console.log(chalk.dim(` ${artifact.purpose ?? artifact.description}`));
|
|
113
|
+
}
|
|
114
|
+
const checks = artifact.checks ?? [];
|
|
115
|
+
for (const check of checks.slice(0, 4)) {
|
|
116
|
+
console.log(chalk.dim(` - ${requestedArtifactCheckLabel(check)}`));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (prep.latest_compile_run_id) {
|
|
121
|
+
console.log();
|
|
122
|
+
console.log(chalk.dim(` latest compile run: ${prep.latest_compile_run_id}`));
|
|
123
|
+
}
|
|
124
|
+
if (prep.latest_test_run_id) {
|
|
125
|
+
console.log(chalk.dim(` latest check run: ${prep.latest_test_run_id}`));
|
|
126
|
+
}
|
|
127
|
+
console.log();
|
|
128
|
+
console.log(chalk.dim(` Run with --json for the raw resource record.`));
|
|
129
|
+
console.log();
|
|
130
|
+
}
|
|
48
131
|
export const prepCommand = {
|
|
49
132
|
command: "prep <subcommand>",
|
|
50
133
|
describe: "Manage preparations on the connected instance",
|
|
@@ -62,7 +145,7 @@ export const prepCommand = {
|
|
|
62
145
|
}
|
|
63
146
|
const preparations = body.preparations ?? [];
|
|
64
147
|
if (preparations.length === 0) {
|
|
65
|
-
console.log(chalk.dim(" No preparations yet. Create one with `interf prep create <id> --source <path
|
|
148
|
+
console.log(chalk.dim(" No preparations yet. Create one with `interf prep create <id> --source <path>`."));
|
|
66
149
|
return;
|
|
67
150
|
}
|
|
68
151
|
console.log();
|
|
@@ -70,26 +153,34 @@ export const prepCommand = {
|
|
|
70
153
|
console.log();
|
|
71
154
|
for (const prep of preparations) {
|
|
72
155
|
const sourceLabel = prep.source?.locator ?? prep.source_path ?? "(no source)";
|
|
73
|
-
const method = prep.method_id ?? "(no
|
|
156
|
+
const method = prep.method_id ?? "(no Build Plan)";
|
|
74
157
|
const readiness = prep.readiness?.status ?? "—";
|
|
158
|
+
const requested = prep.requested_artifacts?.length ?? 0;
|
|
75
159
|
console.log(` ${prep.id}`);
|
|
76
160
|
console.log(chalk.dim(` source: ${sourceLabel}`));
|
|
77
|
-
console.log(chalk.dim(`
|
|
161
|
+
console.log(chalk.dim(` Build Plan: ${method}`));
|
|
162
|
+
console.log(chalk.dim(` requested Artifacts: ${requested}`));
|
|
78
163
|
console.log(chalk.dim(` readiness: ${readiness}`));
|
|
79
164
|
}
|
|
80
165
|
})
|
|
81
|
-
.command("create <prep-id>", "Create a
|
|
166
|
+
.command("create <prep-id>", "Create a Preparation (Build Plan optional — select or draft it later)", (y) => y
|
|
82
167
|
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id (lowercase, dash-separated)" })
|
|
83
|
-
.option("source", { type: "string", demandOption: true, describe: "Path to the Source
|
|
84
|
-
.option("method", { type: "string", describe: "Method id
|
|
85
|
-
.option("about", { type: "string", describe: "One-line description of the agent work" })
|
|
168
|
+
.option("source", { type: "string", demandOption: true, describe: "Path to the Source" })
|
|
169
|
+
.option("method", { type: "string", describe: "Build Plan / Method package id. Optional — bind later via `interf prep set-method`." })
|
|
170
|
+
.option("about", { type: "string", describe: "One-line description of the agent work" })
|
|
171
|
+
.option("requested-artifacts-json", { type: "string", describe: "JSON array of requested Artifacts for this Preparation" })
|
|
172
|
+
.option("source-profile-json", { type: "string", describe: "JSON object describing the agent's advisory source profile" }), async (args) => {
|
|
86
173
|
const { url, token } = requireConnection(args);
|
|
87
174
|
const sourceAbs = resolve(process.cwd(), args.source);
|
|
175
|
+
const requestedArtifacts = parseJsonOption("--requested-artifacts-json", args.requestedArtifactsJson, (input) => RequestedArtifactsCliSchema.parse(input));
|
|
176
|
+
const sourceProfile = parseJsonOption("--source-profile-json", args.sourceProfileJson, (input) => SourceProfileSchema.parse(input));
|
|
88
177
|
const requestBody = {
|
|
89
178
|
id: args.prepId,
|
|
90
179
|
source: { kind: "local-folder", locator: sourceAbs },
|
|
91
180
|
...(args.method ? { method_id: args.method } : {}),
|
|
92
181
|
about: args.about,
|
|
182
|
+
...(requestedArtifacts ? { requested_artifacts: requestedArtifacts } : {}),
|
|
183
|
+
...(sourceProfile ? { source_profile: sourceProfile } : {}),
|
|
93
184
|
checks: [],
|
|
94
185
|
};
|
|
95
186
|
const { status, body, raw } = await callJson(`${url}/v1/preparations`, token, { method: "POST", body: JSON.stringify(requestBody) });
|
|
@@ -101,17 +192,17 @@ export const prepCommand = {
|
|
|
101
192
|
}
|
|
102
193
|
console.log(chalk.green(`Created preparation ${chalk.bold(args.prepId)}.`));
|
|
103
194
|
if (!args.method) {
|
|
104
|
-
console.log(chalk.dim(` no
|
|
195
|
+
console.log(chalk.dim(` no Build Plan selected yet — pick or draft one before compiling:`));
|
|
105
196
|
console.log(chalk.dim(` interf prep set-method ${args.prepId} <method-id>`));
|
|
106
197
|
console.log(chalk.dim(` interf method draft ${args.prepId}`));
|
|
107
198
|
}
|
|
108
|
-
if (body?.portable_context?.value) {
|
|
199
|
+
if (body?.method_id && body?.portable_context?.value) {
|
|
109
200
|
console.log(chalk.dim(` portable context (locator): ${body.portable_context.value}`));
|
|
110
201
|
}
|
|
111
202
|
})
|
|
112
|
-
.command("set-method <prep-id> <method-id>", "
|
|
203
|
+
.command("set-method <prep-id> <method-id>", "Select a Build Plan / Method package for a Preparation", (y) => y
|
|
113
204
|
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
114
|
-
.positional("method-id", { type: "string", demandOption: true, describe: "Method id to
|
|
205
|
+
.positional("method-id", { type: "string", demandOption: true, describe: "Build Plan / Method package id to select" }), async (args) => {
|
|
115
206
|
const { url, token } = requireConnection(args);
|
|
116
207
|
const { status, raw } = await callJson(`${url}${preparationResourcePath(args.prepId)}`, token, { method: "PATCH", body: JSON.stringify({ method_id: args.methodId }) });
|
|
117
208
|
if (status !== 200) {
|
|
@@ -120,9 +211,15 @@ export const prepCommand = {
|
|
|
120
211
|
console.error(raw);
|
|
121
212
|
process.exit(1);
|
|
122
213
|
}
|
|
123
|
-
console.log(chalk.green(`
|
|
214
|
+
console.log(chalk.green(`Selected Build Plan ${chalk.bold(args.methodId)} for ${chalk.bold(args.prepId)}.`));
|
|
124
215
|
})
|
|
125
|
-
.command("show <prep-id>", "Show a preparation's full record", (y) => y
|
|
216
|
+
.command("show <prep-id>", "Show a preparation's full record", (y) => y
|
|
217
|
+
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
218
|
+
.option("json", {
|
|
219
|
+
type: "boolean",
|
|
220
|
+
default: false,
|
|
221
|
+
describe: "Print the raw JSON record instead of the formatted summary",
|
|
222
|
+
}), async (args) => {
|
|
126
223
|
const { url, token } = requireConnection(args);
|
|
127
224
|
const { status, body, raw } = await callJson(`${url}${preparationResourcePath(args.prepId)}`, token);
|
|
128
225
|
if (status !== 200) {
|
|
@@ -131,7 +228,11 @@ export const prepCommand = {
|
|
|
131
228
|
console.error(raw);
|
|
132
229
|
process.exit(1);
|
|
133
230
|
}
|
|
134
|
-
|
|
231
|
+
if (args.json || !body) {
|
|
232
|
+
console.log(JSON.stringify(body, null, 2));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
renderPreparationSummary(body);
|
|
135
236
|
})
|
|
136
237
|
.command("rm <prep-id>", "Delete a preparation", (y) => y.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" }), async (args) => {
|
|
137
238
|
const { url, token } = requireConnection(args);
|
|
@@ -40,6 +40,90 @@ async function callJson(url, token, init = {}) {
|
|
|
40
40
|
}
|
|
41
41
|
return { status: response.status, body, raw };
|
|
42
42
|
}
|
|
43
|
+
function runStatusColor(status) {
|
|
44
|
+
if (status === "succeeded" || status === "completed")
|
|
45
|
+
return chalk.green;
|
|
46
|
+
if (status === "failed" || status === "cancelled")
|
|
47
|
+
return chalk.red;
|
|
48
|
+
if (status === "running")
|
|
49
|
+
return chalk.yellow;
|
|
50
|
+
return chalk.dim;
|
|
51
|
+
}
|
|
52
|
+
function renderRunStatus(run) {
|
|
53
|
+
const status = run.status ?? (run.trace?.run?.error ? "failed" : "unknown");
|
|
54
|
+
const color = runStatusColor(status);
|
|
55
|
+
console.log();
|
|
56
|
+
console.log(` ${chalk.bold(run.title ?? run.run_id)} ${color(`(${status})`)}`);
|
|
57
|
+
console.log(chalk.dim(` run: ${run.run_id}`));
|
|
58
|
+
if (run.run_type)
|
|
59
|
+
console.log(chalk.dim(` type: ${run.run_type}`));
|
|
60
|
+
if (run.preparation)
|
|
61
|
+
console.log(chalk.dim(` preparation: ${run.preparation}`));
|
|
62
|
+
if (run.method)
|
|
63
|
+
console.log(chalk.dim(` Build Plan: ${run.method}`));
|
|
64
|
+
if (run.agent_label)
|
|
65
|
+
console.log(chalk.dim(` agent: ${run.agent_label}`));
|
|
66
|
+
if (run.started_at)
|
|
67
|
+
console.log(chalk.dim(` started: ${run.started_at}`));
|
|
68
|
+
if (run.finished_at)
|
|
69
|
+
console.log(chalk.dim(` finished: ${run.finished_at}`));
|
|
70
|
+
if (run.output_path ?? run.portable_context_path) {
|
|
71
|
+
console.log(chalk.dim(` output: ${run.output_path ?? run.portable_context_path}`));
|
|
72
|
+
}
|
|
73
|
+
if (run.trace?.run?.error?.message) {
|
|
74
|
+
console.log();
|
|
75
|
+
console.log(chalk.red(" Error"));
|
|
76
|
+
console.log(chalk.dim(` ${run.trace.run.error.message}`));
|
|
77
|
+
}
|
|
78
|
+
const readiness = run.readiness;
|
|
79
|
+
if (readiness?.status) {
|
|
80
|
+
console.log();
|
|
81
|
+
const readinessColor = readiness.ready ? chalk.green : chalk.yellow;
|
|
82
|
+
console.log(` readiness: ${readinessColor(readiness.status)}${readiness.summary ? chalk.dim(` (${readiness.summary})`) : ""}`);
|
|
83
|
+
}
|
|
84
|
+
const metrics = run.metrics ?? [];
|
|
85
|
+
if (metrics.length > 0) {
|
|
86
|
+
console.log();
|
|
87
|
+
console.log(chalk.bold(" Metrics"));
|
|
88
|
+
for (const metric of metrics.slice(0, 8)) {
|
|
89
|
+
const value = metric.value !== undefined ? `${metric.value}${metric.unit ? ` ${metric.unit}` : ""}` : "";
|
|
90
|
+
console.log(chalk.dim(` ${metric.label ?? "metric"}: ${value}`));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const artifacts = run.artifacts ?? [];
|
|
94
|
+
if (artifacts.length > 0) {
|
|
95
|
+
console.log();
|
|
96
|
+
console.log(chalk.bold(" Artifacts"));
|
|
97
|
+
for (const artifact of artifacts.slice(0, 12)) {
|
|
98
|
+
const stage = artifact.stage_id ? chalk.dim(` ← ${artifact.stage_id}`) : "";
|
|
99
|
+
console.log(` ${artifact.label ?? artifact.role}: ${chalk.dim(artifact.path)}${stage}`);
|
|
100
|
+
}
|
|
101
|
+
if (artifacts.length > 12)
|
|
102
|
+
console.log(chalk.dim(` ... ${artifacts.length - 12} more`));
|
|
103
|
+
}
|
|
104
|
+
const proof = run.proof ?? [];
|
|
105
|
+
if (proof.length > 0) {
|
|
106
|
+
console.log();
|
|
107
|
+
console.log(chalk.bold(" Proof"));
|
|
108
|
+
for (const check of proof.slice(0, 12)) {
|
|
109
|
+
const marker = check.ok ? chalk.green("pass") : chalk.red("fail");
|
|
110
|
+
console.log(` ${marker} ${check.label}${check.detail ? chalk.dim(` — ${check.detail}`) : ""}`);
|
|
111
|
+
}
|
|
112
|
+
if (proof.length > 12)
|
|
113
|
+
console.log(chalk.dim(` ... ${proof.length - 12} more`));
|
|
114
|
+
}
|
|
115
|
+
const events = run.trace?.events ?? [];
|
|
116
|
+
if (events.length > 0) {
|
|
117
|
+
console.log();
|
|
118
|
+
console.log(chalk.bold(" Recent trace"));
|
|
119
|
+
for (const event of events.slice(-6)) {
|
|
120
|
+
console.log(chalk.dim(` ${event.createdAt ?? ""} ${event.eventType ?? "event"}`.trim()));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
console.log();
|
|
124
|
+
console.log(chalk.dim(" Run with --json for the raw run resource."));
|
|
125
|
+
console.log();
|
|
126
|
+
}
|
|
43
127
|
export const runsCommand = {
|
|
44
128
|
command: "runs <subcommand>",
|
|
45
129
|
describe: "Inspect runs on the connected instance",
|
|
@@ -48,10 +132,7 @@ export const runsCommand = {
|
|
|
48
132
|
.option("token", { type: "string", describe: "Override the active bearer token" })
|
|
49
133
|
.command("ls", "List runs (optionally filtered by preparation)", (y) => y.option("prep", { type: "string", describe: "Filter by preparation id" }), async (args) => {
|
|
50
134
|
const { url, token } = resolveConnection(args);
|
|
51
|
-
const
|
|
52
|
-
? `/v1/preparations/${encodeURIComponent(args.prep)}/runs`
|
|
53
|
-
: "/v1/runs";
|
|
54
|
-
const { status, body, raw } = await callJson(`${url}${path}`, token);
|
|
135
|
+
const { status, body, raw } = await callJson(`${url}/v1/runs`, token);
|
|
55
136
|
if (status !== 200) {
|
|
56
137
|
console.error(chalk.red(`Failed to list runs (HTTP ${status}).`));
|
|
57
138
|
if (raw)
|
|
@@ -60,12 +141,15 @@ export const runsCommand = {
|
|
|
60
141
|
}
|
|
61
142
|
const runs = body?.runs
|
|
62
143
|
?? (body?.compile_runs ?? []).map((r) => r.run).filter(Boolean);
|
|
63
|
-
|
|
144
|
+
const visibleRuns = args.prep
|
|
145
|
+
? runs.filter((run) => run.preparation === args.prep)
|
|
146
|
+
: runs;
|
|
147
|
+
if (visibleRuns.length === 0) {
|
|
64
148
|
console.log(chalk.dim(" No runs."));
|
|
65
149
|
return;
|
|
66
150
|
}
|
|
67
151
|
console.log();
|
|
68
|
-
for (const run of
|
|
152
|
+
for (const run of visibleRuns) {
|
|
69
153
|
console.log(` ${chalk.bold(run.run_id)} ${chalk.dim(`(${run.status ?? "?"})`)}`);
|
|
70
154
|
if (run.preparation)
|
|
71
155
|
console.log(chalk.dim(` prep: ${run.preparation}`));
|
|
@@ -74,14 +158,24 @@ export const runsCommand = {
|
|
|
74
158
|
}
|
|
75
159
|
console.log();
|
|
76
160
|
})
|
|
77
|
-
.command("status <run-id>", "Show full record for a run", (y) => y
|
|
161
|
+
.command("status <run-id>", "Show full record for a run", (y) => y
|
|
162
|
+
.positional("run-id", { type: "string", demandOption: true, describe: "Run id" })
|
|
163
|
+
.option("json", {
|
|
164
|
+
type: "boolean",
|
|
165
|
+
default: false,
|
|
166
|
+
describe: "Print the raw JSON record instead of the formatted summary",
|
|
167
|
+
}), async (args) => {
|
|
78
168
|
const { url, token } = resolveConnection(args);
|
|
79
|
-
const { status, raw } = await callJson(`${url}/v1/runs/${encodeURIComponent(args.runId)}`, token);
|
|
169
|
+
const { status, body, raw } = await callJson(`${url}/v1/runs/${encodeURIComponent(args.runId)}`, token);
|
|
80
170
|
if (status !== 200) {
|
|
81
171
|
console.error(chalk.red(`Failed to read run ${args.runId} (HTTP ${status}).`));
|
|
82
172
|
process.exit(1);
|
|
83
173
|
}
|
|
84
|
-
|
|
174
|
+
if (args.json || !body) {
|
|
175
|
+
console.log(raw);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
renderRunStatus(body);
|
|
85
179
|
})
|
|
86
180
|
.command("cancel <run-id>", "Cancel a running run", (y) => y.positional("run-id", { type: "string", demandOption: true, describe: "Run id" }), async (args) => {
|
|
87
181
|
const { url, token } = resolveConnection(args);
|