Official
files
Built-in files UI (JavaScript UI plugin).
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/files@0.2.0
Permissions in 0.2.0
Files
main.ts1.4 KB
// Register file views before starting app and agent subscriptions.
// Background reads start from app changes, never from rendering.
import * as Effect from "effect/Effect";
import * as Stream from "effect/Stream";
import { App, Events, Views, runPlugin } from "convergence/effect";
import { Files } from "./controller.ts";
import { runFinished } from "./panel.ts";
import { renderRail, renderPanel } from "./views.ts";
const program = Effect.gen(function* () {
const files = yield* Files;
const views = yield* Views;
files.views.push(yield* views.slot("rail", (ctx) => renderRail(ctx, files), { on: ["app_state"], order: 10 }));
files.views.push(
yield* views.slot("right", (ctx) => renderPanel(ctx, files), { on: ["app_state"], order: 10, title: "Files" }),
);
const app = yield* App;
const events = yield* Events;
yield* app.changes.pipe(
Stream.runForEach((next) => Effect.forkScoped(files.followApp(next), { startImmediately: true })),
Effect.forkScoped({ startImmediately: true }),
);
yield* events.stream("agent").pipe(
Stream.runForEach((event) =>
Effect.forkScoped(
runFinished(event.kind) && files.state.workspaceId ? files.refresh(files.state.workspaceId) : Effect.void,
{ startImmediately: true },
),
),
Effect.forkScoped({ startImmediately: true }),
);
yield* files.followApp(yield* app.state);
});
export const activate = runPlugin(Files.layer, program);Versions
| Version | Published | Plugin API | Size | Permissions | Status |
|---|---|---|---|---|---|
| 0.2.0latest | Oct 5, 2026 | >=2 <3 | 6.4 KB | 3 permissions | Listed |
No comments yet.