@interf/compiler 0.13.0 → 0.18.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 (320) hide show
  1. package/LICENSE.md +1 -0
  2. package/README.md +50 -7
  3. package/TRADEMARKS.md +4 -4
  4. package/agent-skills/interf-actions/SKILL.md +51 -5
  5. package/agent-skills/interf-actions/references/cli.md +82 -82
  6. package/builtin-methods/interf-default/README.md +6 -7
  7. package/builtin-methods/interf-default/method.json +7 -68
  8. package/builtin-methods/interf-default/method.schema.json +52 -50
  9. package/dist/cli/commands/agents.d.ts +2 -0
  10. package/dist/cli/commands/agents.js +213 -0
  11. package/dist/cli/commands/compile.js +10 -1
  12. package/dist/cli/commands/doctor.js +1 -1
  13. package/dist/cli/commands/login.js +1 -1
  14. package/dist/cli/commands/logout.js +1 -1
  15. package/dist/cli/commands/mcp.d.ts +42 -0
  16. package/dist/cli/commands/mcp.js +239 -0
  17. package/dist/cli/commands/method.js +1 -1
  18. package/dist/cli/commands/prep.js +81 -7
  19. package/dist/cli/commands/reset.js +1 -1
  20. package/dist/cli/commands/runs.js +1 -1
  21. package/dist/cli/commands/status.js +1 -1
  22. package/dist/cli/commands/verify.d.ts +10 -0
  23. package/dist/cli/commands/{test.js → verify.js} +30 -15
  24. package/dist/cli/commands/web.js +71 -18
  25. package/dist/cli/commands/wizard.js +462 -107
  26. package/dist/cli/index.d.ts +4 -2
  27. package/dist/cli/index.js +7 -3
  28. package/dist/compiler-ui/404.html +1 -1
  29. package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
  30. package/dist/compiler-ui/__next._full.txt +3 -3
  31. package/dist/compiler-ui/__next._head.txt +1 -1
  32. package/dist/compiler-ui/__next._index.txt +2 -2
  33. package/dist/compiler-ui/__next._tree.txt +2 -2
  34. package/dist/compiler-ui/_next/static/chunks/{045gole2ojo3g.css → 0_c_tvh-cukjz.css} +1 -1
  35. package/dist/compiler-ui/_next/static/chunks/0f_geuwdesg_c.js +114 -0
  36. package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
  37. package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
  38. package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
  39. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
  40. package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
  41. package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
  42. package/dist/compiler-ui/_not-found.html +1 -1
  43. package/dist/compiler-ui/_not-found.txt +2 -2
  44. package/dist/compiler-ui/index.html +1 -1
  45. package/dist/compiler-ui/index.txt +3 -3
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.js +2 -2
  48. package/dist/packages/contracts/index.d.ts +2 -1
  49. package/dist/packages/contracts/index.js +1 -0
  50. package/dist/packages/contracts/lib/schema.d.ts +324 -31
  51. package/dist/packages/contracts/lib/schema.js +281 -21
  52. package/dist/packages/{local-service → engine}/action-definitions.js +9 -2
  53. package/dist/packages/{local-service → engine}/action-planner.d.ts +1 -1
  54. package/dist/packages/{local-service → engine}/action-planner.js +1 -1
  55. package/dist/packages/{agents → engine/agents}/index.d.ts +3 -0
  56. package/dist/packages/{agents → engine/agents}/index.js +3 -0
  57. package/dist/packages/{agents → engine/agents}/lib/compiled-bootstrap.js +2 -2
  58. package/dist/packages/engine/agents/lib/detection.d.ts +13 -0
  59. package/dist/packages/{agents → engine/agents}/lib/detection.js +11 -0
  60. package/dist/packages/{agents → engine/agents}/lib/executors.d.ts +2 -2
  61. package/dist/packages/{agents → engine/agents}/lib/shells.d.ts +14 -6
  62. package/dist/packages/{agents → engine/agents}/lib/shells.js +133 -126
  63. package/dist/packages/{agents → engine/agents}/lib/user-config.js +2 -2
  64. package/dist/packages/engine/agents/registry.d.ts +91 -0
  65. package/dist/packages/engine/agents/registry.js +321 -0
  66. package/dist/packages/engine/agents/role-executors.d.ts +35 -0
  67. package/dist/packages/engine/agents/role-executors.js +88 -0
  68. package/dist/packages/engine/agents/role-router.d.ts +66 -0
  69. package/dist/packages/engine/agents/role-router.js +73 -0
  70. package/dist/packages/{local-service → engine}/client.d.ts +9 -9
  71. package/dist/packages/{local-service → engine}/client.js +11 -11
  72. package/dist/packages/engine/cloud-seams.d.ts +115 -0
  73. package/dist/packages/engine/cloud-seams.js +84 -0
  74. package/dist/packages/engine/compile/artifact-counts.d.ts +1 -0
  75. package/dist/packages/{compiler → engine/compile}/artifact-counts.js +4 -4
  76. package/dist/packages/engine/compile/artifact-status.d.ts +41 -0
  77. package/dist/packages/engine/compile/artifact-status.js +166 -0
  78. package/dist/packages/engine/compile/billing-events.d.ts +89 -0
  79. package/dist/packages/engine/compile/billing-events.js +74 -0
  80. package/dist/packages/engine/compile/check-evaluator.d.ts +66 -0
  81. package/dist/packages/engine/compile/check-evaluator.js +298 -0
  82. package/dist/packages/{compiler → engine/compile}/compiled-pipeline.d.ts +12 -1
  83. package/dist/packages/{compiler → engine/compile}/compiled-pipeline.js +16 -6
  84. package/dist/packages/engine/compile/compiled-schema.d.ts +21 -0
  85. package/dist/packages/engine/compile/compiled-schema.js +126 -0
  86. package/dist/packages/{compiler → engine/compile}/compiled-stage-plan.d.ts +2 -1
  87. package/dist/packages/{compiler → engine/compile}/compiled-stage-plan.js +35 -18
  88. package/dist/packages/{compiler → engine/compile}/compiled-stage-runner.d.ts +1 -1
  89. package/dist/packages/{compiler → engine/compile}/compiled-stage-runner.js +4 -4
  90. package/dist/packages/{compiler → engine/compile}/compiled-target.d.ts +2 -2
  91. package/dist/packages/{compiler → engine/compile}/compiled-target.js +2 -2
  92. package/dist/packages/{compiler → engine/compile}/discovery.js +1 -1
  93. package/dist/packages/{compiler → engine/compile}/index.d.ts +0 -1
  94. package/dist/packages/{compiler → engine/compile}/index.js +0 -1
  95. package/dist/packages/{compiler → engine/compile}/lib/schema.d.ts +113 -94
  96. package/dist/packages/{compiler → engine/compile}/lib/schema.js +35 -39
  97. package/dist/packages/engine/compile/method-primitives.d.ts +2 -0
  98. package/dist/packages/{compiler → engine/compile}/method-primitives.js +1 -1
  99. package/dist/packages/{compiler → engine/compile}/method-runs.d.ts +3 -3
  100. package/dist/packages/{compiler → engine/compile}/method-runs.js +3 -3
  101. package/dist/packages/{compiler → engine/compile}/reset.js +4 -4
  102. package/dist/packages/{compiler → engine/compile}/runtime-contracts.js +2 -1
  103. package/dist/packages/{compiler → engine/compile}/runtime-prompt.js +3 -2
  104. package/dist/packages/{compiler → engine/compile}/runtime-reconcile.d.ts +1 -1
  105. package/dist/packages/{compiler → engine/compile}/runtime-reconcile.js +47 -45
  106. package/dist/packages/{compiler → engine/compile}/runtime-runs.d.ts +1 -2
  107. package/dist/packages/{compiler → engine/compile}/runtime-runs.js +3 -44
  108. package/dist/packages/{compiler → engine/compile}/runtime-types.d.ts +7 -12
  109. package/dist/packages/engine/compile/runtime.d.ts +5 -0
  110. package/dist/packages/{compiler → engine/compile}/runtime.js +1 -2
  111. package/dist/packages/{compiler → engine/compile}/source-files.d.ts +1 -1
  112. package/dist/packages/{compiler → engine/compile}/source-files.js +3 -3
  113. package/dist/packages/{compiler → engine/compile}/state-health.js +8 -8
  114. package/dist/packages/{compiler → engine/compile}/state-io.js +2 -2
  115. package/dist/packages/{compiler → engine/compile}/state-view.js +9 -8
  116. package/dist/packages/{compiler → engine/compile}/validate-compiled.js +63 -32
  117. package/dist/packages/{compiler → engine/compile}/validate.d.ts +1 -1
  118. package/dist/packages/{compiler → engine/compile}/validate.js +29 -27
  119. package/dist/packages/{execution → engine/execution}/lib/schema.d.ts +81 -55
  120. package/dist/packages/{execution → engine/execution}/lib/schema.js +14 -6
  121. package/dist/packages/engine/index.d.ts +22 -0
  122. package/dist/packages/engine/index.js +15 -0
  123. package/dist/packages/{local-service → engine}/lib/schema.d.ts +620 -435
  124. package/dist/packages/{local-service → engine}/lib/schema.js +103 -63
  125. package/dist/packages/{local-service → engine}/native-run-handlers.d.ts +7 -5
  126. package/dist/packages/{local-service → engine}/native-run-handlers.js +81 -29
  127. package/dist/packages/{local-service → engine}/preparation-store.d.ts +22 -4
  128. package/dist/packages/{local-service → engine}/preparation-store.js +56 -25
  129. package/dist/packages/{local-service → engine}/readiness-check-draft.d.ts +2 -2
  130. package/dist/packages/{local-service → engine}/routes.d.ts +36 -1
  131. package/dist/packages/{local-service → engine}/routes.js +38 -1
  132. package/dist/packages/{local-service → engine}/run-observability.d.ts +3 -3
  133. package/dist/packages/{local-service → engine}/run-observability.js +15 -15
  134. package/dist/packages/{local-service → engine}/runtime-event-applier.d.ts +1 -1
  135. package/dist/packages/{local-service → engine}/runtime-event-applier.js +7 -0
  136. package/dist/packages/{local-service → engine}/runtime-persistence.d.ts +6 -6
  137. package/dist/packages/{local-service → engine}/runtime-persistence.js +9 -9
  138. package/dist/packages/{local-service → engine}/runtime-proposal-helpers.d.ts +1 -1
  139. package/dist/packages/{local-service → engine}/runtime-proposal-helpers.js +5 -5
  140. package/dist/packages/{local-service → engine}/runtime-resource-builders.d.ts +12 -12
  141. package/dist/packages/{local-service → engine}/runtime-resource-builders.js +6 -5
  142. package/dist/packages/{local-service → engine}/runtime.d.ts +147 -56
  143. package/dist/packages/{local-service → engine}/runtime.js +333 -205
  144. package/dist/packages/{local-service → engine}/server.d.ts +25 -0
  145. package/dist/packages/{local-service → engine}/server.js +338 -17
  146. package/dist/packages/engine/verify/index.d.ts +13 -0
  147. package/dist/packages/engine/verify/index.js +10 -0
  148. package/dist/packages/{testing → engine/verify}/lib/schema.d.ts +1 -1
  149. package/dist/packages/{testing → engine/verify}/lib/schema.js +1 -1
  150. package/dist/packages/{testing → engine/verify}/readiness-check-run.d.ts +27 -11
  151. package/dist/packages/{testing → engine/verify}/readiness-check-run.js +72 -60
  152. package/dist/packages/{testing/test-execution.d.ts → engine/verify/verify-execution.d.ts} +2 -2
  153. package/dist/packages/{testing/test-execution.js → engine/verify/verify-execution.js} +2 -2
  154. package/dist/packages/{testing/test-paths.d.ts → engine/verify/verify-paths.d.ts} +1 -1
  155. package/dist/packages/{testing/test-paths.js → engine/verify/verify-paths.js} +2 -2
  156. package/dist/packages/{testing/test-sandbox.d.ts → engine/verify/verify-sandbox.d.ts} +1 -1
  157. package/dist/packages/{testing/test-sandbox.js → engine/verify/verify-sandbox.js} +6 -6
  158. package/dist/packages/{testing/test-specs.d.ts → engine/verify/verify-specs.d.ts} +1 -1
  159. package/dist/packages/{testing/test-specs.js → engine/verify/verify-specs.js} +2 -2
  160. package/dist/packages/{testing/test-targets.d.ts → engine/verify/verify-targets.d.ts} +1 -1
  161. package/dist/packages/{testing/test-targets.js → engine/verify/verify-targets.js} +3 -3
  162. package/dist/packages/{testing/test.d.ts → engine/verify/verify.d.ts} +4 -4
  163. package/dist/packages/{testing/test.js → engine/verify/verify.js} +3 -3
  164. package/dist/packages/engine/wire-schemas.d.ts +545 -0
  165. package/dist/packages/engine/wire-schemas.js +59 -0
  166. package/dist/packages/methods/authoring/method-authoring.d.ts +34 -0
  167. package/dist/packages/methods/authoring/method-authoring.js +260 -0
  168. package/dist/packages/{method-authoring → methods/authoring}/method-edit-session.d.ts +2 -2
  169. package/dist/packages/{method-authoring → methods/authoring}/method-edit-session.js +5 -5
  170. package/dist/packages/{method-authoring → methods/authoring}/method-improvement.d.ts +4 -4
  171. package/dist/packages/{method-authoring → methods/authoring}/method-improvement.js +16 -10
  172. package/dist/packages/{method-package → methods/package}/builtin-compiled-method.d.ts +12 -12
  173. package/dist/packages/{method-package → methods/package}/builtin-compiled-method.js +27 -24
  174. package/dist/packages/methods/package/context-interface.d.ts +73 -0
  175. package/dist/packages/{method-package → methods/package}/context-interface.js +50 -41
  176. package/dist/packages/{method-package → methods/package}/interf-method-package.js +31 -49
  177. package/dist/packages/{method-package → methods/package}/lib/package-root.js +2 -2
  178. package/dist/packages/{method-package → methods/package}/local-methods.d.ts +10 -5
  179. package/dist/packages/{method-package → methods/package}/local-methods.js +41 -68
  180. package/dist/packages/{method-package → methods/package}/method-definitions.d.ts +11 -7
  181. package/dist/packages/{method-package → methods/package}/method-definitions.js +5 -8
  182. package/dist/packages/{method-package → methods/package}/method-helpers.d.ts +1 -3
  183. package/dist/packages/{method-package → methods/package}/method-helpers.js +4 -8
  184. package/dist/packages/{method-package → methods/package}/method-review-paths.d.ts +1 -1
  185. package/dist/packages/{method-package → methods/package}/method-review-paths.js +1 -1
  186. package/dist/packages/{method-package → methods/package}/method-stage-runner.d.ts +4 -9
  187. package/dist/packages/{method-package → methods/package}/method-stage-runner.js +1 -29
  188. package/dist/packages/{method-package → methods/package}/user-methods.js +2 -2
  189. package/dist/packages/{project-model → project}/interf-bootstrap.d.ts +1 -1
  190. package/dist/packages/{project-model → project}/interf-bootstrap.js +1 -1
  191. package/dist/packages/{project-model → project}/interf-detect.js +4 -4
  192. package/dist/packages/{project-model → project}/interf-scaffold.js +18 -18
  193. package/dist/packages/{project-model → project}/lib/schema.d.ts +2 -2
  194. package/dist/packages/{project-model → project}/lib/schema.js +1 -1
  195. package/dist/packages/{project-model → project}/source-config.d.ts +1 -1
  196. package/dist/packages/{project-model → project}/source-config.js +9 -8
  197. package/dist/packages/{project-model → project}/source-folders.js +2 -2
  198. package/package.json +7 -16
  199. package/dist/cli/commands/test.d.ts +0 -9
  200. package/dist/compiler-ui/_next/static/chunks/17t-lulmyawg5.js +0 -89
  201. package/dist/packages/agents/lib/detection.d.ts +0 -7
  202. package/dist/packages/compiler/artifact-counts.d.ts +0 -1
  203. package/dist/packages/compiler/compiled-schema.d.ts +0 -31
  204. package/dist/packages/compiler/compiled-schema.js +0 -141
  205. package/dist/packages/compiler/method-primitives.d.ts +0 -2
  206. package/dist/packages/compiler/runtime-acceptance.d.ts +0 -9
  207. package/dist/packages/compiler/runtime-acceptance.js +0 -262
  208. package/dist/packages/compiler/runtime.d.ts +0 -6
  209. package/dist/packages/local-service/index.d.ts +0 -22
  210. package/dist/packages/local-service/index.js +0 -15
  211. package/dist/packages/method-authoring/method-authoring.d.ts +0 -24
  212. package/dist/packages/method-authoring/method-authoring.js +0 -116
  213. package/dist/packages/method-package/context-interface.d.ts +0 -60
  214. package/dist/packages/testing/index.d.ts +0 -13
  215. package/dist/packages/testing/index.js +0 -10
  216. /package/dist/compiler-ui/_next/static/{C6vVfy3aeYuIO3d2AoNvC → 6qyE1u9m_oBUkvAhhoCmO}/_buildManifest.js +0 -0
  217. /package/dist/compiler-ui/_next/static/{C6vVfy3aeYuIO3d2AoNvC → 6qyE1u9m_oBUkvAhhoCmO}/_clientMiddlewareManifest.js +0 -0
  218. /package/dist/compiler-ui/_next/static/{C6vVfy3aeYuIO3d2AoNvC → 6qyE1u9m_oBUkvAhhoCmO}/_ssgManifest.js +0 -0
  219. /package/dist/packages/{shared → contracts/utils}/file-types.d.ts +0 -0
  220. /package/dist/packages/{shared → contracts/utils}/file-types.js +0 -0
  221. /package/dist/packages/{shared → contracts/utils}/filesystem.d.ts +0 -0
  222. /package/dist/packages/{shared → contracts/utils}/filesystem.js +0 -0
  223. /package/dist/packages/{shared → contracts/utils}/logger.d.ts +0 -0
  224. /package/dist/packages/{shared → contracts/utils}/logger.js +0 -0
  225. /package/dist/packages/{shared → contracts/utils}/naming.d.ts +0 -0
  226. /package/dist/packages/{shared → contracts/utils}/naming.js +0 -0
  227. /package/dist/packages/{shared → contracts/utils}/parse.d.ts +0 -0
  228. /package/dist/packages/{shared → contracts/utils}/parse.js +0 -0
  229. /package/dist/packages/{shared → contracts/utils}/path-guards.d.ts +0 -0
  230. /package/dist/packages/{shared → contracts/utils}/path-guards.js +0 -0
  231. /package/dist/packages/{local-service → engine}/action-definitions.d.ts +0 -0
  232. /package/dist/packages/{local-service → engine}/action-values.d.ts +0 -0
  233. /package/dist/packages/{local-service → engine}/action-values.js +0 -0
  234. /package/dist/packages/{agents → engine/agents}/lib/agents.d.ts +0 -0
  235. /package/dist/packages/{agents → engine/agents}/lib/agents.js +0 -0
  236. /package/dist/packages/{agents → engine/agents}/lib/args.d.ts +0 -0
  237. /package/dist/packages/{agents → engine/agents}/lib/args.js +0 -0
  238. /package/dist/packages/{agents → engine/agents}/lib/chart-guidance.d.ts +0 -0
  239. /package/dist/packages/{agents → engine/agents}/lib/chart-guidance.js +0 -0
  240. /package/dist/packages/{agents → engine/agents}/lib/compiled-bootstrap.d.ts +0 -0
  241. /package/dist/packages/{agents → engine/agents}/lib/constants.d.ts +0 -0
  242. /package/dist/packages/{agents → engine/agents}/lib/constants.js +0 -0
  243. /package/dist/packages/{agents → engine/agents}/lib/execution-profile.d.ts +0 -0
  244. /package/dist/packages/{agents → engine/agents}/lib/execution-profile.js +0 -0
  245. /package/dist/packages/{agents → engine/agents}/lib/execution.d.ts +0 -0
  246. /package/dist/packages/{agents → engine/agents}/lib/execution.js +0 -0
  247. /package/dist/packages/{agents → engine/agents}/lib/executors.js +0 -0
  248. /package/dist/packages/{agents → engine/agents}/lib/logs.d.ts +0 -0
  249. /package/dist/packages/{agents → engine/agents}/lib/logs.js +0 -0
  250. /package/dist/packages/{agents → engine/agents}/lib/preflight.d.ts +0 -0
  251. /package/dist/packages/{agents → engine/agents}/lib/preflight.js +0 -0
  252. /package/dist/packages/{agents → engine/agents}/lib/render.d.ts +0 -0
  253. /package/dist/packages/{agents → engine/agents}/lib/render.js +0 -0
  254. /package/dist/packages/{agents → engine/agents}/lib/schema.d.ts +0 -0
  255. /package/dist/packages/{agents → engine/agents}/lib/schema.js +0 -0
  256. /package/dist/packages/{agents → engine/agents}/lib/status.d.ts +0 -0
  257. /package/dist/packages/{agents → engine/agents}/lib/status.js +0 -0
  258. /package/dist/packages/{agents → engine/agents}/lib/types.d.ts +0 -0
  259. /package/dist/packages/{agents → engine/agents}/lib/types.js +0 -0
  260. /package/dist/packages/{agents → engine/agents}/lib/user-config.d.ts +0 -0
  261. /package/dist/packages/{compiler → engine/compile}/compiled-compile.d.ts +0 -0
  262. /package/dist/packages/{compiler → engine/compile}/compiled-compile.js +0 -0
  263. /package/dist/packages/{compiler → engine/compile}/compiled-paths.d.ts +0 -0
  264. /package/dist/packages/{compiler → engine/compile}/compiled-paths.js +0 -0
  265. /package/dist/packages/{compiler → engine/compile}/discovery.d.ts +0 -0
  266. /package/dist/packages/{compiler → engine/compile}/reset.d.ts +0 -0
  267. /package/dist/packages/{compiler → engine/compile}/runtime-contracts.d.ts +0 -0
  268. /package/dist/packages/{compiler → engine/compile}/runtime-inventory.d.ts +0 -0
  269. /package/dist/packages/{compiler → engine/compile}/runtime-inventory.js +0 -0
  270. /package/dist/packages/{compiler → engine/compile}/runtime-paths.d.ts +0 -0
  271. /package/dist/packages/{compiler → engine/compile}/runtime-paths.js +0 -0
  272. /package/dist/packages/{compiler → engine/compile}/runtime-prompt.d.ts +0 -0
  273. /package/dist/packages/{compiler → engine/compile}/runtime-types.js +0 -0
  274. /package/dist/packages/{compiler → engine/compile}/state-artifacts.d.ts +0 -0
  275. /package/dist/packages/{compiler → engine/compile}/state-artifacts.js +0 -0
  276. /package/dist/packages/{compiler → engine/compile}/state-health.d.ts +0 -0
  277. /package/dist/packages/{compiler → engine/compile}/state-io.d.ts +0 -0
  278. /package/dist/packages/{compiler → engine/compile}/state-paths.d.ts +0 -0
  279. /package/dist/packages/{compiler → engine/compile}/state-paths.js +0 -0
  280. /package/dist/packages/{compiler → engine/compile}/state-view.d.ts +0 -0
  281. /package/dist/packages/{compiler → engine/compile}/state.d.ts +0 -0
  282. /package/dist/packages/{compiler → engine/compile}/state.js +0 -0
  283. /package/dist/packages/{compiler → engine/compile}/validate-compiled.d.ts +0 -0
  284. /package/dist/packages/{compiler → engine/compile}/validate-helpers.d.ts +0 -0
  285. /package/dist/packages/{compiler → engine/compile}/validate-helpers.js +0 -0
  286. /package/dist/packages/{local-service → engine}/connection-config.d.ts +0 -0
  287. /package/dist/packages/{local-service → engine}/connection-config.js +0 -0
  288. /package/dist/packages/{execution → engine/execution}/adapters.d.ts +0 -0
  289. /package/dist/packages/{execution → engine/execution}/adapters.js +0 -0
  290. /package/dist/packages/{execution → engine/execution}/events.d.ts +0 -0
  291. /package/dist/packages/{execution → engine/execution}/events.js +0 -0
  292. /package/dist/packages/{execution → engine/execution}/index.d.ts +0 -0
  293. /package/dist/packages/{execution → engine/execution}/index.js +0 -0
  294. /package/dist/packages/{local-service → engine}/instance-paths.d.ts +0 -0
  295. /package/dist/packages/{local-service → engine}/instance-paths.js +0 -0
  296. /package/dist/packages/{local-service → engine}/readiness-check-draft.js +0 -0
  297. /package/dist/packages/{local-service → engine}/runtime-caches.d.ts +0 -0
  298. /package/dist/packages/{local-service → engine}/runtime-caches.js +0 -0
  299. /package/dist/packages/{local-service → engine}/service-registry.d.ts +0 -0
  300. /package/dist/packages/{local-service → engine}/service-registry.js +0 -0
  301. /package/dist/packages/{testing/test-profile-presets.d.ts → engine/verify/verify-profile-presets.d.ts} +0 -0
  302. /package/dist/packages/{testing/test-profile-presets.js → engine/verify/verify-profile-presets.js} +0 -0
  303. /package/dist/packages/{testing/test-types.d.ts → engine/verify/verify-types.d.ts} +0 -0
  304. /package/dist/packages/{testing/test-types.js → engine/verify/verify-types.js} +0 -0
  305. /package/dist/packages/{method-authoring → methods/authoring}/index.d.ts +0 -0
  306. /package/dist/packages/{method-authoring → methods/authoring}/index.js +0 -0
  307. /package/dist/packages/{method-authoring → methods/authoring}/lib/method-edit-utils.d.ts +0 -0
  308. /package/dist/packages/{method-authoring → methods/authoring}/lib/method-edit-utils.js +0 -0
  309. /package/dist/packages/{method-package → methods/package}/interf-method-package.d.ts +0 -0
  310. /package/dist/packages/{method-package → methods/package}/lib/package-root.d.ts +0 -0
  311. /package/dist/packages/{method-package → methods/package}/user-methods.d.ts +0 -0
  312. /package/dist/packages/{project-model → project}/index.d.ts +0 -0
  313. /package/dist/packages/{project-model → project}/index.js +0 -0
  314. /package/dist/packages/{project-model → project}/interf-detect.d.ts +0 -0
  315. /package/dist/packages/{project-model → project}/interf-scaffold.d.ts +0 -0
  316. /package/dist/packages/{project-model → project}/interf.d.ts +0 -0
  317. /package/dist/packages/{project-model → project}/interf.js +0 -0
  318. /package/dist/packages/{project-model → project}/preparation-entries.d.ts +0 -0
  319. /package/dist/packages/{project-model → project}/preparation-entries.js +0 -0
  320. /package/dist/packages/{project-model → project}/source-folders.d.ts +0 -0
@@ -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 → offer to start a local engine inline (or connect remote, or quit).
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,8 +16,8 @@ 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 { CONNECT_OR_ERROR_HINT, readActiveConnection, writeConnection, } from "../../packages/local-service/connection-config.js";
19
- import { LOCAL_SERVICE_DEFAULT_HOST, LOCAL_SERVICE_DEFAULT_PORT } from "../../packages/local-service/routes.js";
19
+ import { ConnectionRecordSchema, readActiveConnection, writeConnection, } from "../../packages/engine/connection-config.js";
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();
22
23
  if (token)
@@ -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
@@ -61,12 +74,25 @@ async function probeHealth(url) {
61
74
  }
62
75
  }
63
76
  /**
64
- * Spawn `interf web` detached and wait until it's reachable. Tries two
65
- * signals in parallel: the new `~/.interf/connection.json` record AND a
66
- * direct probe of the default engine URL — so we can connect even when
67
- * the running engine is an older binary that didn't write the record.
77
+ * Connect to an engine. Either an existing one already running on the
78
+ * default port (with a `wasAlreadyRunning` flag so the caller can tell
79
+ * the user honestly) or a fresh one we spawn here.
80
+ *
81
+ * Returns null on timeout / error.
68
82
  */
69
83
  async function startLocalEngineInBackground() {
84
+ // First: check whether an engine is ALREADY running on the default
85
+ // port. If so, don't pretend to start a new one — just connect.
86
+ if (await probeHealth(DEFAULT_ENGINE_URL)) {
87
+ try {
88
+ writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
89
+ }
90
+ catch {
91
+ // best effort
92
+ }
93
+ console.log(chalk.dim(` Engine already running at ${DEFAULT_ENGINE_URL} — connecting.`));
94
+ return { url: DEFAULT_ENGINE_URL, token: null, wasAlreadyRunning: true };
95
+ }
70
96
  const spinner = p.spinner();
71
97
  spinner.start("Starting local Interf engine…");
72
98
  const child = spawn(process.argv[1] ?? "interf", ["web"], {
@@ -78,105 +104,110 @@ async function startLocalEngineInBackground() {
78
104
  const timeoutMs = 30_000;
79
105
  while (Date.now() - startedAt < timeoutMs) {
80
106
  await new Promise((r) => setTimeout(r, 250));
81
- // Path A: connection.json written by 0.13 server.
107
+ // Path A: connection.json written by the spawned 0.13+ server.
82
108
  const conn = readActiveConnection();
83
109
  if (conn) {
84
110
  const url = conn.url.replace(/\/+$/, "");
85
111
  if (await probeHealth(url)) {
86
112
  spinner.stop(chalk.green(`Engine ready at ${url}`));
87
- return { url, token: conn.auth_token };
113
+ return { url, token: conn.auth_token, wasAlreadyRunning: false };
88
114
  }
89
115
  }
90
- // Path B: direct probe of the default engine URL. Works for any
91
- // engine version, including older `interf` binaries that don't
92
- // write connection.json.
116
+ // Path B: spawned engine is ready on the default URL.
93
117
  if (await probeHealth(DEFAULT_ENGINE_URL)) {
94
- // Recover the connection record so subsequent commands work.
95
118
  try {
96
119
  writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
97
120
  }
98
121
  catch {
99
- // best effort — wizard can still proceed using the URL inline
122
+ // best effort
100
123
  }
101
124
  spinner.stop(chalk.green(`Engine ready at ${DEFAULT_ENGINE_URL}`));
102
- return { url: DEFAULT_ENGINE_URL, token: null };
125
+ return { url: DEFAULT_ENGINE_URL, token: null, wasAlreadyRunning: false };
103
126
  }
104
127
  }
105
128
  spinner.stop(chalk.red("Timed out waiting for engine to start."));
106
129
  return null;
107
130
  }
108
- /** Prompt the user to either start a local engine, log in to a remote one, or quit. */
109
- async function offerEngineSetup() {
131
+ /**
132
+ * Print the canonical connect-or-error hint and exit non-zero. Used
133
+ * whenever the wizard needs an engine but no reachable connection
134
+ * exists. The wizard does NOT auto-start an engine — `interf web` is
135
+ * the explicit, foreground way to run one.
136
+ */
137
+ function exitNoEngineConnected(reason) {
138
+ console.log();
139
+ console.log(chalk.yellow(` ${reason}`));
140
+ console.log();
141
+ console.log(" Start one in another terminal:");
142
+ console.log(chalk.bold(" interf web"));
143
+ console.log();
144
+ console.log(" Or connect to a remote engine:");
145
+ console.log(chalk.bold(" interf login --url <https://…>"));
146
+ console.log();
147
+ process.exit(1);
148
+ }
149
+ async function promptForConnection(reason) {
150
+ if (!hasInteractiveTerminal()) {
151
+ exitNoEngineConnected(reason);
152
+ }
110
153
  console.log();
111
- console.log(chalk.yellow(" No Interf engine is connected."));
154
+ console.log(chalk.yellow(` ${reason}`));
112
155
  console.log();
113
156
  const choice = await p.select({
114
- message: "How do you want to connect?",
157
+ message: "How do you want to continue?",
115
158
  options: [
116
- { value: "start", label: "Start a local engine now" },
117
- { value: "remote", label: "Connect to a remote engine" },
118
- { value: "quit", label: "Quit" },
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") },
119
162
  ],
163
+ initialValue: "start-local",
120
164
  });
121
165
  if (p.isCancel(choice) || choice === "quit") {
122
166
  p.outro("Bye.");
123
167
  return null;
124
168
  }
125
- if (choice === "start") {
126
- const started = await startLocalEngineInBackground();
127
- if (started)
128
- return started;
129
- // Fall through to retry / custom URL fallback.
130
- const retry = await p.select({
131
- message: "Engine didn't come up. What now?",
132
- options: [
133
- { value: "probe", label: `Try connecting to ${DEFAULT_ENGINE_URL} (maybe an older engine is already running)` },
134
- { value: "remote", label: "Connect to a different URL" },
135
- { value: "quit", label: "Quit" },
136
- ],
137
- });
138
- if (p.isCancel(retry) || retry === "quit")
139
- return null;
140
- if (retry === "probe") {
141
- if (await probeHealth(DEFAULT_ENGINE_URL)) {
142
- try {
143
- writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
144
- }
145
- catch { /* best effort */ }
146
- return { url: DEFAULT_ENGINE_URL, token: null };
147
- }
148
- console.log(chalk.red(` No engine reachable at ${DEFAULT_ENGINE_URL}.`));
149
- return null;
150
- }
151
- // retry === "remote" falls through to the remote-URL block below
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);
152
175
  }
153
- if (choice === "remote" || choice === "start") {
154
- const remoteUrl = await p.text({
155
- message: "Remote engine URL",
156
- placeholder: "https://your-instance.example.com",
157
- validate: (v) => (v.startsWith("http://") || v.startsWith("https://") ? undefined : "Must start with http:// or https://"),
158
- });
159
- if (p.isCancel(remoteUrl))
160
- return null;
161
- const remoteToken = await p.password({
162
- message: "Bearer token (leave blank if none)",
163
- });
164
- if (p.isCancel(remoteToken))
165
- return null;
166
- const exitCode = await spawnInterf([
167
- "login",
168
- "--url",
169
- String(remoteUrl),
170
- ...(remoteToken ? ["--token", String(remoteToken)] : []),
171
- ]);
172
- if (exitCode !== 0)
173
- return null;
174
- const conn = readActiveConnection();
175
- if (!conn)
176
- return null;
177
- return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
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;
178
190
  }
179
- return null;
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 };
180
211
  }
181
212
  /** Validate that a path exists and is a directory. */
182
213
  function validateSourcePath(value) {
@@ -242,25 +273,40 @@ async function flowCreatePreparation(conn) {
242
273
  });
243
274
  if (p.isCancel(prepId))
244
275
  return null;
276
+ const about = await p.text({
277
+ message: "What is this preparation for? (one line — the agent task intent)",
278
+ placeholder: "Prepare these notes so an agent can answer questions about them.",
279
+ });
280
+ if (p.isCancel(about))
281
+ return null;
282
+ const aboutText = String(about ?? "").trim();
245
283
  const sourcePath = await promptSourcePath();
246
284
  if (!sourcePath)
247
285
  return null;
248
- // Offer the methods that the connected instance knows about.
286
+ // Offer the methods that the connected instance knows about. Method
287
+ // binding is OPTIONAL at create time — the agent first creates the
288
+ // preparation (the unit of agent work) and may pick or draft a method
289
+ // for it later.
249
290
  const methodsResp = await callJson(`${conn.url}/v1/methods`, conn.token);
250
291
  const methods = methodsResp.body?.methods ?? [];
251
292
  const methodOptions = methods
252
293
  .map((m) => ({ value: m.method_id ?? m.id ?? "", label: `${m.method_id ?? m.id ?? "(?)"}${m.label ? ` — ${m.label}` : ""}` }))
253
294
  .filter((opt) => opt.value !== "");
254
- let methodId;
295
+ let methodId = null;
296
+ const skipOption = { value: "__skip__", label: chalk.dim("Skip — pick or draft a method later") };
297
+ const customOption = { value: "__custom__", label: "Other (type a method id)" };
255
298
  if (methodOptions.length > 0) {
256
299
  const chosen = await p.select({
257
- message: "Which method?",
258
- options: [...methodOptions, { value: "__custom__", label: "Other (type a method id)" }],
300
+ message: "Pick a method (optional — you can do this later)",
301
+ options: [...methodOptions, customOption, skipOption],
259
302
  initialValue: methodOptions.find((o) => o.value === "interf-default")?.value ?? methodOptions[0]?.value,
260
303
  });
261
304
  if (p.isCancel(chosen))
262
305
  return null;
263
- if (chosen === "__custom__") {
306
+ if (chosen === "__skip__") {
307
+ methodId = null;
308
+ }
309
+ else if (chosen === "__custom__") {
264
310
  const typed = await p.text({
265
311
  message: "Method id",
266
312
  placeholder: "interf-default",
@@ -274,13 +320,24 @@ async function flowCreatePreparation(conn) {
274
320
  }
275
321
  }
276
322
  else {
277
- const typed = await p.text({
278
- message: "Method id (no methods registered yet)",
279
- initialValue: "interf-default",
323
+ const choose = await p.select({
324
+ message: "No methods registered yet — pick a method id?",
325
+ options: [
326
+ { value: "__type__", label: "Type a method id" },
327
+ skipOption,
328
+ ],
280
329
  });
281
- if (p.isCancel(typed))
330
+ if (p.isCancel(choose))
282
331
  return null;
283
- methodId = String(typed);
332
+ if (choose === "__type__") {
333
+ const typed = await p.text({
334
+ message: "Method id",
335
+ initialValue: "interf-default",
336
+ });
337
+ if (p.isCancel(typed))
338
+ return null;
339
+ methodId = String(typed);
340
+ }
284
341
  }
285
342
  const exitCode = await spawnInterf([
286
343
  "prep",
@@ -288,8 +345,8 @@ async function flowCreatePreparation(conn) {
288
345
  String(prepId),
289
346
  "--source",
290
347
  resolve(String(sourcePath)),
291
- "--method",
292
- methodId,
348
+ ...(methodId ? ["--method", methodId] : []),
349
+ ...(aboutText ? ["--about", aboutText] : []),
293
350
  ]);
294
351
  if (exitCode !== 0)
295
352
  return null;
@@ -313,15 +370,22 @@ async function pickPreparation(conn, message) {
313
370
  return null;
314
371
  return String(choice);
315
372
  }
316
- async function showActionMenu(conn) {
373
+ async function showActionMenu(conn, options = { allowCompileVerify: true }) {
374
+ const compileLabel = options.allowCompileVerify
375
+ ? "Compile a preparation"
376
+ : chalk.dim("Compile a preparation (no agents available)");
377
+ const verifyLabel = options.allowCompileVerify
378
+ ? "Verify a preparation's claim-checks"
379
+ : chalk.dim("Verify (no agents available)");
317
380
  const action = await p.select({
318
381
  message: "What do you want to do?",
319
382
  options: [
383
+ { value: "ui", label: "Open Compiler UI" },
320
384
  { value: "ls", label: "List preparations" },
321
385
  { value: "create", label: "Create a new preparation" },
322
- { value: "compile", label: "Compile a preparation" },
323
- { value: "test", label: "Run readiness checks (test) for a preparation" },
324
- { value: "ui", label: "Open Compiler UI" },
386
+ { value: "agents", label: "Manage agents (list / register / role-map)" },
387
+ { value: "compile", label: compileLabel },
388
+ { value: "verify", label: verifyLabel },
325
389
  { value: "stop", label: "Stop the local engine" },
326
390
  { value: "quit", label: "Quit" },
327
391
  ],
@@ -332,26 +396,47 @@ async function showActionMenu(conn) {
332
396
  await spawnInterf(["prep", "ls"]);
333
397
  return "continue";
334
398
  }
399
+ if (action === "agents") {
400
+ await spawnInterf(["agents", "ls"]);
401
+ return "continue";
402
+ }
335
403
  if (action === "create") {
336
404
  const newId = await flowCreatePreparation(conn);
337
405
  if (newId) {
338
- const compileNow = await p.confirm({ message: `Compile ${newId} now?`, initialValue: true });
339
- if (!p.isCancel(compileNow) && compileNow) {
340
- await spawnInterf(["compile", newId]);
406
+ if (!options.allowCompileVerify) {
407
+ console.log(chalk.dim(" Skipping compile prompt — no agents available. Install one then run `interf compile " +
408
+ newId +
409
+ "`."));
410
+ }
411
+ else {
412
+ const compileNow = await p.confirm({ message: `Compile ${newId} now?`, initialValue: true });
413
+ if (!p.isCancel(compileNow) && compileNow) {
414
+ await spawnInterf(["compile", newId]);
415
+ }
341
416
  }
342
417
  }
343
418
  return "continue";
344
419
  }
345
420
  if (action === "compile") {
421
+ if (!options.allowCompileVerify) {
422
+ console.log(chalk.yellow(" Cannot compile — no agents available."));
423
+ console.log(" Install Claude Code, Codex, Gemini, or another agent CLI, or");
424
+ console.log(" register a custom CLI: `interf agents register <name> --command <cmd>`.");
425
+ return "continue";
426
+ }
346
427
  const id = await pickPreparation(conn, "Which preparation to compile?");
347
428
  if (id)
348
429
  await spawnInterf(["compile", id]);
349
430
  return "continue";
350
431
  }
351
- if (action === "test") {
352
- const id = await pickPreparation(conn, "Which preparation to test?");
432
+ if (action === "verify") {
433
+ if (!options.allowCompileVerify) {
434
+ console.log(chalk.yellow(" Cannot verify — no agents available."));
435
+ return "continue";
436
+ }
437
+ const id = await pickPreparation(conn, "Which preparation to verify?");
353
438
  if (id)
354
- await spawnInterf(["test", id]);
439
+ await spawnInterf(["verify", id]);
355
440
  return "continue";
356
441
  }
357
442
  if (action === "ui") {
@@ -382,42 +467,312 @@ async function showActionMenu(conn) {
382
467
  }
383
468
  return "continue";
384
469
  }
470
+ /**
471
+ * Agent install-cards menu shown when the connected engine has zero
472
+ * detected + registered agents. Returns:
473
+ * - "rerun" → user installed an agent and wants to retry detection
474
+ * - "skip" → continue in UI-only mode (no compile/verify)
475
+ * - "quit" → exit
476
+ */
477
+ async function showAgentInstallCards() {
478
+ console.log();
479
+ console.log(chalk.yellow(" No agents detected."));
480
+ console.log();
481
+ console.log(" Interf needs at least one agent to compile and verify preparations.");
482
+ console.log();
483
+ const choice = await p.select({
484
+ message: "How do you want to proceed?",
485
+ options: [
486
+ {
487
+ value: "claude-code",
488
+ label: `Install Claude Code ${chalk.dim("(opens install docs)")}`,
489
+ },
490
+ {
491
+ value: "codex",
492
+ label: `Install OpenAI Codex ${chalk.dim("(opens install docs)")}`,
493
+ },
494
+ {
495
+ value: "gemini",
496
+ label: `Install Gemini CLI ${chalk.dim("(opens install docs)")}`,
497
+ },
498
+ {
499
+ value: "custom",
500
+ label: "Register a custom CLI as an agent",
501
+ },
502
+ {
503
+ value: "skip",
504
+ label: chalk.dim("Skip — UI-only mode (browse existing portable contexts only)"),
505
+ },
506
+ { value: "quit", label: chalk.dim("Quit") },
507
+ ],
508
+ });
509
+ if (p.isCancel(choice) || choice === "quit")
510
+ return "quit";
511
+ if (choice === "skip")
512
+ return "skip";
513
+ if (choice === "custom") {
514
+ const name = await p.text({
515
+ message: "Agent name (lowercase identifier)",
516
+ placeholder: "opencode",
517
+ validate: (value) => /^[a-z0-9][a-z0-9-]*$/.test(value)
518
+ ? undefined
519
+ : "Lowercase letters, numbers, and dashes only.",
520
+ });
521
+ if (p.isCancel(name))
522
+ return "quit";
523
+ const command = await p.text({
524
+ message: "Command to invoke",
525
+ placeholder: "opencode --prompt",
526
+ });
527
+ if (p.isCancel(command))
528
+ return "quit";
529
+ const displayName = await p.text({
530
+ message: `Display name (defaults to "${name}")`,
531
+ placeholder: String(name),
532
+ });
533
+ if (p.isCancel(displayName))
534
+ return "quit";
535
+ const cliDisplayName = String(displayName).trim() || String(name);
536
+ const exitCode = await spawnInterf([
537
+ "agents",
538
+ "register",
539
+ String(name),
540
+ "--command",
541
+ String(command),
542
+ "--display-name",
543
+ cliDisplayName,
544
+ ]);
545
+ return exitCode === 0 ? "rerun" : "quit";
546
+ }
547
+ // Print install instructions + offer to copy the install command.
548
+ const installCommands = {
549
+ "claude-code": {
550
+ command: "npm install -g @anthropic-ai/claude-code",
551
+ docs: "https://docs.claude.com/claude-code",
552
+ },
553
+ codex: {
554
+ command: "npm install -g @openai/codex",
555
+ docs: "https://github.com/openai/codex",
556
+ },
557
+ gemini: {
558
+ command: "npm install -g @google/gemini-cli",
559
+ docs: "https://github.com/google-gemini/gemini-cli",
560
+ },
561
+ };
562
+ const target = installCommands[String(choice)];
563
+ if (target) {
564
+ console.log();
565
+ console.log(` Install command: ${chalk.bold(target.command)}`);
566
+ console.log(` Docs: ${chalk.dim(target.docs)}`);
567
+ console.log();
568
+ const next = await p.select({
569
+ message: "What now?",
570
+ options: [
571
+ { value: "rerun", label: "I installed it — re-detect" },
572
+ { value: "skip", label: chalk.dim("Skip — continue in UI-only mode") },
573
+ { value: "quit", label: chalk.dim("Quit") },
574
+ ],
575
+ });
576
+ if (p.isCancel(next) || next === "quit")
577
+ return "quit";
578
+ if (next === "skip")
579
+ return "skip";
580
+ return "rerun";
581
+ }
582
+ return "rerun";
583
+ }
584
+ async function fetchAgentSnapshot(conn) {
585
+ const instance = await callJson(`${conn.url}/v1/instance`, conn.token);
586
+ const agentsResponse = await callJson(`${conn.url}/v1/agents`, conn.token);
587
+ if (instance.status !== 200)
588
+ return null;
589
+ // Engines pre-0.15 don't expose /v1/agents. Surface the gap explicitly
590
+ // so the wizard can tell the user to restart instead of silently going
591
+ // through the install-cards flow.
592
+ const engineSupportsAgents = agentsResponse.status === 200 && instance.body?.agent_count !== undefined;
593
+ return {
594
+ agentCount: instance.body?.agent_count ?? 0,
595
+ defaultAgent: instance.body?.default_agent ?? null,
596
+ agents: agentsResponse.body?.agents ?? [],
597
+ engineSupportsAgents,
598
+ };
599
+ }
385
600
  async function runWizard(args) {
386
- let conn;
601
+ // The wizard is the human entry point, so it can ask how to connect.
602
+ // It still never auto-starts an engine: starting `interf web` is an
603
+ // explicit foreground choice, and script/agent commands keep the
604
+ // connect-or-error behavior.
387
605
  const initial = readActiveConnection({
388
606
  urlOverride: args.url,
389
607
  authTokenOverride: args.token,
390
608
  });
609
+ let conn = null;
391
610
  if (!initial) {
392
- conn = await offerEngineSetup();
393
- if (!conn) {
611
+ if (await probeHealth(DEFAULT_ENGINE_URL)) {
612
+ try {
613
+ writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
614
+ }
615
+ catch {
616
+ // best effort
617
+ }
394
618
  console.log();
395
- console.log(CONNECT_OR_ERROR_HINT);
396
- process.exit(1);
619
+ console.log(chalk.dim(` Engine already running at ${DEFAULT_ENGINE_URL} — connecting.`));
620
+ conn = { url: DEFAULT_ENGINE_URL, token: null };
621
+ }
622
+ else {
623
+ conn = await promptForConnection("No Interf engine is connected.");
397
624
  }
398
625
  }
399
626
  else {
400
627
  const url = initial.url.replace(/\/+$/, "");
401
628
  const probe = await callJson(`${url}/health`, initial.auth_token);
402
629
  if (probe.status === 0) {
403
- console.log(chalk.yellow(` Connection ${url} is unreachable.`));
404
- conn = await offerEngineSetup();
405
- if (!conn)
406
- process.exit(1);
630
+ if (!args.url && await probeHealth(DEFAULT_ENGINE_URL)) {
631
+ try {
632
+ writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
633
+ }
634
+ catch {
635
+ // best effort
636
+ }
637
+ console.log();
638
+ console.log(chalk.dim(` Saved connection ${url} is unreachable; using local engine at ${DEFAULT_ENGINE_URL}.`));
639
+ conn = { url: DEFAULT_ENGINE_URL, token: null };
640
+ }
641
+ else {
642
+ conn = await promptForConnection(`Connection ${url} is unreachable.`);
643
+ }
407
644
  }
408
645
  else {
409
646
  conn = { url, token: initial.auth_token };
410
647
  }
411
648
  }
649
+ if (!conn) {
650
+ return;
651
+ }
412
652
  const instance = await callJson(`${conn.url}/v1/instance`, conn.token);
413
653
  console.log();
414
654
  console.log(chalk.bold(` Connected to ${conn.url}`));
415
655
  if (instance.body?.package_version) {
416
656
  console.log(chalk.dim(` v${instance.body.package_version} · ${instance.body.preparation_count ?? 0} preparation(s)`));
417
657
  }
658
+ // 0.15 — surface the connected agents up front. When zero are
659
+ // detected, run the install-cards menu before letting the user
660
+ // try to compile / verify.
661
+ let agents = await fetchAgentSnapshot(conn);
662
+ if (agents && !agents.engineSupportsAgents) {
663
+ console.log();
664
+ console.log(chalk.yellow(" ⚠ The connected engine is older than this CLI."));
665
+ console.log(chalk.dim(" /v1/agents is not available — agent management is disabled."));
666
+ console.log();
667
+ const choice = await p.select({
668
+ message: "Restart the engine now to pick up new features?",
669
+ options: [
670
+ { value: "restart", label: "Yes — stop old engine, start new one" },
671
+ { value: "continue", label: chalk.dim("No — continue with limited features (no agents UI / compile / verify)") },
672
+ { value: "quit", label: "Quit" },
673
+ ],
674
+ initialValue: "restart",
675
+ });
676
+ if (p.isCancel(choice) || choice === "quit") {
677
+ p.outro("Bye.");
678
+ return;
679
+ }
680
+ if (choice === "restart") {
681
+ console.log();
682
+ console.log(chalk.dim(" Stopping old engine…"));
683
+ await spawnInterf(["web", "stop"]);
684
+ // Small grace period for the OS to release the port.
685
+ await new Promise((r) => setTimeout(r, 800));
686
+ const restarted = await startLocalEngineInBackground();
687
+ if (!restarted) {
688
+ console.log(chalk.red(" Could not start the new engine. Try manually: interf web"));
689
+ process.exit(1);
690
+ }
691
+ conn = restarted;
692
+ agents = await fetchAgentSnapshot(conn);
693
+ }
694
+ }
695
+ // Treat "all registered agents are unavailable" the same as "no agents
696
+ // detected" — the install-cards menu lets the user install or register
697
+ // a real one before the active-agent picker runs.
698
+ function installedAgentCount(snapshot) {
699
+ if (!snapshot)
700
+ return 0;
701
+ return snapshot.agents.filter((agent) => agent.available !== false).length;
702
+ }
703
+ let allowCompileVerify = installedAgentCount(agents) > 0;
704
+ while (agents &&
705
+ agents.engineSupportsAgents &&
706
+ installedAgentCount(agents) === 0) {
707
+ const decision = await showAgentInstallCards();
708
+ if (decision === "quit") {
709
+ p.outro("Bye.");
710
+ return;
711
+ }
712
+ if (decision === "skip") {
713
+ allowCompileVerify = false;
714
+ break;
715
+ }
716
+ // decision === "rerun"
717
+ agents = await fetchAgentSnapshot(conn);
718
+ allowCompileVerify = installedAgentCount(agents) > 0;
719
+ }
720
+ if (agents && agents.engineSupportsAgents && installedAgentCount(agents) > 0) {
721
+ // Always confirm the active agent before the action menu. Pre-select
722
+ // the current default; user presses Enter to keep it, Up/Down to
723
+ // change. Customizing per-stage (role-map) is opt-in advanced —
724
+ // accessible via `interf agents map <role> <agent>`.
725
+ //
726
+ // Custom agents whose CLI is no longer on PATH carry `available: false`
727
+ // — show them in a hint instead of as selectable choices so the picker
728
+ // does not let the user pick something the engine cannot run.
729
+ const stale = agents.agents.filter((agent) => agent.available === false);
730
+ if (stale.length > 0) {
731
+ const names = stale.map((agent) => agent.display_name || agent.name).join(", ");
732
+ console.log();
733
+ console.log(chalk.yellow(` ⚠ Registered but not installed: ${names}`));
734
+ console.log(chalk.dim(` Reinstall the CLI or run \`interf agents unregister <name>\` to remove the stale entry.`));
735
+ }
736
+ const installed = agents.agents.filter((agent) => agent.available !== false);
737
+ const options = installed.map((agent) => ({
738
+ value: agent.name,
739
+ label: `${agent.display_name || agent.name}${agent.name === agents.defaultAgent ? chalk.green(" (current active)") : ""}${agent.source === "user" ? chalk.dim(" [custom]") : ""}`,
740
+ }));
741
+ options.push({ value: "__register__", label: chalk.dim("Register a custom CLI as an agent…") });
742
+ const installedDefault = installed.some((agent) => agent.name === agents.defaultAgent)
743
+ ? agents.defaultAgent
744
+ : null;
745
+ const choice = await p.select({
746
+ message: "Active agent for this session (will run every role unless overridden)",
747
+ options,
748
+ initialValue: installedDefault ?? options[0]?.value,
749
+ });
750
+ if (p.isCancel(choice)) {
751
+ p.outro("Bye.");
752
+ return;
753
+ }
754
+ if (choice === "__register__") {
755
+ const decision = await showAgentInstallCards();
756
+ if (decision === "quit") {
757
+ p.outro("Bye.");
758
+ return;
759
+ }
760
+ agents = await fetchAgentSnapshot(conn);
761
+ }
762
+ else if (choice !== agents.defaultAgent) {
763
+ // Switch active agent before proceeding. Reuse the existing CLI to
764
+ // sweep the role-map's `general` row + any role pinned to the
765
+ // previous active.
766
+ await spawnInterf(["agents", "use", String(choice)]);
767
+ agents = await fetchAgentSnapshot(conn);
768
+ }
769
+ if (agents && agents.defaultAgent) {
770
+ console.log(chalk.dim(` Active: ${agents.defaultAgent} · roles default to ${agents.defaultAgent}`));
771
+ }
772
+ }
418
773
  for (;;) {
419
774
  console.log();
420
- const next = await showActionMenu(conn);
775
+ const next = await showActionMenu(conn, { allowCompileVerify });
421
776
  if (next === "exit")
422
777
  break;
423
778
  }