Skip to content

feat: update to new acpx version, reduce noise in acp messages#30036

Merged
osolmaz merged 33 commits intoopenclaw:mainfrom
osolmaz:feat/acpx-configurable-command-version
Mar 1, 2026
Merged

feat: update to new acpx version, reduce noise in acp messages#30036
osolmaz merged 33 commits intoopenclaw:mainfrom
osolmaz:feat/acpx-configurable-command-version

Conversation

@osolmaz
Copy link
Contributor

@osolmaz osolmaz commented Feb 28, 2026

  • Let use alternative acpx build in the config for development purposes
  • Introduces new config options for
    • hiding certain acp messages by default, e.g. usage
    • a delivery mode option which controls whether to send the messages at turn end, or right away (live | final_only)
  • Improve UX around using coding agents in threads

@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation extensions: acpx size: M maintainer Maintainer-authored PR labels Feb 28, 2026
@osolmaz osolmaz changed the title feat: update to new acpx version, reduce message noise feat: update to new acpx version Feb 28, 2026
Copy link

@nikolasdehor nikolasdehor left a comment

Choose a reason for hiding this comment

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

The configurable command/version feature is well-implemented with good validation and test coverage. Two concerns: (1) PR scope: This bundles a significant refactor of the event parsing system (new PromptStreamProjector class, control-errors module, JSON-RPC handling) with the config flexibility feature. These are logically separate changes and would benefit from being split. (2) PR description: The title 'update to new acpx version' doesn't reflect the actual scope — a more descriptive title like 'feat(acpx): add configurable command path and version policy' would help reviewers.

@openclaw-barnacle openclaw-barnacle bot added scripts Repository scripts agents Agent runtime and tooling labels Mar 1, 2026
@osolmaz osolmaz changed the title feat: update to new acpx version feat: update to new acpx version, reduce noise in acp messages Mar 1, 2026
@openclaw-barnacle openclaw-barnacle bot added channel: slack Channel integration: slack app: web-ui App: web-ui labels Mar 1, 2026
@osolmaz osolmaz marked this pull request as ready for review March 1, 2026 18:27
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b3d250548

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +9 to +13
export function parseControlJsonError(value: unknown): AcpxErrorEvent | null {
if (!isRecord(value)) {
return null;
}
const error = isRecord(value.error) ? value.error : null;

Choose a reason for hiding this comment

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

P1 Badge Wire structured control error parser into runtime commands

The new parseControlJsonError helper handles { error: { ... } } control responses, but AcpxRuntime.runControlCommand still only checks toAcpxErrorEvent (type: "error") and can therefore treat structured failures as success when acpx exits 0. In practice this can make control calls like setMode/setConfigOption silently no-op and also break the intended ignoreNoSession handling for cancel/close; the structured parser needs to be applied in the control-command error path before returning events.

Useful? React with 👍 / 👎.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 1, 2026

Greptile Summary

Updated to acpx 0.1.14 with enhanced configuration flexibility and noise reduction features for ACP agent messages.

Key improvements:

  • Added command and expectedVersion config options in acpx plugin to support alternative builds (e.g., local development builds). Set expectedVersion: "any" to skip version checks, or provide a path to use a custom acpx binary
  • Introduced deliveryMode setting (live | final_only) to control message timing - final_only buffers all output until turn completion, reducing message spam
  • Added tagVisibility config to selectively hide message types (usage updates, tool calls, etc.) that create noise in threaded conversations
  • Implemented repeatSuppression to deduplicate identical status messages within a turn
  • Added character limits (maxOutputChars, maxSessionUpdateChars) to prevent overly long streaming outputs
  • Enhanced tool message UX by enabling in-place editing for tool call updates in live mode
  • Fixed Slack thread cache to enforce cap by evicting oldest entries when full
  • Fixed cron cooldown field to properly omit when not configured

Implementation quality:

  • Comprehensive test coverage across all new features
  • Proper defensive programming with input validation and clamping
  • Clean separation of concerns (delivery coordinator, projector, stream settings)
  • Cross-platform path handling
  • Proper timer cleanup and state management

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-architected with comprehensive test coverage, proper defensive programming, and careful attention to edge cases. All new features are backward-compatible (defaults preserve existing behavior), state management is clean with proper cleanup, and cross-platform considerations are handled correctly. No critical bugs or logic errors were identified during review.
  • No files require special attention

Last reviewed commit: 9b3d250

@aisle-research-bot
Copy link

aisle-research-bot bot commented Mar 1, 2026

🔒 Aisle Security Analysis

We found 3 potential security issue(s) in this PR:

# Severity Title
1 🟠 High Unvalidated acpx version spec enables untrusted package source during auto-install
2 🟡 Medium Arbitrary command execution via configurable acpx command override in ACPX plugin config
3 🔵 Low Remote GitHub tarball dependency without integrity pinning in pnpm lockfile

1. 🟠 Unvalidated acpx version spec enables untrusted package source during auto-install

Property Value
Severity High
CWE CWE-494
Location extensions/acpx/src/ensure.ts:196-220

Description

ensureAcpx() builds an npm install command using expectedVersion from configuration without validating that it is a safe, pinned semver.

  • Input: params.expectedVersion (ultimately user/workspace-provided plugin config)
  • Sink: spawnAndCollect({ command: "npm", args: ["install", ..., acpx@${installVersion}] })
  • npm package specs are not limited to strict semver; they may include dist-tags, ranges, or in many npm setups non-registry sources (e.g., git+https://..., file:..., tarball URLs). Installing from such sources can execute attacker-controlled code via install scripts.
  • There is no integrity pinning (lockfile) and no --ignore-scripts, so a compromised/malicious source can lead to arbitrary code execution in the plugin's environment.

Vulnerable code:

const expectedVersion = params.expectedVersion?.trim() || undefined;
const installVersion = expectedVersion ?? ACPX_PINNED_VERSION;
...
await spawnAndCollect({
  command: "npm",
  args: ["install", "--omit=dev", "--no-save", `acpx@${installVersion}`],
  cwd: pluginRoot,
});

This is especially risky if plugin configuration can be influenced by untrusted workspaces/repositories.

Recommendation

Treat the install target as data requiring strict validation.

Recommended defenses (choose based on intended product behavior):

  1. Only allow strict semver versions (no ranges/tags/URLs) when auto-installing:
import semver from "semver";

function assertSafeVersion(v: string): string {
  const cleaned = semver.valid(v);
  if (!cleaned) throw new Error("expectedVersion must be a strict semver (e.g. 0.1.15)");
  return cleaned;
}

const installVersion = expectedVersion ? assertSafeVersion(expectedVersion) : ACPX_PINNED_VERSION;
  1. If you must allow tags/ranges, disallow non-registry specifiers explicitly (e.g., file:, git:, http:, https:) and whitespace/newlines.

  2. Consider hardening the install:

  • Add --ignore-scripts if feasible (prevents install-script execution).
  • Prefer installing a bundled/verified binary over network install.
  • Consider verifying the installed package integrity/version against an allowlist.

Also consider defaulting allowInstall to false unless the config is explicitly trusted by the user.


2. 🟡 Arbitrary command execution via configurable acpx command override in ACPX plugin config

Property Value
Severity Medium
CWE CWE-78
Location extensions/acpx/src/config.ts:162-172

Description

The ACPX plugin now allows the runtime executable to be overridden via plugin configuration (command) and allows disabling version verification (expectedVersion: "any").

This is dangerous because:

  • command is accepted as any non-empty string (including bare command names resolved from PATH, or relative paths resolved against the workspace directory / process.cwd()).
  • The configured value is later executed via child_process.spawn() for every ACP operation (turn execution and control commands).
  • Setting expectedVersion: "any" disables strict version matching, so a non-acpx binary that simply exits 0 on --help can pass health checks and then be used as the backend.

If an attacker can influence OpenClaw config (e.g., via the gateway control-plane config endpoints/UI, or by modifying the config file on disk), they can cause the gateway to execute an arbitrary local binary/script with the gateway's privileges.

Vulnerable code (configurable command resolution):

function resolveConfiguredCommand(params: { configured?: string; workspaceDir?: string }): string {
  const configured = params.configured?.trim();
  if (!configured) {
    return ACPX_BUNDLED_BIN;
  }
  if (path.isAbsolute(configured) || configured.includes(path.sep) || configured.includes("/")) {
    const baseDir = params.workspaceDir?.trim() || process.cwd();
    return path.resolve(baseDir, configured);
  }
  return configured;
}

Execution sink (example):

const child = spawnWithResolvedCommand({
  command: this.config.command,
  args,
  cwd: state.cwd,
});

Recommendation

Treat the command override as a high-risk escape hatch and add hard guardrails.

Suggested mitigations (choose one or combine):

  1. Disallow bare commands and relative paths (require absolute path):
if (configured && !path.isAbsolute(configured)) {
  throw new Error("acpx.command must be an absolute path");
}
  1. Restrict to a safe allowlist (e.g., bundled binary only, or absolute paths under an allowlisted directory):
const resolved = path.resolve(configured);
const allowedRoots = [ACPX_PLUGIN_ROOT /*, maybe workspaceDir */];
if (!allowedRoots.some((root) => resolved.startsWith(root + path.sep))) {
  throw new Error("acpx.command must be inside an allowed directory");
}
  1. Keep version enforcement on by default and limit override values:
  • Only allow expectedVersion to be a strict semver string (no npm specifiers/tags/URLs).
  • Consider removing/guarding expectedVersion: "any" behind an explicit unsafe flag.
  1. Operational controls:
  • Mark these fields as advanced/unsafe in UI hints.
  • If the product has multiple privilege tiers, ensure only the highest-privilege operators can set plugins.entries.acpx.config.command / expectedVersion.

3. 🔵 Remote GitHub tarball dependency without integrity pinning in pnpm lockfile

Property Value
Severity Low
CWE CWE-494
Location pnpm-lock.yaml:3134-3136

Description

The lockfile resolves @​whiskeysockets/libsignal-node via a remote GitHub codeload tarball URL without an integrity (SRI) hash.

  • The dependency is fetched from https://codeload.github.com/.../tar.gz/<commit>.
  • The commit SHA in the URL provides some immutability, but there is no cryptographic content hash recorded in the lockfile to verify the downloaded bytes.
  • This increases exposure to download-of-code-without-integrity-check scenarios (e.g., network/TLS interception in hostile environments, compromised endpoint/CDN returning unexpected bytes), and reduces reproducibility guarantees compared to registry packages which include resolution.integrity.
  • This dependency is pulled into production via @​whiskeysockets/baileys (a top-level dependencies entry in package.json).

Vulnerable/at-risk lock entry:

'@​whiskeysockets/libsignal-node@​https://codeload.github.com/whiskeysockets/libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67':
  resolution: {tarball: https://codeload.github.com/whiskeysockets/libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67}

Recommendation

Prefer dependencies that ship via the npm registry (or another registry) with an immutable resolution.integrity recorded in pnpm-lock.yaml.

Options:

  1. Switch to a registry release of @​whiskeysockets/libsignal-node (if available) rather than a GitHub tarball.
  2. If a registry release is not available:
    • Consider vendoring the dependency (e.g., internal mirror/artifact repository) and pin it with a checksum.
    • Enforce install-time integrity controls in CI (e.g., pnpm install --frozen-lockfile) and consider restricting/allowlisting external fetch hosts.

If you can move to a registry-published version, the lock entry should look like other packages with an integrity field, e.g.:

'@​scope/pkg@​1.2.3':
  resolution:
    integrity: sha512-... 

Analyzed PR: #30036 at commit 87ead23

Last updated on: 2026-03-01T20:01:33Z

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b6c742a1f0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@osolmaz osolmaz self-assigned this Mar 1, 2026
@osolmaz osolmaz force-pushed the feat/acpx-configurable-command-version branch from b6c742a to 87ead23 Compare March 1, 2026 19:39
@osolmaz osolmaz merged commit 907c09e into openclaw:main Mar 1, 2026
3 checks passed
@osolmaz
Copy link
Contributor Author

osolmaz commented Mar 1, 2026

Landed via temp rebase onto main.

  • Gate: pnpm lint && pnpm build && pnpm test
  • Land commit: 87ead23
  • Merge commit: 907c09e

Thanks @osolmaz!

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87ead23d75

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ansh pushed a commit to vibecode/openclaw that referenced this pull request Mar 2, 2026
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
safzanpirani pushed a commit to safzanpirani/clawdbot that referenced this pull request Mar 2, 2026
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
amitmiran137 pushed a commit to amitmiran137/openclaw that referenced this pull request Mar 2, 2026
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
hanqizheng pushed a commit to hanqizheng/openclaw that referenced this pull request Mar 2, 2026
execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 3, 2026
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
sachinkundu pushed a commit to sachinkundu/openclaw that referenced this pull request Mar 6, 2026
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui channel: slack Channel integration: slack docs Improvements or additions to documentation extensions: acpx maintainer Maintainer-authored PR scripts Repository scripts size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants