@interf/compiler 0.6.3 → 0.6.5
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 +92 -94
- package/dist/cli/commands/check-draft.js +4 -4
- package/dist/cli/commands/compile-controller.js +23 -23
- package/dist/cli/commands/compile.js +2 -2
- package/dist/cli/commands/compiled-flow.js +4 -4
- package/dist/cli/commands/create-workflow-wizard.js +8 -8
- package/dist/cli/commands/create.js +5 -5
- package/dist/cli/commands/default.js +1 -1
- package/dist/cli/commands/init.js +44 -44
- package/dist/cli/commands/list.js +2 -2
- package/dist/cli/commands/reset.js +1 -1
- package/dist/cli/commands/source-config-wizard.d.ts +1 -1
- package/dist/cli/commands/source-config-wizard.js +40 -40
- package/dist/cli/commands/status.js +5 -5
- package/dist/cli/commands/test-flow.js +26 -26
- package/dist/cli/commands/test.js +12 -12
- package/dist/lib/chart-guidance.d.ts +1 -1
- package/dist/lib/chart-guidance.js +1 -8
- package/dist/lib/discovery.d.ts +1 -7
- package/dist/lib/discovery.js +1 -84
- package/dist/lib/filesystem.d.ts +1 -2
- package/dist/lib/filesystem.js +1 -55
- package/dist/lib/logger.d.ts +1 -3
- package/dist/lib/logger.js +1 -10
- package/dist/lib/parse.d.ts +1 -8
- package/dist/lib/parse.js +1 -145
- package/dist/lib/util.d.ts +1 -4
- package/dist/lib/util.js +1 -25
- package/dist/packages/agents/index.d.ts +1 -0
- package/dist/packages/agents/index.js +1 -0
- package/dist/packages/agents/lib/chart-guidance.d.ts +1 -0
- package/dist/packages/agents/lib/chart-guidance.js +8 -0
- package/dist/packages/agents/lib/compiled-bootstrap.d.ts +3 -0
- package/dist/packages/agents/lib/compiled-bootstrap.js +18 -0
- package/dist/packages/agents/lib/executors.d.ts +2 -2
- package/dist/packages/agents/lib/shells.d.ts +3 -1
- package/dist/packages/agents/lib/shells.js +22 -20
- package/dist/packages/agents/lib/user-config.js +1 -1
- package/dist/packages/compiler/compiled-compile.d.ts +4 -48
- package/dist/packages/compiler/compiled-compile.js +4 -256
- package/dist/packages/compiler/compiled-paths.d.ts +40 -0
- package/dist/packages/compiler/compiled-paths.js +106 -0
- package/dist/packages/compiler/compiled-pipeline.d.ts +39 -0
- package/dist/packages/compiler/compiled-pipeline.js +134 -0
- package/dist/packages/compiler/compiled-schema.js +2 -2
- package/dist/packages/compiler/compiled-stage-plan.d.ts +15 -0
- package/dist/packages/compiler/compiled-stage-plan.js +79 -0
- package/dist/packages/compiler/compiled-stage-runner.d.ts +10 -0
- package/dist/packages/compiler/compiled-stage-runner.js +46 -0
- package/dist/packages/compiler/compiled-target.d.ts +11 -0
- package/dist/packages/compiler/compiled-target.js +16 -0
- package/dist/packages/compiler/discovery.d.ts +7 -0
- package/dist/packages/compiler/discovery.js +80 -0
- package/dist/packages/compiler/lib/schema.js +2 -0
- package/dist/packages/compiler/raw-snapshot.d.ts +49 -0
- package/dist/packages/compiler/raw-snapshot.js +102 -0
- package/dist/packages/compiler/reset.d.ts +2 -0
- package/dist/packages/compiler/reset.js +72 -0
- package/dist/packages/compiler/runtime-acceptance.js +3 -3
- package/dist/packages/compiler/runtime-contracts.js +1 -1
- package/dist/packages/compiler/runtime-paths.js +1 -1
- package/dist/packages/compiler/runtime-reconcile.js +3 -3
- package/dist/packages/compiler/runtime-runs.js +2 -2
- package/dist/packages/compiler/state-health.js +3 -3
- package/dist/packages/compiler/state-io.js +3 -3
- package/dist/packages/compiler/state-paths.js +1 -1
- package/dist/packages/compiler/state-view.js +2 -2
- package/dist/packages/compiler/validate-compiled.js +3 -3
- package/dist/packages/compiler/validate.js +4 -4
- package/dist/packages/project-model/compiled-paths.d.ts +1 -40
- package/dist/packages/project-model/compiled-paths.js +1 -106
- package/dist/packages/project-model/compiled-raw.d.ts +1 -49
- package/dist/packages/project-model/compiled-raw.js +1 -102
- package/dist/packages/project-model/compiled-reset.d.ts +1 -2
- package/dist/packages/project-model/compiled-reset.js +1 -72
- package/dist/packages/project-model/interf-bootstrap.d.ts +1 -3
- package/dist/packages/project-model/interf-bootstrap.js +1 -18
- package/dist/packages/project-model/interf-detect.js +4 -4
- package/dist/packages/project-model/interf-scaffold.js +7 -7
- package/dist/packages/project-model/source-config.js +6 -5
- package/dist/packages/shared/file-types.d.ts +1 -0
- package/dist/packages/shared/file-types.js +4 -0
- package/dist/packages/shared/filesystem.d.ts +2 -0
- package/dist/packages/shared/filesystem.js +55 -0
- package/dist/packages/shared/index.d.ts +7 -0
- package/dist/packages/shared/index.js +7 -0
- package/dist/packages/shared/logger.d.ts +3 -0
- package/dist/packages/shared/logger.js +10 -0
- package/dist/packages/shared/naming.d.ts +1 -0
- package/dist/packages/shared/naming.js +8 -0
- package/dist/packages/shared/parse.d.ts +8 -0
- package/dist/packages/shared/parse.js +145 -0
- package/dist/packages/shared/path-guards.d.ts +2 -0
- package/dist/packages/shared/path-guards.js +14 -0
- package/dist/packages/shared/util.d.ts +3 -0
- package/dist/packages/shared/util.js +3 -0
- package/dist/packages/testing/test-execution.js +3 -3
- package/dist/packages/testing/test-paths.js +1 -1
- package/dist/packages/testing/test-sandbox.js +3 -3
- package/dist/packages/testing/test-specs.js +1 -1
- package/dist/packages/workflow-authoring/workflow-authoring.js +5 -4
- package/dist/packages/workflow-authoring/workflow-improvement.js +6 -5
- package/dist/packages/workflow-package/builtin-compiled-workflow.js +1 -1
- package/dist/packages/workflow-package/context-interface.d.ts +96 -0
- package/dist/packages/workflow-package/context-interface.js +146 -0
- package/dist/packages/workflow-package/index.d.ts +2 -0
- package/dist/packages/workflow-package/index.js +2 -0
- package/dist/packages/workflow-package/interf-workflow-package.js +75 -28
- package/dist/packages/workflow-package/local-workflows.d.ts +5 -2
- package/dist/packages/workflow-package/local-workflows.js +15 -13
- package/dist/packages/workflow-package/workflow-definitions.d.ts +11 -7
- package/dist/packages/workflow-package/workflow-definitions.js +10 -3
- package/dist/packages/workflow-package/workflow-helpers.js +4 -4
- package/dist/packages/workflow-package/workflow-review-paths.js +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,79 +1,78 @@
|
|
|
1
1
|
# Interf
|
|
2
2
|
|
|
3
|
-
Interf prepares
|
|
3
|
+
Interf prepares context for your agents.
|
|
4
4
|
|
|
5
|
-
Start with the files
|
|
5
|
+
Start with the files for the work you want to do. Tell Interf what you need, let it suggest a few questions to check accuracy, and build portable context for your agents when the files alone are not enough.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Interf Compiler builds portable context in a local folder inside your project.
|
|
8
|
+
Your agents can use it directly. Interf can check it on those same questions.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
Your source files stay the source of truth. Interf builds on them; it does not replace them.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
cd ~/my-project
|
|
13
|
-
interf
|
|
14
|
-
interf test
|
|
15
|
-
interf compile
|
|
16
|
-
interf test
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
The context folder Interf builds is rooted at:
|
|
12
|
+
For the built-in `interf` workflow, a portable context can include:
|
|
20
13
|
|
|
21
14
|
```text
|
|
22
15
|
interf/<dataset>/
|
|
23
|
-
AGENTS.md
|
|
24
|
-
CLAUDE.md
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
interf.json
|
|
29
|
-
workflow/
|
|
30
|
-
runtime/
|
|
31
|
-
tests/
|
|
16
|
+
AGENTS.md # how your agent should use this folder
|
|
17
|
+
CLAUDE.md # same guidance for Claude Code
|
|
18
|
+
home.md # top-level map for the work
|
|
19
|
+
summaries/ # file-by-file summaries
|
|
20
|
+
knowledge/ # linked notes built from those files
|
|
32
21
|
```
|
|
33
22
|
|
|
34
|
-
|
|
23
|
+
That is an example, not a fixed ABI. Different workflows can build different folders. The simple part is that your agent gets one local folder to start from.
|
|
24
|
+
|
|
25
|
+
This repo includes a small PDF example with questions like:
|
|
26
|
+
|
|
27
|
+
- `What were Bristol's annual take-up values in 2018 and 2016?`
|
|
28
|
+
- `What were Bristol's availability values in 2018 and 2016?`
|
|
29
|
+
|
|
30
|
+
On those same questions, a recent run in this repo produced:
|
|
35
31
|
|
|
36
32
|
<!-- PUBLIC_BENCHMARK_TABLE:START -->
|
|
37
|
-
| Agent |
|
|
33
|
+
| Agent | Source files | Portable context |
|
|
38
34
|
| --- | --- | --- |
|
|
39
35
|
| Codex (GPT-5.4, xhigh) | `2/2` | `2/2` |
|
|
40
36
|
| Claude Code (Claude Opus 4.6, max) | `0/2` | `2/2` |
|
|
41
37
|
<!-- PUBLIC_BENCHMARK_TABLE:END -->
|
|
42
38
|
|
|
43
|
-
|
|
39
|
+
That means:
|
|
44
40
|
|
|
45
|
-
-
|
|
46
|
-
-
|
|
41
|
+
- Codex already passed on the source files.
|
|
42
|
+
- Claude Code needed the portable context to pass.
|
|
47
43
|
|
|
48
|
-
Same
|
|
44
|
+
Same work. Same questions. Same local setup.
|
|
49
45
|
|
|
50
46
|
## How It Works
|
|
51
47
|
|
|
52
|
-
1.
|
|
53
|
-
2.
|
|
54
|
-
3.
|
|
55
|
-
4.
|
|
48
|
+
1. Pick the files for the work.
|
|
49
|
+
2. Tell Interf what you need from them.
|
|
50
|
+
3. Review or edit the questions.
|
|
51
|
+
4. Build the portable context for your agents.
|
|
52
|
+
5. Run `interf test` on the same questions.
|
|
56
53
|
|
|
57
|
-
|
|
54
|
+
Check the source files first if you want the baseline. If the files already pass, keep them. If the portable context does better, use it.
|
|
58
55
|
|
|
59
56
|
## Why It Exists
|
|
60
57
|
|
|
61
|
-
|
|
58
|
+
Raw files are often not enough.
|
|
59
|
+
|
|
60
|
+
Local agents can open reports, decks, transcripts, exports, PDFs, notes, and mixed folders. They can still miss the structure the work needs.
|
|
62
61
|
|
|
63
|
-
Interf
|
|
62
|
+
Interf builds a local folder for that work and checks whether it helped.
|
|
64
63
|
|
|
65
|
-
Interf
|
|
64
|
+
Interf is built around a few simple rules:
|
|
66
65
|
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
66
|
+
- Start from the files you already have.
|
|
67
|
+
- Check source files and portable context on the same questions.
|
|
68
|
+
- Keep the result in a local folder you can inspect, diff, review, and version.
|
|
69
|
+
- Keep source files as the source of truth.
|
|
70
|
+
- Use the portable context manually from Claude Code, Codex, or another local agent. Automated Interf runs currently support Claude Code and Codex.
|
|
71
|
+
- If the first pass is not enough, let Interf retry the same workflow or improve the workflow itself.
|
|
73
72
|
|
|
74
73
|
## What You Get
|
|
75
74
|
|
|
76
|
-
A project
|
|
75
|
+
A small project can stay simple:
|
|
77
76
|
|
|
78
77
|
```text
|
|
79
78
|
your-project/
|
|
@@ -88,7 +87,7 @@ your-project/
|
|
|
88
87
|
<dataset>/
|
|
89
88
|
```
|
|
90
89
|
|
|
91
|
-
|
|
90
|
+
After Interf runs, point your agents at `interf/<dataset>/` first. Go back to the source files whenever you need to verify something.
|
|
92
91
|
|
|
93
92
|
## Quick Start
|
|
94
93
|
|
|
@@ -103,17 +102,21 @@ Install:
|
|
|
103
102
|
npm install -g @interf/compiler
|
|
104
103
|
```
|
|
105
104
|
|
|
106
|
-
|
|
105
|
+
Then run Interf in a project folder that already contains the files for the work:
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
```bash
|
|
108
|
+
interf
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The first run opens the dataset wizard for that folder. It can:
|
|
109
112
|
|
|
110
113
|
- draft `interf.json`
|
|
111
|
-
- let you choose the source folder for the
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
- run a files
|
|
115
|
-
- build the context
|
|
116
|
-
-
|
|
114
|
+
- let you choose the source folder for the work
|
|
115
|
+
- ask what work you need help with
|
|
116
|
+
- recommend questions to check accuracy, or let you add them manually
|
|
117
|
+
- run a source-files baseline so you can see what already works
|
|
118
|
+
- build the portable context your agents will use for that work
|
|
119
|
+
- check that portable context on the same questions
|
|
117
120
|
|
|
118
121
|
If Interf cannot find your local executor setup, run:
|
|
119
122
|
|
|
@@ -121,19 +124,21 @@ If Interf cannot find your local executor setup, run:
|
|
|
121
124
|
interf doctor --live
|
|
122
125
|
```
|
|
123
126
|
|
|
124
|
-
##
|
|
127
|
+
## Questions
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
Interf uses simple questions to check whether the portable context is good enough for your agents on this work.
|
|
127
130
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
Good first checks are small and practical:
|
|
131
|
+
Good first questions are small and easy to verify from the files:
|
|
131
132
|
|
|
132
133
|
- one exact number from a chart, table, or filing
|
|
133
134
|
- one short statement that should be true or false
|
|
134
135
|
- one simple comparison across years, files, or sections
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
Interf can recommend a starting set from the files and the work description. You can confirm, edit, or replace them.
|
|
138
|
+
|
|
139
|
+
Each saved question includes the expected answer. In `interf.json`, those definitions live under the technical field `checks[]`.
|
|
140
|
+
|
|
141
|
+
A maintained public test example in this repo stores them like this:
|
|
137
142
|
|
|
138
143
|
<!-- PUBLIC_TEST_CHECKS:START -->
|
|
139
144
|
```jsonc
|
|
@@ -161,33 +166,39 @@ A maintained public test run in this repo uses checks like this:
|
|
|
161
166
|
|
|
162
167
|
## What `interf test` Proves
|
|
163
168
|
|
|
164
|
-
`interf test` compares files
|
|
169
|
+
`interf test` compares the source files and the portable context your agents would use on the same questions.
|
|
165
170
|
|
|
166
|
-
That comparison is the
|
|
171
|
+
That comparison is the proof step:
|
|
167
172
|
|
|
168
|
-
- same
|
|
169
|
-
- same
|
|
173
|
+
- same work
|
|
174
|
+
- same questions
|
|
170
175
|
- same local agent setup
|
|
171
|
-
-
|
|
172
|
-
-
|
|
176
|
+
- source files on one side
|
|
177
|
+
- portable context your agents use on the other
|
|
178
|
+
|
|
179
|
+
If the portable context does not help, keep the source files.
|
|
173
180
|
|
|
174
181
|
Use `interf test` on your own files instead of trusting a frozen benchmark snapshot in the docs.
|
|
175
182
|
|
|
176
|
-
Interf saves the latest comparison plus
|
|
183
|
+
Interf saves the latest comparison plus the underlying source-files and portable-context runs under `interf/tests/` in the same project.
|
|
177
184
|
|
|
178
185
|
## The Core Loop
|
|
179
186
|
|
|
180
|
-
1. Save a few
|
|
181
|
-
2.
|
|
182
|
-
3. Run `interf compile` to
|
|
183
|
-
4. Run `interf test`
|
|
184
|
-
5. If loops are enabled, let Interf retry the same workflow variation or
|
|
187
|
+
1. Save a few questions for the work in `interf.json`.
|
|
188
|
+
2. Check the source files first if you want the baseline.
|
|
189
|
+
3. Run `interf compile` to build the portable context your agents can use.
|
|
190
|
+
4. Run `interf test` on the same questions.
|
|
191
|
+
5. If loops are enabled, let Interf retry the same workflow variation or improve the workflow and test again.
|
|
185
192
|
|
|
186
|
-
The project root stores the source-folder setup and
|
|
193
|
+
The project root stores the source-folder setup and saved questions. Technically, that portable context is the compiled context Interf reuses for repeat runs.
|
|
187
194
|
|
|
188
195
|
## Workflows
|
|
189
196
|
|
|
190
|
-
A workflow
|
|
197
|
+
A workflow is the method Interf uses to prepare files for a kind of work.
|
|
198
|
+
|
|
199
|
+
A context interface is the folder shape that workflow builds for your agent.
|
|
200
|
+
|
|
201
|
+
Technically, a workflow package defines that context interface: the zones, paths, and stage ownership of the compiled context Interf will build for that work.
|
|
191
202
|
|
|
192
203
|
Interf ships with a built-in `interf` workflow for the common case. If you need a different method, create one locally:
|
|
193
204
|
|
|
@@ -200,47 +211,34 @@ Workflow creation supports two paths:
|
|
|
200
211
|
- draft a workflow from the current project with a local agent
|
|
201
212
|
- copy an existing workflow and edit stage guidance directly
|
|
202
213
|
|
|
203
|
-
After assignment, build the context
|
|
214
|
+
After assignment, build the portable context for your agents with `interf compile` and run `interf test` on the same questions.
|
|
204
215
|
|
|
205
216
|
## Compile Loops
|
|
206
217
|
|
|
207
218
|
`max_attempts` is a retry budget for the same workflow variation.
|
|
208
219
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- same configured dataset
|
|
212
|
-
- same workflow variation
|
|
213
|
-
- same checks
|
|
214
|
-
- same measurement
|
|
215
|
-
|
|
216
|
-
`max_loops` enables self-improving workflow edits in the normal `interf compile` path.
|
|
217
|
-
|
|
218
|
-
In that loop, the thing that changes is the workflow itself.
|
|
220
|
+
`max_loops` lets Interf improve the workflow itself between retry batches.
|
|
219
221
|
|
|
220
|
-
|
|
222
|
+
With `max_attempts`, the dataset, questions, and workflow stay fixed.
|
|
221
223
|
|
|
222
|
-
|
|
223
|
-
- test it on the same checks
|
|
224
|
-
- inspect failed traces, preserved stage shells, and test artifacts
|
|
225
|
-
- edit the workflow
|
|
226
|
-
- build and test the next workflow variation
|
|
224
|
+
With `max_loops`, Interf can edit the workflow, build the next variation, and test it again on the same dataset and questions.
|
|
227
225
|
|
|
228
|
-
Interf preserves workflow
|
|
226
|
+
Interf preserves workflow snapshots, failed stage shells, and test runs from each loop so you can inspect what changed.
|
|
229
227
|
|
|
230
228
|
## Use It With Your Agent
|
|
231
229
|
|
|
232
|
-
If you already work through a local coding agent, it
|
|
230
|
+
If you already work through a local coding agent, hand it the whole flow:
|
|
233
231
|
|
|
234
232
|
Paste something like this into your agent:
|
|
235
233
|
|
|
236
234
|
```text
|
|
237
235
|
Install `@interf/compiler`, run `interf` in this folder, and use the local agent executor.
|
|
238
236
|
|
|
239
|
-
If `interf.json` is missing, draft one dataset entry for this
|
|
237
|
+
If `interf.json` is missing, draft one dataset entry for this work. Ask what I need from the selected files. Recommend a few questions I can verify from those files, and add the expected answers for me to confirm under `checks[]`.
|
|
240
238
|
|
|
241
|
-
|
|
239
|
+
Run a source-files baseline if useful. Build the portable context for my agents for that work. Then run `interf test` on the same questions.
|
|
242
240
|
|
|
243
|
-
|
|
241
|
+
Only recommend the portable context if it passes those questions. If you also ran the source-files baseline, tell me whether it did better than the source files.
|
|
244
242
|
```
|
|
245
243
|
|
|
246
244
|
## More Docs
|
|
@@ -11,12 +11,12 @@ export function buildTruthCheckDraftPrompt(options) {
|
|
|
11
11
|
const normalizedAbout = options.about?.trim();
|
|
12
12
|
const taskLines = normalizedAbout
|
|
13
13
|
? [
|
|
14
|
-
`Primary
|
|
15
|
-
"Draft checks that directly measure whether a local agent can answer the key questions from the data behind that
|
|
14
|
+
`Primary work: ${normalizedAbout}`,
|
|
15
|
+
"Draft checks that directly measure whether a local agent can answer the key questions from the data behind that work.",
|
|
16
16
|
"Prefer checks that would make a human confident the dataset is useful for that exact job.",
|
|
17
17
|
]
|
|
18
18
|
: [
|
|
19
|
-
"No primary
|
|
19
|
+
"No primary work was provided.",
|
|
20
20
|
"Prefer broad, representative checks that reflect the most useful questions a human would verify from this source folder.",
|
|
21
21
|
];
|
|
22
22
|
return [
|
|
@@ -43,7 +43,7 @@ export function buildTruthCheckDraftPrompt(options) {
|
|
|
43
43
|
"- Avoid unstable superlatives unless the source itself clearly states the ranking in one place.",
|
|
44
44
|
"- Avoid checks where the expected answer depends on scanning many pages for a hidden exception or a larger outlier.",
|
|
45
45
|
"- Avoid vague essay questions, open-ended opinions, or anything requiring outside knowledge.",
|
|
46
|
-
"- Avoid duplicate checks that
|
|
46
|
+
"- Avoid duplicate checks that cover the same fact in slightly different words.",
|
|
47
47
|
"",
|
|
48
48
|
"Output rules:",
|
|
49
49
|
"- JSON only in the output file.",
|
|
@@ -3,11 +3,11 @@ import { tmpdir } from "node:os";
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { readInterfConfig } from "../../packages/project-model/interf.js";
|
|
6
|
-
import { clearCompiledRuntimeDerivedArtifacts, resetCompiledGeneratedState, } from "../../packages/
|
|
6
|
+
import { clearCompiledRuntimeDerivedArtifacts, resetCompiledGeneratedState, } from "../../packages/compiler/reset.js";
|
|
7
7
|
import { formatActiveCompiledWorkflowStageStep, resolveRequiredCompiledWorkflowFromConfig, } from "../../packages/workflow-package/workflow-definitions.js";
|
|
8
8
|
import { loadCompiledDatasetConfig, resolveDatasetCompileMaxAttempts, resolveDatasetCompileMaxLoops, } from "../../packages/project-model/source-config.js";
|
|
9
9
|
import { runWorkflowImprovementLoop } from "../../packages/workflow-authoring/workflow-improvement.js";
|
|
10
|
-
import { stageExecutionShellsRoot, workflowPackagePathForCompiled, } from "../../packages/
|
|
10
|
+
import { stageExecutionShellsRoot, workflowPackagePathForCompiled, } from "../../packages/compiler/compiled-paths.js";
|
|
11
11
|
import { readCompiledSchemaFile } from "../../packages/compiler/compiled-schema.js";
|
|
12
12
|
import { initializeCompiledRuntimeState } from "../../packages/compiler/state.js";
|
|
13
13
|
import { compileCompiledWithReporter } from "./compiled-flow.js";
|
|
@@ -78,16 +78,16 @@ async function runWorkflowVariation(options) {
|
|
|
78
78
|
const resetTarget = attempt > 1
|
|
79
79
|
? `attempt ${attempt}/${options.maxAttempts}`
|
|
80
80
|
: options.variationLabel;
|
|
81
|
-
console.log(chalk.dim(` Resetting generated
|
|
81
|
+
console.log(chalk.dim(` Resetting generated portable-context state before ${resetTarget}...`));
|
|
82
82
|
resetCompiledGeneratedState(options.compiledPath, "compile");
|
|
83
83
|
}
|
|
84
84
|
const result = await compileCompiledWithReporter(options.executor, options.compiledPath, {
|
|
85
85
|
heading: options.maxAttempts > 1
|
|
86
|
-
? `Building
|
|
87
|
-
: `Building
|
|
86
|
+
? `Building portable context (${options.variationLabel}, attempt ${attempt}/${options.maxAttempts})...`
|
|
87
|
+
: `Building portable context (${options.variationLabel})...`,
|
|
88
88
|
successMessage: options.maxAttempts > 1
|
|
89
|
-
? `
|
|
90
|
-
: `
|
|
89
|
+
? `Portable context ready for ${options.variationLabel}, attempt ${attempt}.`
|
|
90
|
+
: `Portable context ready for ${options.variationLabel}.`,
|
|
91
91
|
preserveStageShells: options.preserveStageShells,
|
|
92
92
|
});
|
|
93
93
|
if (!result.ok) {
|
|
@@ -123,7 +123,7 @@ async function runWorkflowVariation(options) {
|
|
|
123
123
|
bestOutcome,
|
|
124
124
|
bestSnapshotPath,
|
|
125
125
|
bestAttempt,
|
|
126
|
-
fatalError: "Could not run the saved
|
|
126
|
+
fatalError: "Could not run the saved portable-context comparison after compile.",
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
129
|
console.log();
|
|
@@ -181,11 +181,11 @@ function summarizeWorkflowVariation(options) {
|
|
|
181
181
|
const passedQuestions = options.result.bestOutcome?.result.passedCases ?? 0;
|
|
182
182
|
const totalQuestions = options.result.bestOutcome?.result.totalCases ?? options.defaultTotalQuestions;
|
|
183
183
|
const summary = options.result.passed
|
|
184
|
-
? `Passed ${passedQuestions}/${totalQuestions}
|
|
184
|
+
? `Passed ${passedQuestions}/${totalQuestions} questions.`
|
|
185
185
|
: options.result.bestOutcome
|
|
186
|
-
? `Best result: ${passedQuestions}/${totalQuestions}
|
|
186
|
+
? `Best result: ${passedQuestions}/${totalQuestions} questions passed.`
|
|
187
187
|
: options.result.failedStage
|
|
188
|
-
? `Compile failed at stage ${options.result.failedStage} before any
|
|
188
|
+
? `Compile failed at stage ${options.result.failedStage} before any saved comparison result.`
|
|
189
189
|
: "Workflow variation did not produce a passing result.";
|
|
190
190
|
return {
|
|
191
191
|
variation: options.variation,
|
|
@@ -213,16 +213,16 @@ function printStageShellReviewHint(compiledPath, preserveStageShells, result) {
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
function printPostCompileNextStep(options) {
|
|
216
|
-
console.log(chalk.dim(`
|
|
216
|
+
console.log(chalk.dim(` Portable context: ${options.compiledPath}`));
|
|
217
217
|
if (options.checks === 0) {
|
|
218
|
-
console.log(chalk.dim(" Next: run `interf` to add
|
|
218
|
+
console.log(chalk.dim(" Next: run `interf` to add questions, then `interf test`."));
|
|
219
219
|
return;
|
|
220
220
|
}
|
|
221
221
|
if (options.testedDuringCompile) {
|
|
222
|
-
console.log(chalk.dim(" Next: inspect the
|
|
222
|
+
console.log(chalk.dim(" Next: inspect the portable context your 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 the
|
|
225
|
+
console.log(chalk.dim(" Next: run `interf test` to compare the source files and the portable context your agents would use."));
|
|
226
226
|
}
|
|
227
227
|
function formatVariationQuestionSummary(summary) {
|
|
228
228
|
return `${summary.passed_questions}/${summary.total_questions}`;
|
|
@@ -233,7 +233,7 @@ function printWorkflowVariationSummary(summaries) {
|
|
|
233
233
|
console.log();
|
|
234
234
|
console.log(chalk.bold(" Workflow variation summary"));
|
|
235
235
|
console.log();
|
|
236
|
-
console.log(" | Variation | Kind |
|
|
236
|
+
console.log(" | Variation | Kind | Questions | Result |");
|
|
237
237
|
console.log(" | --- | --- | --- | --- |");
|
|
238
238
|
for (const summary of summaries) {
|
|
239
239
|
console.log(` | ${summary.variation} | ${summary.kind} | \`${formatVariationQuestionSummary(summary)}\` | ${summary.passed ? "pass" : "fail"} |`);
|
|
@@ -245,7 +245,7 @@ function printCompiledLocalWorkflowOwnership(compiledPath, bestVariation) {
|
|
|
245
245
|
console.log();
|
|
246
246
|
console.log(chalk.dim(` Best workflow variation now lives in: ${workflowPackagePathForCompiled(compiledPath)}`));
|
|
247
247
|
console.log(chalk.dim(" The project-level workflow selection was not changed automatically."));
|
|
248
|
-
console.log(chalk.dim(" Recompiling this existing
|
|
248
|
+
console.log(chalk.dim(" Recompiling this existing portable context reuses that local workflow draft."));
|
|
249
249
|
}
|
|
250
250
|
export async function runConfiguredCompiledCompile(options) {
|
|
251
251
|
const preserveStageShells = options.preserveStageShells ?? "on-failure";
|
|
@@ -255,12 +255,12 @@ export async function runConfiguredCompiledCompile(options) {
|
|
|
255
255
|
const loopEnabled = maxAttempts != null;
|
|
256
256
|
const checks = options.compiledConfig?.checks ?? [];
|
|
257
257
|
if (loopEnabled && checks.length === 0) {
|
|
258
|
-
console.log(chalk.yellow(" Retry and self-improving modes need
|
|
258
|
+
console.log(chalk.yellow(" Retry and self-improving modes need saved questions. Building once without those loops."));
|
|
259
259
|
}
|
|
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,
|
|
263
|
+
console.log(chalk.dim(" Interf will rerun the same workflow variation, check the portable context for your agents, and stop early if it passes."));
|
|
264
264
|
}
|
|
265
265
|
else {
|
|
266
266
|
console.log(chalk.dim(" Compile mode: 1 attempt per workflow variation."));
|
|
@@ -414,20 +414,20 @@ export async function runConfiguredCompiledCompile(options) {
|
|
|
414
414
|
if (bestSnapshotPath && bestVariation > 0) {
|
|
415
415
|
restoreCompiledBestState(bestSnapshotPath, options.compiledPath);
|
|
416
416
|
console.log();
|
|
417
|
-
console.log(chalk.dim(` Restored the best-performing
|
|
417
|
+
console.log(chalk.dim(` Restored the best-performing portable context from variation ${bestVariation}, attempt ${bestAttempt}.`));
|
|
418
418
|
}
|
|
419
419
|
process.exitCode = 1;
|
|
420
420
|
console.log();
|
|
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(` Context folder 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(` Context folder did not pass within ${maxAttempts} attempt${maxAttempts === 1 ? "" : "s"}.`));
|
|
428
428
|
}
|
|
429
429
|
if (bestOutcome) {
|
|
430
|
-
console.log(chalk.dim(` Best attempt
|
|
430
|
+
console.log(chalk.dim(` Best attempt test pass rate: ${questionPassRate(bestOutcome)}%.`));
|
|
431
431
|
}
|
|
432
432
|
printStageShellReviewHint(options.compiledPath, preserveStageShells, "failure");
|
|
433
433
|
return false;
|
|
@@ -11,10 +11,10 @@ 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
|
|
14
|
+
describe: "Build portable context for your agents and optionally run retry or self-improving compile loops",
|
|
15
15
|
builder: (yargs) => addExecutionProfileOptions(yargs).option("max-attempts", {
|
|
16
16
|
type: "number",
|
|
17
|
-
describe: "Retry compile
|
|
17
|
+
describe: "Retry compile and test the same workflow until the dataset passes or reaches this total attempt limit",
|
|
18
18
|
}).option("max-loops", {
|
|
19
19
|
type: "number",
|
|
20
20
|
describe: "After retries fail, let Interf edit the workflow and test new workflow variations for this dataset up to this loop limit",
|
|
@@ -11,8 +11,8 @@ function formatSavedDatasetHint(entry) {
|
|
|
11
11
|
if (config.about)
|
|
12
12
|
return `${config.path} · ${config.about} · ${workflowHint}`;
|
|
13
13
|
if (checkCount === 0)
|
|
14
|
-
return `${config.path} · No
|
|
15
|
-
return `${config.path} · ${checkCount}
|
|
14
|
+
return `${config.path} · No questions yet · ${workflowHint}`;
|
|
15
|
+
return `${config.path} · ${checkCount} question${checkCount === 1 ? "" : "s"} · ${workflowHint}`;
|
|
16
16
|
}
|
|
17
17
|
export function listSavedCompiledEntries(sourcePath) {
|
|
18
18
|
const builtEntries = new Map();
|
|
@@ -82,7 +82,7 @@ export function ensureCompiledFromConfig(sourcePath, datasetConfig) {
|
|
|
82
82
|
}
|
|
83
83
|
export async function compileCompiledWithReporter(executor, compiledPath, options = {}) {
|
|
84
84
|
console.log();
|
|
85
|
-
console.log(chalk.bold(` ${options.heading ?? "Building
|
|
85
|
+
console.log(chalk.bold(` ${options.heading ?? "Building portable context..."}`));
|
|
86
86
|
const profileLabel = formatWorkflowExecutionProfile(executor.executionProfile);
|
|
87
87
|
if (profileLabel) {
|
|
88
88
|
console.log(chalk.dim(` Execution profile: ${profileLabel}`));
|
|
@@ -102,6 +102,6 @@ export async function compileCompiledWithReporter(executor, compiledPath, option
|
|
|
102
102
|
return result;
|
|
103
103
|
}
|
|
104
104
|
console.log();
|
|
105
|
-
console.log(chalk.green(` ✓ ${options.successMessage ?? "
|
|
105
|
+
console.log(chalk.green(` ✓ ${options.successMessage ?? "Portable context ready."}`));
|
|
106
106
|
return result;
|
|
107
107
|
}
|
|
@@ -7,7 +7,7 @@ import { isWorkflowId, } from "../../packages/workflow-package/local-workflows.j
|
|
|
7
7
|
import { resolveOrConfigureLocalExecutor } from "./executor-flow.js";
|
|
8
8
|
import { runWorkflowAuthoringDraft } from "../../packages/workflow-authoring/workflow-authoring.js";
|
|
9
9
|
import { listSourceDatasetConfigs, loadSourceFolderConfig, resolveSourceDatasetPath, } from "../../packages/project-model/source-config.js";
|
|
10
|
-
import { slugify } from "../../
|
|
10
|
+
import { slugify } from "../../packages/shared/naming.js";
|
|
11
11
|
import { DEFAULT_DATASET_PATH_PLACEHOLDER, listDatasetFolderChoices, normalizeDatasetPathForConfig, } from "./source-config-wizard.js";
|
|
12
12
|
export const clackWorkflowPrompts = {
|
|
13
13
|
intro: p.intro,
|
|
@@ -31,7 +31,7 @@ function findMatchingDatasetConfig(sourcePath, datasetPath) {
|
|
|
31
31
|
function describeSavedDataset(dataset) {
|
|
32
32
|
return dataset.about
|
|
33
33
|
? `${dataset.path} · ${dataset.about}`
|
|
34
|
-
: `${dataset.path} · ${dataset.checks.length}
|
|
34
|
+
: `${dataset.path} · ${dataset.checks.length} test${dataset.checks.length === 1 ? "" : "s"}`;
|
|
35
35
|
}
|
|
36
36
|
async function promptWorkflowDatasetFolder(sourcePath, prompts) {
|
|
37
37
|
const folderChoices = listDatasetFolderChoices(sourcePath);
|
|
@@ -136,7 +136,7 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
|
|
|
136
136
|
{
|
|
137
137
|
value: "draft",
|
|
138
138
|
label: "Draft a workflow from this source folder (Recommended)",
|
|
139
|
-
hint: "Seed a workflow, build a preview, then let a local agent draft a reusable method for this
|
|
139
|
+
hint: "Seed a workflow, build a preview, then let a local agent draft a reusable method for this kind of work",
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
value: "manual",
|
|
@@ -214,9 +214,9 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
|
|
|
214
214
|
matchedDataset = matchedDataset ?? findMatchingDatasetConfig(sourcePath, datasetPath);
|
|
215
215
|
}
|
|
216
216
|
const taskPrompt = await prompts.text({
|
|
217
|
-
message: "What
|
|
218
|
-
placeholder: "Example: chart reads, board
|
|
219
|
-
validate: (value) => (value.trim().length === 0 ? "
|
|
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),
|
|
220
220
|
});
|
|
221
221
|
if (prompts.isCancel(taskPrompt))
|
|
222
222
|
return taskPrompt;
|
|
@@ -224,7 +224,7 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
|
|
|
224
224
|
prompts.log.info(`Shaping this workflow from setup "${matchedDataset.name}".`);
|
|
225
225
|
}
|
|
226
226
|
if (matchedDataset?.checks.length) {
|
|
227
|
-
prompts.log.info(`Using ${matchedDataset.checks.length}
|
|
227
|
+
prompts.log.info(`Using ${matchedDataset.checks.length} saved question${matchedDataset.checks.length === 1 ? "" : "s"} from setup "${matchedDataset.name}" as authoring context.`);
|
|
228
228
|
}
|
|
229
229
|
const resolveExecutor = options.resolveExecutor ?? resolveOrConfigureLocalExecutor;
|
|
230
230
|
const runDraft = options.runDraft ?? runWorkflowAuthoringDraft;
|
|
@@ -259,7 +259,7 @@ export async function createCompiledWorkflowWizard(sourcePath, prompts = clackWo
|
|
|
259
259
|
}
|
|
260
260
|
process.exitCode = 1;
|
|
261
261
|
(prompts.log.error ?? prompts.log.info)(result.status === "no-change"
|
|
262
|
-
? `${result.summary} Draft mode only succeeds when it produces a
|
|
262
|
+
? `${result.summary} Draft mode only succeeds when it produces a work-specific package change.`
|
|
263
263
|
: result.summary);
|
|
264
264
|
prompts.log.info(`Workflow shell kept at: ${result.shellPath}`);
|
|
265
265
|
return null;
|
|
@@ -61,7 +61,7 @@ async function maybeAssignWorkflowToDataset(sourcePath, workflowId) {
|
|
|
61
61
|
options: datasets.map((dataset) => ({
|
|
62
62
|
value: dataset.name,
|
|
63
63
|
label: dataset.name,
|
|
64
|
-
hint: `${dataset.path} · ${dataset.about ?? `${dataset.checks.length}
|
|
64
|
+
hint: `${dataset.path} · ${dataset.about ?? `${dataset.checks.length} question${dataset.checks.length === 1 ? "" : "s"}`}`,
|
|
65
65
|
})),
|
|
66
66
|
});
|
|
67
67
|
if (p.isCancel(selected))
|
|
@@ -83,7 +83,7 @@ async function maybeAssignWorkflowToDataset(sourcePath, workflowId) {
|
|
|
83
83
|
}
|
|
84
84
|
p.log.info(`Assigned workflow "${workflowId}" to dataset "${targetDataset.name}".`);
|
|
85
85
|
if (builtCompiledPath) {
|
|
86
|
-
p.log.info("The active local copy for that
|
|
86
|
+
p.log.info("The active local workflow copy for that portable context lives under `.interf/workflow/`.");
|
|
87
87
|
}
|
|
88
88
|
p.log.info("Next: run `interf compile`, then `interf test`.");
|
|
89
89
|
}
|
|
@@ -132,14 +132,14 @@ export async function createCompiledWizard(options = {}) {
|
|
|
132
132
|
const detected = detectInterf(cwd);
|
|
133
133
|
if (detected) {
|
|
134
134
|
process.exitCode = 1;
|
|
135
|
-
p.log.error("You are already inside
|
|
135
|
+
p.log.error("You are already inside portable context.");
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
138
138
|
const savedDatasets = listSourceDatasetConfigs(loadSourceFolderConfig(cwd));
|
|
139
139
|
if (savedDatasets.length > 0) {
|
|
140
|
-
p.log.info(`This project already has ${savedDatasets.length} saved setup${savedDatasets.length === 1 ? "" : "s"} in interf.json. Add another only when you need a separate folder, focus, or
|
|
140
|
+
p.log.info(`This project already has ${savedDatasets.length} saved setup${savedDatasets.length === 1 ? "" : "s"} in interf.json. Add another only when you need a separate folder, focus, or question set.`);
|
|
141
141
|
}
|
|
142
|
-
p.log.info("Interf works one source-folder setup at a time. Start with the
|
|
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 for your agents when the files alone are not enough.");
|
|
143
143
|
const existingConfig = loadSourceFolderConfig(cwd);
|
|
144
144
|
const draft = await promptSingleCompiledConfig({
|
|
145
145
|
projectPath: cwd,
|
|
@@ -5,7 +5,7 @@ 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 context for your agents from the files you already have, then run `interf test` and use self-improving loops until more questions pass."));
|
|
9
9
|
console.log();
|
|
10
10
|
if (config) {
|
|
11
11
|
console.log(chalk.dim(` Agent: ${config.agent}`));
|