{"_id":"@a24z/alexandria-workspace-panel","_rev":"2-dbed94ae5914b692161f59dc4ef7552a","name":"@a24z/alexandria-workspace-panel","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@a24z/alexandria-workspace-panel","version":"1.0.0","keywords":["panel-extension","workspace","alexandria"],"author":{"name":"Your Name"},"license":"MIT","_id":"@a24z/alexandria-workspace-panel@1.0.0","maintainers":[{"name":"fernando-ram-lugo","email":"principle@principlemd.com"}],"homepage":"https://github.com/a24z-ai/alexandria-workspace-panel#readme","bugs":{"url":"https://github.com/a24z-ai/alexandria-workspace-panel/issues"},"dist":{"shasum":"9cae22c7fd74cacbbe24ed1cfd42d56d2ef9ee23","tarball":"https://registry.npmjs.org/@a24z/alexandria-workspace-panel/-/alexandria-workspace-panel-1.0.0.tgz","fileCount":19,"integrity":"sha512-EzYlbfnakeBhADElo6LSbE/M+GJfFrcCBbYPda2DzUfp+VuR1Xb1LZR81zWlDjTy6QR4tZK86chBMPz8CTojZw==","signatures":[{"sig":"MEUCIQCOvKGl2X6NdUUdllUkjGmI2qmX6oCVycuMyx6s6nSgjQIgCAKkzPk2IhVGouppGjeTLpxzouo4CGqbVtOy3UybIlI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":177084},"main":"dist/panels.bundle.js","type":"module","types":"dist/index.d.ts","module":"dist/panels.bundle.js","gitHead":"701a3327586d4c8fc3d79c9d3d940ac94d1dbf0e","scripts":{"dev":"vite build --watch","lint":"eslint . --ext .ts,.tsx","test":"bun test","build":"bun run clean && bun run build:panel && bun run build:types","clean":"rm -rf dist","format":"prettier --write .","lint:fix":"eslint . --ext .ts,.tsx --fix","storybook":"storybook dev -p 6006","typecheck":"tsc --noEmit","test:watch":"bun test --watch","build:panel":"vite build","build:types":"tsc --project tsconfig.build.json --emitDeclarationOnly --declaration --declarationMap","format:check":"prettier --check .","build-storybook":"storybook build"},"_npmUser":{"name":"fernando-ram-lugo","email":"principle@principlemd.com"},"repository":{"url":"git+https://github.com/a24z-ai/alexandria-workspace-panel.git","type":"git"},"_npmVersion":"10.9.2","description":"Workspace and repository management panel for Panel Framework V2","directories":{},"_nodeVersion":"23.11.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.552.0","@a24z/core-library":"^0.1.32","@a24z/industry-theme":"^0.1.2"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.7","react":"^19.0.0","eslint":"^9.32.0","esbuild":"^0.25.8","prettier":"^3.6.2","react-dom":"^19.0.0","storybook":"^8.5.0","@eslint/js":"^9.32.0","@types/bun":"latest","typescript":"^5.0.4","@types/node":"^22.15.26","@types/react":"^19.0.0","@storybook/test":"^8.5.0","@storybook/react":"^8.5.0","@types/react-dom":"^19.0.0","@storybook/blocks":"^8.5.0","typescript-eslint":"^8.38.0","eslint-plugin-react":"^7.37.2","@vitejs/plugin-react":"^4.3.4","@storybook/react-vite":"^8.5.0","@storybook/addon-links":"^8.5.0","eslint-config-prettier":"^10.1.8","eslint-plugin-storybook":"^0.11.1","@chromatic-com/storybook":"^3.2.2","@typescript-eslint/parser":"^8.38.0","eslint-plugin-react-hooks":"^5.0.0","@storybook/addon-essentials":"^8.5.0","@storybook/addon-onboarding":"^8.5.0","@storybook/addon-interactions":"^8.5.0","@typescript-eslint/eslint-plugin":"^8.38.0","@principal-ade/panel-framework-core":"^0.1.2"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"peerDependenciesMeta":{"@principal-ade/panel-framework-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/alexandria-workspace-panel_1.0.0_1763132285067_0.10009219919704182","host":"s3://npm-registry-packages-npm-production"},"deprecated":"This package has moved to @industry-theme/alexandria-workspace-panel. Please update your dependencies."}},"time":{"created":"2025-11-14T14:58:05.009Z","modified":"2025-11-14T17:56:46.548Z","1.0.0":"2025-11-14T14:58:05.280Z"},"bugs":{"url":"https://github.com/a24z-ai/alexandria-workspace-panel/issues"},"author":{"name":"Your Name"},"license":"MIT","homepage":"https://github.com/a24z-ai/alexandria-workspace-panel#readme","keywords":["panel-extension","workspace","alexandria"],"repository":{"url":"git+https://github.com/a24z-ai/alexandria-workspace-panel.git","type":"git"},"description":"Workspace and repository management panel for Panel Framework V2","maintainers":[{"name":"fernando-ram-lugo","email":"principle@principlemd.com"}],"readme":"# Panel Extension Starter\n\nA starter template for building panel extensions compatible with `@principal-ade/panel-framework-core`. This template follows the [Panel Extension Store Specification V2](https://github.com/principal-ade/panel-framework/blob/main/PANEL_EXTENSION_STORE_SPECIFICATION_V2.md) and provides everything you need to create, build, and publish custom panels.\n\n## What is a Panel Extension?\n\nPanel extensions are React components distributed via NPM that can be dynamically loaded into panel-compatible host applications. They provide a standardized way to extend application functionality through a plugin-like architecture.\n\n### Key Features\n\n- **NPM Distribution**: Published and installed like any NPM package\n- **Multi-Panel Support**: Single package can export multiple related panels\n- **Framework Integration**: Full access to host application context, actions, and events\n- **Type Safety**: Complete TypeScript support with comprehensive type definitions\n- **Dependency Sharing**: Shared dependencies (React, ReactDOM) provided by host\n- **Self-Contained**: Unique dependencies bundled within the panel\n\n## Getting Started\n\n### 1. Clone or Use This Template\n\n```bash\n# Clone the starter\ngit clone https://github.com/your-org/panel-starter.git my-panel-extension\ncd my-panel-extension\n\n# Install dependencies\nbun install\n# or: npm install\n```\n\n### 2. Customize Your Package\n\nUpdate `package.json` with your information:\n\n```json\n{\n  \"name\": \"@your-org/your-panel-name\",\n  \"description\": \"Your panel description\",\n  \"author\": \"Your Name\",\n  \"keywords\": [\"panel-extension\"],\n  \"repository\": {\n    \"url\": \"git+https://github.com/your-org/your-panel-name.git\"\n  }\n}\n```\n\n### 3. Develop Your Panel\n\nEdit `src/panels/ExamplePanel.tsx` or create new panel components:\n\n```tsx\nimport React from 'react';\nimport type { PanelComponentProps } from '../types';\n\nexport const MyPanel: React.FC<PanelComponentProps> = ({\n  context,\n  actions,\n  events,\n}) => {\n  return (\n    <div>\n      <h1>My Custom Panel</h1>\n      <p>Repository: {context.repositoryPath}</p>\n    </div>\n  );\n};\n```\n\n### 4. Register Your Panels\n\nUpdate `src/index.tsx` to export your panel definitions:\n\n```tsx\nimport { MyPanel } from './panels/MyPanel';\n\nexport const panels = [\n  {\n    id: 'your-org.my-panel',\n    name: 'My Panel',\n    icon: '🚀',\n    description: 'My custom panel',\n    component: MyPanel,\n  },\n];\n```\n\n### 5. Develop with Storybook\n\n```bash\n# Start Storybook for interactive development\nbun run storybook\n\n# Build Storybook for deployment\nbun run build-storybook\n```\n\nStorybook will open at `http://localhost:6006` with:\n\n- Interactive component documentation\n- Multiple panel states and examples\n- Live prop editing\n- Code snippets\n\n### 6. Build and Test\n\n```bash\n# Development mode (watch for changes)\nbun run dev\n\n# Build for production\nbun run build\n\n# Type checking\nbun run typecheck\n\n# Linting\nbun run lint\n```\n\n## Project Structure\n\n```\npanel-starter/\n├── src/\n│   ├── panels/\n│   │   ├── ExamplePanel.tsx           # Your panel components\n│   │   └── ExamplePanel.stories.tsx   # Storybook stories\n│   ├── types/\n│   │   └── index.ts                   # TypeScript type definitions\n│   ├── mocks/\n│   │   └── panelContext.tsx           # Mock providers for Storybook\n│   ├── Introduction.mdx               # Storybook introduction\n│   └── index.tsx                      # Main entry - export panels array\n├── .storybook/\n│   ├── main.ts                        # Storybook configuration\n│   └── preview.ts                     # Storybook preview config\n├── dist/\n│   └── panels.bundle.js               # Built output (generated)\n├── package.json                       # Package configuration\n├── tsconfig.json                      # TypeScript config\n├── vite.config.ts                     # Build configuration\n├── eslint.config.js                   # Linting rules\n└── README.md                          # This file\n```\n\n## Panel Component API\n\n### PanelComponentProps\n\nEvery panel component receives these props:\n\n```typescript\ninterface PanelComponentProps {\n  // Access to shared data and state\n  context: PanelContextValue;\n\n  // Actions for host interaction\n  actions: PanelActions;\n\n  // Event system for inter-panel communication\n  events: PanelEventEmitter;\n}\n```\n\n### Context\n\nAccess repository data and state:\n\n```tsx\nconst { context } = props;\n\n// Repository information\ncontext.repositoryPath; // Current repository path\ncontext.repository; // Repository metadata\n\n// Data slices\ncontext.gitStatus; // Git status information\ncontext.fileTree; // File tree structure\ncontext.markdownFiles; // Markdown files list\n\n// State management\ncontext.loading; // Loading state\ncontext.refresh(); // Refresh data\ncontext.hasSlice('git'); // Check slice availability\n```\n\n### Actions\n\nInteract with the host application:\n\n```tsx\nconst { actions } = props;\n\n// File operations\nactions.openFile?.('path/to/file.ts');\nactions.openGitDiff?.('path/to/file.ts', 'unstaged');\n\n// Navigation\nactions.navigateToPanel?.('panel-id');\n\n// Notifications\nactions.notifyPanels?.(event);\n```\n\n### Events\n\nSubscribe to and emit panel events:\n\n```tsx\nconst { events } = props;\n\n// Subscribe to events\nuseEffect(() => {\n  const unsubscribe = events.on('file:opened', (event) => {\n    console.log('File opened:', event.payload);\n  });\n\n  return unsubscribe; // Cleanup\n}, [events]);\n\n// Emit events\nevents.emit({\n  type: 'custom:event',\n  source: 'my-panel',\n  timestamp: Date.now(),\n  payload: { data: 'value' },\n});\n```\n\n## Panel Definition\n\nEach panel must be defined with metadata:\n\n```typescript\ninterface PanelDefinition {\n  id: string; // Unique ID (e.g., 'org.panel-name')\n  name: string; // Display name\n  icon?: string; // Icon (emoji or URL)\n  version?: string; // Version (defaults to package.json)\n  author?: string; // Author (defaults to package.json)\n  description?: string; // Short description\n  component: React.FC; // The panel component\n\n  // Optional lifecycle hooks\n  onMount?: (context) => void | Promise<void>;\n  onUnmount?: (context) => void | Promise<void>;\n  onDataChange?: (slice, data) => void;\n}\n```\n\n## Lifecycle Hooks\n\n### Per-Panel Hooks\n\nCalled for individual panels:\n\n```typescript\n{\n  id: 'my-panel',\n  component: MyPanel,\n\n  onMount: async (context) => {\n    console.log('Panel mounted');\n    if (context.hasSlice('git')) {\n      await context.refresh();\n    }\n  },\n\n  onUnmount: async (context) => {\n    console.log('Panel unmounting');\n    // Cleanup logic\n  },\n\n  onDataChange: (slice, data) => {\n    console.log(`Data changed: ${slice}`, data);\n  },\n}\n```\n\n### Package-Level Hooks\n\nCalled once for the entire package:\n\n```typescript\nexport const onPackageLoad = async () => {\n  console.log('Package loaded');\n  // Initialize shared resources\n};\n\nexport const onPackageUnload = async () => {\n  console.log('Package unloading');\n  // Cleanup shared resources\n};\n```\n\n## Building and Publishing\n\n### Build Configuration\n\nThe build process (via Vite) automatically:\n\n- Externalizes React and ReactDOM (provided by host)\n- Bundles all other dependencies\n- Generates TypeScript declarations\n- Creates source maps\n- Outputs to `dist/panels.bundle.js`\n\n### Local Testing\n\nLink your panel locally for testing:\n\n```bash\n# In your panel directory\nbun run build\nbun link\n\n# In your host application\nbun link @your-org/your-panel-name\n```\n\n### Publishing to NPM\n\n```bash\n# Build the package\nbun run build\n\n# Verify the output\nls -la dist/\n\n# Publish to NPM\nnpm publish --access public\n```\n\n### Installing in Host Application\n\n```bash\n# In the host application\nnpm install @your-org/your-panel-name\n```\n\nThe host application will automatically discover your panel by the `panel-extension` keyword in `package.json`.\n\n## Best Practices\n\n### 1. Namespaced Panel IDs\n\nUse reverse domain notation for panel IDs:\n\n```typescript\nid: 'com.company.feature-panel'; // ✅ Good\nid: 'my-panel'; // ❌ Bad (collision risk)\n```\n\n### 2. Error Handling\n\nAlways handle errors gracefully:\n\n```tsx\nconst [error, setError] = useState(null);\n\nuseEffect(() => {\n  const loadData = async () => {\n    try {\n      if (!context.hasSlice('git')) {\n        throw new Error('Git data not available');\n      }\n      // Use data...\n    } catch (err) {\n      setError(err);\n    }\n  };\n  loadData();\n}, [context]);\n\nif (error) {\n  return <div>Error: {error.message}</div>;\n}\n```\n\n### 3. Loading States\n\nShow loading indicators:\n\n```tsx\nif (context.loading || context.isSliceLoading('git')) {\n  return <div>Loading...</div>;\n}\n```\n\n### 4. Cleanup Subscriptions\n\nAlways unsubscribe from events:\n\n```tsx\nuseEffect(() => {\n  const unsubscribe = events.on('event:type', handler);\n  return unsubscribe; // Cleanup on unmount\n}, [events]);\n```\n\n### 5. Type Safety\n\nUse provided types for type safety:\n\n```tsx\nimport type { PanelComponentProps, GitStatus } from './types';\n\nconst MyPanel: React.FC<PanelComponentProps> = ({ context }) => {\n  const gitStatus: GitStatus = context.gitStatus;\n  // ...\n};\n```\n\n## Available Data Slices\n\nPanels can access these data slices from the host:\n\n| Slice      | Type             | Description                  |\n| ---------- | ---------------- | ---------------------------- |\n| `git`      | `GitStatus`      | Git repository status        |\n| `markdown` | `MarkdownFile[]` | Markdown files in repository |\n| `fileTree` | `FileTree`       | File system tree structure   |\n| `packages` | `PackageLayer[]` | Package dependencies         |\n| `quality`  | `QualityMetrics` | Code quality metrics         |\n\nCheck availability before use:\n\n```tsx\nif (context.hasSlice('git') && !context.isSliceLoading('git')) {\n  // Use git data\n}\n```\n\n## Event Types\n\nStandard panel events:\n\n| Event                | Description        | Payload                |\n| -------------------- | ------------------ | ---------------------- |\n| `file:opened`        | File was opened    | `{ filePath: string }` |\n| `file:saved`         | File was saved     | `{ filePath: string }` |\n| `file:deleted`       | File was deleted   | `{ filePath: string }` |\n| `git:status-changed` | Git status changed | `GitStatus`            |\n| `git:commit`         | Git commit made    | `{ hash: string }`     |\n| `git:branch-changed` | Branch changed     | `{ branch: string }`   |\n| `panel:focus`        | Panel gained focus | `{ panelId: string }`  |\n| `panel:blur`         | Panel lost focus   | `{ panelId: string }`  |\n| `data:refresh`       | Data was refreshed | `{ slices: string[] }` |\n\n## Dependencies\n\n### Peer Dependencies (Required)\n\nThese are provided by the host application:\n\n- `react` >= 19.0.0\n- `react-dom` >= 19.0.0\n\n### Optional Peer Dependencies\n\n- `@principal-ade/panel-framework-core` - For advanced panel features\n\n### Bundled Dependencies\n\nInclude any libraries unique to your panel:\n\n```json\n{\n  \"dependencies\": {\n    \"lodash\": \"^4.17.21\",\n    \"date-fns\": \"^2.29.0\",\n    \"your-custom-lib\": \"^1.0.0\"\n  }\n}\n```\n\nThese will be bundled into your panel output.\n\n## Troubleshooting\n\n### Panel Not Discovered\n\nEnsure `package.json` has:\n\n```json\n{\n  \"keywords\": [\"panel-extension\"],\n  \"main\": \"dist/panels.bundle.js\"\n}\n```\n\n### Build Errors\n\nCheck that peer dependencies are externalized in `vite.config.ts`:\n\n```typescript\nexternal: ['react', 'react-dom'];\n```\n\n### Type Errors\n\nEnsure TypeScript can find types:\n\n```bash\nbun run typecheck\n```\n\n### Runtime Errors\n\nCheck browser console and ensure:\n\n- Panel ID is unique\n- Required exports are present (`panels` array)\n- Component is a valid React component\n\n## Resources\n\n- [Panel Extension Store Specification V2](https://github.com/principal-ade/panel-framework/blob/main/PANEL_EXTENSION_STORE_SPECIFICATION_V2.md)\n- [Panel Framework Core](https://github.com/principal-ade/panel-framework-core)\n- [Example Implementations](https://github.com/principal-ade/example-panels)\n\n## License\n\nMIT © Your Name\n\n## Contributing\n\nContributions welcome! Please read the contributing guidelines first.\n\n## Support\n\nFor issues and questions:\n\n- [GitHub Issues](https://github.com/your-org/your-panel-name/issues)\n- [Discussions](https://github.com/your-org/your-panel-name/discussions)\n","readmeFilename":"README.md"}