@interf/compiler 0.6.8 → 0.7.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.
package/README.md CHANGED
@@ -1,15 +1,12 @@
1
1
  # Interf
2
2
 
3
3
  Interf prepares portable context for your agents.
4
- Check the source files first. Build portable context when the agent misses evidence, loses links across files, or sounds confident without seeing the full picture.
5
4
 
6
- **The files can be right. The agent can still be wrong.**
5
+ Agents now run real work from folders of PDFs, exports, notes, and transcripts. They don't reliably assemble the full picture from them: missed evidence, links lost across files, or answers that sound confident but are wrong. A chart inside one PDF can be obvious to a human analyst and easy for an agent to miss.
7
6
 
8
- Agents now run real work from folders of PDFs, exports, notes, and transcripts. The failure often shows up late: missed evidence, shallow analysis, bad comparisons, or answers that sound confident but are wrong.
7
+ The fix is structure: summarize the files, organize by category, link what belongs together. You tell Interf Compiler how that's a compilation workflow.
9
8
 
10
- A chart inside one PDF can be obvious to a human analyst and easy for an agent to miss. Across the folder, the real problem is rarely one missing fact. The agent never assembles the full picture from the files on its own.
11
-
12
- `Interf Compiler` is the local, open-source runtime that runs context-preparation workflows on your files. A workflow tells Interf how to process, organize, and structure those files for agent use. Your local agent runs each stage. Interf Compiler runs the pipeline and enforces the output shape. `interf test` scores the result on your own questions. The portable context is a proof, not a promise.
9
+ `Interf Compiler` is the local runtime that runs compilation workflows on your files. Your local agent executes each stage. The compiler builds portable context a local folder your agent reads. If the first build misses your questions, Interf improves the compilation workflow and builds again.
13
10
 
14
11
  ```text
15
12
  project-root/
@@ -20,6 +17,9 @@ project-root/
20
17
  interf.json # main config: works, source paths, questions, workflow choices, and defaults
21
18
  interf/
22
19
  bristol-office-analysis/ # portable context your agent starts from
20
+ workflows/
21
+ interf-default/ # built-in compilation workflow, copied here on init — inspect, edit, or fork
22
+ your-custom-workflow/ # optional: your own, via `interf create workflow`
23
23
  tests/
24
24
  bristol-office-analysis/ # saved source-files vs portable-context comparisons
25
25
  ```
@@ -45,8 +45,8 @@ The table is a sample, not a leaderboard. Run it on your own files. If you run m
45
45
 
46
46
  ## Design Choices
47
47
 
48
- - `Check before build`: source files are sometimes already enough. Interf will say so.
49
- - `Prove the full picture`: every build is scored on your own questions. If the portable context does not help, `interf test` tells you.
48
+ - `Check before build`: run `interf test --target raw` first — sometimes the source files already pass on your questions.
49
+ - `Scored on your own questions`: every build is checked against questions you wrote from the files. If the portable context does not help, `interf test` tells you.
50
50
  - `File over app`: the portable context is a local folder next to the source files. Inspect it, diff it, version it.
51
51
  - `Bring your own AI`: use Claude Code, Codex, or another local agent.
52
52
  - `Explicit`: no hidden store, no hidden index. The portable context is plain files on disk.
@@ -63,19 +63,19 @@ Requires Node.js 20+ and a local coding agent such as Claude Code or Codex. Run
63
63
  ## Quick Start
64
64
 
65
65
  1. Run `interf` in the project root.
66
- 2. Pick the source folder for one work.
66
+ 2. Pick the source folder for one piece of agent work.
67
67
  3. Describe what the agent should do with those files.
68
68
  4. Review the suggested questions.
69
- 5. Run `interf test --target raw` to check the source files.
69
+ 5. Run `interf test --target raw` to score the source files.
70
70
  6. Run `interf compile` to build portable context.
71
71
  7. Run `interf test` again to compare source files and portable context on the same questions.
72
72
  8. If the portable context does better, point your agent at `interf/<work>/`.
73
73
 
74
- If the source files already pass, stop there. Interf is allowed to tell you that you do not need portable context for that work.
74
+ `interf init` copies the built-in compilation workflow to `interf/workflows/interf-default/`. That folder is yours inspect it, edit it, or fork it into a new compilation workflow with `interf create workflow`.
75
75
 
76
76
  ## Portable Context
77
77
 
78
- `interf/<work>/` is the local folder your agent starts from when the source files are not enough. For the built-in `interf` workflow, it includes:
78
+ `interf/<work>/` is the local folder Interf Compiler builds from your files a context layer your agents navigate, not a replacement for your files. For the built-in `interf-default`, it includes:
79
79
 
80
80
  ```text
81
81
  interf/bristol-office-analysis/
@@ -89,77 +89,55 @@ interf/bristol-office-analysis/
89
89
 
90
90
  The source files stay the source of truth. Interf builds next to them; it does not replace them.
91
91
 
92
- The portable context is a sibling folder you can inspect, diff, version, or hand to a different agent. The portable context carries its own `raw/` snapshot, so the evidence the agent works from stays attached to the result.
92
+ The portable context is a folder you can inspect, diff, version, or hand to a different agent. The portable context carries its own `raw/` snapshot, so the evidence the agent works from stays attached to the result.
93
93
 
94
94
  ## Workflow Packages
95
95
 
96
- A workflow is Interf's preparation method for a kind of work. It tells the compiler how to process the source files and what folder shape to build for the agent. The workflow declares the compilation stages. Your local agent runs each one. The compiler writes the result as one folder on disk.
97
-
98
- A **context interface** is the shape of that output — the folder tree, the named files, and the rule that every one of them must exist on disk before the build is called done. The workflow defines the interface. The compiler enforces it.
99
-
100
- The built-in `interf` workflow is the default. Run `interf create workflow` to draft a reusable workflow package for a different kind of work — a different method, a different output shape, or both.
96
+ A compilation workflow is how you tell Interf Compiler to organize and structure your files so your agents can reliably work from them. `interf init` copies the built-in `interf-default` into your project at `interf/workflows/interf-default/` it is a real folder you can inspect and edit. Fork it with `interf create workflow` when you need a different method, a different output, or both.
101
97
 
102
98
  ```text
103
- interf/workflows/office-analysis/
99
+ interf/workflows/interf-default/
104
100
  workflow.json # method: how to process and organize the files
105
- workflow.schema.json # output contract: what folder shape the compiler must build
106
- README.md # what this workflow is for, for humans and agents
101
+ workflow.schema.json # output contract: what files and folders the output must contain
102
+ README.md # what this compilation workflow is for, for humans and agents
107
103
  compile/
108
104
  stages/
109
- summarize/ # define your own stages here
105
+ summarize/ # stage instructions the compiler runs with your local agent
110
106
  structure/
111
107
  shape/
112
108
  use/
113
109
  query/ # how your agent reads the portable context
114
- improve/ # how Interf revises this workflow if questions still fail
110
+ improve/ # how Interf revises this compilation workflow if questions still fail
115
111
  ```
116
112
 
117
113
  Think of it as method -> output shape.
118
114
 
119
115
  - `workflow.json` describes the method: expected inputs, stages, and how the files should be processed.
120
- - `workflow.schema.json` describes the output contract: the folder shape and outputs the compiler must build.
121
- - `compile/stages/<stage>/` is where you author one folder per stage — a small, specific job like `summarize` or `structure`. You write the instructions; the compiler runs them with your local agent.
116
+ - `workflow.schema.json` describes the output contract: what files and folders the output must contain. Technically, this is the `context interface`, declared in `workflow.schema.json` and enforced by the compiler.
117
+ - `compile/stages/<stage>/` is where you author one folder per stage — a small, specific phase like `summarize` or `structure`. You write the instructions; the compiler runs them with your local agent.
122
118
  - `use/query/` holds the instructions your agent follows when it reads the portable context for live work.
123
- - `improve/` holds the instructions Interf follows when the first build does not pass and the workflow itself needs editing.
124
-
125
- A workflow package is the reusable preparation method. Interf Compiler runs it on your files. Your local agent runs each stage. The result is a local folder your agents can read.
126
-
127
- ## Compiler Primitives
128
-
129
- Every workflow runs on the same three primitives. Interf Compiler enforces the contract. The workflow chooses the method.
130
-
131
- ### Input snapshot
132
-
133
- The workflow declares what source files it expects — one PDF, a folder of mixed exports, a tree of notes. Interf Compiler copies those inputs into `raw/` before any stage runs. The evidence stays attached to the result.
134
-
135
- ### Context interface
136
-
137
- The workflow declares the folder shape the agent must read. Interf Compiler checks on disk that the shape holds before the build is called done. If a stage writes nothing, the build fails loudly.
138
-
139
- ### Stage execution
140
-
141
- The workflow declares ordered compilation stages — small, specific jobs like `summarize`, `structure`, `shape`. You write the instructions per stage. Interf Compiler runs each one through your local agent and checks the output before moving to the next.
119
+ - `improve/` holds the instructions Interf follows when the first build misses and the compilation workflow itself needs editing.
142
120
 
143
- The context interface is the key guarantee. The shape holds on disk, or `interf test` reports the gap on your own questions.
121
+ A workflow package bundles a compilation workflow. Interf Compiler runs it on your files. Your local agent runs each stage. The result is a local folder your agents can read.
144
122
 
145
123
  ## Self-Improving Workflows
146
124
 
147
- When the first build still misses questions, Interf edits the workflow package itself and compiles again. Same files, same questions, different preparation. The workflow is the unit of improvement — not just the output folder.
125
+ When the first build still misses questions, Interf edits the workflow package itself and compiles again. Same files, same questions, different preparation.
148
126
 
149
127
  Interf saves every scored run under `interf/tests/<work>/`. You can inspect what changed and why a later build did better.
150
128
 
151
129
  ## How the Pieces Fit
152
130
 
153
- - `interf.json` is the project control file. It names the work, points at the source files, saves the questions, and selects the workflow.
154
- - A workflow package is the reusable preparation method.
155
- - `workflow.json` defines that method.
131
+ - `interf.json` is the project control file. It names the work, points at the source files, saves the questions, and selects the compilation workflow.
132
+ - A workflow package bundles a compilation workflow.
133
+ - `workflow.json` defines the method.
156
134
  - `workflow.schema.json` defines the output contract, or context interface, the compiler must build.
157
- - `Interf Compiler` is the local runtime. It runs the workflow, your agent runs each stage, and the portable context lands next to the source files.
135
+ - `Interf Compiler` is the local runtime. It runs the compilation workflow, your agent runs each stage, and the portable context lands next to the source files.
158
136
  - The portable context is the local folder built for your agents. Technically, that folder is the compiled context.
159
137
 
160
138
  ## interf.json
161
139
 
162
- `interf.json` is the main config file in the project root. Each entry describes one work: the source path, the saved questions, the workflow that prepares the context, and optional defaults.
140
+ `interf.json` is the main config file in the project root. Each entry describes one piece of agent work: the source path, the saved questions, the compilation workflow that prepares the context, and optional defaults.
163
141
 
164
142
  ```text
165
143
  {
@@ -168,7 +146,7 @@ Interf saves every scored run under `interf/tests/<work>/`. You can inspect what
168
146
  "name": "bristol-office-analysis",
169
147
  "path": "./bristol-office-analysis",
170
148
  "about": "Read the report and answer the saved questions.",
171
- "workflow": "interf",
149
+ "workflow": "interf-default",
172
150
  "checks": [
173
151
  { "question": "...", "answer": "..." }
174
152
  ]
@@ -177,7 +155,7 @@ Interf saves every scored run under `interf/tests/<work>/`. You can inspect what
177
155
  }
178
156
  ```
179
157
 
180
- The `workflow` field is the key choice per work. Set it to `interf` for the built-in workflow, or to a workflow you have authored. A different workflow is a different method and a different output shape. Same files, different portable context.
158
+ The `workflow` field is the key choice per work. It points to a folder id under `interf/workflows/`. Set it to `interf-default` (the built-in default, copied locally on init) or to a compilation workflow you have authored. A different compilation workflow is a different method and a different output. Same files, different portable context.
181
159
 
182
160
  ## Questions
183
161
 
@@ -219,7 +197,7 @@ A maintained public test example in this repo stores them like this:
219
197
 
220
198
  ## What Interf Is Not
221
199
 
222
- - Not a second brain or memory product. One local folder per work; nothing global.
200
+ - Not a second brain or memory product. One local folder per piece of agent work; nothing global.
223
201
  - Not a vector store or RAG server. The portable context is plain files.
224
202
  - Not a hosted context layer. Interf runs locally and `interf/` is yours.
225
203
  - Not an agent harness. Interf prepares the folder; your existing agent reads it.
@@ -3,7 +3,8 @@ import * as p from "@clack/prompts";
3
3
  import { resolve } from "node:path";
4
4
  import { listCompiledWorkflowChoices, getCompiledWorkflow, } from "../../packages/workflow-package/workflow-definitions.js";
5
5
  import { createLocalWorkflowPackageFromTemplate } from "../../packages/workflow-package/interf-workflow-package.js";
6
- import { isWorkflowId, } from "../../packages/workflow-package/local-workflows.js";
6
+ import { rmSync } from "node:fs";
7
+ import { isWorkflowId, loadWorkflowDefinitionFromDir, } from "../../packages/workflow-package/local-workflows.js";
7
8
  import { resolveOrConfigureLocalExecutor } from "./executor-flow.js";
8
9
  import { runWorkflowAuthoringDraft } from "../../packages/workflow-authoring/workflow-authoring.js";
9
10
  import { listSourceDatasetConfigs, loadSourceFolderConfig, resolveSourceDatasetPath, } from "../../packages/project-model/source-config.js";
@@ -214,9 +215,9 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
214
215
  matchedDataset = matchedDataset ?? findMatchingDatasetConfig(sourcePath, datasetPath);
215
216
  }
216
217
  const taskPrompt = await prompts.text({
217
- message: "What kind of work should this workflow help with?",
218
- placeholder: "Example: chart reads, board prep, or latest planned launch status",
219
- validate: (value) => (value.trim().length === 0 ? "Work focus is required" : undefined),
218
+ message: "How do you want to organize your files?",
219
+ placeholder: "Research interview transcripts. Agent produces per-interview summaries and a themes list with supporting quotes. Flow: summarize each, group by theme, collect evidence across interviews.",
220
+ validate: (value) => (value.trim().length === 0 ? "A description is required" : undefined),
220
221
  });
221
222
  if (prompts.isCancel(taskPrompt))
222
223
  return taskPrompt;
@@ -254,6 +255,26 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
254
255
  preparePreview: true,
255
256
  });
256
257
  if (result.status === "updated") {
258
+ const draft = loadWorkflowDefinitionFromDir(result.workflowPath);
259
+ const stageList = draft?.stages?.map((stage) => stage.id).join(" → ") ?? "—";
260
+ prompts.log.info(`Draft ready at ${result.workflowPath}`);
261
+ prompts.log.info(` Name: ${draft?.label ?? label}`);
262
+ prompts.log.info(` Description: ${draft?.hint ?? hint.trim()}`);
263
+ if (draft?.purpose)
264
+ prompts.log.info(` Purpose: ${draft.purpose}`);
265
+ prompts.log.info(` Stages: ${stageList}`);
266
+ const confirmChoice = await prompts.select({
267
+ message: "Save this workflow?",
268
+ options: [
269
+ { value: "save", label: "Save", hint: "Keep the draft as your new compilation workflow" },
270
+ { value: "cancel", label: "Discard", hint: "Remove the draft folder and exit without saving" },
271
+ ],
272
+ });
273
+ if (prompts.isCancel(confirmChoice) || confirmChoice === "cancel") {
274
+ rmSync(result.workflowPath, { recursive: true, force: true });
275
+ prompts.log.info(`Discarded draft at ${result.workflowPath}`);
276
+ return null;
277
+ }
257
278
  prompts.log.info(`Saved local workflow: ${result.workflowPath}`);
258
279
  return workflowId;
259
280
  }
@@ -5,6 +5,7 @@ import { detectInterf, readInterfConfig, resolveSourceControlPath, } from "../..
5
5
  import { SOURCE_FOLDER_CONFIG_FILE, syncCompiledInterfConfigFromSourceDatasetConfig, upsertSourceDatasetConfig, } from "../../packages/project-model/source-config.js";
6
6
  import { DEFAULT_COMPILED_NAME, describeCompileLoopSelection, promptSingleCompiledConfig, } from "./source-config-wizard.js";
7
7
  import { buildCompiledWorkflowOptions, chooseCompiledWorkflow, createWorkflowWizard, } from "./create-workflow-wizard.js";
8
+ import { seedLocalDefaultWorkflow } from "../../packages/workflow-package/local-workflows.js";
8
9
  import { findBuiltCompiledPath, findSavedCompiledConfig, listSavedCompiledEntries, } from "./compiled-flow.js";
9
10
  import { readCurrentSavedTestComparison, } from "./test-flow.js";
10
11
  import { runCompileCommand } from "./compile.js";
@@ -219,7 +220,7 @@ async function chooseCompiledForWizard(options) {
219
220
  return findSavedCompiledConfig(options.sourcePath, String(selected));
220
221
  }
221
222
  async function promptCompiledSetup(options) {
222
- let workflowId = options.initial?.workflow ?? "interf";
223
+ let workflowId = options.initial?.workflow ?? "interf-default";
223
224
  let workflowLabel = buildCompiledWorkflowOptions(options.sourcePath)
224
225
  .find((option) => option.value === workflowId)?.label ?? workflowId;
225
226
  if (options.introStyle === "edit") {
@@ -258,7 +259,7 @@ async function promptCompiledSetup(options) {
258
259
  console.log(chalk.dim(` Project folder: ${options.sourcePath}`));
259
260
  console.log(chalk.dim(` Setup: ${compiledConfigWithWorkflow.name}`));
260
261
  console.log(chalk.dim(` Source folder: ${compiledConfigWithWorkflow.path}`));
261
- console.log(chalk.dim(` Workflow: ${workflowLabel}`));
262
+ console.log(chalk.dim(` Workflow: ${workflowLabel} · interf/workflows/${workflowId}/`));
262
263
  console.log(chalk.dim(` Compile mode: ${describeCompileLoopSelection({
263
264
  maxAttempts: compiledConfigWithWorkflow.max_attempts,
264
265
  maxLoops: compiledConfigWithWorkflow.max_loops,
@@ -456,13 +457,18 @@ export const initCommand = {
456
457
  };
457
458
  export async function runInitCommand() {
458
459
  p.intro(chalk.bold("Interf"));
459
- p.log.info("Interf prepares portable context for your agents from the source folder you choose. Start with the work, review the suggested questions, check the source files first, and build a local folder when the files need more structure.");
460
+ p.log.info("Interf prepares portable context for your agents.");
461
+ p.log.info("Pick a source folder, review the suggested questions, and build when the files need more structure.");
460
462
  const cwd = process.cwd();
461
463
  const detected = detectInterf(cwd);
462
464
  const sourcePath = detected ? resolveSourceControlPath(detected.path) : cwd;
463
465
  if (detected) {
464
466
  p.log.info(`Working from the project folder: ${sourcePath}`);
465
467
  }
468
+ const seeded = seedLocalDefaultWorkflow({ sourcePath });
469
+ if (!seeded.alreadyExisted) {
470
+ p.log.info(`Copied built-in compilation workflow to interf/workflows/${seeded.workflowId}/ — inspect or fork it anytime.`);
471
+ }
466
472
  const savedEntries = listSavedCompiledEntries(sourcePath);
467
473
  if (savedEntries.length === 0) {
468
474
  const compiledConfig = await promptCompiledSetup({
@@ -37,6 +37,13 @@ export declare function loadWorkflowDefinitionFromDir(dirPath: string): LocalWor
37
37
  export declare function listLocalWorkflowDefinitions(sourcePath: string): LocalWorkflowDefinition[];
38
38
  export declare function loadLocalWorkflowDefinition(sourcePath: string, id: string): LocalWorkflowDefinition | null;
39
39
  export declare function resolveWorkflowPackageSourcePath(sourcePath: string, workflowId: string): string | null;
40
+ export declare function seedLocalDefaultWorkflow(options: {
41
+ sourcePath: string;
42
+ }): {
43
+ workflowId: string;
44
+ targetPath: string;
45
+ alreadyExisted: boolean;
46
+ };
40
47
  export declare function isWorkflowId(value: string): boolean;
41
48
  export declare function patchWorkflowPackageMetadata(dirPath: string, options?: {
42
49
  id?: string;
@@ -131,16 +131,33 @@ export function loadLocalWorkflowDefinition(sourcePath, id) {
131
131
  return loadWorkflowDefinitionFromDir(workflowDefinitionPath(sourcePath, id));
132
132
  }
133
133
  export function resolveWorkflowPackageSourcePath(sourcePath, workflowId) {
134
- const builtinPath = builtinWorkflowRootPath(workflowId);
135
- if (workflowId === "interf" && existsSync(join(builtinPath, "workflow.json")))
136
- return builtinPath;
137
134
  const localPath = workflowDefinitionPath(sourcePath, workflowId);
138
135
  if (existsSync(join(localPath, "workflow.json")))
139
136
  return localPath;
137
+ const builtinPath = builtinWorkflowRootPath(workflowId);
140
138
  if (existsSync(join(builtinPath, "workflow.json")))
141
139
  return builtinPath;
140
+ if (workflowId === "interf-default") {
141
+ const builtinInterfPath = builtinWorkflowRootPath("interf");
142
+ if (existsSync(join(builtinInterfPath, "workflow.json")))
143
+ return builtinInterfPath;
144
+ }
142
145
  return null;
143
146
  }
147
+ export function seedLocalDefaultWorkflow(options) {
148
+ const workflowId = "interf-default";
149
+ const targetPath = workflowDefinitionPath(options.sourcePath, workflowId);
150
+ if (existsSync(join(targetPath, "workflow.json"))) {
151
+ return { workflowId, targetPath, alreadyExisted: true };
152
+ }
153
+ const builtinInterfPath = builtinWorkflowRootPath("interf");
154
+ if (!existsSync(join(builtinInterfPath, "workflow.json"))) {
155
+ throw new Error(`Built-in "interf" workflow not found at ${builtinInterfPath}.`);
156
+ }
157
+ copyWorkflowPackageDirectory(builtinInterfPath, targetPath);
158
+ patchWorkflowPackageMetadata(targetPath, { id: workflowId });
159
+ return { workflowId, targetPath, alreadyExisted: false };
160
+ }
144
161
  export function isWorkflowId(value) {
145
162
  return WorkflowIdPattern.test(value);
146
163
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@interf/compiler",
3
- "version": "0.6.8",
4
- "description": "Interf prepares portable context for your agents by checking your files first, building a local folder when needed, and using self-improving loops until more questions pass.",
3
+ "version": "0.7.0",
4
+ "description": "Local, open-source context compiler for agent work. Build portable context from your files with a compilation workflow you define. Check on your own questions.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "interf": "dist/bin.js"