mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-09-14 14:01:28 +08:00
07f1cf3a3f
* fix(agentbbs-tools): detect the real CLI-only agentbbs package instead of a nonexistent JS import
The published `agentbbs` package (0.2.1) is a CLI-only launcher — a `bin`
script with no importable JS entry point — that downloads/builds a Rust
binary and shells out to it. loadAgentbbs()'s `await import('agentbbs')`
could therefore never resolve, even with the CLI correctly installed and
on PATH, so all 4 federation_bbs_* tools reported degraded:true
unconditionally regardless of install state.
Replace the dynamic import with a subprocess presence probe
(agentbbsCliAvailable(), `agentbbs --version`), matching how the rest of
the codebase treats optional CLI tools. shell:true is required for the
probe to find npm's Windows .cmd shim (child_process does not consult
PATHEXT otherwise).
Making the probe actually succeed surfaced two further pre-existing bugs
in code that was previously always skipped:
- vitest.config.ts externalized @noble/ed25519 alongside genuinely-optional
deps (agentic-flow, agentdb, ...), but it is an always-installed hard
dependency; externalizing it broke dynamic-import resolution under Vite's
SSR transform.
- federation_bbs_human_join dynamically imported @noble/ed25519 a second
time (getSigningKey() already does), which is now deduplicated behind one
memoized loadEd25519() loader.
All 12 tests in agentbbs-tools.test.ts now pass, including the 4
happy-path tests that were previously always skipped.
* fix(agentbbs-tools): gate the probe shell to win32 instead of always on
`shell: true` was unconditional, and the probed binary comes from
`process.env.AGENTBBS_BIN`. Under a shell that argument is command-interpreted,
so `AGENTBBS_BIN='agentbbs --version; touch /tmp/PWNED'` executes the trailing
command. Verified locally: the file is created with `shell: true` and the spawn
fails with ENOENT once the shell is gated off.
This is the case browser-tools.ts already warns about in the comment beside the
same pattern -- "if user-controlled args are ever added, escape them before
spawn" -- and `shell: process.platform === 'win32'` is the convention already
used at browser-tools.ts:49, commands/init.ts:856 and :1194, and
init/helpers-generator.ts:1459. Unconditional `shell: true` appeared nowhere
else in the package.
The Windows behaviour the original was reaching for is unchanged: cmd.exe still
resolves the `agentbbs.cmd` shim via PATHEXT. POSIX simply stops interpreting
the override. Added windowsHide to match the sibling call sites.
Verified the fix still does what it set out to do: with the CLI resolvable the
suite is 12/12 and the four previously-always-skipped happy-path tests execute,
with the shell disabled on POSIX.
Co-Authored-By: RuFlo <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_013u4pmL9ZUAXb6usVQgNo67
44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
import { defineConfig } from 'vitest/config';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
export default defineConfig({
|
|
resolve: {
|
|
conditions: ['node'],
|
|
// Exercise the workspace security source rather than a stale installed
|
|
// package during cross-package policy integration tests (ADR-324).
|
|
alias: {
|
|
'@claude-flow/security': fileURLToPath(new URL('../security/src/index.ts', import.meta.url)),
|
|
},
|
|
},
|
|
plugins: [
|
|
{
|
|
name: 'externalize-optional-deps',
|
|
enforce: 'pre',
|
|
resolveId(source) {
|
|
// Don't let Vite resolve optional deps that may have missing subpath
|
|
// exports. These are imported via try/catch dynamic import in src/
|
|
// (sona-optimizer falls back to no-SONA when the package isn't
|
|
// installed). External-marking them keeps vitest from failing
|
|
// module resolution at transform time.
|
|
if (source.startsWith('agentic-flow')) return { id: source, external: true };
|
|
if (source.startsWith('agentdb')) return { id: source, external: true };
|
|
// memory-bridge dynamic-imports this inside try/catch and degrades to
|
|
// the sql.js path; its dist is absent unless the workspace was built.
|
|
if (source === '@claude-flow/memory') return { id: source, external: true };
|
|
if (source.startsWith('@ruvector/')) return { id: source, external: true };
|
|
if (source.startsWith('@huggingface/transformers')) return { id: source, external: true };
|
|
if (source.startsWith('@xenova/transformers')) return { id: source, external: true };
|
|
return null;
|
|
},
|
|
},
|
|
],
|
|
test: {
|
|
environment: 'node',
|
|
include: ['__tests__/**/*.test.ts'],
|
|
globals: true,
|
|
coverage: {
|
|
enabled: false,
|
|
},
|
|
},
|
|
});
|