@interf/compiler 0.5.1 → 0.6.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 (93) hide show
  1. package/README.md +126 -187
  2. package/builtin-workflows/interf/README.md +22 -10
  3. package/builtin-workflows/interf/compile/stages/shape/SKILL.md +6 -3
  4. package/builtin-workflows/interf/compile/stages/structure/SKILL.md +3 -0
  5. package/builtin-workflows/interf/compile/stages/summarize/SKILL.md +18 -2
  6. package/builtin-workflows/interf/improve/SKILL.md +2 -2
  7. package/builtin-workflows/interf/workflow.json +18 -4
  8. package/builtin-workflows/interf/{compiled.schema.json → workflow.schema.json} +9 -2
  9. package/dist/commands/check-draft.js +3 -3
  10. package/dist/commands/compile-controller.js +6 -13
  11. package/dist/commands/compile.d.ts +19 -1
  12. package/dist/commands/compile.js +98 -28
  13. package/dist/commands/create-workflow-wizard.d.ts +20 -2
  14. package/dist/commands/create-workflow-wizard.js +163 -27
  15. package/dist/commands/create.d.ts +1 -1
  16. package/dist/commands/create.js +67 -60
  17. package/dist/commands/dataset-selection.d.ts +6 -0
  18. package/dist/commands/dataset-selection.js +11 -0
  19. package/dist/commands/default.js +3 -3
  20. package/dist/commands/doctor.js +8 -8
  21. package/dist/commands/executor-flow.d.ts +1 -1
  22. package/dist/commands/executor-flow.js +5 -2
  23. package/dist/commands/init.d.ts +5 -0
  24. package/dist/commands/init.js +56 -48
  25. package/dist/commands/list.js +6 -3
  26. package/dist/commands/reset.js +1 -1
  27. package/dist/commands/source-config-wizard.d.ts +2 -2
  28. package/dist/commands/source-config-wizard.js +50 -17
  29. package/dist/commands/test.d.ts +0 -6
  30. package/dist/commands/test.js +9 -17
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/lib/agent-args.d.ts +1 -0
  34. package/dist/lib/agent-args.js +10 -0
  35. package/dist/lib/agent-execution.js +2 -1
  36. package/dist/lib/agent-preflight.js +2 -1
  37. package/dist/lib/agent-shells.d.ts +26 -1
  38. package/dist/lib/agent-shells.js +213 -39
  39. package/dist/lib/agents.d.ts +1 -1
  40. package/dist/lib/agents.js +1 -1
  41. package/dist/lib/builtin-compiled-workflow.d.ts +6 -97
  42. package/dist/lib/builtin-compiled-workflow.js +66 -125
  43. package/dist/lib/compiled-compile.d.ts +0 -4
  44. package/dist/lib/compiled-compile.js +9 -28
  45. package/dist/lib/compiled-paths.d.ts +1 -0
  46. package/dist/lib/compiled-paths.js +3 -0
  47. package/dist/lib/compiled-reset.d.ts +1 -0
  48. package/dist/lib/compiled-reset.js +42 -14
  49. package/dist/lib/compiled-schema.d.ts +9 -5
  50. package/dist/lib/compiled-schema.js +45 -14
  51. package/dist/lib/discovery.d.ts +1 -1
  52. package/dist/lib/discovery.js +2 -2
  53. package/dist/lib/executors.d.ts +1 -1
  54. package/dist/lib/executors.js +2 -2
  55. package/dist/lib/interf-scaffold.js +4 -11
  56. package/dist/lib/interf-workflow-package.d.ts +8 -3
  57. package/dist/lib/interf-workflow-package.js +128 -62
  58. package/dist/lib/local-workflows.d.ts +4 -3
  59. package/dist/lib/local-workflows.js +126 -103
  60. package/dist/lib/runtime-acceptance.js +15 -3
  61. package/dist/lib/runtime-contracts.js +3 -2
  62. package/dist/lib/runtime-paths.d.ts +1 -0
  63. package/dist/lib/runtime-paths.js +4 -1
  64. package/dist/lib/runtime-prompt.js +3 -1
  65. package/dist/lib/runtime-reconcile.js +88 -51
  66. package/dist/lib/runtime-runs.js +27 -15
  67. package/dist/lib/runtime.d.ts +1 -1
  68. package/dist/lib/runtime.js +1 -1
  69. package/dist/lib/schema.d.ts +71 -14
  70. package/dist/lib/schema.js +15 -12
  71. package/dist/lib/state-view.js +6 -6
  72. package/dist/lib/state.d.ts +1 -0
  73. package/dist/lib/state.js +7 -0
  74. package/dist/lib/test-execution.js +2 -2
  75. package/dist/lib/validate-compiled.js +9 -6
  76. package/dist/lib/validate.d.ts +3 -1
  77. package/dist/lib/validate.js +4 -11
  78. package/dist/lib/workflow-authoring.d.ts +26 -0
  79. package/dist/lib/workflow-authoring.js +119 -0
  80. package/dist/lib/workflow-definitions.d.ts +11 -1
  81. package/dist/lib/workflow-definitions.js +12 -15
  82. package/dist/lib/workflow-edit-session.d.ts +16 -0
  83. package/dist/lib/workflow-edit-session.js +57 -0
  84. package/dist/lib/workflow-edit-utils.d.ts +10 -0
  85. package/dist/lib/workflow-edit-utils.js +39 -0
  86. package/dist/lib/workflow-improvement.js +30 -217
  87. package/dist/lib/workflow-stage-policy.d.ts +5 -0
  88. package/dist/lib/workflow-stage-policy.js +31 -0
  89. package/package.json +4 -5
  90. package/dist/lib/obsidian.d.ts +0 -1
  91. package/dist/lib/obsidian.js +0 -15
  92. package/dist/lib/summarize-plan.d.ts +0 -17
  93. package/dist/lib/summarize-plan.js +0 -120
@@ -1,15 +1,13 @@
1
1
  import chalk from "chalk";
2
2
  import { basename } from "node:path";
3
3
  import * as p from "@clack/prompts";
4
- import { detectInterf, defaultCompiledNameForSource, listCompiledDatasetsForSourceFolder, } from "../lib/interf.js";
4
+ import { detectInterf, defaultCompiledNameForSource, listCompiledDatasetsForSourceFolder, resolveSourceControlPath, } from "../lib/interf.js";
5
5
  import { slugify } from "../lib/util.js";
6
6
  import { addExecutionProfileOptions, executionProfileFromArgv, } from "../lib/execution-profile.js";
7
- import { listSourceDatasetConfigs, loadSourceFolderConfig, upsertSourceDatasetConfig, } from "../lib/source-config.js";
7
+ import { listSourceDatasetConfigs, loadSourceFolderConfig, syncCompiledInterfConfigFromSourceDatasetConfig, upsertSourceDatasetConfig, } from "../lib/source-config.js";
8
8
  import { createWorkflowWizard, } from "./create-workflow-wizard.js";
9
- import { ensureCompiledFromConfig, } from "./compiled-flow.js";
9
+ import { findBuiltCompiledPath, } from "./compiled-flow.js";
10
10
  import { DEFAULT_COMPILED_NAME, promptSingleCompiledConfig, } from "./source-config-wizard.js";
11
- import { resolveOrConfigureLocalExecutor } from "./executor-flow.js";
12
- import { runConfiguredCompiledCompile } from "./compile.js";
13
11
  function normalizeCreateTarget(value) {
14
12
  if (!value)
15
13
  return null;
@@ -41,6 +39,56 @@ async function selectCreateTarget() {
41
39
  ],
42
40
  });
43
41
  }
42
+ async function maybeAssignWorkflowToDataset(sourcePath, workflowId) {
43
+ const config = loadSourceFolderConfig(sourcePath);
44
+ const datasets = listSourceDatasetConfigs(config);
45
+ if (datasets.length === 0) {
46
+ p.log.info(`Created workflow "${workflowId}".`);
47
+ p.log.info(`Next: run \`interf\`, add a dataset, then assign workflow "${workflowId}" from that dataset menu.`);
48
+ return;
49
+ }
50
+ const assignNow = await p.confirm({
51
+ message: "Assign this workflow to a dataset now? (Recommended)",
52
+ initialValue: true,
53
+ });
54
+ if (p.isCancel(assignNow) || !assignNow) {
55
+ p.log.info(`Created workflow "${workflowId}".`);
56
+ p.log.info(`Next: run \`interf\`, open a dataset, and assign workflow "${workflowId}" from that dataset menu.`);
57
+ return;
58
+ }
59
+ let targetDataset = datasets[0] ?? null;
60
+ if (datasets.length > 1) {
61
+ const selected = await p.select({
62
+ message: "Which dataset should use this workflow?",
63
+ options: datasets.map((dataset) => ({
64
+ value: dataset.name,
65
+ label: dataset.name,
66
+ hint: `${dataset.path} · ${dataset.about ?? `${dataset.checks.length} saved truth check${dataset.checks.length === 1 ? "" : "s"}`}`,
67
+ })),
68
+ });
69
+ if (p.isCancel(selected))
70
+ return;
71
+ targetDataset = datasets.find((dataset) => dataset.name === selected) ?? null;
72
+ }
73
+ if (!targetDataset)
74
+ return;
75
+ const nextConfig = {
76
+ ...targetDataset,
77
+ workflow: workflowId,
78
+ };
79
+ upsertSourceDatasetConfig(sourcePath, nextConfig, {
80
+ matchName: targetDataset.name,
81
+ });
82
+ const builtCompiledPath = findBuiltCompiledPath(sourcePath, targetDataset.name);
83
+ if (builtCompiledPath) {
84
+ syncCompiledInterfConfigFromSourceDatasetConfig(builtCompiledPath, nextConfig);
85
+ }
86
+ p.log.info(`Assigned workflow "${workflowId}" to dataset "${targetDataset.name}".`);
87
+ if (builtCompiledPath) {
88
+ p.log.info("The active local copy for that built dataset lives under `.interf/workflow/`.");
89
+ }
90
+ p.log.info("Next: run `interf compile`, then `interf test`.");
91
+ }
44
92
  export const createCommand = {
45
93
  command: "create [type]",
46
94
  describe: "Create a dataset entry or reusable workflow",
@@ -65,7 +113,14 @@ export const createCommand = {
65
113
  type = selected;
66
114
  }
67
115
  if (type === "workflow") {
68
- await createWorkflowWizard({ sourcePath: process.cwd() });
116
+ const detected = detectInterf(process.cwd());
117
+ const workflowId = await createWorkflowWizard({
118
+ sourcePath: detected ? resolveSourceControlPath(detected.path) : process.cwd(),
119
+ executionProfile,
120
+ });
121
+ if (typeof workflowId === "string") {
122
+ await maybeAssignWorkflowToDataset(detected ? resolveSourceControlPath(detected.path) : process.cwd(), workflowId);
123
+ }
69
124
  return;
70
125
  }
71
126
  await createCompiledWizard({ executionProfile });
@@ -86,10 +141,9 @@ export async function createCompiledWizard(options = {}) {
86
141
  if (existing.length > 0) {
87
142
  p.log.info(`This project already has ${existing.length} compiled dataset${existing.length === 1 ? "" : "s"}. Add another only when you need a separate folder, truth checks, or focus.`);
88
143
  }
89
- p.log.info("Interf Compiler measures one dataset at a time. Start with truth checks and a baseline, then build a compiled dataset only when you need it.");
144
+ p.log.info("Interf works one dataset at a time. Start with the task, truth checks, and a baseline, then build a compiled dataset only when you need it.");
90
145
  const existingConfig = loadSourceFolderConfig(cwd);
91
146
  const suggestedName = slugify(defaultCompiledNameForSource(cwd) || basename(cwd)) || DEFAULT_COMPILED_NAME;
92
- const workflowId = "interf";
93
147
  const draft = await promptSingleCompiledConfig({
94
148
  projectPath: cwd,
95
149
  initial: { name: suggestedName },
@@ -99,7 +153,7 @@ export async function createCompiledWizard(options = {}) {
99
153
  return;
100
154
  const configToSave = {
101
155
  ...draft,
102
- workflow: workflowId,
156
+ workflow: "interf",
103
157
  };
104
158
  const existingNames = new Set(listSourceDatasetConfigs(existingConfig).map((dataset) => dataset.name));
105
159
  if (existingNames.has(configToSave.name)) {
@@ -108,55 +162,8 @@ export async function createCompiledWizard(options = {}) {
108
162
  return;
109
163
  }
110
164
  upsertSourceDatasetConfig(cwd, configToSave);
111
- const compileNow = await p.confirm({
112
- message: "Build the compiled dataset now? (Recommended)",
113
- initialValue: true,
114
- });
115
- if (p.isCancel(compileNow) || !compileNow) {
116
- p.outro(configToSave.checks.length > 0
117
- ? "Next:\n interf test\n interf compile"
118
- : "Next:\n interf or interf init");
119
- return;
120
- }
121
- const { executor, error } = await resolveOrConfigureLocalExecutor({
122
- executionProfile: options.executionProfile,
123
- purpose: "compile",
124
- });
125
- if (!executor && !error) {
126
- return;
127
- }
128
- if (!executor) {
129
- process.exitCode = 1;
130
- p.log.error(error ?? "No coding agent detected.");
131
- return;
132
- }
133
- const spinner = p.spinner();
134
- spinner.start("Preparing compiled dataset...");
135
- let compiledPath = "";
136
- try {
137
- compiledPath = ensureCompiledFromConfig(cwd, configToSave);
138
- spinner.stop("Compiled dataset target ready.");
139
- }
140
- catch (error) {
141
- spinner.stop("Compiled dataset target preparation failed.");
142
- process.exitCode = 1;
143
- p.log.error(error instanceof Error ? error.message : String(error));
144
- return;
145
- }
146
- await compileCompiledAfterCreate(executor, cwd, configToSave, compiledPath, options.executionProfile);
147
- }
148
- async function compileCompiledAfterCreate(executor, sourcePath, datasetConfig, compiledPath, executionProfile) {
149
- const compiled = await runConfiguredCompiledCompile({
150
- executor,
151
- compiledPath,
152
- sourcePath,
153
- compiledConfig: datasetConfig,
154
- executionProfile,
155
- maxAttemptsOverride: null,
156
- maxLoopsOverride: null,
157
- });
158
- if (!compiled)
159
- process.exitCode = 1;
160
- return compiled;
165
+ p.outro(configToSave.checks.length > 0
166
+ ? "Saved dataset.\nNext:\n interf test\n interf compile"
167
+ : "Saved dataset.\nNext:\n interf or interf init");
161
168
  }
162
- export { formatWorkflowLabel, chooseCompiledWorkflow, createWorkflowWizard, createCompiledWorkflowWizard, } from "./create-workflow-wizard.js";
169
+ export { formatWorkflowLabel, createWorkflowWizard, createCompiledWorkflowWizard, } from "./create-workflow-wizard.js";
@@ -0,0 +1,6 @@
1
+ import type { SourceDatasetConfig } from "../lib/schema.js";
2
+ export declare function resolveConfiguredDatasetSelection(options: {
3
+ sourcePath: string;
4
+ requestedDatasetName?: string | null;
5
+ hintedDatasetConfig?: SourceDatasetConfig | null;
6
+ }): SourceDatasetConfig | null;
@@ -0,0 +1,11 @@
1
+ import { findSavedCompiledConfig } from "./compiled-flow.js";
2
+ export function resolveConfiguredDatasetSelection(options) {
3
+ if (options.hintedDatasetConfig &&
4
+ (!options.requestedDatasetName || options.hintedDatasetConfig.name === options.requestedDatasetName)) {
5
+ return options.hintedDatasetConfig;
6
+ }
7
+ if (!options.requestedDatasetName) {
8
+ return null;
9
+ }
10
+ return findSavedCompiledConfig(options.sourcePath, options.requestedDatasetName);
11
+ }
@@ -4,8 +4,8 @@ import { runInitCommand } from "./init.js";
4
4
  function printStaticLanding() {
5
5
  const config = loadUserConfig();
6
6
  console.log();
7
- console.log(chalk.bold(" Interf Compiler"));
8
- console.log(chalk.dim(" Define truth checks, measure files-as-is, then compile only if it improves accuracy."));
7
+ console.log(chalk.bold(" Interf"));
8
+ console.log(chalk.dim(" Define the task, save truth checks, measure raw files first, then compile only if they are not good enough."));
9
9
  console.log();
10
10
  if (config) {
11
11
  console.log(chalk.dim(` Agent: ${config.agent}`));
@@ -20,7 +20,7 @@ function printStaticLanding() {
20
20
  console.log(chalk.dim(" More:"));
21
21
  console.log(chalk.dim(" interf init"));
22
22
  console.log(chalk.dim(" interf create workflow"));
23
- console.log(chalk.dim(" interf doctor"));
23
+ console.log(chalk.dim(" interf doctor --live"));
24
24
  console.log(chalk.dim(" interf --help"));
25
25
  console.log();
26
26
  }
@@ -12,7 +12,7 @@ function iconFor(status) {
12
12
  }
13
13
  export const doctorCommand = {
14
14
  command: "doctor",
15
- describe: "Check local executor setup before a real compile",
15
+ describe: "Check local executor setup before a real local run",
16
16
  builder: (yargs) => yargs
17
17
  .option("live", {
18
18
  type: "boolean",
@@ -31,7 +31,7 @@ export const doctorCommand = {
31
31
  if (config) {
32
32
  checks.push({
33
33
  id: "config",
34
- label: "Interf Compiler setup",
34
+ label: "Interf setup",
35
35
  status: "pass",
36
36
  message: `Configured default agent: ${config.agent}`,
37
37
  });
@@ -39,9 +39,9 @@ export const doctorCommand = {
39
39
  else {
40
40
  checks.push({
41
41
  id: "config",
42
- label: "Interf Compiler setup",
42
+ label: "Interf setup",
43
43
  status: "warn",
44
- message: "No saved Interf Compiler setup found. `interf` or `interf init` is recommended for deterministic local runs.",
44
+ message: "No saved Interf setup found. `interf` or `interf init` is recommended for deterministic local runs.",
45
45
  });
46
46
  }
47
47
  if (!agent) {
@@ -56,7 +56,7 @@ export const doctorCommand = {
56
56
  }
57
57
  else {
58
58
  console.log();
59
- console.log(chalk.bold(" Interf Compiler doctor"));
59
+ console.log(chalk.bold(" Interf doctor"));
60
60
  console.log();
61
61
  for (const check of checks) {
62
62
  console.log(` ${iconFor(check.status)} ${check.label}: ${check.message}`);
@@ -79,7 +79,7 @@ export const doctorCommand = {
79
79
  label: "Live executor preflight",
80
80
  status: preflight.ok ? "pass" : "fail",
81
81
  message: preflight.ok
82
- ? `${agent.displayName} accepted Interf Compiler's automated run invocation`
82
+ ? `${agent.displayName} accepted Interf's automated run invocation`
83
83
  : preflight.timedOut
84
84
  ? `${agent.displayName} timed out during preflight`
85
85
  : preflight.error ?? `${agent.displayName} could not complete the preflight run`,
@@ -98,7 +98,7 @@ export const doctorCommand = {
98
98
  id: "live",
99
99
  label: "Live executor preflight",
100
100
  status: "skipped",
101
- message: "Skipped. Run `interf doctor --live` to exercise the real local agent before a compile.",
101
+ message: "Skipped. Run `interf doctor --live` to exercise the real local agent before a truth-check draft, workflow authoring run, test, or compile.",
102
102
  });
103
103
  }
104
104
  const ok = checks.every((check) => check.status !== "fail");
@@ -115,7 +115,7 @@ export const doctorCommand = {
115
115
  }
116
116
  else {
117
117
  console.log();
118
- console.log(chalk.bold(" Interf Compiler doctor"));
118
+ console.log(chalk.bold(" Interf doctor"));
119
119
  console.log();
120
120
  for (const check of checks) {
121
121
  console.log(` ${iconFor(check.status)} ${check.label}: ${check.message}`);
@@ -21,7 +21,7 @@ export declare function promptForTestAgents(): Promise<{
21
21
  export declare function resolveOrConfigureLocalExecutor(options?: {
22
22
  preflight?: boolean;
23
23
  executionProfile?: WorkflowExecutionProfile;
24
- purpose?: "compile" | "test" | "draft";
24
+ purpose?: "compile" | "test" | "draft" | "workflow";
25
25
  }): Promise<{
26
26
  executor: WorkflowExecutor | null;
27
27
  error?: string;
@@ -25,7 +25,6 @@ function persistSelectedAgent(selectedName) {
25
25
  agent: selected.name,
26
26
  agentCommand: selected.command,
27
27
  skillsInstalled: current?.skillsInstalled ?? false,
28
- ...(current?.viewer ? { viewer: current.viewer } : {}),
29
28
  initialized: current?.initialized ?? new Date().toISOString(),
30
29
  });
31
30
  }
@@ -89,7 +88,11 @@ export async function promptForTestAgents() {
89
88
  return { agents, cancelled: false };
90
89
  }
91
90
  async function promptForRunAgent(purpose) {
92
- const purposeLabel = purpose === "draft" ? "truth-check draft" : purpose;
91
+ const purposeLabel = purpose === "draft"
92
+ ? "truth-check draft"
93
+ : purpose === "workflow"
94
+ ? "workflow authoring"
95
+ : purpose;
93
96
  const detected = supportedDetectedAgents();
94
97
  if (detected.length === 0)
95
98
  return { selected: false, cancelled: false };
@@ -1,3 +1,8 @@
1
1
  import type { CommandModule } from "yargs";
2
+ import type { SourceDatasetConfig } from "../lib/schema.js";
3
+ import { runCompileCommand } from "./compile.js";
4
+ export declare function compileSelectedCompiled(sourcePath: string, compiledConfig: SourceDatasetConfig, deps?: {
5
+ runCompileCommand?: typeof runCompileCommand;
6
+ }): Promise<import("./compile.js").CompileCommandResult | null>;
2
7
  export declare const initCommand: CommandModule;
3
8
  export declare function runInitCommand(): Promise<void>;
@@ -1,13 +1,13 @@
1
1
  import chalk from "chalk";
2
2
  import * as p from "@clack/prompts";
3
+ import { resolve } from "node:path";
3
4
  import { detectInterf, readInterfConfig, resolveSourceControlPath, } from "../lib/interf.js";
4
- import { SOURCE_FOLDER_CONFIG_FILE, resolveDatasetCompileMaxAttempts, resolveDatasetCompileMaxLoops, syncCompiledInterfConfigFromSourceDatasetConfig, upsertSourceDatasetConfig, } from "../lib/source-config.js";
5
+ import { SOURCE_FOLDER_CONFIG_FILE, syncCompiledInterfConfigFromSourceDatasetConfig, upsertSourceDatasetConfig, } from "../lib/source-config.js";
5
6
  import { DEFAULT_COMPILED_NAME, describeCompileLoopSelection, promptSingleCompiledConfig, } from "./source-config-wizard.js";
6
7
  import { buildCompiledWorkflowOptions, chooseCompiledWorkflow, createWorkflowWizard, } from "./create-workflow-wizard.js";
7
- import { findBuiltCompiledPath, findSavedCompiledConfig, listSavedCompiledEntries, ensureCompiledFromConfig, } from "./compiled-flow.js";
8
+ import { findBuiltCompiledPath, findSavedCompiledConfig, listSavedCompiledEntries, } from "./compiled-flow.js";
8
9
  import { readSavedTestComparison } from "./test-flow.js";
9
- import { resolveOrConfigureLocalExecutor } from "./executor-flow.js";
10
- import { runConfiguredCompiledCompile } from "./compile.js";
10
+ import { runCompileCommand } from "./compile.js";
11
11
  import { runTestCommand } from "./test.js";
12
12
  function describeSavedQuestions(dataset) {
13
13
  const count = dataset.checks.length;
@@ -15,19 +15,13 @@ function describeSavedQuestions(dataset) {
15
15
  return "No saved truth checks yet";
16
16
  return `${count} saved truth check${count === 1 ? "" : "s"}`;
17
17
  }
18
- function compileModeAlreadyRanSavedTests(dataset) {
19
- if (dataset.checks.length === 0)
20
- return false;
21
- return (resolveDatasetCompileMaxAttempts(dataset) != null ||
22
- resolveDatasetCompileMaxLoops(dataset) != null);
23
- }
24
18
  function printDatasetSummary(options) {
25
19
  const compiledConfig = options.builtCompiledPath
26
20
  ? readInterfConfig(options.builtCompiledPath)
27
21
  : null;
28
22
  const workflowLabel = `${options.dataset.workflow ?? "interf"}${compiledConfig?.workflow_origin?.local_draft === true ? " (local draft)" : ""}`;
29
23
  p.log.info(`Dataset: ${options.dataset.name}`);
30
- p.log.info(`Path: ${options.dataset.path === "." ? "project root" : options.dataset.path}`);
24
+ p.log.info(`Path: ${options.dataset.path === "." ? "source folder" : options.dataset.path}`);
31
25
  if (options.dataset.about) {
32
26
  p.log.info(`About: ${options.dataset.about}`);
33
27
  }
@@ -60,12 +54,12 @@ async function promptDatasetAction(dataset, built, latestComparison) {
60
54
  options.push({
61
55
  value: "test",
62
56
  label: built
63
- ? "Measure files-as-is and compiled accuracy (Recommended)"
57
+ ? "Compare files-as-is and compiled dataset (Recommended)"
64
58
  : hasSavedRawBaseline
65
59
  ? "Rerun the files-as-is baseline"
66
60
  : "Measure the files-as-is baseline (Recommended)",
67
61
  hint: built
68
- ? "Compare whether the compiled dataset is actually better on the saved checks"
62
+ ? "See whether preparation helps on the saved checks"
69
63
  : hasSavedRawBaseline
70
64
  ? "Refresh the saved raw baseline on the current checks"
71
65
  : "See whether the raw dataset is already good enough before compiling",
@@ -162,6 +156,8 @@ async function chooseCompiledForWizard(options) {
162
156
  }
163
157
  async function promptCompiledSetup(options) {
164
158
  let workflowId = options.initial?.workflow ?? "interf";
159
+ let workflowLabel = buildCompiledWorkflowOptions(options.sourcePath)
160
+ .find((option) => option.value === workflowId)?.label ?? workflowId;
165
161
  if (options.introStyle === "edit") {
166
162
  const workflowChoice = await chooseCompiledWorkflow(options.sourcePath, {
167
163
  currentWorkflowId: workflowId,
@@ -170,9 +166,9 @@ async function promptCompiledSetup(options) {
170
166
  if (p.isCancel(workflowChoice))
171
167
  return null;
172
168
  workflowId = workflowChoice;
169
+ workflowLabel = buildCompiledWorkflowOptions(options.sourcePath)
170
+ .find((option) => option.value === workflowId)?.label ?? workflowId;
173
171
  }
174
- const workflowLabel = buildCompiledWorkflowOptions(options.sourcePath)
175
- .find((option) => option.value === workflowId)?.label ?? workflowId;
176
172
  const compiledConfig = await promptSingleCompiledConfig({
177
173
  projectPath: options.sourcePath,
178
174
  initial: options.initial,
@@ -206,31 +202,14 @@ async function promptCompiledSetup(options) {
206
202
  })}`));
207
203
  return compiledConfigWithWorkflow;
208
204
  }
209
- async function compileSelectedCompiled(sourcePath, compiledConfig) {
210
- const { executor, error } = await resolveOrConfigureLocalExecutor({
211
- purpose: "compile",
212
- });
213
- if (!executor && !error) {
214
- return null;
215
- }
216
- if (!executor) {
217
- process.exitCode = 1;
218
- console.log(chalk.red(error ?? "No coding agent detected."));
219
- return null;
220
- }
221
- const compiledPath = ensureCompiledFromConfig(sourcePath, compiledConfig);
222
- const compiled = await runConfiguredCompiledCompile({
223
- executor,
224
- compiledPath,
205
+ export async function compileSelectedCompiled(sourcePath, compiledConfig, deps = {}) {
206
+ return (deps.runCompileCommand ?? runCompileCommand)({
225
207
  sourcePath,
226
- compiledConfig,
227
- maxAttemptsOverride: null,
228
- maxLoopsOverride: null,
208
+ dataset: compiledConfig.name,
209
+ datasetConfig: compiledConfig,
210
+ skipConfirm: true,
211
+ skipDatasetBanner: true,
229
212
  });
230
- if (!compiled) {
231
- return null;
232
- }
233
- return compiledPath;
234
213
  }
235
214
  async function runCompiledActionMenu(sourcePath, compiledConfig, options = {}) {
236
215
  const builtCompiledPath = findBuiltCompiledPath(sourcePath, compiledConfig.name);
@@ -251,7 +230,30 @@ async function runCompiledActionMenu(sourcePath, compiledConfig, options = {}) {
251
230
  return;
252
231
  }
253
232
  if (action === "workflow") {
254
- await createWorkflowWizard({ sourcePath });
233
+ const workflowId = await createWorkflowWizard({
234
+ sourcePath,
235
+ datasetContext: {
236
+ config: compiledConfig,
237
+ datasetPath: compiledConfig.path === "."
238
+ ? sourcePath
239
+ : resolve(sourcePath, compiledConfig.path),
240
+ },
241
+ });
242
+ if (typeof workflowId === "string") {
243
+ const nextConfig = {
244
+ ...compiledConfig,
245
+ workflow: workflowId,
246
+ };
247
+ upsertSourceDatasetConfig(sourcePath, nextConfig, {
248
+ matchName: compiledConfig.name,
249
+ });
250
+ const builtCompiledPath = findBuiltCompiledPath(sourcePath, compiledConfig.name);
251
+ if (builtCompiledPath) {
252
+ syncCompiledInterfConfigFromSourceDatasetConfig(builtCompiledPath, nextConfig);
253
+ }
254
+ p.log.info(`Assigned workflow "${workflowId}" to dataset "${compiledConfig.name}".`);
255
+ p.log.info("Next: run `interf compile`, then `interf test`.");
256
+ }
255
257
  return;
256
258
  }
257
259
  if (action === "dataset") {
@@ -316,8 +318,13 @@ async function runCompiledActionMenu(sourcePath, compiledConfig, options = {}) {
316
318
  return;
317
319
  }
318
320
  }
319
- const compiledPath = await compileSelectedCompiled(sourcePath, compiledConfig);
320
- if (!compiledPath) {
321
+ const compileResult = await compileSelectedCompiled(sourcePath, compiledConfig);
322
+ if (!compileResult) {
323
+ return;
324
+ }
325
+ if (compileResult.testedDuringCompile) {
326
+ p.log.info("This compile run already tested the compiled dataset on the saved checks.");
327
+ p.log.info("Run `interf test` later if you want a fresh side-by-side comparison summary.");
321
328
  return;
322
329
  }
323
330
  await runTestCommand({
@@ -329,12 +336,13 @@ async function runCompiledActionMenu(sourcePath, compiledConfig, options = {}) {
329
336
  return;
330
337
  }
331
338
  if (action === "compile") {
332
- if (!await compileSelectedCompiled(sourcePath, compiledConfig))
339
+ const compileResult = await compileSelectedCompiled(sourcePath, compiledConfig);
340
+ if (!compileResult)
333
341
  return;
334
342
  if (compiledConfig.checks.length === 0)
335
343
  return;
336
- if (compileModeAlreadyRanSavedTests(compiledConfig)) {
337
- p.log.info("Saved compile mode already ran the compiled-dataset test.");
344
+ if (compileResult.testedDuringCompile) {
345
+ p.log.info("This compile run already ran the compiled-dataset test.");
338
346
  return;
339
347
  }
340
348
  const runCompiledTest = await p.confirm({
@@ -356,19 +364,19 @@ async function runCompiledActionMenu(sourcePath, compiledConfig, options = {}) {
356
364
  }
357
365
  export const initCommand = {
358
366
  command: "init",
359
- describe: "Open the root-folder wizard for this folder",
367
+ describe: "Open the dataset wizard for this folder",
360
368
  handler: async () => {
361
369
  await runInitCommand();
362
370
  },
363
371
  };
364
372
  export async function runInitCommand() {
365
- p.intro(chalk.bold("Interf Compiler"));
366
- p.log.info("Measure how accurately your local agents answer from the dataset in this folder, then compile only if it helps.");
373
+ p.intro(chalk.bold("Interf"));
374
+ p.log.info("Measure whether your local agents can answer the questions your task depends on from the data in this folder, then prepare the dataset only if the raw files are not good enough.");
367
375
  const cwd = process.cwd();
368
376
  const detected = detectInterf(cwd);
369
377
  const sourcePath = detected ? resolveSourceControlPath(detected.path) : cwd;
370
378
  if (detected) {
371
- p.log.info(`Working from the dataset control plane: ${sourcePath}`);
379
+ p.log.info(`Working from the source folder: ${sourcePath}`);
372
380
  }
373
381
  const savedEntries = listSavedCompiledEntries(sourcePath);
374
382
  if (savedEntries.length === 0) {
@@ -9,7 +9,7 @@ export const listCommand = {
9
9
  const sourcePath = detected ? resolveSourceControlPath(detected.path) : process.cwd();
10
10
  const datasets = listSavedCompiledEntries(sourcePath);
11
11
  if (datasets.length === 0) {
12
- console.log(chalk.dim(" Nothing found. Start with `interf`, run `interf test`, then compile a dataset when needed."));
12
+ console.log(chalk.dim(" Nothing found. Start with `interf` or `interf init` to define a dataset and save truth checks."));
13
13
  return;
14
14
  }
15
15
  console.log();
@@ -17,8 +17,11 @@ export const listCommand = {
17
17
  console.log();
18
18
  for (const dataset of datasets) {
19
19
  console.log(` ${dataset.config.name}`);
20
- console.log(chalk.dim(` ${dataset.path ?? "not built yet"}`));
21
- console.log(chalk.dim(` workflow: ${dataset.config.workflow ?? "interf"}`));
20
+ if (dataset.config.about) {
21
+ console.log(chalk.dim(` task: ${dataset.config.about}`));
22
+ }
23
+ console.log(chalk.dim(` ${dataset.path ? "built" : "not built yet"} · path: ${dataset.config.path}`));
24
+ console.log(chalk.dim(` workflow: ${dataset.config.workflow ?? "interf"}${dataset.localDraft ? " (local draft)" : ""}`));
22
25
  console.log(chalk.dim(` checks: ${dataset.config.checks.length}`));
23
26
  }
24
27
  },
@@ -3,7 +3,7 @@ import { detectInterf } from "../lib/interf.js";
3
3
  import { resetCompiledGeneratedState } from "../lib/compiled-reset.js";
4
4
  export const resetCommand = {
5
5
  command: "reset <scope>",
6
- describe: "Reset generated compiled state while keeping source files",
6
+ describe: "Reset generated compiled state while keeping `raw/` and the local workflow package",
7
7
  builder: (yargs) => yargs.positional("scope", {
8
8
  type: "string",
9
9
  choices: ["compile", "all"],
@@ -2,9 +2,9 @@ import type { SourceTruthCheck, SourceDatasetConfig } from "../lib/schema.js";
2
2
  export declare const DEFAULT_COMPILED_NAME = "dataset1";
3
3
  export declare const DEFAULT_COMPILED_CHECK_QUESTION_PLACEHOLDER = "A question you can already verify from this dataset";
4
4
  export declare const DEFAULT_COMPILED_CHECK_ANSWER_PLACEHOLDER = "The expected answer in plain English";
5
- export declare const DEFAULT_COMPILED_ABOUT_PLACEHOLDER = "Example: forward-demand metrics, board-prep questions, or chart reads from this dataset.";
5
+ export declare const DEFAULT_COMPILED_ABOUT_PLACEHOLDER = "Example: board-prep questions from these files, chart reads from this report, or tax review from these exports.";
6
6
  export declare const DEFAULT_DATASET_PATH_PLACEHOLDER = "./dataset1";
7
- export declare const DEFAULT_COMPILE_RETRY_ATTEMPTS = 1;
7
+ export declare const DEFAULT_COMPILE_RETRY_ATTEMPTS = 3;
8
8
  export declare const DEFAULT_SELF_IMPROVING_LOOPS = 3;
9
9
  export type CompileLoopMode = "once" | "retry" | "self-improving";
10
10
  export interface CompileLoopSelection {