@interf/compiler 0.9.4 → 0.13.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 (222) hide show
  1. package/README.md +96 -91
  2. package/TRADEMARKS.md +2 -13
  3. package/agent-skills/interf-actions/SKILL.md +97 -32
  4. package/agent-skills/interf-actions/references/cli.md +124 -71
  5. package/builtin-methods/interf-default/README.md +3 -4
  6. package/builtin-methods/interf-default/compile/stages/shape/SKILL.md +2 -2
  7. package/builtin-methods/interf-default/compile/stages/summarize/SKILL.md +2 -1
  8. package/builtin-methods/interf-default/improve/SKILL.md +1 -1
  9. package/builtin-methods/interf-default/method.json +10 -4
  10. package/builtin-methods/interf-default/method.schema.json +0 -9
  11. package/builtin-methods/interf-default/use/query/SKILL.md +5 -5
  12. package/dist/cli/commands/compile.d.ts +9 -31
  13. package/dist/cli/commands/compile.js +75 -388
  14. package/dist/cli/commands/doctor.js +1 -1
  15. package/dist/cli/commands/login.d.ts +7 -0
  16. package/dist/cli/commands/login.js +39 -0
  17. package/dist/cli/commands/logout.d.ts +2 -0
  18. package/dist/cli/commands/logout.js +16 -0
  19. package/dist/cli/commands/method.d.ts +2 -0
  20. package/dist/cli/commands/method.js +113 -0
  21. package/dist/cli/commands/prep.d.ts +2 -0
  22. package/dist/cli/commands/prep.js +134 -0
  23. package/dist/cli/commands/reset.d.ts +8 -1
  24. package/dist/cli/commands/reset.js +47 -15
  25. package/dist/cli/commands/runs.d.ts +2 -0
  26. package/dist/cli/commands/runs.js +120 -0
  27. package/dist/cli/commands/status.d.ts +6 -1
  28. package/dist/cli/commands/status.js +61 -220
  29. package/dist/cli/commands/test.d.ts +6 -15
  30. package/dist/cli/commands/test.js +63 -342
  31. package/dist/cli/commands/web.d.ts +0 -9
  32. package/dist/cli/commands/web.js +140 -367
  33. package/dist/cli/commands/wizard.d.ts +9 -0
  34. package/dist/cli/commands/wizard.js +442 -0
  35. package/dist/cli/index.d.ts +7 -6
  36. package/dist/cli/index.js +13 -10
  37. package/dist/compiler-ui/404.html +1 -1
  38. package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
  39. package/dist/compiler-ui/__next._full.txt +3 -3
  40. package/dist/compiler-ui/__next._head.txt +1 -1
  41. package/dist/compiler-ui/__next._index.txt +2 -2
  42. package/dist/compiler-ui/__next._tree.txt +2 -2
  43. package/dist/compiler-ui/_next/static/chunks/045gole2ojo3g.css +3 -0
  44. package/dist/compiler-ui/_next/static/chunks/17t-lulmyawg5.js +89 -0
  45. package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
  46. package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
  47. package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
  48. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
  49. package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
  50. package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
  51. package/dist/compiler-ui/_not-found.html +1 -1
  52. package/dist/compiler-ui/_not-found.txt +2 -2
  53. package/dist/compiler-ui/index.html +1 -1
  54. package/dist/compiler-ui/index.txt +3 -3
  55. package/dist/index.d.ts +0 -23
  56. package/dist/index.js +0 -16
  57. package/dist/packages/agents/lib/shells.d.ts +1 -1
  58. package/dist/packages/agents/lib/shells.js +113 -54
  59. package/dist/packages/agents/lib/user-config.d.ts +4 -2
  60. package/dist/packages/agents/lib/user-config.js +15 -7
  61. package/dist/packages/compiler/compiled-paths.d.ts +9 -2
  62. package/dist/packages/compiler/compiled-paths.js +30 -15
  63. package/dist/packages/compiler/compiled-pipeline.js +23 -3
  64. package/dist/packages/compiler/compiled-stage-plan.js +4 -0
  65. package/dist/packages/compiler/compiled-target.d.ts +1 -1
  66. package/dist/packages/compiler/compiled-target.js +1 -1
  67. package/dist/packages/compiler/index.d.ts +1 -0
  68. package/dist/packages/compiler/index.js +1 -0
  69. package/dist/packages/compiler/lib/schema.d.ts +27 -32
  70. package/dist/packages/compiler/lib/schema.js +2 -13
  71. package/dist/packages/compiler/method-runs.d.ts +2 -3
  72. package/dist/packages/compiler/method-runs.js +2 -3
  73. package/dist/packages/compiler/reset.js +3 -1
  74. package/dist/packages/compiler/runtime-contracts.js +0 -3
  75. package/dist/packages/compiler/runtime-prompt.js +1 -1
  76. package/dist/packages/compiler/source-files.d.ts +46 -0
  77. package/dist/packages/compiler/source-files.js +149 -0
  78. package/dist/packages/compiler/state-artifacts.d.ts +3 -2
  79. package/dist/packages/compiler/state-artifacts.js +4 -3
  80. package/dist/packages/compiler/state-io.d.ts +3 -2
  81. package/dist/packages/compiler/state-io.js +11 -5
  82. package/dist/packages/compiler/state-paths.d.ts +2 -1
  83. package/dist/packages/compiler/state-paths.js +6 -3
  84. package/dist/packages/compiler/state-view.d.ts +3 -2
  85. package/dist/packages/compiler/state-view.js +18 -28
  86. package/dist/packages/compiler/state.d.ts +4 -4
  87. package/dist/packages/compiler/state.js +3 -3
  88. package/dist/packages/contracts/index.d.ts +1 -1
  89. package/dist/packages/contracts/lib/preparation-paths.d.ts +117 -0
  90. package/dist/packages/contracts/lib/preparation-paths.js +177 -0
  91. package/dist/packages/contracts/lib/schema.d.ts +85 -6
  92. package/dist/packages/contracts/lib/schema.js +46 -2
  93. package/dist/packages/execution/lib/schema.d.ts +50 -57
  94. package/dist/packages/execution/lib/schema.js +1 -2
  95. package/dist/packages/local-service/action-definitions.d.ts +246 -0
  96. package/dist/packages/local-service/action-definitions.js +1147 -0
  97. package/dist/packages/local-service/action-planner.d.ts +9 -0
  98. package/dist/packages/local-service/action-planner.js +135 -0
  99. package/dist/packages/local-service/action-values.d.ts +1 -23
  100. package/dist/packages/local-service/action-values.js +1 -31
  101. package/dist/packages/local-service/client.d.ts +76 -46
  102. package/dist/packages/local-service/client.js +184 -149
  103. package/dist/packages/local-service/connection-config.d.ts +38 -0
  104. package/dist/packages/local-service/connection-config.js +75 -0
  105. package/dist/packages/local-service/index.d.ts +14 -7
  106. package/dist/packages/local-service/index.js +8 -4
  107. package/dist/packages/local-service/instance-paths.d.ts +100 -0
  108. package/dist/packages/local-service/instance-paths.js +165 -0
  109. package/dist/packages/local-service/lib/schema.d.ts +689 -2575
  110. package/dist/packages/local-service/lib/schema.js +260 -101
  111. package/dist/packages/local-service/native-run-handlers.d.ts +23 -0
  112. package/dist/{cli/commands/compile-controller.js → packages/local-service/native-run-handlers.js} +204 -20
  113. package/dist/packages/local-service/preparation-store.d.ts +92 -0
  114. package/dist/packages/local-service/preparation-store.js +171 -0
  115. package/dist/{cli/commands/check-draft.d.ts → packages/local-service/readiness-check-draft.d.ts} +2 -2
  116. package/dist/packages/local-service/routes.d.ts +33 -11
  117. package/dist/packages/local-service/routes.js +44 -15
  118. package/dist/packages/local-service/run-observability.js +25 -27
  119. package/dist/packages/local-service/runtime-caches.d.ts +76 -0
  120. package/dist/packages/local-service/runtime-caches.js +191 -0
  121. package/dist/packages/local-service/runtime-event-applier.d.ts +12 -0
  122. package/dist/packages/local-service/runtime-event-applier.js +177 -0
  123. package/dist/packages/local-service/runtime-persistence.d.ts +47 -0
  124. package/dist/packages/local-service/runtime-persistence.js +137 -0
  125. package/dist/packages/local-service/runtime-proposal-helpers.d.ts +35 -0
  126. package/dist/packages/local-service/runtime-proposal-helpers.js +251 -0
  127. package/dist/packages/local-service/runtime-resource-builders.d.ts +52 -0
  128. package/dist/packages/local-service/runtime-resource-builders.js +149 -0
  129. package/dist/packages/local-service/runtime.d.ts +201 -44
  130. package/dist/packages/local-service/runtime.js +1062 -1106
  131. package/dist/packages/local-service/server.d.ts +15 -0
  132. package/dist/packages/local-service/server.js +651 -233
  133. package/dist/packages/local-service/service-registry.d.ts +47 -0
  134. package/dist/packages/local-service/service-registry.js +137 -0
  135. package/dist/packages/method-authoring/method-authoring.d.ts +1 -1
  136. package/dist/packages/method-authoring/method-authoring.js +2 -2
  137. package/dist/packages/method-authoring/method-improvement.js +1 -1
  138. package/dist/packages/method-package/builtin-compiled-method.d.ts +4 -5
  139. package/dist/packages/method-package/builtin-compiled-method.js +8 -14
  140. package/dist/packages/method-package/context-interface.d.ts +4 -40
  141. package/dist/packages/method-package/context-interface.js +1 -23
  142. package/dist/packages/method-package/interf-method-package.d.ts +4 -4
  143. package/dist/packages/method-package/interf-method-package.js +21 -33
  144. package/dist/packages/method-package/local-methods.d.ts +10 -6
  145. package/dist/packages/method-package/local-methods.js +57 -39
  146. package/dist/packages/method-package/method-definitions.d.ts +8 -34
  147. package/dist/packages/method-package/method-definitions.js +49 -37
  148. package/dist/packages/method-package/method-helpers.d.ts +1 -13
  149. package/dist/packages/method-package/method-helpers.js +8 -42
  150. package/dist/packages/method-package/method-review-paths.d.ts +1 -1
  151. package/dist/packages/method-package/method-review-paths.js +5 -5
  152. package/dist/packages/method-package/method-stage-runner.js +2 -2
  153. package/dist/packages/method-package/user-methods.d.ts +17 -0
  154. package/dist/packages/method-package/user-methods.js +77 -0
  155. package/dist/packages/project-model/index.d.ts +1 -1
  156. package/dist/packages/project-model/index.js +1 -1
  157. package/dist/packages/project-model/interf-detect.d.ts +8 -3
  158. package/dist/packages/project-model/interf-detect.js +34 -34
  159. package/dist/packages/project-model/interf-scaffold.d.ts +3 -3
  160. package/dist/packages/project-model/interf-scaffold.js +23 -32
  161. package/dist/packages/project-model/lib/schema.js +38 -1
  162. package/dist/packages/project-model/preparation-entries.d.ts +11 -0
  163. package/dist/packages/project-model/preparation-entries.js +49 -0
  164. package/dist/packages/project-model/source-config.d.ts +11 -10
  165. package/dist/packages/project-model/source-config.js +83 -44
  166. package/dist/packages/project-model/source-folders.d.ts +5 -5
  167. package/dist/packages/project-model/source-folders.js +14 -14
  168. package/dist/packages/shared/filesystem.d.ts +7 -0
  169. package/dist/packages/shared/filesystem.js +97 -10
  170. package/dist/packages/testing/lib/schema.d.ts +12 -13
  171. package/dist/packages/testing/lib/schema.js +4 -5
  172. package/dist/packages/testing/readiness-check-run.d.ts +7 -7
  173. package/dist/packages/testing/readiness-check-run.js +46 -51
  174. package/dist/packages/testing/test-execution.js +6 -6
  175. package/dist/packages/testing/test-paths.js +4 -3
  176. package/dist/packages/testing/test-sandbox.d.ts +0 -1
  177. package/dist/packages/testing/test-sandbox.js +14 -30
  178. package/dist/packages/testing/test-targets.d.ts +1 -1
  179. package/dist/packages/testing/test-targets.js +6 -6
  180. package/dist/packages/testing/test.d.ts +1 -1
  181. package/dist/packages/testing/test.js +1 -1
  182. package/package.json +6 -26
  183. package/LICENSE +0 -183
  184. package/dist/cli/commands/compile-controller.d.ts +0 -17
  185. package/dist/cli/commands/compiled-flow.d.ts +0 -25
  186. package/dist/cli/commands/compiled-flow.js +0 -112
  187. package/dist/cli/commands/control-path.d.ts +0 -11
  188. package/dist/cli/commands/control-path.js +0 -72
  189. package/dist/cli/commands/create-method-wizard.d.ts +0 -76
  190. package/dist/cli/commands/create-method-wizard.js +0 -465
  191. package/dist/cli/commands/create.d.ts +0 -8
  192. package/dist/cli/commands/create.js +0 -189
  193. package/dist/cli/commands/default.d.ts +0 -2
  194. package/dist/cli/commands/default.js +0 -39
  195. package/dist/cli/commands/executor-flow.d.ts +0 -29
  196. package/dist/cli/commands/executor-flow.js +0 -163
  197. package/dist/cli/commands/init.d.ts +0 -11
  198. package/dist/cli/commands/init.js +0 -784
  199. package/dist/cli/commands/list.d.ts +0 -2
  200. package/dist/cli/commands/list.js +0 -30
  201. package/dist/cli/commands/preparation-selection.d.ts +0 -6
  202. package/dist/cli/commands/preparation-selection.js +0 -11
  203. package/dist/cli/commands/source-config-wizard.d.ts +0 -52
  204. package/dist/cli/commands/source-config-wizard.js +0 -680
  205. package/dist/cli/commands/test-flow.d.ts +0 -58
  206. package/dist/cli/commands/test-flow.js +0 -231
  207. package/dist/cli/commands/verify.d.ts +0 -2
  208. package/dist/cli/commands/verify.js +0 -94
  209. package/dist/compiler-ui/_next/static/chunks/0d~8t0zm6545p.js +0 -118
  210. package/dist/compiler-ui/_next/static/chunks/0xnel.ax9a.2c.css +0 -3
  211. package/dist/packages/compiler/raw-snapshot.d.ts +0 -49
  212. package/dist/packages/compiler/raw-snapshot.js +0 -101
  213. package/dist/packages/method-package/index.d.ts +0 -11
  214. package/dist/packages/method-package/index.js +0 -11
  215. package/dist/packages/method-package/method-stage-policy.d.ts +0 -5
  216. package/dist/packages/method-package/method-stage-policy.js +0 -31
  217. package/dist/packages/project-model/project-paths.d.ts +0 -12
  218. package/dist/packages/project-model/project-paths.js +0 -33
  219. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → C6vVfy3aeYuIO3d2AoNvC}/_buildManifest.js +0 -0
  220. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → C6vVfy3aeYuIO3d2AoNvC}/_clientMiddlewareManifest.js +0 -0
  221. /package/dist/compiler-ui/_next/static/{j7pdoqWrl4YJrJUVnksbl → C6vVfy3aeYuIO3d2AoNvC}/_ssgManifest.js +0 -0
  222. /package/dist/{cli/commands/check-draft.js → packages/local-service/readiness-check-draft.js} +0 -0
@@ -0,0 +1,177 @@
1
+ import { uniqueArtifacts } from "./run-observability.js";
2
+ export function applyEventToCompileRun(run, event) {
3
+ const now = event.timestamp;
4
+ const stageFor = (stageId) => {
5
+ const existing = run.stages.find((stage) => stage.stage_id === stageId);
6
+ if (existing)
7
+ return existing;
8
+ const created = {
9
+ run_id: run.run_id,
10
+ stage_id: stageId,
11
+ status: "queued",
12
+ artifacts: [],
13
+ };
14
+ run.stages.push(created);
15
+ return created;
16
+ };
17
+ const updateStage = (stageId, patch) => {
18
+ const current = stageFor(stageId);
19
+ Object.assign(current, patch);
20
+ };
21
+ switch (event.type) {
22
+ case "run.started":
23
+ return {
24
+ ...run,
25
+ status: "running",
26
+ started_at: run.started_at ?? now,
27
+ events: [...run.events, event],
28
+ };
29
+ case "stage.started":
30
+ updateStage(event.stage_id, {
31
+ status: "running",
32
+ started_at: now,
33
+ stage_index: event.stage_index,
34
+ stage_total: event.stage_total,
35
+ });
36
+ break;
37
+ case "artifact.written": {
38
+ const stage = stageFor(event.stage_id);
39
+ updateStage(event.stage_id, {
40
+ artifacts: uniqueArtifacts([...(stage.artifacts ?? []), event.artifact]),
41
+ });
42
+ break;
43
+ }
44
+ case "proof.updated":
45
+ if (event.stage_id) {
46
+ updateStage(event.stage_id, {
47
+ latest_proof: event.proof,
48
+ });
49
+ }
50
+ return {
51
+ ...run,
52
+ latest_proof: event.proof,
53
+ events: [...run.events, event],
54
+ };
55
+ case "log.appended":
56
+ break;
57
+ case "stage.passed":
58
+ updateStage(event.stage_id, {
59
+ status: "succeeded",
60
+ finished_at: now,
61
+ summary: event.summary ?? null,
62
+ failure: null,
63
+ });
64
+ break;
65
+ case "stage.failed":
66
+ updateStage(event.stage_id, {
67
+ status: "failed",
68
+ finished_at: now,
69
+ summary: event.error,
70
+ failure: event.error,
71
+ });
72
+ break;
73
+ case "run.completed":
74
+ return {
75
+ ...run,
76
+ // Once cancelled, the cancelled status is sticky; the handler may
77
+ // still emit a completion event after the cancel signal has landed.
78
+ status: run.status === "cancelled" ? "cancelled" : "succeeded",
79
+ finished_at: run.finished_at ?? now,
80
+ events: [...run.events, event],
81
+ };
82
+ case "run.failed":
83
+ return {
84
+ ...run,
85
+ status: run.status === "cancelled" ? "cancelled" : "failed",
86
+ finished_at: run.finished_at ?? now,
87
+ events: [...run.events, event],
88
+ };
89
+ case "readiness.updated":
90
+ return {
91
+ ...run,
92
+ readiness: event.readiness,
93
+ events: [...run.events, event],
94
+ };
95
+ default:
96
+ break;
97
+ }
98
+ return {
99
+ ...run,
100
+ events: [...run.events, event],
101
+ };
102
+ }
103
+ export function applyEventToLocalJob(run, event) {
104
+ const stepFor = (stepId) => {
105
+ const existing = run.steps.find((step) => step.id === stepId);
106
+ if (existing)
107
+ return existing;
108
+ const created = {
109
+ id: stepId,
110
+ label: stepId,
111
+ status: "queued",
112
+ };
113
+ run.steps.push(created);
114
+ return created;
115
+ };
116
+ const updateStep = (stepId, patch) => {
117
+ if (!stepId)
118
+ return;
119
+ Object.assign(stepFor(stepId), patch);
120
+ };
121
+ switch (event.type) {
122
+ case "job.started":
123
+ return {
124
+ ...run,
125
+ status: "running",
126
+ started_at: run.started_at ?? event.timestamp,
127
+ events: [...run.events, event],
128
+ };
129
+ case "step.started":
130
+ updateStep(event.step_id, {
131
+ status: "running",
132
+ started_at: event.timestamp,
133
+ ...(event.input ? { input: event.input } : {}),
134
+ });
135
+ break;
136
+ case "step.completed":
137
+ updateStep(event.step_id, {
138
+ status: "succeeded",
139
+ finished_at: event.timestamp,
140
+ summary: event.message ?? null,
141
+ ...(event.output ? { output: event.output } : {}),
142
+ });
143
+ break;
144
+ case "step.failed":
145
+ updateStep(event.step_id, {
146
+ status: "failed",
147
+ finished_at: event.timestamp,
148
+ summary: event.message ?? null,
149
+ ...(event.output ? { output: event.output } : {}),
150
+ });
151
+ break;
152
+ case "job.completed":
153
+ return {
154
+ ...run,
155
+ status: "succeeded",
156
+ finished_at: run.finished_at ?? event.timestamp,
157
+ events: [...run.events, event],
158
+ };
159
+ case "job.failed":
160
+ return {
161
+ ...run,
162
+ status: "failed",
163
+ finished_at: run.finished_at ?? event.timestamp,
164
+ error: event.message ?? "Job failed.",
165
+ events: [...run.events, event],
166
+ };
167
+ case "artifact.written":
168
+ case "log.appended":
169
+ break;
170
+ default:
171
+ break;
172
+ }
173
+ return {
174
+ ...run,
175
+ events: [...run.events, event],
176
+ };
177
+ }
@@ -0,0 +1,47 @@
1
+ import { type CompileRun } from "../execution/lib/schema.js";
2
+ import { type RuntimeRun } from "../compiler/lib/schema.js";
3
+ import { type ActionProposalResource, type LocalJobRunResource, type TestRunResource } from "./lib/schema.js";
4
+ export declare function compileRunsRoot(compiledPath: string): string;
5
+ export declare function compileRunPath(compiledPath: string, runId: string): string;
6
+ export declare function testRunsRoot(compiledPath: string): string;
7
+ export declare function testRunPath(compiledPath: string, runId: string): string;
8
+ export declare function localJobsRoot(rootPath: string): string;
9
+ export declare function localJobPath(rootPath: string, runId: string): string;
10
+ export declare function actionProposalsRoot(rootPath: string): string;
11
+ export declare function actionProposalPath(rootPath: string, proposalId: string): string;
12
+ export declare function readJsonFile(filePath: string): unknown | null;
13
+ export declare function writeJsonFile(filePath: string, value: unknown): void;
14
+ export declare function readJsonOrNull<T>(filePath: string, schema: {
15
+ safeParse(value: unknown): {
16
+ success: true;
17
+ data: T;
18
+ } | {
19
+ success: false;
20
+ };
21
+ }): T | null;
22
+ export declare function listJsonFiles(dirPath: string): string[];
23
+ export declare function readCompileRunAt(filePath: string): CompileRun | null;
24
+ export declare function readTestRunAt(filePath: string): TestRunResource | null;
25
+ export declare function readLocalJobRunAt(filePath: string): LocalJobRunResource | null;
26
+ export declare function readActionProposalAt(filePath: string): ActionProposalResource | null;
27
+ /**
28
+ * Read the per-stage runtime-run history NDJSON. Each line is a `RuntimeRun`
29
+ * record; lines that fail to parse are silently skipped so the runtime can
30
+ * tolerate a partially-written tail without crashing.
31
+ */
32
+ export declare function readRuntimeRunHistory(compiledPath: string): RuntimeRun[];
33
+ /**
34
+ * Sort items newest-first using `started_at` (with a `finished_at` fallback).
35
+ * Used for compile/test run lists where the canonical order is by activity
36
+ * window, not by record-creation time.
37
+ */
38
+ export declare function newestFirst<T extends {
39
+ started_at?: string | null;
40
+ finished_at?: string | null;
41
+ }>(items: T[]): T[];
42
+ /** Sort items newest-first using their `created_at` timestamp. */
43
+ export declare function byCreatedAtDesc<T extends {
44
+ created_at: string;
45
+ }>(items: T[]): T[];
46
+ /** Parse an ISO timestamp into milliseconds; returns 0 for invalid input. */
47
+ export declare function timestampKey(value?: string | null): number;
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Filesystem and JSON persistence helpers for the local service runtime.
3
+ *
4
+ * These functions are pure: they take absolute paths and return values, with
5
+ * no shared state. Every other runtime module composes on top of this layer
6
+ * so the runtime coordinator stays small.
7
+ */
8
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, } from "node:fs";
9
+ import { dirname, join } from "node:path";
10
+ import { CompileRunSchema, } from "../execution/lib/schema.js";
11
+ import { compiledRuntimeRunHistoryPath, compiledRuntimeRoot, testRootForCompiled, } from "../compiler/compiled-paths.js";
12
+ import { RuntimeRunSchema, } from "../compiler/lib/schema.js";
13
+ import { asPreparationDataDir, preparationServiceActionProposalsRoot, preparationServiceJobsRoot, } from "../contracts/lib/preparation-paths.js";
14
+ import { ActionProposalResourceSchema, LocalJobRunResourceSchema, TestRunResourceSchema, } from "./lib/schema.js";
15
+ // ---- Path helpers --------------------------------------------------------
16
+ export function compileRunsRoot(compiledPath) {
17
+ return join(compiledRuntimeRoot(compiledPath), "compile-runs");
18
+ }
19
+ export function compileRunPath(compiledPath, runId) {
20
+ return join(compileRunsRoot(compiledPath), `${runId}.json`);
21
+ }
22
+ export function testRunsRoot(compiledPath) {
23
+ return join(testRootForCompiled(compiledPath), "service-runs");
24
+ }
25
+ export function testRunPath(compiledPath, runId) {
26
+ return join(testRunsRoot(compiledPath), `${runId}.json`);
27
+ }
28
+ export function localJobsRoot(rootPath) {
29
+ return preparationServiceJobsRoot(asPreparationDataDir(rootPath));
30
+ }
31
+ export function localJobPath(rootPath, runId) {
32
+ return join(localJobsRoot(rootPath), `${runId}.json`);
33
+ }
34
+ export function actionProposalsRoot(rootPath) {
35
+ return preparationServiceActionProposalsRoot(asPreparationDataDir(rootPath));
36
+ }
37
+ export function actionProposalPath(rootPath, proposalId) {
38
+ return join(actionProposalsRoot(rootPath), `${proposalId}.json`);
39
+ }
40
+ // ---- JSON IO -------------------------------------------------------------
41
+ export function readJsonFile(filePath) {
42
+ try {
43
+ return JSON.parse(readFileSync(filePath, "utf8"));
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ }
49
+ export function writeJsonFile(filePath, value) {
50
+ mkdirSync(dirname(filePath), { recursive: true });
51
+ writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
52
+ }
53
+ export function readJsonOrNull(filePath, schema) {
54
+ const raw = readJsonFile(filePath);
55
+ if (raw === null)
56
+ return null;
57
+ const parsed = schema.safeParse(raw);
58
+ return parsed.success ? parsed.data : null;
59
+ }
60
+ export function listJsonFiles(dirPath) {
61
+ if (!existsSync(dirPath))
62
+ return [];
63
+ try {
64
+ if (!statSync(dirPath).isDirectory())
65
+ return [];
66
+ }
67
+ catch {
68
+ return [];
69
+ }
70
+ return readdirSync(dirPath)
71
+ .filter((entry) => entry.endsWith(".json"))
72
+ .map((entry) => join(dirPath, entry));
73
+ }
74
+ // ---- Typed readers -------------------------------------------------------
75
+ export function readCompileRunAt(filePath) {
76
+ return readJsonOrNull(filePath, CompileRunSchema);
77
+ }
78
+ export function readTestRunAt(filePath) {
79
+ return readJsonOrNull(filePath, TestRunResourceSchema);
80
+ }
81
+ export function readLocalJobRunAt(filePath) {
82
+ return readJsonOrNull(filePath, LocalJobRunResourceSchema);
83
+ }
84
+ export function readActionProposalAt(filePath) {
85
+ return readJsonOrNull(filePath, ActionProposalResourceSchema);
86
+ }
87
+ /**
88
+ * Read the per-stage runtime-run history NDJSON. Each line is a `RuntimeRun`
89
+ * record; lines that fail to parse are silently skipped so the runtime can
90
+ * tolerate a partially-written tail without crashing.
91
+ */
92
+ export function readRuntimeRunHistory(compiledPath) {
93
+ const historyPath = compiledRuntimeRunHistoryPath(compiledPath);
94
+ if (!existsSync(historyPath))
95
+ return [];
96
+ try {
97
+ return readFileSync(historyPath, "utf8")
98
+ .split(/\r?\n/)
99
+ .map((line) => line.trim())
100
+ .filter((line) => line.length > 0)
101
+ .map((line) => {
102
+ try {
103
+ return RuntimeRunSchema.safeParse(JSON.parse(line));
104
+ }
105
+ catch {
106
+ return { success: false };
107
+ }
108
+ })
109
+ .filter((parsed) => parsed.success)
110
+ .map((parsed) => parsed.data);
111
+ }
112
+ catch {
113
+ return [];
114
+ }
115
+ }
116
+ // ---- Sort helpers --------------------------------------------------------
117
+ /**
118
+ * Sort items newest-first using `started_at` (with a `finished_at` fallback).
119
+ * Used for compile/test run lists where the canonical order is by activity
120
+ * window, not by record-creation time.
121
+ */
122
+ export function newestFirst(items) {
123
+ return [...items].sort((left, right) => {
124
+ const leftTime = Date.parse(left.started_at ?? left.finished_at ?? "");
125
+ const rightTime = Date.parse(right.started_at ?? right.finished_at ?? "");
126
+ return (Number.isFinite(rightTime) ? rightTime : 0) - (Number.isFinite(leftTime) ? leftTime : 0);
127
+ });
128
+ }
129
+ /** Sort items newest-first using their `created_at` timestamp. */
130
+ export function byCreatedAtDesc(items) {
131
+ return [...items].sort((left, right) => Date.parse(right.created_at) - Date.parse(left.created_at));
132
+ }
133
+ /** Parse an ISO timestamp into milliseconds; returns 0 for invalid input. */
134
+ export function timestampKey(value) {
135
+ const parsed = Date.parse(value ?? "");
136
+ return Number.isFinite(parsed) ? parsed : 0;
137
+ }
@@ -0,0 +1,35 @@
1
+ import { type SourcePreparationConfig } from "../project-model/lib/schema.js";
2
+ import { type ActionProposalPlanActionType, type ActionProposalResource } from "./lib/schema.js";
3
+ export declare const ACTION_PLANNER_CLARIFICATION_MESSAGE = "I can help with this Interf Workspace. Ask a question about Interf, or ask me to create a Preparation, prepare, check readiness, improve, or draft a Method and I will prepare an approval proposal.";
4
+ export type LocalTestMode = "source-files" | "compiled" | "both";
5
+ export declare function createActionProposalId(): string;
6
+ export declare function sanitizeActionProposalPlan(value: unknown): unknown;
7
+ export declare function configuredAgentName(): string | null;
8
+ export declare function detectedExecutorOptions(currentAgentName: string | null): {
9
+ name: string;
10
+ display_name: string;
11
+ command: string;
12
+ current: boolean;
13
+ }[];
14
+ export declare function slugFromText(value: string): string;
15
+ export declare function escapeRegExp(value: string): string;
16
+ export declare function stringValue(values: Record<string, unknown> | undefined, key: string): string | null;
17
+ export declare function actionTypeFromValues(values: Record<string, unknown> | undefined): ActionProposalPlanActionType | null;
18
+ export declare function directServiceEndpointForAction(actionType: ActionProposalPlanActionType): string | null;
19
+ export declare function numberValue(values: Record<string, unknown> | undefined, key: string): number | null;
20
+ export declare function testModeFromValues(values: Record<string, unknown> | undefined): LocalTestMode | null;
21
+ export declare function testModeValue(values: Record<string, unknown> | undefined, defaultMode?: LocalTestMode): LocalTestMode;
22
+ export declare function testModeCliTarget(mode: LocalTestMode): "source-files" | "portable-context" | "both";
23
+ export declare function methodIdForProposal(message: string, values: Record<string, unknown> | undefined): string;
24
+ export declare function actionValueMethodTaskPrompt(values: Record<string, unknown> | undefined): string | null;
25
+ export declare function normalizeMethodAuthoringText(value: string): string;
26
+ export declare function extractMethodAuthoringSection(value: string, label: string): string | null;
27
+ export declare function stripMethodCommandPrefix(value: string, methodId: string): string;
28
+ export declare function methodAuthoringPromptFallback(message: string, methodId: string): string;
29
+ export declare function methodAuthoringHintFromPrompt(prompt: string): string;
30
+ export declare function methodLabelFromId(methodId: string): string;
31
+ export declare function detachMethodFromPreparation(preparation: SourcePreparationConfig, methodId: string): SourcePreparationConfig;
32
+ export declare function requireSelectedMethod(preparation: SourcePreparationConfig): string;
33
+ export declare function actionCommandPreview(actionType: ActionProposalResource["action_type"], preparationName: string | null, methodId: string | null, values: Record<string, unknown> | undefined): string;
34
+ export declare function hasCompiledTestTarget(sourcePath: string, preparationConfig: SourcePreparationConfig): boolean;
35
+ export declare function actionAssistantMessage(actionType: ActionProposalResource["action_type"], preparationName: string | null, commandPreview: string): string;
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Pure helpers used by the runtime's action-proposal and method-authoring
3
+ * paths. None of these depend on runtime state — they shape strings, parse
4
+ * proposal values, and build CLI previews. Keeping them out of runtime.ts
5
+ * lets the coordinator stay small and means future tests can reach these
6
+ * helpers without booting a runtime.
7
+ */
8
+ import { existsSync } from "node:fs";
9
+ import { AGENTS, } from "../agents/lib/constants.js";
10
+ import { detectAgents, supportsAutomatedRuns, } from "../agents/lib/detection.js";
11
+ import { loadUserConfig, } from "../agents/lib/user-config.js";
12
+ import { asPreparationDataDir, preparationPortableContextPath, } from "../contracts/lib/preparation-paths.js";
13
+ import { DEFAULT_METHOD_ID, methodIdForSourcePreparationConfig, } from "../project-model/source-config.js";
14
+ import { createCompiledTestTarget, } from "../testing/test-targets.js";
15
+ import { methodAuthoringTaskPrompt, MethodAuthoringActionValuesSchema, } from "./action-values.js";
16
+ import { ActionProposalPlanActionTypeSchema, } from "./lib/schema.js";
17
+ export const ACTION_PLANNER_CLARIFICATION_MESSAGE = "I can help with this Interf Workspace. Ask a question about Interf, or ask me to create a Preparation, prepare, check readiness, improve, or draft a Method and I will prepare an approval proposal.";
18
+ export function createActionProposalId() {
19
+ return `action_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
20
+ }
21
+ export function sanitizeActionProposalPlan(value) {
22
+ if (!value || typeof value !== "object" || Array.isArray(value))
23
+ return value;
24
+ const plan = { ...value };
25
+ for (const key of ["preparation", "method", "title", "summary", "assistant_message", "command_preview"]) {
26
+ const current = plan[key];
27
+ if (current === null || current === undefined) {
28
+ delete plan[key];
29
+ continue;
30
+ }
31
+ if (typeof current === "string" && current.trim().length === 0) {
32
+ delete plan[key];
33
+ }
34
+ }
35
+ return plan;
36
+ }
37
+ export function configuredAgentName() {
38
+ const config = loadUserConfig();
39
+ if (!config)
40
+ return null;
41
+ const configured = AGENTS.find((agent) => agent.command === config.agentCommand) ??
42
+ AGENTS.find((agent) => agent.name === config.agent) ??
43
+ AGENTS.find((agent) => agent.displayName === config.agent);
44
+ return configured?.name ?? null;
45
+ }
46
+ export function detectedExecutorOptions(currentAgentName) {
47
+ return detectAgents()
48
+ .filter(supportsAutomatedRuns)
49
+ .map((agent) => ({
50
+ name: agent.name,
51
+ display_name: agent.displayName,
52
+ command: agent.command,
53
+ current: agent.name === currentAgentName,
54
+ }));
55
+ }
56
+ export function slugFromText(value) {
57
+ const slug = value
58
+ .toLowerCase()
59
+ .replace(/[^a-z0-9]+/g, "-")
60
+ .replace(/^-+|-+$/g, "")
61
+ .slice(0, 42)
62
+ .replace(/-+$/g, "");
63
+ return slug || "custom";
64
+ }
65
+ export function escapeRegExp(value) {
66
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
67
+ }
68
+ export function stringValue(values, key) {
69
+ const value = values?.[key];
70
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
71
+ }
72
+ export function actionTypeFromValues(values) {
73
+ const explicit = stringValue(values, "action_type") ?? stringValue(values, "service_action");
74
+ if (explicit) {
75
+ const parsed = ActionProposalPlanActionTypeSchema.safeParse(explicit);
76
+ if (parsed.success && parsed.data !== "clarification")
77
+ return parsed.data;
78
+ }
79
+ const action = stringValue(values, "action");
80
+ if (action === "compile" || action === "compile-run" || action === "run-preparation")
81
+ return "compile";
82
+ if (action === "test" || action === "check-readiness")
83
+ return "test";
84
+ if (action === "draft-readiness-checks" || action === "readiness-check-draft")
85
+ return "readiness-check-draft";
86
+ if (action === "create-method" || action === "method-authoring")
87
+ return "method-authoring";
88
+ if (action === "method-duplicate" || action === "method-remove" || action === "method-change")
89
+ return "method-change";
90
+ if (action === "preparation-remove" || action === "preparation-change")
91
+ return "preparation-change";
92
+ if (action === "improve-preparation" || action === "method-improvement")
93
+ return "method-improvement";
94
+ return null;
95
+ }
96
+ export function directServiceEndpointForAction(actionType) {
97
+ if (actionType === "preparation-setup")
98
+ return "/v1/preparation-setups";
99
+ if (actionType === "method-change")
100
+ return "/v1/method-changes";
101
+ if (actionType === "preparation-change")
102
+ return "/v1/preparation-changes";
103
+ return null;
104
+ }
105
+ export function numberValue(values, key) {
106
+ const value = values?.[key];
107
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
108
+ }
109
+ export function testModeFromValues(values) {
110
+ const value = stringValue(values, "mode") ?? stringValue(values, "target");
111
+ if (value === "portable-context")
112
+ return "compiled";
113
+ return value === "source-files" || value === "compiled" || value === "both" ? value : null;
114
+ }
115
+ export function testModeValue(values, defaultMode = "both") {
116
+ return testModeFromValues(values) ?? defaultMode;
117
+ }
118
+ export function testModeCliTarget(mode) {
119
+ if (mode === "source-files")
120
+ return "source-files";
121
+ if (mode === "compiled")
122
+ return "portable-context";
123
+ return "both";
124
+ }
125
+ export function methodIdForProposal(message, values) {
126
+ const explicit = stringValue(values, "method_id") ??
127
+ stringValue(values, "method");
128
+ const fromMessage = message.match(/\b(?:create|reate|eate|draft|author|build|make)\s+(?:a\s+new\s+)?(?:interf\s+)?method\s+([a-z0-9][a-z0-9-]{0,79})\b/i)?.[1];
129
+ return explicit ?? fromMessage ?? `custom-${slugFromText(message)}`;
130
+ }
131
+ export function actionValueMethodTaskPrompt(values) {
132
+ const parsed = MethodAuthoringActionValuesSchema.safeParse(values);
133
+ return parsed.success ? methodAuthoringTaskPrompt(parsed.data) : null;
134
+ }
135
+ const METHOD_AUTHORING_INTERNAL_INSTRUCTION = /Use the attached values as the Method authoring request before proposing the action\.?/gi;
136
+ const METHOD_AUTHORING_LABELS = [
137
+ "Agent work",
138
+ "Portable-context output",
139
+ "Readiness checks",
140
+ "CLI preview",
141
+ ];
142
+ export function normalizeMethodAuthoringText(value) {
143
+ return value
144
+ .replace(/[│]+/g, " ")
145
+ .replace(METHOD_AUTHORING_INTERNAL_INSTRUCTION, " ")
146
+ .replace(/\s+/g, " ")
147
+ .trim();
148
+ }
149
+ export function extractMethodAuthoringSection(value, label) {
150
+ const otherLabels = METHOD_AUTHORING_LABELS
151
+ .filter((candidate) => candidate !== label)
152
+ .map(escapeRegExp)
153
+ .join("|");
154
+ const match = value.match(new RegExp(`${escapeRegExp(label)}\\s*:\\s*([\\s\\S]*?)(?=\\s*(?:${otherLabels})\\s*:|$)`, "i"));
155
+ return match?.[1] ? normalizeMethodAuthoringText(match[1]) : null;
156
+ }
157
+ export function stripMethodCommandPrefix(value, methodId) {
158
+ const specific = new RegExp(`^(?:create|reate|eate|draft|author|build|make)\\s+(?:a\\s+new\\s+)?(?:interf\\s+)?method\\s+${escapeRegExp(methodId)}\\.?\\s*`, "i");
159
+ const generic = /^(?:create|reate|eate|draft|author|build|make)\s+(?:a\s+new\s+)?(?:interf\s+)?method\b[^.]{0,180}\.\s*/i;
160
+ const stripped = normalizeMethodAuthoringText(value)
161
+ .replace(specific, "")
162
+ .replace(generic, "")
163
+ .trim();
164
+ return stripped || normalizeMethodAuthoringText(value);
165
+ }
166
+ export function methodAuthoringPromptFallback(message, methodId) {
167
+ const cleaned = message
168
+ .replace(/[│]+/g, " ")
169
+ .replace(METHOD_AUTHORING_INTERNAL_INSTRUCTION, " ")
170
+ .trim();
171
+ const agentWork = extractMethodAuthoringSection(cleaned, "Agent work");
172
+ const portableOutput = extractMethodAuthoringSection(cleaned, "Portable-context output");
173
+ const readinessNotes = extractMethodAuthoringSection(cleaned, "Readiness checks");
174
+ const lines = [
175
+ agentWork ? `Agent work: ${stripMethodCommandPrefix(agentWork, methodId)}` : null,
176
+ portableOutput ? `Portable-context output: ${portableOutput}` : null,
177
+ readinessNotes ? `Readiness checks: ${readinessNotes}` : null,
178
+ ].filter((line) => Boolean(line));
179
+ if (lines.length > 0)
180
+ return lines.join("\n");
181
+ return stripMethodCommandPrefix(cleaned, methodId);
182
+ }
183
+ export function methodAuthoringHintFromPrompt(prompt) {
184
+ const plain = normalizeMethodAuthoringText(prompt.replace(/\b(?:Agent work|Portable-context output|Readiness checks)\s*:/gi, " "));
185
+ if (plain.length <= 180)
186
+ return plain || "Custom Method";
187
+ const clipped = plain.slice(0, 177).replace(/\s+\S*$/, "").trim();
188
+ return `${clipped || plain.slice(0, 177)}...`;
189
+ }
190
+ export function methodLabelFromId(methodId) {
191
+ return methodId
192
+ .split("-")
193
+ .filter(Boolean)
194
+ .map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
195
+ .join(" ") || methodId;
196
+ }
197
+ export function detachMethodFromPreparation(preparation, methodId) {
198
+ if (methodIdForSourcePreparationConfig(preparation) !== methodId)
199
+ return preparation;
200
+ const { method: _removedMethod, ...detachedPreparation } = preparation;
201
+ return detachedPreparation;
202
+ }
203
+ export function requireSelectedMethod(preparation) {
204
+ const methodId = methodIdForSourcePreparationConfig(preparation);
205
+ if (methodId)
206
+ return methodId;
207
+ throw new Error(`Select a Method for Preparation "${preparation.name}" before preparing it.`);
208
+ }
209
+ export function actionCommandPreview(actionType, preparationName, methodId, values) {
210
+ if (actionType === "compile") {
211
+ const methodSuffix = methodId ? ` # Method: ${methodId}` : "";
212
+ return preparationName
213
+ ? `interf compile --preparation ${preparationName}${methodSuffix}`
214
+ : `interf compile${methodSuffix}`;
215
+ }
216
+ if (actionType === "test") {
217
+ const mode = testModeCliTarget(testModeValue(values));
218
+ return preparationName
219
+ ? `interf test --preparation ${preparationName} --target ${mode}`
220
+ : `interf test --target ${mode}`;
221
+ }
222
+ if (actionType === "readiness-check-draft") {
223
+ return "interf # choose Auto-create readiness checks";
224
+ }
225
+ if (actionType === "method-authoring" || actionType === "method-improvement") {
226
+ return "interf create method";
227
+ }
228
+ return "Try: create a Preparation, prepare, check readiness, draft readiness checks, or draft a Method.";
229
+ }
230
+ export function hasCompiledTestTarget(sourcePath, preparationConfig) {
231
+ const compiledPath = preparationPortableContextPath(asPreparationDataDir(sourcePath), preparationConfig.name);
232
+ if (!existsSync(compiledPath))
233
+ return false;
234
+ return createCompiledTestTarget(compiledPath, preparationConfig.name, methodIdForSourcePreparationConfig(preparationConfig) ?? DEFAULT_METHOD_ID).eligible;
235
+ }
236
+ export function actionAssistantMessage(actionType, preparationName, commandPreview) {
237
+ const preparationSuffix = preparationName ? ` for Preparation "${preparationName}"` : "";
238
+ if (actionType === "compile") {
239
+ return `Interf prepared a compile-run proposal${preparationSuffix}. Approve to submit it through the local Interf service and watch the run in Interf. CLI equivalent: ${commandPreview}`;
240
+ }
241
+ if (actionType === "test") {
242
+ return `Interf prepared a readiness-check proposal${preparationSuffix}. Approve to run the requested target against saved readiness checks. CLI equivalent: ${commandPreview}`;
243
+ }
244
+ if (actionType === "readiness-check-draft") {
245
+ return `Interf prepared a proposal to draft readiness checks${preparationSuffix}. Approve to ask the configured local executor to draft saved checks as a visible run. CLI equivalent: ${commandPreview}`;
246
+ }
247
+ if (actionType === "method-authoring" || actionType === "method-improvement") {
248
+ return `Interf prepared a Method draft proposal${preparationSuffix}. Approve to draft a reusable local Method as a visible run. CLI equivalent: ${commandPreview}`;
249
+ }
250
+ return "I could not map that to a safe Interf action. Ask for one action in plain English, such as create a Preparation, prepare the data, check readiness, draft readiness checks, or draft a Method.";
251
+ }