@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.
Files changed (115) hide show
  1. package/README.md +92 -94
  2. package/dist/cli/commands/check-draft.js +4 -4
  3. package/dist/cli/commands/compile-controller.js +23 -23
  4. package/dist/cli/commands/compile.js +2 -2
  5. package/dist/cli/commands/compiled-flow.js +4 -4
  6. package/dist/cli/commands/create-workflow-wizard.js +8 -8
  7. package/dist/cli/commands/create.js +5 -5
  8. package/dist/cli/commands/default.js +1 -1
  9. package/dist/cli/commands/init.js +44 -44
  10. package/dist/cli/commands/list.js +2 -2
  11. package/dist/cli/commands/reset.js +1 -1
  12. package/dist/cli/commands/source-config-wizard.d.ts +1 -1
  13. package/dist/cli/commands/source-config-wizard.js +40 -40
  14. package/dist/cli/commands/status.js +5 -5
  15. package/dist/cli/commands/test-flow.js +26 -26
  16. package/dist/cli/commands/test.js +12 -12
  17. package/dist/lib/chart-guidance.d.ts +1 -1
  18. package/dist/lib/chart-guidance.js +1 -8
  19. package/dist/lib/discovery.d.ts +1 -7
  20. package/dist/lib/discovery.js +1 -84
  21. package/dist/lib/filesystem.d.ts +1 -2
  22. package/dist/lib/filesystem.js +1 -55
  23. package/dist/lib/logger.d.ts +1 -3
  24. package/dist/lib/logger.js +1 -10
  25. package/dist/lib/parse.d.ts +1 -8
  26. package/dist/lib/parse.js +1 -145
  27. package/dist/lib/util.d.ts +1 -4
  28. package/dist/lib/util.js +1 -25
  29. package/dist/packages/agents/index.d.ts +1 -0
  30. package/dist/packages/agents/index.js +1 -0
  31. package/dist/packages/agents/lib/chart-guidance.d.ts +1 -0
  32. package/dist/packages/agents/lib/chart-guidance.js +8 -0
  33. package/dist/packages/agents/lib/compiled-bootstrap.d.ts +3 -0
  34. package/dist/packages/agents/lib/compiled-bootstrap.js +18 -0
  35. package/dist/packages/agents/lib/executors.d.ts +2 -2
  36. package/dist/packages/agents/lib/shells.d.ts +3 -1
  37. package/dist/packages/agents/lib/shells.js +22 -20
  38. package/dist/packages/agents/lib/user-config.js +1 -1
  39. package/dist/packages/compiler/compiled-compile.d.ts +4 -48
  40. package/dist/packages/compiler/compiled-compile.js +4 -256
  41. package/dist/packages/compiler/compiled-paths.d.ts +40 -0
  42. package/dist/packages/compiler/compiled-paths.js +106 -0
  43. package/dist/packages/compiler/compiled-pipeline.d.ts +39 -0
  44. package/dist/packages/compiler/compiled-pipeline.js +134 -0
  45. package/dist/packages/compiler/compiled-schema.js +2 -2
  46. package/dist/packages/compiler/compiled-stage-plan.d.ts +15 -0
  47. package/dist/packages/compiler/compiled-stage-plan.js +79 -0
  48. package/dist/packages/compiler/compiled-stage-runner.d.ts +10 -0
  49. package/dist/packages/compiler/compiled-stage-runner.js +46 -0
  50. package/dist/packages/compiler/compiled-target.d.ts +11 -0
  51. package/dist/packages/compiler/compiled-target.js +16 -0
  52. package/dist/packages/compiler/discovery.d.ts +7 -0
  53. package/dist/packages/compiler/discovery.js +80 -0
  54. package/dist/packages/compiler/lib/schema.js +2 -0
  55. package/dist/packages/compiler/raw-snapshot.d.ts +49 -0
  56. package/dist/packages/compiler/raw-snapshot.js +102 -0
  57. package/dist/packages/compiler/reset.d.ts +2 -0
  58. package/dist/packages/compiler/reset.js +72 -0
  59. package/dist/packages/compiler/runtime-acceptance.js +3 -3
  60. package/dist/packages/compiler/runtime-contracts.js +1 -1
  61. package/dist/packages/compiler/runtime-paths.js +1 -1
  62. package/dist/packages/compiler/runtime-reconcile.js +3 -3
  63. package/dist/packages/compiler/runtime-runs.js +2 -2
  64. package/dist/packages/compiler/state-health.js +3 -3
  65. package/dist/packages/compiler/state-io.js +3 -3
  66. package/dist/packages/compiler/state-paths.js +1 -1
  67. package/dist/packages/compiler/state-view.js +2 -2
  68. package/dist/packages/compiler/validate-compiled.js +3 -3
  69. package/dist/packages/compiler/validate.js +4 -4
  70. package/dist/packages/project-model/compiled-paths.d.ts +1 -40
  71. package/dist/packages/project-model/compiled-paths.js +1 -106
  72. package/dist/packages/project-model/compiled-raw.d.ts +1 -49
  73. package/dist/packages/project-model/compiled-raw.js +1 -102
  74. package/dist/packages/project-model/compiled-reset.d.ts +1 -2
  75. package/dist/packages/project-model/compiled-reset.js +1 -72
  76. package/dist/packages/project-model/interf-bootstrap.d.ts +1 -3
  77. package/dist/packages/project-model/interf-bootstrap.js +1 -18
  78. package/dist/packages/project-model/interf-detect.js +4 -4
  79. package/dist/packages/project-model/interf-scaffold.js +7 -7
  80. package/dist/packages/project-model/source-config.js +6 -5
  81. package/dist/packages/shared/file-types.d.ts +1 -0
  82. package/dist/packages/shared/file-types.js +4 -0
  83. package/dist/packages/shared/filesystem.d.ts +2 -0
  84. package/dist/packages/shared/filesystem.js +55 -0
  85. package/dist/packages/shared/index.d.ts +7 -0
  86. package/dist/packages/shared/index.js +7 -0
  87. package/dist/packages/shared/logger.d.ts +3 -0
  88. package/dist/packages/shared/logger.js +10 -0
  89. package/dist/packages/shared/naming.d.ts +1 -0
  90. package/dist/packages/shared/naming.js +8 -0
  91. package/dist/packages/shared/parse.d.ts +8 -0
  92. package/dist/packages/shared/parse.js +145 -0
  93. package/dist/packages/shared/path-guards.d.ts +2 -0
  94. package/dist/packages/shared/path-guards.js +14 -0
  95. package/dist/packages/shared/util.d.ts +3 -0
  96. package/dist/packages/shared/util.js +3 -0
  97. package/dist/packages/testing/test-execution.js +3 -3
  98. package/dist/packages/testing/test-paths.js +1 -1
  99. package/dist/packages/testing/test-sandbox.js +3 -3
  100. package/dist/packages/testing/test-specs.js +1 -1
  101. package/dist/packages/workflow-authoring/workflow-authoring.js +5 -4
  102. package/dist/packages/workflow-authoring/workflow-improvement.js +6 -5
  103. package/dist/packages/workflow-package/builtin-compiled-workflow.js +1 -1
  104. package/dist/packages/workflow-package/context-interface.d.ts +96 -0
  105. package/dist/packages/workflow-package/context-interface.js +146 -0
  106. package/dist/packages/workflow-package/index.d.ts +2 -0
  107. package/dist/packages/workflow-package/index.js +2 -0
  108. package/dist/packages/workflow-package/interf-workflow-package.js +75 -28
  109. package/dist/packages/workflow-package/local-workflows.d.ts +5 -2
  110. package/dist/packages/workflow-package/local-workflows.js +15 -13
  111. package/dist/packages/workflow-package/workflow-definitions.d.ts +11 -7
  112. package/dist/packages/workflow-package/workflow-definitions.js +10 -3
  113. package/dist/packages/workflow-package/workflow-helpers.js +4 -4
  114. package/dist/packages/workflow-package/workflow-review-paths.js +1 -1
  115. package/package.json +3 -2
@@ -5,7 +5,7 @@ import { createRawTestTarget, createCompiledTestTarget, runTargetTestsAuto, save
5
5
  import { buildTestSpecFromSourceFolderConfig, buildTestSpecFromCompiledDatasetConfig, fingerprintTruthChecks, resolveSourceDatasetPath, } from "../../packages/project-model/source-config.js";
6
6
  import { datasetLatestTestStatePath, datasetLatestTestSummaryPath, normalizeDatasetTestRunId, datasetTestRunPath, datasetTestRunsRoot, datasetTestsRoot, } from "../../packages/project-model/project-paths.js";
7
7
  import { testRootForCompiled } from "../../packages/project-model/compiled-paths.js";
8
- import { readJsonFileWithSchema } from "../../lib/parse.js";
8
+ import { readJsonFileWithSchema } from "../../packages/shared/parse.js";
9
9
  import { TestRunComparisonSchema } from "../../packages/testing/lib/schema.js";
10
10
  import { resolveOrConfigureLocalExecutor } from "./executor-flow.js";
11
11
  import { findBuiltCompiledPath } from "./compiled-flow.js";
@@ -58,56 +58,56 @@ export function readCurrentSavedTestComparison(options) {
58
58
  }
59
59
  function renderLatestSummaryMarkdown(payload) {
60
60
  const lines = [
61
- "# Latest Test Result",
61
+ "# Latest Test Results",
62
62
  "",
63
- "| Target | Truth checks |",
63
+ "| Target | Questions |",
64
64
  "| --- | --- |",
65
65
  ];
66
66
  if (payload.raw) {
67
- lines.push(`| Files as-is | \`${payload.raw.passed_cases}/${payload.raw.total_cases}\` |`);
67
+ lines.push(`| Source files | \`${payload.raw.passed_cases}/${payload.raw.total_cases}\` |`);
68
68
  }
69
69
  if (payload.compiled) {
70
- lines.push(`| Context folder | \`${payload.compiled.passed_cases}/${payload.compiled.total_cases}\` |`);
70
+ lines.push(`| Portable context | \`${payload.compiled.passed_cases}/${payload.compiled.total_cases}\` |`);
71
71
  }
72
72
  lines.push("");
73
73
  if (payload.summary.raw_pass_rate != null && payload.summary.compiled_pass_rate != null) {
74
74
  const direction = (payload.summary.pass_rate_delta ?? 0) >= 0 ? "improved" : "decreased";
75
- lines.push(`Truth-check pass rate ${direction} from ${payload.summary.raw_pass_rate}% to ${payload.summary.compiled_pass_rate}%.`, "");
75
+ lines.push(`Question pass rate ${direction} from ${payload.summary.raw_pass_rate}% to ${payload.summary.compiled_pass_rate}%.`, "");
76
76
  }
77
77
  if (payload.raw) {
78
- lines.push(`- Latest files-as-is run: ${payload.raw.run_path}`);
78
+ lines.push(`- Latest source-files run: ${payload.raw.run_path}`);
79
79
  }
80
80
  if (payload.compiled) {
81
- lines.push(`- Latest compiled run: ${payload.compiled.run_path}`);
81
+ lines.push(`- Latest portable-context run: ${payload.compiled.run_path}`);
82
82
  }
83
83
  return `${lines.join("\n")}\n`;
84
84
  }
85
85
  export function printSavedTestComparisonState(payload, comparisonRunPath) {
86
86
  console.log();
87
- console.log(chalk.bold(" Latest saved test"));
87
+ console.log(chalk.bold(" Latest saved questions"));
88
88
  console.log();
89
- console.log(" | Target | Truth checks |");
89
+ console.log(" | Target | Questions |");
90
90
  console.log(" | --- | --- |");
91
91
  if (payload.raw) {
92
- console.log(` | Files as-is | \`${payload.raw.passed_cases}/${payload.raw.total_cases}\` |`);
92
+ console.log(` | Source files | \`${payload.raw.passed_cases}/${payload.raw.total_cases}\` |`);
93
93
  }
94
94
  if (payload.compiled) {
95
- console.log(` | Context folder | \`${payload.compiled.passed_cases}/${payload.compiled.total_cases}\` |`);
95
+ console.log(` | Portable context | \`${payload.compiled.passed_cases}/${payload.compiled.total_cases}\` |`);
96
96
  }
97
97
  if (!payload.raw || !payload.compiled) {
98
98
  console.log();
99
99
  if (!payload.raw) {
100
- console.log(chalk.dim(" No saved files-as-is baseline yet."));
100
+ console.log(chalk.dim(" No saved source-files baseline yet."));
101
101
  }
102
102
  if (!payload.compiled) {
103
- console.log(chalk.dim(" No saved compiled-context run yet."));
103
+ console.log(chalk.dim(" No saved portable-context run yet."));
104
104
  }
105
105
  }
106
106
  if (payload.summary.raw_pass_rate != null && payload.summary.compiled_pass_rate != null) {
107
107
  const direction = (payload.summary.pass_rate_delta ?? 0) >= 0 ? "improved" : "decreased";
108
108
  const color = (payload.summary.pass_rate_delta ?? 0) >= 0 ? chalk.green : chalk.red;
109
109
  console.log();
110
- console.log(color(` Truth-check pass rate ${direction} from ${payload.summary.raw_pass_rate}% to ${payload.summary.compiled_pass_rate}%.`));
110
+ console.log(color(` Question pass rate ${direction} from ${payload.summary.raw_pass_rate}% to ${payload.summary.compiled_pass_rate}%.`));
111
111
  }
112
112
  if (comparisonRunPath) {
113
113
  console.log();
@@ -136,7 +136,7 @@ export function printAgentTestMatrix(rows) {
136
136
  const includeDelta = includeRaw && includeCompiled;
137
137
  const headers = [
138
138
  "Agent",
139
- ...(includeRaw ? ["Files as-is"] : []),
139
+ ...(includeRaw ? ["Source files"] : []),
140
140
  ...(includeCompiled ? ["Context folder"] : []),
141
141
  ...(includeDelta ? ["Delta"] : []),
142
142
  ];
@@ -161,7 +161,7 @@ export function printAgentTestFailures(rows) {
161
161
  for (const row of rows) {
162
162
  const failures = [];
163
163
  for (const [label, outcome] of [
164
- ["Files as-is", row.rawOutcome ?? null],
164
+ ["Source files", row.rawOutcome ?? null],
165
165
  ["Context folder", row.compiledOutcome ?? null],
166
166
  ]) {
167
167
  if (!outcome || outcome.result.ok)
@@ -170,7 +170,7 @@ export function printAgentTestFailures(rows) {
170
170
  if (caseResult.ok)
171
171
  continue;
172
172
  const reason = caseResult.checks.find((entry) => !entry.ok)?.detail ?? "failed";
173
- failures.push(`${label} · Truth Check ${index + 1}: ${reason}`);
173
+ failures.push(`${label} · Question ${index + 1}: ${reason}`);
174
174
  }
175
175
  }
176
176
  if (failures.length === 0)
@@ -204,11 +204,11 @@ export function printSavedTestOutcome(prefix, outcome) {
204
204
  const status = outcome.result.ok ? chalk.green("PASS") : chalk.red("FAIL");
205
205
  console.log(chalk.bold(` ${prefix}`));
206
206
  console.log();
207
- console.log(color(` ${status} ${outcome.result.passedCases}/${outcome.result.totalCases} questions`));
207
+ console.log(color(` ${status} ${outcome.result.passedCases}/${outcome.result.totalCases} tests`));
208
208
  console.log();
209
209
  for (const [index, caseResult] of outcome.result.caseResults.entries()) {
210
210
  const caseStatus = caseResult.ok ? chalk.green("PASS") : chalk.red("FAIL");
211
- console.log(` ${caseStatus} Truth Check ${index + 1}`);
211
+ console.log(` ${caseStatus} Question ${index + 1}`);
212
212
  console.log(chalk.dim(` ${caseResult.question}`));
213
213
  const failedChecks = caseResult.checks.filter((entry) => !entry.ok).slice(0, 3);
214
214
  for (const failedCheck of failedChecks) {
@@ -227,7 +227,7 @@ export function printSavedTestComparison(rawOutcome, compiledOutcome, comparison
227
227
  return;
228
228
  console.log();
229
229
  if (rawOutcome) {
230
- printSavedTestOutcome("Files as-is", rawOutcome);
230
+ printSavedTestOutcome("Source files", rawOutcome);
231
231
  }
232
232
  if (compiledOutcome) {
233
233
  if (rawOutcome)
@@ -241,7 +241,7 @@ export function printSavedTestComparison(rawOutcome, compiledOutcome, comparison
241
241
  const color = delta >= 0 ? chalk.green : chalk.red;
242
242
  const direction = delta >= 0 ? "improved" : "decreased";
243
243
  console.log();
244
- console.log(color(` Truth-check pass rate ${direction} from ${rawQuestions}% to ${compiledQuestions}%.`));
244
+ console.log(color(` Question pass rate ${direction} from ${rawQuestions}% to ${compiledQuestions}%.`));
245
245
  }
246
246
  if (comparisonRunPath) {
247
247
  console.log();
@@ -254,10 +254,10 @@ export function printSavedTestComparisonSummary(rawOutcome, compiledOutcome, com
254
254
  console.log();
255
255
  console.log(chalk.bold(" Comparison"));
256
256
  console.log();
257
- console.log(" | Target | Truth checks |");
257
+ console.log(" | Target | Questions |");
258
258
  console.log(" | --- | --- |");
259
259
  if (rawOutcome) {
260
- console.log(` | Files as-is | \`${rawOutcome.result.passedCases}/${rawOutcome.result.totalCases}\` |`);
260
+ console.log(` | Source files | \`${rawOutcome.result.passedCases}/${rawOutcome.result.totalCases}\` |`);
261
261
  }
262
262
  if (compiledOutcome) {
263
263
  console.log(` | Context folder | \`${compiledOutcome.result.passedCases}/${compiledOutcome.result.totalCases}\` |`);
@@ -269,7 +269,7 @@ export function printSavedTestComparisonSummary(rawOutcome, compiledOutcome, com
269
269
  const color = delta >= 0 ? chalk.green : chalk.red;
270
270
  const direction = delta >= 0 ? "improved" : "decreased";
271
271
  console.log();
272
- console.log(color(` Truth-check pass rate ${direction} from ${rawQuestions}% to ${compiledQuestions}%.`));
272
+ console.log(color(` Question pass rate ${direction} from ${rawQuestions}% to ${compiledQuestions}%.`));
273
273
  }
274
274
  if (comparisonRunPath) {
275
275
  console.log();
@@ -279,7 +279,7 @@ export function printSavedTestComparisonSummary(rawOutcome, compiledOutcome, com
279
279
  export function saveTestComparisonRun(options) {
280
280
  const generatedAt = new Date().toISOString();
281
281
  const rawSummary = options.rawOutcome
282
- ? summarizeSavedTestOutcome("Files as-is", options.rawOutcome)
282
+ ? summarizeSavedTestOutcome("Source files", options.rawOutcome)
283
283
  : null;
284
284
  const compiledSummary = options.compiledOutcome
285
285
  ? summarizeSavedTestOutcome("Context folder", options.compiledOutcome)
@@ -9,7 +9,7 @@ import { printAgentTestFailures, printAgentTestMatrix, printSavedTestComparisonS
9
9
  import { listRunAgentOptions, promptForTestAgents, resolveNamedLocalExecutor, resolveOrConfigureLocalExecutor, } from "./executor-flow.js";
10
10
  export const testCommand = {
11
11
  command: "test",
12
- describe: "Compare files as-is and a compiled context on checks",
12
+ describe: "Compare source files and the portable context your agents would use on saved questions",
13
13
  builder: (yargs) => addExecutionProfileOptions(yargs)
14
14
  .option("dataset", {
15
15
  type: "string",
@@ -17,7 +17,7 @@ export const testCommand = {
17
17
  })
18
18
  .option("target", {
19
19
  choices: ["both", "raw", "compiled"],
20
- describe: "Test files as-is, the compiled context, or both. Default: both when a compiled context exists, otherwise files as-is.",
20
+ describe: "Test source files, the portable context your agents would use, or both. Default: both when portable context exists, otherwise source files.",
21
21
  })
22
22
  .option("keep-sandboxes", {
23
23
  type: "boolean",
@@ -49,18 +49,18 @@ async function promptTestMode(hasBuiltCompiled) {
49
49
  options: [
50
50
  {
51
51
  value: "both",
52
- label: "Compare files-as-is and compiled context (Recommended)",
53
- hint: "Measure whether compilation helps on the checks",
52
+ label: "Compare source files and the portable context your agents would use (Recommended)",
53
+ hint: "Measure whether the portable context helps your agents on the saved questions",
54
54
  },
55
55
  {
56
56
  value: "raw",
57
- label: "Files-as-is only",
57
+ label: "Source files only",
58
58
  hint: "Measure the current baseline on the dataset files",
59
59
  },
60
60
  {
61
61
  value: "compiled",
62
- label: "Compiled context only",
63
- hint: "Measure the current compiled context on the checks",
62
+ label: "Portable context only",
63
+ hint: "Measure the current portable context for your agents on the saved questions",
64
64
  },
65
65
  ],
66
66
  });
@@ -221,8 +221,8 @@ export async function runTestCommand(argv = {}) {
221
221
  }
222
222
  if (selectedCompiled.checks.length === 0) {
223
223
  process.exitCode = 1;
224
- console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have any checks yet.`));
225
- console.log(chalk.dim(" Run `interf`, edit this setup, and add a few checks first."));
224
+ console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have any questions yet.`));
225
+ console.log(chalk.dim(" Run `interf`, edit this setup, and add a few questions first."));
226
226
  console.log(chalk.dim(" Then rerun `interf test`."));
227
227
  return false;
228
228
  }
@@ -240,13 +240,13 @@ export async function runTestCommand(argv = {}) {
240
240
  return false;
241
241
  if (selectedMode === "compiled" && !hasBuiltCompiled) {
242
242
  process.exitCode = 1;
243
- console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have a context folder yet.`));
243
+ console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have portable context for your agents yet.`));
244
244
  console.log(chalk.dim(" Run `interf compile` first."));
245
245
  return false;
246
246
  }
247
247
  if (selectedMode === "both" && !hasBuiltCompiled) {
248
248
  process.exitCode = 1;
249
- console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have a context folder yet, so Interf cannot compare files-as-is and the context folder.`));
249
+ console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have portable context for your agents yet, so Interf cannot compare source files and the portable context your agents would use.`));
250
250
  console.log(chalk.dim(" Run `interf compile` first, or rerun with `--target raw`."));
251
251
  return false;
252
252
  }
@@ -268,7 +268,7 @@ export async function runTestCommand(argv = {}) {
268
268
  })));
269
269
  if ((mode === "compiled" || mode === "both") && rows.some((row) => !row.compiledOutcome)) {
270
270
  process.exitCode = 1;
271
- console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have a context folder yet.`));
271
+ console.log(chalk.red(` Setup "${selectedCompiled.name}" does not have portable context for your agents yet.`));
272
272
  console.log(chalk.dim(" Run `interf compile` first."));
273
273
  return false;
274
274
  }
@@ -1 +1 @@
1
- export declare const CHART_APPROXIMATION_NOTES: readonly ["When a chart-derived value is approximate, use a bounded range instead of a pseudo-exact number.", "Match the granularity of the visible axis labels or bands. Do not invent finer precision than the chart supports.", "Keep the answer inside the visible tick band unless the chart supports a tighter bound.", "Use an upper-half or lower-half band only when the mark clearly sits there.", "If a mark touches or nearly touches a labeled gridline, anchor the answer at that gridline or the immediately adjacent half-band.", "Do not widen a chart-derived range across multiple visible bands unless the chart genuinely supports that uncertainty."];
1
+ export * from "../packages/agents/lib/chart-guidance.js";
@@ -1,8 +1 @@
1
- export const CHART_APPROXIMATION_NOTES = [
2
- "When a chart-derived value is approximate, use a bounded range instead of a pseudo-exact number.",
3
- "Match the granularity of the visible axis labels or bands. Do not invent finer precision than the chart supports.",
4
- "Keep the answer inside the visible tick band unless the chart supports a tighter bound.",
5
- "Use an upper-half or lower-half band only when the mark clearly sits there.",
6
- "If a mark touches or nearly touches a labeled gridline, anchor the answer at that gridline or the immediately adjacent half-band.",
7
- "Do not widen a chart-derived range across multiple visible bands unless the chart genuinely supports that uncertainty.",
8
- ];
1
+ export * from "../packages/agents/lib/chart-guidance.js";
@@ -1,7 +1 @@
1
- export interface DiscoveryResult {
2
- sourceFiles: string[];
3
- totalCount: number;
4
- ignoredCount: number;
5
- }
6
- export declare function discoverSourceFiles(sourcePath: string, compiledPath: string): DiscoveryResult;
7
- export declare function loadIgnorePatterns(compiledPath: string): string[];
1
+ export * from "../packages/compiler/discovery.js";
@@ -1,84 +1 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { join, relative } from "node:path";
3
- import { listFilesRecursive } from "./filesystem.js";
4
- const DEFAULT_IGNORE_DIRS = new Set([
5
- "interf",
6
- ".interf",
7
- ".git",
8
- ".obsidian",
9
- ".claude",
10
- "node_modules",
11
- ]);
12
- const DEFAULT_IGNORE_FILES = new Set([
13
- "interf.json",
14
- ]);
15
- export function discoverSourceFiles(sourcePath, compiledPath) {
16
- const userPatterns = loadIgnorePatterns(compiledPath);
17
- let ignoredCount = 0;
18
- const allFiles = listFilesRecursive(sourcePath, (filePath) => {
19
- const rel = relative(sourcePath, filePath);
20
- if (isIgnored(rel)) {
21
- ignoredCount++;
22
- return false;
23
- }
24
- if (userPatterns.length > 0 && matchesUserPattern(rel, userPatterns)) {
25
- ignoredCount++;
26
- return false;
27
- }
28
- return true;
29
- });
30
- const sourceFiles = allFiles
31
- .map((f) => relative(sourcePath, f))
32
- .sort((a, b) => a.localeCompare(b));
33
- return {
34
- sourceFiles,
35
- totalCount: sourceFiles.length,
36
- ignoredCount,
37
- };
38
- }
39
- export function loadIgnorePatterns(compiledPath) {
40
- const ignorePath = join(compiledPath, ".interfignore");
41
- if (!existsSync(ignorePath))
42
- return [];
43
- return readFileSync(ignorePath, "utf-8")
44
- .split("\n")
45
- .map((line) => line.trim())
46
- .filter((line) => line.length > 0 && !line.startsWith("#"));
47
- }
48
- function isIgnored(relativePath) {
49
- if (DEFAULT_IGNORE_FILES.has(relativePath))
50
- return true;
51
- const segments = relativePath.split("/");
52
- for (const segment of segments) {
53
- if (segment.startsWith("."))
54
- return true;
55
- if (DEFAULT_IGNORE_DIRS.has(segment))
56
- return true;
57
- }
58
- return false;
59
- }
60
- function matchesUserPattern(relativePath, patterns) {
61
- for (const pattern of patterns) {
62
- if (matchGlob(relativePath, pattern))
63
- return true;
64
- }
65
- return false;
66
- }
67
- function matchGlob(path, pattern) {
68
- // Exact directory match: "build/" matches "build/..." or "sub/build/..."
69
- if (pattern.endsWith("/")) {
70
- const dir = pattern.slice(0, -1);
71
- return path === dir || path.startsWith(dir + "/") || path.includes("/" + dir + "/");
72
- }
73
- // Extension match: "*.log" matches any file ending in .log
74
- if (pattern.startsWith("*.")) {
75
- return path.endsWith(pattern.slice(1));
76
- }
77
- // Exact filename match: ".env" matches ".env" at any depth
78
- if (!pattern.includes("/") && !pattern.includes("*")) {
79
- const filename = path.split("/").pop() ?? "";
80
- return filename === pattern;
81
- }
82
- // Prefix match: "dist/foo" matches "dist/foo" and "dist/foo/bar"
83
- return path === pattern || path.startsWith(pattern + "/");
84
- }
1
+ export * from "../packages/compiler/discovery.js";
@@ -1,2 +1 @@
1
- export declare function countFilesRecursive(dirPath: string): number;
2
- export declare function listFilesRecursive(dirPath: string, predicate?: (filePath: string) => boolean): string[];
1
+ export * from "../packages/shared/filesystem.js";
@@ -1,55 +1 @@
1
- import { existsSync, readdirSync, realpathSync, statSync } from "node:fs";
2
- import { join } from "node:path";
3
- export function countFilesRecursive(dirPath) {
4
- if (!existsSync(dirPath))
5
- return 0;
6
- let total = 0;
7
- walkFilesRecursive(dirPath, () => {
8
- total += 1;
9
- });
10
- return total;
11
- }
12
- export function listFilesRecursive(dirPath, predicate) {
13
- const files = [];
14
- if (!existsSync(dirPath))
15
- return files;
16
- walkFilesRecursive(dirPath, (filePath) => {
17
- if (!predicate || predicate(filePath)) {
18
- files.push(filePath);
19
- }
20
- });
21
- return files;
22
- }
23
- function walkFilesRecursive(dirPath, onFile, visitedDirs = new Set()) {
24
- if (!existsSync(dirPath))
25
- return;
26
- walkFilesRecursiveInternal(dirPath, onFile, visitedDirs);
27
- }
28
- function walkFilesRecursiveInternal(dirPath, onFile, visitedDirs) {
29
- let resolvedDir;
30
- try {
31
- resolvedDir = realpathSync(dirPath);
32
- }
33
- catch {
34
- return;
35
- }
36
- if (visitedDirs.has(resolvedDir))
37
- return;
38
- visitedDirs.add(resolvedDir);
39
- for (const entry of readdirSync(dirPath)) {
40
- const fullPath = join(dirPath, entry);
41
- let stat;
42
- try {
43
- stat = statSync(fullPath);
44
- }
45
- catch {
46
- continue;
47
- }
48
- if (stat.isDirectory()) {
49
- walkFilesRecursiveInternal(fullPath, onFile, visitedDirs);
50
- }
51
- else if (stat.isFile()) {
52
- onFile(fullPath);
53
- }
54
- }
55
- }
1
+ export * from "../packages/shared/filesystem.js";
@@ -1,3 +1 @@
1
- export type InterfWarningHandler = (message: string) => void;
2
- export declare function setInterfWarningHandler(handler?: InterfWarningHandler): void;
3
- export declare function warnInterf(message: string): void;
1
+ export * from "../packages/shared/logger.js";
@@ -1,10 +1 @@
1
- const defaultWarningHandler = (message) => {
2
- console.warn(message);
3
- };
4
- let currentWarningHandler = defaultWarningHandler;
5
- export function setInterfWarningHandler(handler) {
6
- currentWarningHandler = handler ?? defaultWarningHandler;
7
- }
8
- export function warnInterf(message) {
9
- currentWarningHandler(message);
10
- }
1
+ export * from "../packages/shared/logger.js";
@@ -1,8 +1 @@
1
- import type { ZodType } from "zod";
2
- export declare function readJsonFileUnchecked<T>(filePath: string, label: string): T | null;
3
- export declare function readJsonFileWithSchema<T>(filePath: string, label: string, schema: ZodType<T>): T | null;
4
- export declare function renderJsonFrontmatter(frontmatter: Record<string, unknown>): string;
5
- export declare function parseJsonFrontmatter(content: string): {
6
- frontmatter: Record<string, unknown>;
7
- body: string;
8
- } | null;
1
+ export * from "../packages/shared/parse.js";
package/dist/lib/parse.js CHANGED
@@ -1,145 +1 @@
1
- import { readFileSync } from "node:fs";
2
- import { warnInterf } from "./logger.js";
3
- function formatError(error) {
4
- return error instanceof Error ? error.message : String(error);
5
- }
6
- export function readJsonFileUnchecked(filePath, label) {
7
- try {
8
- return JSON.parse(readFileSync(filePath, "utf-8"));
9
- }
10
- catch (error) {
11
- warnInterf(`Warning: failed to parse ${label} at ${filePath}: ${formatError(error)}`);
12
- return null;
13
- }
14
- }
15
- export function readJsonFileWithSchema(filePath, label, schema) {
16
- const raw = readJsonFileUnchecked(filePath, label);
17
- if (raw === null)
18
- return null;
19
- const parsed = schema.safeParse(raw);
20
- if (!parsed.success) {
21
- warnInterf(`Warning: failed to validate ${label} at ${filePath}: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`);
22
- return null;
23
- }
24
- return parsed.data;
25
- }
26
- export function renderJsonFrontmatter(frontmatter) {
27
- return [
28
- "---",
29
- JSON.stringify(frontmatter, null, 2),
30
- "---",
31
- ].join("\n");
32
- }
33
- function parseQuotedString(value) {
34
- if (value.length < 2)
35
- return null;
36
- const quote = value[0];
37
- if ((quote !== "\"" && quote !== "'") || value[value.length - 1] !== quote)
38
- return null;
39
- const inner = value.slice(1, -1);
40
- if (quote === "\"") {
41
- try {
42
- return JSON.parse(value);
43
- }
44
- catch {
45
- return null;
46
- }
47
- }
48
- return inner.replace(/\\'/g, "'");
49
- }
50
- function parseYamlScalar(value) {
51
- const trimmed = value.trim();
52
- if (trimmed.length === 0)
53
- return "";
54
- const quoted = parseQuotedString(trimmed);
55
- if (quoted !== null)
56
- return quoted;
57
- if (trimmed === "true")
58
- return true;
59
- if (trimmed === "false")
60
- return false;
61
- if (trimmed === "null")
62
- return null;
63
- if (/^-?\d+(?:\.\d+)?$/.test(trimmed))
64
- return Number(trimmed);
65
- if ((trimmed.startsWith("[") && trimmed.endsWith("]"))
66
- || (trimmed.startsWith("{") && trimmed.endsWith("}"))) {
67
- try {
68
- return JSON.parse(trimmed);
69
- }
70
- catch {
71
- return trimmed;
72
- }
73
- }
74
- return trimmed;
75
- }
76
- function parseYamlFrontmatter(frontmatterText) {
77
- const lines = frontmatterText.split("\n");
78
- const frontmatter = {};
79
- for (let index = 0; index < lines.length; index += 1) {
80
- const line = lines[index] ?? "";
81
- const trimmed = line.trim();
82
- if (trimmed.length === 0 || trimmed.startsWith("#"))
83
- continue;
84
- const match = line.match(/^([A-Za-z0-9_-]+):(?:\s+(.*))?$/);
85
- if (!match)
86
- return null;
87
- const [, key, inlineValue] = match;
88
- if (!key)
89
- return null;
90
- if (inlineValue && inlineValue.trim().length > 0) {
91
- frontmatter[key] = parseYamlScalar(inlineValue);
92
- continue;
93
- }
94
- const items = [];
95
- let cursor = index + 1;
96
- while (cursor < lines.length) {
97
- const nextLine = lines[cursor] ?? "";
98
- const nextTrimmed = nextLine.trim();
99
- if (nextTrimmed.length === 0) {
100
- cursor += 1;
101
- continue;
102
- }
103
- const itemMatch = nextLine.match(/^\s*-\s+(.*)$/);
104
- if (!itemMatch || !/^\s+/.test(nextLine))
105
- break;
106
- items.push(parseYamlScalar(itemMatch[1] ?? ""));
107
- cursor += 1;
108
- }
109
- if (items.length > 0) {
110
- frontmatter[key] = items;
111
- index = cursor - 1;
112
- continue;
113
- }
114
- frontmatter[key] = "";
115
- }
116
- return Object.keys(frontmatter).length > 0 ? frontmatter : null;
117
- }
118
- export function parseJsonFrontmatter(content) {
119
- const normalized = content.replace(/\r\n/g, "\n");
120
- const match = normalized.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
121
- if (!match)
122
- return null;
123
- const [, frontmatterText, body = ""] = match;
124
- if (frontmatterText === undefined)
125
- return null;
126
- try {
127
- const frontmatter = JSON.parse(frontmatterText);
128
- if (!frontmatter || typeof frontmatter !== "object" || Array.isArray(frontmatter)) {
129
- return null;
130
- }
131
- return {
132
- frontmatter: frontmatter,
133
- body,
134
- };
135
- }
136
- catch {
137
- const frontmatter = parseYamlFrontmatter(frontmatterText);
138
- if (!frontmatter)
139
- return null;
140
- return {
141
- frontmatter,
142
- body,
143
- };
144
- }
145
- }
1
+ export * from "../packages/shared/parse.js";
@@ -1,4 +1 @@
1
- export declare function slugify(input: string): string;
2
- export declare function isMarkdownFile(filePath: string): boolean;
3
- export declare function isPathWithinRoot(rootPath: string, candidatePath: string): boolean;
4
- export declare function assertPathWithinRoot(rootPath: string, candidatePath: string, label: string): string;
1
+ export * from "../packages/shared/util.js";
package/dist/lib/util.js CHANGED
@@ -1,25 +1 @@
1
- import { extname, isAbsolute, relative, resolve, sep } from "node:path";
2
- export function slugify(input) {
3
- return input
4
- .toLowerCase()
5
- .trim()
6
- .replace(/[^a-z0-9]+/g, "-")
7
- .replace(/^-+|-+$/g, "")
8
- .slice(0, 80);
9
- }
10
- export function isMarkdownFile(filePath) {
11
- return extname(filePath).toLowerCase() === ".md";
12
- }
13
- export function isPathWithinRoot(rootPath, candidatePath) {
14
- const root = resolve(rootPath);
15
- const candidate = resolve(candidatePath);
16
- const relativePath = relative(root, candidate);
17
- return relativePath === "" || (!isAbsolute(relativePath) && relativePath !== ".." && !relativePath.startsWith(`..${sep}`));
18
- }
19
- export function assertPathWithinRoot(rootPath, candidatePath, label) {
20
- const resolvedPath = resolve(candidatePath);
21
- if (!isPathWithinRoot(rootPath, resolvedPath)) {
22
- throw new Error(`${label} must stay inside ${resolve(rootPath)}: ${resolvedPath}`);
23
- }
24
- return resolvedPath;
25
- }
1
+ export * from "../packages/shared/util.js";
@@ -13,5 +13,6 @@ export * as executionProfile from "./lib/execution-profile.js";
13
13
  export * as executors from "./lib/executors.js";
14
14
  export * as schema from "./lib/schema.js";
15
15
  export * as userConfig from "./lib/user-config.js";
16
+ export * as compiledBootstrap from "./lib/compiled-bootstrap.js";
16
17
  export type { Agent, } from "./lib/types.js";
17
18
  export type { WorkflowExecutionProfile, WorkflowExecutor, WorkflowExecutorKind, } from "./lib/executors.js";
@@ -13,3 +13,4 @@ export * as executionProfile from "./lib/execution-profile.js";
13
13
  export * as executors from "./lib/executors.js";
14
14
  export * as schema from "./lib/schema.js";
15
15
  export * as userConfig from "./lib/user-config.js";
16
+ export * as compiledBootstrap from "./lib/compiled-bootstrap.js";
@@ -0,0 +1 @@
1
+ export declare const CHART_APPROXIMATION_NOTES: readonly ["When a chart-derived value is approximate, use a bounded range instead of a pseudo-exact number.", "Match the granularity of the visible axis labels or bands. Do not invent finer precision than the chart supports.", "Keep the answer inside the visible tick band unless the chart supports a tighter bound.", "Use an upper-half or lower-half band only when the mark clearly sits there.", "If a mark touches or nearly touches a labeled gridline, anchor the answer at that gridline or the immediately adjacent half-band.", "Do not widen a chart-derived range across multiple visible bands unless the chart genuinely supports that uncertainty."];
@@ -0,0 +1,8 @@
1
+ export const CHART_APPROXIMATION_NOTES = [
2
+ "When a chart-derived value is approximate, use a bounded range instead of a pseudo-exact number.",
3
+ "Match the granularity of the visible axis labels or bands. Do not invent finer precision than the chart supports.",
4
+ "Keep the answer inside the visible tick band unless the chart supports a tighter bound.",
5
+ "Use an upper-half or lower-half band only when the mark clearly sits there.",
6
+ "If a mark touches or nearly touches a labeled gridline, anchor the answer at that gridline or the immediately adjacent half-band.",
7
+ "Do not widen a chart-derived range across multiple visible bands unless the chart genuinely supports that uncertainty.",
8
+ ];