@interf/compiler 0.18.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/README.md +87 -73
- 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 +61 -16
- 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} +16 -18
- package/dist/cli/commands/web.js +82 -8
- package/dist/cli/commands/wizard.js +36 -37
- 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/lib/schema.d.ts +4 -0
- package/dist/packages/contracts/lib/schema.js +2 -1
- 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 +3 -1
- package/dist/packages/engine/agents/lib/shells.js +8 -4
- package/dist/packages/engine/agents/role-executors.js +1 -1
- package/dist/packages/engine/compile/compiled-paths.js +6 -6
- package/dist/packages/engine/connection-config.js +1 -1
- package/dist/packages/engine/execution/lib/schema.d.ts +10 -0
- 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 +686 -30
- package/dist/packages/engine/lib/schema.js +48 -21
- package/dist/packages/engine/native-run-handlers.js +10 -8
- package/dist/packages/engine/preparation-store.d.ts +9 -13
- package/dist/packages/engine/preparation-store.js +12 -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 +1 -1
- package/dist/packages/engine/routes.js +1 -1
- package/dist/packages/engine/run-observability.js +3 -2
- package/dist/packages/engine/runtime-proposal-helpers.d.ts +2 -2
- package/dist/packages/engine/runtime-proposal-helpers.js +5 -7
- package/dist/packages/engine/runtime-resource-builders.d.ts +5 -0
- package/dist/packages/engine/runtime-resource-builders.js +13 -2
- package/dist/packages/engine/runtime.d.ts +3 -1
- package/dist/packages/engine/runtime.js +146 -21
- package/dist/packages/engine/server.js +104 -52
- package/dist/packages/engine/verify/verify-execution.js +1 -1
- package/dist/packages/engine/wire-schemas.d.ts +5 -1
- package/dist/packages/engine/wire-schemas.js +1 -1
- package/dist/packages/methods/authoring/method-authoring.d.ts +3 -1
- package/dist/packages/methods/authoring/method-authoring.js +5 -36
- package/dist/packages/methods/package/builtin-compiled-method.js +1 -1
- package/dist/packages/methods/package/local-methods.d.ts +1 -0
- package/dist/packages/methods/package/local-methods.js +19 -4
- package/dist/packages/methods/package/method-definitions.js +1 -1
- package/dist/packages/project/interf-detect.js +6 -6
- 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 +4 -0
- package/dist/packages/project/source-folders.js +1 -1
- package/package.json +7 -8
- 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 +4 -0
- 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 +1 -1
- 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/use/query/SKILL.md +0 -28
- package/dist/cli/commands/verify.d.ts +0 -10
- 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_c_tvh-cukjz.css +0 -3
- 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/0f_geuwdesg_c.js +0 -114
- 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/0xxmf45eskdt~.css +0 -1
- package/dist/compiler-ui/_next/static/chunks/14wtz~vq25~qq.js +0 -1
- /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_buildManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_clientMiddlewareManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_ssgManifest.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
- /package/{builtin-methods → public-repo/methods}/interf-default/method.schema.json +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,28 @@ 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
|
+
}
|
|
48
72
|
function statusColor(status) {
|
|
49
73
|
if (status === "ready")
|
|
50
74
|
return chalk.green;
|
|
@@ -57,8 +81,7 @@ function statusColor(status) {
|
|
|
57
81
|
function renderPreparationSummary(prep) {
|
|
58
82
|
console.log();
|
|
59
83
|
console.log(` ${chalk.bold(prep.name)}`);
|
|
60
|
-
|
|
61
|
-
console.log(chalk.dim(` method: ${prep.method_id}`));
|
|
84
|
+
console.log(chalk.dim(` Build Plan: ${prep.method_id ?? "(not selected)"}`));
|
|
62
85
|
if (prep.source_path)
|
|
63
86
|
console.log(chalk.dim(` source: ${prep.source_path}`));
|
|
64
87
|
if (prep.portable_context_path) {
|
|
@@ -80,12 +103,26 @@ function renderPreparationSummary(prep) {
|
|
|
80
103
|
console.log(` ${artifact.artifact_id.padEnd(idWidth)} ${colored}${stages}`);
|
|
81
104
|
}
|
|
82
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
|
+
}
|
|
83
120
|
if (prep.latest_compile_run_id) {
|
|
84
121
|
console.log();
|
|
85
122
|
console.log(chalk.dim(` latest compile run: ${prep.latest_compile_run_id}`));
|
|
86
123
|
}
|
|
87
124
|
if (prep.latest_test_run_id) {
|
|
88
|
-
console.log(chalk.dim(` latest
|
|
125
|
+
console.log(chalk.dim(` latest check run: ${prep.latest_test_run_id}`));
|
|
89
126
|
}
|
|
90
127
|
console.log();
|
|
91
128
|
console.log(chalk.dim(` Run with --json for the raw resource record.`));
|
|
@@ -108,7 +145,7 @@ export const prepCommand = {
|
|
|
108
145
|
}
|
|
109
146
|
const preparations = body.preparations ?? [];
|
|
110
147
|
if (preparations.length === 0) {
|
|
111
|
-
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>`."));
|
|
112
149
|
return;
|
|
113
150
|
}
|
|
114
151
|
console.log();
|
|
@@ -116,26 +153,34 @@ export const prepCommand = {
|
|
|
116
153
|
console.log();
|
|
117
154
|
for (const prep of preparations) {
|
|
118
155
|
const sourceLabel = prep.source?.locator ?? prep.source_path ?? "(no source)";
|
|
119
|
-
const method = prep.method_id ?? "(no
|
|
156
|
+
const method = prep.method_id ?? "(no Build Plan)";
|
|
120
157
|
const readiness = prep.readiness?.status ?? "—";
|
|
158
|
+
const requested = prep.requested_artifacts?.length ?? 0;
|
|
121
159
|
console.log(` ${prep.id}`);
|
|
122
160
|
console.log(chalk.dim(` source: ${sourceLabel}`));
|
|
123
|
-
console.log(chalk.dim(`
|
|
161
|
+
console.log(chalk.dim(` Build Plan: ${method}`));
|
|
162
|
+
console.log(chalk.dim(` requested Artifacts: ${requested}`));
|
|
124
163
|
console.log(chalk.dim(` readiness: ${readiness}`));
|
|
125
164
|
}
|
|
126
165
|
})
|
|
127
|
-
.command("create <prep-id>", "Create a
|
|
166
|
+
.command("create <prep-id>", "Create a Preparation (Build Plan optional — select or draft it later)", (y) => y
|
|
128
167
|
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id (lowercase, dash-separated)" })
|
|
129
|
-
.option("source", { type: "string", demandOption: true, describe: "Path to the Source
|
|
130
|
-
.option("method", { type: "string", describe: "Method id
|
|
131
|
-
.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) => {
|
|
132
173
|
const { url, token } = requireConnection(args);
|
|
133
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));
|
|
134
177
|
const requestBody = {
|
|
135
178
|
id: args.prepId,
|
|
136
179
|
source: { kind: "local-folder", locator: sourceAbs },
|
|
137
180
|
...(args.method ? { method_id: args.method } : {}),
|
|
138
181
|
about: args.about,
|
|
182
|
+
...(requestedArtifacts ? { requested_artifacts: requestedArtifacts } : {}),
|
|
183
|
+
...(sourceProfile ? { source_profile: sourceProfile } : {}),
|
|
139
184
|
checks: [],
|
|
140
185
|
};
|
|
141
186
|
const { status, body, raw } = await callJson(`${url}/v1/preparations`, token, { method: "POST", body: JSON.stringify(requestBody) });
|
|
@@ -147,17 +192,17 @@ export const prepCommand = {
|
|
|
147
192
|
}
|
|
148
193
|
console.log(chalk.green(`Created preparation ${chalk.bold(args.prepId)}.`));
|
|
149
194
|
if (!args.method) {
|
|
150
|
-
console.log(chalk.dim(` no
|
|
195
|
+
console.log(chalk.dim(` no Build Plan selected yet — pick or draft one before compiling:`));
|
|
151
196
|
console.log(chalk.dim(` interf prep set-method ${args.prepId} <method-id>`));
|
|
152
197
|
console.log(chalk.dim(` interf method draft ${args.prepId}`));
|
|
153
198
|
}
|
|
154
|
-
if (body?.portable_context?.value) {
|
|
199
|
+
if (body?.method_id && body?.portable_context?.value) {
|
|
155
200
|
console.log(chalk.dim(` portable context (locator): ${body.portable_context.value}`));
|
|
156
201
|
}
|
|
157
202
|
})
|
|
158
|
-
.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
|
|
159
204
|
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
160
|
-
.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) => {
|
|
161
206
|
const { url, token } = requireConnection(args);
|
|
162
207
|
const { status, raw } = await callJson(`${url}${preparationResourcePath(args.prepId)}`, token, { method: "PATCH", body: JSON.stringify({ method_id: args.methodId }) });
|
|
163
208
|
if (status !== 200) {
|
|
@@ -166,7 +211,7 @@ export const prepCommand = {
|
|
|
166
211
|
console.error(raw);
|
|
167
212
|
process.exit(1);
|
|
168
213
|
}
|
|
169
|
-
console.log(chalk.green(`
|
|
214
|
+
console.log(chalk.green(`Selected Build Plan ${chalk.bold(args.methodId)} for ${chalk.bold(args.prepId)}.`));
|
|
170
215
|
})
|
|
171
216
|
.command("show <prep-id>", "Show a preparation's full record", (y) => y
|
|
172
217
|
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
@@ -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);
|
|
@@ -64,12 +64,14 @@ export const statusCommand = {
|
|
|
64
64
|
console.log();
|
|
65
65
|
console.log(chalk.bold(` Preparations (${list.length})`));
|
|
66
66
|
if (list.length === 0) {
|
|
67
|
-
console.log(chalk.dim(" No preparations yet. `interf prep create <id> --source <path
|
|
67
|
+
console.log(chalk.dim(" No preparations yet. `interf prep create <id> --source <path>`."));
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
70
|
for (const prep of list) {
|
|
71
71
|
const readiness = prep.readiness?.status ?? "—";
|
|
72
|
-
|
|
72
|
+
const buildPlan = prep.method_id ?? "no Build Plan";
|
|
73
|
+
const requested = prep.requested_artifacts?.length ?? 0;
|
|
74
|
+
console.log(` ${chalk.bold(prep.id)} ${chalk.dim(`(${buildPlan} · ${requested} requested · ${readiness})`)}`);
|
|
73
75
|
console.log(chalk.dim(` source: ${prep.source.locator}`));
|
|
74
76
|
}
|
|
75
77
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CommandModule } from "yargs";
|
|
2
|
+
type TestTarget = "compiled" | "source-files";
|
|
3
|
+
interface TestArgs {
|
|
4
|
+
prepId: string;
|
|
5
|
+
target?: TestTarget;
|
|
6
|
+
url?: string;
|
|
7
|
+
token?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const testCommand: CommandModule<unknown, TestArgs>;
|
|
10
|
+
export {};
|