mirror of
https://github.com/morluto/rea.git
synced 2026-11-08 15:56:35 +00:00
fix(setup): require product evidence for FreeBuff discovery
Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request.
This commit is contained in:
1 parent
783f0fe45e
commit
6092f6da7e
4 files changed
+48
-9
No files matched your search
@@ -312,16 +312,22 @@ writing a registration ZCode cannot load.
|
||||
|
||||
## FreeBuff
|
||||
|
||||
For FreeBuff, setup writes `mcpServers.rea` into the user-scope
|
||||
For FreeBuff, the proposed integration writes `mcpServers.rea` into the user-scope
|
||||
`~/.agents/mcp.json` shared-agent file. Entries carry `command`, `args`, and
|
||||
`env`; stdio is the default transport. FreeBuff discovers personal skills from
|
||||
`env`; stdio is the default transport. The proposed personal skill location is
|
||||
`~/.agents/skills`, so setup installs its skill copy there. Because the same
|
||||
file doubles as ZCode's user-scope fallback (see above), a `freebuff`
|
||||
registration also loads in ZCode until ZCode defines its own native server.
|
||||
registration is also in the file ZCode uses until ZCode defines its own native server.
|
||||
Setup and doctor detect FreeBuff from its own profile directory
|
||||
(`~/.config/freebuff-desktop`), not from the shared `.agents` folder that
|
||||
REA's skill installs create for every client.
|
||||
|
||||
The configuration write and personal skill locations are proposed integration
|
||||
boundaries. FreeBuff MCP loading and skill discovery have not been verified
|
||||
with an installed native FreeBuff client/version; filesystem tests cover REA's
|
||||
editing, discovery, and ownership behavior only. Automatic applicability
|
||||
requires the FreeBuff profile directory even when the shared MCP file exists.
|
||||
|
||||
FreeBuff is main-only and is not part of npm 6.4.0; `rea setup --client
|
||||
freebuff` against `@latest` reports an unsupported client until a release
|
||||
containing it is published.
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Client and agent verification
|
||||
|
||||
FreeBuff MCP loading and personal skill discovery are currently unverified with
|
||||
an installed native client/version. Its temporary-filesystem coverage verifies
|
||||
REA's configuration and applicability boundaries only; it does not establish
|
||||
that FreeBuff consumes the written registration or skill.
|
||||
|
||||
Use these optional lanes to verify an installed client or evaluate an agent's
|
||||
REA workflow. [Testing REA](testing.md) provides the normal development commands
|
||||
and provider lanes. Each record below states its host, client version, model
|
||||
|
||||
@@ -35,6 +35,8 @@ export interface SetupClient {
|
||||
readonly msixPackage?: MsixPackageView;
|
||||
/** A running client can rewrite its configuration from memory. */
|
||||
readonly quitBeforeSetup?: boolean;
|
||||
/** Product-specific applicability evidence when configuration storage is shared. */
|
||||
readonly discoveryPaths?: readonly string[];
|
||||
readonly format?:
|
||||
| "json"
|
||||
| "toml"
|
||||
@@ -96,6 +98,7 @@ type ClientDefinition = ClientDefinitionBase &
|
||||
interface ClientDefinitionBase {
|
||||
readonly name: string;
|
||||
readonly displayName: string;
|
||||
readonly discoveryPaths?: (context: ClientPathContext) => readonly string[];
|
||||
readonly format: NonNullable<SetupClient["format"]>;
|
||||
readonly quitBeforeSetup?: boolean;
|
||||
readonly zcodeFallbackPath?: (context: ClientPathContext) => string;
|
||||
@@ -713,6 +716,9 @@ export const SUPPORTED_CLIENT_DEFINITIONS = [
|
||||
configPath: ({ home }: ClientPathContext) =>
|
||||
join(home, ".agents", "mcp.json"),
|
||||
markerPath: freebuffProfileDirectory,
|
||||
discoveryPaths: (context: ClientPathContext) => [
|
||||
freebuffProfileDirectory(context),
|
||||
],
|
||||
format: "json",
|
||||
},
|
||||
{
|
||||
@@ -730,14 +736,19 @@ export const SUPPORTED_CLIENT_DEFINITIONS = [
|
||||
* directory override does not exist.
|
||||
*/
|
||||
export const clientEvidencePaths = (
|
||||
client: Pick<SetupClient, "configPath" | "configPaths" | "markerPath">,
|
||||
client: Pick<
|
||||
SetupClient,
|
||||
"configPath" | "configPaths" | "markerPath" | "discoveryPaths"
|
||||
>,
|
||||
): readonly string[] => [
|
||||
...new Set(
|
||||
[
|
||||
client.configPath,
|
||||
...(client.configPaths ?? []),
|
||||
client.markerPath,
|
||||
].filter((path): path is string => path !== undefined && path.length > 0),
|
||||
(
|
||||
client.discoveryPaths ?? [
|
||||
client.configPath,
|
||||
...(client.configPaths ?? []),
|
||||
client.markerPath,
|
||||
]
|
||||
).filter((path): path is string => path !== undefined && path.length > 0),
|
||||
),
|
||||
];
|
||||
|
||||
@@ -805,6 +816,9 @@ export const supportedClients = (
|
||||
...(definition.quitBeforeSetup === true
|
||||
? { quitBeforeSetup: true }
|
||||
: {}),
|
||||
...(definition.discoveryPaths === undefined
|
||||
? {}
|
||||
: { discoveryPaths: definition.discoveryPaths(context) }),
|
||||
format: definition.format,
|
||||
};
|
||||
} catch (cause: unknown) {
|
||||
|
||||
@@ -36,6 +36,7 @@ describe("FreeBuff configuration paths", () => {
|
||||
displayName: "FreeBuff",
|
||||
configPath: join("/home/a", ".agents", "mcp.json"),
|
||||
markerPath: join("/home/a", ".config", "freebuff-desktop"),
|
||||
discoveryPaths: [join("/home/a", ".config", "freebuff-desktop")],
|
||||
format: "json",
|
||||
});
|
||||
expect(freebuffPath("/Users/a", "darwin")?.markerPath).toBe(
|
||||
@@ -50,9 +51,21 @@ describe("FreeBuff configuration paths", () => {
|
||||
const home = await createTestTempDirectory("rea-freebuff-shared-");
|
||||
// REA's own skill installs create this directory for every client.
|
||||
await mkdir(join(home, ".agents", "skills"), { recursive: true });
|
||||
await writeFile(
|
||||
join(home, ".agents", "mcp.json"),
|
||||
'{"mcpServers":{"other":{"command":"other-server"}}}',
|
||||
);
|
||||
expect((await detectClients(home)).map(({ name }) => name)).not.toContain(
|
||||
"freebuff",
|
||||
);
|
||||
expect(
|
||||
(
|
||||
await readClientRegistrationStatuses(home, undefined, {
|
||||
platform: process.platform,
|
||||
environment: {},
|
||||
})
|
||||
).map(({ client }) => client),
|
||||
).not.toContain("freebuff");
|
||||
|
||||
await mkdir(join(home, ".config", "freebuff-desktop"), {
|
||||
recursive: true,
|
||||
@@ -85,6 +98,7 @@ describe("FreeBuff JSON registration", () => {
|
||||
const client = freebuffPath(home, process.platform);
|
||||
if (client === undefined) throw new Error("missing FreeBuff client");
|
||||
await mkdir(dirname(client.configPath), { recursive: true });
|
||||
await mkdir(client.markerPath!, { recursive: true });
|
||||
return { home, client };
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user