Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ updates:
- "*"
# The app supplies these to a running plugin, so a plugin's own copy is a
# type-checking stand-in for whatever Paseo ships, not a dependency it can
# move on its own. @getpaseo/plugin peer-depends on the exact react the
# app bundles, so bumping react (and react-native, which drags react with
# it) fails ERESOLVE outright; the others merely let the typechecker
# describe APIs the host does not have. They move by hand, when Paseo's
# `plugin init` scaffold moves.
# move on its own: a newer copy lets the typechecker describe APIs the
# host does not have. They move by hand, to the versions in Paseo's
# `packages/app/package.json` at the release `paseo-plugin.json` requires.
ignore:
- dependency-name: react
- dependency-name: react-native
Expand Down
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,32 @@ pin and a line to read before you move.

## [Unreleased]

### Changed

- **Requires Paseo 0.13.0.** The plugin now builds against `@getpaseo/plugin` 0.13.0 and registers
through the APIs that replace the ones 0.13.0 deprecates: `addScreen`, `addSidebarHeaderItem` and
`openScreen` instead of `addSurface`, `addSidebarItem` and `openSurface`, and
`@getpaseo/plugin/client/ui` instead of `@getpaseo/plugin/client/react-native`. Paseo removes the
old ones after April 2027. The `react` and `react-native` type stand-ins follow the 0.13.0 app
(19.2.3 and 0.86.3). An app or daemon on 0.12 or older refuses to load the plugin.

### Fixed

- **The client loads again on current Paseo** (#11). Lucide dropped its brand icons, so `Github`
no longer resolved and the host rejected the whole client registration with `Unknown Lucide
icon: Github`. The sidebar row, the settings screen, the command-center entry and the timeline
card use `GitPullRequest`. Thanks to @keithpk for the report and the fix.

### Security

- **The 11 open Dependabot advisories are closed.** vite 8.3.5 and vitest 5.0.5 (with
`@vitest/mocker`) fix the dev-server file disclosure, `launch-editor` command injection and mock
registration advisories; shell-quote 1.12.0 fixes the `quote()` command injection;
brace-expansion 1.x and sprintf-js left the tree with react-native 0.86.3. zod moved to 4.6.7 for
the oversized-collection memory exhaustion `npm audit` reports. All of these are development or
type-checking dependencies: Paseo compiles the plugin and supplies every module it imports at
runtime, so no installed copy of the plugin ran them.

## [1.0.1] — 2026-09-12

### Changed
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ row that fails validation still renders as nothing rather than throwing.

Still `props.navigation.openAgent({ agentId })`, run in the client bundle because the server half
lives beside the daemon, which on a remote host is a different machine from the one the user is
looking at. The plugin now requires Paseo `>=0.8.0` outright, so the pre-navigation-prop fallback
looking at. The plugin now requires Paseo `>=0.13.0` outright, so the pre-navigation-prop fallback
this section used to describe is gone: every client that can run this bundle at all received the
`navigation` prop with it.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ command to run and a button to copy it, rather than an error.

## Install

Requires Paseo **0.8.0 or newer** on the daemon *and* on the app, plus the
Requires Paseo **0.13.0 or newer** on the daemon *and* on the app, plus the
[`gh` CLI](https://cli.github.com/) authenticated on the daemon machine — the plugin shells out to
it and never handles a token itself.

Expand Down
2 changes: 1 addition & 1 deletion client/board/board-header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PluginSurfaceProps } from "@getpaseo/plugin/client";
import { Icon } from "@getpaseo/plugin/client/react-native";
import { Icon } from "@getpaseo/plugin/client/ui";
import { ActivityIndicator, Pressable, Text, View } from "react-native";

import type { Board } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/board/item-row.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { memo, useCallback, useState } from "react";
import { Icon } from "@getpaseo/plugin/client/react-native";
import { Icon } from "@getpaseo/plugin/client/ui";
import type { PluginSurfaceProps } from "@getpaseo/plugin/client";
import { Pressable, Text, View } from "react-native";

Expand Down
24 changes: 24 additions & 0 deletions client/board/sidebar-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { PluginSidebarItemProps } from "@getpaseo/plugin/client";
import { SidebarRow } from "@getpaseo/plugin/client/ui";

/**
* The board's screen id, shared by `addScreen`, this row and the command-center entry. It stays
* `"board"`, the id the legacy `addSidebarItem` registration used: Paseo resolves a remembered
* `/sidebar/board` route to a screen with the same id, so a restored tab still lands on the board.
*/
export const BOARD_SCREEN_ID = "board";

/**
* The sidebar header row. The host draws one row per item even with several hosts connected, picks
* the host itself, and labels the row with the registered title, so this only decides the icon and
* when the row reads as active.
*/
export function BoardSidebarItem(props: PluginSidebarItemProps) {
return (
<SidebarRow
icon="GitPullRequest"
active={props.currentScreen?.screenId === BOARD_SCREEN_ID}
onPress={() => props.openScreen({ screenId: BOARD_SCREEN_ID })}
/>
);
}
4 changes: 2 additions & 2 deletions client/board/use-board-overlays.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { PluginSurfaceProps } from "@getpaseo/plugin/client";
import { useToast } from "@getpaseo/plugin/client/react-native";
import { useToast } from "@getpaseo/plugin/client/ui";
import { Animated, Easing, Platform, StatusBar, View } from "react-native";

import type { Board, BoardItem, ColumnId, PromptSettings } from "../../shared/board";
Expand Down Expand Up @@ -228,7 +228,7 @@ export function useBoardOverlays(
* `navigateToAgent` against the host rendering the surface.
*
* The prop is still typed optional because hosts before 0.7.0-beta.3 passed
* nothing. This plugin now requires Paseo >=0.8.0, and each app checks that
* nothing. This plugin now requires Paseo >=0.13.0, and each app checks that
* against its *own* version before it evaluates this bundle, so every client
* that can run this code passes it. The `undefined` branch therefore only
* leaves the notice standing — which already names the workspace the work went
Expand Down
2 changes: 1 addition & 1 deletion client/board/use-board-settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { type SettingsState, useRpc, useSettings } from "@getpaseo/plugin/client";
import { useToast } from "@getpaseo/plugin/client/react-native";
import { useToast } from "@getpaseo/plugin/client/ui";
import type { SettingsDefinition } from "@getpaseo/plugin";

import type { PromptSettings } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/detail/detail-comments.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Icon } from "@getpaseo/plugin/client/react-native";
import { Icon } from "@getpaseo/plugin/client/ui";
import { ActivityIndicator, Pressable, Text, View } from "react-native";

import type { ItemComment } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/detail/detail-header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Icon } from "@getpaseo/plugin/client/react-native";
import { Icon } from "@getpaseo/plugin/client/ui";
import { Pressable, Text, View } from "react-native";

import type { ItemDetails } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/detail/merge-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Modal } from "@getpaseo/plugin/client/react-native";
import { Modal } from "@getpaseo/plugin/client/ui";
import { Pressable, Text } from "react-native";

import type { BoardItem, MergeMethod } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/detail/use-item-actions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useState } from "react";
import { useToast } from "@getpaseo/plugin/client/react-native";
import { useToast } from "@getpaseo/plugin/client/ui";
import { useRpc } from "@getpaseo/plugin/client";

import type { BoardItem, ItemDetails, MergeMethod } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/launch/pickers.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type React from "react";
import { ScrollView as SheetScrollView } from "@getpaseo/plugin/client/react-native";
import { ScrollView as SheetScrollView } from "@getpaseo/plugin/client/ui";
import { Pressable, Text, View } from "react-native";

import type { Styles } from "../theme/use-styles";
Expand Down
2 changes: 1 addition & 1 deletion client/launch/send-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Modal, TextInput as SheetTextInput } from "@getpaseo/plugin/client/react-native";
import { Modal, TextInput as SheetTextInput } from "@getpaseo/plugin/client/ui";
import { Pressable, Text } from "react-native";

import type { BoardItem } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/launch/use-send-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import { usePaseo, useRpc } from "@getpaseo/plugin/client";
import { useToast } from "@getpaseo/plugin/client/react-native";
import { useToast } from "@getpaseo/plugin/client/ui";
import { Keyboard } from "react-native";

import type { BoardItem, Isolation, LaunchDefaults } from "../../shared/board";
Expand Down
2 changes: 1 addition & 1 deletion client/projects/project-board-view.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PluginSurfaceProps } from "@getpaseo/plugin/client";
import { Icon } from "@getpaseo/plugin/client/react-native";
import { Icon } from "@getpaseo/plugin/client/ui";
import { useRpc } from "@getpaseo/plugin/client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { ActivityIndicator, Pressable, ScrollView, Text, View } from "react-native";
Expand Down
2 changes: 1 addition & 1 deletion client/projects/projects-list-view.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PluginSurfaceProps } from "@getpaseo/plugin/client";
import { copyText, Icon } from "@getpaseo/plugin/client/react-native";
import { copyText, Icon } from "@getpaseo/plugin/client/ui";
import { useRpc } from "@getpaseo/plugin/client";
import { useCallback, useEffect, useRef, useState } from "react";
import { ActivityIndicator, Pressable, ScrollView, Text, View } from "react-native";
Expand Down
2 changes: 1 addition & 1 deletion client/settings/settings-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
* gear button with nowhere to go.
*/
import { type PluginSurfaceProps, useRpc, useSettings } from "@getpaseo/plugin/client";
import { useToast } from "@getpaseo/plugin/client/react-native";
import {
SettingsAction,
SettingsInput,
type SettingsInputHandle,
SettingsRow,
SettingsSection,
useToast,
} from "@getpaseo/plugin/client/ui";
import { useCallback, useMemo, useRef, useState } from "react";
import { View } from "react-native";
Expand Down
2 changes: 1 addition & 1 deletion client/timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* outcome as never having appended one.
*/
import type { PluginTimelineItemProps } from "@getpaseo/plugin/client";
import { Icon } from "@getpaseo/plugin/client/react-native";
import { Icon } from "@getpaseo/plugin/client/ui";
import { useMemo } from "react";
import { Pressable, Text, View } from "react-native";

Expand Down
12 changes: 4 additions & 8 deletions index.client.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { PluginClientContext } from "@getpaseo/plugin/client";

import { GitHubBoard } from "./client/board/github-board";
import { BOARD_SCREEN_ID, BoardSidebarItem } from "./client/board/sidebar-item";
import { BoardSettingsScreen } from "./client/settings/settings-screen";
import { BoardTimelineCard } from "./client/timeline";
import { BoardTimelineItemSchema } from "./shared/board";
import { BOARD_ITEM_TIMELINE_KIND, BOARD_ITEM_TIMELINE_VERSION } from "./shared/timeline";

export default function contribute(client: PluginClientContext) {
client.addSurface("board", GitHubBoard);
client.addScreen({ id: BOARD_SCREEN_ID, title: "GitHub", Component: GitHubBoard });
/**
* Renders the rows `sendToChatHandler` appends. The `kind`/`version` pair has
* to match what the daemon wrote, which is why both sides import it from
Expand All @@ -23,12 +24,7 @@ export default function contribute(client: PluginClientContext) {
schema: BoardTimelineItemSchema,
Component: BoardTimelineCard,
});
client.addSidebarItem({
id: "board",
title: "GitHub",
icon: "GitPullRequest",
surface: "board",
});
client.addSidebarHeaderItem({ id: BOARD_SCREEN_ID, title: "GitHub", Component: BoardSidebarItem });
client.addSettingsScreen({
id: "board",
title: "GitHub board",
Expand All @@ -52,7 +48,7 @@ export default function contribute(client: PluginClientContext) {
keywords: ["github", "issues", "pull requests", "prs", "discussions"],
context: "global",
onSelect(context) {
context.openSurface("board");
context.openScreen({ screenId: BOARD_SCREEN_ID });
},
});

Expand Down
Loading
Loading