diff --git a/install.sh b/install.sh index d2617d82..a4e82b52 100755 --- a/install.sh +++ b/install.sh @@ -51,6 +51,20 @@ ensure_path() { esac } +pnpm_cmd() { + if command -v pnpm &>/dev/null; then + pnpm "$@" + return + fi + if command -v corepack &>/dev/null && corepack pnpm --version &>/dev/null; then + corepack pnpm "$@" + return + fi + red "pnpm is not available in this shell." + red "Try opening a new shell, or install pnpm manually: https://pnpm.io/installation" + exit 1 +} + ensure_env_key() { local file="$1" local key="$2" @@ -104,9 +118,15 @@ green " curl ✓" if ! command -v pnpm &>/dev/null; then yellow " pnpm not found — installing via corepack…" - corepack enable 2>/dev/null || npm install -g pnpm + if command -v corepack &>/dev/null; then + corepack enable 2>/dev/null || true + corepack prepare pnpm@latest --activate 2>/dev/null || true + fi + if ! command -v pnpm &>/dev/null && ! (command -v corepack &>/dev/null && corepack pnpm --version &>/dev/null); then + npm install -g pnpm + fi fi -green " pnpm $(pnpm --version) ✓" +green " pnpm $(pnpm_cmd --version) ✓" # ─── install hermes-agent (delegate to Nous upstream installer) ────────── # hermes-agent is NOT on PyPI. It installs from source via Nous's own @@ -193,7 +213,7 @@ if [[ -f "$HERMES_ENV_PATH" ]]; then fi cyan "→ Installing npm deps (pnpm install)…" -pnpm install --silent +pnpm_cmd install --silent green " deps installed ✓" # ─── seed Hermes skills (Conductor needs workspace-dispatch) ───────────── diff --git a/package.json b/package.json index e5f1a7db..bde03140 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "main": "electron/main.cjs", "scripts": { "dev": "NODE_OPTIONS=\"--max-old-space-size=2048\" vite dev", - "build": "vite build", + "build": "NODE_OPTIONS=\"--max-old-space-size=${NODE_MAX_OLD_SPACE_SIZE:-2048}\" vite build", "start:all": "concurrently \"hermes gateway run\" \"pnpm dev\"", "start": "NODE_OPTIONS=\"--max-old-space-size=2048\" node server-entry.js", "start:dev": "NODE_OPTIONS=\"--max-old-space-size=2048\" vite dev", diff --git a/src/screens/chat/components/chat-sidebar.tsx b/src/screens/chat/components/chat-sidebar.tsx index 69424ab2..89bf4a0f 100644 --- a/src/screens/chat/components/chat-sidebar.tsx +++ b/src/screens/chat/components/chat-sidebar.tsx @@ -821,7 +821,7 @@ function ChatSidebarComponent({ kind: 'link', to: '/tasks', icon: CheckListIcon, - label: 'Kanban', + label: 'Tasks', active: isTasksActive, }, { diff --git a/src/screens/tasks/tasks-screen.tsx b/src/screens/tasks/tasks-screen.tsx index 9fc655b3..f180311e 100644 --- a/src/screens/tasks/tasks-screen.tsx +++ b/src/screens/tasks/tasks-screen.tsx @@ -8,30 +8,30 @@ import { HugeiconsIcon } from '@hugeicons/react' import { Add01Icon, CheckListIcon, RefreshIcon } from '@hugeicons/core-free-icons' import { TaskCard } from './task-card' import { TaskDialog } from './task-dialog' +import type { ClaudeTask, CreateTaskInput, TaskAssignee, TaskColumn } from '@/lib/tasks-api' import { toast } from '@/components/ui/toast' import { cn } from '@/lib/utils' import { - fetchTasks, - fetchAssignees, - createTask, - updateTask, - deleteTask, - moveTask, - launchSession, - linkSession, + COLUMN_COLORS, COLUMN_LABELS, COLUMN_ORDER, - COLUMN_COLORS, + createTask, + deleteTask, + fetchAssignees, + fetchTasks, isOverdue, + launchSession, + linkSession, + moveTask, + updateTask, } from '@/lib/tasks-api' import { stashPendingSend } from '@/screens/chat/pending-send' -import type { ClaudeTask, TaskColumn, CreateTaskInput, TaskAssignee } from '@/lib/tasks-api' const QUERY_KEY = ['claude', 'tasks'] as const const ASSIGNEES_KEY = ['claude', 'tasks', 'assignees'] as const export const TASKS_BOARD_HELP_TEXT = - 'Drag cards to change status. Open a card to set assignee and due date.' + 'Workspace Tasks is a lightweight task board. Drag cards to change status. Use Dashboard Kanban for native multi-board controls.' function SkeletonCard() { return ( @@ -93,7 +93,7 @@ export function TasksScreen() { } for (const t of tasks) { if (assigneeFilter && t.assignee !== assigneeFilter) continue - if (map[t.column]) map[t.column].push(t) + map[t.column].push(t) } for (const col of COLUMN_ORDER) { map[col].sort((a, b) => a.position - b.position) diff --git a/src/screens/tasks/tasks-ux.test.ts b/src/screens/tasks/tasks-ux.test.ts index c02f735c..ed675a08 100644 --- a/src/screens/tasks/tasks-ux.test.ts +++ b/src/screens/tasks/tasks-ux.test.ts @@ -6,7 +6,7 @@ import { TASKS_BOARD_HELP_TEXT } from './tasks-screen' describe('tasks UX copy', () => { it('exposes helper copy that explains drag and assignment behavior', () => { expect(TASKS_BOARD_HELP_TEXT).toBe( - 'Drag cards to change status. Open a card to set assignee and due date.', + 'Workspace Tasks is a lightweight task board. Drag cards to change status. Use Dashboard Kanban for native multi-board controls.', ) })