diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aecb3a6..ffb75d9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,13 @@ build output, not the raw source. `postinstall` handles this on a fresh `npm ins edits made after that without a fresh build. (This exact ordering mistake broke CI once already — see `.github/workflows/ci.yml`'s comments.) +**If you're changing the Paseo plugin itself** (`index.client.tsx`, `index.server.ts`, `client/`, `server/`, +`shared/`), pointing `paseo plugin install`/`reload` straight at the repo root doesn't work under Paseo +0.8+ — its build step scans the whole given directory and rejects `packages/cli`'s own files as not +belonging to `client/`/`server/`/`shared/`. Use `npm run package:plugin` (stages a self-contained copy into +`build/paseo-plugin`, with no sibling-package contamination) and point `paseo` at that instead — see +[`docs/MANUAL.md`](docs/MANUAL.md#installing-the-paseo-plugin) for the exact dev-loop commands. + ## CI `.github/workflows/ci.yml` runs on every push to `main` and every PR: `build` → `typecheck` → `test` → a @@ -86,6 +93,11 @@ workflow's release tag format if either changes. considering it done, not just synthetic fixtures — see `packages/cli/src/core/opencode-adapter.server.ts` and `aider-adapter.server.ts` for adapters that were built and tuned against real, messy production data (including a real bug found and fixed that way: non-ASCII text handling in relationship detection). +- Paseo's plugin API has already broken backward compatibility once (v0.8's client/server/shared split — + see `paseo-plugin.json`'s `requirements.paseo` field and `paseo-plugin.d.ts`'s ambient module + declarations). If it happens again, verify the actual migration against a real Paseo daemon at the new + version — `paseo plugin install`/`ls` reporting `running` is the only real evidence a fix worked, not + just a clean typecheck. ## Reporting issues diff --git a/main.client.tsx b/client/sessions.tsx similarity index 99% rename from main.client.tsx rename to client/sessions.tsx index 40835cf..0b7c884 100644 --- a/main.client.tsx +++ b/client/sessions.tsx @@ -1,5 +1,5 @@ -import type { PluginSurfaceProps } from "@getpaseo/plugin"; -import { useRpc } from "@getpaseo/plugin"; +import type { PluginSurfaceProps } from "@getpaseo/plugin/client"; +import { useRpc } from "@getpaseo/plugin/client"; import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { FlatList, Image, Modal, Pressable, ScrollView, Text, TextInput, View } from "react-native"; import { @@ -12,7 +12,7 @@ import { SessionRelationshipSchema, SessionSchema, showSessionRpc, -} from "./src/server/session-contracts.shared"; +} from "../shared/session-contracts"; import type { z } from "zod"; type SessionDto = z.infer; diff --git a/docs/MANUAL.md b/docs/MANUAL.md index 4b3a071..e71d528 100644 --- a/docs/MANUAL.md +++ b/docs/MANUAL.md @@ -103,12 +103,25 @@ directory. It never touches the daemon's `pluginsEnabled` switch itself — plug code, so if plugins aren't enabled on your daemon, `wire-paseo` stops and tells you to enable them yourself first (Settings → Plugins → Enable plugins in the Paseo app). -The manual way — needed if you're developing the plugin itself, since it points `paseo` straight at your -working tree instead of a downloaded release snapshot: +The manual way — needed if you're developing the plugin itself. **Point `paseo` at `build/paseo-plugin`, not +at the repo root** — Paseo 0.8's build step scans the *entire* given directory for stray plugin modules, and +rejects anything outside `client/`/`server/`/`shared/`, including unrelated files from this monorepo's +sibling `packages/cli` workspace (verified: installing straight from the repo root fails with `Plugin +modules belong in client/, server/, or shared/: .../packages/cli/dist/index.d.ts`). `npm run package:plugin` +stages exactly the plugin's own files with no such sibling-package contamination — the same staged +directory the tarball attached to releases is built from — so point `paseo` there instead: ```bash -paseo plugin install /path/to/sessionforge -paseo plugin reload sessionforge # after any source change — never auto-reloaded +npm run package:plugin # stages the plugin (and everything it needs) into build/paseo-plugin +paseo plugin install ./build/paseo-plugin --id sessionforge # first time +``` + +After any source change, repackage then reload (reload just re-reads from the same installed path, so it +won't pick up new edits until you repackage first): + +```bash +npm run package:plugin +paseo plugin reload sessionforge paseo plugin logs sessionforge # tail console.log/console.error from the server contribution ``` diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 77c0ed4..0685aec 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -48,20 +48,29 @@ packages/cli/ @aadaa88/sessionforge — the standalone pack dist/ compiled output (git-ignored) — the actual import target for library consumers, built via `npm run build`; the CLI itself runs off raw TS via tsx, no build needed -src/server/ Paseo plugin RPC layer — depends on sessionforge like any npm package - session-contracts.shared.ts Zod RPC contracts (session.list, .show, .search, .cleanup, .archive, .restore, .delete, .discover) - session-handlers.server.ts handler implementations + background rescan scheduling (ADAPTERS = Claude Code, Codex, Gemini CLI, OpenCode, Aider) - -index.ts Paseo plugin entry point — pure plugin.handle()/addSurface()/addSidebarItem() registration only - (kept minimal: Paseo's Electron-main "evaluate" introspection pass calls this file's - top-level code without a real server context, so it must not directly call anything - imported from a .server.ts file) -main.client.tsx session browser UI (sidebar panel): search/filter/agent tabs, List/Timeline view toggle, - checkboxes + bulk actions, per-provider logo icons, click-to-preview dialog with related - sessions, per-session and per-provider file size +shared/session-contracts.ts Zod RPC contracts (session.list, .show, .search, .cleanup, .archive, .restore, .delete, .discover) — + imported by both index.client.tsx and index.server.ts, per Paseo 0.8's client/server/shared split +server/session-handlers.ts handler implementations + background rescan scheduling (ADAPTERS = Claude Code, Codex, Gemini CLI, OpenCode, Aider) +client/sessions.tsx session browser UI (sidebar panel): search/filter/agent tabs, List/Timeline view toggle, + checkboxes + bulk actions, per-provider logo icons, click-to-preview dialog with related + sessions, per-session and per-provider file size + +index.client.tsx Paseo plugin app-bundle entry point — addSurface()/addSidebarItem()/addCommandCenterItem() + registration only +index.server.ts Paseo plugin daemon-bundle entry point — plugin.handle() registration + the + background-rescan cleanup hook +paseo-plugin.d.ts hand-written ambient types for @getpaseo/plugin's root/client/server modules — Paseo + supplies the real runtime implementations at install time, so there's no real npm + package installed here to pull types from scripts/package-plugin.mjs packages the Paseo plugin (this repo's root — see above) into a self-contained - directory, then tars it — what `sessionforge wire-paseo` downloads and installs + directory, then tars it — what `sessionforge wire-paseo` downloads and installs. + Also required for *local* plugin development under Paseo 0.8+: pointing + `paseo plugin install` straight at this repo's root fails, since Paseo's build step + scans the whole given directory and rejects the sibling packages/cli workspace's own + files as "not in client/, server/, or shared/" — see MANUAL.md's Installing the Paseo + plugin section for the actual dev-loop commands (`npm run package:plugin` + install/ + reload against `build/paseo-plugin`, not the repo root) .github/workflows/ CI (typecheck/test/build on Linux/macOS/Windows) + a tag-triggered release workflow (git tag vX.Y.Z && git push origin vX.Y.Z — the tag is the version, @@ -78,10 +87,10 @@ was always necessary. Splitting that CLI (plus the whole engine underneath it) i `packages/cli` / `@aadaa88/sessionforge`, takes that one step further: nothing in it imports `@getpaseo/*`, `react`, or `react-native`, so it's usable — as a standalone binary, or as a library — by anyone who never touches Paseo, with zero risk of Paseo/React dependencies leaking into it. `packages/cli` is -`"private": true` and never published to npm; the repo root — `index.ts`, `main.client.tsx`, -`src/server/*` — is just the Paseo plugin, depending on `@aadaa88/sessionforge` as a workspace-local -dependency (npm workspace resolution symlinks it in, same mechanism a published package would use, just -without ever actually publishing). +`"private": true` and never published to npm; the repo root — `index.client.tsx`, `index.server.ts`, +`client/`, `server/`, `shared/` — is just the Paseo plugin, depending on `@aadaa88/sessionforge` as a +workspace-local dependency (npm workspace resolution symlinks it in, same mechanism a published package +would use, just without ever actually publishing). `packages/cli` builds a real `dist/` (compiled JS + `.d.ts`) as its library entry point rather than shipping raw TypeScript for that path, specifically so the plugin's cross-package import (`import ... from diff --git a/index.client.tsx b/index.client.tsx new file mode 100644 index 0000000..aff440c --- /dev/null +++ b/index.client.tsx @@ -0,0 +1,18 @@ +import type { PluginClientContext } from "@getpaseo/plugin/client"; +import { SessionsSurface } from "./client/sessions"; + +export default function contribute(client: PluginClientContext) { + client.addSurface("sessions", SessionsSurface); + client.addSidebarItem({ id: "sessionforge", title: "SessionForge", icon: "Blocks", surface: "sessions" }); + client.addCommandCenterItem({ + id: "sessionforge-open", + title: "Open SessionForge", + icon: "Blocks", + context: "global", + onSelect({ openSurface }) { + openSurface("sessions"); + }, + }); + + return () => {}; +} diff --git a/index.server.ts b/index.server.ts new file mode 100644 index 0000000..42bbb2b --- /dev/null +++ b/index.server.ts @@ -0,0 +1,45 @@ +import type { PluginServerContext } from "@getpaseo/plugin/server"; +import { + archiveSessionRpc, + cleanupSessionsRpc, + deleteSessionsRpc, + discoverSessionsRpc, + listSessionsRpc, + restoreSessionRpc, + searchSessionsRpc, + showSessionRpc, +} from "./shared/session-contracts"; +import { + archiveSessionHandler, + cleanupSessions, + deleteSessionsHandler, + discoverSessions, + listSessions, + restoreSessionHandler, + searchSessions, + showSession, + stopBackgroundDiscovery, +} from "./server/session-handlers"; + +export default function contribute(server: PluginServerContext) { + server.handle(listSessionsRpc, listSessions); + server.handle(showSessionRpc, showSession); + server.handle(searchSessionsRpc, searchSessions); + server.handle(discoverSessionsRpc, discoverSessions); + server.handle(cleanupSessionsRpc, cleanupSessions); + server.handle(archiveSessionRpc, archiveSessionHandler); + server.handle(restoreSessionRpc, restoreSessionHandler); + server.handle(deleteSessionsRpc, deleteSessionsHandler); + + return () => { + try { + stopBackgroundDiscovery(); + } catch { + // Left over from the pre-0.8 single-entry-point architecture, where Paseo's main-process + // introspection pass could invoke this same cleanup in a context without real server bindings. Now + // that server code only ever runs in the daemon subprocess bundle, that specific scenario likely + // can't happen anymore — kept as a zero-cost safety net rather than removed on an assumption that + // hasn't been directly verified against the new architecture. + } + }; +} diff --git a/index.ts b/index.ts deleted file mode 100644 index 52b8305..0000000 --- a/index.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { PluginContext } from "@getpaseo/plugin"; -import { SessionsSurface } from "./main.client"; -import { - archiveSessionRpc, - cleanupSessionsRpc, - deleteSessionsRpc, - discoverSessionsRpc, - listSessionsRpc, - restoreSessionRpc, - searchSessionsRpc, - showSessionRpc, -} from "./src/server/session-contracts.shared"; -import { - archiveSessionHandler, - cleanupSessions, - deleteSessionsHandler, - discoverSessions, - listSessions, - restoreSessionHandler, - searchSessions, - showSession, - stopBackgroundDiscovery, -} from "./src/server/session-handlers.server"; - -export default function contribute(plugin: PluginContext) { - plugin.handle(listSessionsRpc, listSessions); - plugin.handle(showSessionRpc, showSession); - plugin.handle(searchSessionsRpc, searchSessions); - plugin.handle(discoverSessionsRpc, discoverSessions); - plugin.handle(cleanupSessionsRpc, cleanupSessions); - plugin.handle(archiveSessionRpc, archiveSessionHandler); - plugin.handle(restoreSessionRpc, restoreSessionHandler); - plugin.handle(deleteSessionsRpc, deleteSessionsHandler); - - plugin.addSurface("sessions", SessionsSurface); - plugin.addSidebarItem({ id: "sessionforge", title: "SessionForge", icon: "Blocks", surface: "sessions" }); - plugin.addCommandCenterItem({ - id: "sessionforge-open", - title: "Open SessionForge", - icon: "Blocks", - context: "global", - onSelect({ openSurface }) { - openSurface("sessions"); - }, - }); - - return () => { - try { - stopBackgroundDiscovery(); - } catch { - // The plugin-introspection pass in Paseo's main process also invokes this cleanup, - // in a context where server-only bindings aren't callable — safe to ignore there. - } - }; -} diff --git a/packages/cli/src/core/discover.server.test.ts b/packages/cli/src/core/discover.server.test.ts index 1cc7f40..c8299ed 100644 --- a/packages/cli/src/core/discover.server.test.ts +++ b/packages/cli/src/core/discover.server.test.ts @@ -11,6 +11,14 @@ function jsonl(...lines: Record[]): string { return `${lines.map((line) => JSON.stringify(line)).join("\n")}\n`; } +/** Relative to whenever the test actually runs, not a fixed calendar date — classifySession's + * ARCHIVE_AGE_DAYS (14) threshold is age-based, so a hardcoded past timestamp is a time bomb: it read as + * "recent" when first written, then silently flipped this fixture's own classification from KEEP to + * ARCHIVE once enough real time passed, breaking this test and the two others that depend on it. */ +function daysAgoIso(days: number): string { + return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString(); +} + describe("discover + lifecycle actions (integration)", () => { let root: string; let previousConfigDir: string | undefined; @@ -30,14 +38,14 @@ describe("discover + lifecycle actions (integration)", () => { { type: "user", message: { content: "please implement the search command end to end" }, - timestamp: "2026-08-20T10:00:00.000Z", + timestamp: daysAgoIso(2), cwd: "/home/amgln/demo", sessionId: "keep-session", }, { type: "assistant", message: { content: [{ type: "text", text: "Sure, starting now." }] }, - timestamp: "2026-08-20T10:00:05.000Z", + timestamp: daysAgoIso(2), cwd: "/home/amgln/demo", sessionId: "keep-session", }, @@ -50,7 +58,7 @@ describe("discover + lifecycle actions (integration)", () => { jsonl({ type: "user", message: { content: "test" }, - timestamp: "2026-08-21T10:00:00.000Z", + timestamp: daysAgoIso(1), cwd: "/home/amgln/demo", sessionId: "junk-session", }), diff --git a/paseo-plugin.d.ts b/paseo-plugin.d.ts index ca5f499..768a6fd 100644 --- a/paseo-plugin.d.ts +++ b/paseo-plugin.d.ts @@ -1,11 +1,12 @@ -declare module "@getpaseo/plugin/server" { - import type { PaseoApi } from "@getpaseo/client"; - import type { ZodType, input as ZodInput, output as ZodOutput } from "zod"; +// Hand-written ambient type declarations for @getpaseo/plugin's v0.8+ split client/server/shared module +// architecture (Paseo supplies the real runtime implementations at install time; consumers don't install +// this package themselves, so there's no real npm package here to pull types from). Reorganized from the +// pre-0.8 single-module shape when this plugin migrated for the v0.8 requirements.paseo breaking change — +// see https://paseo.sh/docs/plugins/v0.8/migration. +declare module "@getpaseo/plugin" { + import type { ZodType } from "zod"; - export interface PluginRpcContract< - InputSchema extends ZodType = ZodType, - OutputSchema extends ZodType = ZodType, - > { + export interface PluginRpcContract { name: string; input: InputSchema; output: OutputSchema; @@ -34,45 +35,47 @@ declare module "@getpaseo/plugin/server" { search: PluginRpcContract; } - export interface PluginHandlerContext { - paseo: PaseoApi; - } - export function defineRpc(definition: { name: string; input: InputSchema; output: OutputSchema; }): PluginRpcContract; - export function defineAttachmentSource( - definition: Definition, - ): Definition; + export function defineAttachmentSource(definition: Definition): Definition; export const PluginAttachmentItemSchema: import("zod").ZodType; export const PluginAttachmentSearchPayloadSchema: import("zod").ZodType; + + export type PluginCleanup = () => void | Promise; } -declare module "@getpaseo/plugin" { +declare module "@getpaseo/plugin/server" { + import type { PaseoApi } from "@getpaseo/client"; + import type { input as ZodInput, output as ZodOutput, ZodType } from "zod"; + import type { PluginCleanup, PluginRpcContract } from "@getpaseo/plugin"; + + export interface PluginHandlerContext { + paseo: PaseoApi; + } + + export interface PluginServerContext { + handle( + contract: PluginRpcContract, + handler: ( + input: ZodOutput, + context: PluginHandlerContext, + ) => ZodInput | Promise>, + ): void; + } + + export type PluginServerContribution = (server: PluginServerContext) => PluginCleanup; +} + +declare module "@getpaseo/plugin/client" { import type { ComponentType } from "react"; import type { PaseoApi } from "@getpaseo/client"; - import type { ZodType, input as ZodInput, output as ZodOutput } from "zod"; - import type { - PluginAttachmentSourceContribution, - PluginHandlerContext, - PluginRpcContract, - } from "@getpaseo/plugin/server"; - - export { - PluginAttachmentItemSchema, - PluginAttachmentSearchPayloadSchema, - defineAttachmentSource, - defineRpc, - type PluginAttachmentItem, - type PluginAttachmentSearchPayload, - type PluginAttachmentSourceContribution, - type PluginHandlerContext, - type PluginRpcContract, - } from "@getpaseo/plugin/server"; + import type { input as ZodInput, output as ZodOutput, ZodType } from "zod"; + import type { PluginAttachmentSourceContribution, PluginCleanup, PluginRpcContract } from "@getpaseo/plugin"; export interface PluginTheme { readonly colors: { @@ -140,11 +143,27 @@ declare module "@getpaseo/plugin" { } export type PluginPanelLocation = "workspace" | "explorer"; - export interface PluginOpenPanelOptions { location?: PluginPanelLocation; } + export interface PluginOpenPanelOptions { + location?: PluginPanelLocation; + } export type PluginWorkspacePanelContribution = - | { id: string; title: string; icon: string; locations?: readonly PluginPanelLocation[]; context: "workspace"; Component: ComponentType } - | { id: string; title: string; icon: string; locations?: readonly PluginPanelLocation[]; context: "agent"; Component: ComponentType }; + | { + id: string; + title: string; + icon: string; + locations?: readonly PluginPanelLocation[]; + context: "workspace"; + Component: ComponentType; + } + | { + id: string; + title: string; + icon: string; + locations?: readonly PluginPanelLocation[]; + context: "agent"; + Component: ComponentType; + }; export interface PluginSidebarContribution { id: string; @@ -203,18 +222,32 @@ declare module "@getpaseo/plugin" { } export type PluginCommandCenterItemContribution = - | { id: string; title: string; icon: string; keywords?: readonly string[]; context: "global"; onSelect(context: PluginGlobalCommandContext): void | Promise } - | { id: string; title: string; icon: string; keywords?: readonly string[]; context: "workspace"; onSelect(context: PluginWorkspaceCommandContext): void | Promise } - | { id: string; title: string; icon: string; keywords?: readonly string[]; context: "agent"; onSelect(context: PluginAgentCommandContext): void | Promise }; - - export interface PluginContext { - handle( - contract: PluginRpcContract, - handler: ( - input: ZodOutput, - context: PluginHandlerContext, - ) => ZodInput | Promise>, - ): void; + | { + id: string; + title: string; + icon: string; + keywords?: readonly string[]; + context: "global"; + onSelect(context: PluginGlobalCommandContext): void | Promise; + } + | { + id: string; + title: string; + icon: string; + keywords?: readonly string[]; + context: "workspace"; + onSelect(context: PluginWorkspaceCommandContext): void | Promise; + } + | { + id: string; + title: string; + icon: string; + keywords?: readonly string[]; + context: "agent"; + onSelect(context: PluginAgentCommandContext): void | Promise; + }; + + export interface PluginClientContext { addSurface(id: string, Component: ComponentType): void; addSidebarItem(contribution: PluginSidebarContribution): void; addWorkspacePanel(contribution: PluginWorkspacePanelContribution): void; @@ -223,8 +256,7 @@ declare module "@getpaseo/plugin" { addTheme(contribution: PluginThemeContribution): void; } - export type PluginCleanup = () => void | Promise; - export type PluginContribution = (plugin: PluginContext) => PluginCleanup; + export type PluginClientContribution = (client: PluginClientContext) => PluginCleanup; export function useRpc( contract: PluginRpcContract, @@ -232,13 +264,7 @@ declare module "@getpaseo/plugin" { export function usePaseo(): PaseoApi; - export function useWorkspace( - workspaceId: string, - selector: (workspace: PluginWorkspaceSnapshot) => Selection, - ): Selection | null; + export function useWorkspace(workspaceId: string, selector: (workspace: PluginWorkspaceSnapshot) => Selection): Selection | null; - export function useAgent( - agentId: string, - selector: (agent: PluginAgentSnapshot) => Selection, - ): Selection | null; + export function useAgent(agentId: string, selector: (agent: PluginAgentSnapshot) => Selection): Selection | null; } diff --git a/paseo-plugin.json b/paseo-plugin.json index b8b0d2b..1027ab5 100644 --- a/paseo-plugin.json +++ b/paseo-plugin.json @@ -1,3 +1,4 @@ { - "id": "sessionforge" + "id": "sessionforge", + "requirements": { "paseo": ">=0.8.0" } } diff --git a/scripts/package-plugin.mjs b/scripts/package-plugin.mjs index 263f4de..703c4e6 100644 --- a/scripts/package-plugin.mjs +++ b/scripts/package-plugin.mjs @@ -1,7 +1,10 @@ #!/usr/bin/env node -// Packages this repo's Paseo plugin (index.ts, main.client.tsx, src/server/*) into a self-contained -// directory, then tars it — the artifact `sessionforge wire-paseo` downloads and points a local -// `paseo plugin install` at, so a user doesn't need to clone this whole monorepo just to get the plugin. +// Packages this repo's Paseo plugin (index.client.tsx, index.server.ts, client/, server/, shared/) into a +// self-contained directory, then tars it — the artifact `sessionforge wire-paseo` downloads and points a +// local `paseo plugin install` at, so a user doesn't need to clone this whole monorepo just to get the +// plugin. File layout follows Paseo's v0.8+ split client/server/shared architecture (see +// https://paseo.sh/docs/plugins/v0.8/migration) — "the directory is the boundary": code under client/ +// compiles only into the app bundle, server/ only into the daemon bundle, shared/ into both. // // This can't just be "git clone the repo and let Paseo build it" (verified empirically): Paseo's // git-source plugin install does a fresh checkout and bundles the plugin directly, with no npm-workspace @@ -24,10 +27,20 @@ const buildDir = join(repoRoot, "build"); const stageDir = join(buildDir, "paseo-plugin"); const archivePath = join(buildDir, "sessionforge-paseo-plugin.tar.gz"); -// Everything the plugin's own source actually imports (`index.ts`, `main.client.tsx`, `src/server/*`) — -// verified by reading the actual import statements, not guessed. `tsconfig.json` isn't required at -// runtime (Paseo transpiles the plugin's TS/TSX on the fly) but costs nothing to include. -const PLUGIN_FILES = ["paseo-plugin.json", "paseo-plugin.d.ts", "index.ts", "main.client.tsx", "package.json", "tsconfig.json", "src/server"]; +// Everything the plugin's own source actually imports (`index.client.tsx`, `index.server.ts`, `client/`, +// `server/`, `shared/`) — verified by reading the actual import statements, not guessed. `tsconfig.json` +// isn't required at runtime (Paseo transpiles the plugin's TS/TSX on the fly) but costs nothing to include. +const PLUGIN_FILES = [ + "paseo-plugin.json", + "paseo-plugin.d.ts", + "index.client.tsx", + "index.server.ts", + "client", + "server", + "shared", + "package.json", + "tsconfig.json", +]; function main() { const cliDist = join(repoRoot, "packages", "cli", "dist"); diff --git a/src/server/session-handlers.server.ts b/server/session-handlers.ts similarity index 100% rename from src/server/session-handlers.server.ts rename to server/session-handlers.ts diff --git a/src/server/session-contracts.shared.ts b/shared/session-contracts.ts similarity index 98% rename from src/server/session-contracts.shared.ts rename to shared/session-contracts.ts index c694816..5210bf0 100644 --- a/src/server/session-contracts.shared.ts +++ b/shared/session-contracts.ts @@ -1,4 +1,4 @@ -import { defineRpc } from "@getpaseo/plugin/server"; +import { defineRpc } from "@getpaseo/plugin"; import { z } from "zod"; export const AgentIdSchema = z.enum(["claude-code", "codex", "gemini-cli", "aider", "opencode", "custom"]);