@interf/compiler 0.9.4 → 0.13.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 (222) hide show
  1. package/README.md +96 -91
  2. package/TRADEMARKS.md +2 -13
  3. package/agent-skills/interf-actions/SKILL.md +97 -32
  4. package/agent-skills/interf-actions/references/cli.md +124 -71
  5. package/builtin-methods/interf-default/README.md +3 -4
  6. package/builtin-methods/interf-default/compile/stages/shape/SKILL.md +2 -2
  7. package/builtin-methods/interf-default/compile/stages/summarize/SKILL.md +2 -1
  8. package/builtin-methods/interf-default/improve/SKILL.md +1 -1
  9. package/builtin-methods/interf-default/method.json +10 -4
  10. package/builtin-methods/interf-default/method.schema.json +0 -9
  11. package/builtin-methods/interf-default/use/query/SKILL.md +5 -5
  12. package/dist/cli/commands/compile.d.ts +9 -31
  13. package/dist/cli/commands/compile.js +75 -388
  14. package/dist/cli/commands/doctor.js +1 -1
  15. package/dist/cli/commands/login.d.ts +7 -0
  16. package/dist/cli/commands/login.js +39 -0
  17. package/dist/cli/commands/logout.d.ts +2 -0
  18. package/dist/cli/commands/logout.js +16 -0
  19. package/dist/cli/commands/method.d.ts +2 -0
  20. package/dist/cli/commands/method.js +113 -0
  21. package/dist/cli/commands/prep.d.ts +2 -0
  22. package/dist/cli/commands/prep.js +134 -0
  23. package/dist/cli/commands/reset.d.ts +8 -1
  24. package/dist/cli/commands/reset.js +47 -15
  25. package/dist/cli/commands/runs.d.ts +2 -0
  26. package/dist/cli/commands/runs.js +120 -0
  27. package/dist/cli/commands/status.d.ts +6 -1
  28. package/dist/cli/commands/status.js +61 -220
  29. package/dist/cli/commands/test.d.ts +6 -15
  30. package/dist/cli/commands/test.js +63 -342
  31. package/dist/cli/commands/web.d.ts +0 -9
  32. package/dist/cli/commands/web.js +140 -367
  33. package/dist/cli/commands/wizard.d.ts +9 -0
  34. package/dist/cli/commands/wizard.js +442 -0
  35. package/dist/cli/index.d.ts +7 -6
  36. package/dist/cli/index.js +13 -10
  37. package/dist/compiler-ui/404.html +1 -1
  38. package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
  39. package/dist/compiler-ui/__next._full.txt +3 -3
  40. package/dist/compiler-ui/__next._head.txt +1 -1
  41. package/dist/compiler-ui/__next._index.txt +2 -2
  42. package/dist/compiler-ui/__next._tree.txt +2 -2
  43. package/dist/compiler-ui/_next/static/chunks/045gole2ojo3g.css +3 -0
  44. package/dist/compiler-ui/_next/static/chunks/17t-lulmyawg5.js +89 -0
  45. package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
  46. package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
  47. package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
  48. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
  49. package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
  50. package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
  51. package/dist/compiler-ui/_not-found.html +1 -1
  52. package/dist/compiler-ui/_not-found.txt +2 -2
  53. package/dist/compiler-ui/index.html +1 -1
  54. package/dist/compiler-ui/index.txt +3 -3
  55. package/dist/index.d.ts +0 -23
  56. package/dist/index.js +0 -16
  57. package/dist/packages/agents/lib/shells.d.ts +1 -1
  58. package/dist/packages/agents/lib/shells.js +113 -54
  59. package/dist/packages/agents/lib/user-config.d.ts +4 -2
  60. package/dist/packages/agents/lib/user-config.js +15 -7
  61. package/dist/packages/compiler/compiled-paths.d.ts +9 -2
  62. package/dist/packages/compiler/compiled-paths.js +30 -15
  63. package/dist/packages/compiler/compiled-pipeline.js +23 -3
  64. package/dist/packages/compiler/compiled-stage-plan.js +4 -0
  65. package/dist/packages/compiler/compiled-target.d.ts +1 -1
  66. package/dist/packages/compiler/compiled-target.js +1 -1
  67. package/dist/packages/compiler/index.d.ts +1 -0
  68. package/dist/packages/compiler/index.js +1 -0
  69. package/dist/packages/compiler/lib/schema.d.ts +27 -32
  70. package/dist/packages/compiler/lib/schema.js +2 -13
  71. package/dist/packages/compiler/method-runs.d.ts +2 -3
  72. package/dist/packages/compiler/method-runs.js +2 -3
  73. package/dist/packages/compiler/reset.js +3 -1
  74. package/dist/packages/compiler/runtime-contracts.js +0 -3
  75. package/dist/packages/compiler/runtime-prompt.js +1 -1
  76. package/dist/packages/compiler/source-files.d.ts +46 -0
  77. package/dist/packages/compiler/source-files.js +149 -0
  78. package/dist/packages/compiler/state-artifacts.d.ts +3 -2
  79. package/dist/packages/compiler/state-artifacts.js +4 -3
  80. package/dist/packages/compiler/state-io.d.ts +3 -2
  81. package/dist/packages/compiler/state-io.js +11 -5
  82. package/dist/packages/compiler/state-paths.d.ts +2 -1
  83. package/dist/packages/compiler/state-paths.js +6 -3
  84. package/dist/packages/compiler/state-view.d.ts +3 -2
  85. package/dist/packages/compiler/state-view.js +18 -28
  86. package/dist/packages/compiler/state.d.ts +4 -4
  87. package/dist/packages/compiler/state.js +3 -3
  88. package/dist/packages/contracts/index.d.ts +1 -1
  89. package/dist/packages/contracts/lib/preparation-paths.d.ts +117 -0
  90. package/dist/packages/contracts/lib/preparation-paths.js +177 -0
  91. package/dist/packages/contracts/lib/schema.d.ts +85 -6
  92. package/dist/packages/contracts/lib/schema.js +46 -2
  93. package/dist/packages/execution/lib/schema.d.ts +50 -57
  94. package/dist/packages/execution/lib/schema.js +1 -2
  95. package/dist/packages/local-service/action-definitions.d.ts +246 -0
  96. package/dist/packages/local-service/action-definitions.js +1147 -0
  97. package/dist/packages/local-service/action-planner.d.ts +9 -0
  98. package/dist/packages/local-service/action-planner.js +135 -0
  99. package/dist/packages/local-service/action-values.d.ts +1 -23
  100. package/dist/packages/local-service/action-values.js +1 -31
  101. package/dist/packages/local-service/client.d.ts +76 -46
  102. package/dist/packages/local-service/client.js +184 -149
  103. package/dist/packages/local-service/connection-config.d.ts +38 -0
  104. package/dist/packages/local-service/connection-config.js +75 -0
  105. package/dist/packages/local-service/index.d.ts +14 -7
  106. package/dist/packages/local-service/index.js +8 -4
  107. package/dist/packages/local-service/instance-paths.d.ts +100 -0
  108. package/dist/packages/local-service/instance-paths.js +165 -0
  109. package/dist/packages/local-service/lib/schema.d.ts +689 -2575
  110. package/dist/packages/local-service/lib/schema.js +260 -101
  111. package/dist/packages/local-service/native-run-handlers.d.ts +23 -0
  112. package/dist/{cli/commands/compile-controller.js → packages/local-service/native-run-handlers.js} +204 -20
  113. package/dist/packages/local-service/preparation-store.d.ts +92 -0
  114. package/dist/packages/local-service/preparation-store.js +171 -0
  115. package/dist/{cli/commands/check-draft.d.ts → packages/local-service/readiness-check-draft.d.ts} +2 -2
  116. package/dist/packages/local-service/routes.d.ts +33 -11
  117. package/dist/packages/local-service/routes.js +44 -15
  118. package/dist/packages/local-service/run-observability.js +25 -27
  119. package/dist/packages/local-service/runtime-caches.d.ts +76 -0
  120. package/dist/packages/local-service/runtime-caches.js +191 -0
  121. package/dist/packages/local-service/runtime-event-applier.d.ts +12 -0
  122. package/dist/packages/local-service/runtime-event-applier.js +177 -0
  123. package/dist/packages/local-service/runtime-persistence.d.ts +47 -0
  124. package/dist/packages/local-service/runtime-persistence.js +137 -0
  125. package/dist/packages/local-service/runtime-proposal-helpers.d.ts +35 -0
  126. package/dist/packages/local-service/runtime-proposal-helpers.js +251 -0
  127. package/dist/packages/local-service/runtime-resource-builders.d.ts +52 -0
  128. package/dist/packages/local-service/runtime-resource-builders.js +149 -0
  129. package/dist/packages/local-service/runtime.d.ts +201 -44
  130. package/dist/packages/local-service/runtime.js +1062 -1106
  131. package/dist/packages/local-service/server.d.ts +15 -0
  132. package/dist/packages/local-service/server.js +651 -233
  133. package/dist/packages/local-service/service-registry.d.ts +47 -0
  134. package/dist/packages/local-service/service-registry.js +137 -0
  135. package/dist/packages/method-authoring/method-authoring.d.ts +1 -1
  136. package/dist/packages/method-authoring/method-authoring.js +2 -2
  137. package/dist/packages/method-authoring/method-improvement.js +1 -1
  138. package/dist/packages/method-package/builtin-compiled-method.d.ts +4 -5
  139. package/dist/packages/method-package/builtin-compiled-method.js +8 -14
  140. package/dist/packages/method-package/context-interface.d.ts +4 -40
  141. package/dist/packages/method-package/context-interface.js +1 -23
  142. package/dist/packages/method-package/interf-method-package.d.ts +4 -4
  143. package/dist/packages/method-package/interf-method-package.js +21 -33
  144. package/dist/packages/method-package/local-methods.d.ts +10 -6
  145. package/dist/packages/method-package/local-methods.js +57 -39
  146. package/dist/packages/method-package/method-definitions.d.ts +8 -34
  147. package/dist/packages/method-package/method-definitions.js +49 -37
  148. package/dist/packages/method-package/method-helpers.d.ts +1 -13
  149. package/dist/packages/method-package/method-helpers.js +8 -42
  150. package/dist/packages/method-package/method-review-paths.d.ts +1 -1
  151. package/dist/packages/method-package/method-review-paths.js +5 -5
  152. package/dist/packages/method-package/method-stage-runner.js +2 -2
  153. package/dist/packages/method-package/user-methods.d.ts +17 -0
  154. package/dist/packages/method-package/user-methods.js +77 -0
  155. package/dist/packages/project-model/index.d.ts +1 -1
  156. package/dist/packages/project-model/index.js +1 -1
  157. package/dist/packages/project-model/interf-detect.d.ts +8 -3
  158. package/dist/packages/project-model/interf-detect.js +34 -34
  159. package/dist/packages/project-model/interf-scaffold.d.ts +3 -3
  160. package/dist/packages/project-model/interf-scaffold.js +23 -32
  161. package/dist/packages/project-model/lib/schema.js +38 -1
  162. package/dist/packages/project-model/preparation-entries.d.ts +11 -0
  163. package/dist/packages/project-model/preparation-entries.js +49 -0
  164. package/dist/packages/project-model/source-config.d.ts +11 -10
  165. package/dist/packages/project-model/source-config.js +83 -44
  166. package/dist/packages/project-model/source-folders.d.ts +5 -5
  167. package/dist/packages/project-model/source-folders.js +14 -14
  168. package/dist/packages/shared/filesystem.d.ts +7 -0
  169. package/dist/packages/shared/filesystem.js +97 -10
  170. package/dist/packages/testing/lib/schema.d.ts +12 -13
  171. package/dist/packages/testing/lib/schema.js +4 -5
  172. package/dist/packages/testing/readiness-check-run.d.ts +7 -7
  173. package/dist/packages/testing/readiness-check-run.js +46 -51
  174. package/dist/packages/testing/test-execution.js +6 -6
  175. package/dist/packages/testing/test-paths.js +4 -3
  176. package/dist/packages/testing/test-sandbox.d.ts +0 -1
  177. package/dist/packages/testing/test-sandbox.js +14 -30
  178. package/dist/packages/testing/test-targets.d.ts +1 -1
  179. package/dist/packages/testing/test-targets.js +6 -6
  180. package/dist/packages/testing/test.d.ts +1 -1
  181. package/dist/packages/testing/test.js +1 -1
  182. package/package.json +6 -26
  183. package/LICENSE +0 -183
  184. package/dist/cli/commands/compile-controller.d.ts +0 -17
  185. package/dist/cli/commands/compiled-flow.d.ts +0 -25
  186. package/dist/cli/commands/compiled-flow.js +0 -112
  187. package/dist/cli/commands/control-path.d.ts +0 -11
  188. package/dist/cli/commands/control-path.js +0 -72
  189. package/dist/cli/commands/create-method-wizard.d.ts +0 -76
  190. package/dist/cli/commands/create-method-wizard.js +0 -465
  191. package/dist/cli/commands/create.d.ts +0 -8
  192. package/dist/cli/commands/create.js +0 -189
  193. package/dist/cli/commands/default.d.ts +0 -2
  194. package/dist/cli/commands/default.js +0 -39
  195. package/dist/cli/commands/executor-flow.d.ts +0 -29
  196. package/dist/cli/commands/executor-flow.js +0 -163
  197. package/dist/cli/commands/init.d.ts +0 -11
  198. package/dist/cli/commands/init.js +0 -784
  199. package/dist/cli/commands/list.d.ts +0 -2
  200. package/dist/cli/commands/list.js +0 -30
  201. package/dist/cli/commands/preparation-selection.d.ts +0 -6
  202. package/dist/cli/commands/preparation-selection.js +0 -11
  203. package/dist/cli/commands/source-config-wizard.d.ts +0 -52
  204. package/dist/cli/commands/source-config-wizard.js +0 -680
  205. package/dist/cli/commands/test-flow.d.ts +0 -58
  206. package/dist/cli/commands/test-flow.js +0 -231
  207. package/dist/cli/commands/verify.d.ts +0 -2
  208. package/dist/cli/commands/verify.js +0 -94
  209. package/dist/compiler-ui/_next/static/chunks/0d~8t0zm6545p.js +0 -118
  210. package/dist/compiler-ui/_next/static/chunks/0xnel.ax9a.2c.css +0 -3
  211. package/dist/packages/compiler/raw-snapshot.d.ts +0 -49
  212. package/dist/packages/compiler/raw-snapshot.js +0 -101
  213. package/dist/packages/method-package/index.d.ts +0 -11
  214. package/dist/packages/method-package/index.js +0 -11
  215. package/dist/packages/method-package/method-stage-policy.d.ts +0 -5
  216. package/dist/packages/method-package/method-stage-policy.js +0 -31
  217. package/dist/packages/project-model/project-paths.d.ts +0 -12
  218. package/dist/packages/project-model/project-paths.js +0 -33
  219. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → C6vVfy3aeYuIO3d2AoNvC}/_buildManifest.js +0 -0
  220. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → C6vVfy3aeYuIO3d2AoNvC}/_clientMiddlewareManifest.js +0 -0
  221. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → C6vVfy3aeYuIO3d2AoNvC}/_ssgManifest.js +0 -0
  222. /package/dist/{cli/commands/check-draft.js → packages/local-service/readiness-check-draft.js} +0 -0
@@ -1,386 +1,159 @@
1
- import { existsSync, mkdirSync, readFileSync, } from "node:fs";
2
- import { join, resolve } from "node:path";
1
+ /**
2
+ * `interf web` start the engine in the foreground until Ctrl-C.
3
+ *
4
+ * interf web # start on default port; hard error if port busy
5
+ * interf web stop # send SIGTERM to the running engine
6
+ * interf web status # print engine info via the connected URL
7
+ *
8
+ * Pure server. No reuse / register-with-existing logic. Writes
9
+ * `~/.interf/connection.json` on startup so subsequent CLI commands can
10
+ * connect without a pointer file.
11
+ */
3
12
  import chalk from "chalk";
4
- import { resolveLocalExecutor, } from "../../packages/agents/lib/executors.js";
5
- import { ActionProposalPlanSchema, startLocalService, } from "../../packages/local-service/index.js";
6
- import { loadSourceFolderConfig, saveSourceFolderConfig, sourceFolderConfigPath, } from "../../packages/project-model/source-config.js";
7
- import { runConfiguredCompiledCompile, } from "./compile-controller.js";
8
- import { draftReadinessChecks, } from "./check-draft.js";
9
- import { runReadinessChecksForExecutor, } from "../../packages/testing/readiness-check-run.js";
10
- import { runMethodAuthoringDraft, } from "../../packages/method-authoring/method-authoring.js";
11
- import { PACKAGE_ROOT } from "../../packages/method-package/lib/package-root.js";
12
- import { seedLocalDefaultMethod } from "../../packages/method-package/local-methods.js";
13
- import { findNearestInterfInstanceConfig, hasInterfInstanceConfig, relativeSourceFolderPath, resolveInterfInstanceContext, } from "./control-path.js";
14
- import { listSourceFolderChoices, } from "../../packages/project-model/source-folders.js";
15
- import { methodIdForSourcePreparationConfig } from "../../packages/methods/method-resolution.js";
16
- export const webCommand = {
17
- command: "web",
18
- describe: "Start Interf UI and the local Interf API",
19
- builder: (yargs) => yargs
20
- .option("host", {
21
- type: "string",
22
- describe: "Host for the local Interf service",
23
- })
24
- .option("port", {
25
- type: "number",
26
- describe: "Port for the local Interf service",
27
- })
28
- .option("control-path", {
29
- type: "string",
30
- describe: "Folder where Interf stores local config, Methods, runs, and portable context",
31
- })
32
- .option("source-folder", {
33
- type: "string",
34
- describe: "Source Folder to prepare when initializing a new Interf Workspace",
35
- }),
36
- handler: async (argv) => {
37
- await runWebCommand(argv);
38
- },
39
- };
40
- function stringOption(value) {
41
- return typeof value === "string" && value.trim().length > 0
42
- ? value.trim()
43
- : undefined;
44
- }
45
- function numberOption(value) {
46
- if (typeof value !== "number" || !Number.isInteger(value))
13
+ import { readFileSync } from "node:fs";
14
+ import { LOCAL_SERVICE_DEFAULT_HOST, LOCAL_SERVICE_DEFAULT_PORT, buildLocalServiceUrl, } from "../../packages/local-service/routes.js";
15
+ import { startLocalService } from "../../packages/local-service/server.js";
16
+ import { createNativeLocalServiceRunHandlers } from "../../packages/local-service/native-run-handlers.js";
17
+ import { CONNECT_OR_ERROR_HINT, clearConnection, readActiveConnection, } from "../../packages/local-service/connection-config.js";
18
+ import { serviceRegistryPath } from "../../packages/local-service/instance-paths.js";
19
+ function packageVersionFromManifest() {
20
+ try {
21
+ const url = new URL("../../../package.json", import.meta.url);
22
+ const raw = readFileSync(url, "utf8");
23
+ const parsed = JSON.parse(raw);
24
+ return parsed.version;
25
+ }
26
+ catch {
47
27
  return undefined;
48
- return value;
28
+ }
29
+ }
30
+ function isPortInUseError(error) {
31
+ if (!error || typeof error !== "object")
32
+ return false;
33
+ const code = error.code;
34
+ return code === "EADDRINUSE";
49
35
  }
50
- function extractJsonObject(text) {
36
+ async function runWebForeground(args) {
37
+ const host = args.host ?? LOCAL_SERVICE_DEFAULT_HOST;
38
+ const port = args.port ?? LOCAL_SERVICE_DEFAULT_PORT;
39
+ let service;
51
40
  try {
52
- return JSON.parse(text);
41
+ service = await startLocalService({
42
+ host,
43
+ port,
44
+ packageVersion: packageVersionFromManifest(),
45
+ handlers: createNativeLocalServiceRunHandlers(),
46
+ });
53
47
  }
54
- catch {
55
- const match = text.match(/\{[\s\S]*\}/);
56
- if (!match)
57
- throw new Error("Planner did not write a JSON object.");
58
- return JSON.parse(match[0]);
48
+ catch (error) {
49
+ if (isPortInUseError(error)) {
50
+ console.error(chalk.red(`Error: another Interf engine is already running at ${buildLocalServiceUrl({ host, port })}.`));
51
+ console.error(`Stop it first with \`interf web stop\`.`);
52
+ process.exit(1);
53
+ }
54
+ throw error;
59
55
  }
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
+ const shutdown = async () => {
63
+ try {
64
+ await service.close();
65
+ }
66
+ catch {
67
+ // best effort
68
+ }
69
+ process.exit(0);
70
+ };
71
+ process.on("SIGINT", shutdown);
72
+ process.on("SIGTERM", shutdown);
73
+ await new Promise(() => {
74
+ /* block forever; signals trigger shutdown */
75
+ });
60
76
  }
61
- function readActionSkill() {
62
- const skillDir = join(PACKAGE_ROOT, "agent-skills", "interf-actions");
63
- const skillPath = join(skillDir, "SKILL.md");
64
- const cliReferencePath = join(skillDir, "references", "cli.md");
77
+ function findEnginePidByUrl(url) {
65
78
  try {
66
- const skill = readFileSync(skillPath, "utf8");
67
- const cliReference = readFileSync(cliReferencePath, "utf8");
68
- return [
69
- skill,
70
- "## Bundled reference: references/cli.md",
71
- cliReference,
72
- ].join("\n\n");
79
+ const raw = readFileSync(serviceRegistryPath(), "utf8");
80
+ const parsed = JSON.parse(raw);
81
+ const entry = parsed.services?.find((s) => s.url === url);
82
+ return entry?.pid ?? null;
73
83
  }
74
84
  catch {
75
- return [
76
- "# Interf Actions",
77
- "Use `interf --help`, `interf list`, `interf status`, and command-specific help as the source of truth.",
78
- "In Interf proposal mode, do not run CLI commands. Write the requested JSON proposal only.",
79
- ].join("\n\n");
85
+ return null;
80
86
  }
81
87
  }
82
- export function resolveWebProjectPaths(argv = {}, cwd = process.cwd()) {
83
- const currentPath = resolve(cwd);
84
- const configuredControlPath = stringOption(argv["control-path"]);
85
- const configuredSourceFolder = stringOption(argv["source-folder"]);
86
- if (configuredControlPath) {
87
- return {
88
- controlPath: resolve(currentPath, configuredControlPath),
89
- sourceFolderPath: configuredSourceFolder ? resolve(currentPath, configuredSourceFolder) : null,
90
- };
88
+ async function runWebStop(args) {
89
+ const conn = readActiveConnection({
90
+ urlOverride: args.url,
91
+ authTokenOverride: args.token,
92
+ });
93
+ if (!conn) {
94
+ console.error("No active Interf connection to stop.");
95
+ process.exit(1);
91
96
  }
92
- const existingControlPath = findNearestInterfInstanceConfig(currentPath);
93
- if (existingControlPath) {
94
- return {
95
- controlPath: existingControlPath,
96
- sourceFolderPath: configuredSourceFolder ? resolve(currentPath, configuredSourceFolder) : null,
97
- };
97
+ const url = conn.url.replace(/\/+$/, "");
98
+ const pid = findEnginePidByUrl(url);
99
+ if (!pid) {
100
+ console.error(`Could not locate engine PID for ${url}.`);
101
+ process.exit(1);
98
102
  }
99
- if (configuredSourceFolder) {
100
- const resolvedSourceFolder = resolve(currentPath, configuredSourceFolder);
101
- const context = resolveInterfInstanceContext(resolvedSourceFolder);
102
- return {
103
- controlPath: context.controlPath,
104
- sourceFolderPath: resolvedSourceFolder,
105
- };
103
+ try {
104
+ process.kill(pid, "SIGTERM");
105
+ console.log(chalk.green(`Sent SIGTERM to engine pid ${pid} (${url}).`));
106
+ clearConnection();
106
107
  }
107
- const context = resolveInterfInstanceContext(currentPath);
108
- return {
109
- controlPath: context.controlPath,
110
- sourceFolderPath: context.defaultSourceFolderPath ?? currentPath,
111
- };
112
- }
113
- export function ensureWebProjectInitialized(controlPath, options = {}) {
114
- const inferSourceFolderPath = () => {
115
- if (options.sourceFolderPath)
116
- return options.sourceFolderPath;
117
- const choices = listSourceFolderChoices(controlPath);
118
- return choices.length === 1 ? resolve(controlPath, choices[0]?.value ?? "") : null;
119
- };
120
- if (existsSync(sourceFolderConfigPath(controlPath))) {
121
- if (!hasInterfInstanceConfig(controlPath)) {
122
- throw new Error(`Interf Workspace path is not usable: ${sourceFolderConfigPath(controlPath)}. Choose a different --control-path.`);
123
- }
124
- const existing = loadSourceFolderConfig(controlPath);
125
- const sourceFolderPath = existing?.source_folder ? null : inferSourceFolderPath();
126
- if (existing && sourceFolderPath) {
127
- saveSourceFolderConfig(controlPath, {
128
- source_folder: {
129
- path: relativeSourceFolderPath(controlPath, sourceFolderPath),
130
- },
131
- preparations: existing.preparations ?? [],
132
- });
133
- }
134
- return;
108
+ catch (error) {
109
+ console.error(`Failed to stop engine pid ${pid}: ${error instanceof Error ? error.message : String(error)}`);
110
+ process.exit(1);
135
111
  }
136
- seedLocalDefaultMethod({ sourcePath: controlPath });
137
- const sourceFolderPath = inferSourceFolderPath();
138
- saveSourceFolderConfig(controlPath, {
139
- ...(sourceFolderPath
140
- ? {
141
- source_folder: {
142
- path: relativeSourceFolderPath(controlPath, sourceFolderPath),
143
- },
144
- }
145
- : {}),
146
- preparations: [],
147
- });
148
112
  }
149
- function buildActionPlannerPrompt(request, context, outputPath) {
150
- const actionSkill = readActionSkill();
151
- const preparations = context.preparations.map((preparation) => ({
152
- name: preparation.name,
153
- path: preparation.path,
154
- about: preparation.about ?? null,
155
- method: methodIdForSourcePreparationConfig(preparation),
156
- checks: preparation.checks?.length ?? 0,
157
- }));
158
- const recentProposals = context.recentProposals.map((proposal) => ({
159
- status: proposal.status,
160
- action_type: proposal.action_type,
161
- title: proposal.title,
162
- preparation: proposal.preparation ?? null,
163
- request: proposal.request,
164
- command_preview: proposal.command_preview ?? null,
165
- }));
166
- const sourceFolders = context.sourceFolders.map((folder) => ({
167
- path: folder.value,
168
- label: folder.label,
169
- hint: folder.hint,
170
- }));
171
- return `You are the local Interf action planner.
172
-
173
- User request:
174
- ${request.message}
175
-
176
- Selected Preparation hint: ${request.preparation ?? "(none)"}
177
-
178
- Structured request values:
179
- ${JSON.stringify(request.values ?? {}, null, 2)}
180
-
181
- Available Preparations:
182
- ${JSON.stringify(preparations, null, 2)}
183
-
184
- Visible Source Folders:
185
- ${JSON.stringify(sourceFolders, null, 2)}
186
-
187
- Action health:
188
- ${JSON.stringify(context.preparationHealth, null, 2)}
189
-
190
- Recent proposals, newest first. A short follow-up like "target source only" may be correcting the latest pending proposal:
191
- ${JSON.stringify(recentProposals, null, 2)}
192
-
193
- Interf action skill source:
194
- ${actionSkill}
195
-
196
- Use the Interf action skill source as the authority for CLI semantics and Interf proposal mode. Preserve user intent over defaults.
197
- Use Action health to avoid proposing work that cannot run yet. If can_check_readiness is false, prefer the recommended next actions; do not propose a generic readiness check unless the user explicitly asks for a source-files-only baseline.
198
- If the user is asking a question or making casual conversation, return "clarification" with a helpful assistant_message. Do not invent a CLI command for non-action chat.
199
- If a field does not apply, omit it instead of writing null or an empty string.
200
- Do not run any CLI command. Do not edit files except the output JSON file.
201
-
202
- Write only this JSON object to:
203
- ${outputPath}
204
-
205
- JSON schema:
206
- {
207
- "action_type": "preparation-setup" | "compile" | "test" | "readiness-check-draft" | "method-authoring" | "clarification",
208
- "preparation": "Preparation id if applicable",
209
- "method": "Method id if applicable",
210
- "values": {},
211
- "title": "short approval card title",
212
- "summary": "one sentence describing what will run",
213
- "assistant_message": "concise explanation for the user",
214
- "command_preview": "interf command the user is approving"
215
- }
216
- `;
217
- }
218
- export async function runWebCommand(argv = {}) {
219
- const { controlPath, sourceFolderPath } = resolveWebProjectPaths(argv);
220
- ensureWebProjectInitialized(controlPath, { sourceFolderPath });
221
- const handlers = {
222
- async planActionProposal(request, context) {
223
- const resolved = resolveLocalExecutor({ preflight: true });
224
- if (!resolved.executor) {
225
- return ActionProposalPlanSchema.parse({
226
- action_type: "clarification",
227
- preparation: request.preparation,
228
- assistant_message: resolved.error ?? "No local agent detected for action planning.",
229
- });
230
- }
231
- const planRoot = join(context.sourcePath, "interf", ".service", "action-plans", Date.now().toString(36));
232
- mkdirSync(planRoot, { recursive: true });
233
- const outputPath = join(planRoot, "proposal.json");
234
- const prompt = buildActionPlannerPrompt(request, context, outputPath);
235
- const exitCode = await resolved.executor.execute(context.sourcePath, prompt, {
236
- eventLogPath: join(planRoot, "planner.events.ndjson"),
237
- statusLogPath: join(planRoot, "planner.status.log"),
238
- completionCheck: () => existsSync(outputPath),
239
- });
240
- if (exitCode !== 0 && !existsSync(outputPath)) {
241
- return ActionProposalPlanSchema.parse({
242
- action_type: "clarification",
243
- preparation: request.preparation,
244
- assistant_message: `${resolved.executor.displayName} could not create a safe Interf proposal.`,
245
- });
246
- }
247
- try {
248
- return ActionProposalPlanSchema.parse(extractJsonObject(readFileSync(outputPath, "utf8")));
249
- }
250
- catch {
251
- return ActionProposalPlanSchema.parse({
252
- action_type: "clarification",
253
- preparation: request.preparation,
254
- assistant_message: "I can help with this Interf Workspace. Ask a question about Interf, or ask me to create a Preparation, prepare, check readiness, improve, or draft a Method and I will prepare an approval proposal.",
255
- });
256
- }
257
- },
258
- async createCompileRun(request, context) {
259
- const resolved = resolveLocalExecutor({ preflight: true });
260
- if (!resolved.executor) {
261
- throw new Error(resolved.error ?? "No local agent detected.");
262
- }
263
- const ok = await runConfiguredCompiledCompile({
264
- executor: resolved.executor,
265
- testExecutor: resolved.executor,
266
- compiledPath: context.compiledPath,
267
- sourcePath: context.sourcePath,
268
- compiledConfig: context.preparationConfig,
269
- maxAttemptsOverride: request.max_attempts ?? null,
270
- maxLoopsOverride: request.max_loops ?? null,
271
- preserveStageShells: request.preserve_stage_shells,
272
- runId: context.runId,
273
- events: context.events,
274
- });
275
- return { ok };
276
- },
277
- async createTestRun(request, context) {
278
- const resolved = resolveLocalExecutor({ preflight: true });
279
- if (!resolved.executor) {
280
- throw new Error(resolved.error ?? "No local agent detected.");
281
- }
282
- const result = await runReadinessChecksForExecutor({
283
- sourcePath: context.sourcePath,
284
- preparationConfig: context.preparationConfig,
285
- portableContextPath: context.compiledPath,
286
- mode: request.mode,
287
- executor: resolved.executor,
288
- });
289
- const missingSourceFiles = (request.mode === "raw" || request.mode === "both") && !result.rawOutcome;
290
- const missingPortableContext = (request.mode === "compiled" || request.mode === "both") && !result.compiledOutcome;
291
- if (missingSourceFiles || missingPortableContext) {
292
- return {
293
- ok: false,
294
- comparison: result.comparison,
295
- error: missingPortableContext
296
- ? "Portable Context is not ready for readiness checks."
297
- : "Source files are not ready for readiness checks.",
298
- };
299
- }
300
- return {
301
- ok: true,
302
- comparison: result.comparison,
303
- };
304
- },
305
- async createReadinessCheckDraft(request, context) {
306
- const resolved = resolveLocalExecutor({ preflight: true });
307
- if (!resolved.executor) {
308
- throw new Error(resolved.error ?? "No local agent detected.");
309
- }
310
- context.emit({
311
- type: "log.appended",
312
- step_id: "agent-draft",
313
- message: `Using ${resolved.executor.displayName} for readiness-check drafting.`,
314
- });
315
- const drafted = await draftReadinessChecks({
316
- preparationName: request.preparation,
317
- sourceFolderPath: request.source_folder_path,
318
- about: request.about,
319
- executor: resolved.executor,
320
- targetCount: request.target_count,
321
- onStatus: (line) => context.emit({
322
- type: "log.appended",
323
- step_id: "agent-draft",
324
- message: line,
325
- }),
326
- });
327
- if (!drafted.checks) {
328
- throw new Error(drafted.error ?? "Could not draft readiness checks from this Source Folder.");
329
- }
330
- return {
331
- checks: drafted.checks,
332
- };
333
- },
334
- async createMethodAuthoringRun(request, context) {
335
- const resolved = resolveLocalExecutor({ preflight: true });
336
- if (!resolved.executor) {
337
- throw new Error(resolved.error ?? "No local agent detected.");
338
- }
339
- context.emit({
340
- type: "log.appended",
341
- step_id: "draft-package",
342
- message: `Using ${resolved.executor.displayName} for Method authoring.`,
343
- });
344
- const result = await runMethodAuthoringDraft({
345
- sourcePath: context.sourcePath,
346
- sourceFolderPath: request.source_folder_path,
347
- baseMethodId: request.reference_method_id ?? request.base_method_id,
348
- methodId: request.method_id,
349
- label: request.label,
350
- hint: request.hint,
351
- taskPrompt: request.task_prompt,
352
- checks: request.checks,
353
- executor: resolved.executor,
354
- onStatus: (line) => context.emit({
355
- type: "log.appended",
356
- step_id: "draft-package",
357
- message: line,
358
- }),
359
- });
360
- return {
361
- status: result.status,
362
- changed: result.changed,
363
- summary: result.summary,
364
- validation: result.validation,
365
- method_path: result.methodPath,
366
- shell_path: result.shellPath,
367
- };
368
- },
369
- };
370
- const service = await startLocalService({
371
- rootPath: controlPath,
372
- host: stringOption(argv.host),
373
- port: numberOption(argv.port),
374
- handlers,
375
- });
376
- console.log(chalk.green(` Interf: ${service.url}/`));
377
- console.log(chalk.dim(` Health: ${service.url}/health`));
378
- console.log(chalk.dim(" Press Ctrl-C to stop the local Interf service."));
379
- await new Promise((resolve) => {
380
- const shutdown = () => {
381
- void service.close().finally(resolve);
382
- };
383
- process.once("SIGINT", shutdown);
384
- process.once("SIGTERM", shutdown);
113
+ async function runWebStatus(args) {
114
+ const conn = readActiveConnection({
115
+ urlOverride: args.url,
116
+ authTokenOverride: args.token,
385
117
  });
118
+ if (!conn) {
119
+ console.error(CONNECT_OR_ERROR_HINT);
120
+ process.exit(1);
121
+ }
122
+ const url = conn.url.replace(/\/+$/, "");
123
+ try {
124
+ const headers = new Headers();
125
+ if (conn.auth_token)
126
+ headers.set("authorization", `Bearer ${conn.auth_token}`);
127
+ const response = await fetch(`${url}/v1/instance`, { headers });
128
+ const raw = await response.text();
129
+ if (response.status !== 200) {
130
+ console.error(chalk.red(`Engine status request failed (HTTP ${response.status}).`));
131
+ if (raw)
132
+ console.error(raw);
133
+ process.exit(1);
134
+ }
135
+ console.log(raw);
136
+ }
137
+ catch (error) {
138
+ console.error(chalk.red(`Engine ${url} unreachable: ${error instanceof Error ? error.message : String(error)}`));
139
+ process.exit(1);
140
+ }
386
141
  }
142
+ export const webCommand = {
143
+ command: "web [subcommand]",
144
+ describe: "Start / stop / inspect the Interf engine",
145
+ builder: (yargs) => yargs
146
+ .command("stop", "Stop the connected engine", (y) => y
147
+ .option("url", { type: "string", describe: "Override the active connection URL" })
148
+ .option("token", { type: "string", describe: "Override the active bearer token" }), runWebStop)
149
+ .command("status", "Show engine status via the connected URL", (y) => y
150
+ .option("url", { type: "string", describe: "Override the active connection URL" })
151
+ .option("token", { type: "string", describe: "Override the active bearer token" }), runWebStatus)
152
+ .command("$0", "Start the engine in the foreground (default)", (y) => y
153
+ .option("host", { type: "string", default: LOCAL_SERVICE_DEFAULT_HOST, describe: "Host to bind" })
154
+ .option("port", { type: "number", default: LOCAL_SERVICE_DEFAULT_PORT, describe: "Port to bind" }), runWebForeground)
155
+ .strict(),
156
+ handler: () => {
157
+ /* yargs subcommand handlers do the work */
158
+ },
159
+ };
@@ -0,0 +1,9 @@
1
+ import type { CommandModule } from "yargs";
2
+ interface WizardArgs {
3
+ url?: string;
4
+ token?: string;
5
+ }
6
+ export declare const wizardCommand: CommandModule<unknown, WizardArgs>;
7
+ /** Alias: `interf init` runs the same wizard. */
8
+ export declare const initCommand: CommandModule<unknown, WizardArgs>;
9
+ export {};