@interf/compiler 0.7.2 → 0.9.1

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 (306) hide show
  1. package/README.md +141 -99
  2. package/TRADEMARKS.md +1 -1
  3. package/agent-skills/interf-actions/SKILL.md +71 -0
  4. package/agent-skills/interf-actions/references/cli.md +190 -0
  5. package/apps/compiler-ui/.next/server/app/index.html +1 -0
  6. package/apps/compiler-ui/.next/static/XWKL548yXD_UOG4ID9G3J/_buildManifest.js +11 -0
  7. package/apps/compiler-ui/.next/static/XWKL548yXD_UOG4ID9G3J/_clientMiddlewareManifest.js +1 -0
  8. package/apps/compiler-ui/.next/static/XWKL548yXD_UOG4ID9G3J/_ssgManifest.js +1 -0
  9. package/apps/compiler-ui/.next/static/chunks/03~yq9q893hmn.js +1 -0
  10. package/apps/compiler-ui/.next/static/chunks/06z~l3kwb891e.js +1 -0
  11. package/apps/compiler-ui/.next/static/chunks/08g7lvje.te.u.js +1 -0
  12. package/apps/compiler-ui/.next/static/chunks/08m7vf5asqlsm.js +91 -0
  13. package/apps/compiler-ui/.next/static/chunks/0_i-3_5l9t2qe.js +1 -0
  14. package/apps/compiler-ui/.next/static/chunks/0b-ywny_j0g~0.js +1 -0
  15. package/apps/compiler-ui/.next/static/chunks/0b52v41o1gixx.js +1 -0
  16. package/apps/compiler-ui/.next/static/chunks/0fgt_8knmicoz.js +124 -0
  17. package/apps/compiler-ui/.next/static/chunks/0gpzgsv0w.q~m.js +31 -0
  18. package/apps/compiler-ui/.next/static/chunks/0ilwfezfvu6~-.js +1 -0
  19. package/apps/compiler-ui/.next/static/chunks/0n51hrfoufc7g.js +1 -0
  20. package/apps/compiler-ui/.next/static/chunks/0ti_66mx7~w2-.js +5 -0
  21. package/apps/compiler-ui/.next/static/chunks/0xxmf45eskdt~.css +1 -0
  22. package/apps/compiler-ui/.next/static/chunks/0y5z3t-z1c8ks.js.map +5 -0
  23. package/apps/compiler-ui/.next/static/chunks/13g~4mamjft.c.css +3 -0
  24. package/apps/compiler-ui/.next/static/chunks/14wtz~vq25~qq.js +1 -0
  25. package/apps/compiler-ui/.next/static/chunks/turbopack-109rtik40vwh5.js +1 -0
  26. package/apps/compiler-ui/.next/static/chunks/turbopack-10e~t1yzi4svj.js +1 -0
  27. package/apps/compiler-ui/.next/static/chunks/turbopack-worker-0sjn--fhq~1cg.js +1 -0
  28. package/apps/compiler-ui/.next/static/media/GeistMono_Variable.p.17jn9btb_52pq.woff2 +0 -0
  29. package/apps/compiler-ui/.next/static/media/Geist_Variable-s.p.0-te~ja_gpvcf.woff2 +0 -0
  30. package/apps/compiler-ui/.next/static/media/worker.102zas1s52_pf.js +109 -0
  31. package/builtin-workflows/interf/README.md +8 -8
  32. package/builtin-workflows/interf/compile/stages/shape/SKILL.md +6 -6
  33. package/builtin-workflows/interf/compile/stages/structure/SKILL.md +1 -1
  34. package/builtin-workflows/interf/improve/SKILL.md +2 -2
  35. package/builtin-workflows/interf/use/query/SKILL.md +2 -2
  36. package/builtin-workflows/interf/workflow.json +9 -9
  37. package/builtin-workflows/interf/workflow.schema.json +2 -2
  38. package/dist/cli/commands/check-draft.d.ts +5 -4
  39. package/dist/cli/commands/check-draft.js +18 -17
  40. package/dist/cli/commands/compile-controller.d.ts +3 -0
  41. package/dist/cli/commands/compile-controller.js +53 -45
  42. package/dist/cli/commands/compile.js +83 -27
  43. package/dist/cli/commands/compiled-flow.d.ts +3 -0
  44. package/dist/cli/commands/compiled-flow.js +9 -7
  45. package/dist/cli/commands/control-path.d.ts +11 -0
  46. package/dist/cli/commands/control-path.js +72 -0
  47. package/dist/cli/commands/create-workflow-wizard.d.ts +12 -0
  48. package/dist/cli/commands/create-workflow-wizard.js +232 -66
  49. package/dist/cli/commands/create.js +70 -46
  50. package/dist/cli/commands/default.js +5 -3
  51. package/dist/cli/commands/doctor.js +5 -5
  52. package/dist/cli/commands/executor-flow.js +1 -1
  53. package/dist/cli/commands/init.js +362 -101
  54. package/dist/cli/commands/list.js +8 -7
  55. package/dist/cli/commands/preparation-selection.d.ts +6 -0
  56. package/dist/cli/commands/preparation-selection.js +11 -0
  57. package/dist/cli/commands/reset.js +3 -3
  58. package/dist/cli/commands/source-config-wizard.d.ts +4 -4
  59. package/dist/cli/commands/source-config-wizard.js +175 -200
  60. package/dist/cli/commands/status.js +116 -8
  61. package/dist/cli/commands/test-flow.d.ts +1 -1
  62. package/dist/cli/commands/test-flow.js +35 -33
  63. package/dist/cli/commands/test.d.ts +4 -0
  64. package/dist/cli/commands/test.js +95 -58
  65. package/dist/cli/commands/verify.js +7 -7
  66. package/dist/cli/commands/web.d.ts +11 -0
  67. package/dist/cli/commands/web.js +373 -0
  68. package/dist/cli/index.d.ts +2 -1
  69. package/dist/cli/index.js +3 -1
  70. package/dist/index.d.ts +4 -2
  71. package/dist/index.js +3 -1
  72. package/dist/packages/agents/lib/execution.js +4 -2
  73. package/dist/packages/agents/lib/executors.d.ts +1 -0
  74. package/dist/packages/agents/lib/executors.js +1 -0
  75. package/dist/packages/agents/lib/render.d.ts +2 -2
  76. package/dist/packages/agents/lib/render.js +10 -9
  77. package/dist/packages/agents/lib/shells.d.ts +3 -11
  78. package/dist/packages/agents/lib/shells.js +58 -106
  79. package/dist/packages/agents/lib/types.d.ts +1 -0
  80. package/dist/packages/compiler/compiled-paths.d.ts +4 -1
  81. package/dist/packages/compiler/compiled-paths.js +8 -2
  82. package/dist/packages/compiler/compiled-pipeline.d.ts +7 -0
  83. package/dist/packages/compiler/compiled-pipeline.js +15 -4
  84. package/dist/packages/compiler/compiled-schema.js +1 -1
  85. package/dist/packages/compiler/compiled-stage-plan.d.ts +2 -2
  86. package/dist/packages/compiler/compiled-stage-plan.js +4 -4
  87. package/dist/packages/compiler/compiled-stage-runner.d.ts +5 -0
  88. package/dist/packages/compiler/compiled-stage-runner.js +50 -2
  89. package/dist/packages/compiler/compiled-target.d.ts +1 -1
  90. package/dist/packages/compiler/compiled-target.js +2 -2
  91. package/dist/packages/compiler/lib/schema.d.ts +161 -1
  92. package/dist/packages/compiler/lib/schema.js +87 -1
  93. package/dist/packages/compiler/raw-snapshot.d.ts +9 -2
  94. package/dist/packages/compiler/runtime-acceptance.js +1 -1
  95. package/dist/packages/compiler/runtime-contracts.js +2 -2
  96. package/dist/packages/compiler/runtime-prompt.js +7 -7
  97. package/dist/packages/compiler/runtime-reconcile.js +3 -3
  98. package/dist/packages/compiler/runtime-runs.js +3 -0
  99. package/dist/packages/compiler/runtime-types.d.ts +1 -0
  100. package/dist/packages/compiler/state-health.js +1 -1
  101. package/dist/packages/compiler/state-view.js +2 -2
  102. package/dist/packages/compiler/validate-compiled.js +11 -9
  103. package/dist/packages/execution/adapters.d.ts +15 -0
  104. package/dist/packages/execution/adapters.js +1 -0
  105. package/dist/packages/execution/events.d.ts +8 -0
  106. package/dist/packages/execution/events.js +16 -0
  107. package/dist/packages/execution/index.d.ts +9 -0
  108. package/dist/packages/execution/index.js +6 -0
  109. package/dist/packages/execution/lib/schema.d.ts +1554 -0
  110. package/dist/packages/execution/lib/schema.js +319 -0
  111. package/dist/packages/local-service/action-values.d.ts +23 -0
  112. package/dist/packages/local-service/action-values.js +31 -0
  113. package/dist/packages/local-service/client.d.ts +119 -0
  114. package/dist/packages/local-service/client.js +356 -0
  115. package/dist/packages/local-service/index.d.ts +15 -0
  116. package/dist/packages/local-service/index.js +11 -0
  117. package/dist/packages/local-service/lib/schema.d.ts +7355 -0
  118. package/dist/packages/local-service/lib/schema.js +636 -0
  119. package/dist/packages/local-service/routes.d.ts +27 -0
  120. package/dist/packages/local-service/routes.js +32 -0
  121. package/dist/packages/local-service/runtime.d.ts +134 -0
  122. package/dist/packages/local-service/runtime.js +2841 -0
  123. package/dist/packages/local-service/server.d.ts +17 -0
  124. package/dist/packages/local-service/server.js +572 -0
  125. package/dist/packages/project-model/index.d.ts +2 -1
  126. package/dist/packages/project-model/index.js +1 -0
  127. package/dist/packages/project-model/interf-detect.d.ts +6 -2
  128. package/dist/packages/project-model/interf-detect.js +48 -19
  129. package/dist/packages/project-model/interf-scaffold.d.ts +1 -0
  130. package/dist/packages/project-model/interf-scaffold.js +39 -17
  131. package/dist/packages/project-model/interf.d.ts +2 -2
  132. package/dist/packages/project-model/interf.js +2 -2
  133. package/dist/packages/project-model/lib/schema.d.ts +80 -6
  134. package/dist/packages/project-model/lib/schema.js +29 -19
  135. package/dist/packages/project-model/project-paths.d.ts +3 -1
  136. package/dist/packages/project-model/project-paths.js +6 -2
  137. package/dist/packages/project-model/source-config.d.ts +25 -11
  138. package/dist/packages/project-model/source-config.js +152 -82
  139. package/dist/packages/project-model/source-folders.d.ts +11 -0
  140. package/dist/packages/project-model/source-folders.js +110 -0
  141. package/dist/packages/testing/test-execution.js +5 -5
  142. package/dist/packages/testing/test-paths.js +4 -3
  143. package/dist/packages/workflow-authoring/workflow-authoring.d.ts +4 -6
  144. package/dist/packages/workflow-authoring/workflow-authoring.js +46 -85
  145. package/dist/packages/workflow-authoring/workflow-edit-session.d.ts +2 -0
  146. package/dist/packages/workflow-authoring/workflow-edit-session.js +83 -49
  147. package/dist/packages/workflow-authoring/workflow-improvement.js +2 -1
  148. package/dist/packages/workflow-package/context-interface.js +2 -2
  149. package/dist/packages/workflow-package/interf-workflow-package.d.ts +6 -0
  150. package/dist/packages/workflow-package/interf-workflow-package.js +115 -8
  151. package/dist/packages/workflow-package/local-workflows.js +33 -17
  152. package/dist/packages/workflow-package/workflow-definitions.d.ts +5 -5
  153. package/dist/packages/workflow-package/workflow-definitions.js +23 -22
  154. package/dist/packages/workflow-package/workflow-helpers.js +10 -6
  155. package/dist/packages/workflow-package/workflow-review-paths.js +5 -1
  156. package/dist/packages/workflow-package/workflow-stage-runner.d.ts +1 -0
  157. package/dist/packages/workflow-package/workflow-stage-runner.js +2 -0
  158. package/package.json +18 -4
  159. package/dist/cli/commands/dataset-selection.d.ts +0 -6
  160. package/dist/cli/commands/dataset-selection.js +0 -11
  161. package/dist/lib/agent-args.d.ts +0 -1
  162. package/dist/lib/agent-args.js +0 -1
  163. package/dist/lib/agent-constants.d.ts +0 -1
  164. package/dist/lib/agent-constants.js +0 -1
  165. package/dist/lib/agent-detection.d.ts +0 -1
  166. package/dist/lib/agent-detection.js +0 -1
  167. package/dist/lib/agent-execution.d.ts +0 -1
  168. package/dist/lib/agent-execution.js +0 -1
  169. package/dist/lib/agent-logs.d.ts +0 -1
  170. package/dist/lib/agent-logs.js +0 -1
  171. package/dist/lib/agent-preflight.d.ts +0 -1
  172. package/dist/lib/agent-preflight.js +0 -1
  173. package/dist/lib/agent-render.d.ts +0 -1
  174. package/dist/lib/agent-render.js +0 -1
  175. package/dist/lib/agent-shells.d.ts +0 -1
  176. package/dist/lib/agent-shells.js +0 -1
  177. package/dist/lib/agent-status.d.ts +0 -1
  178. package/dist/lib/agent-status.js +0 -1
  179. package/dist/lib/agent-types.d.ts +0 -1
  180. package/dist/lib/agent-types.js +0 -1
  181. package/dist/lib/agents.d.ts +0 -1
  182. package/dist/lib/agents.js +0 -1
  183. package/dist/lib/builtin-compiled-workflow.d.ts +0 -1
  184. package/dist/lib/builtin-compiled-workflow.js +0 -1
  185. package/dist/lib/chart-guidance.d.ts +0 -1
  186. package/dist/lib/chart-guidance.js +0 -1
  187. package/dist/lib/compiled-compile.d.ts +0 -1
  188. package/dist/lib/compiled-compile.js +0 -1
  189. package/dist/lib/compiled-paths.d.ts +0 -1
  190. package/dist/lib/compiled-paths.js +0 -3
  191. package/dist/lib/compiled-raw.d.ts +0 -1
  192. package/dist/lib/compiled-raw.js +0 -3
  193. package/dist/lib/compiled-reset.d.ts +0 -1
  194. package/dist/lib/compiled-reset.js +0 -3
  195. package/dist/lib/compiled-schema.d.ts +0 -1
  196. package/dist/lib/compiled-schema.js +0 -1
  197. package/dist/lib/discovery.d.ts +0 -1
  198. package/dist/lib/discovery.js +0 -1
  199. package/dist/lib/execution-profile.d.ts +0 -1
  200. package/dist/lib/execution-profile.js +0 -1
  201. package/dist/lib/executors.d.ts +0 -1
  202. package/dist/lib/executors.js +0 -1
  203. package/dist/lib/filesystem.d.ts +0 -1
  204. package/dist/lib/filesystem.js +0 -1
  205. package/dist/lib/interf-bootstrap.d.ts +0 -1
  206. package/dist/lib/interf-bootstrap.js +0 -3
  207. package/dist/lib/interf-detect.d.ts +0 -1
  208. package/dist/lib/interf-detect.js +0 -3
  209. package/dist/lib/interf-scaffold.d.ts +0 -1
  210. package/dist/lib/interf-scaffold.js +0 -3
  211. package/dist/lib/interf-workflow-package.d.ts +0 -1
  212. package/dist/lib/interf-workflow-package.js +0 -1
  213. package/dist/lib/interf.d.ts +0 -1
  214. package/dist/lib/interf.js +0 -3
  215. package/dist/lib/local-workflows.d.ts +0 -1
  216. package/dist/lib/local-workflows.js +0 -1
  217. package/dist/lib/logger.d.ts +0 -1
  218. package/dist/lib/logger.js +0 -1
  219. package/dist/lib/package-root.d.ts +0 -1
  220. package/dist/lib/package-root.js +0 -1
  221. package/dist/lib/parse.d.ts +0 -1
  222. package/dist/lib/parse.js +0 -1
  223. package/dist/lib/project-paths.d.ts +0 -1
  224. package/dist/lib/project-paths.js +0 -3
  225. package/dist/lib/runtime-acceptance.d.ts +0 -1
  226. package/dist/lib/runtime-acceptance.js +0 -1
  227. package/dist/lib/runtime-contracts.d.ts +0 -1
  228. package/dist/lib/runtime-contracts.js +0 -1
  229. package/dist/lib/runtime-inventory.d.ts +0 -1
  230. package/dist/lib/runtime-inventory.js +0 -1
  231. package/dist/lib/runtime-paths.d.ts +0 -1
  232. package/dist/lib/runtime-paths.js +0 -1
  233. package/dist/lib/runtime-prompt.d.ts +0 -1
  234. package/dist/lib/runtime-prompt.js +0 -1
  235. package/dist/lib/runtime-reconcile.d.ts +0 -1
  236. package/dist/lib/runtime-reconcile.js +0 -1
  237. package/dist/lib/runtime-runs.d.ts +0 -1
  238. package/dist/lib/runtime-runs.js +0 -1
  239. package/dist/lib/runtime-types.d.ts +0 -1
  240. package/dist/lib/runtime-types.js +0 -1
  241. package/dist/lib/runtime.d.ts +0 -1
  242. package/dist/lib/runtime.js +0 -1
  243. package/dist/lib/schema.d.ts +0 -4
  244. package/dist/lib/schema.js +0 -6
  245. package/dist/lib/source-config.d.ts +0 -1
  246. package/dist/lib/source-config.js +0 -3
  247. package/dist/lib/state-artifacts.d.ts +0 -1
  248. package/dist/lib/state-artifacts.js +0 -1
  249. package/dist/lib/state-health.d.ts +0 -1
  250. package/dist/lib/state-health.js +0 -1
  251. package/dist/lib/state-io.d.ts +0 -1
  252. package/dist/lib/state-io.js +0 -1
  253. package/dist/lib/state-paths.d.ts +0 -1
  254. package/dist/lib/state-paths.js +0 -1
  255. package/dist/lib/state-view.d.ts +0 -1
  256. package/dist/lib/state-view.js +0 -1
  257. package/dist/lib/state.d.ts +0 -1
  258. package/dist/lib/state.js +0 -1
  259. package/dist/lib/test-execution.d.ts +0 -1
  260. package/dist/lib/test-execution.js +0 -3
  261. package/dist/lib/test-matrices.d.ts +0 -1
  262. package/dist/lib/test-matrices.js +0 -3
  263. package/dist/lib/test-paths.d.ts +0 -1
  264. package/dist/lib/test-paths.js +0 -3
  265. package/dist/lib/test-profile-presets.d.ts +0 -1
  266. package/dist/lib/test-profile-presets.js +0 -3
  267. package/dist/lib/test-sandbox.d.ts +0 -1
  268. package/dist/lib/test-sandbox.js +0 -3
  269. package/dist/lib/test-specs.d.ts +0 -1
  270. package/dist/lib/test-specs.js +0 -3
  271. package/dist/lib/test-targets.d.ts +0 -1
  272. package/dist/lib/test-targets.js +0 -3
  273. package/dist/lib/test-types.d.ts +0 -1
  274. package/dist/lib/test-types.js +0 -3
  275. package/dist/lib/test.d.ts +0 -1
  276. package/dist/lib/test.js +0 -3
  277. package/dist/lib/util.d.ts +0 -1
  278. package/dist/lib/util.js +0 -1
  279. package/dist/lib/validate-compiled.d.ts +0 -1
  280. package/dist/lib/validate-compiled.js +0 -1
  281. package/dist/lib/validate-helpers.d.ts +0 -1
  282. package/dist/lib/validate-helpers.js +0 -1
  283. package/dist/lib/validate.d.ts +0 -1
  284. package/dist/lib/validate.js +0 -1
  285. package/dist/lib/workflow-authoring.d.ts +0 -1
  286. package/dist/lib/workflow-authoring.js +0 -1
  287. package/dist/lib/workflow-definitions.d.ts +0 -1
  288. package/dist/lib/workflow-definitions.js +0 -1
  289. package/dist/lib/workflow-edit-session.d.ts +0 -1
  290. package/dist/lib/workflow-edit-session.js +0 -1
  291. package/dist/lib/workflow-edit-utils.d.ts +0 -1
  292. package/dist/lib/workflow-edit-utils.js +0 -1
  293. package/dist/lib/workflow-helpers.d.ts +0 -1
  294. package/dist/lib/workflow-helpers.js +0 -1
  295. package/dist/lib/workflow-improvement.d.ts +0 -1
  296. package/dist/lib/workflow-improvement.js +0 -1
  297. package/dist/lib/workflow-primitives.d.ts +0 -1
  298. package/dist/lib/workflow-primitives.js +0 -1
  299. package/dist/lib/workflow-review-paths.d.ts +0 -1
  300. package/dist/lib/workflow-review-paths.js +0 -1
  301. package/dist/lib/workflow-stage-policy.d.ts +0 -1
  302. package/dist/lib/workflow-stage-policy.js +0 -1
  303. package/dist/lib/workflow-stage-runner.d.ts +0 -1
  304. package/dist/lib/workflow-stage-runner.js +0 -1
  305. package/dist/lib/workflows.d.ts +0 -1
  306. package/dist/lib/workflows.js +0 -1
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
3
- import { join, relative, resolve, sep } from "node:path";
3
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
4
4
  import { refreshCompiledBootstrapGuidance } from "../agents/lib/compiled-bootstrap.js";
5
5
  import { readInterfConfig, } from "./interf.js";
6
6
  import { seedCompiledWorkflowPackage } from "../workflow-package/interf-workflow-package.js";
@@ -8,13 +8,21 @@ import { readJsonFileWithSchema } from "../shared/parse.js";
8
8
  import { getCompiledWorkflow } from "../workflow-package/workflow-definitions.js";
9
9
  import { SourceFolderConfigSchema, } from "./lib/schema.js";
10
10
  import { slugify } from "../shared/naming.js";
11
- import { assertPathWithinRoot } from "../shared/path-guards.js";
11
+ import { assertPathWithinRoot, isPathWithinRoot } from "../shared/path-guards.js";
12
12
  import { defaultControlPathForCompiled, resolveSourceControlPathForCompiled, compiledInterfConfigPath, compiledInterfRoot, } from "../compiler/compiled-paths.js";
13
+ import { projectInterfRoot, PROJECT_INTERF_DIR } from "./project-paths.js";
13
14
  export const SOURCE_FOLDER_CONFIG_FILE = "interf.json";
14
- function sourceConfigPath(sourcePath) {
15
- return join(sourcePath, SOURCE_FOLDER_CONFIG_FILE);
15
+ export const SOURCE_FOLDER_CONFIG_PATH = `${PROJECT_INTERF_DIR}/${SOURCE_FOLDER_CONFIG_FILE}`;
16
+ export function sourceFolderConfigPath(sourcePath) {
17
+ return join(projectInterfRoot(sourcePath), SOURCE_FOLDER_CONFIG_FILE);
16
18
  }
17
- function normalizeTruthChecks(cases) {
19
+ export function resolveSourceFolderConfigPath(sourcePath) {
20
+ return sourceFolderConfigPath(sourcePath);
21
+ }
22
+ function readSourceFolderConfigFile(filePath) {
23
+ return readJsonFileWithSchema(filePath, "Interf project config", SourceFolderConfigSchema);
24
+ }
25
+ function normalizeReadinessChecks(cases) {
18
26
  const seen = new Set();
19
27
  return cases.map((caseSpec, index) => {
20
28
  const baseId = slugify(caseSpec.id ?? caseSpec.question) || `check-${index + 1}`;
@@ -34,7 +42,7 @@ function normalizeTruthChecks(cases) {
34
42
  };
35
43
  });
36
44
  }
37
- export function fingerprintTruthChecks(checks) {
45
+ export function fingerprintReadinessChecks(checks) {
38
46
  const normalized = checks.map((check) => ({
39
47
  question: check.question.trim(),
40
48
  ...(check.answer ? { answer: check.answer.trim() } : {}),
@@ -47,14 +55,29 @@ export function fingerprintTruthChecks(checks) {
47
55
  .slice(0, 16);
48
56
  }
49
57
  export function loadSourceFolderConfig(sourcePath) {
50
- const filePath = sourceConfigPath(sourcePath);
58
+ const filePath = resolveSourceFolderConfigPath(sourcePath);
51
59
  if (!existsSync(filePath))
52
60
  return null;
53
- return readJsonFileWithSchema(filePath, "Interf project config", SourceFolderConfigSchema);
61
+ return readSourceFolderConfigFile(filePath);
62
+ }
63
+ export function methodIdForSourcePreparationConfig(preparationConfig) {
64
+ return preparationConfig?.method ?? preparationConfig?.workflow ?? null;
65
+ }
66
+ function normalizeSourcePreparationConfig(preparationConfig) {
67
+ const method = methodIdForSourcePreparationConfig(preparationConfig);
68
+ return {
69
+ ...preparationConfig,
70
+ ...(method ? { method } : {}),
71
+ };
54
72
  }
55
- export function listSourceDatasetConfigs(config) {
56
- return config?.datasets ?? [];
73
+ export function listSourcePreparationConfigs(config) {
74
+ const explicitPreparations = config?.preparations ?? [];
75
+ const preparations = explicitPreparations.length > 0
76
+ ? explicitPreparations
77
+ : config?.datasets ?? [];
78
+ return preparations.map((preparation) => normalizeSourcePreparationConfig(preparation));
57
79
  }
80
+ export const listSourceDatasetConfigs = listSourcePreparationConfigs;
58
81
  export function resolveDatasetCompileMaxAttempts(datasetConfig, override = null) {
59
82
  const configured = override ?? datasetConfig.max_attempts ?? null;
60
83
  if (configured == null)
@@ -73,71 +96,98 @@ export function resolveDatasetCompileMaxLoops(datasetConfig, override = null) {
73
96
  return 1;
74
97
  return Math.min(3, normalized);
75
98
  }
76
- export function getDefaultSourceDatasetConfig(config) {
77
- const datasets = listSourceDatasetConfigs(config);
78
- return datasets[0] ?? null;
99
+ export function getDefaultSourcePreparationConfig(config) {
100
+ const preparations = listSourcePreparationConfigs(config);
101
+ return preparations[0] ?? null;
79
102
  }
80
- export function findSourceDatasetConfig(config, datasetName) {
81
- return listSourceDatasetConfigs(config).find((dataset) => dataset.name === datasetName) ?? null;
103
+ export const getDefaultSourceDatasetConfig = getDefaultSourcePreparationConfig;
104
+ export function findSourcePreparationConfig(config, preparationName) {
105
+ return listSourcePreparationConfigs(config).find((preparation) => preparation.name === preparationName) ?? null;
106
+ }
107
+ export const findSourceDatasetConfig = findSourcePreparationConfig;
108
+ export function configuredSourceFolderPath(config) {
109
+ return config?.source_folder?.path ?? null;
110
+ }
111
+ export function resolveConfiguredSourceFolderPath(sourcePath, config = loadSourceFolderConfig(sourcePath)) {
112
+ const configuredPath = configuredSourceFolderPath(config);
113
+ return configuredPath ? resolve(sourcePath, configuredPath) : null;
82
114
  }
83
115
  function toWritableSourceProjectConfig(config) {
84
- const datasets = config?.datasets ?? [];
85
- if (datasets.length > 0) {
116
+ const explicitPreparations = config?.preparations ?? [];
117
+ const preparations = explicitPreparations.length > 0
118
+ ? explicitPreparations
119
+ : config?.datasets ?? [];
120
+ const sourceFolder = config?.source_folder;
121
+ if (preparations.length > 0) {
86
122
  return {
87
- datasets: datasets.map((dataset) => toWritableSourceDatasetConfig(dataset)),
123
+ ...(sourceFolder ? { source_folder: sourceFolder } : {}),
124
+ preparations: preparations.map((preparation) => toWritableSourcePreparationConfig(preparation)),
88
125
  };
89
126
  }
90
- return {};
127
+ return {
128
+ ...(sourceFolder ? { source_folder: sourceFolder } : {}),
129
+ preparations: [],
130
+ };
91
131
  }
92
- function toWritableSourceDatasetConfig(dataset) {
132
+ function toWritableSourcePreparationConfig(preparation) {
133
+ const method = methodIdForSourcePreparationConfig(preparation);
93
134
  return {
94
- name: dataset.name,
95
- path: dataset.path,
96
- ...(dataset.about ? { about: dataset.about } : {}),
97
- ...(dataset.workflow && dataset.workflow !== "interf" ? { workflow: dataset.workflow } : {}),
98
- ...(typeof dataset.max_attempts === "number" ? { max_attempts: dataset.max_attempts } : {}),
99
- ...(typeof dataset.max_loops === "number" ? { max_loops: dataset.max_loops } : {}),
100
- checks: dataset.checks,
135
+ name: preparation.name,
136
+ path: preparation.path,
137
+ ...(preparation.about ? { about: preparation.about } : {}),
138
+ ...(method && method !== "interf" ? { method } : {}),
139
+ ...(typeof preparation.max_attempts === "number" ? { max_attempts: preparation.max_attempts } : {}),
140
+ ...(typeof preparation.max_loops === "number" ? { max_loops: preparation.max_loops } : {}),
141
+ checks: preparation.checks,
101
142
  };
102
143
  }
144
+ const toWritableSourceDatasetConfig = toWritableSourcePreparationConfig;
103
145
  export function saveSourceFolderConfig(sourcePath, config) {
104
- writeFileSync(sourceConfigPath(sourcePath), JSON.stringify(toWritableSourceProjectConfig(config), null, 2) + "\n");
146
+ const existing = loadSourceFolderConfig(sourcePath);
147
+ const mergedConfig = {
148
+ ...(existing?.source_folder && !config.source_folder ? { source_folder: existing.source_folder } : {}),
149
+ ...config,
150
+ };
151
+ mkdirSync(projectInterfRoot(sourcePath), { recursive: true });
152
+ writeFileSync(sourceFolderConfigPath(sourcePath), JSON.stringify(toWritableSourceProjectConfig(mergedConfig), null, 2) + "\n");
105
153
  }
106
- export function appendSourceDatasetChecks(sourcePath, datasetName, checks) {
154
+ export function appendSourceDatasetChecks(sourcePath, preparationName, checks) {
107
155
  const existing = loadSourceFolderConfig(sourcePath);
108
- const currentDataset = findSourceDatasetConfig(existing, datasetName);
109
- const otherDatasets = listSourceDatasetConfigs(existing).filter((dataset) => dataset.name !== datasetName);
110
- const currentChecks = currentDataset?.checks ?? [];
111
- const nextDataset = {
112
- ...toWritableSourceDatasetConfig(currentDataset ?? {
113
- name: datasetName,
114
- path: `./${datasetName}`,
156
+ const currentPreparation = findSourcePreparationConfig(existing, preparationName);
157
+ const otherPreparations = listSourcePreparationConfigs(existing).filter((preparation) => preparation.name !== preparationName);
158
+ const currentChecks = currentPreparation?.checks ?? [];
159
+ const nextPreparation = {
160
+ ...toWritableSourcePreparationConfig(currentPreparation ?? {
161
+ name: preparationName,
162
+ path: `./${preparationName}`,
115
163
  checks: [],
116
164
  }),
117
165
  checks: [...currentChecks, ...checks],
118
166
  };
119
167
  saveSourceFolderConfig(sourcePath, {
120
- datasets: [
121
- nextDataset,
122
- ...otherDatasets,
168
+ preparations: [
169
+ nextPreparation,
170
+ ...otherPreparations,
123
171
  ],
124
172
  });
125
173
  }
126
- export function upsertSourceDatasetConfig(sourcePath, datasetConfig, options = {}) {
174
+ export const appendSourcePreparationChecks = appendSourceDatasetChecks;
175
+ export function upsertSourceDatasetConfig(sourcePath, preparationConfig, options = {}) {
127
176
  const existing = loadSourceFolderConfig(sourcePath);
128
- const datasets = listSourceDatasetConfigs(existing);
129
- const candidateNames = Array.from(new Set([datasetConfig.name, options.matchName].filter((value) => Boolean(value))));
130
- const existingIndex = datasets.findIndex((entry) => candidateNames.includes(entry.name));
177
+ const preparations = listSourcePreparationConfigs(existing);
178
+ const candidateNames = Array.from(new Set([preparationConfig.name, options.matchName].filter((value) => Boolean(value))));
179
+ const existingIndex = preparations.findIndex((entry) => candidateNames.includes(entry.name));
131
180
  if (existingIndex >= 0) {
132
- datasets[existingIndex] = datasetConfig;
181
+ preparations[existingIndex] = normalizeSourcePreparationConfig(preparationConfig);
133
182
  }
134
183
  else {
135
- datasets.push(datasetConfig);
184
+ preparations.push(normalizeSourcePreparationConfig(preparationConfig));
136
185
  }
137
186
  saveSourceFolderConfig(sourcePath, {
138
- datasets,
187
+ preparations,
139
188
  });
140
189
  }
190
+ export const upsertSourcePreparationConfig = upsertSourceDatasetConfig;
141
191
  export function compiledMaxAttempts(maxAttempts) {
142
192
  if (maxAttempts == null)
143
193
  return undefined;
@@ -148,12 +198,13 @@ export function compiledMaxLoops(maxLoops) {
148
198
  return undefined;
149
199
  return resolveDatasetCompileMaxLoops({ max_loops: maxLoops }, null) ?? 1;
150
200
  }
151
- export function sourceDatasetConfigFromInterfConfig(config, datasetPath = `./${config.name}`) {
201
+ export function sourceDatasetConfigFromInterfConfig(config, preparationPath = `./${config.name}`) {
202
+ const method = config.method ?? config.workflow;
152
203
  return {
153
204
  name: config.name,
154
- path: datasetPath,
205
+ path: preparationPath,
155
206
  ...(config.about ? { about: config.about } : {}),
156
- ...(config.workflow ? { workflow: config.workflow } : {}),
207
+ ...(method ? { method } : {}),
157
208
  ...(typeof config.max_attempts === "number"
158
209
  ? { max_attempts: config.max_attempts }
159
210
  : {}),
@@ -168,14 +219,27 @@ export function loadCompiledDatasetConfig(compiledPath) {
168
219
  if (!config)
169
220
  return null;
170
221
  const projectPath = resolveSourceControlPathForCompiled(compiledPath);
171
- const configuredDatasets = listSourceDatasetConfigs(loadSourceFolderConfig(projectPath));
172
- const fallbackDatasetPath = configuredDatasets.length === 1
173
- ? configuredDatasets[0].path
222
+ const configuredPreparations = listSourcePreparationConfigs(loadSourceFolderConfig(projectPath));
223
+ const defaultPreparationPath = configuredPreparations.length === 1
224
+ ? configuredPreparations[0].path
174
225
  : `./${config.name}`;
175
- const datasetPath = typeof config.source?.dataset_path === "string" && config.source.dataset_path.length > 0
176
- ? relative(projectPath, assertPathWithinRoot(projectPath, resolve(compiledPath, config.source.dataset_path), "Compiled context source path")).split(sep).join("/") || fallbackDatasetPath
177
- : fallbackDatasetPath;
178
- return sourceDatasetConfigFromInterfConfig(config, datasetPath);
226
+ const sourceBinding = typeof config.source?.preparation_path === "string" && config.source.preparation_path.length > 0
227
+ ? config.source.preparation_path
228
+ : typeof config.source?.source_folder_path === "string" && config.source.source_folder_path.length > 0
229
+ ? config.source.source_folder_path
230
+ : typeof config.source?.dataset_path === "string" && config.source.dataset_path.length > 0
231
+ ? config.source.dataset_path
232
+ : null;
233
+ const preparationPath = sourceBinding
234
+ ? (() => {
235
+ const sourceAbsolutePath = resolve(compiledPath, sourceBinding);
236
+ if (!isPathWithinRoot(projectPath, sourceAbsolutePath)) {
237
+ return sourceAbsolutePath;
238
+ }
239
+ return relative(projectPath, sourceAbsolutePath).split(sep).join("/") || defaultPreparationPath;
240
+ })()
241
+ : defaultPreparationPath;
242
+ return sourceDatasetConfigFromInterfConfig(config, preparationPath);
179
243
  }
180
244
  export function saveCompiledInterfConfig(compiledPath, config) {
181
245
  mkdirSync(compiledInterfRoot(compiledPath), { recursive: true });
@@ -185,17 +249,17 @@ export function saveCompiledInterfConfig(compiledPath, config) {
185
249
  export function syncCompiledInterfConfigFromSourceDatasetConfig(compiledPath, datasetConfig) {
186
250
  const current = readInterfConfig(compiledPath);
187
251
  const projectPath = resolveSourceControlPathForCompiled(compiledPath);
188
- const datasetAbsolutePath = resolve(projectPath, datasetConfig.path);
252
+ const datasetAbsolutePath = resolveSourceDatasetPath(projectPath, datasetConfig);
189
253
  const datasetRelativePath = relative(compiledPath, datasetAbsolutePath).split(sep).join("/") || ".";
190
- const workflowId = datasetConfig.workflow ?? current?.workflow ?? "interf";
191
- const workflowChanged = current?.workflow !== undefined && current.workflow !== workflowId;
192
- const workflowOrigin = workflowChanged || !current?.workflow_origin
254
+ const methodId = methodIdForSourcePreparationConfig(datasetConfig) ?? current?.method ?? current?.workflow ?? "interf";
255
+ const methodChanged = current?.method !== undefined && current.method !== methodId;
256
+ const methodOrigin = methodChanged || !current?.method_origin
193
257
  ? {
194
- selected: workflowId,
258
+ selected: methodId,
195
259
  local_draft: false,
196
260
  }
197
- : current.workflow_origin;
198
- const { type: _ignoredType, name: _ignoredName, about: _ignoredAbout, workflow: _ignoredWorkflow, max_attempts: _ignoredMaxAttempts, max_loops: _ignoredMaxLoops, checks: _ignoredChecks, workflow_origin: _ignoredWorkflowOrigin, source: _ignoredSource, ...passthrough } = current ?? {};
261
+ : current.method_origin;
262
+ const { type: _ignoredType, name: _ignoredName, about: _ignoredAbout, method: _ignoredMethod, workflow: _ignoredWorkflow, max_attempts: _ignoredMaxAttempts, max_loops: _ignoredMaxLoops, checks: _ignoredChecks, method_origin: _ignoredMethodOrigin, workflow_origin: _ignoredWorkflowOrigin, source: _ignoredSource, ...passthrough } = current ?? {};
199
263
  const nextConfig = {
200
264
  ...passthrough,
201
265
  ...(!current ? {
@@ -207,7 +271,7 @@ export function syncCompiledInterfConfigFromSourceDatasetConfig(compiledPath, da
207
271
  type: "compiled",
208
272
  name: datasetConfig.name,
209
273
  ...(datasetConfig.about ? { about: datasetConfig.about } : {}),
210
- workflow: workflowId,
274
+ method: methodId,
211
275
  ...(typeof datasetConfig.max_attempts === "number"
212
276
  ? { max_attempts: datasetConfig.max_attempts }
213
277
  : {}),
@@ -215,17 +279,17 @@ export function syncCompiledInterfConfigFromSourceDatasetConfig(compiledPath, da
215
279
  ? { max_loops: datasetConfig.max_loops }
216
280
  : {}),
217
281
  checks: datasetConfig.checks,
218
- workflow_origin: workflowOrigin,
282
+ method_origin: methodOrigin,
219
283
  source: {
220
284
  path: current?.source?.path ?? "./raw",
221
285
  control_path: defaultControlPathForCompiled(compiledPath),
222
- dataset_path: datasetRelativePath,
286
+ preparation_path: datasetRelativePath,
223
287
  },
224
288
  };
225
289
  const saved = saveCompiledInterfConfig(compiledPath, nextConfig);
226
- if (workflowChanged) {
290
+ if (methodChanged) {
227
291
  const sourcePath = projectPath;
228
- const selectedWorkflow = getCompiledWorkflow(workflowId, { sourcePath });
292
+ const selectedWorkflow = getCompiledWorkflow(methodId, { sourcePath });
229
293
  seedCompiledWorkflowPackage({
230
294
  compiledPath,
231
295
  sourcePath,
@@ -244,8 +308,8 @@ function buildLoadedTestSpec(options) {
244
308
  filePath: options.filePath,
245
309
  type: options.targetType,
246
310
  name: options.name,
247
- description: options.about ?? options.fallbackDescription,
248
- cases: normalizeTruthChecks(options.checks),
311
+ description: options.about ?? options.defaultDescription,
312
+ cases: normalizeReadinessChecks(options.checks),
249
313
  };
250
314
  }
251
315
  export function buildTestSpecFromSourceFolderConfig(options) {
@@ -253,17 +317,17 @@ export function buildTestSpecFromSourceFolderConfig(options) {
253
317
  const config = loadSourceFolderConfig(sourcePath);
254
318
  if (!config)
255
319
  return null;
256
- const datasets = listSourceDatasetConfigs(config);
257
- if (datasets.length === 0)
320
+ const preparations = listSourcePreparationConfigs(config);
321
+ if (preparations.length === 0)
258
322
  return null;
259
323
  const match = targetName
260
- ? datasets.find((entry) => entry.name === targetName)
261
- : datasets.length === 1
262
- ? datasets[0]
263
- : getDefaultSourceDatasetConfig(config);
324
+ ? preparations.find((entry) => entry.name === targetName)
325
+ : preparations.length === 1
326
+ ? preparations[0]
327
+ : getDefaultSourcePreparationConfig(config);
264
328
  if (!match)
265
329
  return null;
266
- const configPath = sourceConfigPath(sourcePath);
330
+ const configPath = resolveSourceFolderConfigPath(sourcePath);
267
331
  return buildLoadedTestSpec({
268
332
  id: match.id,
269
333
  name: match.name,
@@ -271,9 +335,9 @@ export function buildTestSpecFromSourceFolderConfig(options) {
271
335
  checks: match.checks,
272
336
  targetType,
273
337
  filePath: targetType === "raw"
274
- ? `${configPath}#datasets/${match.name}:file-as-is`
275
- : `${configPath}#datasets/${match.name}:compiled`,
276
- fallbackDescription: `Derived from saved dataset checks in ${SOURCE_FOLDER_CONFIG_FILE}`,
338
+ ? `${configPath}#preparations/${match.name}:source-files`
339
+ : `${configPath}#preparations/${match.name}:portable-context`,
340
+ defaultDescription: `Derived from saved Preparation checks in ${SOURCE_FOLDER_CONFIG_PATH}`,
277
341
  });
278
342
  }
279
343
  export function buildTestSpecFromCompiledDatasetConfig(options) {
@@ -290,9 +354,15 @@ export function buildTestSpecFromCompiledDatasetConfig(options) {
290
354
  filePath: targetType === "raw"
291
355
  ? `${configPath}#checks:file-as-is`
292
356
  : `${configPath}#checks:compiled`,
293
- fallbackDescription: "Derived from checks in the compiled context config.",
357
+ defaultDescription: "Derived from checks in the compiled context config.",
294
358
  });
295
359
  }
296
360
  export function resolveSourceDatasetPath(projectPath, datasetConfig) {
297
- return assertPathWithinRoot(projectPath, resolve(projectPath, datasetConfig.path), "Dataset path");
361
+ const configuredPath = datasetConfig.path.trim();
362
+ const resolvedPath = resolve(projectPath, configuredPath);
363
+ if (isAbsolute(configuredPath)) {
364
+ return resolvedPath;
365
+ }
366
+ return assertPathWithinRoot(projectPath, resolvedPath, "Source folder path");
298
367
  }
368
+ export const resolveSourcePreparationPath = resolveSourceDatasetPath;
@@ -0,0 +1,11 @@
1
+ export declare function listVisibleSourceFolders(projectPath: string): string[];
2
+ export declare function isReservedSourceDatasetPath(relativePath: string): boolean;
3
+ export declare function normalizeSourceDatasetPathForConfig(projectPath: string, value: string): string;
4
+ export declare function defaultDatasetNameForPath(datasetPath: string): string;
5
+ export declare function findSingleSourceFolderCandidate(projectPath: string): string | null;
6
+ export declare function listSourceFolderChoices(projectPath?: string): Array<{
7
+ value: string;
8
+ label: string;
9
+ hint: string;
10
+ }>;
11
+ export declare function defaultSourceDatasetPathForPrompt(name: string, introStyle: "first" | "additional" | "edit", projectPath?: string): string;
@@ -0,0 +1,110 @@
1
+ import { existsSync, readdirSync, statSync } from "node:fs";
2
+ import { isAbsolute, join, relative, sep } from "node:path";
3
+ import { slugify } from "../shared/naming.js";
4
+ import { resolveSourceDatasetPath } from "./source-config.js";
5
+ import { isPathWithinRoot } from "../shared/path-guards.js";
6
+ const DEFAULT_DATASET_NAME = "dataset1";
7
+ const IGNORED_SOURCE_FOLDER_ENTRIES = new Set([
8
+ ".DS_Store",
9
+ ".git",
10
+ ".interf",
11
+ "interf",
12
+ "interf.json",
13
+ "node_modules",
14
+ ]);
15
+ export function listVisibleSourceFolders(projectPath) {
16
+ let rootEntries = [];
17
+ try {
18
+ rootEntries = readdirSync(projectPath);
19
+ }
20
+ catch {
21
+ return [];
22
+ }
23
+ const visibleEntries = rootEntries.filter((entry) => (!IGNORED_SOURCE_FOLDER_ENTRIES.has(entry) && !entry.startsWith(".")));
24
+ const visibleDirectories = [];
25
+ for (const entry of visibleEntries) {
26
+ try {
27
+ const entryPath = join(projectPath, entry);
28
+ if (statSync(entryPath).isDirectory()) {
29
+ visibleDirectories.push(entry);
30
+ }
31
+ }
32
+ catch {
33
+ // Ignore unreadable entries.
34
+ }
35
+ }
36
+ return visibleDirectories.sort((left, right) => left.localeCompare(right));
37
+ }
38
+ export function isReservedSourceDatasetPath(relativePath) {
39
+ const normalized = relativePath.replace(/\\/g, "/").replace(/^\.\/+/, "");
40
+ return normalized === "interf" ||
41
+ normalized.startsWith("interf/") ||
42
+ normalized === ".interf" ||
43
+ normalized.startsWith(".interf/");
44
+ }
45
+ export function normalizeSourceDatasetPathForConfig(projectPath, value) {
46
+ const trimmedValue = value.trim();
47
+ const resolvedPath = resolveSourceDatasetPath(projectPath, { path: trimmedValue });
48
+ const relativePath = relative(projectPath, resolvedPath).split(sep).join("/") || ".";
49
+ if (relativePath === ".") {
50
+ throw new Error("Pick a Source Folder, not the Interf Workspace itself.");
51
+ }
52
+ if (isAbsolute(trimmedValue) && !isPathWithinRoot(projectPath, resolvedPath)) {
53
+ if (!existsSync(resolvedPath)) {
54
+ throw new Error("Pick an existing source folder.");
55
+ }
56
+ if (!statSync(resolvedPath).isDirectory()) {
57
+ throw new Error("Source folder must be a directory.");
58
+ }
59
+ return resolvedPath;
60
+ }
61
+ if (isReservedSourceDatasetPath(relativePath)) {
62
+ throw new Error("Pick an existing source folder, not `interf/` or `.interf/`.");
63
+ }
64
+ if (!existsSync(resolvedPath)) {
65
+ throw new Error("Pick an existing source folder.");
66
+ }
67
+ if (!statSync(resolvedPath).isDirectory()) {
68
+ throw new Error("Source folder must be a directory.");
69
+ }
70
+ return relativePath.startsWith("./") ? relativePath : `./${relativePath}`;
71
+ }
72
+ export function defaultDatasetNameForPath(datasetPath) {
73
+ const segments = datasetPath
74
+ .replace(/\\/g, "/")
75
+ .replace(/\/+$/g, "")
76
+ .split("/")
77
+ .filter((segment) => segment.length > 0 && segment !== ".");
78
+ return slugify(segments[segments.length - 1] ?? "") || DEFAULT_DATASET_NAME;
79
+ }
80
+ export function findSingleSourceFolderCandidate(projectPath) {
81
+ const visibleDirectories = listVisibleSourceFolders(projectPath);
82
+ if (visibleDirectories.length !== 1) {
83
+ return null;
84
+ }
85
+ return `./${visibleDirectories[0]}`;
86
+ }
87
+ export function listSourceFolderChoices(projectPath = process.cwd()) {
88
+ return listVisibleSourceFolders(projectPath).map((entry) => ({
89
+ value: `./${entry}`,
90
+ label: entry,
91
+ hint: `Use ./${entry} as the source folder`,
92
+ }));
93
+ }
94
+ export function defaultSourceDatasetPathForPrompt(name, introStyle, projectPath = process.cwd()) {
95
+ const namedFolderPath = join(projectPath, name);
96
+ if (existsSync(namedFolderPath)) {
97
+ try {
98
+ if (statSync(namedFolderPath).isDirectory()) {
99
+ return `./${name}`;
100
+ }
101
+ }
102
+ catch {
103
+ // Fall through to the normal default.
104
+ }
105
+ }
106
+ if (introStyle === "first") {
107
+ return findSingleSourceFolderCandidate(projectPath) ?? `./${name}`;
108
+ }
109
+ return `./${name}`;
110
+ }
@@ -201,9 +201,9 @@ function buildTestQueryPrompt(target, testCase, answerPath, tracePath) {
201
201
  "Read `AGENTS.md` first.",
202
202
  "Use the local native `interf-query` skill available in this portable context.",
203
203
  "Answer the check question the same way you would answer a real user inside this portable context.",
204
- "Prefer the workflow-declared context outputs before raw fallback.",
205
- "This sandbox is self-contained: the copied portable context has its own sanitized `raw/` fallback via `.interf/interf.json` `source.path`.",
206
- "The original project root is intentionally absent from this sandbox. Work only from this sandboxed compiled context and its embedded raw files.",
204
+ "Prefer the workflow-declared context outputs before consulting `raw/`.",
205
+ "This sandbox is self-contained: the copied portable context has sanitized source files under `raw/` via `.interf/interf.json` `source.path`.",
206
+ "The original control plane folder is intentionally absent from this sandbox. Work only from this sandboxed compiled context and its embedded raw files.",
207
207
  ]
208
208
  : [
209
209
  "You are running an Interf baseline test inside an isolated raw test shell.",
@@ -211,14 +211,14 @@ function buildTestQueryPrompt(target, testCase, answerPath, tracePath) {
211
211
  "Use the local native `interf-query` skill available in this shell.",
212
212
  "There is no compiled context in this sandbox.",
213
213
  "Answer only from `raw/` inside this shell.",
214
- "The original project root is intentionally absent from this sandbox.",
214
+ "The original control plane folder is intentionally absent from this sandbox.",
215
215
  ];
216
216
  return [
217
217
  ...header,
218
218
  "Emit only STATUS:, DONE:, BLOCKED:, or ERROR: lines.",
219
219
  "Do not ask follow-up questions.",
220
220
  `Write the answer to ${JSON.stringify(answerPath)}.`,
221
- `Write the trace to ${JSON.stringify(tracePath)} with keys: case_id, target, artifacts_consulted, raw_paths_read, used_raw_fallback, answer_summary.`,
221
+ `Write the trace to ${JSON.stringify(tracePath)} with keys: case_id, target, artifacts_consulted, raw_paths_read, used_source_files, answer_summary.`,
222
222
  `Set \`case_id\` to ${JSON.stringify(testCase.id)}.`,
223
223
  `Set \`target\` to ${JSON.stringify(target.type)}.`,
224
224
  `Question: ${testCase.question}`,
@@ -10,7 +10,8 @@ export function testSpecTypePath(sourcePath, type) {
10
10
  return join(testSpecRootPath(sourcePath), type);
11
11
  }
12
12
  function isDatasetTestsRootPath(artifactRootPath) {
13
- return basename(dirname(artifactRootPath)) === "tests";
13
+ return basename(artifactRootPath) === "tests" &&
14
+ basename(dirname(artifactRootPath)) === ".interf";
14
15
  }
15
16
  export function targetTestRunsPath(compiledPath, type) {
16
17
  if (existsSync(compiledInterfConfigPath(compiledPath))) {
@@ -19,7 +20,7 @@ export function targetTestRunsPath(compiledPath, type) {
19
20
  if (isDatasetTestsRootPath(compiledPath)) {
20
21
  return join(compiledPath, type === "raw" ? "file-as-is" : "compiled", "runs");
21
22
  }
22
- throw new Error(`Unsupported test artifact root: ${compiledPath}. Expected a compiled context or interf/tests/<dataset> root.`);
23
+ throw new Error(`Unsupported test artifact root: ${compiledPath}. Expected a compiled context or interf/<dataset>/.interf/tests root.`);
23
24
  }
24
25
  export function targetTestRunGitignorePath(compiledPath, type) {
25
26
  return join(targetTestRunsPath(compiledPath, type), ".gitignore");
@@ -31,7 +32,7 @@ export function targetTestSandboxesPath(compiledPath, type) {
31
32
  if (isDatasetTestsRootPath(compiledPath)) {
32
33
  return join(compiledPath, type === "raw" ? "file-as-is" : "compiled", "sandboxes");
33
34
  }
34
- throw new Error(`Unsupported test artifact root: ${compiledPath}. Expected a compiled context or interf/tests/<dataset> root.`);
35
+ throw new Error(`Unsupported test artifact root: ${compiledPath}. Expected a compiled context or interf/<dataset>/.interf/tests root.`);
35
36
  }
36
37
  export function targetTestSandboxGitignorePath(compiledPath, type) {
37
38
  return join(targetTestSandboxesPath(compiledPath, type), ".gitignore");
@@ -1,7 +1,6 @@
1
1
  import type { WorkflowExecutor } from "../agents/lib/executors.js";
2
2
  import { validateWorkflowPackage } from "../workflow-package/local-workflows.js";
3
- import { type WorkflowReporter } from "../compiler/workflows.js";
4
- import type { SourceTruthCheck } from "../project-model/lib/schema.js";
3
+ import type { SourceReadinessCheck } from "../project-model/lib/schema.js";
5
4
  export interface WorkflowAuthoringRunResult {
6
5
  status: "updated" | "no-change" | "invalid" | "executor-failed";
7
6
  changed: boolean;
@@ -13,14 +12,13 @@ export interface WorkflowAuthoringRunResult {
13
12
  export declare function runWorkflowAuthoringDraft(options: {
14
13
  sourcePath: string;
15
14
  datasetPath: string;
16
- baseWorkflowId: string;
15
+ baseWorkflowId?: string;
17
16
  workflowId: string;
18
17
  label: string;
19
18
  hint: string;
20
19
  taskPrompt: string;
21
- checks?: SourceTruthCheck[];
20
+ checks?: SourceReadinessCheck[];
22
21
  executor: WorkflowExecutor;
23
- preparePreview?: boolean;
24
- previewReporter?: WorkflowReporter | null;
22
+ onStatus?: (line: string) => void;
25
23
  }): Promise<WorkflowAuthoringRunResult>;
26
24
  export declare function resolveWorkflowDraftPath(sourcePath: string, workflowId: string): string;