@theproductguy/create-mission-control 1.0.0
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/README.md +37 -0
- package/bin/cli.js +170 -0
- package/package.json +44 -0
- package/src/template/App.tsx +28 -0
- package/src/template/agent-os/commands/create-tasks/1-get-spec-requirements.md +19 -0
- package/src/template/agent-os/commands/create-tasks/2-create-tasks-list.md +234 -0
- package/src/template/agent-os/commands/create-tasks/create-tasks.md +254 -0
- package/src/template/agent-os/commands/design-screen/design-screen.md +32 -0
- package/src/template/agent-os/commands/design-shell/design-shell.md +34 -0
- package/src/template/agent-os/commands/design-tokens/design-tokens.md +36 -0
- package/src/template/agent-os/commands/export-product/export-product.md +181 -0
- package/src/template/agent-os/commands/implement-tasks/1-determine-tasks.md +13 -0
- package/src/template/agent-os/commands/implement-tasks/2-implement-tasks.md +63 -0
- package/src/template/agent-os/commands/implement-tasks/3-verify-implementation.md +113 -0
- package/src/template/agent-os/commands/implement-tasks/implement-tasks.md +207 -0
- package/src/template/agent-os/commands/initialize-design/initialize-design.md +67 -0
- package/src/template/agent-os/commands/orchestrate-tasks/orchestrate-tasks.md +180 -0
- package/src/template/agent-os/commands/plan-product/1-product-concept.md +53 -0
- package/src/template/agent-os/commands/plan-product/2-create-mission.md +78 -0
- package/src/template/agent-os/commands/plan-product/3-create-roadmap.md +73 -0
- package/src/template/agent-os/commands/plan-product/4-create-tech-stack.md +46 -0
- package/src/template/agent-os/commands/plan-product/plan-product.md +241 -0
- package/src/template/agent-os/commands/sample-data/sample-data.md +51 -0
- package/src/template/agent-os/commands/scaffold-implementation/scaffold-implementation.md +35 -0
- package/src/template/agent-os/commands/screenshot-design/screenshot-design.md +21 -0
- package/src/template/agent-os/commands/shape-spec/1-initialize-spec.md +95 -0
- package/src/template/agent-os/commands/shape-spec/2-shape-spec.md +300 -0
- package/src/template/agent-os/commands/shape-spec/shape-spec.md +40 -0
- package/src/template/agent-os/commands/write-spec/write-spec.md +134 -0
- package/src/template/agent-os/config.yml +13 -0
- package/src/template/agent-os/product/mission.md +29 -0
- package/src/template/agent-os/product/roadmap.md +9 -0
- package/src/template/agent-os/product/tech-stack.md +14 -0
- package/src/template/agent-os/scripts/generate_docs.sh +150 -0
- package/src/template/agent-os/specs/README.md +1 -0
- package/src/template/agent-os/standards/backend/api.md +10 -0
- package/src/template/agent-os/standards/backend/migrations.md +9 -0
- package/src/template/agent-os/standards/backend/models.md +10 -0
- package/src/template/agent-os/standards/backend/queries.md +9 -0
- package/src/template/agent-os/standards/frontend/accessibility.md +10 -0
- package/src/template/agent-os/standards/frontend/components.md +11 -0
- package/src/template/agent-os/standards/frontend/css.md +7 -0
- package/src/template/agent-os/standards/frontend/responsive.md +11 -0
- package/src/template/agent-os/standards/global/coding-style.md +10 -0
- package/src/template/agent-os/standards/global/commenting.md +5 -0
- package/src/template/agent-os/standards/global/conventions.md +11 -0
- package/src/template/agent-os/standards/global/error-handling.md +9 -0
- package/src/template/agent-os/standards/global/tech-stack.md +31 -0
- package/src/template/agent-os/standards/global/validation.md +11 -0
- package/src/template/agent-os/standards/testing/test-writing.md +9 -0
- package/src/template/agent-os-ui/README.md +73 -0
- package/src/template/agent-os-ui/package.json +54 -0
- package/src/template/agent-os-ui/src/components/AgentShell.tsx +31 -0
- package/src/template/agent-os-ui/src/components/AgentSidebar.tsx +65 -0
- package/src/template/agent-os-ui/src/components/GuidanceCard.tsx +75 -0
- package/src/template/agent-os-ui/src/components/MarkdownViewer.tsx +25 -0
- package/src/template/agent-os-ui/src/components/PromptButton.tsx +28 -0
- package/src/template/agent-os-ui/src/components/StatusItem.tsx +45 -0
- package/src/template/agent-os-ui/src/components/ThemeToggle.tsx +72 -0
- package/src/template/agent-os-ui/src/index.ts +11 -0
- package/src/template/agent-os-ui/src/style.css +3 -0
- package/src/template/agent-os-ui/tsconfig.json +33 -0
- package/src/template/agent-os-ui/vite.config.ts +32 -0
- package/src/template/control-center/backend/index.js +253 -0
- package/src/template/control-center/backend/package.json +19 -0
- package/src/template/control-center/frontend/README.md +73 -0
- package/src/template/control-center/frontend/eslint.config.js +23 -0
- package/src/template/control-center/frontend/index.html +21 -0
- package/src/template/control-center/frontend/package.json +43 -0
- package/src/template/control-center/frontend/postcss.config.js +6 -0
- package/src/template/control-center/frontend/public/favicon.svg +4 -0
- package/src/template/control-center/frontend/public/runtime-config.json +11 -0
- package/src/template/control-center/frontend/public/vite.svg +1 -0
- package/src/template/control-center/frontend/src/App.css +42 -0
- package/src/template/control-center/frontend/src/App.tsx +835 -0
- package/src/template/control-center/frontend/src/assets/react.svg +1 -0
- package/src/template/control-center/frontend/src/components/ThemeToggle.tsx +64 -0
- package/src/template/control-center/frontend/src/components/ui/ToastContext.tsx +81 -0
- package/src/template/control-center/frontend/src/index.css +149 -0
- package/src/template/control-center/frontend/src/main.tsx +14 -0
- package/src/template/control-center/frontend/src/vite-env.d.ts +1 -0
- package/src/template/control-center/frontend/tailwind.config.js +81 -0
- package/src/template/control-center/frontend/tsconfig.app.json +28 -0
- package/src/template/control-center/frontend/tsconfig.json +7 -0
- package/src/template/control-center/frontend/tsconfig.node.json +26 -0
- package/src/template/control-center/frontend/vite.config.ts +21 -0
- package/src/template/design/.claude/commands/design-os/data-model.md +122 -0
- package/src/template/design/.claude/commands/design-os/design-screen.md +309 -0
- package/src/template/design/.claude/commands/design-os/design-shell.md +238 -0
- package/src/template/design/.claude/commands/design-os/design-tokens.md +166 -0
- package/src/template/design/.claude/commands/design-os/export-product.md +1105 -0
- package/src/template/design/.claude/commands/design-os/product-roadmap.md +121 -0
- package/src/template/design/.claude/commands/design-os/product-vision.md +99 -0
- package/src/template/design/.claude/commands/design-os/sample-data.md +263 -0
- package/src/template/design/.claude/commands/design-os/screenshot-design.md +112 -0
- package/src/template/design/.claude/commands/design-os/shape-section.md +138 -0
- package/src/template/design/.claude/skills/frontend-design/SKILL.md +42 -0
- package/src/template/design/.github/CODE_OF_CONDUCT.md +5 -0
- package/src/template/design/.github/CONTRIBUTING.md +51 -0
- package/src/template/design/.github/ISSUE_TEMPLATE/config.yml +22 -0
- package/src/template/design/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- package/src/template/design/.github/SECURITY.yml +5 -0
- package/src/template/design/.github/SUPPORT.md +19 -0
- package/src/template/design/.github/workflows/pr-decline.yml +135 -0
- package/src/template/design/.github/workflows/stale.yml +25 -0
- package/src/template/design/CHANGELOG.md +13 -0
- package/src/template/design/LICENSE +21 -0
- package/src/template/design/README.md +54 -0
- package/src/template/design/agents.md +218 -0
- package/src/template/design/claude.md +1 -0
- package/src/template/design/components.json +22 -0
- package/src/template/design/docs/codebase-implementation.md +153 -0
- package/src/template/design/docs/design-section.md +135 -0
- package/src/template/design/docs/export.md +149 -0
- package/src/template/design/docs/getting-started.md +59 -0
- package/src/template/design/docs/index.md +56 -0
- package/src/template/design/docs/product-planning.md +113 -0
- package/src/template/design/docs/requirements.md +22 -0
- package/src/template/design/docs/usage.md +62 -0
- package/src/template/design/eslint.config.js +23 -0
- package/src/template/design/index.html +21 -0
- package/src/template/design/package.json +46 -0
- package/src/template/design/postcss.config.js +6 -0
- package/src/template/design/public/favicon.svg +4 -0
- package/src/template/design/public/vite.svg +1 -0
- package/src/template/design/src/assets/react.svg +1 -0
- package/src/template/design/src/components/AppLayout.tsx +95 -0
- package/src/template/design/src/components/DataCard.tsx +139 -0
- package/src/template/design/src/components/DataModelPage.tsx +120 -0
- package/src/template/design/src/components/DesignPage.tsx +284 -0
- package/src/template/design/src/components/EmptyState.tsx +158 -0
- package/src/template/design/src/components/ExportPage.tsx +354 -0
- package/src/template/design/src/components/NextPhaseButton.tsx +33 -0
- package/src/template/design/src/components/PhaseNav.tsx +152 -0
- package/src/template/design/src/components/PhaseWarningBanner.tsx +81 -0
- package/src/template/design/src/components/ProductOverviewCard.tsx +102 -0
- package/src/template/design/src/components/ProductPage.tsx +97 -0
- package/src/template/design/src/components/ScreenDesignPage.tsx +370 -0
- package/src/template/design/src/components/ScreenDesignsCard.tsx +49 -0
- package/src/template/design/src/components/SectionPage.tsx +256 -0
- package/src/template/design/src/components/SectionsCard.tsx +47 -0
- package/src/template/design/src/components/SectionsPage.tsx +181 -0
- package/src/template/design/src/components/ShellCard.tsx +85 -0
- package/src/template/design/src/components/ShellDesignPage.tsx +242 -0
- package/src/template/design/src/components/SpecCard.tsx +121 -0
- package/src/template/design/src/components/StepIndicator.tsx +75 -0
- package/src/template/design/src/components/ThemeToggle.tsx +86 -0
- package/src/template/design/src/components/ui/ToastContext.tsx +81 -0
- package/src/template/design/src/components/ui/avatar.tsx +53 -0
- package/src/template/design/src/components/ui/badge.tsx +46 -0
- package/src/template/design/src/components/ui/button.tsx +60 -0
- package/src/template/design/src/components/ui/card.tsx +92 -0
- package/src/template/design/src/components/ui/collapsible.tsx +48 -0
- package/src/template/design/src/components/ui/dialog.tsx +143 -0
- package/src/template/design/src/components/ui/dropdown-menu.tsx +255 -0
- package/src/template/design/src/components/ui/input.tsx +21 -0
- package/src/template/design/src/components/ui/label.tsx +22 -0
- package/src/template/design/src/components/ui/progress.tsx +24 -0
- package/src/template/design/src/components/ui/scroll-area.tsx +18 -0
- package/src/template/design/src/components/ui/select.tsx +67 -0
- package/src/template/design/src/components/ui/separator.tsx +28 -0
- package/src/template/design/src/components/ui/sheet.tsx +137 -0
- package/src/template/design/src/components/ui/skeleton.tsx +13 -0
- package/src/template/design/src/components/ui/switch.tsx +46 -0
- package/src/template/design/src/components/ui/table.tsx +116 -0
- package/src/template/design/src/components/ui/tabs.tsx +64 -0
- package/src/template/design/src/index.css +239 -0
- package/src/template/design/src/lib/data-model-loader.ts +91 -0
- package/src/template/design/src/lib/design-system-loader.ts +101 -0
- package/src/template/design/src/lib/product-loader.ts +221 -0
- package/src/template/design/src/lib/router.tsx +61 -0
- package/src/template/design/src/lib/section-loader.ts +272 -0
- package/src/template/design/src/lib/shell-loader.ts +175 -0
- package/src/template/design/src/lib/utils.ts +6 -0
- package/src/template/design/src/main.tsx +15 -0
- package/src/template/design/src/sections/.gitkeep +0 -0
- package/src/template/design/src/sections/ai-orchestration-engine-oai/OrchestrationEngine.tsx +348 -0
- package/src/template/design/src/sections/core-platform-shell/AppShell.tsx +403 -0
- package/src/template/design/src/sections/gemini-live-integration/GeminiIntegration.tsx +332 -0
- package/src/template/design/src/sections/interactive-2d-canvas/WhiteboardCanvas.tsx +334 -0
- package/src/template/design/src/sections/participation-equity-tracker/EquityTracker.tsx +383 -0
- package/src/template/design/src/sections/persistent-memory-system/PersistentMemory.tsx +308 -0
- package/src/template/design/src/sections/real-time-communication-layer/VideoSession.tsx +342 -0
- package/src/template/design/src/sections/visual-intelligence-agents/VisualAgents.tsx +311 -0
- package/src/template/design/src/types/product.ts +97 -0
- package/src/template/design/src/types/section.ts +33 -0
- package/src/template/design/tailwind.config.js +77 -0
- package/src/template/design/tsconfig.app.json +34 -0
- package/src/template/design/tsconfig.json +13 -0
- package/src/template/design/tsconfig.node.json +26 -0
- package/src/template/design/vite.config.ts +17 -0
- package/src/template/index.css +102 -0
- package/src/template/package.json +27 -0
- package/src/template/tailwind.config.js +80 -0
- package/src/template/vite.config.ts +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Specs
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## API endpoint standards and conventions
|
|
2
|
+
|
|
3
|
+
- **RESTful Design**: Follow REST principles with clear resource-based URLs and appropriate HTTP methods (GET, POST, PUT, PATCH, DELETE)
|
|
4
|
+
- **Consistent Naming**: Use consistent, lowercase, hyphenated or underscored naming conventions for endpoints across the API
|
|
5
|
+
- **Versioning**: Implement API versioning strategy (URL path or headers) to manage breaking changes without disrupting existing clients
|
|
6
|
+
- **Plural Nouns**: Use plural nouns for resource endpoints (e.g., `/users`, `/products`) for consistency
|
|
7
|
+
- **Nested Resources**: Limit nesting depth to 2-3 levels maximum to keep URLs readable and maintainable
|
|
8
|
+
- **Query Parameters**: Use query parameters for filtering, sorting, pagination, and search rather than creating separate endpoints
|
|
9
|
+
- **HTTP Status Codes**: Return appropriate, consistent HTTP status codes that accurately reflect the response (200, 201, 400, 404, 500, etc.)
|
|
10
|
+
- **Rate Limiting Headers**: Include rate limit information in response headers to help clients manage their usage
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Database migration best practices
|
|
2
|
+
|
|
3
|
+
- **Reversible Migrations**: Always implement rollback/down methods to enable safe migration reversals
|
|
4
|
+
- **Small, Focused Changes**: Keep each migration focused on a single logical change for clarity and easier troubleshooting
|
|
5
|
+
- **Zero-Downtime Deployments**: Consider deployment order and backwards compatibility for high-availability systems
|
|
6
|
+
- **Separate Schema and Data**: Keep schema changes separate from data migrations for better rollback safety
|
|
7
|
+
- **Index Management**: Create indexes on large tables carefully, using concurrent options when available to avoid locks
|
|
8
|
+
- **Naming Conventions**: Use clear, descriptive names that indicate what the migration does
|
|
9
|
+
- **Version Control**: Always commit migrations to version control and never modify existing migrations after deployment
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Database model best practices
|
|
2
|
+
|
|
3
|
+
- **Clear Naming**: Use singular names for models and plural for tables following your framework's conventions
|
|
4
|
+
- **Timestamps**: Include created and updated timestamps on all tables for auditing and debugging
|
|
5
|
+
- **Data Integrity**: Use database constraints (NOT NULL, UNIQUE, foreign keys) to enforce data rules at the database level
|
|
6
|
+
- **Appropriate Data Types**: Choose data types that match the data's purpose and size requirements
|
|
7
|
+
- **Indexes on Foreign Keys**: Index foreign key columns and other frequently queried fields for performance
|
|
8
|
+
- **Validation at Multiple Layers**: Implement validation at both model and database levels for defense in depth
|
|
9
|
+
- **Relationship Clarity**: Define relationships clearly with appropriate cascade behaviors and naming conventions
|
|
10
|
+
- **Avoid Over-Normalization**: Balance normalization with practical query performance needs
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Database query best practices
|
|
2
|
+
|
|
3
|
+
- **Prevent SQL Injection**: Always use parameterized queries or ORM methods; never interpolate user input into SQL strings
|
|
4
|
+
- **Avoid N+1 Queries**: Use eager loading or joins to fetch related data in a single query instead of multiple queries
|
|
5
|
+
- **Select Only Needed Data**: Request only the columns you need rather than using SELECT * for better performance
|
|
6
|
+
- **Index Strategic Columns**: Index columns used in WHERE, JOIN, and ORDER BY clauses for query optimization
|
|
7
|
+
- **Use Transactions for Related Changes**: Wrap related database operations in transactions to maintain data consistency
|
|
8
|
+
- **Set Query Timeouts**: Implement timeouts to prevent runaway queries from impacting system performance
|
|
9
|
+
- **Cache Expensive Queries**: Cache results of complex or frequently-run queries when appropriate
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## UI accessibility best practices
|
|
2
|
+
|
|
3
|
+
- **Semantic HTML**: Use appropriate HTML elements (nav, main, button, etc.) that convey meaning to assistive technologies
|
|
4
|
+
- **Keyboard Navigation**: Ensure all interactive elements are accessible via keyboard with visible focus indicators
|
|
5
|
+
- **Color Contrast**: Maintain sufficient contrast ratios (4.5:1 for normal text) and don't rely solely on color to convey information
|
|
6
|
+
- **Alternative Text**: Provide descriptive alt text for images and meaningful labels for all form inputs
|
|
7
|
+
- **Screen Reader Testing**: Test and verify that all views are accessible on screen reading devices.
|
|
8
|
+
- **ARIA When Needed**: Use ARIA attributes to enhance complex components when semantic HTML isn't sufficient
|
|
9
|
+
- **Logical Heading Structure**: Use heading levels (h1-h6) in proper order to create a clear document outline
|
|
10
|
+
- **Focus Management**: Manage focus appropriately in dynamic content, modals, and single-page applications
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## UI component best practices
|
|
2
|
+
|
|
3
|
+
- **Single Responsibility**: Each component should have one clear purpose and do it well
|
|
4
|
+
- **Reusability**: Design components to be reused across different contexts with configurable props
|
|
5
|
+
- **Composability**: Build complex UIs by combining smaller, simpler components rather than monolithic structures
|
|
6
|
+
- **Clear Interface**: Define explicit, well-documented props with sensible defaults for ease of use
|
|
7
|
+
- **Encapsulation**: Keep internal implementation details private and expose only necessary APIs
|
|
8
|
+
- **Consistent Naming**: Use clear, descriptive names that indicate the component's purpose and follow team conventions
|
|
9
|
+
- **State Management**: Keep state as local as possible; lift it up only when needed by multiple components
|
|
10
|
+
- **Minimal Props**: Keep the number of props manageable; if a component needs many props, consider composition or splitting it
|
|
11
|
+
- **Documentation**: Document component usage, props, and provide examples for easier adoption by team members
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## CSS best practices
|
|
2
|
+
|
|
3
|
+
- **Consistent Methodology**: Apply and stick to the project's consistent CSS methodology (Tailwind, BEM, utility classes, CSS modules, etc.) across the entire project
|
|
4
|
+
- **Avoid Overriding Framework Styles**: Work with your framework's patterns rather than fighting against them with excessive overrides
|
|
5
|
+
- **Maintain Design System**: Establish and document design tokens (colors, spacing, typography) for consistency
|
|
6
|
+
- **Minimize Custom CSS**: Leverage framework utilities and components to reduce custom CSS maintenance burden
|
|
7
|
+
- **Performance Considerations**: Optimize for production with CSS purging/tree-shaking to remove unused styles
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Responsive design best practices
|
|
2
|
+
|
|
3
|
+
- **Mobile-First Development**: Start with mobile layout and progressively enhance for larger screens
|
|
4
|
+
- **Standard Breakpoints**: Consistently use standard breakpoints across the application (e.g., mobile, tablet, desktop)
|
|
5
|
+
- **Fluid Layouts**: Use percentage-based widths and flexible containers that adapt to screen size
|
|
6
|
+
- **Relative Units**: Prefer rem/em units over fixed pixels for better scalability and accessibility
|
|
7
|
+
- **Test Across Devices**: Test and verify UI changes across multiple screen sizes from mobile to tablet to desktop screen sizes and ensure a balanced, user-friendly viewing and reading experience on all
|
|
8
|
+
- **Touch-Friendly Design**: Ensure tap targets are appropriately sized (minimum 44x44px) for mobile users
|
|
9
|
+
- **Performance on Mobile**: Optimize images and assets for mobile network conditions and smaller screens
|
|
10
|
+
- **Readable Typography**: Maintain readable font sizes across all breakpoints without requiring zoom
|
|
11
|
+
- **Content Priority**: Show the most important content first on smaller screens through thoughtful layout decisions
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Coding style best practices
|
|
2
|
+
|
|
3
|
+
- **Consistent Naming Conventions**: Establish and follow naming conventions for variables, functions, classes, and files across the codebase
|
|
4
|
+
- **Automated Formatting**: Maintain consistent code style (indenting, line breaks, etc.)
|
|
5
|
+
- **Meaningful Names**: Choose descriptive names that reveal intent; avoid abbreviations and single-letter variables except in narrow contexts
|
|
6
|
+
- **Small, Focused Functions**: Keep functions small and focused on a single task for better readability and testability
|
|
7
|
+
- **Consistent Indentation**: Use consistent indentation (spaces or tabs) and configure your editor/linter to enforce it
|
|
8
|
+
- **Remove Dead Code**: Delete unused code, commented-out blocks, and imports rather than leaving them as clutter
|
|
9
|
+
- **Backward compatibility only when required:** Unless specifically instructed otherwise, assume you do not need to write additional code logic to handle backward compatibility.
|
|
10
|
+
- **DRY Principle**: Avoid duplication by extracting common logic into reusable functions or modules
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
## Code commenting best practices
|
|
2
|
+
|
|
3
|
+
- **Self-Documenting Code**: Write code that explains itself through clear structure and naming
|
|
4
|
+
- **Minimal, helpful comments**: Add concise, minimal comments to explain large sections of code logic.
|
|
5
|
+
- **Don't comment changes or fixes**: Do not leave code comments that speak to recent or temporary changes or fixes. Comments should be evergreen informational texts that are relevant far into the future.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## General development conventions
|
|
2
|
+
|
|
3
|
+
- **Consistent Project Structure**: Organize files and directories in a predictable, logical structure that team members can navigate easily
|
|
4
|
+
- **Clear Documentation**: Maintain up-to-date README files with setup instructions, architecture overview, and contribution guidelines
|
|
5
|
+
- **Version Control Best Practices**: Use clear commit messages, feature branches, and meaningful pull/merge requests with descriptions
|
|
6
|
+
- **Environment Configuration**: Use environment variables for configuration; never commit secrets or API keys to version control
|
|
7
|
+
- **Dependency Management**: Keep dependencies up-to-date and minimal; document why major dependencies are used
|
|
8
|
+
- **Code Review Process**: Establish a consistent code review process with clear expectations for reviewers and authors
|
|
9
|
+
- **Testing Requirements**: Define what level of testing is required before merging (unit tests, integration tests, etc.)
|
|
10
|
+
- **Feature Flags**: Use feature flags for incomplete features rather than long-lived feature branches
|
|
11
|
+
- **Changelog Maintenance**: Keep a changelog or release notes to track significant changes and improvements
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Error handling best practices
|
|
2
|
+
|
|
3
|
+
- **User-Friendly Messages**: Provide clear, actionable error messages to users without exposing technical details or security information
|
|
4
|
+
- **Fail Fast and Explicitly**: Validate input and check preconditions early; fail with clear error messages rather than allowing invalid state
|
|
5
|
+
- **Specific Exception Types**: Use specific exception/error types rather than generic ones to enable targeted handling
|
|
6
|
+
- **Centralized Error Handling**: Handle errors at appropriate boundaries (controllers, API layers) rather than scattering try-catch blocks everywhere
|
|
7
|
+
- **Graceful Degradation**: Design systems to degrade gracefully when non-critical services fail rather than breaking entirely
|
|
8
|
+
- **Retry Strategies**: Implement exponential backoff for transient failures in external service calls
|
|
9
|
+
- **Clean Up Resources**: Always clean up resources (file handles, connections) in finally blocks or equivalent mechanisms
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
## Tech stack
|
|
2
|
+
|
|
3
|
+
Define your technical stack below. This serves as a reference for all team members and helps maintain consistency across the project.
|
|
4
|
+
|
|
5
|
+
### Framework & Runtime
|
|
6
|
+
- **Application Framework:** [e.g., Rails, Django, Next.js, Express]
|
|
7
|
+
- **Language/Runtime:** [e.g., Ruby, Python, Node.js, Java]
|
|
8
|
+
- **Package Manager:** [e.g., bundler, pip, npm, yarn]
|
|
9
|
+
|
|
10
|
+
### Frontend
|
|
11
|
+
- **JavaScript Framework:** [e.g., React, Vue, Svelte, Alpine, vanilla JS]
|
|
12
|
+
- **CSS Framework:** [e.g., Tailwind CSS, Bootstrap, custom]
|
|
13
|
+
- **UI Components:** [e.g., shadcn/ui, Material UI, custom library]
|
|
14
|
+
|
|
15
|
+
### Database & Storage
|
|
16
|
+
- **Database:** [e.g., PostgreSQL, MySQL, MongoDB]
|
|
17
|
+
- **ORM/Query Builder:** [e.g., ActiveRecord, Prisma, Sequelize]
|
|
18
|
+
- **Caching:** [e.g., Redis, Memcached]
|
|
19
|
+
|
|
20
|
+
### Testing & Quality
|
|
21
|
+
- **Test Framework:** [e.g., Jest, RSpec, pytest]
|
|
22
|
+
- **Linting/Formatting:** [e.g., ESLint, Prettier, RuboCop]
|
|
23
|
+
|
|
24
|
+
### Deployment & Infrastructure
|
|
25
|
+
- **Hosting:** [e.g., Heroku, AWS, Vercel, Railway]
|
|
26
|
+
- **CI/CD:** [e.g., GitHub Actions, CircleCI]
|
|
27
|
+
|
|
28
|
+
### Third-Party Services
|
|
29
|
+
- **Authentication:** [e.g., Auth0, Devise, NextAuth]
|
|
30
|
+
- **Email:** [e.g., SendGrid, Postmark]
|
|
31
|
+
- **Monitoring:** [e.g., Sentry, Datadog]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Validation best practices
|
|
2
|
+
|
|
3
|
+
- **Validate on Server Side**: Always validate on the server; never trust client-side validation alone for security or data integrity
|
|
4
|
+
- **Client-Side for UX**: Use client-side validation to provide immediate user feedback, but duplicate checks server-side
|
|
5
|
+
- **Fail Early**: Validate input as early as possible and reject invalid data before processing
|
|
6
|
+
- **Specific Error Messages**: Provide clear, field-specific error messages that help users correct their input
|
|
7
|
+
- **Allowlists Over Blocklists**: When possible, define what is allowed rather than trying to block everything that's not
|
|
8
|
+
- **Type and Format Validation**: Check data types, formats, ranges, and required fields systematically
|
|
9
|
+
- **Sanitize Input**: Sanitize user input to prevent injection attacks (SQL, XSS, command injection)
|
|
10
|
+
- **Business Rule Validation**: Validate business rules (e.g., sufficient balance, valid dates) at the appropriate application layer
|
|
11
|
+
- **Consistent Validation**: Apply validation consistently across all entry points (web forms, API endpoints, background jobs)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Test coverage best practices
|
|
2
|
+
|
|
3
|
+
- **Write Minimal Tests During Development**: Do NOT write tests for every change or intermediate step. Focus on completing the feature implementation first, then add strategic tests only at logical completion points
|
|
4
|
+
- **Test Only Core User Flows**: Write tests exclusively for critical paths and primary user workflows. Skip writing tests for non-critical utilities and secondary workflows until if/when you're instructed to do so.
|
|
5
|
+
- **Defer Edge Case Testing**: Do NOT test edge cases, error states, or validation logic unless they are business-critical. These can be addressed in dedicated testing phases, not during feature development.
|
|
6
|
+
- **Test Behavior, Not Implementation**: Focus tests on what the code does, not how it does it, to reduce brittleness
|
|
7
|
+
- **Clear Test Names**: Use descriptive names that explain what's being tested and the expected outcome
|
|
8
|
+
- **Mock External Dependencies**: Isolate units by mocking databases, APIs, file systems, and other external services
|
|
9
|
+
- **Fast Execution**: Keep unit tests fast (milliseconds) so developers run them frequently during development
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# @builderos/agent-os-ui
|
|
2
|
+
|
|
3
|
+
The official UI capability for the **Agent OS** workflow.
|
|
4
|
+
Use this library to build the control interface that guides you through the Antigravity development process (Product -> Design -> Build -> Verify).
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @builderos/agent-os-ui
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
1. Import the styles:
|
|
15
|
+
```ts
|
|
16
|
+
import '@builderos/agent-os-ui/style.css';
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. Build your Control Dashboard:
|
|
20
|
+
```tsx
|
|
21
|
+
import { AgentShell, GuidanceCard } from '@builderos/agent-os-ui';
|
|
22
|
+
|
|
23
|
+
export function ControlCenter() {
|
|
24
|
+
return (
|
|
25
|
+
<AgentShell sidebar={...}>
|
|
26
|
+
<div className="p-8 space-y-6">
|
|
27
|
+
{/* The core workflow component */}
|
|
28
|
+
<GuidanceCard
|
|
29
|
+
phase="Phase 1: Strategy"
|
|
30
|
+
title="Plan Your Product"
|
|
31
|
+
description="Define your Mission and Roadmap."
|
|
32
|
+
prompt="Antigravity, plan the product..."
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
</AgentShell>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
- **AgentShell**: Full application layout (Sidebar + Header + Main).
|
|
42
|
+
- **AgentSidebar**: Standardized navigation menu.
|
|
43
|
+
- **GuidanceCard**: The "Next Step" card with integrated prompt copying.
|
|
44
|
+
- **ThemeToggle**: Dark/Light mode switcher with system sync.
|
|
45
|
+
- **MarkdownViewer**: Beautifully styled Markdown rendering (Prose).
|
|
46
|
+
- **StatusItem**: Standardized pills for checking system health.
|
|
47
|
+
|
|
48
|
+
## Example Layout
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { AgentShell, AgentSidebar, ThemeToggle } from '@builderos/agent-os-ui';
|
|
52
|
+
import { Home, Layers } from 'lucide-react';
|
|
53
|
+
|
|
54
|
+
export default function App() {
|
|
55
|
+
return (
|
|
56
|
+
<AgentShell
|
|
57
|
+
sidebar={
|
|
58
|
+
<AgentSidebar
|
|
59
|
+
items={[
|
|
60
|
+
{ label: 'Home', icon: <Home size={18}/>, active: true },
|
|
61
|
+
{ label: 'Design', icon: <Layers size={18}/> }
|
|
62
|
+
]}
|
|
63
|
+
footer={<ThemeToggle />}
|
|
64
|
+
/>
|
|
65
|
+
}
|
|
66
|
+
>
|
|
67
|
+
<div className="p-8">
|
|
68
|
+
<h1 className="text-2xl font-bold">Welcome to Agent OS</h1>
|
|
69
|
+
</div>
|
|
70
|
+
</AgentShell>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@builderos/agent-os-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/agent-os-ui.umd.cjs",
|
|
6
|
+
"module": "./dist/agent-os-ui.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/agent-os-ui.js",
|
|
15
|
+
"require": "./dist/agent-os-ui.umd.cjs"
|
|
16
|
+
},
|
|
17
|
+
"./style.css": "./dist/style.css"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "vite",
|
|
21
|
+
"build": "tsc && vite build",
|
|
22
|
+
"lint": "eslint ."
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"react": ">=18.0.0",
|
|
26
|
+
"react-dom": ">=18.0.0"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"clsx": "^2.1.0",
|
|
30
|
+
"lucide-react": "^0.469.0",
|
|
31
|
+
"react-markdown": "^9.0.0",
|
|
32
|
+
"remark-breaks": "^4.0.0",
|
|
33
|
+
"remark-gfm": "^4.0.0",
|
|
34
|
+
"tailwind-merge": "^2.2.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@tailwindcss/typography": "^0.5.19",
|
|
38
|
+
"@types/node": "^20.10.0",
|
|
39
|
+
"@types/react": "^18.2.0",
|
|
40
|
+
"@types/react-dom": "^18.2.0",
|
|
41
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
42
|
+
"autoprefixer": "^10.4.20",
|
|
43
|
+
"postcss": "^8.4.49",
|
|
44
|
+
"react": "^18.3.1",
|
|
45
|
+
"react-dom": "^18.3.1",
|
|
46
|
+
"tailwindcss": "^3.4.17",
|
|
47
|
+
"tailwindcss-animate": "^1.0.7",
|
|
48
|
+
"eslint": "^9.39.1",
|
|
49
|
+
"globals": "^16.5.0",
|
|
50
|
+
"typescript": "^5.3.3",
|
|
51
|
+
"vite": "^5.0.10",
|
|
52
|
+
"vite-plugin-dts": "^3.7.0"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
interface AgentShellProps {
|
|
4
|
+
sidebar: ReactNode
|
|
5
|
+
header?: ReactNode
|
|
6
|
+
children: ReactNode
|
|
7
|
+
className?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function AgentShell({ sidebar, header, children, className }: AgentShellProps) {
|
|
11
|
+
return (
|
|
12
|
+
<div className={`flex h-screen bg-stone-50 dark:bg-stone-900 text-stone-900 dark:text-stone-100 font-sans transition-colors ${className || ''}`}>
|
|
13
|
+
{/* Sidebar Area */}
|
|
14
|
+
<div className="shrink-0">
|
|
15
|
+
{sidebar}
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
{/* Main Content Area */}
|
|
19
|
+
<div className="flex-1 flex flex-col min-w-0 overflow-hidden">
|
|
20
|
+
{header && (
|
|
21
|
+
<div className="shrink-0">
|
|
22
|
+
{header}
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
<main className="flex-1 overflow-auto bg-stone-50 dark:bg-black/20">
|
|
26
|
+
{children}
|
|
27
|
+
</main>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
interface SidebarItem {
|
|
4
|
+
label: string
|
|
5
|
+
icon?: ReactNode
|
|
6
|
+
active?: boolean
|
|
7
|
+
onClick?: () => void
|
|
8
|
+
badge?: string | number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface AgentSidebarProps {
|
|
12
|
+
title?: string
|
|
13
|
+
version?: string
|
|
14
|
+
items: SidebarItem[]
|
|
15
|
+
footer?: ReactNode
|
|
16
|
+
className?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function AgentSidebar({ title = "Agent OS", version = "v1.0", items, footer, className }: AgentSidebarProps) {
|
|
20
|
+
return (
|
|
21
|
+
<div className={`w-64 h-full bg-white dark:bg-stone-950 border-r border-stone-200 dark:border-stone-800 flex flex-col ${className || ''}`}>
|
|
22
|
+
{/* Header */}
|
|
23
|
+
<div className="p-6">
|
|
24
|
+
<div className="flex items-center gap-2 mb-1">
|
|
25
|
+
<div className="w-8 h-8 bg-stone-900 dark:bg-stone-100 rounded-lg flex items-center justify-center">
|
|
26
|
+
<div className="w-4 h-4 bg-white dark:bg-stone-900 rounded-sm" />
|
|
27
|
+
</div>
|
|
28
|
+
<span className="font-bold text-lg tracking-tight">{title}</span>
|
|
29
|
+
</div>
|
|
30
|
+
<div className="text-xs text-stone-500 font-mono pl-1">{version}</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
{/* Navigation */}
|
|
34
|
+
<div className="flex-1 px-4 space-y-1 overflow-y-auto">
|
|
35
|
+
{items.map((item, index) => (
|
|
36
|
+
<button
|
|
37
|
+
key={index}
|
|
38
|
+
onClick={item.onClick}
|
|
39
|
+
className={`w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm font-medium transition-colors ${item.active
|
|
40
|
+
? 'bg-stone-100 dark:bg-stone-800 text-stone-900 dark:text-stone-100'
|
|
41
|
+
: 'text-stone-600 dark:text-stone-400 hover:bg-stone-50 dark:hover:bg-stone-900'
|
|
42
|
+
}`}
|
|
43
|
+
>
|
|
44
|
+
<div className="flex items-center gap-3">
|
|
45
|
+
{item.icon}
|
|
46
|
+
<span>{item.label}</span>
|
|
47
|
+
</div>
|
|
48
|
+
{item.badge && (
|
|
49
|
+
<span className="text-xs bg-stone-200 dark:bg-stone-800 px-1.5 py-0.5 rounded-md">
|
|
50
|
+
{item.badge}
|
|
51
|
+
</span>
|
|
52
|
+
)}
|
|
53
|
+
</button>
|
|
54
|
+
))}
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
{/* Footer */}
|
|
58
|
+
{footer && (
|
|
59
|
+
<div className="p-4 border-t border-stone-200 dark:border-stone-800">
|
|
60
|
+
{footer}
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { PromptButton } from './PromptButton'
|
|
2
|
+
|
|
3
|
+
interface GuidanceCardProps {
|
|
4
|
+
phase?: string
|
|
5
|
+
title: string
|
|
6
|
+
description: string
|
|
7
|
+
prompt?: string
|
|
8
|
+
actionLabel?: string
|
|
9
|
+
onAction?: () => void
|
|
10
|
+
onCopy?: (text: string) => void
|
|
11
|
+
className?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function GuidanceCard({
|
|
15
|
+
phase,
|
|
16
|
+
title,
|
|
17
|
+
description,
|
|
18
|
+
prompt,
|
|
19
|
+
actionLabel,
|
|
20
|
+
onAction,
|
|
21
|
+
onCopy,
|
|
22
|
+
className
|
|
23
|
+
}: GuidanceCardProps) {
|
|
24
|
+
const handleCopy = (text: string) => {
|
|
25
|
+
if (onCopy) {
|
|
26
|
+
onCopy(text)
|
|
27
|
+
} else if (navigator.clipboard) {
|
|
28
|
+
navigator.clipboard.writeText(text)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className={`bg-white dark:bg-stone-900 border border-stone-200 dark:border-stone-800 rounded-xl p-6 shadow-sm relative overflow-hidden ${className || ''}`}>
|
|
34
|
+
{/* Decorative Background Icon Effect - Optional, kept simple for package */}
|
|
35
|
+
|
|
36
|
+
<div className="relative z-10">
|
|
37
|
+
{phase && (
|
|
38
|
+
<div className="text-xs font-bold tracking-wider text-stone-500 uppercase mb-2">
|
|
39
|
+
{phase}
|
|
40
|
+
</div>
|
|
41
|
+
)}
|
|
42
|
+
|
|
43
|
+
<h2 className="text-2xl font-bold text-stone-900 dark:text-stone-100 mb-2">
|
|
44
|
+
{title}
|
|
45
|
+
</h2>
|
|
46
|
+
|
|
47
|
+
<p className="text-stone-600 dark:text-stone-400 mb-6 max-w-2xl leading-relaxed">
|
|
48
|
+
{description}
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<div className="flex flex-col sm:flex-row gap-4 items-start sm:items-center">
|
|
52
|
+
{prompt && (
|
|
53
|
+
<div className="flex-1 w-full sm:w-auto">
|
|
54
|
+
<PromptButton
|
|
55
|
+
label="Copy Prompt for Agent"
|
|
56
|
+
prompt={prompt}
|
|
57
|
+
onClick={handleCopy}
|
|
58
|
+
primary
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
)}
|
|
62
|
+
|
|
63
|
+
{actionLabel && onAction && (
|
|
64
|
+
<button
|
|
65
|
+
onClick={onAction}
|
|
66
|
+
className="px-4 py-2 text-sm font-medium text-stone-700 dark:text-stone-300 bg-stone-100 dark:bg-stone-800 hover:bg-stone-200 dark:hover:bg-stone-700 rounded-lg transition-colors"
|
|
67
|
+
>
|
|
68
|
+
{actionLabel}
|
|
69
|
+
</button>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import ReactMarkdown from 'react-markdown'
|
|
2
|
+
import remarkGfm from 'remark-gfm'
|
|
3
|
+
import remarkBreaks from 'remark-breaks'
|
|
4
|
+
|
|
5
|
+
interface MarkdownViewerProps {
|
|
6
|
+
content: string
|
|
7
|
+
className?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function MarkdownViewer({ content, className }: MarkdownViewerProps) {
|
|
11
|
+
return (
|
|
12
|
+
<article className={`prose dark:prose-invert max-w-none
|
|
13
|
+
prose-headings:font-serif prose-headings:font-semibold
|
|
14
|
+
prose-a:text-stone-900 dark:prose-a:text-stone-100
|
|
15
|
+
prose-code:text-stone-900 dark:prose-code:text-stone-100
|
|
16
|
+
prose-pre:bg-stone-50 dark:prose-pre:bg-stone-900/50
|
|
17
|
+
prose-pre:border prose-pre:border-stone-200 dark:prose-pre:border-stone-800
|
|
18
|
+
prose-p:leading-relaxed prose-p:mb-4
|
|
19
|
+
${className || ''}`}>
|
|
20
|
+
<ReactMarkdown remarkPlugins={[remarkGfm, remarkBreaks]}>
|
|
21
|
+
{content || ''}
|
|
22
|
+
</ReactMarkdown>
|
|
23
|
+
</article>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Copy } from 'lucide-react'
|
|
2
|
+
|
|
3
|
+
interface PromptButtonProps {
|
|
4
|
+
label: string
|
|
5
|
+
prompt: string
|
|
6
|
+
onClick: (text: string) => void
|
|
7
|
+
small?: boolean
|
|
8
|
+
primary?: boolean
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function PromptButton({ label, prompt, onClick, small, primary, className }: PromptButtonProps) {
|
|
13
|
+
return (
|
|
14
|
+
<button
|
|
15
|
+
onClick={() => onClick(prompt)}
|
|
16
|
+
className={`flex items-center justify-center gap-2 rounded-lg font-medium transition cursor-pointer
|
|
17
|
+
${small ? 'px-3 py-1.5 text-xs flex-1' : 'px-4 py-2 text-sm w-full'}
|
|
18
|
+
${primary
|
|
19
|
+
? 'bg-stone-900 hover:bg-stone-800 dark:bg-stone-100 dark:hover:bg-white text-white dark:text-stone-900 shadow-sm'
|
|
20
|
+
: 'bg-white hover:bg-stone-100 dark:bg-stone-950 dark:hover:bg-stone-900 border border-stone-200 dark:border-stone-800 text-stone-900 dark:text-stone-100'}
|
|
21
|
+
${className || ''}
|
|
22
|
+
`}
|
|
23
|
+
>
|
|
24
|
+
<Copy size={small ? 12 : 14} />
|
|
25
|
+
{label}
|
|
26
|
+
</button>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
interface Status {
|
|
4
|
+
exists: boolean
|
|
5
|
+
completed?: number
|
|
6
|
+
total?: number
|
|
7
|
+
label?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface StatusItemProps {
|
|
11
|
+
label: string
|
|
12
|
+
status: Status | undefined | null
|
|
13
|
+
icon: ReactNode
|
|
14
|
+
small?: boolean
|
|
15
|
+
onClick?: () => void
|
|
16
|
+
className?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function StatusItem({ label, status, icon, small, onClick, className }: StatusItemProps) {
|
|
20
|
+
if (!status) return null
|
|
21
|
+
const isComplete = status.exists && (status.total && status.total > 0 ? status.completed === status.total : true)
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div
|
|
25
|
+
onClick={onClick}
|
|
26
|
+
className={`flex items-center justify-between ${small ? 'text-xs' : 'text-sm'} ${onClick ? 'cursor-pointer hover:bg-black/5 dark:hover:bg-white/5 p-1.5 -mx-1.5 rounded-md transition-colors group' : ''} ${className || ''}`}
|
|
27
|
+
>
|
|
28
|
+
<div className="flex items-center gap-2 text-stone-500 dark:text-stone-400 group-hover:text-stone-900 dark:group-hover:text-stone-200 transition-colors">
|
|
29
|
+
{icon}
|
|
30
|
+
<span>{label}</span>
|
|
31
|
+
</div>
|
|
32
|
+
<div>
|
|
33
|
+
{status.exists ? (
|
|
34
|
+
<span className={`px-2 py-0.5 rounded-full text-xs font-medium border ${isComplete
|
|
35
|
+
? 'bg-emerald-50 dark:bg-emerald-900/20 text-emerald-600 dark:text-emerald-400 border-emerald-200 dark:border-emerald-800'
|
|
36
|
+
: 'bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-800'}`}>
|
|
37
|
+
{status.total && status.total > 0 ? `${status.completed}/${status.total}` : (status.label || 'Done')}
|
|
38
|
+
</span>
|
|
39
|
+
) : (
|
|
40
|
+
<span className="px-2 py-0.5 rounded-full text-xs font-medium bg-stone-100 dark:bg-stone-800 text-stone-500 dark:text-stone-400 border border-stone-200 dark:border-stone-700">Missing</span>
|
|
41
|
+
)}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
}
|