@interf/compiler 0.33.0 → 0.50.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 (234) hide show
  1. package/README.md +122 -226
  2. package/dist/cli/commands/agents.js +1 -32
  3. package/dist/cli/commands/benchmark.d.ts +2 -3
  4. package/dist/cli/commands/benchmark.js +1 -31
  5. package/dist/cli/commands/build-plan.js +26 -50
  6. package/dist/cli/commands/build.d.ts +2 -3
  7. package/dist/cli/commands/build.js +1 -31
  8. package/dist/cli/commands/graphs.js +177 -32
  9. package/dist/cli/commands/mcp.d.ts +1 -0
  10. package/dist/cli/commands/mcp.js +223 -126
  11. package/dist/cli/commands/project.js +10 -36
  12. package/dist/cli/commands/reset.d.ts +2 -3
  13. package/dist/cli/commands/reset.js +1 -22
  14. package/dist/cli/commands/runs.js +86 -33
  15. package/dist/cli/commands/status.js +3 -24
  16. package/dist/cli/commands/traces.js +1 -29
  17. package/dist/cli/commands/wizard.js +17 -29
  18. package/dist/cli/lib/http-client.d.ts +39 -0
  19. package/dist/cli/lib/http-client.js +73 -0
  20. package/dist/packages/build-plans/authoring/brief.d.ts +25 -4
  21. package/dist/packages/build-plans/authoring/build-plan-authoring.d.ts +42 -1
  22. package/dist/packages/build-plans/authoring/build-plan-authoring.js +470 -63
  23. package/dist/packages/build-plans/authoring/build-plan-edit-session.d.ts +9 -0
  24. package/dist/packages/build-plans/authoring/build-plan-edit-session.js +27 -10
  25. package/dist/packages/build-plans/authoring/build-plan-improvement.js +62 -8
  26. package/dist/packages/build-plans/authoring/lib/build-plan-edit-utils.d.ts +1 -0
  27. package/dist/packages/build-plans/package/build-plan-definitions.d.ts +0 -1
  28. package/dist/packages/build-plans/package/build-plan-definitions.js +5 -3
  29. package/dist/packages/build-plans/package/build-plan-stage-runner.d.ts +1 -0
  30. package/dist/packages/build-plans/package/build-plan-stage-runner.js +2 -1
  31. package/dist/packages/build-plans/package/builtin-build-plan.d.ts +2 -2
  32. package/dist/packages/build-plans/package/builtin-build-plan.js +3 -3
  33. package/dist/packages/build-plans/package/context-interface.d.ts +3 -0
  34. package/dist/packages/build-plans/package/context-interface.js +5 -5
  35. package/dist/packages/build-plans/package/interf-build-plan-package.js +22 -22
  36. package/dist/packages/build-plans/package/local-build-plans.d.ts +10 -5
  37. package/dist/packages/build-plans/package/local-build-plans.js +57 -32
  38. package/dist/packages/contracts/index.d.ts +4 -3
  39. package/dist/packages/contracts/index.js +2 -1
  40. package/dist/packages/contracts/lib/context-graph-layer.d.ts +161 -0
  41. package/dist/packages/contracts/lib/context-graph-layer.js +216 -0
  42. package/dist/packages/contracts/lib/project-paths.d.ts +7 -0
  43. package/dist/packages/contracts/lib/project-paths.js +9 -0
  44. package/dist/packages/contracts/lib/project-schema.d.ts +264 -1
  45. package/dist/packages/contracts/lib/project-schema.js +38 -13
  46. package/dist/packages/contracts/lib/schema.d.ts +556 -23
  47. package/dist/packages/contracts/lib/schema.js +279 -18
  48. package/dist/packages/contracts/utils/filesystem.d.ts +1 -0
  49. package/dist/packages/contracts/utils/filesystem.js +29 -1
  50. package/dist/packages/projects/lib/schema.d.ts +6 -8
  51. package/dist/packages/projects/lib/schema.js +3 -1
  52. package/dist/packages/projects/source-config.d.ts +0 -5
  53. package/dist/packages/projects/source-config.js +9 -22
  54. package/dist/packages/runtime/actions/fields.d.ts +4 -0
  55. package/dist/packages/runtime/actions/form-builders.js +79 -31
  56. package/dist/packages/runtime/actions/form-validators.js +9 -3
  57. package/dist/packages/runtime/actions/helpers.js +3 -3
  58. package/dist/packages/runtime/actions/registry.d.ts +1 -1
  59. package/dist/packages/runtime/actions/registry.js +1 -1
  60. package/dist/packages/runtime/actions/requests.d.ts +1 -1
  61. package/dist/packages/runtime/actions/requests.js +12 -6
  62. package/dist/packages/runtime/actions/schemas.d.ts +7 -0
  63. package/dist/packages/runtime/actions/schemas.js +1 -0
  64. package/dist/packages/runtime/agent-handoff.js +8 -7
  65. package/dist/packages/runtime/agents/lib/execution-profile.d.ts +14 -0
  66. package/dist/packages/runtime/agents/lib/execution-profile.js +23 -0
  67. package/dist/packages/runtime/agents/lib/execution.js +14 -8
  68. package/dist/packages/runtime/agents/lib/executors.d.ts +1 -0
  69. package/dist/packages/runtime/agents/lib/executors.js +11 -2
  70. package/dist/packages/runtime/agents/lib/logs.d.ts +10 -0
  71. package/dist/packages/runtime/agents/lib/logs.js +32 -8
  72. package/dist/packages/runtime/agents/lib/preflight.js +4 -1
  73. package/dist/packages/runtime/agents/lib/render.d.ts +18 -0
  74. package/dist/packages/runtime/agents/lib/render.js +44 -18
  75. package/dist/packages/runtime/agents/lib/shell-templates.js +105 -63
  76. package/dist/packages/runtime/agents/lib/shells.d.ts +29 -0
  77. package/dist/packages/runtime/agents/lib/shells.js +158 -32
  78. package/dist/packages/runtime/agents/lib/source-context-scan.d.ts +10 -0
  79. package/dist/packages/runtime/agents/lib/source-context-scan.js +388 -0
  80. package/dist/packages/runtime/agents/lib/status.js +1 -14
  81. package/dist/packages/runtime/agents/lib/string-utils.d.ts +16 -0
  82. package/dist/packages/runtime/agents/lib/string-utils.js +36 -0
  83. package/dist/packages/runtime/agents/lib/types.d.ts +1 -0
  84. package/dist/packages/runtime/agents/providers/codex.js +2 -0
  85. package/dist/packages/runtime/agents/role-executors.js +2 -1
  86. package/dist/packages/runtime/auth/session-store.js +11 -3
  87. package/dist/packages/runtime/benchmark-question-draft.d.ts +3 -0
  88. package/dist/packages/runtime/benchmark-question-draft.js +57 -28
  89. package/dist/packages/runtime/build/artifact-status.d.ts +1 -1
  90. package/dist/packages/runtime/build/artifact-status.js +1 -1
  91. package/dist/packages/runtime/build/build-evidence.d.ts +2 -1
  92. package/dist/packages/runtime/build/build-evidence.js +11 -5
  93. package/dist/packages/runtime/build/build-pipeline.js +89 -5
  94. package/dist/packages/runtime/build/build-stage-plan.js +3 -1
  95. package/dist/packages/runtime/build/build-stage-runner.js +169 -32
  96. package/dist/packages/runtime/build/build-target.d.ts +3 -0
  97. package/dist/packages/runtime/build/build-target.js +25 -1
  98. package/dist/packages/runtime/build/check-evaluator.d.ts +1 -1
  99. package/dist/packages/runtime/build/check-evaluator.js +655 -4
  100. package/dist/packages/runtime/build/context-graph-paths.d.ts +13 -0
  101. package/dist/packages/runtime/build/context-graph-paths.js +27 -0
  102. package/dist/packages/runtime/build/index.d.ts +2 -2
  103. package/dist/packages/runtime/build/index.js +2 -2
  104. package/dist/packages/runtime/build/inspect-map.d.ts +10 -0
  105. package/dist/packages/runtime/build/inspect-map.js +270 -0
  106. package/dist/packages/runtime/build/lib/schema.d.ts +246 -53
  107. package/dist/packages/runtime/build/lib/schema.js +173 -15
  108. package/dist/packages/runtime/build/native-entrypoint.d.ts +2 -0
  109. package/dist/packages/runtime/build/native-entrypoint.js +286 -0
  110. package/dist/packages/runtime/build/runtime-contracts.js +9 -3
  111. package/dist/packages/runtime/build/runtime-log-paths.d.ts +3 -0
  112. package/dist/packages/runtime/build/runtime-log-paths.js +16 -0
  113. package/dist/packages/runtime/build/runtime-prompt.js +6 -4
  114. package/dist/packages/runtime/build/runtime-runs.js +63 -10
  115. package/dist/packages/runtime/build/runtime-types.d.ts +4 -1
  116. package/dist/packages/runtime/build/runtime.d.ts +3 -1
  117. package/dist/packages/runtime/build/runtime.js +3 -1
  118. package/dist/packages/runtime/build/source-files.js +11 -2
  119. package/dist/packages/runtime/build/source-inventory.d.ts +1 -0
  120. package/dist/packages/runtime/build/source-inventory.js +246 -7
  121. package/dist/packages/runtime/build/source-manifest.d.ts +11 -0
  122. package/dist/packages/runtime/build/source-manifest.js +30 -2
  123. package/dist/packages/runtime/build/stage-evidence.js +80 -11
  124. package/dist/packages/runtime/build/stage-manifest.d.ts +45 -0
  125. package/dist/packages/runtime/build/stage-manifest.js +1125 -0
  126. package/dist/packages/runtime/build/stage-reuse.js +12 -0
  127. package/dist/packages/runtime/build/stage-session.d.ts +81 -0
  128. package/dist/packages/runtime/build/stage-session.js +308 -0
  129. package/dist/packages/runtime/build/state-io.js +10 -11
  130. package/dist/packages/runtime/build/state-view.js +1 -1
  131. package/dist/packages/runtime/build/state.d.ts +1 -1
  132. package/dist/packages/runtime/build/state.js +1 -1
  133. package/dist/packages/runtime/build/summary-coverage-index.d.ts +21 -0
  134. package/dist/packages/runtime/build/summary-coverage-index.js +189 -0
  135. package/dist/packages/runtime/build/traces.js +3 -3
  136. package/dist/packages/runtime/build/validate-context-graph.d.ts +1 -1
  137. package/dist/packages/runtime/build/validate-context-graph.js +5 -5
  138. package/dist/packages/runtime/build/validate.d.ts +1 -1
  139. package/dist/packages/runtime/build/validate.js +1 -1
  140. package/dist/packages/runtime/client.d.ts +3 -3
  141. package/dist/packages/runtime/client.js +8 -13
  142. package/dist/packages/runtime/context-checks.js +13 -0
  143. package/dist/packages/runtime/context-graph-scaffold.js +2 -1
  144. package/dist/packages/runtime/context-graph-semantic-graph.d.ts +9 -0
  145. package/dist/packages/runtime/context-graph-semantic-graph.js +416 -0
  146. package/dist/packages/runtime/execution/lib/schema.d.ts +34 -31
  147. package/dist/packages/runtime/index.d.ts +2 -2
  148. package/dist/packages/runtime/index.js +1 -1
  149. package/dist/packages/runtime/native-run-handlers.d.ts +38 -0
  150. package/dist/packages/runtime/native-run-handlers.js +52 -33
  151. package/dist/packages/runtime/plan-artifact-contract.js +1 -1
  152. package/dist/packages/runtime/project-source-state.d.ts +4 -4
  153. package/dist/packages/runtime/project-source-state.js +5 -2
  154. package/dist/packages/runtime/project-store.d.ts +5 -0
  155. package/dist/packages/runtime/project-store.js +30 -3
  156. package/dist/packages/runtime/requested-artifacts.js +1 -1
  157. package/dist/packages/runtime/run-observability.js +9 -4
  158. package/dist/packages/runtime/runtime-action-proposals.js +3 -3
  159. package/dist/packages/runtime/runtime-build-plans.js +47 -3
  160. package/dist/packages/runtime/runtime-build-runs.js +9 -16
  161. package/dist/packages/runtime/runtime-caches.d.ts +26 -0
  162. package/dist/packages/runtime/runtime-caches.js +47 -0
  163. package/dist/packages/runtime/runtime-jobs.js +6 -6
  164. package/dist/packages/runtime/runtime-project-mutations.js +1 -0
  165. package/dist/packages/runtime/runtime-project-reads.d.ts +4 -1
  166. package/dist/packages/runtime/runtime-project-reads.js +229 -36
  167. package/dist/packages/runtime/runtime-proposal-helpers.js +6 -6
  168. package/dist/packages/runtime/runtime-resource-builders.d.ts +4 -2
  169. package/dist/packages/runtime/runtime-resource-builders.js +16 -14
  170. package/dist/packages/runtime/runtime-status.d.ts +14 -0
  171. package/dist/packages/runtime/runtime-status.js +15 -0
  172. package/dist/packages/runtime/runtime-verify-runs.js +6 -5
  173. package/dist/packages/runtime/runtime.d.ts +439 -22
  174. package/dist/packages/runtime/runtime.js +16 -2
  175. package/dist/packages/runtime/schemas/actions.d.ts +24 -0
  176. package/dist/packages/runtime/schemas/agents.d.ts +28 -0
  177. package/dist/packages/runtime/schemas/agents.js +33 -0
  178. package/dist/packages/runtime/schemas/build-plans.d.ts +181 -8
  179. package/dist/packages/runtime/schemas/build-plans.js +36 -2
  180. package/dist/packages/runtime/schemas/context-graphs.d.ts +1522 -0
  181. package/dist/packages/runtime/schemas/context-graphs.js +110 -0
  182. package/dist/packages/runtime/schemas/files.d.ts +7 -347
  183. package/dist/packages/runtime/schemas/files.js +1 -24
  184. package/dist/packages/runtime/schemas/index.d.ts +1 -0
  185. package/dist/packages/runtime/schemas/index.js +1 -0
  186. package/dist/packages/runtime/schemas/jobs.js +4 -0
  187. package/dist/packages/runtime/schemas/projects.d.ts +48 -21
  188. package/dist/packages/runtime/schemas/projects.js +34 -10
  189. package/dist/packages/runtime/schemas/runs.d.ts +1009 -240
  190. package/dist/packages/runtime/schemas/runs.js +17 -0
  191. package/dist/packages/runtime/service/openapi.js +1 -0
  192. package/dist/packages/runtime/service/operations.d.ts +1666 -145
  193. package/dist/packages/runtime/service/operations.js +147 -17
  194. package/dist/packages/runtime/service/routes.d.ts +11 -3
  195. package/dist/packages/runtime/service/routes.js +11 -3
  196. package/dist/packages/runtime/service/server-app-boot.js +2 -2
  197. package/dist/packages/runtime/service/server-helpers.d.ts +11 -0
  198. package/dist/packages/runtime/service/server-helpers.js +19 -0
  199. package/dist/packages/runtime/service/server-routes-action-proposals.js +4 -2
  200. package/dist/packages/runtime/service/server-routes-agents.js +19 -85
  201. package/dist/packages/runtime/service/server-routes-build-plans.js +14 -11
  202. package/dist/packages/runtime/service/server-routes-project-context.js +102 -7
  203. package/dist/packages/runtime/service/server-routes-project-jobs.js +19 -12
  204. package/dist/packages/runtime/service/server-routes-project-runs.js +5 -2
  205. package/dist/packages/runtime/service/server-routes-projects.js +6 -2
  206. package/dist/packages/runtime/service/server-routes-runs.js +11 -4
  207. package/dist/packages/runtime/verify/lib/schema.js +12 -0
  208. package/dist/packages/runtime/verify/test-file-guard.d.ts +2 -0
  209. package/dist/packages/runtime/verify/test-file-guard.js +29 -0
  210. package/dist/packages/runtime/verify/verify-execution.d.ts +7 -0
  211. package/dist/packages/runtime/verify/verify-execution.js +109 -35
  212. package/dist/packages/runtime/verify/verify-paths.d.ts +1 -0
  213. package/dist/packages/runtime/verify/verify-paths.js +4 -0
  214. package/dist/packages/runtime/verify/verify-specs.js +49 -39
  215. package/dist/packages/runtime/wire-schemas.d.ts +1 -1
  216. package/dist/packages/runtime/wire-schemas.js +1 -1
  217. package/package.json +2 -8
  218. package/public-repo/CONTRIBUTING.md +10 -3
  219. package/public-repo/README.md +122 -226
  220. package/public-repo/build-plans/interf-default/README.md +15 -12
  221. package/public-repo/build-plans/interf-default/build/stages/entrypoint/SKILL.md +74 -0
  222. package/public-repo/build-plans/interf-default/build/stages/knowledge/SKILL.md +95 -0
  223. package/public-repo/build-plans/interf-default/build/stages/summarize/SKILL.md +38 -5
  224. package/public-repo/build-plans/interf-default/build-plan.json +27 -23
  225. package/public-repo/build-plans/interf-default/build-plan.schema.json +24 -20
  226. package/public-repo/build-plans/interf-default/use/query/SKILL.md +8 -7
  227. package/public-repo/openapi/local-service.openapi.json +11637 -4213
  228. package/public-repo/skills/interf/SKILL.md +174 -134
  229. package/dist/packages/runtime/build/runtime-paths.d.ts +0 -8
  230. package/dist/packages/runtime/build/runtime-paths.js +0 -26
  231. package/dist/packages/runtime/build/state-paths.d.ts +0 -7
  232. package/dist/packages/runtime/build/state-paths.js +0 -22
  233. package/public-repo/build-plans/interf-default/build/stages/shape/SKILL.md +0 -34
  234. package/public-repo/build-plans/interf-default/build/stages/structure/SKILL.md +0 -28
@@ -2,7 +2,7 @@
2
2
  * `interf project` — Project CRUD against a connected instance.
3
3
  *
4
4
  * interf project ls
5
- * interf project create <id> --source <path> [--build-plan <id>]
5
+ * interf project create <id> --source <path> --intent "..." [--build-plan <id>]
6
6
  * interf project show <id>
7
7
  * interf project rm <id>
8
8
  * Every subcommand requires an active connection. If `~/.interf/connection.json`
@@ -11,40 +11,9 @@
11
11
  */
12
12
  import { resolve } from "node:path";
13
13
  import chalk from "chalk";
14
- import { CONNECT_OR_ERROR_HINT, readActiveConnection, } from "../../packages/runtime/connection-config.js";
14
+ import { callJson, resolveConnection as requireConnection } from "../lib/http-client.js";
15
15
  import { projectResourcePath } from "../../packages/runtime/service/routes.js";
16
16
  import { ProjectListResponseSchema, ProjectResourceSchema, ProjectWireShapeSchema, } from "../../packages/runtime/schemas/index.js";
17
- function requireConnection(args) {
18
- const conn = readActiveConnection({
19
- urlOverride: args.url,
20
- authTokenOverride: args.token,
21
- });
22
- if (!conn) {
23
- console.error(CONNECT_OR_ERROR_HINT);
24
- process.exit(1);
25
- }
26
- return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
27
- }
28
- async function callJson(url, token, init = {}) {
29
- const headers = new Headers(init.headers ?? {});
30
- if (token)
31
- headers.set("authorization", `Bearer ${token}`);
32
- if (init.body && !headers.has("content-type")) {
33
- headers.set("content-type", "application/json");
34
- }
35
- const response = await fetch(url, { ...init, headers });
36
- const raw = await response.text();
37
- let body = null;
38
- if (raw.length > 0) {
39
- try {
40
- body = JSON.parse(raw);
41
- }
42
- catch {
43
- body = null;
44
- }
45
- }
46
- return { status: response.status, body, raw };
47
- }
48
17
  function statusColor(status) {
49
18
  if (status === "ready")
50
19
  return chalk.green;
@@ -58,6 +27,8 @@ function renderProjectSummary(project) {
58
27
  console.log();
59
28
  console.log(` ${chalk.bold(project.name)}`);
60
29
  console.log(chalk.dim(` Build Plan: ${project.build_plan_id ?? "(not selected)"}`));
30
+ if (project.intent)
31
+ console.log(chalk.dim(` agent task: ${project.intent}`));
61
32
  if (project.source_path)
62
33
  console.log(chalk.dim(` source: ${project.source_path}`));
63
34
  const contextGraphPath = project.context_graph_path;
@@ -70,7 +41,7 @@ function renderProjectSummary(project) {
70
41
  }
71
42
  if (project.artifacts && project.artifacts.length > 0) {
72
43
  console.log();
73
- console.log(chalk.bold(" Artifacts"));
44
+ console.log(chalk.bold(" Outputs"));
74
45
  const idWidth = Math.max(...project.artifacts.map((entry) => entry.artifact_id.length), 8);
75
46
  for (const artifact of project.artifacts) {
76
47
  const colored = statusColor(artifact.status)(artifact.status);
@@ -114,7 +85,7 @@ export const projectCommand = {
114
85
  }
115
86
  const projects = parsed.data.projects;
116
87
  if (projects.length === 0) {
117
- console.log(chalk.dim(" No Projects yet. Create one with `interf project create <id> --source <path>`."));
88
+ console.log(chalk.dim(" No Projects yet. Create one with `interf project create <id> --source <path> --intent \"<agent task>\"`."));
118
89
  return;
119
90
  }
120
91
  console.log();
@@ -124,6 +95,7 @@ export const projectCommand = {
124
95
  const sourceLabel = project.source.locator;
125
96
  const buildPlan = project.build_plan_id ?? "(no Build Plan)";
126
97
  console.log(` ${project.id}`);
98
+ console.log(chalk.dim(` agent task: ${project.intent}`));
127
99
  console.log(chalk.dim(` source: ${sourceLabel}`));
128
100
  console.log(chalk.dim(` Build Plan: ${buildPlan}`));
129
101
  }
@@ -131,11 +103,13 @@ export const projectCommand = {
131
103
  .command("create <project-id>", "Create a Project (Build Plan optional — select or draft it later)", (y) => y
132
104
  .positional("project-id", { type: "string", demandOption: true, describe: "Project id (lowercase, dash-separated)" })
133
105
  .option("source", { type: "string", demandOption: true, describe: "Path to the Source" })
106
+ .option("intent", { type: "string", demandOption: true, describe: "Agent task this Project's Context Graph should support" })
134
107
  .option("build-plan", { type: "string", describe: "Build Plan id. Optional — select later with `interf plan select`." }), async (args) => {
135
108
  const { url, token } = requireConnection(args);
136
109
  const sourceAbs = resolve(process.cwd(), args.source);
137
110
  const requestBody = {
138
111
  id: args.projectId,
112
+ intent: args.intent,
139
113
  source: { kind: "local-folder", locator: sourceAbs },
140
114
  ...(args.buildPlan ? { build_plan_id: args.buildPlan } : {}),
141
115
  };
@@ -150,7 +124,7 @@ export const projectCommand = {
150
124
  if (!args.buildPlan) {
151
125
  console.log(chalk.dim(` no Build Plan selected yet — pick or draft one before building:`));
152
126
  console.log(chalk.dim(` interf plan select ${args.projectId} <plan-id>`));
153
- console.log(chalk.dim(` interf plan draft ${args.projectId} --intent "..."`));
127
+ console.log(chalk.dim(` interf plan draft ${args.projectId}`));
154
128
  }
155
129
  const parsed = ProjectWireShapeSchema.safeParse(body);
156
130
  if (parsed.success && parsed.data.build_plan_id && parsed.data.context_graph.value) {
@@ -1,9 +1,8 @@
1
1
  import type { CommandModule } from "yargs";
2
- interface ResetArgs {
2
+ import { type ConnectionArgs } from "../lib/http-client.js";
3
+ interface ResetArgs extends ConnectionArgs {
3
4
  projectId: string;
4
5
  mode?: "build" | "all";
5
- url?: string;
6
- token?: string;
7
6
  }
8
7
  export declare const resetCommand: CommandModule<unknown, ResetArgs>;
9
8
  export {};
@@ -5,28 +5,7 @@
5
5
  * interf reset bristol --mode all # also clear Build Plan draft runs
6
6
  */
7
7
  import chalk from "chalk";
8
- import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/runtime/connection-config.js";
9
- function resolveConnection(args) {
10
- const conn = readActiveConnection({
11
- urlOverride: args.url,
12
- authTokenOverride: args.token,
13
- });
14
- if (!conn) {
15
- console.error(CONNECT_OR_ERROR_HINT);
16
- process.exit(1);
17
- }
18
- return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
19
- }
20
- async function callJson(url, token, init = {}) {
21
- const headers = new Headers(init.headers ?? {});
22
- if (token)
23
- headers.set("authorization", `Bearer ${token}`);
24
- if (init.body && !headers.has("content-type"))
25
- headers.set("content-type", "application/json");
26
- const response = await fetch(url, { ...init, headers });
27
- const raw = await response.text();
28
- return { status: response.status, raw };
29
- }
8
+ import { callJson, resolveConnection } from "../lib/http-client.js";
30
9
  export const resetCommand = {
31
10
  command: "reset <project-id>",
32
11
  describe: "Reset a Project's built output",
@@ -3,41 +3,13 @@
3
3
  *
4
4
  * interf runs ls [--project <id>]
5
5
  * interf runs status <run-id>
6
+ * interf runs events <run-id>
7
+ * interf runs artifacts <run-id>
6
8
  * interf runs cancel <run-id>
7
9
  */
8
10
  import chalk from "chalk";
9
- import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/runtime/connection-config.js";
10
- import { RunObservabilityListResponseSchema, RunObservabilityResourceSchema, } from "../../packages/runtime/schemas/index.js";
11
- function resolveConnection(args) {
12
- const conn = readActiveConnection({
13
- urlOverride: args.url,
14
- authTokenOverride: args.token,
15
- });
16
- if (!conn) {
17
- console.error(CONNECT_OR_ERROR_HINT);
18
- process.exit(1);
19
- }
20
- return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
21
- }
22
- async function callJson(url, token, init = {}) {
23
- const headers = new Headers(init.headers ?? {});
24
- if (token)
25
- headers.set("authorization", `Bearer ${token}`);
26
- if (init.body && !headers.has("content-type"))
27
- headers.set("content-type", "application/json");
28
- const response = await fetch(url, { ...init, headers });
29
- const raw = await response.text();
30
- let body = null;
31
- if (raw) {
32
- try {
33
- body = JSON.parse(raw);
34
- }
35
- catch {
36
- body = null;
37
- }
38
- }
39
- return { status: response.status, body, raw };
40
- }
11
+ import { callJson, resolveConnection } from "../lib/http-client.js";
12
+ import { RunArtifactsResponseSchema, RunEventsResponseSchema, RunObservabilityListResponseSchema, RunObservabilityResourceSchema, } from "../../packages/runtime/schemas/index.js";
41
13
  function runStatusColor(status) {
42
14
  if (status === "succeeded" || status === "completed")
43
15
  return chalk.green;
@@ -90,7 +62,7 @@ function renderRunStatus(run) {
90
62
  const artifacts = run.artifacts ?? [];
91
63
  if (artifacts.length > 0) {
92
64
  console.log();
93
- console.log(chalk.bold(" Artifacts"));
65
+ console.log(chalk.bold(" Outputs"));
94
66
  for (const artifact of artifacts.slice(0, 12)) {
95
67
  const stage = artifact.stage_id ? chalk.dim(` ← ${artifact.stage_id}`) : "";
96
68
  console.log(` ${artifact.label ?? "output"}: ${chalk.dim(artifact.path)}${stage}`);
@@ -121,6 +93,35 @@ function renderRunStatus(run) {
121
93
  console.log(chalk.dim(" Run with --json for the raw run resource."));
122
94
  console.log();
123
95
  }
96
+ function renderEvents(events) {
97
+ if (events.length === 0) {
98
+ console.log(chalk.dim(" No events recorded for this run."));
99
+ return;
100
+ }
101
+ console.log();
102
+ for (const event of events) {
103
+ // stage_id / path exist only on some event variants; read defensively.
104
+ const stageId = "stage_id" in event ? event.stage_id : undefined;
105
+ const path = "path" in event ? event.path : undefined;
106
+ const detail = [stageId, path].filter(Boolean).join(" · ");
107
+ console.log(` ${chalk.dim(event.timestamp)} ${chalk.bold(event.type)}${detail ? chalk.dim(` ${detail}`) : ""}`);
108
+ }
109
+ console.log();
110
+ console.log(chalk.dim(" Run with --json for full event payloads."));
111
+ console.log();
112
+ }
113
+ function renderArtifacts(artifacts) {
114
+ if (artifacts.length === 0) {
115
+ console.log(chalk.dim(" No artifacts recorded for this run."));
116
+ return;
117
+ }
118
+ console.log();
119
+ for (const artifact of artifacts) {
120
+ const stage = artifact.stage_id ? chalk.dim(` ← ${artifact.stage_id}`) : "";
121
+ console.log(` ${artifact.label ?? artifact.role}: ${chalk.dim(artifact.path)}${stage}`);
122
+ }
123
+ console.log();
124
+ }
124
125
  export const runsCommand = {
125
126
  command: "runs <subcommand>",
126
127
  describe: "Inspect durable Runs on the connected instance",
@@ -198,6 +199,58 @@ export const runsCommand = {
198
199
  process.exit(1);
199
200
  }
200
201
  renderRunStatus(parsed.data);
202
+ })
203
+ .command("events <run-id>", "Read the durable event log for a Build run", (y) => y
204
+ .positional("run-id", { type: "string", demandOption: true, describe: "Run id" })
205
+ .option("json", {
206
+ type: "boolean",
207
+ default: false,
208
+ describe: "Print the raw JSON event array",
209
+ }), async (args) => {
210
+ const { url, token } = resolveConnection(args);
211
+ const { status, body, raw } = await callJson(`${url}/v1/runs/${encodeURIComponent(args.runId)}/events`, token);
212
+ if (status !== 200) {
213
+ console.error(chalk.red(`Failed to read events for ${args.runId} (HTTP ${status}).`));
214
+ if (raw)
215
+ console.error(raw);
216
+ process.exit(1);
217
+ }
218
+ const parsed = RunEventsResponseSchema.safeParse(body);
219
+ if (!parsed.success) {
220
+ console.error(chalk.red(`Failed to parse events for ${args.runId}.`));
221
+ process.exit(1);
222
+ }
223
+ if (args.json) {
224
+ console.log(JSON.stringify(parsed.data.events, null, 2));
225
+ return;
226
+ }
227
+ renderEvents(parsed.data.events);
228
+ })
229
+ .command("artifacts <run-id>", "Read the artifact manifest for a finished Build run", (y) => y
230
+ .positional("run-id", { type: "string", demandOption: true, describe: "Run id" })
231
+ .option("json", {
232
+ type: "boolean",
233
+ default: false,
234
+ describe: "Print the raw JSON artifact array",
235
+ }), async (args) => {
236
+ const { url, token } = resolveConnection(args);
237
+ const { status, body, raw } = await callJson(`${url}/v1/runs/${encodeURIComponent(args.runId)}/artifacts`, token);
238
+ if (status !== 200) {
239
+ console.error(chalk.red(`Failed to read artifacts for ${args.runId} (HTTP ${status}).`));
240
+ if (raw)
241
+ console.error(raw);
242
+ process.exit(1);
243
+ }
244
+ const parsed = RunArtifactsResponseSchema.safeParse(body);
245
+ if (!parsed.success) {
246
+ console.error(chalk.red(`Failed to parse artifacts for ${args.runId}.`));
247
+ process.exit(1);
248
+ }
249
+ if (args.json) {
250
+ console.log(JSON.stringify(parsed.data.artifacts, null, 2));
251
+ return;
252
+ }
253
+ renderArtifacts(parsed.data.artifacts);
201
254
  })
202
255
  .command("cancel <run-id>", "Cancel a running run", (y) => y.positional("run-id", { type: "string", demandOption: true, describe: "Run id" }), async (args) => {
203
256
  const { url, token } = resolveConnection(args);
@@ -3,29 +3,8 @@
3
3
  */
4
4
  import chalk from "chalk";
5
5
  import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/runtime/connection-config.js";
6
+ import { callJsonSafe } from "../lib/http-client.js";
6
7
  import { InstanceResourceSchema, ProjectListResponseSchema, } from "../../packages/runtime/schemas/index.js";
7
- async function callJson(url, token) {
8
- const headers = new Headers();
9
- if (token)
10
- headers.set("authorization", `Bearer ${token}`);
11
- try {
12
- const response = await fetch(url, { headers });
13
- const raw = await response.text();
14
- let body = null;
15
- if (raw) {
16
- try {
17
- body = JSON.parse(raw);
18
- }
19
- catch {
20
- body = null;
21
- }
22
- }
23
- return { status: response.status, body };
24
- }
25
- catch {
26
- return { status: 0, body: null };
27
- }
28
- }
29
8
  export const statusCommand = {
30
9
  command: "status",
31
10
  describe: "Show connection + Project summary",
@@ -44,7 +23,7 @@ export const statusCommand = {
44
23
  }
45
24
  const url = conn.url.replace(/\/+$/, "");
46
25
  const token = conn.auth_token;
47
- const instance = await callJson(`${url}/v1/instance`, token);
26
+ const instance = await callJsonSafe(`${url}/v1/instance`, token);
48
27
  if (instance.status === 0) {
49
28
  console.error(chalk.red(`Connection ${url} is unreachable.`));
50
29
  console.error(CONNECT_OR_ERROR_HINT);
@@ -67,7 +46,7 @@ export const statusCommand = {
67
46
  console.log(` Uptime: ${instanceResource.data.uptime_seconds}s`);
68
47
  }
69
48
  console.log(` Auth: ${instanceResource.data.auth_required ? "required (token in connection.json)" : "open (explicit dev/test mode)"}`);
70
- const projects = await callJson(`${url}/v1/projects`, token);
49
+ const projects = await callJsonSafe(`${url}/v1/projects`, token);
71
50
  const parsedProjects = ProjectListResponseSchema.safeParse(projects.body);
72
51
  if (!parsedProjects.success) {
73
52
  console.error(chalk.red("Connected service returned an invalid Project list."));
@@ -5,37 +5,9 @@
5
5
  * interf traces show <trace-kind> --project <id>
6
6
  */
7
7
  import chalk from "chalk";
8
- import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/runtime/connection-config.js";
8
+ import { callJson, resolveConnection } from "../lib/http-client.js";
9
9
  import { TracesSchema, } from "../../packages/contracts/lib/project-schema.js";
10
10
  import { projectSubresourcePath } from "../../packages/runtime/service/routes.js";
11
- function resolveConnection(args) {
12
- const conn = readActiveConnection({
13
- urlOverride: args.url,
14
- authTokenOverride: args.token,
15
- });
16
- if (!conn) {
17
- console.error(CONNECT_OR_ERROR_HINT);
18
- process.exit(1);
19
- }
20
- return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
21
- }
22
- async function callJson(url, token) {
23
- const headers = new Headers();
24
- if (token)
25
- headers.set("authorization", `Bearer ${token}`);
26
- const response = await fetch(url, { headers });
27
- const raw = await response.text();
28
- let body = null;
29
- if (raw) {
30
- try {
31
- body = JSON.parse(raw);
32
- }
33
- catch {
34
- body = null;
35
- }
36
- }
37
- return { status: response.status, body, raw };
38
- }
39
11
  function tracesUrl(baseUrl, projectId) {
40
12
  return `${baseUrl}${projectSubresourcePath(projectId, "traces")}`;
41
13
  }
@@ -17,29 +17,8 @@ import { homedir } from "node:os";
17
17
  import { basename, resolve } from "node:path";
18
18
  import { spawn } from "node:child_process";
19
19
  import { ConnectionRecordSchema, readActiveConnection, writeConnection, } from "../../packages/runtime/connection-config.js";
20
+ import { callJsonSafe } from "../lib/http-client.js";
20
21
  import { LOCAL_SERVICE_DEFAULT_HOST, LOCAL_SERVICE_DEFAULT_PORT } from "../../packages/runtime/service/routes.js";
21
- async function callJson(url, token) {
22
- const headers = new Headers();
23
- if (token)
24
- headers.set("authorization", `Bearer ${token}`);
25
- try {
26
- const response = await fetch(url, { headers });
27
- const raw = await response.text();
28
- let body = null;
29
- if (raw) {
30
- try {
31
- body = JSON.parse(raw);
32
- }
33
- catch {
34
- body = null;
35
- }
36
- }
37
- return { status: response.status, body };
38
- }
39
- catch {
40
- return { status: 0, body: null };
41
- }
42
- }
43
22
  function spawnInterf(args) {
44
23
  return new Promise((resolveSpawn) => {
45
24
  const child = spawn(process.argv[1] ?? "interf", args, { stdio: "inherit" });
@@ -233,7 +212,7 @@ async function promptForConnection(reason) {
233
212
  auth_token: String(tokenValue ?? "").trim() || null,
234
213
  });
235
214
  const url = record.url.replace(/\/+$/, "");
236
- const probe = await callJson(`${url}/health`, record.auth_token);
215
+ const probe = await callJsonSafe(`${url}/health`, record.auth_token);
237
216
  if (probe.status === 0) {
238
217
  return promptForConnection(`Connection ${url} is unreachable.`);
239
218
  }
@@ -308,10 +287,17 @@ async function flowCreateProject(conn) {
308
287
  const sourcePath = await promptSourcePath();
309
288
  if (!sourcePath)
310
289
  return null;
290
+ const intent = await p.text({
291
+ message: "What should the agent do with this Source?",
292
+ placeholder: "Compare the launch timeline against approval notes and produce a sourced handoff.",
293
+ validate: (value) => String(value).trim().length > 0 ? undefined : "Agent task is required.",
294
+ });
295
+ if (p.isCancel(intent))
296
+ return null;
311
297
  // Offer saved Build Plans, but keep selection optional. The agent-first
312
298
  // path usually creates the Project from Source first, then drafts a
313
299
  // custom Build Plan for review.
314
- const buildPlansResp = await callJson(`${conn.url}/v1/build-plans`, conn.token);
300
+ const buildPlansResp = await callJsonSafe(`${conn.url}/v1/build-plans`, conn.token);
315
301
  const buildPlans = buildPlansResp.body?.build_plans ?? [];
316
302
  const buildPlanOptions = buildPlans
317
303
  .map((plan) => ({ value: plan.build_plan_id ?? plan.id ?? "", label: `${plan.build_plan_id ?? plan.id ?? "(?)"}${plan.label ? ` - ${plan.label}` : ""}` }))
@@ -369,6 +355,8 @@ async function flowCreateProject(conn) {
369
355
  String(projectId),
370
356
  "--source",
371
357
  resolve(String(sourcePath)),
358
+ "--intent",
359
+ String(intent),
372
360
  ...(buildPlanId ? ["--build-plan", buildPlanId] : []),
373
361
  ]);
374
362
  if (exitCode !== 0)
@@ -376,7 +364,7 @@ async function flowCreateProject(conn) {
376
364
  return { id: String(projectId), buildPlanId };
377
365
  }
378
366
  async function pickProject(conn, message) {
379
- const projects = await callJson(`${conn.url}/v1/projects`, conn.token);
367
+ const projects = await callJsonSafe(`${conn.url}/v1/projects`, conn.token);
380
368
  const list = projects.body?.projects ?? [];
381
369
  if (list.length === 0) {
382
370
  console.log(chalk.dim(" No Projects yet. Create one first."));
@@ -590,8 +578,8 @@ async function showAgentInstallCards() {
590
578
  return "rerun";
591
579
  }
592
580
  async function fetchAgentState(conn) {
593
- const instance = await callJson(`${conn.url}/v1/instance`, conn.token);
594
- const agentsResponse = await callJson(`${conn.url}/v1/agents`, conn.token);
581
+ const instance = await callJsonSafe(`${conn.url}/v1/instance`, conn.token);
582
+ const agentsResponse = await callJsonSafe(`${conn.url}/v1/agents`, conn.token);
595
583
  if (instance.status !== 200)
596
584
  return null;
597
585
  // Older engines don't expose /v1/agents. Surface the gap explicitly so
@@ -632,7 +620,7 @@ async function runWizard(args) {
632
620
  }
633
621
  else {
634
622
  const url = initial.url.replace(/\/+$/, "");
635
- const probe = await callJson(`${url}/health`, initial.auth_token);
623
+ const probe = await callJsonSafe(`${url}/health`, initial.auth_token);
636
624
  if (probe.status === 0) {
637
625
  if (!args.url && await probeHealth(DEFAULT_ENGINE_URL)) {
638
626
  conn = await connectToReachableEngine(DEFAULT_ENGINE_URL);
@@ -655,7 +643,7 @@ async function runWizard(args) {
655
643
  if (!conn) {
656
644
  return;
657
645
  }
658
- const instance = await callJson(`${conn.url}/v1/instance`, conn.token);
646
+ const instance = await callJsonSafe(`${conn.url}/v1/instance`, conn.token);
659
647
  console.log();
660
648
  console.log(chalk.bold(` Connected to ${conn.url}`));
661
649
  console.log(chalk.dim(` ${instance.body?.project_count ?? 0} project(s)`));
@@ -0,0 +1,39 @@
1
+ /** Per-call connection overrides parsed from `--url` / `--token` flags. */
2
+ export interface ConnectionArgs {
3
+ url?: string;
4
+ token?: string;
5
+ }
6
+ /** Resolved connection: normalized base URL plus an optional bearer token. */
7
+ export interface ResolvedConnection {
8
+ url: string;
9
+ token: string | null;
10
+ }
11
+ /**
12
+ * Resolve the active connection or exit non-zero with the connect-or-error
13
+ * hint. Mutating CLI commands never auto-start a service, so absence here is a
14
+ * hard error.
15
+ */
16
+ export declare function resolveConnection(args: ConnectionArgs): ResolvedConnection;
17
+ /** Outcome of a JSON request: HTTP status, parsed body (null on empty/parse-fail), and the raw text. */
18
+ export interface JsonResponse<T> {
19
+ status: number;
20
+ body: T | null;
21
+ raw: string;
22
+ }
23
+ /**
24
+ * Issue a request and parse the response body as JSON.
25
+ *
26
+ * - Attaches the bearer token and a JSON content-type for bodied requests.
27
+ * - Returns `body: null` when the response is empty or not valid JSON; callers
28
+ * inspect `status`/`raw` to handle those cases.
29
+ * - Network/transport errors reject (callers that need reachability probing use
30
+ * {@link callJsonSafe}).
31
+ */
32
+ export declare function callJson<T = unknown>(url: string, token: string | null, init?: RequestInit): Promise<JsonResponse<T>>;
33
+ /**
34
+ * Reachability-tolerant variant of {@link callJson}. A network/transport error
35
+ * is reported as `status: 0` instead of rejecting, so probe paths (e.g.
36
+ * `interf status`, the wizard) can distinguish "unreachable" from an HTTP
37
+ * error.
38
+ */
39
+ export declare function callJsonSafe<T = unknown>(url: string, token: string | null, init?: RequestInit): Promise<JsonResponse<T>>;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * CLI-owned HTTP + connection helpers.
3
+ *
4
+ * Every `interf` command is a thin authorized client of one connected
5
+ * instance. The connection-resolution and JSON-fetch logic was previously
6
+ * copy-pasted into every command file; this module is the single definition
7
+ * the commands import.
8
+ *
9
+ * This is deliberately CLI-scoped. The runtime's own `fetchJson`
10
+ * (`runtime/client.ts`) is private and 500ms-timeout-scoped — it is not the
11
+ * reuse target for interactive CLI calls, which must not impose a short
12
+ * timeout on long Build/benchmark requests.
13
+ */
14
+ import { CONNECT_OR_ERROR_HINT, readActiveConnection, } from "../../packages/runtime/connection-config.js";
15
+ /**
16
+ * Resolve the active connection or exit non-zero with the connect-or-error
17
+ * hint. Mutating CLI commands never auto-start a service, so absence here is a
18
+ * hard error.
19
+ */
20
+ export function resolveConnection(args) {
21
+ const conn = readActiveConnection({
22
+ urlOverride: args.url,
23
+ authTokenOverride: args.token,
24
+ });
25
+ if (!conn) {
26
+ console.error(CONNECT_OR_ERROR_HINT);
27
+ process.exit(1);
28
+ }
29
+ return { url: conn.url.replace(/\/+$/, ""), token: conn.auth_token };
30
+ }
31
+ /**
32
+ * Issue a request and parse the response body as JSON.
33
+ *
34
+ * - Attaches the bearer token and a JSON content-type for bodied requests.
35
+ * - Returns `body: null` when the response is empty or not valid JSON; callers
36
+ * inspect `status`/`raw` to handle those cases.
37
+ * - Network/transport errors reject (callers that need reachability probing use
38
+ * {@link callJsonSafe}).
39
+ */
40
+ export async function callJson(url, token, init = {}) {
41
+ const headers = new Headers(init.headers ?? {});
42
+ if (token)
43
+ headers.set("authorization", `Bearer ${token}`);
44
+ if (init.body && !headers.has("content-type")) {
45
+ headers.set("content-type", "application/json");
46
+ }
47
+ const response = await fetch(url, { ...init, headers });
48
+ const raw = await response.text();
49
+ let body = null;
50
+ if (raw.length > 0) {
51
+ try {
52
+ body = JSON.parse(raw);
53
+ }
54
+ catch {
55
+ body = null;
56
+ }
57
+ }
58
+ return { status: response.status, body, raw };
59
+ }
60
+ /**
61
+ * Reachability-tolerant variant of {@link callJson}. A network/transport error
62
+ * is reported as `status: 0` instead of rejecting, so probe paths (e.g.
63
+ * `interf status`, the wizard) can distinguish "unreachable" from an HTTP
64
+ * error.
65
+ */
66
+ export async function callJsonSafe(url, token, init = {}) {
67
+ try {
68
+ return await callJson(url, token, init);
69
+ }
70
+ catch {
71
+ return { status: 0, body: null, raw: "" };
72
+ }
73
+ }