Files
fusion/plugins/fusion-plugin-grok-runtime/src/index.ts
gsxdsm e4ddfe0218 fix: make Grok process lifecycle tests full-suite safe (#2289)
## Summary
Full Suite after #2288 still red on shard 4: `process-lifecycle.test.ts`
times out at 5s under shard transform load even after reducing
reimports.

- Move Symbol.for `process.exit` reaper onto `process-manager`
(lifecycle owner)
- Stress test reimports that module (not the full plugin graph)
- Explicit 15s timeout for the cold-transform bound stress test

## Test plan
- [x] Local process-lifecycle green (~2s)
- [ ] PR merge gate
- [ ] Post-merge Full Suite green

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
  - Improved Grok runtime process cleanup during application shutdown.
- Prevented duplicate cleanup handlers from accumulating during repeated
module loading.
- Ensured managed processes are reliably terminated when the process
exits.

- **Tests**
  - Expanded lifecycle coverage to validate repeated loading scenarios.
  - Increased test timeouts for more reliable stress-test execution.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-18 00:54:33 -07:00

100 lines
3.5 KiB
TypeScript

import { definePlugin } from "@fusion/plugin-sdk";
import type { FusionPlugin } from "@fusion/plugin-sdk";
/*
FNXC:ProcessLifecycle 2026-07-16-07:00 / 2026-07-18-07:40:
Exit-hook ownership lives in ./acp/process-manager (Symbol.for guard + shared
registry). Import that module from the plugin entry so plugin load still arms
the process.exit reaper; re-evaluation stays bounded by the Symbol.for guard.
*/
import "./acp/process-manager.js";
import { probeGrokBinary } from "./probe.js";
import { discoverGrokProviderModels } from "./provider.js";
import { GrokRuntimeAdapter } from "./runtime-adapter.js";
/*
FNXC:GrokCli 2026-07-08-00:00:
FN-7705: mirrors the landed Cursor Runtime plugin (FN-7697) end to end, with
one contract difference — Grok is API-key auth (GROK_API_KEY env var or
~/.grok/user-settings.json apiKey), not an OAuth/session CLI, so there is no
`grok status --format json` route; probe/authRoute here surface key-presence
auth state instead (see probe.ts). This shells out to an operator-installed
`grok` binary on PATH — Fusion does not download or bundle it.
FNXC:GrokAcp 2026-07-11-12:00:
Prompt transport is now native ACP (`grok agent stdio`) via vendored
AcpRuntimeAdapter under ./acp/ — realtime session/update streaming, tool calls,
and multi-turn session reuse. Probe/model discovery still use the CLI.
FNXC:GrokAcp 2026-07-11-16:00:
ACP client code is copied into this plugin (src/acp/), not imported from
fusion-plugin-acp-runtime, so bundled Grok does not depend on the experimental
ACP example plugin package.
*/
const plugin: FusionPlugin = definePlugin({
manifest: {
id: "fusion-plugin-grok-runtime",
name: "Grok Runtime Plugin",
version: "0.2.0",
description: "Grok CLI runtime support for Fusion (ACP agent stdio)",
runtime: {
runtimeId: "grok",
name: "Grok Runtime",
version: "0.2.0",
},
},
state: "installed",
hooks: {
onLoad: (ctx) => {
ctx.logger.info(
"Grok Runtime Plugin loaded — transport=ACP (grok agent stdio); probe uses grok --version",
);
},
},
runtime: {
metadata: {
runtimeId: "grok",
name: "Grok Runtime",
version: "0.2.0",
},
factory: async () => new GrokRuntimeAdapter(),
},
cliProviders: [
{
providerId: "grok-cli",
displayName: "Grok CLI",
binaryName: "grok",
providerType: "cli",
statusRoute: "/providers/grok-cli/status",
authRoute: "/auth/grok-cli",
actions: [
{ actionId: "enable", label: "Enable", actionType: "enable", method: "POST", route: "/auth/grok-cli" },
{ actionId: "disable", label: "Disable", actionType: "disable", method: "POST", route: "/auth/grok-cli" },
{ actionId: "test", label: "Test", actionType: "test", method: "GET", route: "/providers/grok-cli/status" }
],
probe: async () => {
const status = await probeGrokBinary();
return {
available: status.available,
authenticated: status.authenticated,
binaryPath: status.binaryPath,
binaryName: status.binaryName,
version: status.version,
reason: status.reason,
};
},
discoverModels: discoverGrokProviderModels,
runtime: {
runtimeId: "grok",
createAdapter: async () => new GrokRuntimeAdapter(),
},
},
],
});
export default plugin;
export { probeGrokBinary } from "./probe.js";
export { discoverGrokProviderModels } from "./provider.js";
export { GrokRuntimeAdapter } from "./runtime-adapter.js";
export type { GrokBinaryStatus } from "./types.js";