paseo-kanban 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/OVERVIEW.md ADDED
@@ -0,0 +1,9 @@
1
+ # Kanban
2
+
3
+ Organize tasks in customizable swimlanes, add descriptions and subtasks, and link tasks to Paseo projects. Drag cards to reorder them within a lane or move them between lanes.
4
+
5
+ Open the board from the sidebar or from a workspace's `+` menu. Workspace tabs initially filter to their project's tasks and can sit beside an agent or terminal using Paseo's native split controls. Each open board has its own project filter; all boards on the same host share tasks and lanes.
6
+
7
+ Board data is stored in Paseo's host-scoped plugin settings. Concurrent edits use revision checks so a stale edit cannot overwrite a newer board. If a project's name cannot be read, its stored ID remains available. If workspace project context is unavailable when the board opens, it initially shows all tasks.
8
+
9
+ Requires Paseo 0.8.0 or later. No accounts, tokens, or additional setup are required.
package/README.md CHANGED
@@ -8,11 +8,12 @@ A lightweight, responsive Kanban board plugin for [Paseo](https://paseo.sh) work
8
8
 
9
9
  ## Features
10
10
 
11
- - **Flexible Swimlanes**: Default lanes (`To Plan`, `In Progress`, `Done`) with full support for adding, renaming, and deleting custom lanes.
11
+ - **Flexible Swimlanes**: Three initial lanes that you can rename, with support for adding and deleting custom lanes.
12
12
  - **Rich Task Cards**:
13
- - Task title and multi-line markdown description.
13
+ - Task title and multi-line description.
14
14
  - Subtasks checklist with completion toggles and live progress tracking.
15
15
  - Native Paseo project association.
16
+ - **Workspace Tabs and Splits**: Open the board beside an agent or terminal, initially filtered to the workspace's project. The sidebar remains available.
16
17
  - **Project Filtering**: Instantly filter board cards by linked Paseo project to keep context focused.
17
18
  - **Smooth Drag-and-Drop**: Real-time hit-testing for reordering cards within lanes and moving cards across lanes.
18
19
  - **Versioned State Persistence**: Persists board data through Paseo's settings API with optimistic concurrency control (CAS) to prevent race conditions and accidental overwrites.
@@ -21,8 +22,8 @@ A lightweight, responsive Kanban board plugin for [Paseo](https://paseo.sh) work
21
22
 
22
23
  ## Requirements
23
24
 
24
- - **Paseo Host Runtime Commitment**: `>= 0.8.0` (declared in `paseo-plugin.json`). As a Paseo workspace plugin, production runtime execution is managed and hosted by the Paseo application environment. No consumer-side Node version restriction is imposed in `package.json`.
25
- - **Development & CI Baseline**: Node.js 24 (pinned in `.nvmrc` and `.node-version`). Node 24 is required for local contributors and CI automation workflows running quality checks (`npm run check`), type stripping (`--experimental-strip-types`), and native test suites (`node --test`).
25
+ - **Paseo host**: `>= 0.8.0` (declared in `paseo-plugin.json`). The host runs the plugin.
26
+ - **Development and CI**: Node.js 24 (pinned in `.nvmrc` and `.node-version`) for checks, TypeScript stripping, and native tests.
26
27
 
27
28
  ---
28
29
 
@@ -30,7 +31,7 @@ A lightweight, responsive Kanban board plugin for [Paseo](https://paseo.sh) work
30
31
 
31
32
  ### Quick Install (Recommended)
32
33
 
33
- No manual build or git cloning needed. You can install directly via npm or GitHub:
34
+ Install directly from npm or GitHub:
34
35
 
35
36
  **Via NPM (Release package):**
36
37
 
@@ -56,7 +57,12 @@ Verify that the plugin is running:
56
57
  paseo plugin ls
57
58
  ```
58
59
 
59
- Once active, open Paseo. The **Kanban** icon (`PanelsTopLeft`) will appear in the sidebar. Click it to launch the board.
60
+ Once active, open the board from either entry:
61
+
62
+ - **Sidebar → Kanban**: shows all tasks by default.
63
+ - **Workspace → `+` → Kanban**: initially filters to the workspace's project, with other filters available. Use Paseo's native split controls to place it beside an agent or terminal.
64
+
65
+ Both entries share tasks and lanes with full editing support; their filters are independent. Closing and reopening the board or restarting restores the entry's default filter. If workspace project context is unavailable, the board silently shows all tasks and keeps that filter even if context arrives later. Narrow splits retain horizontal lane scrolling.
60
66
 
61
67
  ### Local Development
62
68
 
@@ -66,7 +72,7 @@ To contribute or debug locally:
66
72
  # 1. Clone repository and install dependencies
67
73
  git clone https://github.com/breathi3552/paseo-kanban.git
68
74
  cd paseo-kanban
69
- npm install
75
+ npm ci
70
76
 
71
77
  # 2. Link this directory into your local Paseo daemon
72
78
  paseo plugin link .
@@ -76,56 +82,26 @@ paseo plugin link .
76
82
 
77
83
  ## Development & Testing
78
84
 
79
- ### Install Dependencies
85
+ Install dependencies and run the full quality check:
80
86
 
81
87
  ```bash
82
- npm install
83
- # or clean install:
84
88
  npm ci
89
+ npm run check
85
90
  ```
86
91
 
87
- ### Unified Quality Guardrails (Check)
92
+ Individual commands (`npm test`, `npm run typecheck`, `npm run lint`, `npm run format:check`, `npm run check:package`) are defined in [`package.json`](./package.json). For tag-based publishing, release sources of truth, recovery, and host acceptance, see the [development guide](./docs/development.md#21-标签发布github-actions).
88
93
 
89
- Runs typecheck, automated test suites, linting, format verification, and release package checks in sequence:
94
+ ---
90
95
 
91
- ```bash
92
- npm run check
93
- ```
96
+ ## Releases
94
97
 
95
- ### Individual Quality Tasks
96
-
97
- - **Package Verification**: Validates release package contents, entrypoints, and TypeScript AST relative imports:
98
- ```bash
99
- npm run check:package
100
- ```
101
- - **Run Tests**: Cross-platform auto-discovery of all `test/*.test.mjs` suites:
102
- ```bash
103
- npm test
104
- ```
105
- - **Type Checking**: Validates TypeScript types across client and server entry points:
106
- ```bash
107
- npm run typecheck
108
- ```
109
- - **Linting**: Static code analysis with ESLint:
110
- ```bash
111
- npm run lint
112
- ```
113
- - **Formatting**: Check or format code style with Prettier:
114
- ```bash
115
- npm run format:check
116
- npm run format
117
- ```
118
-
119
- Maintainers can publish a new GitHub Release and npm package in one run of the **Release to GitHub and npm** GitHub Action: select `patch`, `minor`, or `major`. Configure `NPM_TOKEN` and repository write permissions first. For setup, recovery, and manual host acceptance, see the [Development & Acceptance Guide](./docs/development.md#24-一键发布github-actions).
98
+ See the [0.1.3 release notes](./docs/releases/0.1.3.md). Each release's npm package and GitHub Release share the same version tag; GitHub includes the verified npm tarball. `main` may contain changes beyond the latest release.
120
99
 
121
100
  ---
122
101
 
123
102
  ## Architecture & Design
124
103
 
125
- The complete architectural breakdown and interactive visual diagram are archived in the repository:
126
-
127
- - **Interactive Architecture Viewer**: Open [`docs/architecture/paseo-kanban.architecture.html`](./docs/architecture/paseo-kanban.architecture.html) in your browser.
128
- - **Architecture Schema & Model**: [`docs/architecture/paseo-kanban.architecture.json`](./docs/architecture/paseo-kanban.architecture.json).
104
+ Core terminology and design decisions are documented in [`CONTEXT.md`](./CONTEXT.md) and [`docs/adr/`](./docs/adr/).
129
105
 
130
106
  ---
131
107
 
package/README.zh-CN.md CHANGED
@@ -13,16 +13,17 @@
13
13
  - 任务标题与多行描述编辑。
14
14
  - 子步骤清单支持独立增删改、完成状态勾选及实时进度展示。
15
15
  - 支持关联本地已有的 Paseo 项目。
16
+ - **工作区标签页与分屏**:与 Agent、Terminal 并排打开看板,默认筛选工作区所属项目;保留侧边栏入口。
16
17
  - **项目维度筛选**:一键按关联的 Paseo 项目过滤看板卡片,聚焦当前目标。
17
18
  - **流畅拖拽交互**:精准的拖拽命中测试(Hit-Testing),支持同泳道排序与跨泳道状态流转。
18
- - **版本化数据持久化**:基于 Paseo 原生 settings API 存储,内置乐观并发版本控制(CAS),杜绝多会话覆写与状态不一致。
19
+ - **版本化数据持久化**:通过 Paseo settings API 存储看板,使用乐观并发版本控制(CAS)处理多会话写入冲突。
19
20
 
20
21
  ---
21
22
 
22
23
  ## 环境要求
23
24
 
24
- - **Paseo 宿主版本承诺**:`>= 0.8.0`(声明于 `paseo-plugin.json`)。作为 Paseo 工作区插件,插件的生产运行时环境由 Paseo 宿主应用提供并托管执行,不在 `package.json` 对消费端强加额外的 `engines.node` 限制。
25
- - **开发与 CI 环境基线**:Node.js 24(显式声明于 `.nvmrc` 与 `.node-version`)。本地参与开发、运行质量检查护栏(`npm run check`)、代码格式化、类型检查与自动化测试必须基于 Node 24,依赖其原生的 `--experimental-strip-types` 类型擦除与原生测试运行器(`node --test`)。
25
+ - **Paseo 宿主**:`>= 0.8.0`(声明于 `paseo-plugin.json`),由 Paseo 运行插件。
26
+ - **开发与 CI**:使用 Node.js 24(声明于 `.nvmrc` 与 `.node-version`)执行质量检查、TypeScript 类型擦除和原生测试。
26
27
 
27
28
  ---
28
29
 
@@ -30,7 +31,7 @@
30
31
 
31
32
  ### 快速安装(推荐)
32
33
 
33
- 无需克隆源码或手动编译,推荐直接使用 Paseo CLI 安装:
34
+ 通过 Paseo CLI 从 npm 或 GitHub 安装:
34
35
 
35
36
  **方式一:通过 NPM 官方包安装(推荐)**
36
37
 
@@ -56,7 +57,12 @@ paseo plugin add breathi3552/paseo-kanban --ref main
56
57
  paseo plugin ls
57
58
  ```
58
59
 
59
- 状态显示为 `running` 后打开 Paseo,侧边栏将出现 **看板** 入口(图标:`PanelsTopLeft`),点击即可进入看板。
60
+ 状态显示为 `running` 后,可从两个入口打开看板:
61
+
62
+ - **侧边栏 → 看板**:默认展示全部任务。
63
+ - **工作区 → `+` → 看板**:默认筛选工作区所属项目,可切换范围;使用 Paseo 原生分屏操作与 Agent、Terminal 等并排显示。
64
+
65
+ 两个入口共享任务和泳道,保留完整编辑能力,筛选互不影响。关闭重开或重启后恢复入口默认筛选。无法取得工作区所属项目时静默展示全部任务,本次打开期间不因项目上下文恢复而自动切换。窄分屏保持横向滚动浏览泳道。
60
66
 
61
67
  ### 本地开发与调试
62
68
 
@@ -66,7 +72,7 @@ paseo plugin ls
66
72
  # 1. 克隆代码仓库并安装依赖
67
73
  git clone https://github.com/breathi3552/paseo-kanban.git
68
74
  cd paseo-kanban
69
- npm install
75
+ npm ci
70
76
 
71
77
  # 2. 将当前开发目录软链接至本地 Paseo 守护进程
72
78
  paseo plugin link .
@@ -76,58 +82,26 @@ paseo plugin link .
76
82
 
77
83
  ## 开发与测试
78
84
 
79
- ### 安装依赖
85
+ 安装依赖并运行完整检查:
80
86
 
81
87
  ```bash
82
- npm install
83
- # 或干净安装验证:
84
88
  npm ci
89
+ npm run check
85
90
  ```
86
91
 
87
- ### 统一质量护栏检查
92
+ 单项命令(`npm test`、`npm run typecheck`、`npm run lint`、`npm run format:check`、`npm run check:package`)见 [`package.json`](./package.json)。标签发布、事实来源、失败重试与宿主验收见[开发指南](./docs/development.md#21-标签发布github-actions)。
88
93
 
89
- 按顺序执行类型检查、自动化测试套件、静态代码检查、代码格式验证及发布包完整性检查:
94
+ ---
90
95
 
91
- ```bash
92
- npm run check
93
- ```
96
+ ## 版本发布
94
97
 
95
- ### 各独立质量命令
96
-
97
- - **发布包完整性检查**:静态校验发布包产物清单、入口完整性与 TypeScript AST 相对导入闭包:
98
- ```bash
99
- npm run check:package
100
- ```
101
- - **运行单元测试**:跨平台自动发现并执行所有 `test/*.test.mjs` 测试套件:
102
- ```bash
103
- npm test
104
- ```
105
- - **类型检查**:校验前端组件与服务端扩展的 TypeScript 类型完整性:
106
- ```bash
107
- npm run typecheck
108
- ```
109
- - **代码规范检查 (Lint)**:基于 ESLint 开展轻量静态检查:
110
- ```bash
111
- npm run lint
112
- ```
113
- - **代码格式检查与格式化 (Format)**:基于 Prettier 校验或自动格式化:
114
- ```bash
115
- npm run format:check
116
- npm run format
117
- ```
118
-
119
- 维护者可在 GitHub Actions 的 **Release to GitHub and npm** 工作流中选择 `patch` / `minor` / `major` 一键发布 GitHub Release 与 npm 包;首次使用需配置 `NPM_TOKEN` 和仓库写入权限。操作及失败重试说明见 [开发与宿主验收指南](./docs/development.md#24-一键发布github-actions)。
120
-
121
- 详细开发贡献流程、发布前检查机制与真实宿主环境手工验收指南,请参阅 [开发与宿主验收指南](./docs/development.md)。
98
+ 参见 [0.1.3 版本说明](./docs/releases/0.1.3.md)。每版 npm 包与 GitHub Release 对应同一个版本 tag,GitHub 附带经过验证的 npm tarball。`main` 可能包含最新发布版之后的改动。
122
99
 
123
100
  ---
124
101
 
125
102
  ## 架构设计
126
103
 
127
- 完整的插件架构图景与交互式全景模型已归档于仓库:
128
-
129
- - **交互式架构全景图**:直接使用浏览器打开 [`docs/architecture/paseo-kanban.architecture.html`](./docs/architecture/paseo-kanban.architecture.html) 查看。
130
- - **架构定义元数据**:[`docs/architecture/paseo-kanban.architecture.json`](./docs/architecture/paseo-kanban.architecture.json)。
104
+ 核心术语和架构决策见 [`CONTEXT.md`](./CONTEXT.md) 与 [`docs/adr/`](./docs/adr/)。
131
105
 
132
106
  ---
133
107
 
@@ -6,6 +6,7 @@ import {
6
6
  Pressable,
7
7
  StyleSheet,
8
8
  ActivityIndicator,
9
+ type LayoutChangeEvent,
9
10
  } from "react-native";
10
11
  import { useSettings } from "@getpaseo/plugin/client";
11
12
  import type { PluginSurfaceProps } from "@getpaseo/plugin/client";
@@ -25,8 +26,23 @@ import {
25
26
  } from "./kanban-session";
26
27
  import { useI18n } from "./i18n";
27
28
 
28
- export function KanbanBoardView(props: PluginSurfaceProps) {
29
- const { theme, layout } = props;
29
+ interface KanbanBoardProps extends PluginSurfaceProps {
30
+ initialProjectId?: string | null;
31
+ }
32
+
33
+ export function KanbanBoardView(props: KanbanBoardProps) {
34
+ const { theme } = props;
35
+ const [panelWidth, setPanelWidth] = useState<number | null>(null);
36
+ const compact =
37
+ props.layout.compact || (panelWidth !== null && panelWidth < 600);
38
+ const layout = useMemo(
39
+ () => ({ ...props.layout, compact }),
40
+ [props.layout, compact],
41
+ );
42
+ const handleLayout = (event: LayoutChangeEvent) => {
43
+ const { width } = event.nativeEvent.layout;
44
+ if (width > 0) setPanelWidth(width);
45
+ };
30
46
  const { t, language } = useI18n(props);
31
47
  const settings = useSettings(kanbanSettings);
32
48
  const {
@@ -35,13 +51,29 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
35
51
  isError: projectsError,
36
52
  } = useProjects();
37
53
 
38
- const [selectedProjectId, setSelectedProjectId] = useState<string>("all");
54
+ const [selectedProjectId, setSelectedProjectId] = useState(
55
+ props.initialProjectId || "all",
56
+ );
39
57
  const [activeTaskSession, setActiveTaskSession] =
40
58
  useState<TaskEditSession | null>(null);
41
59
  const [activeLaneSession, setActiveLaneSession] =
42
60
  useState<LaneEditSession | null>(null);
43
61
  const [reorderError, setReorderError] = useState<string | null>(null);
44
62
 
63
+ const selectableProjects = useMemo(() => {
64
+ const missingIds = new Set([props.initialProjectId, selectedProjectId]);
65
+ const missingProjects = [...missingIds]
66
+ .filter(
67
+ (id): id is string =>
68
+ !!id &&
69
+ id !== "all" &&
70
+ id !== "unassigned" &&
71
+ !projects.some((project) => project.projectId === id),
72
+ )
73
+ .map((id) => ({ projectId: id, projectDisplayName: id }));
74
+ return [...projects, ...missingProjects];
75
+ }, [projects, props.initialProjectId, selectedProjectId]);
76
+
45
77
  const isReady = settings.status === "ready";
46
78
  const board = isReady ? settings.values : null;
47
79
  const revision = isReady ? settings.revision : "";
@@ -154,6 +186,8 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
154
186
  StyleSheet.create({
155
187
  container: {
156
188
  flex: 1,
189
+ minWidth: 0,
190
+ minHeight: 0,
157
191
  backgroundColor: theme.colors.surface0,
158
192
  userSelect: "none",
159
193
  },
@@ -174,6 +208,9 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
174
208
  },
175
209
  titleRow: {
176
210
  flexDirection: "row",
211
+ flexWrap: "wrap",
212
+ flexShrink: 1,
213
+ maxWidth: "100%",
177
214
  alignItems: "center",
178
215
  gap: 8,
179
216
  },
@@ -184,6 +221,8 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
184
221
  },
185
222
  headerActions: {
186
223
  flexDirection: "row",
224
+ flexWrap: "wrap",
225
+ maxWidth: "100%",
187
226
  alignItems: "center",
188
227
  gap: 8,
189
228
  },
@@ -270,6 +309,7 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
270
309
  },
271
310
  lanesWrapper: {
272
311
  flex: 1,
312
+ minHeight: 0,
273
313
  position: "relative",
274
314
  userSelect: "none",
275
315
  },
@@ -370,7 +410,7 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
370
410
  if (!board) return null;
371
411
 
372
412
  return (
373
- <View style={styles.container}>
413
+ <View style={styles.container} onLayout={handleLayout}>
374
414
  {/* Top Header */}
375
415
  <View style={styles.header}>
376
416
  <View style={styles.headerTopRow}>
@@ -462,7 +502,7 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
462
502
  </Text>
463
503
  </Pressable>
464
504
 
465
- {projects.map((proj) => {
505
+ {selectableProjects.map((proj) => {
466
506
  const isSelected = selectedProjectId === proj.projectId;
467
507
  return (
468
508
  <Pressable
@@ -567,7 +607,7 @@ export function KanbanBoardView(props: PluginSurfaceProps) {
567
607
  open={activeTaskSession !== null}
568
608
  onClose={() => setActiveTaskSession(null)}
569
609
  session={activeTaskSession}
570
- projects={projects}
610
+ projects={selectableProjects}
571
611
  theme={theme}
572
612
  layout={layout}
573
613
  />
@@ -90,7 +90,6 @@ export interface TaskPreviewItem {
90
90
 
91
91
  export interface KanbanDragOptions {
92
92
  lanes?: ({ id: string } | string)[];
93
- onMoveTask?: (taskId: string, targetLaneId: string) => void | Promise<void>;
94
93
  onReorderTask?: (
95
94
  taskId: string,
96
95
  targetLaneId: string,
@@ -175,10 +174,6 @@ export class KanbanDragController {
175
174
  private containerRef: ContainerRefTarget | null = null;
176
175
  private scrollX: number = 0;
177
176
  private activeSession: ActiveDragSession | null = null;
178
- private onMoveTask?: (
179
- taskId: string,
180
- targetLaneId: string,
181
- ) => void | Promise<void>;
182
177
  private onReorderTask?: (
183
178
  taskId: string,
184
179
  targetLaneId: string,
@@ -231,9 +226,6 @@ export class KanbanDragController {
231
226
  if (options?.lanes) {
232
227
  this.setLanes(options.lanes);
233
228
  }
234
- if (options?.onMoveTask) {
235
- this.setOnMoveTask(options.onMoveTask);
236
- }
237
229
  if (options?.onReorderTask) {
238
230
  this.setOnReorderTask(options.onReorderTask);
239
231
  }
@@ -253,12 +245,6 @@ export class KanbanDragController {
253
245
  }
254
246
  };
255
247
 
256
- setOnMoveTask = (
257
- fn: (taskId: string, targetLaneId: string) => void | Promise<void>,
258
- ) => {
259
- this.onMoveTask = fn;
260
- };
261
-
262
248
  setOnReorderTask = (
263
249
  fn: (
264
250
  taskId: string,
@@ -908,8 +894,6 @@ export class KanbanDragController {
908
894
  drop.targetLaneId,
909
895
  drop.targetIndex,
910
896
  );
911
- } else if (this.onMoveTask && drop.targetLaneId !== drop.sourceLaneId) {
912
- await this.onMoveTask(drop.taskId, drop.targetLaneId);
913
897
  }
914
898
  }
915
899
  } finally {
@@ -1396,21 +1380,17 @@ export interface UseKanbanDragReturn {
1396
1380
  export function useKanbanDrag(
1397
1381
  options: KanbanDragOptions = {},
1398
1382
  ): UseKanbanDragReturn {
1399
- const { lanes = [], onMoveTask, onReorderTask, getTaskPreview } = options;
1383
+ const { lanes = [], onReorderTask, getTaskPreview } = options;
1400
1384
  const controllerRef = useRef<KanbanDragController | null>(null);
1401
1385
  if (!controllerRef.current) {
1402
1386
  controllerRef.current = new KanbanDragController({
1403
1387
  lanes,
1404
- onMoveTask,
1405
1388
  onReorderTask,
1406
1389
  });
1407
1390
  }
1408
1391
  const controller = controllerRef.current;
1409
1392
 
1410
1393
  controller.setLanes(lanes);
1411
- if (onMoveTask) {
1412
- controller.setOnMoveTask(onMoveTask);
1413
- }
1414
1394
  if (onReorderTask) {
1415
1395
  controller.setOnReorderTask(onReorderTask);
1416
1396
  }
@@ -0,0 +1,13 @@
1
+ import {
2
+ useWorkspace,
3
+ type PluginWorkspacePanelProps,
4
+ } from "@getpaseo/plugin/client";
5
+ import { KanbanBoardView } from "./kanban-board";
6
+
7
+ export function KanbanWorkspacePanel(props: PluginWorkspacePanelProps) {
8
+ const projectId = useWorkspace(
9
+ props.workspaceId,
10
+ (workspace) => workspace.projectId,
11
+ );
12
+ return <KanbanBoardView {...props} initialProjectId={projectId} />;
13
+ }
package/index.client.tsx CHANGED
@@ -1,33 +1,45 @@
1
1
  import type { PluginClientContext } from "@getpaseo/plugin/client";
2
2
  import { KanbanBoardView } from "./client/kanban-board";
3
+ import { KanbanWorkspacePanel } from "./client/kanban-workspace-panel";
3
4
  import { t, getLanguage, subscribeLanguage } from "./client/i18n";
4
5
 
5
6
  export default function contribute(client: PluginClientContext) {
6
- client.addSurface("kanban", KanbanBoardView);
7
-
7
+ const removeSurface = client.addSurface("kanban", KanbanBoardView);
8
8
  let currentLang = getLanguage();
9
- let removeSidebar = client.addSidebarItem({
10
- id: "kanban",
11
- title: t("kanban.sidebarTitle", currentLang),
12
- icon: "PanelsTopLeft",
13
- surface: "kanban",
14
- });
15
9
 
10
+ const registerEntries = () => {
11
+ const title = t("kanban.sidebarTitle", currentLang);
12
+ const removeSidebar = client.addSidebarItem({
13
+ id: "kanban",
14
+ title,
15
+ icon: "PanelsTopLeft",
16
+ surface: "kanban",
17
+ });
18
+ const removePanel = client.addWorkspacePanel({
19
+ id: "kanban",
20
+ title,
21
+ icon: "PanelsTopLeft",
22
+ context: "workspace",
23
+ Component: KanbanWorkspacePanel,
24
+ });
25
+ return () => {
26
+ removeSidebar();
27
+ removePanel();
28
+ };
29
+ };
30
+
31
+ let removeEntries = registerEntries();
16
32
  const unsubscribe = subscribeLanguage((newLang) => {
17
33
  if (newLang !== currentLang) {
18
34
  currentLang = newLang;
19
- removeSidebar();
20
- removeSidebar = client.addSidebarItem({
21
- id: "kanban",
22
- title: t("kanban.sidebarTitle", newLang),
23
- icon: "PanelsTopLeft",
24
- surface: "kanban",
25
- });
35
+ removeEntries();
36
+ removeEntries = registerEntries();
26
37
  }
27
38
  });
28
39
 
29
40
  return () => {
30
41
  unsubscribe();
31
- removeSidebar();
42
+ removeEntries();
43
+ removeSurface();
32
44
  };
33
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paseo-kanban",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "A lightweight, responsive Kanban board plugin for Paseo workspaces",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,6 +20,7 @@
20
20
  "board"
21
21
  ],
22
22
  "files": [
23
+ "OVERVIEW.md",
23
24
  "paseo-plugin.json",
24
25
  "index.client.tsx",
25
26
  "index.server.ts",
@@ -33,6 +34,7 @@
33
34
  "format:check": "prettier --check .",
34
35
  "format": "prettier --write .",
35
36
  "check:package": "node scripts/check-package.mjs",
37
+ "verify:release": "node scripts/verify-release.mjs",
36
38
  "check": "npm run typecheck && npm run test && npm run lint && npm run format:check && npm run check:package"
37
39
  },
38
40
  "devDependencies": {