adfinem 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1,13 @@
1
+ ADFINEM_ENV=local
2
+ ADFINEM_API_BASE_URL=https://example-api
3
+ ADFINEM_API_TLS_INSECURE=false
4
+ # raw is useful while developing; set redacted before sharing evidence.
5
+ ADFINEM_EVIDENCE_VISIBILITY=raw
6
+ ADFINEM_DB_USER=
7
+ ADFINEM_DB_PASSWORD=
8
+ ADFINEM_DB_CONNECT_STRING=
9
+ ADFINEM_SSH_USER=
10
+ ADFINEM_SSH_PASSWORD=
11
+ ADFINEM_SSH_PRIVATE_KEY_PATH=
12
+ ADFINEM_SSH_QA_WORKER_HOST=
13
+ ADFINEM_BATCH_WORKDIR=
package/CHANGELOG.md CHANGED
@@ -1,10 +1,17 @@
1
- # Changelog
2
-
3
- All notable changes to Adfinem are documented here.
4
-
5
- ## [0.1.0] - 2026-06-06
6
-
7
- - Publish the initial open-source Adfinem snapshot.
8
- - Include catalog-gated API, database, Unix batch, and flow automation.
9
- - Include smoke scenarios, sample flows, a React workbench, and compiled CLI output.
10
- - Add npm package metadata and publication safeguards.
1
+ # Changelog
2
+
3
+ All notable changes to Adfinem are documented here.
4
+
5
+ ## [0.1.1] - 2026-06-06
6
+
7
+ - Add `adfinem init` to create a starter project from the global package.
8
+ - Add `adfinem app` to launch the web workbench from a global install.
9
+ - Make CLI commands resolve catalogs, config, evidence, flows, and scenarios from the current project directory.
10
+ - Include built web assets and `.env.example` in the npm package.
11
+
12
+ ## [0.1.0] - 2026-06-06
13
+
14
+ - Publish the initial open-source Adfinem snapshot.
15
+ - Include catalog-gated API, database, Unix batch, and flow automation.
16
+ - Include smoke scenarios, sample flows, a React workbench, and compiled CLI output.
17
+ - Add npm package metadata and publication safeguards.
@@ -1,21 +1,21 @@
1
- # Code of Conduct
2
-
3
- Adfinem follows the Contributor Covenant Code of Conduct.
4
-
5
- ## Our Pledge
6
-
7
- We pledge to make participation in this project a harassment-free experience for everyone, regardless of background, identity, experience level, or viewpoint.
8
-
9
- ## Expected Behavior
10
-
11
- - Be respectful and constructive.
12
- - Prefer clear technical discussion over personal criticism.
13
- - Assume good intent, while taking reported harm seriously.
14
-
15
- ## Unacceptable Behavior
16
-
17
- Harassment, threats, discriminatory language, sustained disruption, or publishing private information without permission are not acceptable.
18
-
19
- ## Enforcement
20
-
21
- Project maintainers may remove, edit, or reject comments, commits, issues, and pull requests that do not align with this Code of Conduct.
1
+ # Code of Conduct
2
+
3
+ Adfinem follows the Contributor Covenant Code of Conduct.
4
+
5
+ ## Our Pledge
6
+
7
+ We pledge to make participation in this project a harassment-free experience for everyone, regardless of background, identity, experience level, or viewpoint.
8
+
9
+ ## Expected Behavior
10
+
11
+ - Be respectful and constructive.
12
+ - Prefer clear technical discussion over personal criticism.
13
+ - Assume good intent, while taking reported harm seriously.
14
+
15
+ ## Unacceptable Behavior
16
+
17
+ Harassment, threats, discriminatory language, sustained disruption, or publishing private information without permission are not acceptable.
18
+
19
+ ## Enforcement
20
+
21
+ Project maintainers may remove, edit, or reject comments, commits, issues, and pull requests that do not align with this Code of Conduct.
package/CONTRIBUTING.md CHANGED
@@ -1,29 +1,29 @@
1
- # Contributing
2
-
3
- Thanks for helping improve Adfinem.
4
-
5
- ## Local Setup
6
-
7
- ```bash
8
- npm install
9
- npm run check
10
- npm run validate
11
- npm run smoke:dry
12
- ```
13
-
14
- Use dry runs while changing catalog or environment configuration.
15
-
16
- ## Development Notes
17
-
18
- - Keep scenarios catalog-gated; do not add arbitrary SQL, shell, or request bodies directly to scenario files when a catalog entry is the safer fit.
19
- - Do not commit `.env`, evidence folders, uploaded batch input files, or local logs.
20
- - Add or update tests when changing compiler, runner, adapter, or validation behavior.
21
- - Run `npm run package:dry-run` before proposing publication-related changes.
22
-
23
- ## Pull Requests
24
-
25
- Please include:
26
-
27
- - A short summary of the change.
28
- - The commands you ran.
29
- - Any migration notes for catalogs, scenarios, or flows.
1
+ # Contributing
2
+
3
+ Thanks for helping improve Adfinem.
4
+
5
+ ## Local Setup
6
+
7
+ ```bash
8
+ npm install
9
+ npm run check
10
+ npm run validate
11
+ npm run smoke:dry
12
+ ```
13
+
14
+ Use dry runs while changing catalog or environment configuration.
15
+
16
+ ## Development Notes
17
+
18
+ - Keep scenarios catalog-gated; do not add arbitrary SQL, shell, or request bodies directly to scenario files when a catalog entry is the safer fit.
19
+ - Do not commit `.env`, evidence folders, uploaded batch input files, or local logs.
20
+ - Add or update tests when changing compiler, runner, adapter, or validation behavior.
21
+ - Run `npm run package:dry-run` before proposing publication-related changes.
22
+
23
+ ## Pull Requests
24
+
25
+ Please include:
26
+
27
+ - A short summary of the change.
28
+ - The commands you ran.
29
+ - Any migration notes for catalogs, scenarios, or flows.
package/README.md CHANGED
@@ -1,87 +1,97 @@
1
- # Adfinem
2
-
3
- Open-source end-to-end QA test helper for deterministic API, database, Unix batch, and workflow automation.
4
-
5
- Adfinem is built for testers working on enterprise-grade business solutions where repeatable, catalog-gated checks matter.
6
-
7
- Adfinem executes catalog-gated workflows only. Scenario YAML can reference:
8
-
9
- - `catalogs/api-operations.yaml`
10
- - `catalogs/queries.yaml`
11
- - `catalogs/batches.yaml`
12
-
13
- ## What It Does
14
-
15
- Adfinem lets QA teams define repeatable end-to-end checks that combine:
16
-
17
- - REST API calls from an allowlisted operation catalog
18
- - database queries, assertions, and execution steps
19
- - Unix commands over SSH, including batch operations and file-backed processing
20
- - SFTP file placement before Unix jobs and output retrieval after they finish
21
- - workflow files that chain API, DB, Unix, loop, parallel, and reusable flow blocks
22
- - dry-run validation before touching external systems
23
- - evidence output for executed runs
24
-
25
- ## Install
26
-
27
- ```bash
28
- npm install
29
- npm run check
30
- ```
31
-
32
- When published to npm, the CLI can also be installed globally:
33
-
34
- ```bash
35
- npm install -g adfinem
36
- adfinem validate scenarios/smoke/account-processing-smoke.yaml
37
- ```
38
-
39
- ## Commands
40
-
41
- ```bash
42
- npm install
43
- npm test
44
- npm run build
45
- npm run validate
46
- npm run smoke:dry
47
- ```
48
-
49
- ## CLI-Only Usage
50
-
51
- Adfinem can be used fully from the terminal when a GUI is not wanted.
52
-
53
- ```bash
54
- # Validate a scenario before running it
55
- npm run adfinem -- validate scenarios/smoke/account-processing-smoke.yaml
56
-
57
- # Run a scenario without external side effects
58
- npm run adfinem -- run scenarios/smoke/account-processing-smoke.yaml --env local --dry-run
59
-
60
- # Execute a cataloged API operation
61
- npm run adfinem -- api-call create_test_case --env local --param tenant=demo --param external_id=CASE-1001 --param case_type=account-processing
62
-
63
- # Execute a cataloged DB query
64
- npm run adfinem -- db-query test_activity_exists --env local --param case_id=CASE-1001 --param amount=json:111
65
-
66
- # Run a cataloged Unix batch
67
- npm run adfinem -- run-batch daily_processing --env local --param processing_date=2026-04-27
68
- ```
69
-
70
- Use `--dry-run` while catalogs and environment credentials are still being completed.
71
-
72
- See `docs/FLOW_BUILDER.md` for flow files and `docs/DB_UNIX_OPERATIONS.md` for database and Unix scenario steps.
73
-
74
- ## Package Safety
75
-
76
- The npm package is allowlisted through `package.json#files` so local state such as `.env`, evidence, logs, dependencies, and uploaded batch input files are not included in published artifacts.
77
-
78
- Before publishing or opening a release PR, run:
79
-
80
- ```bash
81
- npm run check
82
- npm run package:dry-run
83
- ```
84
-
85
- ## License
86
-
87
- MIT
1
+ # Adfinem
2
+
3
+ Open-source end-to-end QA test helper for deterministic API, database, Unix batch, and workflow automation.
4
+
5
+ Adfinem is built for testers working on enterprise-grade business solutions where repeatable, catalog-gated checks matter.
6
+
7
+ Adfinem executes catalog-gated workflows only. Scenario YAML can reference:
8
+
9
+ - `catalogs/api-operations.yaml`
10
+ - `catalogs/queries.yaml`
11
+ - `catalogs/batches.yaml`
12
+
13
+ ## What It Does
14
+
15
+ Adfinem lets QA teams define repeatable end-to-end checks that combine:
16
+
17
+ - REST API calls from an allowlisted operation catalog
18
+ - database queries, assertions, and execution steps
19
+ - Unix commands over SSH, including batch operations and file-backed processing
20
+ - SFTP file placement before Unix jobs and output retrieval after they finish
21
+ - workflow files that chain API, DB, Unix, loop, parallel, and reusable flow blocks
22
+ - dry-run validation before touching external systems
23
+ - evidence output for executed runs
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ npm install
29
+ npm run check
30
+ ```
31
+
32
+ The published CLI can also be installed globally:
33
+
34
+ ```bash
35
+ npm install -g adfinem
36
+ adfinem init my-adfinem-tests
37
+ cd my-adfinem-tests
38
+ adfinem validate scenarios/smoke/account-processing-smoke.yaml
39
+ adfinem app
40
+ ```
41
+
42
+ ## Commands
43
+
44
+ ```bash
45
+ npm install
46
+ npm test
47
+ npm run build
48
+ npm run validate
49
+ npm run smoke:dry
50
+ ```
51
+
52
+ ## CLI-Only Usage
53
+
54
+ Adfinem can be used fully from the terminal when a GUI is not wanted.
55
+
56
+ ```bash
57
+ # Create a starter project when using the global package
58
+ adfinem init my-adfinem-tests
59
+ cd my-adfinem-tests
60
+
61
+ # Open the web workbench for the current project
62
+ adfinem app
63
+
64
+ # Validate a scenario before running it
65
+ adfinem validate scenarios/smoke/account-processing-smoke.yaml
66
+
67
+ # Run a scenario without external side effects
68
+ adfinem run scenarios/smoke/account-processing-smoke.yaml --env local --dry-run
69
+
70
+ # Execute a cataloged API operation
71
+ adfinem api-call create_test_case --env local --param tenant=demo --param external_id=CASE-1001 --param case_type=account-processing
72
+
73
+ # Execute a cataloged DB query
74
+ adfinem db-query test_activity_exists --env local --param case_id=CASE-1001 --param amount=json:111
75
+
76
+ # Run a cataloged Unix batch
77
+ adfinem run-batch daily_processing --env local --param processing_date=2026-04-27
78
+ ```
79
+
80
+ Use `--dry-run` while catalogs and environment credentials are still being completed.
81
+
82
+ See `docs/FLOW_BUILDER.md` for flow files and `docs/DB_UNIX_OPERATIONS.md` for database and Unix scenario steps.
83
+
84
+ ## Package Safety
85
+
86
+ The npm package is allowlisted through `package.json#files` so local state such as `.env`, evidence, logs, dependencies, and uploaded batch input files are not included in published artifacts.
87
+
88
+ Before publishing or opening a release PR, run:
89
+
90
+ ```bash
91
+ npm run check
92
+ npm run package:dry-run
93
+ ```
94
+
95
+ ## License
96
+
97
+ MIT
package/SECURITY.md CHANGED
@@ -1,13 +1,13 @@
1
- # Security Policy
2
-
3
- ## Reporting a Vulnerability
4
-
5
- Please report suspected vulnerabilities privately through GitHub security advisories when available, or by contacting the repository owner directly.
6
-
7
- Do not include secrets, credentials, private endpoints, raw production payloads, or proprietary SQL in public issues.
8
-
9
- ## Sensitive Data
10
-
11
- Adfinem is designed around catalog-gated actions, but users are still responsible for keeping local environment files, evidence, logs, and batch input files out of published artifacts.
12
-
13
- The repository `.gitignore` excludes common local-state paths such as `.env`, `evidence/`, `web-dist/`, and uploaded batch input files.
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ Please report suspected vulnerabilities privately through GitHub security advisories when available, or by contacting the repository owner directly.
6
+
7
+ Do not include secrets, credentials, private endpoints, raw production payloads, or proprietary SQL in public issues.
8
+
9
+ ## Sensitive Data
10
+
11
+ Adfinem is designed around catalog-gated actions, but users are still responsible for keeping local environment files, evidence, logs, and batch input files out of published artifacts.
12
+
13
+ The repository `.gitignore` excludes common local-state paths such as `.env`, `evidence/`, `web-dist/`, and uploaded batch input files.
@@ -17,11 +17,12 @@ import { loadFlow, writeFlow } from "../flows/parser.js";
17
17
  import { validateFlow } from "../flows/validator.js";
18
18
  import { importPostmanCollection, loadApiCollections, previewPostmanCollection } from "../adapters/api/api-collections.js";
19
19
  import { normalizeBindParamRecord, normalizeQueryCatalog } from "../adapters/db/query-catalog.js";
20
- const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
20
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
21
+ const rootDir = resolve(process.env.ADFINEM_PROJECT_ROOT ?? packageRoot);
21
22
  const flowsDir = join(rootDir, "flows");
22
23
  const evidenceDir = join(rootDir, "evidence");
23
24
  const batchInputFilesDir = join(rootDir, "data", "batch-input-files");
24
- const webDistDir = join(rootDir, "web-dist");
25
+ const webDistDir = resolve(process.env.ADFINEM_WEB_DIST ?? join(packageRoot, "web-dist"));
25
26
  const queriesFile = join(rootDir, "catalogs", "queries.yaml");
26
27
  const batchesFile = join(rootDir, "catalogs", "batches.yaml");
27
28
  const catalogYamlOptions = { defaultStringType: "PLAIN", defaultKeyType: "PLAIN", lineWidth: 0 };
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
- import { writeFile } from "node:fs/promises";
3
+ import { access, cp, mkdir, writeFile } from "node:fs/promises";
4
4
  import { basename, dirname, join, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { ZodError } from "zod";
@@ -21,12 +21,60 @@ import { compileFlow } from "./flows/compiler.js";
21
21
  import { loadFlow, readFlowSource, writeFlow } from "./flows/parser.js";
22
22
  import { validateFlow } from "./flows/validator.js";
23
23
  import { concatFlows } from "./flows/concat.js";
24
- const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
24
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
25
+ const rootDir = resolve(process.env.ADFINEM_PROJECT_ROOT ?? process.cwd());
25
26
  const program = new Command();
26
27
  program
27
28
  .name("adfinem")
28
29
  .description("Adfinem deterministic API, database, and Unix scenario runner")
29
- .version("0.1.0");
30
+ .version("0.1.1");
31
+ program
32
+ .command("init")
33
+ .argument("[directory]", "Project directory to create or update", ".")
34
+ .description("Create a starter Adfinem project with catalogs, config, scenarios, flows, docs, and templates")
35
+ .option("--force", "Overwrite starter files that already exist")
36
+ .action(async (directory, options) => {
37
+ await handleErrors(async () => {
38
+ const targetRoot = resolve(process.cwd(), directory);
39
+ await mkdir(targetRoot, { recursive: true });
40
+ const entries = ["catalogs", "config", "flows", "scenarios", "templates", "docs", ".env.example"];
41
+ const copied = [];
42
+ const skipped = [];
43
+ for (const entry of entries) {
44
+ const source = join(packageRoot, entry);
45
+ const target = join(targetRoot, entry);
46
+ if (!options.force && await pathExists(target)) {
47
+ skipped.push(entry);
48
+ continue;
49
+ }
50
+ await cp(source, target, { recursive: true, force: Boolean(options.force) });
51
+ copied.push(entry);
52
+ }
53
+ console.log(`Adfinem project ready: ${targetRoot}`);
54
+ if (copied.length > 0)
55
+ console.log(`Created: ${copied.join(", ")}`);
56
+ if (skipped.length > 0)
57
+ console.log(`Skipped existing: ${skipped.join(", ")} (use --force to overwrite)`);
58
+ console.log("Next:");
59
+ console.log(` cd ${targetRoot}`);
60
+ console.log(" adfinem validate scenarios/smoke/account-processing-smoke.yaml");
61
+ console.log(" adfinem app");
62
+ });
63
+ });
64
+ program
65
+ .command("app")
66
+ .description("Start the Adfinem web workbench for the current project")
67
+ .option("--project <dir>", "Project root containing catalogs, config, scenarios, and flows", ".")
68
+ .option("--port <port>", "Port to bind; defaults to 4177 with fallback ports", parseInteger)
69
+ .action(async (options) => {
70
+ await handleErrors(async () => {
71
+ process.env.ADFINEM_PROJECT_ROOT = resolve(process.cwd(), options.project);
72
+ process.env.ADFINEM_WEB_DIST = join(packageRoot, "web-dist");
73
+ if (options.port !== undefined)
74
+ process.env.ADFINEM_RUNNER_PORT = String(options.port);
75
+ await import("./app/server.js");
76
+ });
77
+ });
30
78
  program
31
79
  .command("validate")
32
80
  .argument("<scenario>", "Scenario YAML path")
@@ -390,6 +438,9 @@ function parseInteger(value) {
390
438
  throw new Error(`Invalid integer: ${value}`);
391
439
  return parsed;
392
440
  }
441
+ async function pathExists(path) {
442
+ return access(path).then(() => true).catch(() => false);
443
+ }
393
444
  function collectOption(value, previous) {
394
445
  return [...previous, value];
395
446
  }
package/package.json CHANGED
@@ -1,71 +1,73 @@
1
- {
2
- "name": "adfinem",
3
- "version": "0.1.0",
4
- "description": "Open-source QA test helper for deterministic API, database, Unix, and workflow automation",
5
- "keywords": [
6
- "qa",
7
- "testing",
8
- "api",
9
- "database",
10
- "unix",
11
- "workflow",
12
- "automation",
13
- "cli"
14
- ],
15
- "author": "Adfinem contributors",
16
- "license": "MIT",
17
- "private": false,
18
- "homepage": "https://github.com/amnotabot/adfinem#readme",
19
- "repository": {
20
- "type": "git",
21
- "url": "git+https://github.com/amnotabot/adfinem.git"
22
- },
23
- "bugs": {
24
- "url": "https://github.com/amnotabot/adfinem/issues"
25
- },
26
- "type": "module",
27
- "bin": {
28
- "adfinem": "dist/cli.js"
29
- },
30
- "files": [
31
- "dist",
32
- "src",
33
- "web",
34
- "catalogs",
35
- "config",
36
- "flows",
37
- "scenarios",
38
- "templates",
39
- "docs",
40
- "README.md",
41
- "LICENSE",
42
- "CHANGELOG.md",
43
- "CONTRIBUTING.md",
44
- "CODE_OF_CONDUCT.md",
45
- "SECURITY.md",
46
- "tsconfig.json",
47
- "vite.config.ts"
48
- ],
49
- "engines": {
50
- "node": ">=20"
51
- },
52
- "publishConfig": {
53
- "access": "public"
54
- },
55
- "scripts": {
56
- "build": "tsc -p tsconfig.json",
57
- "adfinem": "tsx src/cli.ts",
58
- "cli": "tsx src/cli.ts",
59
- "test": "tsx --test tests/api-only.test.ts",
60
- "check": "npm run build && npm test",
61
- "validate": "tsx src/cli.ts validate scenarios/smoke/account-processing-smoke.yaml",
62
- "smoke:dry": "tsx src/cli.ts run scenarios/smoke/account-processing-smoke.yaml --env local --dry-run",
63
- "web:build": "vite build",
64
- "app": "npm run web:build && tsx src/app/server.ts",
65
- "package:dry-run": "npm pack --dry-run --json",
66
- "release:validate": "npm run check && npm run web:build && npm run validate && npm run smoke:dry && npm run package:dry-run",
67
- "prepublishOnly": "npm run release:validate"
68
- },
1
+ {
2
+ "name": "adfinem",
3
+ "version": "0.1.1",
4
+ "description": "Open-source QA test helper for deterministic API, database, Unix, and workflow automation",
5
+ "keywords": [
6
+ "qa",
7
+ "testing",
8
+ "api",
9
+ "database",
10
+ "unix",
11
+ "workflow",
12
+ "automation",
13
+ "cli"
14
+ ],
15
+ "author": "Adfinem contributors",
16
+ "license": "MIT",
17
+ "private": false,
18
+ "homepage": "https://github.com/amnotabot/adfinem#readme",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/amnotabot/adfinem.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/amnotabot/adfinem/issues"
25
+ },
26
+ "type": "module",
27
+ "bin": {
28
+ "adfinem": "dist/cli.js"
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "src",
33
+ "web",
34
+ "web-dist",
35
+ "catalogs",
36
+ "config",
37
+ "flows",
38
+ "scenarios",
39
+ "templates",
40
+ "docs",
41
+ ".env.example",
42
+ "README.md",
43
+ "LICENSE",
44
+ "CHANGELOG.md",
45
+ "CONTRIBUTING.md",
46
+ "CODE_OF_CONDUCT.md",
47
+ "SECURITY.md",
48
+ "tsconfig.json",
49
+ "vite.config.ts"
50
+ ],
51
+ "engines": {
52
+ "node": ">=20"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "scripts": {
58
+ "build": "tsc -p tsconfig.json",
59
+ "adfinem": "tsx src/cli.ts",
60
+ "cli": "tsx src/cli.ts",
61
+ "test": "tsx --test tests/api-only.test.ts",
62
+ "check": "npm run build && npm test",
63
+ "validate": "tsx src/cli.ts validate scenarios/smoke/account-processing-smoke.yaml",
64
+ "smoke:dry": "tsx src/cli.ts run scenarios/smoke/account-processing-smoke.yaml --env local --dry-run",
65
+ "web:build": "vite build",
66
+ "app": "npm run web:build && tsx src/app/server.ts",
67
+ "package:dry-run": "npm pack --dry-run --json",
68
+ "release:validate": "npm run check && npm run web:build && npm run validate && npm run smoke:dry && npm run package:dry-run",
69
+ "prepublishOnly": "npm run release:validate"
70
+ },
69
71
  "dependencies": {
70
72
  "@xyflow/react": "^12.10.2",
71
73
  "axios": "^1.9.0",
package/src/app/server.ts CHANGED
@@ -26,11 +26,12 @@ import type { BatchCatalogEntry, QueryCatalogEntry, StepResult } from "../dsl/ty
26
26
  import { importPostmanCollection, loadApiCollections, previewPostmanCollection } from "../adapters/api/api-collections.js";
27
27
  import { normalizeBindParamRecord, normalizeQueryCatalog } from "../adapters/db/query-catalog.js";
28
28
 
29
- const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
29
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
30
+ const rootDir = resolve(process.env.ADFINEM_PROJECT_ROOT ?? packageRoot);
30
31
  const flowsDir = join(rootDir, "flows");
31
32
  const evidenceDir = join(rootDir, "evidence");
32
33
  const batchInputFilesDir = join(rootDir, "data", "batch-input-files");
33
- const webDistDir = join(rootDir, "web-dist");
34
+ const webDistDir = resolve(process.env.ADFINEM_WEB_DIST ?? join(packageRoot, "web-dist"));
34
35
  const queriesFile = join(rootDir, "catalogs", "queries.yaml");
35
36
  const batchesFile = join(rootDir, "catalogs", "batches.yaml");
36
37
  const catalogYamlOptions = { defaultStringType: "PLAIN", defaultKeyType: "PLAIN", lineWidth: 0 } as const;