Skip to content

feat: publish query filtering binary#1066

Open
Dodecahedr0x wants to merge 13 commits into
masterfrom
dode/private-er-binairy
Open

feat: publish query filtering binary#1066
Dodecahedr0x wants to merge 13 commits into
masterfrom
dode/private-er-binairy

Conversation

@Dodecahedr0x
Copy link
Copy Markdown
Contributor

@Dodecahedr0x Dodecahedr0x commented Mar 17, 2026

Summary by CodeRabbit

  • New Features

    • Adds a new cross-platform CLI command "query-filtering-service" with platform-specific distributions for macOS and Linux (ARM64/x64).
    • CLI prefers the bundled binary, falls back to a system binary, and enforces exact version matching before running.
  • Chores

    • Automated version alignment now updates the package's optional distribution entries for the CLI.
    • Minor packaging and formatting fixes.

Review Change Stack

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 17, 2026

Manual Deploy Available

You can trigger a manual deploy of this PR branch to testnet:

Deploy to Testnet 🚀

Alternative: Comment /deploy on this PR to trigger deployment directly.

⚠️ Note: Manual deploy requires authorization. Only authorized users can trigger deployments.

Comment updated automatically when the PR is synchronized.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 17, 2026

📝 Walkthrough

Walkthrough

Adds a new query-filtering-service CLI to the npm package: package.json exposes a query-filtering-service binary and platform-specific optionalDependencies; a TypeScript wrapper (queryFilteringService.ts) runs the packaged binary (with path resolution, version checking, and exit/signal forwarding) and falls back to a PATH-installed binary if needed; version-align.sh now fetches and applies the latest query-filtering-service package version to optionalDependencies.

Suggested reviewers

  • GabrielePicco
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dode/private-er-binairy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/packages/npm-package/queryFilteringService.ts:
- Around line 99-108: The version-check currently just returns on failure,
allowing a successful exit; update the failure paths in the version check (the
branch that tests error !== null and the branch that compares binaryVersion !==
PACKAGE_VERSION) to call process.exit(1) after logging the error so the wrapper
exits non-zero on failure. Locate the conditional that references error,
binaryVersion and PACKAGE_VERSION and append a non-zero exit (process.exit(1))
to both failure branches to ensure the process signals failure to the caller.
- Line 8: The PACKAGE_VERSION constant is using a non-existent key
VERSIONS.PRIVATE_EPHEMERAL_VALIDATOR; update the constant to use the correct key
VERSIONS.QUERY_FILTERING_SERVICE (the key returned by getVersions()) so
PACKAGE_VERSION = `query-filtering-service ${VERSIONS.QUERY_FILTERING_SERVICE}`;
ensure you reference the VERSIONS symbol and PACKAGE_VERSION constant when
making the change.

In @.github/version-align.sh:
- Around line 50-55: The if condition is using the wrong guard variable so the
query-filtering-service update never runs; change the guard in the conditional
from private_validator_latest to query_filtering_service_latest (the variable
used in the echo and jq command) so the block executes when
query_filtering_service_latest is set; update the conditional that currently
references private_validator_latest to reference query_filtering_service_latest
in the same if/else block surrounding the jq call that updates
packages/npm-package/package.json.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6f8c719d-d047-4c34-b101-151264f8d6f5

📥 Commits

Reviewing files that changed from the base of the PR and between adb60d5 and 7c08e53.

📒 Files selected for processing (4)
  • .github/packages/npm-package/getVersions.ts
  • .github/packages/npm-package/package.json
  • .github/packages/npm-package/queryFilteringService.ts
  • .github/version-align.sh

Comment thread .github/packages/npm-package/queryFilteringService.ts Outdated
Comment thread .github/packages/npm-package/queryFilteringService.ts
Comment thread .github/version-align.sh Outdated
Copy link
Copy Markdown
Contributor

@lucacillario lucacillario left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Dodecahedr0x look at code rabbit comments, the first one and the last one have to be addresseed

@Dodecahedr0x Dodecahedr0x requested a review from lucacillario May 18, 2026 18:30
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/packages/npm-package/queryFilteringService.ts:
- Around line 20-26: The Windows fallback in trySystemQueryFilteringService()
currently probes only "/query-filtering-service" so it misses ".exe" (and
".cmd") binaries; update trySystemQueryFilteringService() to mirror
getExePath()'s platform handling by constructing and trying candidate names in
order (e.g., "query-filtering-service.exe", "query-filtering-service.cmd", then
"query-filtering-service") when on Windows (detect via
platform()/process.platform or reuse the same os/extension logic), testing each
candidate in PATH before giving up so the packaged-binary fallback and system
PATH resolution behave consistently.
- Around line 65-70: The current tryPackageQueryFilteringService function
returns true immediately after calling runQueryFilteringService(resolvedPath)
but spawn failures are emitted asynchronously; change
tryPackageQueryFilteringService to await a Promise returned by
runQueryFilteringService (or wrap the internal spawn in a Promise) that only
resolves true when the child emits the "spawn" event and resolves false when the
child emits an "error" event (and attach the error handler to avoid uncaught
exceptions); keep using getExePath to resolve the path and ensure
runWithForwardedExit's child is wired into that Promise so the top-level ||
fallback is reached when the Promise resolves false.
- Around line 36-45: The exit-forwarding currently defers propagation by
installing a process.on("exit") handler inside runWithForwardedExit's
child.on("exit") callback; change runWithForwardedExit to forward immediately
when the child emits "exit": inside the child.on("exit", ...) handler, if a
signal is present call process.kill(process.pid, signal) right away, otherwise
call process.exit(code) immediately (handling null case appropriately), and
remove the nested process.on("exit") usage so the parent exits/forwards as soon
as the child terminates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4d3f4cb3-fe5f-4fea-af9b-a015f4ab96f4

📥 Commits

Reviewing files that changed from the base of the PR and between 7c08e53 and d37aef3.

📒 Files selected for processing (3)
  • .github/packages/npm-package/package.json
  • .github/packages/npm-package/queryFilteringService.ts
  • .github/version-align.sh

Comment thread .github/packages/npm-package/queryFilteringService.ts
Comment thread .github/packages/npm-package/queryFilteringService.ts
Comment thread .github/packages/npm-package/queryFilteringService.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/packages/npm-package/queryFilteringService.ts:
- Around line 45-48: The process.on("SIGINT") handler currently sends both
child.kill("SIGINT") and child.kill("SIGTERM") immediately; remove the immediate
SIGTERM and instead send only SIGINT, then start a short timeout to send SIGTERM
if the child hasn't exited (e.g., setTimeout(() => child.kill("SIGTERM"), 5000)
and clear it if the child exits). Update the process.on("SIGINT") handler and
any child exit listeners to clear the escalation timer so SIGTERM is only used
as a fallback.
- Around line 10-17: getBinaryVersion currently treats stdout as a valid version
even when the spawned process exits with a non-zero status; update the function
to check result.status (from spawnSync) and treat any non-zero status as an
error case: if result.status !== 0 (or result.signal is set) build an error
string that includes the exit status/signal and stderr (if present) and return
that as the first tuple element instead of stdout; continue to return stdout
only when status is zero and no result.error exists. Reference: getBinaryVersion
and the spawnSync result fields (status, signal, stderr, stdout).
- Around line 84-116: trySystemQueryFilteringService currently discards the
Promise returned by runQueryFilteringService so spawn failures don't lead to
process.exit; make trySystemQueryFilteringService async, await the call to
runQueryFilteringService(absoluteBinaryPath), and if the awaited result is false
(spawn/error case) call process.exit(1); keep the existing binary/version checks
using getBinaryVersion and PACKAGE_VERSION unchanged but ensure callers that
invoke trySystemQueryFilteringService handle the returned Promise (await or
propagate) so the process exit behavior is honored.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ab817d97-f5f3-40dc-b8dd-ca9fe5bf8e07

📥 Commits

Reviewing files that changed from the base of the PR and between d37aef3 and 308242e.

📒 Files selected for processing (1)
  • .github/packages/npm-package/queryFilteringService.ts

Comment on lines +10 to +17
function getBinaryVersion(location: string): [string | null, string | null] {
const result = spawnSync(location, ["--version"]);
const error: string | null =
(result.error && result.error.toString()) ||
(result.stderr.length > 0 && result.stderr.toString().trim()) ||
null;
return [error, result.stdout && result.stdout.toString().trim()];
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Check exit status in version validation.

getBinaryVersion only checks result.error and result.stderr, but ignores result.status. If the binary exits with a non-zero status code while still writing to stdout, the function will treat that output as a valid version string. This could cause version validation to incorrectly accept malformed or error output.

🛡️ Proposed fix
 function getBinaryVersion(location: string): [string | null, string | null] {
   const result = spawnSync(location, ["--version"]);
   const error: string | null =
     (result.error && result.error.toString()) ||
+    (result.status !== 0 && `Process exited with code ${result.status}`) ||
     (result.stderr.length > 0 && result.stderr.toString().trim()) ||
     null;
   return [error, result.stdout && result.stdout.toString().trim()];
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/packages/npm-package/queryFilteringService.ts around lines 10 - 17,
getBinaryVersion currently treats stdout as a valid version even when the
spawned process exits with a non-zero status; update the function to check
result.status (from spawnSync) and treat any non-zero status as an error case:
if result.status !== 0 (or result.signal is set) build an error string that
includes the exit status/signal and stderr (if present) and return that as the
first tuple element instead of stdout; continue to return stdout only when
status is zero and no result.error exists. Reference: getBinaryVersion and the
spawnSync result fields (status, signal, stderr, stdout).

Comment on lines +45 to +48
process.on("SIGINT", () => {
child.kill("SIGINT");
child.kill("SIGTERM");
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove redundant SIGTERM after SIGINT.

Sending both SIGINT and SIGTERM in immediate succession (lines 46-47) doesn't give the child process time to handle SIGINT gracefully. Typically you would send SIGINT first and only escalate to SIGTERM if the child doesn't exit. The current code sends both signals at once, which may interfere with the child's signal handlers.

♻️ Proposed fix
   process.on("SIGINT", () => {
     child.kill("SIGINT");
-    child.kill("SIGTERM");
   });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
process.on("SIGINT", () => {
child.kill("SIGINT");
child.kill("SIGTERM");
});
process.on("SIGINT", () => {
child.kill("SIGINT");
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/packages/npm-package/queryFilteringService.ts around lines 45 - 48,
The process.on("SIGINT") handler currently sends both child.kill("SIGINT") and
child.kill("SIGTERM") immediately; remove the immediate SIGTERM and instead send
only SIGINT, then start a short timeout to send SIGTERM if the child hasn't
exited (e.g., setTimeout(() => child.kill("SIGTERM"), 5000) and clear it if the
child exits). Update the process.on("SIGINT") handler and any child exit
listeners to clear the escalation timer so SIGTERM is only used as a fallback.

Comment on lines +84 to +116
function trySystemQueryFilteringService(): void {
const absolutePath = process.env.PATH?.split(path.delimiter)
.filter((dir) => dir !== path.dirname(process.argv[1]))
.find((dir) => {
try {
fs.accessSync(`${dir}/query-filtering-service`, fs.constants.X_OK);
return true;
} catch {
return false;
}
});

if (!absolutePath) {
console.error("Could not find globally installed query-filtering-service.");
process.exit(1);
}

const absoluteBinaryPath = `${absolutePath}/query-filtering-service`;
const [error, binaryVersion] = getBinaryVersion(absoluteBinaryPath);

if (error !== null) {
console.error(`Failed to get version of global binary: ${error}`);
process.exit(1);
}
if (binaryVersion !== PACKAGE_VERSION) {
console.error(
`Globally installed query-filtering-service version is not correct. Expected "${PACKAGE_VERSION}", found "${binaryVersion}".`,
);
process.exit(1);
}

void runQueryFilteringService(absoluteBinaryPath);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Handle spawn failure in system fallback path.

At line 115, void runQueryFilteringService(absoluteBinaryPath) discards the Promise. If the spawn fails (missing executable, permission denied, etc.), the "error" event fires, logs a message, and the Promise resolves to false, but nothing is awaiting it. Control returns to main(), which completes, and the process may exit with code 0 or hang indefinitely depending on event loop state. This contradicts the explicit process.exit(1) calls on lines 98, 106, and 112 for other error conditions.

🐛 Proposed fix
-  void runQueryFilteringService(absoluteBinaryPath);
+  const success = await runQueryFilteringService(absoluteBinaryPath);
+  if (!success) {
+    console.error("Failed to spawn query-filtering-service from system PATH.");
+    process.exit(1);
+  }
 }
 
-async function main(): Promise<void> {
+async function main(): Promise<void> {
   if (!(await tryPackageQueryFilteringService())) {
-    trySystemQueryFilteringService();
+    await trySystemQueryFilteringService();
   }
 }

Make trySystemQueryFilteringService async and await the spawn result so spawn failures exit with code 1.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/packages/npm-package/queryFilteringService.ts around lines 84 - 116,
trySystemQueryFilteringService currently discards the Promise returned by
runQueryFilteringService so spawn failures don't lead to process.exit; make
trySystemQueryFilteringService async, await the call to
runQueryFilteringService(absoluteBinaryPath), and if the awaited result is false
(spawn/error case) call process.exit(1); keep the existing binary/version checks
using getBinaryVersion and PACKAGE_VERSION unchanged but ensure callers that
invoke trySystemQueryFilteringService handle the returned Promise (await or
propagate) so the process exit behavior is honored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants