Official
acp
ACP agents from the ACP registry (Gemini, Cursor, Droid, Kilo, pi, ...), Oh My Pi, and your own entries (custom.json in the plugin's data folder). Agents are discovered at runtime.
The app opens the listing; nothing installs until an agent in your Plugins workspace has read the files and you enable the plugin. In a terminal: cvg install convergence/acp@0.2.0
Permissions in 0.2.0
Take care. This plugin asks for permissions that can do anything your account can. The app asks you to hold Enable for two seconds or to type the plugin's name before it turns on.
Files
main.ts1.9 KB
// ACP provider wiring: lazily share login environment and platform detection,
// then serve the registry in the plugin's resource scope.
import * as Effect from "effect/Effect";
import * as Scope from "effect/Scope";
import { Env, Process, runPlugin } from "convergence/effect";
import { RpcTransport } from "../sdk/effect.ts";
import { detectPlatform } from "./registry.ts";
import { AcpPlugin } from "./plugin.ts";
import type { AcpContext } from "./types.ts";
export { AcpPlugin } from "./plugin.ts";
export const ENV_VARS = ["XAI_API_KEY"];
const loginEnv = Effect.fn("Acp.loginEnv")(function* () {
const env = yield* Env;
const values: Record<string, string> = {};
for (const name of ENV_VARS) {
const value = yield* env.get(name).pipe(
Effect.catchTag(["HostCallFailed", "PermissionNotGranted", "NeedsReview"], (error) =>
Effect.sync(() => {
console.warn(`acp: reading ${name} failed: ${error.message}`);
return null;
}),
),
);
if (typeof value === "string" && value) values[name] = value;
}
return values;
});
export const serve = Effect.fn("Acp.serve")(function* (observe?: (plugin: AcpPlugin) => void) {
const scope = yield* Scope.Scope;
const transport = yield* RpcTransport;
const process = yield* Process;
const platform = yield* Effect.cached(detectPlatform().pipe(Effect.scoped));
const env = yield* Effect.cached(loginEnv());
const context: AcpContext = {
which: (program) =>
process.which(program).pipe(
Effect.map((result) => result.path ?? null),
Effect.catchTag(["HostCallFailed", "PermissionNotGranted", "NeedsReview"], () => Effect.succeed(null)),
),
platform: () => platform,
loginEnv: () => env,
icons: {},
};
const plugin = new AcpPlugin(scope, transport, context);
observe?.(plugin);
yield* plugin.start();
});
export const activate = runPlugin(RpcTransport.layer, serve());Versions
| Version | Published | Plugin API | Size | Permissions | Status |
|---|---|---|---|---|---|
| 0.2.0latest | Oct 5, 2026 | >=2 <3 | 94.9 KB | 6 permissions | Listed |
No comments yet.