4 months ago
259987f* feat: import plugins and skills from Claude and Codex Add a dedicated Import flow that browses and copies plugins/skills already on disk from Claude Code (~/.claude) and Codex (~/.codex) into Cowork. - core src/import/: external home discovery (scoped to plugins/cache, plugins/marketplaces, skills), plugin/skill discovery with diagnostics and already-installed detection, Claude .claude-plugin -> cowork conversion (strip commands/agents/hooks/$schema/object mcpServers), and operations that reuse installPluginsFromSource / installSkillsFromSource. - WebSocket-first: cowork/import/list, cowork/import/plugin, cowork/import/skill JSON-RPC methods + import_list event, wired through SkillManager, AgentSession, and a new SessionImportService. Imports emit the standard plugins_catalog / skills_catalog events so every UI refreshes. - desktop: reusable ImportDialog with a Claude/Codex toggle mounted on the Plugins and Skills catalog pages, with per-item Import to Global/Workspace and installed indicators, backed by new store state/actions. - docs + generated jsonrpc artifacts updated; tests cover discovery, conversion, end-to-end import, and the JSON-RPC routes against a real server. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(desktop): make import dialog a contained scrollable list with nicer UI The import list overflowed the dialog (items bled past the rounded container). Follow the established PluginDetailDialog scroll pattern: make DialogContent a bounded flex column (max-h-[85vh], gap-0, p-0, overflow-hidden) with a fixed header and a flex-1 overflow-y-auto body so the list scrolls inside the dialog. Also polish the UI: icon tiles (package/sparkles), a segmented Claude/Codex toggle, a result count, monospace ids, 2-line clamped descriptions, inline diagnostic alerts, and per-item import spinners. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(desktop): add "Import directory" button to copy a local skill folder Add a native folder picker on the Skills page that imports a selected directory's skill(s) by copying (never symlinking) into Global or Workspace. - new generic desktop IPC `pickDirectory` (no workspace-approval side effects) wired through preload, desktopApi, desktopSchemas, files IPC, the renderer command, and the web adapter (prompt fallback). - ImportDirectoryButton: a Copy to Global / Copy to Workspace dropdown that picks a folder and reuses installSkills -> cowork/skills/install, which copies via fs.cp and writes the install manifest. Busy spinner + inline error. Copy semantics are guaranteed by the existing skill install pipeline (replacePluginInstallRoot + fs.cp), so e.g. ~/Desktop/diligence-report is copied in, not linked. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(desktop): move folder import into the Import dialog as a "Folder" source Per feedback, fold the local-directory import into the Import dialog instead of a separate toolbar button. The source toggle is now Claude / Codex / Folder. - Folder tab: a "Choose a folder…" native picker, then Import to Global / Import to Workspace with busy spinners and inline error/success. Skills copy via installSkills; plugins via installPlugins (both copy, never symlink). - Remove the standalone ImportDirectoryButton and its toolbar wiring; drop the now-unused isDesktopApiAvailable helper. The pickDirectory IPC stays and is now driven by the dialog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: harden desktop ipc boundaries * feat: add skill and plugin turn references Add @mention reference plumbing for turn/start and turn/steer so referenced skills are force-injected before model execution and referenced plugins are rendered into turn-scoped system context. Preserve references through desktop send, reconnect, queued-message, and workspace-default paths; enforce skill-over-plugin precedence, disabled/gated reference filtering, and the 32-reference client/server cap. Verified with bun test --max-concurrency 1, bun run typecheck, and bun run docs:check. * fix: resolve biome lint errors and format issues - Fix useExhaustiveDependencies in ComposerMentionInput (remove unnecessary value dep) - Replace array index keys with stable keys in ComposerHighlightOverlay - Add start/end fields to text segments for stable React keys - Format composerMentions.ts to satisfy line length - Fix import-related type and schema issues across desktop and core - Update synthetic skill injection tests for reference injection changes * fix * Update mockDesktopCommands.ts * Update NewChatLanding.tsx * fix: fall back after local title generation failures * fix: harden Apple title generation * fix: require Koffi files in Apple title bundle * chore: organize Apple title imports * chat/plugins/tagging * feat: add standalone skills to the plugin marketplace Surface marketplace-offered standalone skills alongside plugins: - marketplace.json gains an optional `skills[]` array, parsed locally and remotely (reusing the GitHub tree-URL install source) - skill catalog snapshots include `availableSkills`; the skills_catalog event carries `availableSkillsPartial`, mirroring the plugin marketplace flow - SkillManager queues a remote marketplace refresh on catalog read - desktop Skills page gains an "Available" section; install reuses cowork/skills/install - regenerated JSON-RPC artifacts and documented the new fields Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: use stable mention segment keys * fixes * fix: refresh available skills after skill mutations Uninstalling a marketplace skill left it absent from "Available" until a manual refresh, because skill mutations only re-emitted the local catalog. Queue a remote skill-marketplace refresh after skill mutations (scoped so plugin mutations don't trigger an extra fetch) — an uninstalled skill that's still in the marketplace now reappears as available automatically. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: deliver available marketplace skills in a single catalog emit The async "local-first then queue remote refresh" never reached the desktop client: the workspace-control read/refresh path captures one synchronous skills_catalog emit and disposes the ephemeral binding, so the queued remote emit was orphaned — an uninstalled marketplace skill never reappeared under "Available". Emit a single marketplace-inclusive catalog from getSkillsCatalog so both the catalog read and the post-mutation subscriber push (readRefreshEvents -> getCatalog) carry availableSkills. Drop the dead queue machinery. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: fall back to raw GitHub marketplace fetch * Update AGENTS.md * style: format marketplace skill test * Fix canvas previews and preserve turn reference context * fix: harden local import discovery * fix: surface subagent usage accounting * fix: derive legacy usage cost breakdowns * fix: cap canvas preview reads * fix: match composer mentions case-insensitively * fix: remove stale pending thread queue helper * style: satisfy biome check * fix: keep usage cost derivation renderer-safe --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Parentd15cd53