@interf/compiler 0.9.4 → 0.9.5

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 (103) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +2 -1
  3. package/agent-skills/interf-actions/SKILL.md +17 -11
  4. package/agent-skills/interf-actions/references/cli.md +8 -22
  5. package/dist/cli/commands/action-input-cli.d.ts +25 -0
  6. package/dist/cli/commands/action-input-cli.js +73 -0
  7. package/dist/cli/commands/compile.d.ts +3 -8
  8. package/dist/cli/commands/compile.js +13 -41
  9. package/dist/cli/commands/create-method-wizard.d.ts +0 -12
  10. package/dist/cli/commands/create-method-wizard.js +95 -126
  11. package/dist/cli/commands/create.d.ts +0 -2
  12. package/dist/cli/commands/create.js +16 -22
  13. package/dist/cli/commands/doctor.js +1 -1
  14. package/dist/cli/commands/executor-flow.js +1 -1
  15. package/dist/cli/commands/init.d.ts +16 -1
  16. package/dist/cli/commands/init.js +40 -53
  17. package/dist/cli/commands/list.js +1 -1
  18. package/dist/cli/commands/preparation-action.d.ts +8 -0
  19. package/dist/cli/commands/preparation-action.js +29 -0
  20. package/dist/cli/commands/preparation-picker.d.ts +5 -0
  21. package/dist/cli/commands/preparation-picker.js +36 -0
  22. package/dist/cli/commands/preparation-selection.js +2 -2
  23. package/dist/cli/commands/reset.js +15 -4
  24. package/dist/cli/commands/service-action-flow.d.ts +9 -0
  25. package/dist/cli/commands/service-action-flow.js +19 -0
  26. package/dist/cli/commands/source-config-wizard.d.ts +0 -1
  27. package/dist/cli/commands/source-config-wizard.js +43 -53
  28. package/dist/cli/commands/status.js +7 -123
  29. package/dist/cli/commands/test.d.ts +1 -2
  30. package/dist/cli/commands/test.js +40 -203
  31. package/dist/cli/commands/web.js +8 -262
  32. package/dist/compiler-ui/404.html +1 -1
  33. package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
  34. package/dist/compiler-ui/__next._full.txt +3 -3
  35. package/dist/compiler-ui/__next._head.txt +1 -1
  36. package/dist/compiler-ui/__next._index.txt +2 -2
  37. package/dist/compiler-ui/__next._tree.txt +2 -2
  38. package/dist/compiler-ui/_next/static/chunks/177mvn4rse235.js +89 -0
  39. package/dist/compiler-ui/_next/static/chunks/18a8f2jkv3z.c.css +3 -0
  40. package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
  41. package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
  42. package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
  43. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
  44. package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
  45. package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
  46. package/dist/compiler-ui/_not-found.html +1 -1
  47. package/dist/compiler-ui/_not-found.txt +2 -2
  48. package/dist/compiler-ui/index.html +1 -1
  49. package/dist/compiler-ui/index.txt +3 -3
  50. package/dist/index.d.ts +0 -23
  51. package/dist/index.js +0 -16
  52. package/dist/packages/agents/lib/shells.js +2 -2
  53. package/dist/packages/compiler/lib/schema.d.ts +1 -1
  54. package/dist/packages/compiler/lib/schema.js +1 -1
  55. package/dist/packages/contracts/lib/schema.d.ts +0 -1
  56. package/dist/packages/contracts/lib/schema.js +0 -1
  57. package/dist/packages/execution/lib/schema.d.ts +0 -7
  58. package/dist/packages/execution/lib/schema.js +0 -1
  59. package/dist/packages/local-service/action-definitions.d.ts +246 -0
  60. package/dist/packages/local-service/action-definitions.js +1148 -0
  61. package/dist/packages/local-service/action-planner.d.ts +9 -0
  62. package/dist/packages/local-service/action-planner.js +134 -0
  63. package/dist/packages/local-service/action-values.d.ts +1 -23
  64. package/dist/packages/local-service/action-values.js +1 -31
  65. package/dist/packages/local-service/client.d.ts +48 -17
  66. package/dist/packages/local-service/client.js +95 -52
  67. package/dist/packages/local-service/index.d.ts +8 -5
  68. package/dist/packages/local-service/index.js +5 -3
  69. package/dist/packages/local-service/lib/schema.d.ts +301 -295
  70. package/dist/packages/local-service/lib/schema.js +114 -39
  71. package/dist/packages/local-service/native-run-handlers.d.ts +23 -0
  72. package/dist/{cli/commands/compile-controller.js → packages/local-service/native-run-handlers.js} +203 -19
  73. package/dist/{cli/commands/check-draft.d.ts → packages/local-service/readiness-check-draft.d.ts} +2 -2
  74. package/dist/packages/local-service/routes.d.ts +6 -1
  75. package/dist/packages/local-service/routes.js +7 -2
  76. package/dist/packages/local-service/run-observability.js +15 -17
  77. package/dist/packages/local-service/runtime.d.ts +10 -7
  78. package/dist/packages/local-service/runtime.js +427 -297
  79. package/dist/packages/local-service/server.js +94 -44
  80. package/dist/packages/method-package/method-review-paths.d.ts +1 -1
  81. package/dist/packages/method-package/method-review-paths.js +5 -5
  82. package/dist/packages/project-model/index.d.ts +1 -0
  83. package/dist/packages/project-model/index.js +1 -0
  84. package/dist/packages/project-model/preparation-entries.d.ts +11 -0
  85. package/dist/packages/project-model/preparation-entries.js +49 -0
  86. package/dist/packages/project-model/source-config.d.ts +1 -0
  87. package/dist/packages/project-model/source-config.js +12 -1
  88. package/dist/packages/testing/lib/schema.d.ts +2 -3
  89. package/dist/packages/testing/lib/schema.js +2 -3
  90. package/dist/packages/testing/readiness-check-run.d.ts +3 -3
  91. package/dist/packages/testing/readiness-check-run.js +12 -17
  92. package/package.json +5 -24
  93. package/dist/cli/commands/compile-controller.d.ts +0 -17
  94. package/dist/cli/commands/compiled-flow.d.ts +0 -25
  95. package/dist/cli/commands/compiled-flow.js +0 -112
  96. package/dist/cli/commands/test-flow.d.ts +0 -58
  97. package/dist/cli/commands/test-flow.js +0 -231
  98. package/dist/compiler-ui/_next/static/chunks/0d~8t0zm6545p.js +0 -118
  99. package/dist/compiler-ui/_next/static/chunks/0xnel.ax9a.2c.css +0 -3
  100. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → 84FaeF3EzBF9kKTMjSEVN}/_buildManifest.js +0 -0
  101. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → 84FaeF3EzBF9kKTMjSEVN}/_clientMiddlewareManifest.js +0 -0
  102. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → 84FaeF3EzBF9kKTMjSEVN}/_ssgManifest.js +0 -0
  103. /package/dist/{cli/commands/check-draft.js → packages/local-service/readiness-check-draft.js} +0 -0
@@ -1,50 +1,7 @@
1
1
  import chalk from "chalk";
2
- import * as p from "@clack/prompts";
3
- import { detectInterf, listPortableContextsForSourceFolder, readInterfConfig, resolveSourceControlPath, } from "../../packages/project-model/interf.js";
4
- import { computeCompiledHealth } from "../../packages/compiler/state.js";
5
- import { sourcePreparationConfigFromInterfConfig, loadCompiledPreparationConfig, } from "../../packages/project-model/source-config.js";
6
- import { printSavedTestComparisonState, readCurrentSavedTestComparison } from "./test-flow.js";
2
+ import { detectInterf, resolveSourceControlPath, } from "../../packages/project-model/interf.js";
7
3
  import { findLocalService, readLocalServiceRunSnapshot, } from "../../packages/local-service/index.js";
8
4
  import { resolveCommandControlPath } from "./control-path.js";
9
- function statusColor(status) {
10
- switch (status) {
11
- case "compiled":
12
- return chalk.green;
13
- case "running":
14
- return chalk.yellow;
15
- case "failed":
16
- return chalk.red;
17
- default:
18
- return chalk.dim;
19
- }
20
- }
21
- function publicReadinessStatus(status) {
22
- return status === "compiled" ? "ready" : "not ready";
23
- }
24
- function publicPrepareState(status) {
25
- if (status === "compiled")
26
- return "prepared";
27
- if (status === "idle")
28
- return "not prepared";
29
- return status;
30
- }
31
- function publicHealthSummary(health) {
32
- const completedStages = health.metrics.completed_stages;
33
- const stageTotal = health.metrics.stage_total;
34
- if (typeof completedStages === "number" && typeof stageTotal === "number") {
35
- if (health.status === "compiled") {
36
- return `Portable Context ready — ${completedStages}/${stageTotal} Method stages satisfied.`;
37
- }
38
- if (health.status === "stale") {
39
- return `Portable Context not ready — ${completedStages}/${stageTotal} Method stages satisfied.`;
40
- }
41
- }
42
- return health.summary
43
- .replace(/\bCompiled\b/g, "Prepared")
44
- .replace(/\bcompiled\b/g, "prepared")
45
- .replace(/\bmethod stages\b/g, "Method stages")
46
- .replace(/\bmethod stage\b/g, "Method stage");
47
- }
48
5
  export const statusCommand = {
49
6
  command: "status",
50
7
  describe: "Show deterministic health for the Portable Context agents use",
@@ -54,7 +11,6 @@ export const statusCommand = {
54
11
  describe: "Poll the local Interf service for live run status",
55
12
  }),
56
13
  handler: async (argv) => {
57
- let compiledPath = null;
58
14
  const detected = detectInterf(process.cwd());
59
15
  const serviceProjectPath = detected ? resolveSourceControlPath(detected.path) : resolveCommandControlPath();
60
16
  const service = await findLocalService({
@@ -68,82 +24,10 @@ export const statusCommand = {
68
24
  }
69
25
  return;
70
26
  }
71
- if (detected) {
72
- compiledPath = detected.path;
73
- }
74
- else {
75
- const sourcePath = resolveCommandControlPath();
76
- const local = listPortableContextsForSourceFolder(sourcePath).map(({ path, config }) => ({
77
- path,
78
- name: config.name,
79
- }));
80
- if (local.length === 0) {
81
- process.exitCode = 1;
82
- console.log(chalk.red(" No Portable Context found."));
83
- console.log(chalk.dim(" Run `interf`, save readiness checks, and compile Portable Context agents can use first."));
84
- return;
85
- }
86
- if (local.length === 1) {
87
- compiledPath = local[0].path;
88
- }
89
- else {
90
- const selected = await p.select({
91
- message: "Which Portable Context?",
92
- options: local.map((entry) => ({ value: entry.path, label: entry.name })),
93
- });
94
- if (p.isCancel(selected))
95
- return;
96
- compiledPath = selected;
97
- }
98
- }
99
- const health = computeCompiledHealth(compiledPath);
100
- const color = statusColor(health.status);
101
- console.log();
102
- console.log(color(` ${health.target_name}`));
103
- console.log(chalk.dim(` readiness: ${publicReadinessStatus(health.status)}`));
104
- console.log(chalk.dim(` prepare state: ${publicPrepareState(health.status)}`));
105
- console.log(chalk.dim(` ${publicHealthSummary(health)}`));
106
- const compiledConfig = readInterfConfig(compiledPath);
107
- const sourcePath = resolveSourceControlPath(compiledPath);
108
- const latestComparisonState = compiledConfig
109
- ? readCurrentSavedTestComparison({
110
- projectPath: sourcePath,
111
- preparationName: compiledConfig.name,
112
- checks: (loadCompiledPreparationConfig(compiledPath)
113
- ?? sourcePreparationConfigFromInterfConfig(compiledConfig)).checks,
114
- })
115
- : { comparison: null, stale: false };
116
- const latestComparison = latestComparisonState.comparison;
117
- if (latestComparison) {
118
- printSavedTestComparisonState(latestComparison);
119
- }
120
- else {
121
- console.log();
122
- console.log(chalk.dim(latestComparisonState.stale
123
- ? " Saved readiness results are stale for the current checks. Run `interf test` again."
124
- : " No saved readiness check run yet. Run `interf test` to check source files and Portable Context."));
125
- }
126
- console.log();
127
- const metricOrder = [
128
- "source_total",
129
- "stage_total",
130
- "completed_stages",
131
- "warnings",
132
- "errors",
133
- ];
134
- const printed = new Set();
135
- for (const key of metricOrder) {
136
- const value = health.metrics[key];
137
- if (typeof value !== "number")
138
- continue;
139
- printed.add(key);
140
- console.log(chalk.dim(` ${key}: ${value}`));
141
- }
142
- for (const [key, value] of Object.entries(health.metrics)) {
143
- if (printed.has(key))
144
- continue;
145
- console.log(chalk.dim(` ${key}: ${value}`));
146
- }
27
+ process.exitCode = 1;
28
+ console.log(chalk.red(" Interf local service is not running."));
29
+ console.log(chalk.dim(" Start `interf web`, then rerun `interf status` so status comes from the service source of truth."));
30
+ return;
147
31
  },
148
32
  };
149
33
  function formatEventTime(value) {
@@ -157,8 +41,8 @@ function formatEventTime(value) {
157
41
  });
158
42
  }
159
43
  function testScore(run) {
160
- const compiled = run.comparison?.compiled;
161
- const raw = run.comparison?.raw;
44
+ const compiled = run.readiness_run?.compiled;
45
+ const raw = run.readiness_run?.raw;
162
46
  if (compiled)
163
47
  return `${compiled.passed_cases}/${compiled.total_cases}`;
164
48
  if (raw)
@@ -1,13 +1,12 @@
1
1
  import type { CommandModule } from "yargs";
2
2
  import type { SourcePreparationConfig } from "../../packages/project-model/lib/schema.js";
3
- import { type AgentTestMatrixRow } from "./test-flow.js";
4
3
  type TestMode = "raw" | "compiled" | "both";
5
4
  export interface TestCommandResult {
6
5
  sourcePath: string;
7
6
  preparationConfig: SourcePreparationConfig;
8
7
  builtCompiledPath: string | null;
9
8
  mode: TestMode;
10
- rows: AgentTestMatrixRow[];
9
+ rows: [];
11
10
  }
12
11
  export interface TestCommandFailure {
13
12
  message: string;
@@ -2,20 +2,17 @@ import chalk from "chalk";
2
2
  import * as p from "@clack/prompts";
3
3
  import { detectInterf, resolveSourceControlPath, } from "../../packages/project-model/interf.js";
4
4
  import { loadCompiledPreparationConfig, sourcePreparationConfigFromInterfConfig, } from "../../packages/project-model/source-config.js";
5
- import { addExecutionProfileOptions, executionProfileFromArgv, } from "../../packages/agents/lib/execution-profile.js";
6
- import { chooseCompiledConfigToBuild, findBuiltCompiledPath, } from "./compiled-flow.js";
5
+ import { choosePreparationConfig, } from "./preparation-picker.js";
6
+ import { findBuiltPortableContextPath, } from "../../packages/project-model/preparation-entries.js";
7
7
  import { resolveConfiguredPreparationSelection } from "./preparation-selection.js";
8
- import { printAgentTestFailures, printAgentTestMatrix, printSavedTestComparisonState, } from "./test-flow.js";
9
8
  import { createCompiledTestTarget } from "../../packages/testing/test-targets.js";
10
- import { runReadinessChecksForExecutor, } from "../../packages/testing/readiness-check-run.js";
11
9
  import { resolveMethodId } from "../../packages/methods/method-resolution.js";
12
- import { listRunAgentOptions, promptForTestAgents, resolveNamedLocalExecutor, resolveOrConfigureLocalExecutor, } from "./executor-flow.js";
13
10
  import { submitTestRunToLocalService, waitForLocalTestRun, } from "../../packages/local-service/index.js";
14
11
  import { resolveCommandControlPath } from "./control-path.js";
15
12
  export const testCommand = {
16
13
  command: "test",
17
14
  describe: "Run readiness checks against source files and Portable Context",
18
- builder: (yargs) => addExecutionProfileOptions(yargs)
15
+ builder: (yargs) => yargs
19
16
  .option("preparation", {
20
17
  type: "string",
21
18
  describe: "Preparation id to check when this Source Folder has more than one Preparation",
@@ -23,24 +20,11 @@ export const testCommand = {
23
20
  .option("target", {
24
21
  choices: ["both", "source-files", "portable-context"],
25
22
  describe: "Check source files, Portable Context, or both. Default: both when Portable Context exists, otherwise source files.",
26
- })
27
- .option("keep-sandboxes", {
28
- type: "boolean",
29
- default: false,
30
- describe: "Keep every readiness-check sandbox for review instead of pruning successful ones",
31
- })
32
- .option("agents", {
33
- type: "string",
34
- describe: "Comma-separated local agents to use for readiness checks, or `all`. Example: --agents claude-code,codex",
35
23
  }),
36
24
  handler: async (argv) => {
37
25
  await runTestCommand(argv);
38
26
  },
39
27
  };
40
- function readSandboxRetentionMode(argv) {
41
- const enabled = argv["keep-sandboxes"] ?? argv.keepSandboxes ?? false;
42
- return enabled ? "always" : "on-failure";
43
- }
44
28
  function readRequestedMode(argv) {
45
29
  const value = argv.target;
46
30
  const target = value === "source-files" || value === "portable-context" || value === "both"
@@ -97,103 +81,6 @@ async function promptTestMode(hasBuiltCompiled) {
97
81
  return null;
98
82
  return selected;
99
83
  }
100
- function parseRequestedAgents(argv) {
101
- const raw = argv.agents;
102
- if (typeof raw !== "string" || raw.trim().length === 0)
103
- return null;
104
- if (raw.trim() === "all") {
105
- return listRunAgentOptions().map((agent) => agent.name);
106
- }
107
- return raw
108
- .split(",")
109
- .map((value) => value.trim())
110
- .filter((value) => value.length > 0);
111
- }
112
- async function resolveSelectedTestAgents(options) {
113
- const requestedAgents = parseRequestedAgents(options.argv);
114
- if (requestedAgents && requestedAgents.length > 0) {
115
- const selected = [];
116
- for (const agentName of requestedAgents) {
117
- const resolved = resolveNamedLocalExecutor(agentName, {
118
- executionProfile: options.executionProfile,
119
- });
120
- if (!resolved.executor) {
121
- process.exitCode = 1;
122
- console.log(chalk.red(` ${resolved.error ?? `Could not resolve local agent \"${agentName}\".`}`));
123
- return null;
124
- }
125
- const option = listRunAgentOptions().find((agent) => agent.name === agentName);
126
- selected.push({
127
- name: agentName,
128
- label: option?.displayName ?? agentName,
129
- executor: resolved.executor,
130
- });
131
- }
132
- return selected;
133
- }
134
- if (process.stdin.isTTY && process.stdout.isTTY) {
135
- const prompted = await promptForTestAgents();
136
- if (prompted.cancelled)
137
- return null;
138
- if (prompted.agents.length > 0) {
139
- const selected = [];
140
- for (const agent of prompted.agents) {
141
- const resolved = resolveNamedLocalExecutor(agent.name, {
142
- executionProfile: options.executionProfile,
143
- });
144
- if (!resolved.executor) {
145
- process.exitCode = 1;
146
- console.log(chalk.red(` ${resolved.error ?? `Could not resolve local agent \"${agent.name}\".`}`));
147
- return null;
148
- }
149
- selected.push({
150
- name: agent.name,
151
- label: agent.displayName,
152
- executor: resolved.executor,
153
- });
154
- }
155
- return selected;
156
- }
157
- }
158
- const resolved = await resolveOrConfigureLocalExecutor({
159
- preflight: true,
160
- executionProfile: options.executionProfile,
161
- purpose: "test",
162
- });
163
- if (!resolved.executor) {
164
- if (resolved.cancelled)
165
- return null;
166
- process.exitCode = 1;
167
- console.log(chalk.red(resolved.error ?? "No local agent detected."));
168
- return null;
169
- }
170
- return [
171
- {
172
- name: resolved.executor.name,
173
- label: resolved.executor.displayName,
174
- executor: resolved.executor,
175
- },
176
- ];
177
- }
178
- async function runModeForAgent(options) {
179
- const result = await runReadinessChecksForExecutor({
180
- sourcePath: options.sourcePath,
181
- preparationConfig: options.preparationConfig,
182
- portableContextPath: options.builtCompiledPath,
183
- mode: options.mode,
184
- preserveSandboxes: options.preserveSandboxes,
185
- executor: options.executor,
186
- runSuffix: options.executor.name,
187
- saveLatest: options.saveLatest,
188
- });
189
- return {
190
- agentLabel: options.executor.displayName,
191
- rawOutcome: result.rawOutcome,
192
- compiledOutcome: result.compiledOutcome,
193
- comparisonRunPath: result.comparisonRunPath,
194
- comparison: result.comparison,
195
- };
196
- }
197
84
  export async function runTestCommand(argv = {}) {
198
85
  const cwd = process.cwd();
199
86
  const detected = detectInterf(cwd);
@@ -223,7 +110,7 @@ export async function runTestCommand(argv = {}) {
223
110
  requestedPreparationName,
224
111
  hintedPreparationConfig,
225
112
  })
226
- : await chooseCompiledConfigToBuild({
113
+ : await choosePreparationConfig({
227
114
  sourcePath,
228
115
  selectMessage: "Which saved Preparation do you want to test?",
229
116
  });
@@ -241,11 +128,9 @@ export async function runTestCommand(argv = {}) {
241
128
  "Then rerun `interf test`.",
242
129
  ]);
243
130
  }
244
- const executionProfile = executionProfileFromArgv(argv);
245
- const preserveSandboxes = readSandboxRetentionMode(argv);
246
131
  const builtCompiledPath = detected?.config.name === selectedCompiled.name
247
132
  ? detected.path
248
- : findBuiltCompiledPath(sourcePath, selectedCompiled.name);
133
+ : findBuiltPortableContextPath(sourcePath, selectedCompiled.name);
249
134
  const hasBuiltCompiled = builtCompiledPath
250
135
  ? createCompiledTestTarget(builtCompiledPath, selectedCompiled.name, resolveMethodId(selectedCompiled)).eligible
251
136
  : false;
@@ -255,97 +140,49 @@ export async function runTestCommand(argv = {}) {
255
140
  : (hasBuiltCompiled ? "both" : "raw"));
256
141
  if (!selectedMode)
257
142
  return false;
258
- if (selectedMode === "compiled" && !hasBuiltCompiled) {
259
- return reportTestCommandFailure(argv, `Preparation "${selectedCompiled.name}" does not have Portable Context agents can use yet.`, ["Run `interf compile` first."]);
260
- }
261
- if (selectedMode === "both" && !hasBuiltCompiled) {
262
- return reportTestCommandFailure(argv, `Preparation "${selectedCompiled.name}" does not have Portable Context agents can use yet, so Interf cannot compare source files and Portable Context.`, ["Run `interf compile` first, or rerun with `--target source-files`."]);
263
- }
264
143
  const mode = selectedMode;
265
- if (argv.skipService !== true) {
266
- const submitted = await submitTestRunToLocalService({
267
- projectPath: sourcePath,
268
- request: {
269
- preparation: selectedCompiled.name,
270
- mode,
271
- },
272
- });
273
- if (submitted) {
274
- console.log(chalk.dim(` Visible in Interf: ${submitted.serviceUrl}/`));
275
- let lastStatus = "";
276
- const completed = await waitForLocalTestRun({
277
- serviceUrl: submitted.serviceUrl,
278
- runId: submitted.resource.run_id,
279
- onUpdate(resource) {
280
- if (resource.status === lastStatus)
281
- return;
282
- lastStatus = resource.status;
283
- console.log(chalk.dim(` Readiness check run: ${resource.status}`));
284
- },
285
- });
286
- if (completed.status !== "succeeded") {
287
- return reportTestCommandFailure(argv, `Readiness check run ${completed.status}.`, completed.error ? [completed.error] : []);
288
- }
289
- const compiledScore = completed.comparison?.compiled;
290
- const rawScore = completed.comparison?.raw;
291
- if (compiledScore) {
292
- console.log(chalk.green(` Portable Context readiness checks: ${compiledScore.passed_cases}/${compiledScore.total_cases}`));
293
- }
294
- if (rawScore) {
295
- console.log(chalk.dim(` Source files readiness checks: ${rawScore.passed_cases}/${rawScore.total_cases}`));
296
- }
297
- return true;
298
- }
144
+ const submitted = await submitTestRunToLocalService({
145
+ projectPath: sourcePath,
146
+ request: {
147
+ preparation: selectedCompiled.name,
148
+ mode,
149
+ },
150
+ });
151
+ if (!submitted) {
152
+ return reportTestCommandFailure(argv, "Interf local service is not running for this Workspace.", ["Start it with `interf web`, then rerun `interf test` so the readiness-check run is visible in Interf."]);
299
153
  }
300
- const selectedAgents = await resolveSelectedTestAgents({
301
- argv,
302
- executionProfile,
154
+ console.log(chalk.dim(` Visible in Interf: ${submitted.serviceUrl}/`));
155
+ let lastStatus = "";
156
+ const completed = await waitForLocalTestRun({
157
+ serviceUrl: submitted.serviceUrl,
158
+ runId: submitted.resource.run_id,
159
+ onUpdate(resource) {
160
+ if (resource.status === lastStatus)
161
+ return;
162
+ lastStatus = resource.status;
163
+ console.log(chalk.dim(` Readiness check run: ${resource.status}`));
164
+ },
303
165
  });
304
- if (!selectedAgents || selectedAgents.length === 0) {
305
- return false;
166
+ if (completed.status !== "succeeded") {
167
+ return reportTestCommandFailure(argv, `Readiness check run ${completed.status}.`, completed.error ? [completed.error] : []);
306
168
  }
307
- const rows = await Promise.all(selectedAgents.map((agent) => runModeForAgent({
308
- sourcePath,
309
- preparationConfig: selectedCompiled,
310
- builtCompiledPath: builtCompiledPath ?? null,
311
- mode,
312
- preserveSandboxes,
313
- executor: agent.executor,
314
- saveLatest: selectedAgents.length === 1,
315
- })));
316
- if ((mode === "compiled" || mode === "both") && rows.some((row) => !row.compiledOutcome)) {
317
- return reportTestCommandFailure(argv, `Preparation "${selectedCompiled.name}" does not have Portable Context agents can use yet.`, ["Run `interf compile` first."]);
169
+ const compiledScore = completed.readiness_run?.compiled;
170
+ const rawScore = completed.readiness_run?.raw;
171
+ if (compiledScore) {
172
+ console.log(chalk.green(` Portable Context readiness checks: ${compiledScore.passed_cases}/${compiledScore.total_cases}`));
318
173
  }
319
- printAgentTestMatrix(rows);
320
- printAgentTestFailures(rows);
321
- const resultSummary = {
174
+ if (rawScore) {
175
+ console.log(chalk.dim(` Source files readiness checks: ${rawScore.passed_cases}/${rawScore.total_cases}`));
176
+ }
177
+ const onComplete = typeof argv.onComplete === "function"
178
+ ? argv.onComplete
179
+ : null;
180
+ await onComplete?.({
322
181
  sourcePath,
323
182
  preparationConfig: selectedCompiled,
324
183
  builtCompiledPath: builtCompiledPath ?? null,
325
184
  mode,
326
- rows,
327
- };
328
- const onComplete = typeof argv.onComplete === "function"
329
- ? argv.onComplete
330
- : null;
331
- if (rows.length === 1) {
332
- const row = rows[0];
333
- const comparisonRunPath = row?.comparisonRunPath ?? null;
334
- const latestComparison = row?.comparison ?? null;
335
- if (latestComparison) {
336
- if (mode === "both") {
337
- console.log();
338
- console.log(chalk.dim(` Saved summary: ${comparisonRunPath}`));
339
- }
340
- else {
341
- printSavedTestComparisonState(latestComparison, comparisonRunPath);
342
- }
343
- }
344
- await onComplete?.(resultSummary);
345
- return true;
346
- }
347
- console.log();
348
- console.log(chalk.dim(" Multi-agent compare does not overwrite the saved latest single-agent result."));
349
- await onComplete?.(resultSummary);
185
+ rows: [],
186
+ });
350
187
  return true;
351
188
  }