@interf/compiler 0.7.1 → 0.7.3
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 +77 -72
- package/builtin-workflows/interf/README.md +4 -4
- package/builtin-workflows/interf/compile/stages/shape/SKILL.md +4 -4
- package/builtin-workflows/interf/improve/SKILL.md +1 -1
- package/builtin-workflows/interf/use/query/SKILL.md +1 -1
- package/builtin-workflows/interf/workflow.json +4 -4
- package/builtin-workflows/interf/workflow.schema.json +1 -1
- package/dist/cli/commands/compile-controller.js +5 -5
- package/dist/cli/commands/compile.js +1 -1
- package/dist/cli/commands/create-workflow-wizard.d.ts +6 -0
- package/dist/cli/commands/create-workflow-wizard.js +57 -5
- package/dist/cli/commands/create.js +21 -11
- package/dist/cli/commands/default.js +2 -1
- package/dist/cli/commands/init.js +65 -54
- package/dist/cli/commands/source-config-wizard.d.ts +0 -1
- package/dist/cli/commands/source-config-wizard.js +1 -4
- package/dist/cli/commands/status.js +3 -3
- package/dist/cli/commands/test-flow.js +9 -7
- package/dist/cli/commands/test.js +7 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/packages/agents/lib/shells.js +22 -19
- package/dist/packages/compiler/compiled-paths.js +1 -1
- package/dist/packages/compiler/runtime-prompt.js +1 -1
- package/dist/packages/project-model/interf-detect.js +24 -10
- package/dist/packages/project-model/interf-scaffold.d.ts +1 -0
- package/dist/packages/project-model/interf-scaffold.js +30 -11
- package/dist/packages/project-model/interf.d.ts +1 -1
- package/dist/packages/project-model/interf.js +1 -1
- package/dist/packages/project-model/project-paths.d.ts +3 -1
- package/dist/packages/project-model/project-paths.js +6 -2
- package/dist/packages/project-model/source-config.d.ts +5 -0
- package/dist/packages/project-model/source-config.js +60 -7
- package/dist/packages/testing/test-paths.js +6 -3
- package/dist/packages/workflow-authoring/workflow-authoring.js +4 -2
- package/dist/packages/workflow-authoring/workflow-edit-session.js +5 -2
- package/dist/packages/workflow-package/context-interface.js +1 -1
- package/dist/packages/workflow-package/workflow-review-paths.js +5 -1
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
# Interf
|
|
2
2
|
|
|
3
|
-
Interf prepares portable context
|
|
3
|
+
Interf prepares data for agent work. It runs locally, processes your files, shows evidence that your data is ready, and writes portable context: a local folder with verifiable outputs agents can use.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Hallucinations aren't an agent problem. They're a data preparation problem.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
When agents start from source files, they have to discover the full picture while they work. That discovery is hidden: you cannot see which files were processed, which evidence was used, or which connections were found.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Interf replaces that hidden discovery with a visible file-processing workflow: how you tell Interf to prepare your files for the job agents need to do. You define how the files should be processed, what outputs agents should get, and what evidence should show the data is ready. Interf runs the workflow locally and writes the portable context: evidence, structure, and cross-file connections for agents.
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
interf.json
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
bristol-office-analysis/
|
|
13
|
+
report.md
|
|
14
|
+
notes.md
|
|
15
|
+
exports/
|
|
16
|
+
interf/
|
|
17
|
+
interf.json # saved setup: source paths, questions, workflow choices, and defaults
|
|
18
|
+
bristol-office-analysis/ # portable context agents read
|
|
19
|
+
AGENTS.md # agent-facing entry point
|
|
20
|
+
raw/ # same source files copied here
|
|
21
|
+
report.md
|
|
22
|
+
notes.md
|
|
23
|
+
exports/
|
|
24
|
+
home.md # overview and routes for agents
|
|
25
|
+
summaries/ # one note per source file
|
|
26
|
+
knowledge/ # linked notes built from the files
|
|
27
|
+
workflows/ # editable file-processing workflows
|
|
25
28
|
```
|
|
26
29
|
|
|
27
|
-
The project root is the control plane. Your agent starts from `interf/<work>/` when the source files are not enough.
|
|
28
|
-
|
|
29
30
|
## What a Run Looks Like
|
|
30
31
|
|
|
31
|
-
Same files, same questions. What changes is whether the
|
|
32
|
+
`interf test` scores source files and portable context on the same questions: small, verifiable facts from the files. Same files, same questions. What changes is whether Interf prepared the full picture first.
|
|
32
33
|
|
|
33
34
|
A recent public run — one market report, two questions, two agents on the same setup — produced:
|
|
34
35
|
|
|
@@ -39,20 +40,20 @@ A recent public run — one market report, two questions, two agents on the same
|
|
|
39
40
|
| Claude Code (Claude Opus 4.6, max) | `0/2` | `2/2` |
|
|
40
41
|
<!-- PUBLIC_BENCHMARK_TABLE:END -->
|
|
41
42
|
|
|
42
|
-
Codex passed on the raw files; Claude Code only passed after Interf prepared the portable context. Both numbers come from
|
|
43
|
+
Codex passed on the raw files; Claude Code only passed after Interf prepared the portable context. Both numbers come from that same scoring pass.
|
|
43
44
|
|
|
44
|
-
That
|
|
45
|
+
That tells you whether preparation helped on this agent work.
|
|
45
46
|
|
|
46
|
-
The table is a sample, not a leaderboard. Run
|
|
47
|
+
The table is a sample, not a leaderboard. Run `interf test` on your own files. If you run more than one local agent, one scoring pass can include each of them.
|
|
47
48
|
|
|
48
49
|
## Design Choices
|
|
49
50
|
|
|
50
|
-
- `
|
|
51
|
-
- `
|
|
52
|
-
- `
|
|
53
|
-
- `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.
|
|
51
|
+
- `Per-work`: every portable context is prepared for one specific job agents need to do, not a generic index over your files.
|
|
52
|
+
- `Deterministic`: Interf runs each stage, an ordered phase of the file-processing workflow, and shows stage-by-stage proof of work: which files were processed, what each stage produced, and whether required outputs exist. Agents do not have to rebuild the full picture while they work.
|
|
53
|
+
- `Local-first and private`: your files, your questions, and your agent runs stay on your machine. No cloud, no uploads, no telemetry.
|
|
54
54
|
- `Bring your own AI`: use Claude Code, Codex, or another local agent.
|
|
55
|
-
- `
|
|
55
|
+
- `File over app`: the portable context is a local folder next to the source files — no hidden store, no hidden index. Inspect it, diff it, version it.
|
|
56
|
+
- `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.
|
|
56
57
|
|
|
57
58
|
## Install
|
|
58
59
|
|
|
@@ -66,79 +67,83 @@ Requires Node.js 20+ and a local coding agent such as Claude Code or Codex. Run
|
|
|
66
67
|
## Quick Start
|
|
67
68
|
|
|
68
69
|
1. Run `interf` in the project root.
|
|
69
|
-
2. Pick the source folder for
|
|
70
|
+
2. Pick the source folder for the job agents need to do.
|
|
70
71
|
3. Describe what the agent should do with those files.
|
|
71
|
-
4. Review the suggested questions.
|
|
72
|
-
5.
|
|
72
|
+
4. Review the suggested questions Interf will use to compare source files and portable context.
|
|
73
|
+
5. Choose the file-processing workflow, or create one by describing the source data, outputs, and proof you need.
|
|
73
74
|
6. Run `interf compile` to build portable context.
|
|
74
|
-
7. Run `interf test`
|
|
75
|
+
7. Run `interf test` to compare source files and portable context on the same questions.
|
|
75
76
|
8. If the portable context does better, point your agent at `interf/<work>/`.
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
If you want a baseline before building, run `interf test --target raw`. It is optional proof, not the main path.
|
|
79
|
+
|
|
80
|
+
`interf init` saves setup in `interf/interf.json` and copies the built-in file-processing workflow to `interf/workflows/interf-default/`. That workflow package is yours — inspect it, edit it, or fork it with `interf create workflow`.
|
|
78
81
|
|
|
79
82
|
## Portable Context
|
|
80
83
|
|
|
81
|
-
`interf/<work>/` is the local folder Interf
|
|
84
|
+
`interf/<work>/` is the local folder Interf writes from your files. It gives agents evidence, structure, and cross-file connections for navigating the files. It is not a replacement for your files. For the built-in `interf-default`, it includes:
|
|
82
85
|
|
|
83
86
|
```text
|
|
84
87
|
interf/bristol-office-analysis/
|
|
85
|
-
AGENTS.md #
|
|
88
|
+
AGENTS.md # agent-facing entry point and retrieval rules
|
|
86
89
|
CLAUDE.md # same guidance for Claude Code
|
|
87
|
-
raw/ #
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
raw/ # same source files copied here
|
|
91
|
+
report.md
|
|
92
|
+
notes.md
|
|
93
|
+
exports/
|
|
94
|
+
home.md # overview and routes for agents
|
|
95
|
+
summaries/ # one note per source file
|
|
90
96
|
knowledge/ # linked notes built from the files
|
|
91
97
|
```
|
|
92
98
|
|
|
93
99
|
The source files stay the source of truth. Interf builds next to them; it does not replace them.
|
|
94
100
|
|
|
95
|
-
|
|
101
|
+
`AGENTS.md` tells agents how to use the portable context: start from the prepared outputs, follow the prepared routes, and verify against `raw/` when exact source evidence matters.
|
|
102
|
+
|
|
103
|
+
Interf also records stage-by-stage proof of work: which files were processed, what each stage produced, and whether required outputs were created.
|
|
104
|
+
|
|
105
|
+
The portable context is self-contained — it carries its own `raw/` snapshot, so the evidence the agent works from stays attached to the result. Hand it to a different agent and the folder stands on its own.
|
|
96
106
|
|
|
97
107
|
## Workflow Packages
|
|
98
108
|
|
|
99
|
-
A
|
|
109
|
+
A workflow package tells Interf how to process your files for the job agents need to do. When you create one, describe three things: what data is in the folder, what the portable context should contain, and what evidence should show your data is ready. The built-in `interf-default` lives at `interf/workflows/interf-default/`. Fork it with `interf create workflow` when you need a different method, a different output, or both.
|
|
100
110
|
|
|
101
111
|
```text
|
|
102
112
|
interf/workflows/interf-default/
|
|
103
|
-
workflow.json # method:
|
|
104
|
-
workflow.schema.json # output contract:
|
|
105
|
-
README.md # what this
|
|
113
|
+
workflow.json # method: source data, stages, and processing rules
|
|
114
|
+
workflow.schema.json # output contract: required portable-context files and folders
|
|
115
|
+
README.md # what this workflow package is for, for humans and agents
|
|
106
116
|
compile/
|
|
107
117
|
stages/
|
|
108
|
-
summarize/ # stage instructions
|
|
118
|
+
summarize/ # stage instructions Interf runs during compile
|
|
109
119
|
structure/
|
|
110
120
|
shape/
|
|
111
121
|
use/
|
|
112
|
-
query/ # how
|
|
113
|
-
improve/ # how Interf revises this
|
|
122
|
+
query/ # how agents read the portable context
|
|
123
|
+
improve/ # how Interf revises this workflow package if questions still fail
|
|
114
124
|
```
|
|
115
125
|
|
|
116
|
-
- `workflow.json` describes the method:
|
|
117
|
-
- `workflow.schema.json` describes the output contract: what
|
|
118
|
-
- `compile/stages/<stage>/` is where you author one folder per stage — a small, specific phase like `summarize` or `structure`. You write the instructions;
|
|
119
|
-
- `use/query/` holds the instructions
|
|
120
|
-
- `improve/` holds the instructions Interf follows when the first build misses and the
|
|
126
|
+
- `workflow.json` describes the method: source data, stages, and how the files should be processed.
|
|
127
|
+
- `workflow.schema.json` describes the output contract: what the portable context must contain. Technically, this is the `context interface`, declared in `workflow.schema.json` and enforced when you run `interf compile`.
|
|
128
|
+
- `compile/stages/<stage>/` is where you author one folder per stage — a small, specific phase like `summarize` or `structure`. You write the instructions; Interf runs them during compile.
|
|
129
|
+
- `use/query/` holds the instructions agents follow when they read the portable context for live work.
|
|
130
|
+
- `improve/` holds the instructions Interf follows when the first build misses and the workflow package itself needs editing.
|
|
121
131
|
|
|
122
|
-
A workflow package bundles
|
|
132
|
+
A workflow package bundles the method Interf runs on your files. It defines the stages, output contract, proof requirements, and improvement instructions. The result is portable context your agents can read.
|
|
123
133
|
|
|
124
|
-
##
|
|
134
|
+
## Workflow Improvement
|
|
125
135
|
|
|
126
|
-
When the first build still misses questions, Interf edits the workflow package itself and compiles again. Same files, same questions, different preparation.
|
|
136
|
+
When the first portable-context build still misses questions, Interf edits the workflow package itself and compiles again. Same files, same questions, different preparation.
|
|
127
137
|
|
|
128
|
-
Interf saves every scored run under `interf/tests
|
|
138
|
+
Interf saves every scored run under `interf/<work>/.interf/tests/`. You can inspect what changed and why a later build did better.
|
|
129
139
|
|
|
130
140
|
## How the Pieces Fit
|
|
131
141
|
|
|
132
|
-
|
|
133
|
-
- A workflow package bundles a compilation workflow.
|
|
134
|
-
- `workflow.json` defines the method.
|
|
135
|
-
- `workflow.schema.json` defines the output contract, or context interface, the compiler must build.
|
|
136
|
-
- `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.
|
|
137
|
-
- The portable context is the local folder built for your agents. Technically, that folder is the compiled context.
|
|
142
|
+
`interf/interf.json` names the agent work and selects the workflow package. Interf runs it and writes the portable context as a local folder next to your source files.
|
|
138
143
|
|
|
139
|
-
## interf.json
|
|
144
|
+
## interf/interf.json
|
|
140
145
|
|
|
141
|
-
`interf.json` is the main config file
|
|
146
|
+
`interf/interf.json` is the main config file for the project. It lives under `interf/` with workflow packages and portable contexts, so the project root stays clean. Each entry describes one agent work setup: the source path, the saved questions, the workflow package that prepares the portable context, and optional defaults.
|
|
142
147
|
|
|
143
148
|
```text
|
|
144
149
|
{
|
|
@@ -156,11 +161,11 @@ Interf saves every scored run under `interf/tests/<work>/`. You can inspect what
|
|
|
156
161
|
}
|
|
157
162
|
```
|
|
158
163
|
|
|
159
|
-
The `workflow` field
|
|
164
|
+
The `workflow` field selects the workflow package for that job. It points to a folder id under `interf/workflows/`. Set it to `interf-default` (the built-in default) or to a workflow package you have authored. A different workflow package is a different method and a different output. Same files, different portable context.
|
|
160
165
|
|
|
161
166
|
## Questions
|
|
162
167
|
|
|
163
|
-
In the flow, they look like plain questions. In `interf.json`, they live under `checks[]`.
|
|
168
|
+
In the setup flow, they look like plain questions. In `interf/interf.json`, they live under `checks[]`.
|
|
164
169
|
|
|
165
170
|
They should be small, verifiable facts you already know from the files:
|
|
166
171
|
|
|
@@ -198,24 +203,24 @@ A maintained public test example in this repo stores them like this:
|
|
|
198
203
|
|
|
199
204
|
## What Interf Is Not
|
|
200
205
|
|
|
201
|
-
- Not a second brain or memory product. One local folder per
|
|
206
|
+
- Not a second brain or memory product. One local folder per agent job; nothing global.
|
|
202
207
|
- Not a vector store or RAG server. The portable context is plain files.
|
|
203
|
-
- Not a hosted
|
|
204
|
-
- Not an agent harness. Interf prepares the
|
|
205
|
-
- Not a public leaderboard. Every score comes from your files, your questions, and your agent.
|
|
208
|
+
- Not a hosted data platform. Interf runs locally and `interf/` is yours.
|
|
209
|
+
- Not an agent harness. Interf prepares the data; your existing agent reads the portable context.
|
|
210
|
+
- Not a public leaderboard. Every score comes from your files, your questions, and your agent runs.
|
|
206
211
|
|
|
207
212
|
## Useful Commands
|
|
208
213
|
|
|
209
214
|
- `interf` or `interf init` — open the wizard and save the first setup
|
|
210
|
-
- `interf compile` — build portable context
|
|
215
|
+
- `interf compile` — build portable context agents can use
|
|
211
216
|
- `interf test` — compare source files and portable context on the same questions
|
|
212
217
|
- `interf create workflow` — draft a reusable workflow package
|
|
213
218
|
- `interf doctor --live` — verify the local executor
|
|
214
219
|
|
|
215
220
|
## Docs
|
|
216
221
|
|
|
217
|
-
- [src/packages/README.md](./src/packages/README.md) —
|
|
218
|
-
- [src/packages/compiler/PACKAGE.md](./src/packages/compiler/PACKAGE.md) —
|
|
222
|
+
- [src/packages/README.md](./src/packages/README.md) — package boundaries
|
|
223
|
+
- [src/packages/compiler/PACKAGE.md](./src/packages/compiler/PACKAGE.md) — local engine primitives and runtime contract
|
|
219
224
|
- [src/packages/workflow-package/PACKAGE.md](./src/packages/workflow-package/PACKAGE.md) — workflow package model
|
|
220
225
|
- [src/packages/workflow-authoring/PACKAGE.md](./src/packages/workflow-authoring/PACKAGE.md) — workflow authoring and workflow improvement
|
|
221
226
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Interf (Built-in Workflow)
|
|
2
2
|
|
|
3
|
-
Interf's built-in workflow: summarize source-grounded evidence, structure the cross-file layer, then shape the final context
|
|
3
|
+
Interf's built-in workflow: summarize source-grounded evidence, structure the cross-file layer, then shape the final portable context around its task focus and checks.
|
|
4
4
|
|
|
5
5
|
## Purpose
|
|
6
6
|
|
|
7
|
-
- General
|
|
7
|
+
- General portable-context workflow for agent use
|
|
8
8
|
- Compile mixed raw files into evidence-backed summaries, cross-file structure, and a usable entrypoint for agents answering the questions this task depends on.
|
|
9
9
|
|
|
10
10
|
## Zones
|
|
@@ -21,11 +21,11 @@ Interf's built-in workflow: summarize source-grounded evidence, structure the cr
|
|
|
21
21
|
|
|
22
22
|
- `summarize` — Turn source files into per-file summaries. (compiled-file-evidence; reads: raw, runtime; writes: summaries)
|
|
23
23
|
- `structure` — Build the cross-file knowledge structure from the summaries. (compiled-knowledge-structure; reads: summaries, runtime; writes: knowledge-entities, knowledge-claims, knowledge-indexes)
|
|
24
|
-
- `shape` — Shape the final context
|
|
24
|
+
- `shape` — Shape the final portable context around the saved task focus and checks. (compiled-query-shape; reads: raw, summaries, knowledge-entities, knowledge-claims, knowledge-indexes, runtime; writes: knowledge-indexes, home)
|
|
25
25
|
|
|
26
26
|
## Why `home.md` exists here
|
|
27
27
|
|
|
28
|
-
This built-in workflow creates `home.md` as the main agent entrypoint for the context
|
|
28
|
+
This built-in workflow creates `home.md` as the main agent entrypoint for the portable context.
|
|
29
29
|
That is behavior of the `interf` workflow, not a compiler-wide rule.
|
|
30
30
|
|
|
31
31
|
This package is the built-in seed for `interf`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Shape
|
|
2
2
|
|
|
3
|
-
Shape the final context
|
|
3
|
+
Shape the final portable context around the saved task focus and checks.
|
|
4
4
|
|
|
5
5
|
Contract type: `compiled-query-shape`
|
|
6
6
|
|
|
@@ -18,12 +18,12 @@ Contract type: `compiled-query-shape`
|
|
|
18
18
|
- If a mark touches or nearly touches a labeled gridline, anchor the answer at that gridline or the immediately adjacent half-band.
|
|
19
19
|
- Do not widen a chart-derived range across multiple visible bands unless the chart genuinely supports that uncertainty.
|
|
20
20
|
- When you settle on a bounded chart read, keep that same band consistent across `home.md`, focused indexes, and claim/entity notes for that metric and year.
|
|
21
|
-
- Do not copy expected answers into the context
|
|
21
|
+
- Do not copy expected answers into the portable context.
|
|
22
22
|
|
|
23
23
|
## Notes
|
|
24
24
|
|
|
25
|
-
- Use the saved task focus and checks to bias the final context
|
|
26
|
-
- Do not copy expected answers into the final context
|
|
25
|
+
- Use the saved task focus and checks to bias the final portable context toward the job it should be especially good at.
|
|
26
|
+
- Do not copy expected answers into the final portable context just because the checks imply them.
|
|
27
27
|
- Prefer the saved summary evidence and structured notes when they already preserve the bounded chart/table reads plus provenance you need.
|
|
28
28
|
- Reopen `raw/` during shaping only when the compiled layer is missing the needed value, the metric family is ambiguous, or the earlier bounded read is clearly inconsistent.
|
|
29
29
|
- If a saved truth check depends on chart-derived or table-derived values, carry the final bounded reads forward into focused notes with provenance instead of repeatedly recomputing them from raw.
|
|
@@ -8,7 +8,7 @@ The improver edits this local package directly.
|
|
|
8
8
|
Default loop:
|
|
9
9
|
1. Read the loop context first.
|
|
10
10
|
2. Review preserved stage shells, runtime logs, and saved test runs from failed attempts.
|
|
11
|
-
3. Edit only the local workflow package for this context
|
|
11
|
+
3. Edit only the local workflow package for this compiled context to create a better workflow variation for this task.
|
|
12
12
|
4. Keep `workflow.json`, `workflow.schema.json`, and any changed stage docs aligned.
|
|
13
13
|
|
|
14
14
|
Guardrails:
|
|
@@ -25,4 +25,4 @@ Answering rule:
|
|
|
25
25
|
- if multiple compiled notes mention the same chart read, keep the answer consistent with the most focused compiled note rather than synthesizing a new midpoint or shifted band
|
|
26
26
|
- when the compiled layer is insufficient, verify in `raw/` and then answer
|
|
27
27
|
|
|
28
|
-
You can edit this file to bias manual question-answering behavior for this context
|
|
28
|
+
You can edit this file to bias manual question-answering behavior for this portable context.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"task_hint": "Compile mixed raw files into evidence-backed summaries, cross-file structure, and a usable entrypoint for agents answering the questions this task depends on."
|
|
11
11
|
},
|
|
12
12
|
"label": "Interf (Built-in)",
|
|
13
|
-
"hint": "Interf's built-in workflow: summarize source-grounded evidence, structure the cross-file layer, then shape the final context
|
|
13
|
+
"hint": "Interf's built-in workflow: summarize source-grounded evidence, structure the cross-file layer, then shape the final portable context around its task focus and checks.",
|
|
14
14
|
"stages": [
|
|
15
15
|
{
|
|
16
16
|
"id": "summarize",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
{
|
|
83
83
|
"id": "shape",
|
|
84
84
|
"label": "Shape",
|
|
85
|
-
"description": "Shape the final context
|
|
85
|
+
"description": "Shape the final portable context around the saved task focus and checks.",
|
|
86
86
|
"contract_type": "compiled-query-shape",
|
|
87
87
|
"skill_dir": "shape",
|
|
88
88
|
"reads": [
|
|
@@ -135,8 +135,8 @@
|
|
|
135
135
|
"For summary references, prefer explicit links like `[[summaries/<file-stem>]]` or plain code paths. For knowledge notes, prefer the final filename stem under `knowledge/`."
|
|
136
136
|
],
|
|
137
137
|
"shape": [
|
|
138
|
-
"Use the saved task focus and checks to bias the final context
|
|
139
|
-
"Do not copy expected answers into the final context
|
|
138
|
+
"Use the saved task focus and checks to bias the final portable context toward the job it should be especially good at.",
|
|
139
|
+
"Do not copy expected answers into the final portable context just because the checks imply them.",
|
|
140
140
|
"If a saved truth check depends on chart-derived or table-derived values, verify the needed evidence in `raw/` while shaping and write focused notes that preserve bounded values plus provenance.",
|
|
141
141
|
"Prefer better routing, prioritization, and focused navigation over speculative synthesis.",
|
|
142
142
|
"Any wikilinks you add to `home.md` or indexes must resolve to real compiled note basenames or explicit relative paths."
|
|
@@ -219,10 +219,10 @@ function printPostCompileNextStep(options) {
|
|
|
219
219
|
return;
|
|
220
220
|
}
|
|
221
221
|
if (options.testedDuringCompile) {
|
|
222
|
-
console.log(chalk.dim(" Next: inspect the portable context
|
|
222
|
+
console.log(chalk.dim(" Next: inspect the portable context agents will use, or run `interf test` if you also want a source-files-versus-portable-context comparison."));
|
|
223
223
|
return;
|
|
224
224
|
}
|
|
225
|
-
console.log(chalk.dim(" Next: run `interf test` to compare
|
|
225
|
+
console.log(chalk.dim(" Next: run `interf test` to compare source files and portable context."));
|
|
226
226
|
}
|
|
227
227
|
function formatVariationQuestionSummary(summary) {
|
|
228
228
|
return `${summary.passed_questions}/${summary.total_questions}`;
|
|
@@ -260,7 +260,7 @@ export async function runConfiguredCompiledCompile(options) {
|
|
|
260
260
|
else if (loopEnabled) {
|
|
261
261
|
if (maxAttempts > 1) {
|
|
262
262
|
console.log(chalk.dim(` Retry mode: up to ${maxAttempts} compile attempts.`));
|
|
263
|
-
console.log(chalk.dim(" Interf will rerun the same workflow variation, check the portable context
|
|
263
|
+
console.log(chalk.dim(" Interf will rerun the same workflow variation, check the portable context agents can use, and stop early if it passes."));
|
|
264
264
|
}
|
|
265
265
|
else {
|
|
266
266
|
console.log(chalk.dim(" Compile mode: 1 attempt per workflow variation."));
|
|
@@ -421,10 +421,10 @@ export async function runConfiguredCompiledCompile(options) {
|
|
|
421
421
|
printWorkflowVariationSummary(previousVariations);
|
|
422
422
|
printCompiledLocalWorkflowOwnership(options.compiledPath, bestVariation);
|
|
423
423
|
if (maxLoops != null) {
|
|
424
|
-
console.log(chalk.red(`
|
|
424
|
+
console.log(chalk.red(` Portable context did not pass after ${maxAttempts} attempt${maxAttempts === 1 ? "" : "s"} per variation and ${maxLoops} workflow-improvement loop${maxLoops === 1 ? "" : "s"}.`));
|
|
425
425
|
}
|
|
426
426
|
else {
|
|
427
|
-
console.log(chalk.red(`
|
|
427
|
+
console.log(chalk.red(` Portable context did not pass within ${maxAttempts} attempt${maxAttempts === 1 ? "" : "s"}.`));
|
|
428
428
|
}
|
|
429
429
|
if (bestOutcome) {
|
|
430
430
|
console.log(chalk.dim(` Best attempt test pass rate: ${questionPassRate(bestOutcome)}%.`));
|
|
@@ -11,7 +11,7 @@ import { runConfiguredCompiledCompile } from "./compile-controller.js";
|
|
|
11
11
|
export { runConfiguredCompiledCompile } from "./compile-controller.js";
|
|
12
12
|
export const compileCommand = {
|
|
13
13
|
command: "compile",
|
|
14
|
-
describe: "Build portable context
|
|
14
|
+
describe: "Build portable context agents can use and optionally run retry or self-improving compile loops",
|
|
15
15
|
builder: (yargs) => addExecutionProfileOptions(yargs).option("max-attempts", {
|
|
16
16
|
type: "number",
|
|
17
17
|
describe: "Retry compile and test the same workflow until the dataset passes or reaches this total attempt limit",
|
|
@@ -48,6 +48,12 @@ export declare function chooseCompiledWorkflow(sourcePath: string, options?: {
|
|
|
48
48
|
currentWorkflowId?: string;
|
|
49
49
|
message?: string;
|
|
50
50
|
}): Promise<string | symbol>;
|
|
51
|
+
export declare function chooseOrCreateCompiledWorkflowForDataset(sourcePath: string, datasetConfig: SourceDatasetConfig, options?: {
|
|
52
|
+
currentWorkflowId?: string;
|
|
53
|
+
executionProfile?: WorkflowExecutionProfile;
|
|
54
|
+
resolveExecutor?: typeof resolveOrConfigureLocalExecutor;
|
|
55
|
+
runDraft?: typeof runWorkflowAuthoringDraft;
|
|
56
|
+
}, prompts?: WorkflowWizardPrompts): Promise<string | symbol | null>;
|
|
51
57
|
export declare function createWorkflowWizard(options?: {
|
|
52
58
|
intro?: boolean;
|
|
53
59
|
sourcePath?: string;
|
|
@@ -4,7 +4,7 @@ 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
6
|
import { rmSync } from "node:fs";
|
|
7
|
-
import { isWorkflowId, loadWorkflowDefinitionFromDir, } from "../../packages/workflow-package/local-workflows.js";
|
|
7
|
+
import { isWorkflowId, loadWorkflowDefinitionFromDir, seedLocalDefaultWorkflow, } from "../../packages/workflow-package/local-workflows.js";
|
|
8
8
|
import { resolveOrConfigureLocalExecutor } from "./executor-flow.js";
|
|
9
9
|
import { runWorkflowAuthoringDraft } from "../../packages/workflow-authoring/workflow-authoring.js";
|
|
10
10
|
import { listSourceDatasetConfigs, loadSourceFolderConfig, resolveSourceDatasetPath, } from "../../packages/project-model/source-config.js";
|
|
@@ -111,6 +111,58 @@ export async function chooseCompiledWorkflow(sourcePath, options = {}) {
|
|
|
111
111
|
options: orderedOptions,
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
|
+
export async function chooseOrCreateCompiledWorkflowForDataset(sourcePath, datasetConfig, options = {}, prompts = clackWorkflowPrompts) {
|
|
115
|
+
seedLocalDefaultWorkflow({ sourcePath });
|
|
116
|
+
const currentWorkflowId = options.currentWorkflowId ?? datasetConfig.workflow ?? "interf-default";
|
|
117
|
+
const workflowOptions = buildCompiledWorkflowOptions(sourcePath)
|
|
118
|
+
.filter((workflow) => workflow.value !== "interf");
|
|
119
|
+
const currentWorkflow = workflowOptions.find((workflow) => workflow.value === currentWorkflowId) ??
|
|
120
|
+
workflowOptions.find((workflow) => workflow.value === "interf-default") ??
|
|
121
|
+
workflowOptions[0];
|
|
122
|
+
const selected = await prompts.select({
|
|
123
|
+
message: "Choose the file-processing workflow",
|
|
124
|
+
options: [
|
|
125
|
+
...(currentWorkflow
|
|
126
|
+
? [{
|
|
127
|
+
value: "__current__",
|
|
128
|
+
label: `Use ${currentWorkflow.label} (Recommended)`,
|
|
129
|
+
hint: currentWorkflow.hint,
|
|
130
|
+
}]
|
|
131
|
+
: []),
|
|
132
|
+
{
|
|
133
|
+
value: "__create__",
|
|
134
|
+
label: "Create a workflow for this setup",
|
|
135
|
+
hint: "Draft a file-processing workflow from this source folder, work description, and questions",
|
|
136
|
+
},
|
|
137
|
+
...workflowOptions
|
|
138
|
+
.filter((workflow) => workflow.value !== currentWorkflow?.value)
|
|
139
|
+
.map((workflow) => ({
|
|
140
|
+
...workflow,
|
|
141
|
+
label: `Use ${workflow.label}`,
|
|
142
|
+
})),
|
|
143
|
+
],
|
|
144
|
+
});
|
|
145
|
+
if (prompts.isCancel(selected))
|
|
146
|
+
return selected;
|
|
147
|
+
if (selected === "__current__") {
|
|
148
|
+
return currentWorkflow?.value ?? currentWorkflowId;
|
|
149
|
+
}
|
|
150
|
+
if (selected === "__create__") {
|
|
151
|
+
const workflowId = await createWorkflowWizard({
|
|
152
|
+
intro: false,
|
|
153
|
+
sourcePath,
|
|
154
|
+
executionProfile: options.executionProfile,
|
|
155
|
+
resolveExecutor: options.resolveExecutor,
|
|
156
|
+
runDraft: options.runDraft,
|
|
157
|
+
datasetContext: {
|
|
158
|
+
config: datasetConfig,
|
|
159
|
+
datasetPath: resolveSourceDatasetPath(sourcePath, datasetConfig),
|
|
160
|
+
},
|
|
161
|
+
}, prompts);
|
|
162
|
+
return workflowId;
|
|
163
|
+
}
|
|
164
|
+
return String(selected);
|
|
165
|
+
}
|
|
114
166
|
export async function createWorkflowWizard(options = {}, prompts = clackWorkflowPrompts) {
|
|
115
167
|
if (options.intro !== false) {
|
|
116
168
|
prompts.intro(chalk.bold("Create a workflow"));
|
|
@@ -150,7 +202,7 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
|
|
|
150
202
|
return creationMode;
|
|
151
203
|
const rawName = await prompts.text({
|
|
152
204
|
message: "New workflow name?",
|
|
153
|
-
placeholder: "
|
|
205
|
+
placeholder: "customer-research",
|
|
154
206
|
validate: (value) => {
|
|
155
207
|
if (value.trim().length === 0)
|
|
156
208
|
return "Name is required";
|
|
@@ -215,8 +267,8 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
|
|
|
215
267
|
matchedDataset = matchedDataset ?? findMatchingDatasetConfig(sourcePath, datasetPath);
|
|
216
268
|
}
|
|
217
269
|
const taskPrompt = await prompts.text({
|
|
218
|
-
message: "
|
|
219
|
-
placeholder: "
|
|
270
|
+
message: "What should this file-processing workflow produce and prove?",
|
|
271
|
+
placeholder: "Data: research interviews. Output: per-file summaries, themes, entities, claims, and source links. Proof: every file processed, evidence linked to sources, required outputs created.",
|
|
220
272
|
validate: (value) => (value.trim().length === 0 ? "A description is required" : undefined),
|
|
221
273
|
});
|
|
222
274
|
if (prompts.isCancel(taskPrompt))
|
|
@@ -266,7 +318,7 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
|
|
|
266
318
|
const confirmChoice = await prompts.select({
|
|
267
319
|
message: "Save this workflow?",
|
|
268
320
|
options: [
|
|
269
|
-
{ value: "save", label: "Save", hint: "Keep the draft as your new
|
|
321
|
+
{ value: "save", label: "Save", hint: "Keep the draft as your new workflow package" },
|
|
270
322
|
{ value: "cancel", label: "Discard", hint: "Remove the draft folder and exit without saving" },
|
|
271
323
|
],
|
|
272
324
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import * as p from "@clack/prompts";
|
|
3
|
-
import { detectInterf, resolveSourceControlPath, } from "../../packages/project-model/interf.js";
|
|
3
|
+
import { detectInterf, ensurePortableContextScaffold, resolveSourceControlPath, } from "../../packages/project-model/interf.js";
|
|
4
4
|
import { addExecutionProfileOptions, executionProfileFromArgv, } from "../../packages/agents/lib/execution-profile.js";
|
|
5
|
-
import { listSourceDatasetConfigs, loadSourceFolderConfig, syncCompiledInterfConfigFromSourceDatasetConfig, upsertSourceDatasetConfig, } from "../../packages/project-model/source-config.js";
|
|
6
|
-
import { createWorkflowWizard, } from "./create-workflow-wizard.js";
|
|
5
|
+
import { SOURCE_FOLDER_CONFIG_PATH, listSourceDatasetConfigs, loadSourceFolderConfig, syncCompiledInterfConfigFromSourceDatasetConfig, upsertSourceDatasetConfig, } from "../../packages/project-model/source-config.js";
|
|
6
|
+
import { chooseOrCreateCompiledWorkflowForDataset, createWorkflowWizard, } from "./create-workflow-wizard.js";
|
|
7
7
|
import { findBuiltCompiledPath, } from "./compiled-flow.js";
|
|
8
8
|
import { DEFAULT_COMPILED_NAME, promptSingleCompiledConfig, } from "./source-config-wizard.js";
|
|
9
9
|
function normalizeCreateTarget(value) {
|
|
@@ -81,6 +81,9 @@ async function maybeAssignWorkflowToDataset(sourcePath, workflowId) {
|
|
|
81
81
|
if (builtCompiledPath) {
|
|
82
82
|
syncCompiledInterfConfigFromSourceDatasetConfig(builtCompiledPath, nextConfig);
|
|
83
83
|
}
|
|
84
|
+
else {
|
|
85
|
+
ensurePortableContextScaffold(sourcePath, nextConfig.name, nextConfig.workflow ?? "interf-default");
|
|
86
|
+
}
|
|
84
87
|
p.log.info(`Assigned workflow "${workflowId}" to dataset "${targetDataset.name}".`);
|
|
85
88
|
if (builtCompiledPath) {
|
|
86
89
|
p.log.info("The active local workflow copy for that portable context lives under `.interf/workflow/`.");
|
|
@@ -137,9 +140,9 @@ export async function createCompiledWizard(options = {}) {
|
|
|
137
140
|
}
|
|
138
141
|
const savedDatasets = listSourceDatasetConfigs(loadSourceFolderConfig(cwd));
|
|
139
142
|
if (savedDatasets.length > 0) {
|
|
140
|
-
p.log.info(`This project already has ${savedDatasets.length} saved setup${savedDatasets.length === 1 ? "" : "s"} in
|
|
143
|
+
p.log.info(`This project already has ${savedDatasets.length} saved setup${savedDatasets.length === 1 ? "" : "s"} in ${SOURCE_FOLDER_CONFIG_PATH}. Add another only when you need a separate folder, focus, or question set.`);
|
|
141
144
|
}
|
|
142
|
-
p.log.info("Interf works one source-folder setup at a time. Start with the work, the relevant files, and a few questions, then build portable context
|
|
145
|
+
p.log.info("Interf works one source-folder setup at a time. Start with the work, the relevant files, and a few questions, then build portable context when you need evidence that the data is ready for agents.");
|
|
143
146
|
const existingConfig = loadSourceFolderConfig(cwd);
|
|
144
147
|
const draft = await promptSingleCompiledConfig({
|
|
145
148
|
projectPath: cwd,
|
|
@@ -148,17 +151,24 @@ export async function createCompiledWizard(options = {}) {
|
|
|
148
151
|
});
|
|
149
152
|
if (!draft)
|
|
150
153
|
return;
|
|
151
|
-
const configToSave = {
|
|
152
|
-
...draft,
|
|
153
|
-
workflow: "interf",
|
|
154
|
-
};
|
|
155
154
|
const existingNames = new Set(listSourceDatasetConfigs(existingConfig).map((dataset) => dataset.name));
|
|
156
|
-
if (existingNames.has(
|
|
155
|
+
if (existingNames.has(draft.name)) {
|
|
157
156
|
process.exitCode = 1;
|
|
158
|
-
p.log.error(`Setup "${
|
|
157
|
+
p.log.error(`Setup "${draft.name}" already exists. Use \`interf\` or \`interf init\` to edit it.`);
|
|
159
158
|
return;
|
|
160
159
|
}
|
|
160
|
+
const workflowChoice = await chooseOrCreateCompiledWorkflowForDataset(cwd, draft, {
|
|
161
|
+
currentWorkflowId: "interf-default",
|
|
162
|
+
executionProfile: options.executionProfile,
|
|
163
|
+
});
|
|
164
|
+
if (!workflowChoice || p.isCancel(workflowChoice))
|
|
165
|
+
return;
|
|
166
|
+
const configToSave = {
|
|
167
|
+
...draft,
|
|
168
|
+
workflow: String(workflowChoice),
|
|
169
|
+
};
|
|
161
170
|
upsertSourceDatasetConfig(cwd, configToSave);
|
|
171
|
+
ensurePortableContextScaffold(cwd, configToSave.name, configToSave.workflow);
|
|
162
172
|
p.outro(configToSave.checks.length > 0
|
|
163
173
|
? "Saved dataset.\nNext:\n interf test\n interf compile"
|
|
164
174
|
: "Saved dataset.\nNext:\n interf or interf init");
|
|
@@ -5,7 +5,8 @@ function printStaticLanding() {
|
|
|
5
5
|
const config = userConfig.loadUserConfig();
|
|
6
6
|
console.log();
|
|
7
7
|
console.log(chalk.bold(" Interf"));
|
|
8
|
-
console.log(chalk.dim(" Prepare
|
|
8
|
+
console.log(chalk.dim(" Prepare data for agent work."));
|
|
9
|
+
console.log(chalk.dim(" Run locally, process files, show evidence that your data is ready, and write verifiable outputs as portable context for agents."));
|
|
9
10
|
console.log();
|
|
10
11
|
if (config) {
|
|
11
12
|
console.log(chalk.dim(` Agent: ${config.agent}`));
|