@interf/compiler 0.16.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -0
- package/README.md +90 -73
- package/TRADEMARKS.md +4 -4
- package/dist/cli/commands/mcp.d.ts +0 -34
- package/dist/cli/commands/mcp.js +246 -45
- package/dist/cli/commands/method.js +261 -15
- package/dist/cli/commands/prep.js +116 -15
- package/dist/cli/commands/runs.js +103 -9
- package/dist/cli/commands/status.js +4 -2
- package/dist/cli/commands/test.d.ts +10 -0
- package/dist/cli/commands/{verify.js → test.js} +24 -17
- package/dist/cli/commands/web.js +82 -8
- package/dist/cli/commands/wizard.js +158 -51
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +3 -3
- package/dist/compiler-ui/404.html +1 -1
- package/dist/compiler-ui/__next.__PAGE__.txt +5 -5
- package/dist/compiler-ui/__next._full.txt +13 -12
- package/dist/compiler-ui/__next._head.txt +3 -3
- package/dist/compiler-ui/__next._index.txt +5 -4
- package/dist/compiler-ui/__next._tree.txt +4 -3
- package/dist/compiler-ui/_next/static/chunks/01646j7yi.w5a.css +1 -0
- package/dist/compiler-ui/_next/static/chunks/{0n51hrfoufc7g.js → 02f_.8.ebn556.js} +1 -1
- package/dist/compiler-ui/_next/static/chunks/02r7siaw-_p5w.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/{08m7vf5asqlsm.js → 04d0ly-7xb~-j.js} +10 -10
- package/dist/compiler-ui/_next/static/chunks/0fhs9psnxqd8s.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/0mssmhpbifj15.css +2 -0
- package/dist/compiler-ui/_next/static/chunks/0nypu~ddwxari.js +116 -0
- package/dist/compiler-ui/_next/static/chunks/0p3s8iyhgcww2.js +31 -0
- package/dist/compiler-ui/_next/static/chunks/0tjf-vu_rz8s0.css +1 -0
- package/dist/compiler-ui/_next/static/chunks/0u6p3fpbbfgtl.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/0wpx5..8dnh0w.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/0y0uj160p0ts~.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/10t8l~_oenf.c.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/13gz9e7z~imx1.js +5 -0
- package/dist/compiler-ui/_next/static/chunks/156xed-b6czaw.js +1 -0
- package/dist/compiler-ui/_next/static/chunks/{turbopack-0.uq1k8c0j4s..js → turbopack-02-3e_c-yz~5g.js} +1 -1
- package/dist/compiler-ui/_next/static/chunks/{turbopack-10e~t1yzi4svj.js → turbopack-0apv8vb-nczuy.js} +1 -1
- package/dist/compiler-ui/_not-found/__next._full.txt +10 -9
- package/dist/compiler-ui/_not-found/__next._head.txt +3 -3
- package/dist/compiler-ui/_not-found/__next._index.txt +5 -4
- package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._not-found.txt +3 -3
- package/dist/compiler-ui/_not-found/__next._tree.txt +3 -2
- package/dist/compiler-ui/_not-found.html +1 -1
- package/dist/compiler-ui/_not-found.txt +10 -9
- package/dist/compiler-ui/index.html +1 -1
- package/dist/compiler-ui/index.txt +13 -12
- package/dist/packages/contracts/index.d.ts +2 -2
- package/dist/packages/contracts/index.js +1 -1
- package/dist/packages/contracts/lib/schema.d.ts +275 -72
- package/dist/packages/contracts/lib/schema.js +244 -83
- package/dist/packages/engine/action-definitions.d.ts +174 -13
- package/dist/packages/engine/action-definitions.js +125 -122
- package/dist/packages/engine/action-planner.js +4 -11
- package/dist/packages/engine/agents/lib/shells.d.ts +15 -5
- package/dist/packages/engine/agents/lib/shells.js +134 -123
- package/dist/packages/engine/agents/role-executors.js +1 -1
- package/dist/packages/engine/cloud-seams.d.ts +115 -0
- package/dist/packages/engine/cloud-seams.js +84 -0
- package/dist/packages/engine/compile/artifact-counts.d.ts +1 -1
- package/dist/packages/engine/compile/artifact-counts.js +3 -3
- package/dist/packages/engine/compile/artifact-status.d.ts +41 -0
- package/dist/packages/engine/compile/artifact-status.js +166 -0
- package/dist/packages/engine/compile/billing-events.d.ts +89 -0
- package/dist/packages/engine/compile/billing-events.js +74 -0
- package/dist/packages/engine/compile/check-evaluator.d.ts +66 -0
- package/dist/packages/engine/compile/check-evaluator.js +298 -0
- package/dist/packages/engine/compile/compiled-paths.js +6 -6
- package/dist/packages/engine/compile/compiled-schema.d.ts +7 -17
- package/dist/packages/engine/compile/compiled-schema.js +55 -70
- package/dist/packages/engine/compile/compiled-stage-plan.d.ts +1 -0
- package/dist/packages/engine/compile/compiled-stage-plan.js +32 -15
- package/dist/packages/engine/compile/compiled-stage-runner.js +1 -1
- package/dist/packages/engine/compile/index.d.ts +0 -1
- package/dist/packages/engine/compile/index.js +0 -1
- package/dist/packages/engine/compile/lib/schema.d.ts +111 -92
- package/dist/packages/engine/compile/lib/schema.js +35 -39
- package/dist/packages/engine/compile/method-primitives.d.ts +2 -2
- package/dist/packages/engine/compile/method-primitives.js +1 -1
- package/dist/packages/engine/compile/reset.js +4 -4
- package/dist/packages/engine/compile/runtime-contracts.js +2 -1
- package/dist/packages/engine/compile/runtime-prompt.js +3 -2
- package/dist/packages/engine/compile/runtime-reconcile.js +35 -35
- package/dist/packages/engine/compile/runtime-runs.js +0 -1
- package/dist/packages/engine/compile/runtime-types.d.ts +7 -8
- package/dist/packages/engine/compile/runtime.d.ts +1 -2
- package/dist/packages/engine/compile/runtime.js +0 -1
- package/dist/packages/engine/compile/state-health.js +6 -6
- package/dist/packages/engine/compile/state-view.js +7 -6
- package/dist/packages/engine/compile/validate-compiled.js +61 -30
- package/dist/packages/engine/compile/validate.js +26 -24
- package/dist/packages/engine/connection-config.js +1 -1
- package/dist/packages/engine/execution/lib/schema.d.ts +89 -33
- package/dist/packages/engine/execution/lib/schema.js +13 -5
- package/dist/packages/engine/index.d.ts +2 -2
- package/dist/packages/engine/index.js +1 -1
- package/dist/packages/engine/instance-paths.d.ts +15 -9
- package/dist/packages/engine/instance-paths.js +15 -9
- package/dist/packages/engine/lib/schema.d.ts +1316 -351
- package/dist/packages/engine/lib/schema.js +99 -36
- package/dist/packages/engine/native-run-handlers.js +25 -15
- package/dist/packages/engine/preparation-store.d.ts +9 -7
- package/dist/packages/engine/preparation-store.js +20 -0
- package/dist/packages/engine/requested-artifacts.d.ts +5 -0
- package/dist/packages/engine/requested-artifacts.js +36 -0
- package/dist/packages/engine/routes.d.ts +7 -1
- package/dist/packages/engine/routes.js +7 -1
- package/dist/packages/engine/run-observability.js +4 -4
- package/dist/packages/engine/runtime-event-applier.js +7 -0
- package/dist/packages/engine/runtime-proposal-helpers.d.ts +2 -2
- package/dist/packages/engine/runtime-proposal-helpers.js +6 -8
- package/dist/packages/engine/runtime-resource-builders.d.ts +11 -6
- package/dist/packages/engine/runtime-resource-builders.js +18 -6
- package/dist/packages/engine/runtime.d.ts +70 -8
- package/dist/packages/engine/runtime.js +304 -49
- package/dist/packages/engine/server.d.ts +25 -0
- package/dist/packages/engine/server.js +161 -50
- package/dist/packages/engine/verify/index.d.ts +10 -10
- package/dist/packages/engine/verify/index.js +8 -8
- package/dist/packages/engine/verify/readiness-check-run.d.ts +27 -4
- package/dist/packages/engine/verify/readiness-check-run.js +92 -24
- package/dist/packages/engine/verify/{test-execution.d.ts → verify-execution.d.ts} +2 -2
- package/dist/packages/engine/verify/{test-execution.js → verify-execution.js} +3 -3
- package/dist/packages/engine/verify/{test-paths.d.ts → verify-paths.d.ts} +1 -1
- package/dist/packages/engine/verify/{test-sandbox.d.ts → verify-sandbox.d.ts} +1 -1
- package/dist/packages/engine/verify/{test-specs.d.ts → verify-specs.d.ts} +1 -1
- package/dist/packages/engine/verify/{test-specs.js → verify-specs.js} +1 -1
- package/dist/packages/engine/verify/{test-targets.d.ts → verify-targets.d.ts} +1 -1
- package/dist/packages/engine/verify/{test.d.ts → verify.d.ts} +4 -4
- package/dist/packages/engine/verify/{test.js → verify.js} +3 -3
- package/dist/packages/engine/wire-schemas.d.ts +549 -0
- package/dist/packages/engine/wire-schemas.js +59 -0
- package/dist/packages/methods/authoring/method-authoring.d.ts +5 -1
- package/dist/packages/methods/authoring/method-authoring.js +68 -18
- package/dist/packages/methods/authoring/method-edit-session.js +5 -5
- package/dist/packages/methods/authoring/method-improvement.js +1 -1
- package/dist/packages/methods/package/builtin-compiled-method.d.ts +12 -12
- package/dist/packages/methods/package/builtin-compiled-method.js +26 -23
- package/dist/packages/methods/package/context-interface.d.ts +39 -26
- package/dist/packages/methods/package/context-interface.js +48 -39
- package/dist/packages/methods/package/interf-method-package.js +28 -47
- package/dist/packages/methods/package/local-methods.d.ts +4 -4
- package/dist/packages/methods/package/local-methods.js +53 -66
- package/dist/packages/methods/package/method-definitions.d.ts +4 -6
- package/dist/packages/methods/package/method-definitions.js +1 -5
- package/dist/packages/methods/package/method-helpers.d.ts +0 -2
- package/dist/packages/methods/package/method-helpers.js +0 -4
- package/dist/packages/project/interf-detect.js +6 -6
- package/dist/packages/project/interf-scaffold.js +12 -12
- package/dist/packages/project/lib/schema.d.ts +193 -0
- package/dist/packages/project/lib/schema.js +46 -1
- package/dist/packages/project/source-config.js +6 -1
- package/dist/packages/project/source-folders.js +1 -1
- package/package.json +12 -23
- package/public-repo/CONTRIBUTING.md +47 -0
- package/public-repo/LICENSE.md +1 -0
- package/public-repo/README.md +325 -0
- package/public-repo/SECURITY.md +67 -0
- package/public-repo/TRADEMARKS.md +8 -0
- package/{builtin-methods → public-repo/methods}/interf-default/README.md +10 -7
- package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/shape/SKILL.md +4 -8
- package/{builtin-methods → public-repo/methods}/interf-default/method.json +8 -69
- package/public-repo/methods/interf-default/method.schema.json +75 -0
- package/public-repo/methods/interf-default/use/query/SKILL.md +23 -0
- package/public-repo/plugins/README.md +9 -0
- package/public-repo/plugins/interf/.claude-plugin/plugin.json +21 -0
- package/public-repo/plugins/interf/.mcp.json +12 -0
- package/public-repo/plugins/interf/README.md +29 -0
- package/public-repo/plugins/interf/skills/interf/SKILL.md +477 -0
- package/public-repo/skills/interf/SKILL.md +477 -0
- package/agent-skills/interf-actions/SKILL.md +0 -185
- package/agent-skills/interf-actions/references/cli.md +0 -243
- package/builtin-methods/interf-default/method.schema.json +0 -73
- package/builtin-methods/interf-default/use/query/SKILL.md +0 -28
- package/dist/cli/commands/verify.d.ts +0 -8
- package/dist/compiler-ui/_next/static/chunks/06yhdspx~ca5-.js +0 -5
- package/dist/compiler-ui/_next/static/chunks/06z~l3kwb891e.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/08g7lvje.te.u.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0_i-3_5l9t2qe.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0b-ywny_j0g~0.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0b52v41o1gixx.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0gpzgsv0w.q~m.js +0 -31
- package/dist/compiler-ui/_next/static/chunks/0ilwfezfvu6~-.js +0 -1
- package/dist/compiler-ui/_next/static/chunks/0jipmpez3_ehh.js +0 -89
- package/dist/compiler-ui/_next/static/chunks/0xxmf45eskdt~.css +0 -1
- package/dist/compiler-ui/_next/static/chunks/13awzu4tooflw.css +0 -3
- package/dist/compiler-ui/_next/static/chunks/14wtz~vq25~qq.js +0 -1
- package/dist/packages/engine/compile/runtime-acceptance.d.ts +0 -9
- package/dist/packages/engine/compile/runtime-acceptance.js +0 -265
- /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → tYHMLL9oKds1yDoNYgkPV}/_buildManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → tYHMLL9oKds1yDoNYgkPV}/_clientMiddlewareManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → tYHMLL9oKds1yDoNYgkPV}/_ssgManifest.js +0 -0
- /package/dist/packages/engine/verify/{test-paths.js → verify-paths.js} +0 -0
- /package/dist/packages/engine/verify/{test-profile-presets.d.ts → verify-profile-presets.d.ts} +0 -0
- /package/dist/packages/engine/verify/{test-profile-presets.js → verify-profile-presets.js} +0 -0
- /package/dist/packages/engine/verify/{test-sandbox.js → verify-sandbox.js} +0 -0
- /package/dist/packages/engine/verify/{test-targets.js → verify-targets.js} +0 -0
- /package/dist/packages/engine/verify/{test-types.d.ts → verify-types.d.ts} +0 -0
- /package/dist/packages/engine/verify/{test-types.js → verify-types.js} +0 -0
- /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/structure/SKILL.md +0 -0
- /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/summarize/SKILL.md +0 -0
- /package/{builtin-methods → public-repo/methods}/interf-default/improve/SKILL.md +0 -0
|
@@ -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 {};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `interf
|
|
3
|
-
* judge against the latest
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* `interf test <prep-id>` — run readiness checks for a Preparation via a
|
|
3
|
+
* judge against the latest portable context (default) or against the source
|
|
4
|
+
* baseline (`--target source-files`). The source-files target reveals how
|
|
5
|
+
* much value the Method adds. Together with Method Artifact checks
|
|
6
|
+
* (auto-run on every `interf compile`), this feeds the Preparation's
|
|
7
|
+
* overall readiness state.
|
|
6
8
|
*
|
|
7
|
-
* interf
|
|
9
|
+
* interf test bristol
|
|
10
|
+
* interf test bristol --target source-files
|
|
8
11
|
*/
|
|
9
12
|
import chalk from "chalk";
|
|
10
13
|
import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/engine/connection-config.js";
|
|
@@ -38,37 +41,41 @@ async function callJson(url, token, init = {}) {
|
|
|
38
41
|
}
|
|
39
42
|
return { status: response.status, body, raw };
|
|
40
43
|
}
|
|
41
|
-
export const
|
|
42
|
-
command: "
|
|
43
|
-
describe: "
|
|
44
|
+
export const testCommand = {
|
|
45
|
+
command: "test <prep-id>",
|
|
46
|
+
describe: "Run readiness checks against a Preparation's portable context (or source-files baseline)",
|
|
44
47
|
builder: (yargs) => yargs
|
|
45
48
|
.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
|
|
49
|
+
.option("target", {
|
|
50
|
+
type: "string",
|
|
51
|
+
choices: ["compiled", "source-files"],
|
|
52
|
+
default: "compiled",
|
|
53
|
+
describe: "Judge target: 'compiled' (default) checks the portable context, 'source-files' checks the raw Source baseline",
|
|
54
|
+
})
|
|
46
55
|
.option("url", { type: "string", describe: "Override the active connection URL" })
|
|
47
56
|
.option("token", { type: "string", describe: "Override the active bearer token" }),
|
|
48
57
|
handler: async (args) => {
|
|
49
58
|
const { url, token } = resolveConnection(args);
|
|
50
|
-
// 0.15 hard-error: refuse to start a
|
|
51
|
-
// zero connected agents — verifier-role stages can't run without
|
|
52
|
-
// one.
|
|
59
|
+
// 0.15 hard-error: refuse to start a readiness-check run if the engine
|
|
60
|
+
// has zero connected agents — verifier-role stages can't run without one.
|
|
53
61
|
const instance = await callJson(`${url}/v1/instance`, token);
|
|
54
62
|
if (instance.body && instance.body.agent_count === 0) {
|
|
55
|
-
console.error(chalk.red(" Cannot
|
|
63
|
+
console.error(chalk.red(" Cannot run readiness checks — no agents available."));
|
|
56
64
|
console.error(" Install Claude Code, Codex, Gemini, or another agent CLI, or");
|
|
57
65
|
console.error(" register a custom CLI: `interf agents register <name> --command <cmd>`.");
|
|
58
66
|
process.exit(1);
|
|
59
67
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// are gone — claims are evaluated against the compiled output only.
|
|
63
|
-
const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/verify-runs`, token, { method: "POST", body: JSON.stringify({ mode: "compiled" }) });
|
|
68
|
+
const target = args.target ?? "compiled";
|
|
69
|
+
const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/verify-runs`, token, { method: "POST", body: JSON.stringify({ target }) });
|
|
64
70
|
if (status !== 201 && status !== 200) {
|
|
65
|
-
console.error(chalk.red(`Failed to start
|
|
71
|
+
console.error(chalk.red(`Failed to start readiness-check run for ${args.prepId} (HTTP ${status}).`));
|
|
66
72
|
if (raw)
|
|
67
73
|
console.error(raw);
|
|
68
74
|
process.exit(1);
|
|
69
75
|
}
|
|
70
76
|
console.log();
|
|
71
77
|
console.log(` Run ${chalk.bold(body?.run_id ?? "(?)")} ${chalk.dim(`(${body?.status ?? "started"})`)}`);
|
|
78
|
+
console.log(` Target: ${target}`);
|
|
72
79
|
if (body?.readiness?.status)
|
|
73
80
|
console.log(` Readiness: ${body.readiness.status}`);
|
|
74
81
|
if (body?.error)
|
package/dist/cli/commands/web.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* `interf web` — start the engine in the foreground until Ctrl-C.
|
|
3
3
|
*
|
|
4
4
|
* interf web # start on default port; hard error if port busy
|
|
5
|
+
* interf web start # start the engine in the background
|
|
5
6
|
* interf web stop # send SIGTERM to the running engine
|
|
6
7
|
* interf web status # print engine info via the connected URL
|
|
7
8
|
*
|
|
@@ -10,11 +11,13 @@
|
|
|
10
11
|
* connect without a pointer file.
|
|
11
12
|
*/
|
|
12
13
|
import chalk from "chalk";
|
|
13
|
-
import { readFileSync } from "node:fs";
|
|
14
|
+
import { closeSync, mkdirSync, openSync, readFileSync } from "node:fs";
|
|
15
|
+
import { spawn } from "node:child_process";
|
|
16
|
+
import { dirname } from "node:path";
|
|
14
17
|
import { LOCAL_SERVICE_DEFAULT_HOST, LOCAL_SERVICE_DEFAULT_PORT, buildLocalServiceUrl, } from "../../packages/engine/routes.js";
|
|
15
18
|
import { startLocalService } from "../../packages/engine/server.js";
|
|
16
19
|
import { createNativeLocalServiceRunHandlers } from "../../packages/engine/native-run-handlers.js";
|
|
17
|
-
import { CONNECT_OR_ERROR_HINT, clearConnection, readActiveConnection, } from "../../packages/engine/connection-config.js";
|
|
20
|
+
import { CONNECT_OR_ERROR_HINT, clearConnection, readActiveConnection, writeConnection, } from "../../packages/engine/connection-config.js";
|
|
18
21
|
import { serviceRegistryPath } from "../../packages/engine/instance-paths.js";
|
|
19
22
|
function packageVersionFromManifest() {
|
|
20
23
|
try {
|
|
@@ -53,12 +56,6 @@ async function runWebForeground(args) {
|
|
|
53
56
|
}
|
|
54
57
|
throw error;
|
|
55
58
|
}
|
|
56
|
-
console.log();
|
|
57
|
-
console.log(` Interf engine: ${chalk.bold(service.url)}`);
|
|
58
|
-
console.log(` Compiler UI: ${service.url}/`);
|
|
59
|
-
console.log(` Health: ${service.url}/health`);
|
|
60
|
-
console.log(chalk.dim(" Press Ctrl-C to stop."));
|
|
61
|
-
console.log();
|
|
62
59
|
const shutdown = async () => {
|
|
63
60
|
try {
|
|
64
61
|
await service.close();
|
|
@@ -68,12 +65,84 @@ async function runWebForeground(args) {
|
|
|
68
65
|
}
|
|
69
66
|
process.exit(0);
|
|
70
67
|
};
|
|
68
|
+
console.log();
|
|
69
|
+
console.log(` Interf engine: ${chalk.bold(service.url)}`);
|
|
70
|
+
console.log(` Compiler UI: ${service.url}/`);
|
|
71
|
+
console.log(` Health: ${service.url}/health`);
|
|
72
|
+
console.log(chalk.dim(" Press Ctrl-C to stop."));
|
|
73
|
+
console.log();
|
|
71
74
|
process.on("SIGINT", shutdown);
|
|
72
75
|
process.on("SIGTERM", shutdown);
|
|
73
76
|
await new Promise(() => {
|
|
74
77
|
/* block forever; signals trigger shutdown */
|
|
75
78
|
});
|
|
76
79
|
}
|
|
80
|
+
async function isEngineReachable(url) {
|
|
81
|
+
try {
|
|
82
|
+
const response = await fetch(`${url}/health`);
|
|
83
|
+
return response.status === 200;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function waitForEngine(url, timeoutMs) {
|
|
90
|
+
const started = Date.now();
|
|
91
|
+
while (Date.now() - started < timeoutMs) {
|
|
92
|
+
if (await isEngineReachable(url))
|
|
93
|
+
return true;
|
|
94
|
+
await new Promise((resolveWait) => setTimeout(resolveWait, 150));
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
function managedWebLogPath(port) {
|
|
99
|
+
return `${dirname(serviceRegistryPath())}/interf-web-${port}.log`;
|
|
100
|
+
}
|
|
101
|
+
async function runWebStart(args) {
|
|
102
|
+
const host = args.host ?? LOCAL_SERVICE_DEFAULT_HOST;
|
|
103
|
+
const port = args.port ?? LOCAL_SERVICE_DEFAULT_PORT;
|
|
104
|
+
const url = buildLocalServiceUrl({ host, port });
|
|
105
|
+
if (await isEngineReachable(url)) {
|
|
106
|
+
writeConnection({ url, auth_token: null });
|
|
107
|
+
console.log(chalk.green(`Interf engine already running at ${chalk.bold(url)}.`));
|
|
108
|
+
console.log(`Compiler UI: ${url}/`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const binPath = process.argv[1];
|
|
112
|
+
if (!binPath) {
|
|
113
|
+
console.error(chalk.red("Cannot locate the Interf CLI entrypoint for managed start."));
|
|
114
|
+
console.error(`Try running \`interf web\` in a separate terminal instead.`);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
const logPath = args.log ?? managedWebLogPath(port);
|
|
118
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
119
|
+
const stdoutFd = openSync(logPath, "a");
|
|
120
|
+
const stderrFd = openSync(logPath, "a");
|
|
121
|
+
let child;
|
|
122
|
+
try {
|
|
123
|
+
child = spawn(process.execPath, [binPath, "web", "--host", host, "--port", String(port)], {
|
|
124
|
+
detached: true,
|
|
125
|
+
stdio: ["ignore", stdoutFd, stderrFd],
|
|
126
|
+
env: process.env,
|
|
127
|
+
});
|
|
128
|
+
child.unref();
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
closeSync(stdoutFd);
|
|
132
|
+
closeSync(stderrFd);
|
|
133
|
+
}
|
|
134
|
+
const ready = await waitForEngine(url, args.timeoutMs ?? 5000);
|
|
135
|
+
if (!ready) {
|
|
136
|
+
console.error(chalk.red(`Timed out waiting for Interf engine at ${url}.`));
|
|
137
|
+
console.error(`Log: ${logPath}`);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
writeConnection({ url, auth_token: null });
|
|
141
|
+
console.log(chalk.green(`Started Interf engine at ${chalk.bold(url)}.`));
|
|
142
|
+
console.log(`Compiler UI: ${url}/`);
|
|
143
|
+
console.log(`Log: ${logPath}`);
|
|
144
|
+
console.log(chalk.dim(`Stop it with \`interf web stop\`.`));
|
|
145
|
+
}
|
|
77
146
|
function findEnginePidByUrl(url) {
|
|
78
147
|
try {
|
|
79
148
|
const raw = readFileSync(serviceRegistryPath(), "utf8");
|
|
@@ -196,6 +265,11 @@ export const webCommand = {
|
|
|
196
265
|
command: "web [subcommand]",
|
|
197
266
|
describe: "Start / stop / inspect the Interf engine",
|
|
198
267
|
builder: (yargs) => yargs
|
|
268
|
+
.command("start", "Start the engine in the background", (y) => y
|
|
269
|
+
.option("host", { type: "string", default: LOCAL_SERVICE_DEFAULT_HOST, describe: "Host to bind" })
|
|
270
|
+
.option("port", { type: "number", default: LOCAL_SERVICE_DEFAULT_PORT, describe: "Port to bind" })
|
|
271
|
+
.option("timeout-ms", { type: "number", default: 5000, describe: "How long to wait for startup" })
|
|
272
|
+
.option("log", { type: "string", describe: "Path to write background engine logs" }), runWebStart)
|
|
199
273
|
.command("stop", "Stop the connected engine", (y) => y
|
|
200
274
|
.option("url", { type: "string", describe: "Override the active connection URL" })
|
|
201
275
|
.option("token", { type: "string", describe: "Override the active bearer token" }), runWebStop)
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* `interf` (no subcommand) and `interf init` — the wizard.
|
|
3
3
|
*
|
|
4
4
|
* Casual-user entry point. End-to-end onboarding:
|
|
5
|
-
* - If no connection →
|
|
5
|
+
* - If no connection → connect to an already-running local engine, or ask
|
|
6
|
+
* whether to start the foreground local engine, connect remote, or quit.
|
|
6
7
|
* - Once connected → action menu (list / create / compile / test / open UI / stop engine / quit).
|
|
7
8
|
* - Each action loops back to the menu instead of exiting.
|
|
8
9
|
*
|
|
@@ -15,7 +16,7 @@ import { existsSync, statSync } from "node:fs";
|
|
|
15
16
|
import { homedir } from "node:os";
|
|
16
17
|
import { basename, resolve } from "node:path";
|
|
17
18
|
import { spawn } from "node:child_process";
|
|
18
|
-
import { readActiveConnection, writeConnection, } from "../../packages/engine/connection-config.js";
|
|
19
|
+
import { ConnectionRecordSchema, readActiveConnection, writeConnection, } from "../../packages/engine/connection-config.js";
|
|
19
20
|
import { LOCAL_SERVICE_DEFAULT_HOST, LOCAL_SERVICE_DEFAULT_PORT } from "../../packages/engine/routes.js";
|
|
20
21
|
async function callJson(url, token) {
|
|
21
22
|
const headers = new Headers();
|
|
@@ -46,6 +47,18 @@ function spawnInterf(args) {
|
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
const DEFAULT_ENGINE_URL = `http://${LOCAL_SERVICE_DEFAULT_HOST}:${LOCAL_SERVICE_DEFAULT_PORT}`;
|
|
50
|
+
function hasInteractiveTerminal() {
|
|
51
|
+
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
52
|
+
}
|
|
53
|
+
function isHttpUrl(value) {
|
|
54
|
+
try {
|
|
55
|
+
const parsed = new URL(value);
|
|
56
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
49
62
|
/**
|
|
50
63
|
* Probe a URL's `/health` endpoint and return whether the engine is up.
|
|
51
64
|
* Used as a fallback when `connection.json` may be missing (e.g. older
|
|
@@ -133,6 +146,69 @@ function exitNoEngineConnected(reason) {
|
|
|
133
146
|
console.log();
|
|
134
147
|
process.exit(1);
|
|
135
148
|
}
|
|
149
|
+
async function promptForConnection(reason) {
|
|
150
|
+
if (!hasInteractiveTerminal()) {
|
|
151
|
+
exitNoEngineConnected(reason);
|
|
152
|
+
}
|
|
153
|
+
console.log();
|
|
154
|
+
console.log(chalk.yellow(` ${reason}`));
|
|
155
|
+
console.log();
|
|
156
|
+
const choice = await p.select({
|
|
157
|
+
message: "How do you want to continue?",
|
|
158
|
+
options: [
|
|
159
|
+
{ value: "start-local", label: "Start local engine (serves Compiler UI)" },
|
|
160
|
+
{ value: "connect-remote", label: "Connect to remote engine" },
|
|
161
|
+
{ value: "quit", label: chalk.dim("Exit") },
|
|
162
|
+
],
|
|
163
|
+
initialValue: "start-local",
|
|
164
|
+
});
|
|
165
|
+
if (p.isCancel(choice) || choice === "quit") {
|
|
166
|
+
p.outro("Bye.");
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
if (choice === "start-local") {
|
|
170
|
+
console.log();
|
|
171
|
+
console.log(chalk.dim(" Starting `interf web` in this terminal. Press Ctrl-C to stop the engine."));
|
|
172
|
+
console.log();
|
|
173
|
+
const code = await spawnInterf(["web"]);
|
|
174
|
+
process.exit(code);
|
|
175
|
+
}
|
|
176
|
+
const urlValue = await p.text({
|
|
177
|
+
message: "Remote engine URL",
|
|
178
|
+
placeholder: "https://api.interf.cloud",
|
|
179
|
+
validate: (value) => {
|
|
180
|
+
const trimmed = String(value ?? "").trim();
|
|
181
|
+
if (!trimmed)
|
|
182
|
+
return "URL is required.";
|
|
183
|
+
const parsed = ConnectionRecordSchema.safeParse({ url: trimmed, auth_token: null });
|
|
184
|
+
return parsed.success && isHttpUrl(trimmed) ? undefined : "Enter a valid http(s) URL.";
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
if (p.isCancel(urlValue)) {
|
|
188
|
+
p.outro("Bye.");
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
const tokenValue = await p.password({
|
|
192
|
+
message: "Bearer token (optional)",
|
|
193
|
+
mask: "*",
|
|
194
|
+
});
|
|
195
|
+
if (p.isCancel(tokenValue)) {
|
|
196
|
+
p.outro("Bye.");
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
const record = ConnectionRecordSchema.parse({
|
|
200
|
+
url: String(urlValue).trim(),
|
|
201
|
+
auth_token: String(tokenValue ?? "").trim() || null,
|
|
202
|
+
});
|
|
203
|
+
const url = record.url.replace(/\/+$/, "");
|
|
204
|
+
const probe = await callJson(`${url}/health`, record.auth_token);
|
|
205
|
+
if (probe.status === 0) {
|
|
206
|
+
return promptForConnection(`Connection ${url} is unreachable.`);
|
|
207
|
+
}
|
|
208
|
+
writeConnection(record);
|
|
209
|
+
console.log(chalk.green("Connection saved."));
|
|
210
|
+
return { url, token: record.auth_token };
|
|
211
|
+
}
|
|
136
212
|
/** Validate that a path exists and is a directory. */
|
|
137
213
|
function validateSourcePath(value) {
|
|
138
214
|
const abs = resolve(value);
|
|
@@ -170,7 +246,7 @@ async function promptSourcePath() {
|
|
|
170
246
|
}
|
|
171
247
|
options.push({ value: "__custom__", label: chalk.dim("Type a custom path…") });
|
|
172
248
|
const choice = await p.select({
|
|
173
|
-
message: "Where
|
|
249
|
+
message: "Where are the source files?",
|
|
174
250
|
options,
|
|
175
251
|
initialValue: resolve(cwd),
|
|
176
252
|
});
|
|
@@ -178,7 +254,7 @@ async function promptSourcePath() {
|
|
|
178
254
|
return null;
|
|
179
255
|
if (choice === "__custom__") {
|
|
180
256
|
const typed = await p.text({
|
|
181
|
-
message: "Custom source
|
|
257
|
+
message: "Custom source path",
|
|
182
258
|
placeholder: cwd,
|
|
183
259
|
initialValue: cwd,
|
|
184
260
|
validate: validateSourcePath,
|
|
@@ -207,23 +283,22 @@ async function flowCreatePreparation(conn) {
|
|
|
207
283
|
const sourcePath = await promptSourcePath();
|
|
208
284
|
if (!sourcePath)
|
|
209
285
|
return null;
|
|
210
|
-
// Offer
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
// for it later.
|
|
286
|
+
// Offer saved Build Plans, but keep selection optional. The agent-first
|
|
287
|
+
// path usually creates the Preparation from requested Artifacts first,
|
|
288
|
+
// then drafts a custom Build Plan for review.
|
|
214
289
|
const methodsResp = await callJson(`${conn.url}/v1/methods`, conn.token);
|
|
215
290
|
const methods = methodsResp.body?.methods ?? [];
|
|
216
291
|
const methodOptions = methods
|
|
217
292
|
.map((m) => ({ value: m.method_id ?? m.id ?? "", label: `${m.method_id ?? m.id ?? "(?)"}${m.label ? ` — ${m.label}` : ""}` }))
|
|
218
293
|
.filter((opt) => opt.value !== "");
|
|
219
294
|
let methodId = null;
|
|
220
|
-
const skipOption = { value: "__skip__", label: chalk.dim("Skip — pick or draft a
|
|
221
|
-
const customOption = { value: "__custom__", label: "Other (type a
|
|
295
|
+
const skipOption = { value: "__skip__", label: chalk.dim("Skip — pick or draft a Build Plan later") };
|
|
296
|
+
const customOption = { value: "__custom__", label: "Other (type a Build Plan / Method id)" };
|
|
222
297
|
if (methodOptions.length > 0) {
|
|
223
298
|
const chosen = await p.select({
|
|
224
|
-
message: "
|
|
225
|
-
options: [...methodOptions, customOption
|
|
226
|
-
initialValue:
|
|
299
|
+
message: "Select a Build Plan (optional — you can do this later)",
|
|
300
|
+
options: [skipOption, ...methodOptions, customOption],
|
|
301
|
+
initialValue: skipOption.value,
|
|
227
302
|
});
|
|
228
303
|
if (p.isCancel(chosen))
|
|
229
304
|
return null;
|
|
@@ -232,7 +307,7 @@ async function flowCreatePreparation(conn) {
|
|
|
232
307
|
}
|
|
233
308
|
else if (chosen === "__custom__") {
|
|
234
309
|
const typed = await p.text({
|
|
235
|
-
message: "Method id",
|
|
310
|
+
message: "Build Plan / Method id",
|
|
236
311
|
placeholder: "interf-default",
|
|
237
312
|
});
|
|
238
313
|
if (p.isCancel(typed))
|
|
@@ -245,17 +320,17 @@ async function flowCreatePreparation(conn) {
|
|
|
245
320
|
}
|
|
246
321
|
else {
|
|
247
322
|
const choose = await p.select({
|
|
248
|
-
message: "No
|
|
323
|
+
message: "No saved Build Plans registered yet — pick an id?",
|
|
249
324
|
options: [
|
|
250
|
-
{ value: "__type__", label: "Type a method id" },
|
|
251
325
|
skipOption,
|
|
326
|
+
{ value: "__type__", label: "Type a Build Plan / Method id" },
|
|
252
327
|
],
|
|
253
328
|
});
|
|
254
329
|
if (p.isCancel(choose))
|
|
255
330
|
return null;
|
|
256
331
|
if (choose === "__type__") {
|
|
257
332
|
const typed = await p.text({
|
|
258
|
-
message: "Method id",
|
|
333
|
+
message: "Build Plan / Method id",
|
|
259
334
|
initialValue: "interf-default",
|
|
260
335
|
});
|
|
261
336
|
if (p.isCancel(typed))
|
|
@@ -287,20 +362,20 @@ async function pickPreparation(conn, message) {
|
|
|
287
362
|
message,
|
|
288
363
|
options: list.map((prep) => ({
|
|
289
364
|
value: prep.id,
|
|
290
|
-
label: `${prep.id} ${chalk.dim(`(${prep.method_id} · ${prep.readiness?.status ?? "—"})`)}`,
|
|
365
|
+
label: `${prep.id} ${chalk.dim(`(${prep.method_id ?? "no Build Plan"} · ${prep.readiness?.status ?? "—"})`)}`,
|
|
291
366
|
})),
|
|
292
367
|
});
|
|
293
368
|
if (p.isCancel(choice))
|
|
294
369
|
return null;
|
|
295
370
|
return String(choice);
|
|
296
371
|
}
|
|
297
|
-
async function showActionMenu(conn, options = {
|
|
298
|
-
const compileLabel = options.
|
|
372
|
+
async function showActionMenu(conn, options = { allowAgentRuns: true }) {
|
|
373
|
+
const compileLabel = options.allowAgentRuns
|
|
299
374
|
? "Compile a preparation"
|
|
300
375
|
: chalk.dim("Compile a preparation (no agents available)");
|
|
301
|
-
const
|
|
302
|
-
? "
|
|
303
|
-
: chalk.dim("
|
|
376
|
+
const testLabel = options.allowAgentRuns
|
|
377
|
+
? "Run readiness checks"
|
|
378
|
+
: chalk.dim("Readiness checks (no agents available)");
|
|
304
379
|
const action = await p.select({
|
|
305
380
|
message: "What do you want to do?",
|
|
306
381
|
options: [
|
|
@@ -309,7 +384,7 @@ async function showActionMenu(conn, options = { allowCompileVerify: true }) {
|
|
|
309
384
|
{ value: "create", label: "Create a new preparation" },
|
|
310
385
|
{ value: "agents", label: "Manage agents (list / register / role-map)" },
|
|
311
386
|
{ value: "compile", label: compileLabel },
|
|
312
|
-
{ value: "
|
|
387
|
+
{ value: "test", label: testLabel },
|
|
313
388
|
{ value: "stop", label: "Stop the local engine" },
|
|
314
389
|
{ value: "quit", label: "Quit" },
|
|
315
390
|
],
|
|
@@ -327,7 +402,7 @@ async function showActionMenu(conn, options = { allowCompileVerify: true }) {
|
|
|
327
402
|
if (action === "create") {
|
|
328
403
|
const newId = await flowCreatePreparation(conn);
|
|
329
404
|
if (newId) {
|
|
330
|
-
if (!options.
|
|
405
|
+
if (!options.allowAgentRuns) {
|
|
331
406
|
console.log(chalk.dim(" Skipping compile prompt — no agents available. Install one then run `interf compile " +
|
|
332
407
|
newId +
|
|
333
408
|
"`."));
|
|
@@ -342,7 +417,7 @@ async function showActionMenu(conn, options = { allowCompileVerify: true }) {
|
|
|
342
417
|
return "continue";
|
|
343
418
|
}
|
|
344
419
|
if (action === "compile") {
|
|
345
|
-
if (!options.
|
|
420
|
+
if (!options.allowAgentRuns) {
|
|
346
421
|
console.log(chalk.yellow(" Cannot compile — no agents available."));
|
|
347
422
|
console.log(" Install Claude Code, Codex, Gemini, or another agent CLI, or");
|
|
348
423
|
console.log(" register a custom CLI: `interf agents register <name> --command <cmd>`.");
|
|
@@ -353,14 +428,14 @@ async function showActionMenu(conn, options = { allowCompileVerify: true }) {
|
|
|
353
428
|
await spawnInterf(["compile", id]);
|
|
354
429
|
return "continue";
|
|
355
430
|
}
|
|
356
|
-
if (action === "
|
|
357
|
-
if (!options.
|
|
358
|
-
console.log(chalk.yellow(" Cannot
|
|
431
|
+
if (action === "test") {
|
|
432
|
+
if (!options.allowAgentRuns) {
|
|
433
|
+
console.log(chalk.yellow(" Cannot run readiness checks — no agents available."));
|
|
359
434
|
return "continue";
|
|
360
435
|
}
|
|
361
|
-
const id = await pickPreparation(conn, "Which preparation
|
|
436
|
+
const id = await pickPreparation(conn, "Which preparation should Interf test?");
|
|
362
437
|
if (id)
|
|
363
|
-
await spawnInterf(["
|
|
438
|
+
await spawnInterf(["test", id]);
|
|
364
439
|
return "continue";
|
|
365
440
|
}
|
|
366
441
|
if (action === "ui") {
|
|
@@ -395,14 +470,14 @@ async function showActionMenu(conn, options = { allowCompileVerify: true }) {
|
|
|
395
470
|
* Agent install-cards menu shown when the connected engine has zero
|
|
396
471
|
* detected + registered agents. Returns:
|
|
397
472
|
* - "rerun" → user installed an agent and wants to retry detection
|
|
398
|
-
* - "skip" → continue in UI-only mode (no compile/
|
|
473
|
+
* - "skip" → continue in UI-only mode (no compile/test)
|
|
399
474
|
* - "quit" → exit
|
|
400
475
|
*/
|
|
401
476
|
async function showAgentInstallCards() {
|
|
402
477
|
console.log();
|
|
403
478
|
console.log(chalk.yellow(" No agents detected."));
|
|
404
479
|
console.log();
|
|
405
|
-
console.log(" Interf needs at least one agent to compile and
|
|
480
|
+
console.log(" Interf needs at least one agent to compile source files and run readiness checks.");
|
|
406
481
|
console.log();
|
|
407
482
|
const choice = await p.select({
|
|
408
483
|
message: "How do you want to proceed?",
|
|
@@ -522,25 +597,57 @@ async function fetchAgentSnapshot(conn) {
|
|
|
522
597
|
};
|
|
523
598
|
}
|
|
524
599
|
async function runWizard(args) {
|
|
525
|
-
//
|
|
526
|
-
//
|
|
527
|
-
//
|
|
528
|
-
//
|
|
529
|
-
// the user's hands — no surprise background processes, no stale
|
|
530
|
-
// binaries served by a long-lived auto-spawn.
|
|
600
|
+
// The wizard is the human entry point, so it can ask how to connect.
|
|
601
|
+
// It still never auto-starts an engine: starting `interf web` is an
|
|
602
|
+
// explicit foreground choice, and script/agent commands keep the
|
|
603
|
+
// connect-or-error behavior.
|
|
531
604
|
const initial = readActiveConnection({
|
|
532
605
|
urlOverride: args.url,
|
|
533
606
|
authTokenOverride: args.token,
|
|
534
607
|
});
|
|
608
|
+
let conn = null;
|
|
535
609
|
if (!initial) {
|
|
536
|
-
|
|
610
|
+
if (await probeHealth(DEFAULT_ENGINE_URL)) {
|
|
611
|
+
try {
|
|
612
|
+
writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
|
|
613
|
+
}
|
|
614
|
+
catch {
|
|
615
|
+
// best effort
|
|
616
|
+
}
|
|
617
|
+
console.log();
|
|
618
|
+
console.log(chalk.dim(` Engine already running at ${DEFAULT_ENGINE_URL} — connecting.`));
|
|
619
|
+
conn = { url: DEFAULT_ENGINE_URL, token: null };
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
conn = await promptForConnection("No Interf engine is connected.");
|
|
623
|
+
}
|
|
537
624
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
625
|
+
else {
|
|
626
|
+
const url = initial.url.replace(/\/+$/, "");
|
|
627
|
+
const probe = await callJson(`${url}/health`, initial.auth_token);
|
|
628
|
+
if (probe.status === 0) {
|
|
629
|
+
if (!args.url && await probeHealth(DEFAULT_ENGINE_URL)) {
|
|
630
|
+
try {
|
|
631
|
+
writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
|
|
632
|
+
}
|
|
633
|
+
catch {
|
|
634
|
+
// best effort
|
|
635
|
+
}
|
|
636
|
+
console.log();
|
|
637
|
+
console.log(chalk.dim(` Saved connection ${url} is unreachable; using local engine at ${DEFAULT_ENGINE_URL}.`));
|
|
638
|
+
conn = { url: DEFAULT_ENGINE_URL, token: null };
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
conn = await promptForConnection(`Connection ${url} is unreachable.`);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
conn = { url, token: initial.auth_token };
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
if (!conn) {
|
|
649
|
+
return;
|
|
542
650
|
}
|
|
543
|
-
let conn = { url, token: initial.auth_token };
|
|
544
651
|
const instance = await callJson(`${conn.url}/v1/instance`, conn.token);
|
|
545
652
|
console.log();
|
|
546
653
|
console.log(chalk.bold(` Connected to ${conn.url}`));
|
|
@@ -549,7 +656,7 @@ async function runWizard(args) {
|
|
|
549
656
|
}
|
|
550
657
|
// 0.15 — surface the connected agents up front. When zero are
|
|
551
658
|
// detected, run the install-cards menu before letting the user
|
|
552
|
-
// try to compile
|
|
659
|
+
// try to compile or run readiness checks.
|
|
553
660
|
let agents = await fetchAgentSnapshot(conn);
|
|
554
661
|
if (agents && !agents.engineSupportsAgents) {
|
|
555
662
|
console.log();
|
|
@@ -560,7 +667,7 @@ async function runWizard(args) {
|
|
|
560
667
|
message: "Restart the engine now to pick up new features?",
|
|
561
668
|
options: [
|
|
562
669
|
{ value: "restart", label: "Yes — stop old engine, start new one" },
|
|
563
|
-
{ value: "continue", label: chalk.dim("No — continue with limited features (no agents UI / compile /
|
|
670
|
+
{ value: "continue", label: chalk.dim("No — continue with limited features (no agents UI / compile / test)") },
|
|
564
671
|
{ value: "quit", label: "Quit" },
|
|
565
672
|
],
|
|
566
673
|
initialValue: "restart",
|
|
@@ -592,7 +699,7 @@ async function runWizard(args) {
|
|
|
592
699
|
return 0;
|
|
593
700
|
return snapshot.agents.filter((agent) => agent.available !== false).length;
|
|
594
701
|
}
|
|
595
|
-
let
|
|
702
|
+
let allowAgentRuns = installedAgentCount(agents) > 0;
|
|
596
703
|
while (agents &&
|
|
597
704
|
agents.engineSupportsAgents &&
|
|
598
705
|
installedAgentCount(agents) === 0) {
|
|
@@ -602,12 +709,12 @@ async function runWizard(args) {
|
|
|
602
709
|
return;
|
|
603
710
|
}
|
|
604
711
|
if (decision === "skip") {
|
|
605
|
-
|
|
712
|
+
allowAgentRuns = false;
|
|
606
713
|
break;
|
|
607
714
|
}
|
|
608
715
|
// decision === "rerun"
|
|
609
716
|
agents = await fetchAgentSnapshot(conn);
|
|
610
|
-
|
|
717
|
+
allowAgentRuns = installedAgentCount(agents) > 0;
|
|
611
718
|
}
|
|
612
719
|
if (agents && agents.engineSupportsAgents && installedAgentCount(agents) > 0) {
|
|
613
720
|
// Always confirm the active agent before the action menu. Pre-select
|
|
@@ -664,7 +771,7 @@ async function runWizard(args) {
|
|
|
664
771
|
}
|
|
665
772
|
for (;;) {
|
|
666
773
|
console.log();
|
|
667
|
-
const next = await showActionMenu(conn, {
|
|
774
|
+
const next = await showActionMenu(conn, { allowAgentRuns });
|
|
668
775
|
if (next === "exit")
|
|
669
776
|
break;
|
|
670
777
|
}
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { agentsCommand } from "./commands/agents.js";
|
|
2
2
|
import { compileCommand } from "./commands/compile.js";
|
|
3
|
-
import {
|
|
3
|
+
import { testCommand } from "./commands/test.js";
|
|
4
4
|
import { doctorCommand } from "./commands/doctor.js";
|
|
5
5
|
import { methodCommand } from "./commands/method.js";
|
|
6
6
|
import { mcpCommand } from "./commands/mcp.js";
|
|
@@ -22,4 +22,4 @@ export declare function runCli(argv?: string[]): {
|
|
|
22
22
|
_: (string | number)[];
|
|
23
23
|
$0: string;
|
|
24
24
|
}>;
|
|
25
|
-
export { initCommand, compileCommand,
|
|
25
|
+
export { initCommand, compileCommand, testCommand, agentsCommand, doctorCommand, methodCommand, mcpCommand, runsCommand, statusCommand, resetCommand, webCommand, prepCommand, loginCommand, logoutCommand, wizardCommand, };
|