@interf/compiler 0.16.0 → 0.18.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.
Files changed (133) hide show
  1. package/LICENSE.md +1 -0
  2. package/README.md +10 -7
  3. package/TRADEMARKS.md +4 -4
  4. package/builtin-methods/interf-default/README.md +6 -7
  5. package/builtin-methods/interf-default/method.json +7 -68
  6. package/builtin-methods/interf-default/method.schema.json +52 -50
  7. package/dist/cli/commands/prep.js +58 -2
  8. package/dist/cli/commands/verify.d.ts +2 -0
  9. package/dist/cli/commands/verify.js +17 -8
  10. package/dist/cli/commands/wizard.js +122 -14
  11. package/dist/compiler-ui/404.html +1 -1
  12. package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
  13. package/dist/compiler-ui/__next._full.txt +3 -3
  14. package/dist/compiler-ui/__next._head.txt +1 -1
  15. package/dist/compiler-ui/__next._index.txt +2 -2
  16. package/dist/compiler-ui/__next._tree.txt +2 -2
  17. package/dist/compiler-ui/_next/static/chunks/{13awzu4tooflw.css → 0_c_tvh-cukjz.css} +1 -1
  18. package/dist/compiler-ui/_next/static/chunks/{0jipmpez3_ehh.js → 0f_geuwdesg_c.js} +42 -17
  19. package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
  20. package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
  21. package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
  22. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
  23. package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
  24. package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
  25. package/dist/compiler-ui/_not-found.html +1 -1
  26. package/dist/compiler-ui/_not-found.txt +2 -2
  27. package/dist/compiler-ui/index.html +1 -1
  28. package/dist/compiler-ui/index.txt +3 -3
  29. package/dist/packages/contracts/index.d.ts +2 -2
  30. package/dist/packages/contracts/index.js +1 -1
  31. package/dist/packages/contracts/lib/schema.d.ts +271 -72
  32. package/dist/packages/contracts/lib/schema.js +243 -83
  33. package/dist/packages/engine/action-definitions.js +1 -1
  34. package/dist/packages/engine/agents/lib/shells.d.ts +12 -4
  35. package/dist/packages/engine/agents/lib/shells.js +127 -120
  36. package/dist/packages/engine/cloud-seams.d.ts +115 -0
  37. package/dist/packages/engine/cloud-seams.js +84 -0
  38. package/dist/packages/engine/compile/artifact-counts.d.ts +1 -1
  39. package/dist/packages/engine/compile/artifact-counts.js +3 -3
  40. package/dist/packages/engine/compile/artifact-status.d.ts +41 -0
  41. package/dist/packages/engine/compile/artifact-status.js +166 -0
  42. package/dist/packages/engine/compile/billing-events.d.ts +89 -0
  43. package/dist/packages/engine/compile/billing-events.js +74 -0
  44. package/dist/packages/engine/compile/check-evaluator.d.ts +66 -0
  45. package/dist/packages/engine/compile/check-evaluator.js +298 -0
  46. package/dist/packages/engine/compile/compiled-schema.d.ts +7 -17
  47. package/dist/packages/engine/compile/compiled-schema.js +55 -70
  48. package/dist/packages/engine/compile/compiled-stage-plan.d.ts +1 -0
  49. package/dist/packages/engine/compile/compiled-stage-plan.js +32 -15
  50. package/dist/packages/engine/compile/compiled-stage-runner.js +1 -1
  51. package/dist/packages/engine/compile/index.d.ts +0 -1
  52. package/dist/packages/engine/compile/index.js +0 -1
  53. package/dist/packages/engine/compile/lib/schema.d.ts +111 -92
  54. package/dist/packages/engine/compile/lib/schema.js +35 -39
  55. package/dist/packages/engine/compile/method-primitives.d.ts +2 -2
  56. package/dist/packages/engine/compile/method-primitives.js +1 -1
  57. package/dist/packages/engine/compile/reset.js +4 -4
  58. package/dist/packages/engine/compile/runtime-contracts.js +2 -1
  59. package/dist/packages/engine/compile/runtime-prompt.js +3 -2
  60. package/dist/packages/engine/compile/runtime-reconcile.js +35 -35
  61. package/dist/packages/engine/compile/runtime-runs.js +0 -1
  62. package/dist/packages/engine/compile/runtime-types.d.ts +7 -8
  63. package/dist/packages/engine/compile/runtime.d.ts +1 -2
  64. package/dist/packages/engine/compile/runtime.js +0 -1
  65. package/dist/packages/engine/compile/state-health.js +6 -6
  66. package/dist/packages/engine/compile/state-view.js +7 -6
  67. package/dist/packages/engine/compile/validate-compiled.js +61 -30
  68. package/dist/packages/engine/compile/validate.js +26 -24
  69. package/dist/packages/engine/execution/lib/schema.d.ts +79 -33
  70. package/dist/packages/engine/execution/lib/schema.js +13 -5
  71. package/dist/packages/engine/index.d.ts +2 -2
  72. package/dist/packages/engine/index.js +1 -1
  73. package/dist/packages/engine/lib/schema.d.ts +551 -242
  74. package/dist/packages/engine/lib/schema.js +53 -17
  75. package/dist/packages/engine/native-run-handlers.js +15 -7
  76. package/dist/packages/engine/preparation-store.d.ts +6 -0
  77. package/dist/packages/engine/preparation-store.js +8 -0
  78. package/dist/packages/engine/routes.d.ts +6 -0
  79. package/dist/packages/engine/routes.js +6 -0
  80. package/dist/packages/engine/run-observability.js +1 -2
  81. package/dist/packages/engine/runtime-event-applier.js +7 -0
  82. package/dist/packages/engine/runtime-proposal-helpers.js +1 -1
  83. package/dist/packages/engine/runtime-resource-builders.d.ts +6 -6
  84. package/dist/packages/engine/runtime-resource-builders.js +5 -4
  85. package/dist/packages/engine/runtime.d.ts +67 -7
  86. package/dist/packages/engine/runtime.js +159 -29
  87. package/dist/packages/engine/server.d.ts +25 -0
  88. package/dist/packages/engine/server.js +62 -3
  89. package/dist/packages/engine/verify/index.d.ts +10 -10
  90. package/dist/packages/engine/verify/index.js +8 -8
  91. package/dist/packages/engine/verify/readiness-check-run.d.ts +27 -4
  92. package/dist/packages/engine/verify/readiness-check-run.js +92 -24
  93. package/dist/packages/engine/verify/{test-execution.d.ts → verify-execution.d.ts} +2 -2
  94. package/dist/packages/engine/verify/{test-execution.js → verify-execution.js} +2 -2
  95. package/dist/packages/engine/verify/{test-paths.d.ts → verify-paths.d.ts} +1 -1
  96. package/dist/packages/engine/verify/{test-sandbox.d.ts → verify-sandbox.d.ts} +1 -1
  97. package/dist/packages/engine/verify/{test-specs.d.ts → verify-specs.d.ts} +1 -1
  98. package/dist/packages/engine/verify/{test-specs.js → verify-specs.js} +1 -1
  99. package/dist/packages/engine/verify/{test-targets.d.ts → verify-targets.d.ts} +1 -1
  100. package/dist/packages/engine/verify/{test.d.ts → verify.d.ts} +4 -4
  101. package/dist/packages/engine/verify/{test.js → verify.js} +3 -3
  102. package/dist/packages/engine/wire-schemas.d.ts +545 -0
  103. package/dist/packages/engine/wire-schemas.js +59 -0
  104. package/dist/packages/methods/authoring/method-authoring.d.ts +2 -0
  105. package/dist/packages/methods/authoring/method-authoring.js +99 -18
  106. package/dist/packages/methods/authoring/method-edit-session.js +5 -5
  107. package/dist/packages/methods/authoring/method-improvement.js +1 -1
  108. package/dist/packages/methods/package/builtin-compiled-method.d.ts +12 -12
  109. package/dist/packages/methods/package/builtin-compiled-method.js +25 -22
  110. package/dist/packages/methods/package/context-interface.d.ts +39 -26
  111. package/dist/packages/methods/package/context-interface.js +48 -39
  112. package/dist/packages/methods/package/interf-method-package.js +28 -47
  113. package/dist/packages/methods/package/local-methods.d.ts +3 -4
  114. package/dist/packages/methods/package/local-methods.js +34 -62
  115. package/dist/packages/methods/package/method-definitions.d.ts +4 -6
  116. package/dist/packages/methods/package/method-definitions.js +0 -4
  117. package/dist/packages/methods/package/method-helpers.d.ts +0 -2
  118. package/dist/packages/methods/package/method-helpers.js +0 -4
  119. package/dist/packages/project/interf-scaffold.js +12 -12
  120. package/dist/packages/project/source-config.js +2 -1
  121. package/package.json +6 -16
  122. package/dist/packages/engine/compile/runtime-acceptance.d.ts +0 -9
  123. package/dist/packages/engine/compile/runtime-acceptance.js +0 -265
  124. /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → 6qyE1u9m_oBUkvAhhoCmO}/_buildManifest.js +0 -0
  125. /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → 6qyE1u9m_oBUkvAhhoCmO}/_clientMiddlewareManifest.js +0 -0
  126. /package/dist/compiler-ui/_next/static/{a3UiUF0DiMEbfWy_0gihg → 6qyE1u9m_oBUkvAhhoCmO}/_ssgManifest.js +0 -0
  127. /package/dist/packages/engine/verify/{test-paths.js → verify-paths.js} +0 -0
  128. /package/dist/packages/engine/verify/{test-profile-presets.d.ts → verify-profile-presets.d.ts} +0 -0
  129. /package/dist/packages/engine/verify/{test-profile-presets.js → verify-profile-presets.js} +0 -0
  130. /package/dist/packages/engine/verify/{test-sandbox.js → verify-sandbox.js} +0 -0
  131. /package/dist/packages/engine/verify/{test-targets.js → verify-targets.js} +0 -0
  132. /package/dist/packages/engine/verify/{test-types.d.ts → verify-types.d.ts} +0 -0
  133. /package/dist/packages/engine/verify/{test-types.js → verify-types.js} +0 -0
package/LICENSE.md ADDED
@@ -0,0 +1 @@
1
+ © 2026 Interf Inc. All rights reserved. Use is subject to Interf's [Commercial Terms of Service](https://interf.com/legal/commercial-terms).
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Interf
2
2
 
3
+ **Prepare your data for AI agents. With proof.**
4
+
3
5
  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
6
 
5
7
  **Hallucinations aren't an agent problem. They're a data preparation problem.**
@@ -63,7 +65,7 @@ The agent can still do the processing. Interf shows what ran, which files were p
63
65
 
64
66
  ```bash
65
67
  npm install -g @interf/compiler
66
- interf # opens the wizard once an instance is running
68
+ interf # opens the wizard; start or connect an engine when needed
67
69
  ```
68
70
 
69
71
  Requires Node.js 20+ and a local coding agent such as Claude Code or Codex. Run `interf doctor --live` if the executor is not detected.
@@ -80,9 +82,10 @@ interf test bristol # check readiness
80
82
  ```
81
83
 
82
84
  `interf web` starts the engine in the foreground and writes
83
- `~/.interf/connection.json` so subsequent CLI commands can connect. Mutating
84
- commands never auto-start an engine if no instance is connected, every
85
- command exits with a hint pointing at `interf web` (local) or
85
+ `~/.interf/connection.json` so subsequent CLI commands can connect. The
86
+ interactive `interf` wizard can ask whether to start `interf web` or connect a
87
+ remote engine. Mutating commands never auto-start an engine if no instance is
88
+ connected, they exit with a hint pointing at `interf web` (local) or
86
89
  `interf login` (future cloud).
87
90
 
88
91
  `interf compile` returns the artifact locator on success — for a local
@@ -193,7 +196,7 @@ Verify runs always resolve to the `verifier` role. Method-authoring runs ask the
193
196
 
194
197
  The instance owns preparation state. A preparation declares a source binding (`{ kind: "local-folder", locator: <path> }`) and a method id; the instance stores its config at `~/.interf/preparations/<prep-id>/config.json` and writes portable context to `~/.interf/preparations/<prep-id>/portable-context/`. A compile run processes the selected source files and produces the artifact locator the API returns. `interf test` checks Source Folder files and portable context against the same readiness checks.
195
198
 
196
- Readiness is one `ready` / `not ready` status, not a separate score. Interf builds it from evidence primitives: stage/Method acceptance criteria, proof records, file coverage, artifact validation, and readiness checks.
199
+ Readiness is one `ready` / `not ready` status, not a separate score. Interf builds it from evidence primitives: Method Artifact checks, proof records, file coverage, artifact validation, and readiness checks.
197
200
 
198
201
  `interf web` runs the local Interf instance and serves Interf Compiler UI. The UI reads local-service resources: Source Files, Methods, runs, stages, proof, artifacts, readiness checks, and whether portable context is `ready` or `not ready`. It renders local instance state; it does not own compiler, Method, or readiness semantics.
199
202
 
@@ -225,7 +228,7 @@ There is no auto-start. There is no per-folder pointer file. One mental model: c
225
228
 
226
229
  There are two checks in the system, and they answer different questions.
227
230
 
228
- Method acceptance criteria check the build: did the Method produce the files, folders, artifacts, and stage outputs it promised? Interf checks those while it compiles.
231
+ Method Artifact checks check the build: did the Method produce the files, folders, Artifacts, and stage outputs it promised? Interf checks those while it compiles.
229
232
 
230
233
  Readiness checks check the Method output: is this portable context good enough for the specific agent work? They are the confidence layer on top of the portable context, not the product output.
231
234
 
@@ -304,5 +307,5 @@ A maintained public test example uses this preparation:
304
307
 
305
308
  Contributors: see [CONTRIBUTING.md](./CONTRIBUTING.md).
306
309
 
307
- Code: proprietary (this repo is private; the package is not published).
310
+ License: see [LICENSE.md](./LICENSE.md). © 2026 Interf Inc. All rights reserved.
308
311
  Name and branding: see [TRADEMARKS.md](./TRADEMARKS.md).
package/TRADEMARKS.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Trademarks
2
2
 
3
- `Interf`, the Interf word mark, and related logos are trademarks of Interf, Inc.
3
+ `Interf`, the Interf word mark, and related logos are trademarks of Interf Inc.
4
4
 
5
- This repository is proprietary and currently private. The Interf marks are
6
- not licensed for public use.
5
+ The Interf marks are not licensed for public use. Public visibility of any
6
+ Interf code, docs, or package does not grant trademark or branding rights.
7
7
 
8
- If you need official brand usage permission, contact Interf, Inc.
8
+ If you need official brand usage permission, contact Interf Inc.
@@ -7,20 +7,19 @@ Built-in file-processing Method: summarize source-grounded evidence, structure c
7
7
  - General portable-context Method for agent use
8
8
  - Compile mixed source files into evidence-backed summaries, cross-file structure, and a usable entrypoint for agents running the readiness checks this task depends on.
9
9
 
10
- ## Zones
10
+ ## Artifacts
11
11
 
12
- - `summaries` — working directory at `summaries`
12
+ - `summaries` — output directory at `summaries`
13
13
  - `knowledge-entities` — output directory at `knowledge/entities`
14
14
  - `knowledge-claims` — output directory at `knowledge/claims`
15
15
  - `knowledge-indexes` — output directory at `knowledge/indexes`
16
- - `home` — output file at `home.md` used as the primary entrypoint for this Method
17
- - `runtime` — runtime zone at `.interf/runtime`
16
+ - `atlas` — output file at `home.md` used as the primary entrypoint for this Method
18
17
 
19
18
  ## Stages
20
19
 
21
- - `summarize` — Turn source files into per-file summaries. (compiled-file-evidence; reads: runtime; writes: summaries)
22
- - `structure` — Build the cross-file knowledge structure from the summaries. (compiled-knowledge-structure; reads: summaries, runtime; writes: knowledge-entities, knowledge-claims, knowledge-indexes)
23
- - `shape` — Shape the final portable context around the saved task focus and readiness checks. (compiled-query-shape; reads: summaries, knowledge-entities, knowledge-claims, knowledge-indexes, runtime; writes: knowledge-indexes, home)
20
+ - `summarize` — Turn source files into per-file summaries. (compiled-file-evidence; reads: none; writes: summaries)
21
+ - `structure` — Build the cross-file knowledge structure from the summaries. (compiled-knowledge-structure; reads: summaries; writes: knowledge-entities, knowledge-claims, knowledge-indexes)
22
+ - `shape` — Shape the final portable context around the saved task focus and readiness checks. (compiled-query-shape; reads: summaries, knowledge-entities, knowledge-claims, knowledge-indexes; writes: knowledge-indexes, atlas)
24
23
 
25
24
  ## Why `home.md` exists here
26
25
 
@@ -26,35 +26,10 @@
26
26
  "description": "Turn source files into per-file summaries.",
27
27
  "contract_type": "compiled-file-evidence",
28
28
  "skill_dir": "summarize",
29
- "reads": [
30
- "runtime"
31
- ],
29
+ "reads": [],
32
30
  "writes": [
33
31
  "summaries"
34
- ],
35
- "acceptance": {
36
- "stage_truthy": [
37
- "finished_at"
38
- ],
39
- "zone_counts_at_least_counts": {
40
- "summaries": "source_total"
41
- },
42
- "markdown_frontmatter_valid_zones": [
43
- "summaries"
44
- ],
45
- "frontmatter_required_keys_in_zones": {
46
- "summaries": [
47
- "source",
48
- "source_kind",
49
- "evidence_tier",
50
- "truth_mode",
51
- "state"
52
- ]
53
- },
54
- "markdown_abstract_valid_zones": [
55
- "summaries"
56
- ]
57
- }
32
+ ]
58
33
  },
59
34
  {
60
35
  "id": "structure",
@@ -63,28 +38,13 @@
63
38
  "contract_type": "compiled-knowledge-structure",
64
39
  "skill_dir": "structure",
65
40
  "reads": [
66
- "summaries",
67
- "runtime"
41
+ "summaries"
68
42
  ],
69
43
  "writes": [
70
44
  "knowledge-entities",
71
45
  "knowledge-claims",
72
46
  "knowledge-indexes"
73
- ],
74
- "acceptance": {
75
- "artifacts_exist": [
76
- "knowledge/indexes"
77
- ],
78
- "stage_truthy": [
79
- "finished_at"
80
- ],
81
- "wikilinks_valid_in_zones": [
82
- "summaries",
83
- "knowledge-entities",
84
- "knowledge-claims",
85
- "knowledge-indexes"
86
- ]
87
- }
47
+ ]
88
48
  },
89
49
  {
90
50
  "id": "shape",
@@ -96,33 +56,12 @@
96
56
  "summaries",
97
57
  "knowledge-entities",
98
58
  "knowledge-claims",
99
- "knowledge-indexes",
100
- "runtime"
59
+ "knowledge-indexes"
101
60
  ],
102
61
  "writes": [
103
62
  "knowledge-indexes",
104
- "home"
105
- ],
106
- "acceptance": {
107
- "artifacts_exist": [
108
- "home.md"
109
- ],
110
- "stage_truthy": [
111
- "finished_at"
112
- ],
113
- "wikilinks_valid_in_zones": [
114
- "summaries",
115
- "knowledge-entities",
116
- "knowledge-claims",
117
- "knowledge-indexes",
118
- "home"
119
- ],
120
- "artifacts_must_not_contain": {
121
- "home.md": [
122
- "Not yet compiled."
123
- ]
124
- }
125
- }
63
+ "atlas"
64
+ ]
126
65
  }
127
66
  ],
128
67
  "stage_policy_notes": {
@@ -3,71 +3,73 @@
3
3
  "version": 1,
4
4
  "target_type": "compiled",
5
5
  "label": "Interf built-in Method schema",
6
- "zones": [
6
+ "artifacts": [
7
+ {
8
+ "id": "atlas",
9
+ "description": "Primary entrypoint note that agents read first. Routes to summaries, knowledge entities, claims, and indexes.",
10
+ "shape": { "kind": "path", "path": "home.md", "artifact_kind": "file" },
11
+ "checks": [
12
+ { "id": "exists", "kind": "file_exists", "required": true },
13
+ {
14
+ "id": "no-placeholder",
15
+ "kind": "must_not_contain",
16
+ "required": true,
17
+ "params": { "phrases": ["Not yet compiled."] }
18
+ },
19
+ { "id": "wikilinks", "kind": "wikilinks_valid", "required": true }
20
+ ],
21
+ "built_by_stages": ["shape"]
22
+ },
7
23
  {
8
24
  "id": "summaries",
9
- "role": "working",
10
- "path": "summaries",
11
- "kind": "directory",
12
- "required": true,
13
- "owned_by": [
14
- "summarize"
25
+ "description": "Per-file evidence notes that preserve the source-grounded synthesis agents quote against.",
26
+ "shape": { "kind": "path", "path": "summaries", "artifact_kind": "directory" },
27
+ "checks": [
28
+ {
29
+ "id": "all-files-summarized",
30
+ "kind": "min_file_count_matches_source",
31
+ "required": true,
32
+ "params": { "match": "source_total" }
33
+ },
34
+ { "id": "frontmatter-valid", "kind": "frontmatter_valid", "required": true },
35
+ {
36
+ "id": "evidence-keys",
37
+ "kind": "frontmatter_required_keys",
38
+ "required": true,
39
+ "params": { "keys": ["source", "source_kind", "evidence_tier", "truth_mode", "state"] }
40
+ }
15
41
  ],
16
- "description": "Per-file evidence notes produced by file-evidence stages."
42
+ "built_by_stages": ["summarize"]
17
43
  },
18
44
  {
19
45
  "id": "knowledge-entities",
20
- "role": "output",
21
- "path": "knowledge/entities",
22
- "kind": "directory",
23
- "required": true,
24
- "owned_by": [
25
- "structure"
46
+ "description": "Canonical entity notes that anchor the cross-file knowledge structure.",
47
+ "shape": { "kind": "path", "path": "knowledge/entities", "artifact_kind": "directory" },
48
+ "checks": [
49
+ { "id": "exists", "kind": "min_file_count", "required": true, "params": { "min": 1 } },
50
+ { "id": "wikilinks", "kind": "wikilinks_valid", "required": true }
26
51
  ],
27
- "description": "Canonical entity notes produced by knowledge-structure stages."
52
+ "built_by_stages": ["structure"]
28
53
  },
29
54
  {
30
55
  "id": "knowledge-claims",
31
- "role": "output",
32
- "path": "knowledge/claims",
33
- "kind": "directory",
34
- "required": true,
35
- "owned_by": [
36
- "structure"
56
+ "description": "Claim notes extracted from summaries with evidence references.",
57
+ "shape": { "kind": "path", "path": "knowledge/claims", "artifact_kind": "directory" },
58
+ "checks": [
59
+ { "id": "exists", "kind": "min_file_count", "required": true, "params": { "min": 1 } },
60
+ { "id": "wikilinks", "kind": "wikilinks_valid", "required": true }
37
61
  ],
38
- "description": "Claim notes produced by knowledge-structure stages."
62
+ "built_by_stages": ["structure"]
39
63
  },
40
64
  {
41
65
  "id": "knowledge-indexes",
42
- "role": "output",
43
- "path": "knowledge/indexes",
44
- "kind": "directory",
45
- "required": true,
46
- "owned_by": [
47
- "structure",
48
- "shape"
49
- ],
50
- "description": "Retrieval indexes and navigation notes produced by structure and shape stages."
51
- },
52
- {
53
- "id": "home",
54
- "role": "output",
55
- "path": "home.md",
56
- "kind": "file",
57
- "required": true,
58
- "owned_by": [
59
- "shape"
66
+ "description": "Retrieval indexes and navigation notes for the knowledge structure.",
67
+ "shape": { "kind": "path", "path": "knowledge/indexes", "artifact_kind": "directory" },
68
+ "checks": [
69
+ { "id": "exists", "kind": "min_file_count", "required": true, "params": { "min": 1 } },
70
+ { "id": "wikilinks", "kind": "wikilinks_valid", "required": true }
60
71
  ],
61
- "description": "Primary entrypoint note for agents using the portable context."
62
- },
63
- {
64
- "id": "runtime",
65
- "role": "runtime",
66
- "path": ".interf/runtime",
67
- "kind": "runtime",
68
- "required": true,
69
- "owned_by": [],
70
- "description": "CLI-owned runtime state, health, stage contracts, and proof artifacts."
72
+ "built_by_stages": ["structure", "shape"]
71
73
  }
72
74
  ]
73
75
  }
@@ -45,6 +45,52 @@ async function callJson(url, token, init = {}) {
45
45
  }
46
46
  return { status: response.status, body, raw };
47
47
  }
48
+ function statusColor(status) {
49
+ if (status === "ready")
50
+ return chalk.green;
51
+ if (status === "failed")
52
+ return chalk.red;
53
+ if (status === "skipped")
54
+ return chalk.dim;
55
+ return chalk.yellow;
56
+ }
57
+ function renderPreparationSummary(prep) {
58
+ console.log();
59
+ console.log(` ${chalk.bold(prep.name)}`);
60
+ if (prep.method_id)
61
+ console.log(chalk.dim(` method: ${prep.method_id}`));
62
+ if (prep.source_path)
63
+ console.log(chalk.dim(` source: ${prep.source_path}`));
64
+ if (prep.portable_context_path) {
65
+ console.log(chalk.dim(` output: ${prep.portable_context_path}`));
66
+ }
67
+ if (prep.readiness?.status) {
68
+ const aggColor = prep.readiness.ready ? chalk.green : chalk.yellow;
69
+ console.log(` readiness: ${aggColor(prep.readiness.status)}${prep.readiness.summary ? chalk.dim(` (${prep.readiness.summary})`) : ""}`);
70
+ }
71
+ if (prep.artifacts && prep.artifacts.length > 0) {
72
+ console.log();
73
+ console.log(chalk.bold(" Artifacts"));
74
+ const idWidth = Math.max(...prep.artifacts.map((entry) => entry.artifact_id.length), 8);
75
+ for (const artifact of prep.artifacts) {
76
+ const colored = statusColor(artifact.status)(artifact.status);
77
+ const stages = artifact.built_by_stages && artifact.built_by_stages.length > 0
78
+ ? chalk.dim(` ← ${artifact.built_by_stages.join(", ")}`)
79
+ : "";
80
+ console.log(` ${artifact.artifact_id.padEnd(idWidth)} ${colored}${stages}`);
81
+ }
82
+ }
83
+ if (prep.latest_compile_run_id) {
84
+ console.log();
85
+ console.log(chalk.dim(` latest compile run: ${prep.latest_compile_run_id}`));
86
+ }
87
+ if (prep.latest_test_run_id) {
88
+ console.log(chalk.dim(` latest verify run: ${prep.latest_test_run_id}`));
89
+ }
90
+ console.log();
91
+ console.log(chalk.dim(` Run with --json for the raw resource record.`));
92
+ console.log();
93
+ }
48
94
  export const prepCommand = {
49
95
  command: "prep <subcommand>",
50
96
  describe: "Manage preparations on the connected instance",
@@ -122,7 +168,13 @@ export const prepCommand = {
122
168
  }
123
169
  console.log(chalk.green(`Bound ${chalk.bold(args.methodId)} to ${chalk.bold(args.prepId)}.`));
124
170
  })
125
- .command("show <prep-id>", "Show a preparation's full record", (y) => y.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" }), async (args) => {
171
+ .command("show <prep-id>", "Show a preparation's full record", (y) => y
172
+ .positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
173
+ .option("json", {
174
+ type: "boolean",
175
+ default: false,
176
+ describe: "Print the raw JSON record instead of the formatted summary",
177
+ }), async (args) => {
126
178
  const { url, token } = requireConnection(args);
127
179
  const { status, body, raw } = await callJson(`${url}${preparationResourcePath(args.prepId)}`, token);
128
180
  if (status !== 200) {
@@ -131,7 +183,11 @@ export const prepCommand = {
131
183
  console.error(raw);
132
184
  process.exit(1);
133
185
  }
134
- console.log(JSON.stringify(body, null, 2));
186
+ if (args.json || !body) {
187
+ console.log(JSON.stringify(body, null, 2));
188
+ return;
189
+ }
190
+ renderPreparationSummary(body);
135
191
  })
136
192
  .command("rm <prep-id>", "Delete a preparation", (y) => y.positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" }), async (args) => {
137
193
  const { url, token } = requireConnection(args);
@@ -1,6 +1,8 @@
1
1
  import type { CommandModule } from "yargs";
2
+ type VerifyTarget = "compiled" | "source-files";
2
3
  interface VerifyArgs {
3
4
  prepId: string;
5
+ target?: VerifyTarget;
4
6
  url?: string;
5
7
  token?: string;
6
8
  }
@@ -1,10 +1,14 @@
1
1
  /**
2
2
  * `interf verify <prep-id>` — verify a preparation's claim-checks via a
3
- * judge against the latest compiled portable context. Together with the
4
- * method's structural checks (auto-run on every `interf compile`), this
5
- * feeds the preparation's overall readiness state.
3
+ * judge against the latest compiled portable context (default) or
4
+ * against the source folder baseline (`--target source-files`). The
5
+ * source-files target reveals how much value the Method actually adds.
6
+ * Together with the method's structural checks (auto-run on every
7
+ * `interf compile`), this feeds the preparation's overall readiness
8
+ * state.
6
9
  *
7
10
  * interf verify bristol
11
+ * interf verify bristol --target source-files
8
12
  */
9
13
  import chalk from "chalk";
10
14
  import { CONNECT_OR_ERROR_HINT, readActiveConnection } from "../../packages/engine/connection-config.js";
@@ -40,9 +44,15 @@ async function callJson(url, token, init = {}) {
40
44
  }
41
45
  export const verifyCommand = {
42
46
  command: "verify <prep-id>",
43
- describe: "Verify a preparation's claim-checks against its portable context",
47
+ describe: "Verify a preparation's claim-checks against its portable context (or source-files baseline)",
44
48
  builder: (yargs) => yargs
45
49
  .positional("prep-id", { type: "string", demandOption: true, describe: "Preparation id" })
50
+ .option("target", {
51
+ type: "string",
52
+ choices: ["compiled", "source-files"],
53
+ default: "compiled",
54
+ describe: "Judge target: 'compiled' (default) checks the portable context, 'source-files' checks the raw source folder baseline",
55
+ })
46
56
  .option("url", { type: "string", describe: "Override the active connection URL" })
47
57
  .option("token", { type: "string", describe: "Override the active bearer token" }),
48
58
  handler: async (args) => {
@@ -57,10 +67,8 @@ export const verifyCommand = {
57
67
  console.error(" register a custom CLI: `interf agents register <name> --command <cmd>`.");
58
68
  process.exit(1);
59
69
  }
60
- // Verify the user's claims against the compiled portable context.
61
- // The legacy "source-files" / "both" targets (file-as-is judging)
62
- // are gone — claims are evaluated against the compiled output only.
63
- const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/verify-runs`, token, { method: "POST", body: JSON.stringify({ mode: "compiled" }) });
70
+ const target = args.target ?? "compiled";
71
+ const { status, body, raw } = await callJson(`${url}/v1/preparations/${encodeURIComponent(args.prepId)}/verify-runs`, token, { method: "POST", body: JSON.stringify({ target }) });
64
72
  if (status !== 201 && status !== 200) {
65
73
  console.error(chalk.red(`Failed to start verify run for ${args.prepId} (HTTP ${status}).`));
66
74
  if (raw)
@@ -69,6 +77,7 @@ export const verifyCommand = {
69
77
  }
70
78
  console.log();
71
79
  console.log(` Run ${chalk.bold(body?.run_id ?? "(?)")} ${chalk.dim(`(${body?.status ?? "started"})`)}`);
80
+ console.log(` Target: ${target}`);
72
81
  if (body?.readiness?.status)
73
82
  console.log(` Readiness: ${body.readiness.status}`);
74
83
  if (body?.error)
@@ -2,7 +2,8 @@
2
2
  * `interf` (no subcommand) and `interf init` — the wizard.
3
3
  *
4
4
  * Casual-user entry point. End-to-end onboarding:
5
- * - If no connection → offer to start a local engine inline (or connect remote, or quit).
5
+ * - If no connection → connect to an already-running local engine, or ask
6
+ * whether to start the foreground local engine, connect remote, or quit.
6
7
  * - Once connected → action menu (list / create / compile / test / open UI / stop engine / quit).
7
8
  * - Each action loops back to the menu instead of exiting.
8
9
  *
@@ -15,7 +16,7 @@ import { existsSync, statSync } from "node:fs";
15
16
  import { homedir } from "node:os";
16
17
  import { basename, resolve } from "node:path";
17
18
  import { spawn } from "node:child_process";
18
- import { readActiveConnection, writeConnection, } from "../../packages/engine/connection-config.js";
19
+ import { ConnectionRecordSchema, readActiveConnection, writeConnection, } from "../../packages/engine/connection-config.js";
19
20
  import { LOCAL_SERVICE_DEFAULT_HOST, LOCAL_SERVICE_DEFAULT_PORT } from "../../packages/engine/routes.js";
20
21
  async function callJson(url, token) {
21
22
  const headers = new Headers();
@@ -46,6 +47,18 @@ function spawnInterf(args) {
46
47
  });
47
48
  }
48
49
  const DEFAULT_ENGINE_URL = `http://${LOCAL_SERVICE_DEFAULT_HOST}:${LOCAL_SERVICE_DEFAULT_PORT}`;
50
+ function hasInteractiveTerminal() {
51
+ return process.stdin.isTTY === true && process.stdout.isTTY === true;
52
+ }
53
+ function isHttpUrl(value) {
54
+ try {
55
+ const parsed = new URL(value);
56
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
49
62
  /**
50
63
  * Probe a URL's `/health` endpoint and return whether the engine is up.
51
64
  * Used as a fallback when `connection.json` may be missing (e.g. older
@@ -133,6 +146,69 @@ function exitNoEngineConnected(reason) {
133
146
  console.log();
134
147
  process.exit(1);
135
148
  }
149
+ async function promptForConnection(reason) {
150
+ if (!hasInteractiveTerminal()) {
151
+ exitNoEngineConnected(reason);
152
+ }
153
+ console.log();
154
+ console.log(chalk.yellow(` ${reason}`));
155
+ console.log();
156
+ const choice = await p.select({
157
+ message: "How do you want to continue?",
158
+ options: [
159
+ { value: "start-local", label: "Start local engine (serves Compiler UI)" },
160
+ { value: "connect-remote", label: "Connect to remote engine" },
161
+ { value: "quit", label: chalk.dim("Exit") },
162
+ ],
163
+ initialValue: "start-local",
164
+ });
165
+ if (p.isCancel(choice) || choice === "quit") {
166
+ p.outro("Bye.");
167
+ return null;
168
+ }
169
+ if (choice === "start-local") {
170
+ console.log();
171
+ console.log(chalk.dim(" Starting `interf web` in this terminal. Press Ctrl-C to stop the engine."));
172
+ console.log();
173
+ const code = await spawnInterf(["web"]);
174
+ process.exit(code);
175
+ }
176
+ const urlValue = await p.text({
177
+ message: "Remote engine URL",
178
+ placeholder: "https://api.interf.cloud",
179
+ validate: (value) => {
180
+ const trimmed = String(value ?? "").trim();
181
+ if (!trimmed)
182
+ return "URL is required.";
183
+ const parsed = ConnectionRecordSchema.safeParse({ url: trimmed, auth_token: null });
184
+ return parsed.success && isHttpUrl(trimmed) ? undefined : "Enter a valid http(s) URL.";
185
+ },
186
+ });
187
+ if (p.isCancel(urlValue)) {
188
+ p.outro("Bye.");
189
+ return null;
190
+ }
191
+ const tokenValue = await p.password({
192
+ message: "Bearer token (optional)",
193
+ mask: "*",
194
+ });
195
+ if (p.isCancel(tokenValue)) {
196
+ p.outro("Bye.");
197
+ return null;
198
+ }
199
+ const record = ConnectionRecordSchema.parse({
200
+ url: String(urlValue).trim(),
201
+ auth_token: String(tokenValue ?? "").trim() || null,
202
+ });
203
+ const url = record.url.replace(/\/+$/, "");
204
+ const probe = await callJson(`${url}/health`, record.auth_token);
205
+ if (probe.status === 0) {
206
+ return promptForConnection(`Connection ${url} is unreachable.`);
207
+ }
208
+ writeConnection(record);
209
+ console.log(chalk.green("Connection saved."));
210
+ return { url, token: record.auth_token };
211
+ }
136
212
  /** Validate that a path exists and is a directory. */
137
213
  function validateSourcePath(value) {
138
214
  const abs = resolve(value);
@@ -522,25 +598,57 @@ async function fetchAgentSnapshot(conn) {
522
598
  };
523
599
  }
524
600
  async function runWizard(args) {
525
- // Connect-or-error: the wizard never auto-starts an engine. If
526
- // `~/.interf/connection.json` is missing or unreachable, exit
527
- // non-zero and tell the user to run `interf web` (or
528
- // `interf login`) explicitly. This keeps the engine lifecycle in
529
- // the user's hands — no surprise background processes, no stale
530
- // binaries served by a long-lived auto-spawn.
601
+ // The wizard is the human entry point, so it can ask how to connect.
602
+ // It still never auto-starts an engine: starting `interf web` is an
603
+ // explicit foreground choice, and script/agent commands keep the
604
+ // connect-or-error behavior.
531
605
  const initial = readActiveConnection({
532
606
  urlOverride: args.url,
533
607
  authTokenOverride: args.token,
534
608
  });
609
+ let conn = null;
535
610
  if (!initial) {
536
- exitNoEngineConnected("No Interf engine is connected.");
611
+ if (await probeHealth(DEFAULT_ENGINE_URL)) {
612
+ try {
613
+ writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
614
+ }
615
+ catch {
616
+ // best effort
617
+ }
618
+ console.log();
619
+ console.log(chalk.dim(` Engine already running at ${DEFAULT_ENGINE_URL} — connecting.`));
620
+ conn = { url: DEFAULT_ENGINE_URL, token: null };
621
+ }
622
+ else {
623
+ conn = await promptForConnection("No Interf engine is connected.");
624
+ }
537
625
  }
538
- const url = initial.url.replace(/\/+$/, "");
539
- const probe = await callJson(`${url}/health`, initial.auth_token);
540
- if (probe.status === 0) {
541
- exitNoEngineConnected(`Connection ${url} is unreachable.`);
626
+ else {
627
+ const url = initial.url.replace(/\/+$/, "");
628
+ const probe = await callJson(`${url}/health`, initial.auth_token);
629
+ if (probe.status === 0) {
630
+ if (!args.url && await probeHealth(DEFAULT_ENGINE_URL)) {
631
+ try {
632
+ writeConnection({ url: DEFAULT_ENGINE_URL, auth_token: null });
633
+ }
634
+ catch {
635
+ // best effort
636
+ }
637
+ console.log();
638
+ console.log(chalk.dim(` Saved connection ${url} is unreachable; using local engine at ${DEFAULT_ENGINE_URL}.`));
639
+ conn = { url: DEFAULT_ENGINE_URL, token: null };
640
+ }
641
+ else {
642
+ conn = await promptForConnection(`Connection ${url} is unreachable.`);
643
+ }
644
+ }
645
+ else {
646
+ conn = { url, token: initial.auth_token };
647
+ }
648
+ }
649
+ if (!conn) {
650
+ return;
542
651
  }
543
- let conn = { url, token: initial.auth_token };
544
652
  const instance = await callJson(`${conn.url}/v1/instance`, conn.token);
545
653
  console.log();
546
654
  console.log(chalk.bold(` Connected to ${conn.url}`));