@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.
Files changed (129) hide show
  1. package/README.md +87 -73
  2. package/dist/cli/commands/mcp.d.ts +0 -34
  3. package/dist/cli/commands/mcp.js +246 -45
  4. package/dist/cli/commands/method.js +261 -15
  5. package/dist/cli/commands/prep.js +61 -16
  6. package/dist/cli/commands/runs.js +103 -9
  7. package/dist/cli/commands/status.js +4 -2
  8. package/dist/cli/commands/test.d.ts +10 -0
  9. package/dist/cli/commands/{verify.js → test.js} +16 -18
  10. package/dist/cli/commands/web.js +82 -8
  11. package/dist/cli/commands/wizard.js +36 -37
  12. package/dist/cli/index.d.ts +2 -2
  13. package/dist/cli/index.js +3 -3
  14. package/dist/compiler-ui/404.html +1 -1
  15. package/dist/compiler-ui/__next.__PAGE__.txt +5 -5
  16. package/dist/compiler-ui/__next._full.txt +13 -12
  17. package/dist/compiler-ui/__next._head.txt +3 -3
  18. package/dist/compiler-ui/__next._index.txt +5 -4
  19. package/dist/compiler-ui/__next._tree.txt +4 -3
  20. package/dist/compiler-ui/_next/static/chunks/01646j7yi.w5a.css +1 -0
  21. package/dist/compiler-ui/_next/static/chunks/{0n51hrfoufc7g.js → 02f_.8.ebn556.js} +1 -1
  22. package/dist/compiler-ui/_next/static/chunks/02r7siaw-_p5w.js +1 -0
  23. package/dist/compiler-ui/_next/static/chunks/{08m7vf5asqlsm.js → 04d0ly-7xb~-j.js} +10 -10
  24. package/dist/compiler-ui/_next/static/chunks/0fhs9psnxqd8s.js +1 -0
  25. package/dist/compiler-ui/_next/static/chunks/0mssmhpbifj15.css +2 -0
  26. package/dist/compiler-ui/_next/static/chunks/0nypu~ddwxari.js +116 -0
  27. package/dist/compiler-ui/_next/static/chunks/0p3s8iyhgcww2.js +31 -0
  28. package/dist/compiler-ui/_next/static/chunks/0tjf-vu_rz8s0.css +1 -0
  29. package/dist/compiler-ui/_next/static/chunks/0u6p3fpbbfgtl.js +1 -0
  30. package/dist/compiler-ui/_next/static/chunks/0wpx5..8dnh0w.js +1 -0
  31. package/dist/compiler-ui/_next/static/chunks/0y0uj160p0ts~.js +1 -0
  32. package/dist/compiler-ui/_next/static/chunks/10t8l~_oenf.c.js +1 -0
  33. package/dist/compiler-ui/_next/static/chunks/13gz9e7z~imx1.js +5 -0
  34. package/dist/compiler-ui/_next/static/chunks/156xed-b6czaw.js +1 -0
  35. package/dist/compiler-ui/_next/static/chunks/{turbopack-0.uq1k8c0j4s..js → turbopack-02-3e_c-yz~5g.js} +1 -1
  36. package/dist/compiler-ui/_next/static/chunks/{turbopack-10e~t1yzi4svj.js → turbopack-0apv8vb-nczuy.js} +1 -1
  37. package/dist/compiler-ui/_not-found/__next._full.txt +10 -9
  38. package/dist/compiler-ui/_not-found/__next._head.txt +3 -3
  39. package/dist/compiler-ui/_not-found/__next._index.txt +5 -4
  40. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +2 -2
  41. package/dist/compiler-ui/_not-found/__next._not-found.txt +3 -3
  42. package/dist/compiler-ui/_not-found/__next._tree.txt +3 -2
  43. package/dist/compiler-ui/_not-found.html +1 -1
  44. package/dist/compiler-ui/_not-found.txt +10 -9
  45. package/dist/compiler-ui/index.html +1 -1
  46. package/dist/compiler-ui/index.txt +13 -12
  47. package/dist/packages/contracts/lib/schema.d.ts +4 -0
  48. package/dist/packages/contracts/lib/schema.js +2 -1
  49. package/dist/packages/engine/action-definitions.d.ts +174 -13
  50. package/dist/packages/engine/action-definitions.js +125 -122
  51. package/dist/packages/engine/action-planner.js +4 -11
  52. package/dist/packages/engine/agents/lib/shells.d.ts +3 -1
  53. package/dist/packages/engine/agents/lib/shells.js +8 -4
  54. package/dist/packages/engine/agents/role-executors.js +1 -1
  55. package/dist/packages/engine/compile/compiled-paths.js +6 -6
  56. package/dist/packages/engine/connection-config.js +1 -1
  57. package/dist/packages/engine/execution/lib/schema.d.ts +10 -0
  58. package/dist/packages/engine/instance-paths.d.ts +15 -9
  59. package/dist/packages/engine/instance-paths.js +15 -9
  60. package/dist/packages/engine/lib/schema.d.ts +686 -30
  61. package/dist/packages/engine/lib/schema.js +48 -21
  62. package/dist/packages/engine/native-run-handlers.js +10 -8
  63. package/dist/packages/engine/preparation-store.d.ts +9 -13
  64. package/dist/packages/engine/preparation-store.js +12 -0
  65. package/dist/packages/engine/requested-artifacts.d.ts +5 -0
  66. package/dist/packages/engine/requested-artifacts.js +36 -0
  67. package/dist/packages/engine/routes.d.ts +1 -1
  68. package/dist/packages/engine/routes.js +1 -1
  69. package/dist/packages/engine/run-observability.js +3 -2
  70. package/dist/packages/engine/runtime-proposal-helpers.d.ts +2 -2
  71. package/dist/packages/engine/runtime-proposal-helpers.js +5 -7
  72. package/dist/packages/engine/runtime-resource-builders.d.ts +5 -0
  73. package/dist/packages/engine/runtime-resource-builders.js +13 -2
  74. package/dist/packages/engine/runtime.d.ts +3 -1
  75. package/dist/packages/engine/runtime.js +146 -21
  76. package/dist/packages/engine/server.js +104 -52
  77. package/dist/packages/engine/verify/verify-execution.js +1 -1
  78. package/dist/packages/engine/wire-schemas.d.ts +5 -1
  79. package/dist/packages/engine/wire-schemas.js +1 -1
  80. package/dist/packages/methods/authoring/method-authoring.d.ts +3 -1
  81. package/dist/packages/methods/authoring/method-authoring.js +5 -36
  82. package/dist/packages/methods/package/builtin-compiled-method.js +1 -1
  83. package/dist/packages/methods/package/local-methods.d.ts +1 -0
  84. package/dist/packages/methods/package/local-methods.js +19 -4
  85. package/dist/packages/methods/package/method-definitions.js +1 -1
  86. package/dist/packages/project/interf-detect.js +6 -6
  87. package/dist/packages/project/lib/schema.d.ts +193 -0
  88. package/dist/packages/project/lib/schema.js +46 -1
  89. package/dist/packages/project/source-config.js +4 -0
  90. package/dist/packages/project/source-folders.js +1 -1
  91. package/package.json +7 -8
  92. package/public-repo/CONTRIBUTING.md +47 -0
  93. package/public-repo/LICENSE.md +1 -0
  94. package/public-repo/README.md +325 -0
  95. package/public-repo/SECURITY.md +67 -0
  96. package/public-repo/TRADEMARKS.md +8 -0
  97. package/{builtin-methods → public-repo/methods}/interf-default/README.md +4 -0
  98. package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/shape/SKILL.md +4 -8
  99. package/{builtin-methods → public-repo/methods}/interf-default/method.json +1 -1
  100. package/public-repo/methods/interf-default/use/query/SKILL.md +23 -0
  101. package/public-repo/plugins/README.md +9 -0
  102. package/public-repo/plugins/interf/.claude-plugin/plugin.json +21 -0
  103. package/public-repo/plugins/interf/.mcp.json +12 -0
  104. package/public-repo/plugins/interf/README.md +29 -0
  105. package/public-repo/plugins/interf/skills/interf/SKILL.md +477 -0
  106. package/public-repo/skills/interf/SKILL.md +477 -0
  107. package/agent-skills/interf-actions/SKILL.md +0 -185
  108. package/agent-skills/interf-actions/references/cli.md +0 -243
  109. package/builtin-methods/interf-default/use/query/SKILL.md +0 -28
  110. package/dist/cli/commands/verify.d.ts +0 -10
  111. package/dist/compiler-ui/_next/static/chunks/06yhdspx~ca5-.js +0 -5
  112. package/dist/compiler-ui/_next/static/chunks/06z~l3kwb891e.js +0 -1
  113. package/dist/compiler-ui/_next/static/chunks/08g7lvje.te.u.js +0 -1
  114. package/dist/compiler-ui/_next/static/chunks/0_c_tvh-cukjz.css +0 -3
  115. package/dist/compiler-ui/_next/static/chunks/0_i-3_5l9t2qe.js +0 -1
  116. package/dist/compiler-ui/_next/static/chunks/0b-ywny_j0g~0.js +0 -1
  117. package/dist/compiler-ui/_next/static/chunks/0b52v41o1gixx.js +0 -1
  118. package/dist/compiler-ui/_next/static/chunks/0f_geuwdesg_c.js +0 -114
  119. package/dist/compiler-ui/_next/static/chunks/0gpzgsv0w.q~m.js +0 -31
  120. package/dist/compiler-ui/_next/static/chunks/0ilwfezfvu6~-.js +0 -1
  121. package/dist/compiler-ui/_next/static/chunks/0xxmf45eskdt~.css +0 -1
  122. package/dist/compiler-ui/_next/static/chunks/14wtz~vq25~qq.js +0 -1
  123. /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_buildManifest.js +0 -0
  124. /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_clientMiddlewareManifest.js +0 -0
  125. /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_ssgManifest.js +0 -0
  126. /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/structure/SKILL.md +0 -0
  127. /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/summarize/SKILL.md +0 -0
  128. /package/{builtin-methods → public-repo/methods}/interf-default/improve/SKILL.md +0 -0
  129. /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("draft <prep-id>", "Start a method-authoring run for a preparation", (y) => y.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" }), async (args) => {
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}/v1/preparations/${encodeURIComponent(args.prepId)}/method-authoring-runs`, token, { method: "POST", body: JSON.stringify({}) });
89
- if (status !== 201 && status !== 200) {
90
- console.error(chalk.red(`Failed to start method-authoring run (HTTP ${status}).`));
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
- console.log(chalk.green(`Method-authoring run ${chalk.bold(body?.run_id ?? "(?)")} started.`));
96
- })
97
- .command("improve <prep-id>", "Start a method-improvement run for a preparation", (y) => y.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" }), async (args) => {
98
- const { url, token } = resolveConnection(args);
99
- const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/method-improvement-runs`, token, { method: "POST", body: JSON.stringify({}) });
100
- if (status !== 201 && status !== 200) {
101
- console.error(chalk.red(`Failed to start method-improvement run (HTTP ${status}).`));
102
- if (raw)
103
- console.error(raw);
104
- process.exit(1);
320
+ if (args.json) {
321
+ console.log(JSON.stringify(body, null, 2));
322
+ return;
105
323
  }
106
- console.log(chalk.green(`Method-improvement run ${chalk.bold(body?.run_id ?? "(?)")} started.`));
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
- if (prep.method_id)
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 verify run: ${prep.latest_test_run_id}`));
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> --method <method-id>`."));
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 method)";
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(` method: ${method}`));
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 preparation (method binding optional — set later if you don't have one yet)", (y) => y
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 Folder" })
130
- .option("method", { type: "string", describe: "Method id (e.g. interf-default). Optional — bind later via `interf prep set-method`." })
131
- .option("about", { type: "string", describe: "One-line description of the agent work" }), async (args) => {
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 method bound yet — pick or draft one before compiling:`));
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>", "Bind a method to a preparation (or change which method it uses)", (y) => y
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 bind" }), async (args) => {
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(`Bound ${chalk.bold(args.methodId)} to ${chalk.bold(args.prepId)}.`));
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 path = args.prep
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
- if (runs.length === 0) {
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 runs) {
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.positional("run-id", { type: "string", demandOption: true, describe: "Run id" }), async (args) => {
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
- console.log(raw);
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> --method <id>`."));
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
- console.log(` ${chalk.bold(prep.id)} ${chalk.dim(`(${prep.method_id} · ${readiness})`)}`);
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 {};