Nicholai 4e92884d51 feat: add Claude-style artifacts for persistent workspace documents
Implement a comprehensive artifacts system that allows users to create, edit,
and manage persistent documents alongside conversations, inspired by Claude's
artifacts feature.

Key Features:
- AI model integration with system prompts teaching artifact usage
- Inline preview cards in chat messages with collapsible previews
- On-demand side panel overlay (replaces split view)
- Preview/Code toggle for rendered markdown vs raw content
- Artifacts sidebar for managing multiple artifacts per thread
- Monaco editor integration for code artifacts
- Autosave with debounced writes and conflict detection
- Diff preview system for proposed updates
- Keyboard shortcuts and quick switcher
- Export/import functionality

Backend (Rust):
- New artifacts module in src-tauri/src/core/artifacts/
- 12 Tauri commands for CRUD, proposals, and export/import
- Atomic file writes with SHA256 hashing
- Sharded history storage with pruning policy
- Path traversal validation and UTF-8 enforcement

Frontend (TypeScript/React):
- ArtifactSidePanel: Claude-style overlay panel from right
- InlineArtifactCard: Preview cards embedded in chat
- ArtifactsSidebar: Floating list for artifact switching
- Enhanced ArtifactActionMessage: Parses AI metadata from content
- useArtifacts: Zustand store with autosave and conflict resolution

Types:
- Extended ThreadMessage.metadata with ArtifactAction
- ProposedContentRef supports inline and temp storage
- MIME-like content_type values for extensibility

Platform:
- Fixed platform detection to check window.__TAURI__
- Web service stubs for browser mode compatibility
- Updated assistant system prompts in both extension and web-app

This implements the complete workflow studied from Claude:
1. AI only creates artifacts when explicitly requested
2. Inline cards appear in chat with preview buttons
3. Side panel opens on demand, not automatic split
4. Users can toggle Preview/Code views and edit content
5. Autosave and version management prevent data loss
2025-11-02 12:19:36 -07:00

67 lines
1.8 KiB
TypeScript

/**
* Shortcuts Configuration
* Centralized shortcut definitions based on platform capabilities
*/
import { PlatformFeatures } from '../platform/const'
import { PlatformFeature } from '../platform/types'
import { ShortcutAction, type ShortcutMap } from './types'
/**
* Platform-specific shortcut mappings
* Uses alternate bindings for web to avoid browser conflicts
*/
export const PlatformShortcuts: ShortcutMap = {
// Toggle sidebar - same on both platforms (no browser conflict)
[ShortcutAction.TOGGLE_SIDEBAR]: {
key: 'b',
usePlatformMetaKey: true,
},
// New chat - different per platform to avoid browser "new window" conflict
[ShortcutAction.NEW_CHAT]: PlatformFeatures[PlatformFeature.ALTERNATE_SHORTCUT_BINDINGS]
? { key: 'Enter', usePlatformMetaKey: true }
: { key: 'n', usePlatformMetaKey: true },
// Go to settings - different per platform to avoid browser "preferences" conflict
[ShortcutAction.GO_TO_SETTINGS]: PlatformFeatures[PlatformFeature.ALTERNATE_SHORTCUT_BINDINGS]
? { key: '.', usePlatformMetaKey: true }
: { key: ',', usePlatformMetaKey: true },
// Zoom shortcuts - same on both platforms (standard shortcuts)
[ShortcutAction.ZOOM_IN]: {
key: '+',
usePlatformMetaKey: true,
},
[ShortcutAction.ZOOM_OUT]: {
key: '-',
usePlatformMetaKey: true,
},
// Toggle artifacts split view
[ShortcutAction.TOGGLE_ARTIFACTS]: {
key: '\\',
usePlatformMetaKey: true,
},
// Create new artifact
[ShortcutAction.NEW_ARTIFACT]: {
key: 'a',
shiftKey: true,
usePlatformMetaKey: true,
},
// Force save current artifact
[ShortcutAction.SAVE_ARTIFACT]: {
key: 's',
usePlatformMetaKey: true,
},
// Artifact quick switcher
[ShortcutAction.ARTIFACT_QUICK_SWITCHER]: {
key: 'k',
usePlatformMetaKey: true,
},
}