diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 6f29b6b..ec050bf 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,7 +5,7 @@ "email": "support@claudecodeplugins.dev" }, "metadata": { - "description": "Awesome Claude Code plugins — a curated list of slash commands, subagents, MCP servers, and hooks for Claude Code", + "description": "Awesome Claude Code plugins \u2014 a curated list of slash commands, subagents, MCP servers, and hooks for Claude Code", "version": "0.0.1", "homepage": "https://claudecodeplugins.dev" }, @@ -73,7 +73,7 @@ { "name": "ultrathink", "source": "./plugins/ultrathink", - "description": "Use /ultrathink to launch a Coordinator Agent that directs four specialist sub-agents—Architect, Research, Coder, and Tester—to analyze, design, implement, and validate your coding task. The process breaks the task into clear steps, gathers insights, and synthesizes a cohesive solution with actionable outputs. Relevant files can be referenced ad-hoc using @ filename syntax.", + "description": "Use /ultrathink to launch a Coordinator Agent that directs four specialist sub-agents\u2014Architect, Research, Coder, and Tester\u2014to analyze, design, implement, and validate your coding task. The process breaks the task into clear steps, gathers insights, and synthesizes a cohesive solution with actionable outputs. Relevant files can be referenced ad-hoc using @ filename syntax.", "version": "1.0.0", "author": { "name": "Jeronim Morina" @@ -847,7 +847,7 @@ "description": "Use this agent when setting up CI/CD pipelines, configuring Docker containers, deploying applications to cloud platforms, setting up Kubernetes clusters, implementing infrastructure as code, or automating deployment workflows. Examples: Context: User is setting up a new project and needs deployment automation. user: \"I've built a FastAPI application and need to deploy it to production with proper CI/CD\" assistant: \"I'll use the deployment-engineer agent to set up a complete deployment pipeline with Docker, GitHub Actions, and production-ready configurations.\" Context: User mentions containerization or deployment issues. user: \"Our deployment process is manual and error-prone. We need to automate it.\" assistant: \"Let me use the deployment-engineer agent to design an automated CI/CD pipeline that eliminates manual steps and ensures reliable deployments.\"", "version": "1.0.0", "author": { - "name": "Jure Šunić" + "name": "Jure \u0160uni\u0107" }, "category": "Automation DevOps", "homepage": "https://github.com/ccplugins/awesome-claude-code-plugins/tree/main/plugins/deployment-engineer", @@ -1141,7 +1141,7 @@ "description": "Use this agent when you need to design, build, or validate n8n automation workflows. This agent specializes in creating efficient n8n workflows using proper validation techniques and MCP tools integration.\\n\\nExamples:\\n- \\n Context: User wants to create a Slack notification workflow when a new GitHub issue is created.\\n user: \"I need to create an n8n workflow that sends a Slack message whenever a new GitHub issue is opened\"\\n assistant: \"I'll use the n8n-workflow-builder agent to design and build this GitHub-to-Slack automation workflow with proper validation.\"\\n \\n The user needs n8n workflow creation, so use the n8n-workflow-builder agent to handle the complete workflow design, validation, and deployment process.\\n \\n\\n- \\n Context: User has an existing n8n workflow that needs debugging and optimization.\\n user: \"My n8n workflow keeps failing at the HTTP Request node, can you help me fix it?\"\\n assistant: \"I'll use the n8n-workflow-builder agent to analyze and debug your workflow, focusing on the HTTP Request node configuration.\"\\n \\n Since this involves n8n workflow troubleshooting and validation, use the n8n-workflow-builder agent to diagnose and fix the issue.\\n \\n\\n- \\n Context: User wants to understand n8n best practices and available nodes for a specific use case.\\n user: \"What are the best n8n nodes for processing CSV data and sending email reports?\"\\n assistant: \"I'll use the n8n-workflow-builder agent to explore the available nodes and recommend the best approach for CSV processing and email automation.\"\\n \\n This requires n8n expertise and node discovery, so use the n8n-workflow-builder agent to provide comprehensive guidance.\\n \\n", "version": "1.0.0", "author": { - "name": "Jure Šunić" + "name": "Jure \u0160uni\u0107" }, "category": "Automation DevOps", "homepage": "https://github.com/ccplugins/awesome-claude-code-plugins/tree/main/plugins/n8n-workflow-builder", @@ -1197,7 +1197,7 @@ "description": "Use this agent when you need to create comprehensive Product Requirements Documents (PRDs) that combine business strategy, technical architecture, and user research. Examples: Context: The user needs to create a PRD for a new feature or product launch. user: \"I need to create a PRD for our new user authentication system that will support SSO and multi-factor authentication\" assistant: \"I'll use the prd-specialist agent to create a comprehensive PRD that covers the strategic foundation, technical requirements, and implementation blueprint for your authentication system.\" Context: The user is planning a major product initiative and needs strategic documentation. user: \"We're launching a mobile app for our e-commerce platform and need a detailed PRD to guide development\" assistant: \"Let me engage the prd-specialist agent to develop a thorough PRD that includes market analysis, user research integration, technical architecture, and implementation roadmap for your mobile app initiative.\"", "version": "1.0.0", "author": { - "name": "Jure Šunić" + "name": "Jure \u0160uni\u0107" }, "category": "Project & Product Management", "homepage": "https://github.com/ccplugins/awesome-claude-code-plugins/tree/main/plugins/prd-specialist", @@ -1281,7 +1281,7 @@ "description": "Use this agent when working with Python code that requires advanced features, performance optimization, or comprehensive refactoring. Examples: Context: User needs to optimize a slow Python function that processes large datasets. user: \"This function is taking too long to process our data, can you help optimize it?\" assistant: \"I'll use the python-expert agent to analyze and optimize your Python code with advanced techniques and performance profiling.\" Context: User wants to implement async/await patterns in their existing synchronous Python code. user: \"I need to convert this synchronous code to use async/await for better performance\" assistant: \"Let me use the python-expert agent to refactor your code with proper async/await patterns and concurrent programming techniques.\" Context: User needs help implementing complex Python design patterns. user: \"I want to implement a factory pattern with decorators for my API endpoints\" assistant: \"I'll use the python-expert agent to implement advanced Python patterns with decorators and proper design principles.\"", "version": "1.0.0", "author": { - "name": "Jure Šunić" + "name": "Jure \u0160uni\u0107" }, "category": "Development Engineering", "homepage": "https://github.com/ccplugins/awesome-claude-code-plugins/tree/main/plugins/python-expert", @@ -1670,6 +1670,48 @@ "security", "compliance" ] + }, + { + "name": "dataform-toolkit", + "source": "./plugins/dataform-toolkit", + "description": "Comprehensive toolkit for BigQuery Dataform development with engineering best practices, TDD workflow, proper ref() usage, safety practices, and comprehensive documentation", + "version": "1.0.0", + "author": { + "name": "Ivan Histand", + "email": "ihistand@rotoplas.com", + "url": "https://github.com/ihistand" + }, + "category": "Data Analytics", + "homepage": "https://github.com/ihistand/claude-plugins/tree/main/dataform-toolkit", + "keywords": [ + "dataform", + "bigquery", + "etl", + "data-engineering", + "tdd", + "sql" + ] + }, + { + "name": "stl-generator-toolkit", + "source": "./plugins/stl-generator-toolkit", + "description": "Comprehensive toolkit for generating 3D printable STL files for woodworking jigs and fixtures using CadQuery, with pre-built scripts and parametric design patterns", + "version": "1.0.0", + "author": { + "name": "Ivan Histand", + "email": "ihistand@rotoplas.com", + "url": "https://github.com/ihistand" + }, + "category": "Development Engineering", + "homepage": "https://github.com/ihistand/claude-plugins/tree/main/stl-generator-toolkit", + "keywords": [ + "3d-printing", + "stl", + "cadquery", + "woodworking", + "cad", + "parametric" + ] } ] } \ No newline at end of file diff --git a/plugins/dataform-toolkit/.claude-plugin/plugin.json b/plugins/dataform-toolkit/.claude-plugin/plugin.json new file mode 100644 index 0000000..bf47305 --- /dev/null +++ b/plugins/dataform-toolkit/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "dataform-toolkit", + "version": "1.0.0", + "description": "Comprehensive toolkit for BigQuery Dataform development with engineering best practices. Enforces TDD workflow, proper ref() usage, comprehensive documentation, and safe development patterns. Includes quick-access commands for common ETL workflows.", + "author": { + "name": "Ivan Histand", + "email": "ihistand@rotoplas.com", + "url": "https://github.com/ihistand" + }, + "skills": "./skills", + "commands": "./commands" +} diff --git a/plugins/dataform-toolkit/README.md b/plugins/dataform-toolkit/README.md new file mode 100644 index 0000000..2130bd6 --- /dev/null +++ b/plugins/dataform-toolkit/README.md @@ -0,0 +1,200 @@ +# Dataform Toolkit + +Comprehensive toolkit for BigQuery Dataform development with engineering best practices. Enforces TDD workflow, proper ref() usage, comprehensive documentation, and safe development patterns. + +## What's Included + +### Skills + +**dataform-engineering-fundamentals** - Complete guide for BigQuery Dataform development that enforces: +- Test-Driven Development (TDD) for data transformations +- Safety practices (`--schema-suffix dev`, `--dry-run`) +- Dependency management (ALWAYS `${ref()}`, NEVER hardcoded table paths) +- Comprehensive documentation (`columns: {}` blocks mandatory) +- Proper architecture patterns (layering, incremental processing, source declarations) + +The skill is designed to be bulletproof against rationalization - it works especially when you're under time pressure, tired, or tempted to skip best practices. + +### Slash Commands + +**`/dataform-test`** - Test a Dataform table in dev environment with complete safety checks: +- Compile validation +- Dry-run SQL validation +- Dev environment execution +- Result verification + +**`/dataform-deploy`** - Deploy a tested table to production with pre-deployment verification: +- Confirms dev testing completed +- Verifies tests passing +- Checks documentation completeness +- Safe production deployment + +**`/dataform-new-table`** - Create new tables using TDD workflow: +- RED: Write tests first, watch them fail +- GREEN: Write minimal implementation, watch tests pass +- REFACTOR: Improve while keeping tests passing + +**`/dataform-etl`** - Launch the ETL agent specialized in BigQuery Dataform development: +- Complex transformations +- Pipeline troubleshooting +- Data quality implementations +- ELT workflow coordination + +## Installation + +### Option 1: Install from Local Directory + +```bash +# From your Claude Code session +/plugin marketplace add /path/to/plugins/dataform-toolkit +/plugin install dataform-toolkit@dev +``` + +Then restart Claude Code. + +### Option 2: Install from Git Repository (Future) + +Once published to a Git repository: + +```bash +/plugin marketplace add / +/plugin install dataform-toolkit@ +``` + +## Usage Examples + +### Testing a Table + +``` +User: I need to test my customer_metrics table +Claude: /dataform-test +[Follows complete testing workflow with safety checks] +``` + +### Creating a New Table + +``` +User: Help me create a new sales summary table +Claude: /dataform-new-table +[Guides through TDD workflow: tests first, then implementation] +``` + +### Deploying to Production + +``` +User: The customer_metrics table is ready for production +Claude: /dataform-deploy +[Verifies testing completed, then safely deploys] +``` + +### Complex Dataform Work + +``` +User: I need to build a complex pipeline that aggregates data from multiple sources +Claude: /dataform-etl +[Launches ETL agent with full Dataform expertise] +``` + +## Key Principles + +### Non-Negotiable Safety Practices + +1. **Always use `--schema-suffix dev` for testing** - Protects production data +2. **Always use `--dry-run` before execution** - Catches errors early +3. **Create source declarations before using ref()** - Enables dependency tracking +4. **ALWAYS use ${ref()} - NEVER hardcoded table paths** - Maintains dependency graph +5. **Use proper ref() syntax** - Single argument when source exists +6. **Add validation queries** - Verify results immediately + +### Architecture Requirements + +- **Layered structure**: sources/ → intermediate/ → output/ +- **Incremental vs full refresh**: Choose based on data characteristics +- **Dataform assertions**: Automated data quality checks +- **Source declarations**: Use .sqlx files (not .js) for new declarations +- **Schema configuration**: No schema: config in operations/ or test/ files + +### Documentation Standards + +- **columns: {} mandatory** for all tables with `type: "table"` +- Get descriptions from source docs, API documentation, or business logic +- Document source declarations when applicable +- Clear, concise descriptions following Strunk's writing rules + +### Test-Driven Development + +1. **RED Phase**: Write assertions first, watch them fail +2. **GREEN Phase**: Write minimal implementation, watch tests pass +3. **REFACTOR Phase**: Improve while keeping tests passing + +**Critical**: Tests-first means defining what should happen. Tests-after means checking what does happen. + +## Time Pressure Protocol + +Even under extreme time pressure (board meeting in 2 hours, production down, stakeholder waiting): + +✅ **Still required**: +- Dev testing (3 minutes saves 60 minutes debugging) +- `--dry-run` validation +- Source declarations +- `columns: {}` documentation (2 minutes, saves hours) +- Tests first (TDD) +- Basic validation + +⚠️ **Can skip** (but document as technical debt): +- Extensive documentation files +- Peer review +- Performance optimization + +**Bottom line**: Safety practices save time. Skipping them wastes time. + +## Common Mistakes to Avoid + +1. ❌ Using tables before declaring sources → ✅ Create source declarations first +2. ❌ Hardcoded table paths → ✅ Use ${ref()} always +3. ❌ Skipping dev testing under pressure → ✅ Dev testing prevents production issues +4. ❌ Creating monolithic transformations → ✅ Break into intermediate tables +5. ❌ Missing columns: {} documentation → ✅ Document all tables immediately +6. ❌ Writing implementation before tests → ✅ Follow TDD cycle (RED-GREEN-REFACTOR) +7. ❌ Using .js files for NEW declarations → ✅ Use .sqlx files +8. ❌ Adding schema: to operations/tests → ✅ Use default schemas from workflow_settings.yaml + +## Quick Reference Commands + +| Command | Purpose | Example | +|---------|---------|---------| +| `dataform compile` | Validate syntax | Check for errors | +| `dataform run --schema-suffix dev --dry-run --actions table` | Validate SQL | Check before execution | +| `dataform run --schema-suffix dev --actions table` | Test in dev | Safe execution | +| `dataform run --schema-suffix dev --include-deps --actions table` | Run with deps | Include upstream tables | +| `dataform run --schema-suffix dev --tags looker` | Run by tag | Execute tagged tables | +| `dataform run --actions table` | Production deploy | After dev testing succeeds | + +## Related Skills + +- **superpowers:test-driven-development** - Foundational TDD principles +- **superpowers:brainstorming** - Refine requirements before coding +- **superpowers:systematic-debugging** - Structured troubleshooting +- **superpowers:root-cause-tracing** - Trace errors to source +- **elements-of-style:writing-clearly-and-concisely** - Clear documentation writing + +## Official Documentation + +- [Dataform Documentation](https://cloud.google.com/dataform/docs) +- [Dataform Best Practices](https://cloud.google.com/dataform/docs/best-practices-repositories) +- [BigQuery GoogleSQL Reference](https://cloud.google.com/bigquery/docs/reference/standard-sql) + +## License + +Created by Ivan Histand (ihistand@rotoplas.com) + +## Contributing + +This plugin follows the superpowers framework principles: +- Skills enforce discipline, not just provide information +- Must be bulletproof against rationalization +- Include red flags to catch deviation attempts +- Document common mistakes with corrections +- Reference related skills for workflow chains + +For questions or contributions, contact Ivan Histand. diff --git a/plugins/dataform-toolkit/commands/dataform-deploy.md b/plugins/dataform-toolkit/commands/dataform-deploy.md new file mode 100644 index 0000000..d15b708 --- /dev/null +++ b/plugins/dataform-toolkit/commands/dataform-deploy.md @@ -0,0 +1,21 @@ +--- +description: Deploy tested Dataform table to production +--- + +You are deploying a Dataform table to production using best practices from the dataform-engineering-fundamentals skill. + +**Workflow:** + +1. Invoke the dataform-engineering-fundamentals skill +2. Ask the user which table they want to deploy +3. **Pre-deployment verification:** + - Confirm the table has been tested in dev environment + - Verify all tests are passing + - Check that documentation (columns: {}) is complete +4. **Deployment:** + - Run `dataform run --dry-run --actions ` (production dry-run) + - If successful, run `dataform run --actions ` (production execution) + - Verify deployment with validation queries +5. Report deployment results + +**Critical**: Never deploy without dev testing first. Wrong results delivered quickly are worse than correct results delivered with a small delay. diff --git a/plugins/dataform-toolkit/commands/dataform-etl.md b/plugins/dataform-toolkit/commands/dataform-etl.md new file mode 100644 index 0000000..75abb6b --- /dev/null +++ b/plugins/dataform-toolkit/commands/dataform-etl.md @@ -0,0 +1,24 @@ +--- +description: Launch ETL agent for BigQuery Dataform development +--- + +You are launching the ETL Dataform engineer agent to handle data transformation pipeline work. + +**Purpose**: The ETL agent specializes in BigQuery Dataform projects, SQLX files, data quality, and pipeline development. Use this for: +- Complex Dataform transformations +- Pipeline troubleshooting +- Data quality implementations +- ELT workflow coordination + +**Task**: Use the Task tool with `subagent_type="etl"` to launch the ETL agent. Pass the user's request as the prompt, including: +- What they need to accomplish +- Any relevant context about tables, datasets, or business logic +- Whether this is new development, modification, or troubleshooting + +The ETL agent has access to the dataform-engineering-fundamentals skill and will follow best practices for BigQuery Dataform development. + +**Example**: +``` +User asks: "Help me create a customer metrics table" +You launch: Task tool with subagent_type="etl" and prompt="Create a customer metrics table in Dataform following TDD workflow. Ask user about required metrics and data sources." +``` diff --git a/plugins/dataform-toolkit/commands/dataform-new-table.md b/plugins/dataform-toolkit/commands/dataform-new-table.md new file mode 100644 index 0000000..c774465 --- /dev/null +++ b/plugins/dataform-toolkit/commands/dataform-new-table.md @@ -0,0 +1,33 @@ +--- +description: Create new Dataform table using TDD workflow +--- + +You are creating a new Dataform table following the Test-Driven Development (TDD) workflow from the dataform-engineering-fundamentals skill. + +**Workflow:** + +1. Invoke the dataform-engineering-fundamentals skill +2. Ask the user about the table requirements: + - Table name and purpose + - Expected columns and their descriptions + - Data sources (for creating source declarations if needed) + - Business logic and transformations +3. **RED Phase - Write tests first:** + - Create assertion file in `definitions/assertions/` + - Write data quality tests (duplicates, nulls, invalid values) + - Run tests - they should FAIL (table doesn't exist yet) +4. **GREEN Phase - Write minimal implementation:** + - Create source declarations if needed + - Create table SQLX file with: + - Proper config block with type, schema + - Complete columns: {} documentation + - SQL transformation + - Run table creation: `dataform run --schema-suffix dev --actions ` + - Run tests - they should PASS +5. **REFACTOR Phase - Improve while keeping tests passing:** + - Optimize query performance if needed + - Add partitioning/clustering if appropriate + - Improve documentation clarity +6. Report completion with file locations and next steps + +**Critical**: Always write tests FIRST, then implementation. Tests-after means you're checking what it does, not defining what it should do. diff --git a/plugins/dataform-toolkit/commands/dataform-test.md b/plugins/dataform-toolkit/commands/dataform-test.md new file mode 100644 index 0000000..adcf4db --- /dev/null +++ b/plugins/dataform-toolkit/commands/dataform-test.md @@ -0,0 +1,18 @@ +--- +description: Test Dataform table in dev environment with safety checks +--- + +You are testing a Dataform table using best practices from the dataform-engineering-fundamentals skill. + +**Workflow:** + +1. Invoke the dataform-engineering-fundamentals skill +2. Ask the user which table they want to test +3. Follow the safety checklist: + - Run `dataform compile` to check syntax + - Run `dataform run --schema-suffix dev --dry-run --actions ` to validate SQL + - Run `dataform run --schema-suffix dev --actions ` to execute in dev + - Run basic validation queries to verify results +4. Report results and any issues found + +**Critical**: Always use `--schema-suffix dev` for testing. Never test directly in production. diff --git a/plugins/dataform-toolkit/skills/dataform-engineering-fundamentals.md b/plugins/dataform-toolkit/skills/dataform-engineering-fundamentals.md new file mode 100644 index 0000000..fe974ff --- /dev/null +++ b/plugins/dataform-toolkit/skills/dataform-engineering-fundamentals.md @@ -0,0 +1,661 @@ +--- +name: dataform-engineering-fundamentals +description: Use when developing BigQuery Dataform transformations, SQLX files, source declarations, or troubleshooting pipelines - enforces TDD workflow (tests first), ALWAYS use ${ref()} never hardcoded table paths, comprehensive columns:{} documentation, safety practices (--schema-suffix dev, --dry-run), proper ref() syntax, .sqlx for new declarations, no schema config in operations/tests, and architecture patterns that prevent technical debt under time pressure +--- + +# Dataform Engineering Fundamentals + +## Overview + +**Core principle**: Safety practices and proper architecture are NEVER optional in Dataform development, regardless of time pressure or business urgency. + +**REQUIRED FOUNDATION:** This skill builds upon superpowers:test-driven-development. All TDD principles from that skill apply to Dataform development. This skill adapts TDD specifically for BigQuery Dataform SQLX files. + +**Official Documentation:** For Dataform syntax, configuration options, and API reference, see https://docs.cloud.google.com/dataform/docs?hl=en + +**Best Practices Guide:** For repository structure, naming conventions, and managing large workflows, see https://docs.cloud.google.com/dataform/docs/best-practices-repositories?hl=en + +Time pressure does not justify skipping safety checks or creating technical debt. The time "saved" by shortcuts gets multiplied into hours of debugging, broken dependencies, and production issues. + +## When to Use + +Use this skill for ANY Dataform work: +- Creating new SQLX transformations +- Modifying existing tables +- Adding data sources +- Troubleshooting pipeline failures +- "Quick" reports or ad-hoc analysis + +**Especially** use when: +- Under time pressure or deadlines +- Stakeholders are waiting +- Working late at night (exhausted) +- Tempted to "just make it work" + +**Related Skills**: +- **Before designing new features**: Use superpowers:brainstorming to refine requirements into clear designs before writing any code +- **When troubleshooting failures**: Use superpowers:systematic-debugging for structured problem-solving +- **When debugging complex issues**: Use superpowers:root-cause-tracing to trace errors back to their source +- **When writing documentation, commit messages, or any prose**: Use elements-of-style:writing-clearly-and-concisely to apply Strunk's timeless writing rules for clarity and conciseness + +## Non-Negotiable Safety Practices + +These are ALWAYS required. No exceptions for deadlines, urgency, or "simple" tasks: + +### 1. Always Use `--schema-suffix dev` for Testing + +```bash +# WRONG: Testing in production +dataform run --actions my_table + +# CORRECT: Test in dev first +dataform run --schema-suffix dev --actions my_table +``` + +**Why**: Writes to `schema_dev.my_table` instead of `schema_prod.my_table` (or adds `_dev` suffix based on your configuration). Allows safe testing without impacting production data or dashboards. + +### 2. Always Use `--dry-run` Before Execution + +```bash +# Check compilation +dataform compile + +# Validate SQL without executing +dataform run --schema-suffix dev --dry-run --actions my_table + +# Only then execute +dataform run --schema-suffix dev --actions my_table +``` + +**Why**: Catches SQL errors, missing dependencies, and cost estimation before using BigQuery slots. + +### 3. Source Declarations Before ref() + +**WRONG**: Using tables without source declarations +```sql +-- This will break dependency tracking +FROM `project_id.external_schema.table_name` +``` + +**CORRECT**: Create source declaration first +```sql +-- definitions/sources/external_system/table_name.sqlx +config { + type: "declaration", + database: "project_id", + schema: "external_schema", + name: "table_name" +} + +-- Then reference it +FROM ${ref("table_name")} +``` + +### 4. ALWAYS Use ${ref()} - NEVER Hardcoded Table Paths + +**WRONG**: Hardcoded table paths +```sql +-- NEVER do this +FROM `project.external_schema.table_name` +FROM `project.reporting_schema.customer_metrics` +SELECT * FROM project.source_schema.customers +``` + +**CORRECT**: Always use ${ref()} +```sql +-- Create source declaration first, then reference +FROM ${ref("table_name")} +FROM ${ref("customer_metrics")} +SELECT * FROM ${ref("customers")} +``` + +**Why**: +- Dataform tracks dependencies automatically with ref() +- Hardcoded paths break dependency graphs +- ref() enables --schema-suffix to work correctly +- Refactoring is easier when references are managed + +**Exception**: None. There is NO valid reason to use hardcoded table paths in SQLX files. + +### 5. Proper ref() Syntax + +**WRONG**: Including schema in ref() unnecessarily +```sql +FROM ${ref("external_schema", "sales_order")} +``` + +**CORRECT**: Use single argument when source declared +```sql +FROM ${ref("sales_order")} +``` + +**When to use two-argument ref()**: +- Source declarations that haven't been imported yet +- Special schema architectures where schema suffix behavior needs explicit control +- Cross-database references in multi-project setups + +**Why**: +- Single-argument ref() works for most tables +- Dataform resolves the full path from source declarations +- Two-argument form is only needed for special cases + +### 6. Basic Validation Queries + +Always verify your output: +```bash +# Check row counts +bq query --use_legacy_sql=false \ + "SELECT COUNT(*) FROM \`project.schema_dev.my_table\`" + +# Check for nulls in critical fields +bq query --use_legacy_sql=false \ + "SELECT COUNT(*) FROM \`project.schema_dev.my_table\` + WHERE key_field IS NULL" +``` + +**Why**: Catches silent failures (empty tables, null values, bad joins) immediately. + +## Architecture Patterns (Not Optional) + +Even for "quick" work, follow these patterns: + +**Reference:** For detailed guidance on repository structure, naming conventions, and managing large workflows, see https://docs.cloud.google.com/dataform/docs/best-practices-repositories?hl=en + +### Layered Structure + +``` +definitions/ + sources/ # External data declarations + intermediate/ # Transformations and business logic + output/ # Final tables for consumption + reports/ # Reporting tables + marts/ # Data marts for specific use cases +``` + +**Don't**: Create monolithic queries directly in output layer + +**Do**: Break into intermediate steps for reusability and testing + +### Incremental vs Full Refresh + +```sql +config { + type: "incremental", + uniqueKey: "order_id", + bigquery: { + partitionBy: "DATE(order_date)", + clusterBy: ["customer_id", "product_id"] + } +} +``` + +**When to use incremental**: Tables that grow daily (events, transactions, logs) + +**When to use full refresh**: Small dimension tables, aggregations with lookback windows + +### Dataform Assertions + +```sql +config { + type: "table", + assertions: { + uniqueKey: ["call_id"], + nonNull: ["customer_phone_number", "start_time"], + rowConditions: ["duration >= 0"] + } +} +``` + +**Why**: Catches data quality issues automatically during pipeline runs. + +### Source Declarations: Prefer .sqlx Files + +**STRONGLY PREFER**: .sqlx files for ALL new declarations +```sql +-- definitions/sources/external_system/table_name.sqlx +config { + type: "declaration", + database: "project_id", + schema: "external_schema", + name: "table_name", + columns: { + id: "Unique identifier for records", + // ... more columns + } +} +``` + +**ACCEPTABLE (legacy only)**: .js files for existing declarations +```javascript +// definitions/sources/legacy_declarations.js (existing file) +declare({ + database: "project_id", + schema: "source_schema", + name: "customers" +}); +``` + +**Rule**: ALL NEW source declarations MUST be .sqlx files. Existing .js declarations can remain but should be migrated to .sqlx when modifying them. + +**Why**: .sqlx files support column documentation, are more maintainable, and integrate better with Dataform's dependency tracking. + +### Schema Configuration Rules + +**Operations**: Files in `definitions/operations/` should NOT include `schema:` config +```sql +-- CORRECT +config { + type: "operations", + tags: ["daily"] +} + +-- WRONG +config { + type: "operations", + schema: "dataform", // DON'T specify schema + tags: ["daily"] +} +``` + +**Tests/Assertions**: Files in `definitions/test/` should NOT include `schema:` config +```sql +-- CORRECT +config { + type: "assertion", + description: "Check for duplicates" +} + +-- WRONG +config { + type: "assertion", + schema: "dataform_assertions", // DON'T specify schema + description: "Check for duplicates" +} +``` + +**Why**: Operations live in the default `dataform` schema and assertions live in `dataform_assertions` schema (configured in `workflow_settings.yaml`). Specifying schema explicitly can cause conflicts. + +## Documentation Standards (Non-Negotiable) + +All tables with `type: "table"` MUST include comprehensive `columns: {}` documentation in the config block. + +**Writing Clear Documentation**: When writing column descriptions, commit messages, or any prose that humans will read, use elements-of-style:writing-clearly-and-concisely to ensure clarity and conciseness. + +### columns: {} Requirement + +**WRONG**: Table without column documentation +```sql +config { + type: "table", + schema: "reporting" +} + +SELECT customer_id, total_revenue FROM ${ref("orders")} +``` + +**CORRECT**: Complete column documentation +```sql +config { + type: "table", + schema: "reporting", + columns: { + customer_id: "Unique customer identifier from source system", + total_revenue: "Sum of all order amounts in USD, excluding refunds" + } +} + +SELECT customer_id, total_revenue FROM ${ref("orders")} +``` + +### Where to Get Column Descriptions + +Column descriptions should be derived from: + +1. **Source Declarations**: Copy descriptions from upstream source tables +2. **Third-party Documentation**: Use official API documentation for external systems (CRM, ERP, analytics platforms) +3. **Business Logic**: Document calculated fields, transformations, and business rules +4. **BI Tool Requirements**: Include context that dashboard builders and analysts need +5. **Dataform Documentation**: Reference https://docs.cloud.google.com/dataform/docs?hl=en for Dataform-specific configuration and built-in functions + +**Example with ERP source documentation**: +```sql +config { + type: "table", + schema: "reporting", + columns: { + customer_id: "Unique customer identifier from ERP system", + customer_name: "Customer legal business name", + account_group: "Customer classification code for account management", + credit_limit: "Maximum allowed credit in USD" + } +} +``` + +### Source Declarations Should Include columns: {} + +When applicable, source declarations should also document columns: + +```sql +-- definitions/sources/external_api/events.sqlx +config { + type: "declaration", + database: "project_id", + schema: "external_api", + name: "events", + description: "Event records from external API with enriched data", + columns: { + event_id: "Unique event identifier from API", + user_id: "User identifier who triggered the event", + event_type: "Type of event (click, view, purchase, etc.)", + timestamp: "UTC timestamp when event occurred", + properties: "JSON object containing event-specific properties" + } +} +``` + +**Why document sources**: Downstream tables inherit and extend these descriptions, creating documentation consistency across the pipeline. + +## Test-Driven Development (TDD) Workflow + +**REQUIRED BACKGROUND:** You MUST understand and follow superpowers:test-driven-development + +**BEFORE TDD:** When creating NEW features with unclear requirements, use superpowers:brainstorming FIRST to refine rough ideas into clear designs. Only start TDD once you have a clear understanding of what needs to be built. + +When creating NEW features or tables in Dataform, apply the TDD cycle: + +1. **RED**: Write tests first, watch them fail +2. **GREEN**: Write minimal code to make tests pass +3. **REFACTOR**: Clean up while keeping tests passing + +The superpowers:test-driven-development skill provides the foundational TDD principles. This section adapts those principles specifically for Dataform tables and SQLX files. + +### TDD for Dataform Tables + +**WRONG: Implementation-first approach** +``` +1. Write SQLX transformation +2. Test manually with bq query +3. "It works, ship it" +``` + +**CORRECT: Test-first approach** +``` +1. Write data quality assertions first +2. Write unit tests for business logic +3. Run tests - they should FAIL (table doesn't exist yet) +4. Write SQLX transformation +5. Run tests - they should PASS +6. Refactor transformation if needed +``` + +### Example TDD Workflow + +**Step 1: Write assertions first** (definitions/assertions/assert_customer_metrics.sqlx) +```sql +config { + type: "assertion", + description: "Customer metrics must have valid data" +} + +-- This WILL fail initially (table doesn't exist) +SELECT 'Duplicate customer_id' AS test +FROM ${ref("customer_metrics")} +GROUP BY customer_id +HAVING COUNT(*) > 1 + +UNION ALL + +SELECT 'Negative lifetime value' AS test +FROM ${ref("customer_metrics")} +WHERE lifetime_value < 0 +``` + +**Step 2: Run tests - watch them fail** +```bash +dataform run --schema-suffix dev --run-tests --actions assert_customer_metrics +# ERROR: Table customer_metrics does not exist ✓ EXPECTED +``` + +**Step 3: Write minimal implementation** (definitions/output/reports/customer_metrics.sqlx) +```sql +config { + type: "table", + schema: "reporting", + columns: { + customer_id: "Unique customer identifier", + lifetime_value: "Total revenue from customer in USD" + } +} + +SELECT + customer_id, + SUM(order_total) AS lifetime_value +FROM ${ref("orders")} +GROUP BY customer_id +``` + +**Step 4: Run tests - watch them pass** +```bash +dataform run --schema-suffix dev --actions customer_metrics +dataform run --schema-suffix dev --run-tests --actions assert_customer_metrics +# No rows returned ✓ TESTS PASS +``` + +### Why TDD Matters in Dataform + +- **Catches bugs before production**: Tests fail when logic is wrong +- **Documents expected behavior**: Tests show what the table should do +- **Prevents regressions**: Future changes won't break existing logic +- **Faster debugging**: Test failures pinpoint exact issues +- **Confidence in refactoring**: Change code safely with test coverage + +### TDD Red Flags + +If you're thinking: +- "I'll write tests after the implementation" → **NO, write tests FIRST** +- "Tests are overkill for this simple table" → **NO, simple tables break too** +- "I'll test manually with bq query" → **NO, manual tests aren't repeatable** +- "Tests after achieve the same result" → **NO, tests-first catches design flaws** + +**All of these mean**: You're skipping TDD. Write tests first, then implementation. + +**See also**: The superpowers:test-driven-development skill contains additional TDD rationalizations and red flags that apply universally to all code, including Dataform SQLX files. + +## Quick Reference + +| Task | Command | Notes | +|------|---------|-------| +| Compile only | `dataform compile` | Check syntax, no BigQuery execution | +| Dry run | `dataform run --schema-suffix dev --dry-run --actions table_name` | Validate SQL, estimate cost | +| Test in dev | `dataform run --schema-suffix dev --actions table_name` | Safe execution in dev environment | +| Run with dependencies | `dataform run --schema-suffix dev --include-deps --actions table_name` | Run upstream dependencies first | +| Run by tag | `dataform run --schema-suffix dev --tags looker` | Run all tables with tag | +| Production deploy | `dataform run --actions table_name` | Only after dev testing succeeds | + +## Common Rationalizations (And Why They're Wrong) + +| Excuse | Reality | Fix | +|--------|---------|-----| +| "Too urgent to test in dev" | Production failures waste MORE time than dev testing | 3 minutes testing saves 60 minutes debugging | +| "It's just a quick report" | "Quick" reports become permanent tables | Use proper architecture from start | +| "Business is waiting" | Broken output wastes stakeholder time | Correct results delivered 10 minutes later > wrong results now | +| "Hardcoding table path is faster than ${ref()}" | Breaks dependency tracking, creates maintenance nightmare | Create source declaration, use ${ref()} (30 seconds) | +| "I'll refactor it later" | Technical debt rarely gets fixed | Do it right the first time (saves time overall) | +| "Correctness over elegance" | Architecture = maintainability, not elegance | Proper structure IS correctness | +| "I'll add tests after" | After = never | Write tests FIRST (TDD), then implementation | +| "I'll add documentation after" | After = never | Add columns: {} in config block immediately | +| "Working late, just need it working" | Exhaustion causes mistakes | Discipline matters MORE when tired | +| "Column docs are optional for internal tables" | All tables become external eventually | Document everything, always | +| "Tests after achieve same result" | Tests-after = checking what it does; tests-first = defining what it should do | TDD catches design flaws early | + +## Red Flags - STOP Immediately + +If you're thinking any of these thoughts, STOP and follow the skill: + +- "I'll skip `--schema-suffix dev` this once" +- "No time for `--dry-run`" +- "I'll just hardcode the table path instead of using ${ref()}" +- "I'll use backticks instead of ${ref()} (it's faster)" +- "I'll just create one file instead of intermediate layers" +- "Tests are optional for ad-hoc work" +- "I'll write tests after the implementation" +- "I'll add column documentation later" +- "This table doesn't need columns: {} block" +- "I'll use a .js file for declarations (faster to write)" +- "I'll add schema: config to this operation/test file" +- "I'll fix the technical debt later" +- "This is different because [business reason]" + +**All of these mean**: You're about to create problems. Follow the non-negotiable practices. + +## Common Mistakes + +### Mistake 1: Using tables before declaring sources + +```sql +-- WRONG: Direct table reference +FROM `project.external_schema.contacts` + +-- CORRECT: Declare source first +FROM ${ref("contacts")} +``` + +**Fix**: Create source declaration in `definitions/sources/` before using in queries. + +### Mistake 2: Mixing ref() with manual schema qualification + +```sql +-- WRONG: When source exists +FROM ${ref("dataset_name", "table_name")} + +-- CORRECT +FROM ${ref("table_name")} +``` + +**Fix**: Use single-argument `ref()` when source declaration exists. Dataform handles full path resolution. + +### Mistake 3: Skipping dev testing under pressure + +**Symptom**: "I'll deploy directly to production because it's urgent" + +**Fix**: `--schema-suffix dev` takes 30 seconds longer than production deploy. Production failures take hours to fix. + +### Mistake 4: Creating monolithic transformations + +**Symptom**: 200-line SQLX file with 5 CTEs doing multiple transformations + +**Fix**: Break into intermediate tables. Each table should do ONE transformation clearly. + +### Mistake 5: Missing columns: {} documentation + +**Symptom**: Table config without column descriptions + +**Fix**: Add comprehensive `columns: {}` block to EVERY table with `type: "table"`. Get descriptions from source docs, upstream tables, or business logic. + +### Mistake 6: Writing implementation before tests + +**Symptom**: Creating SQLX file, then adding assertions afterward (or never) + +**Fix**: Follow TDD cycle - write assertions first, watch them fail, write implementation, watch tests pass. + +### Mistake 7: Using .js files for NEW source declarations + +**Symptom**: Creating NEW `definitions/sources/sources.js` files with declare() functions + +**Fix**: Create .sqlx files in `definitions/sources/[system]/[table].sqlx` with proper config blocks and column documentation. Existing .js files can remain until they need modification. + +### Mistake 8: Hardcoded table paths instead of ${ref()} + +**Symptom**: Using backtick-quoted table paths in queries +```sql +FROM `project.external_api.events` +SELECT * FROM project.source_schema.customers +``` + +**Fix**: ALWAYS use ${ref()} after creating source declarations +```sql +FROM ${ref("events")} +SELECT * FROM ${ref("customers")} +``` + +**Why critical**: Hardcoded paths break dependency tracking, prevent --schema-suffix from working, and make refactoring impossible. + +### Mistake 9: Adding schema: config to operations or tests + +**Symptom**: Operations or test files with explicit schema configuration +```sql +config { + type: "operations", + schema: "dataform", // Wrong! +} +``` + +**Fix**: Remove schema: config - operations and tests use default schemas from workflow_settings.yaml + +## Time Pressure Protocol + +When under extreme time pressure (board meeting in 2 hours, production down, stakeholder waiting): + +1. ✅ **Still use dev testing** - 3 minutes saves 60 minutes debugging +2. ✅ **Still use --dry-run** - Catches errors before wasting BigQuery slots +3. ✅ **Still create source declarations** - Broken dependencies waste MORE time +4. ✅ **Still add columns: {} documentation** - Takes 2 minutes, saves hours explaining to Looker users +5. ✅ **Still write tests first (TDD)** - 5 minutes writing assertions prevents production bugs +6. ✅ **Still do basic validation** - Wrong results are worse than delayed results +7. ⚠️ **Can skip**: Extensive documentation files, peer review, performance optimization +8. ⚠️ **Must document**: Tag as "technical_debt", create TODO with follow-up tasks + +**The bottom line**: Safety practices save time. Skipping them wastes time. Even under pressure. + +## Troubleshooting Dataform Errors + +**RECOMMENDED APPROACH:** When encountering ANY bug, test failure, or unexpected behavior, use superpowers:systematic-debugging before attempting fixes. For errors deep in execution or cascading failures, use superpowers:root-cause-tracing to identify the original trigger. + +**Official Reference:** For Dataform-specific errors, configuration issues, or syntax questions, consult https://docs.cloud.google.com/dataform/docs?hl=en + +### "Table not found" errors + +**Quick fixes:** +1. Check source declaration exists in `definitions/sources/` +2. Verify ref() syntax (single argument if source exists) +3. Check schema/database match in source config +4. Run `dataform compile` to see resolved SQL + +**If issue persists:** Use superpowers:systematic-debugging for structured root cause investigation. + +### Dependency cycle errors + +**Quick fixes:** +1. Use `${ref("table_name")}` not direct table references +2. Check for circular dependencies (A → B → A) +3. Review dependency graph in Dataform UI + +**If issue persists:** Use superpowers:root-cause-tracing to trace the dependency chain back to the source of the cycle. + +### Timeout errors + +**Quick fixes:** +1. Add partitioning/clustering to config +2. Use incremental updates instead of full refresh +3. Break large transformations into smaller intermediate tables + +**If issue persists:** Use superpowers:systematic-debugging to investigate query performance systematically. + +## Real-World Impact + +**Scenario**: "Quick" report created without source declarations, skipping dev testing. + +**Cost**: +- 10 minutes saved initially +- 2 hours debugging "table not found" errors in production +- 3 stakeholder escalations +- 1 broken morning dashboard +- Net loss: 110 minutes + +**With proper practices**: +- 13 minutes total (3 extra for dev testing) +- Zero production issues +- Zero escalations +- Net gain: 97 minutes + +**Takeaway**: Discipline is faster than shortcuts. diff --git a/plugins/stl-generator-toolkit/.claude-plugin/plugin.json b/plugins/stl-generator-toolkit/.claude-plugin/plugin.json new file mode 100644 index 0000000..e4fc2b2 --- /dev/null +++ b/plugins/stl-generator-toolkit/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "stl-generator-toolkit", + "version": "1.0.0", + "description": "Comprehensive toolkit for generating 3D printable STL files for woodworking jigs and fixtures using CadQuery. Includes pre-built scripts for circle cutting jigs, angle wedges, spacing blocks, and custom parametric designs. Optimized for Elegoo Neptune 4 Pro with engineering best practices.", + "author": { + "name": "Ivan Histand", + "email": "ihistand@rotoplas.com", + "url": "https://github.com/ihistand" + }, + "skills": "./skills", + "commands": "./commands" +} diff --git a/plugins/stl-generator-toolkit/README.md b/plugins/stl-generator-toolkit/README.md new file mode 100644 index 0000000..a9b8e7f --- /dev/null +++ b/plugins/stl-generator-toolkit/README.md @@ -0,0 +1,260 @@ +# STL Generator Toolkit + +Comprehensive toolkit for generating 3D printable STL files for woodworking jigs and fixtures using CadQuery. Optimized for Elegoo Neptune 4 Pro with engineering best practices and pre-built parametric scripts. + +## What's Included + +### Skills + +**stl-generator** - Complete guide for 3D printable woodworking jig design that includes: +- Pre-built scripts for common jigs (circle cutting, angle wedges, spacing blocks) +- CadQuery parametric design patterns +- Printer-specific constraints (Elegoo Neptune 4 Pro: 225×225×265mm) +- Structural integrity and printability best practices +- Hardware integration guidelines +- Reference files for design patterns and printer specifications + +### Slash Commands + +**`/stl-generate`** - Generate custom STL files for any woodworking jig: +- Ask user for requirements and dimensions +- Use pre-built scripts when applicable +- Write custom CadQuery code for unique designs +- Export and provide download links + +**`/stl-circle-jig`** - Quick generation of circle cutting jigs: +- Router jigs for perfect circles +- Ideal for lampshade rings and circular frames +- Adjustable inner/outer diameters + +**`/stl-angle-wedge`** - Generate angle guide wedges: +- Compound miter cuts and angled assembly +- Any angle from 1-60 degrees +- Embossed angle labels for easy identification + +**`/stl-spacing-block`** - Create precision spacing blocks: +- Single blocks or matched sets +- Embossed dimension labels +- Finger relief cutouts for easy handling + +## Installation + +### Option 1: Install from Marketplace + +```bash +# Add marketplace +/plugin marketplace add ihistand/claude-plugins + +# Install plugin +/plugin install stl-generator-toolkit@ihistand +``` + +### Option 2: Install from Local Directory + +```bash +# Add marketplace locally +/plugin marketplace add /path/to/claude-plugins + +# Install plugin +/plugin install stl-generator-toolkit@dev +``` + +Then restart Claude Code. + +## Usage Examples + +### Generate a Circle Cutting Jig + +``` +User: I need a jig for cutting a 300mm diameter lampshade ring with 250mm inner diameter +Claude: /stl-circle-jig +[Generates jig with specified dimensions] +``` + +### Create an Angle Wedge + +``` +User: I need a 22.5 degree angle guide for octagon assembly +Claude: /stl-angle-wedge +[Generates wedge with embossed angle marking] +``` + +### Generate Spacing Blocks + +``` +User: I need spacing blocks for 5mm, 10mm, and 15mm gaps +Claude: /stl-spacing-block +[Generates set of three labeled spacing blocks] +``` + +### Custom Jig Design + +``` +User: I need a custom router template for mortising +Claude: /stl-generate +[Gathers requirements and writes custom CadQuery code] +``` + +## Target Printer Specifications + +- **Printer**: Elegoo Neptune 4 Pro +- **Build Volume**: 225mm × 225mm × 265mm +- **Layer Height**: 0.2mm standard +- **Units**: Metric (millimeters) + +All designs are optimized for this printer's capabilities and constraints. + +## Pre-Built Scripts + +The plugin includes three production-ready Python scripts: + +| Script | Purpose | Parameters | +|--------|---------|------------| +| `circle_cutting_jig.py` | Router jigs for perfect circles | outer_diameter, inner_diameter | +| `angle_wedge.py` | Angle guide wedges | angle_degrees (1-60°) | +| `spacing_block.py` | Precision spacing blocks | height (single) or set of heights | + +**Location**: `stl-generator-toolkit/scripts/` + +## Design Best Practices + +### Structural Integrity + +- **Wall thickness**: 3-4 perimeter walls for strength +- **Base thickness**: Minimum 5mm for flatness +- **Chamfers/fillets**: 1-2mm to reduce stress concentrations +- **Layer orientation**: Perpendicular to primary load direction + +### Printability + +- **Overhangs**: Keep under 45° to avoid supports +- **Bridges**: Avoid unsupported spans over 30mm +- **Orientation**: Largest flat surface on print bed +- **Draft angles**: 0.2mm for nesting parts + +### Woodworking Functionality + +- **Reference surfaces**: Smooth, no text on work contact areas +- **Alignment marks**: Visual indicators (notches, text, contrasting surfaces) +- **Finger reliefs**: Easy handling for small parts +- **Clamping access**: 25mm+ clearance + +### Hardware Integration + +Common hole sizes (add 0.3-0.5mm clearance): +- M3: 3.3mm hole +- M4: 4.3mm hole +- M5: 5.3mm hole +- #8 wood screw: 4.5mm hole +- 1/4"-20 bolt: 6.6mm hole + +## CadQuery Quick Reference + +**Basic structure**: +```python +import cadquery as cq + +# Create base +part = cq.Workplane("XY").box(50, 30, 10) + +# Add features +part = ( + part.faces(">Z") + .workplane() + .circle(5) + .cutThruAll() +) + +# Export +cq.exporters.export(part, "output.stl") +``` + +**Essential methods**: +- `.box(w, d, h)` - rectangular solid +- `.circle(r)` - circle sketch +- `.extrude(height)` - extrude 2D to 3D +- `.cutThruAll()` - cut through entire part +- `.fillet(radius)` - round edges +- `.chamfer(distance)` - bevel edges + +For detailed patterns, see `references/cadquery_patterns.md`. + +## Common Jig Types + +### Lampshade Jigs +- Circle cutting for ring frames +- Angle guides for tapered shades +- Spacing blocks for consistent rib spacing + +### Router Jigs +- Edge guides with adjustable fence +- Template guides (16mm OD standard) +- Bit clearance slots (7-8mm for 1/4" shanks) + +### Assembly Jigs +- Right angle corner blocks +- Spacing sets for consistent gaps +- Alignment pins (6mm diameter, 10mm height) + +### Clamping Aids +- Flat cauls with finger reliefs +- Pressure distributors +- Sacrificial clamp blocks + +## File Organization + +STL files are automatically moved to `/mnt/user-data/outputs/` for easy access and download. + +**Naming convention**: +- Good: `lampshade_jig_300mm_OD.stl` +- Good: `wedge_22.5_degrees.stl` +- Poor: `jig1.stl` + +## Troubleshooting + +### "Module 'cadquery' not found" +```bash +pip install --break-system-packages cadquery +``` + +### STL appears hollow in slicer +This is normal - slicers add infill during slicing. The generated STL is a surface model (shell). + +### Features too small to print +- Check minimum feature size: 1.0mm +- Increase wall thickness to at least 2-3mm +- Verify hole diameters are >= 2mm + +### Part doesn't fit on print bed +- Check dimensions against 220×220mm effective area +- Consider splitting large jigs into sections +- Rotate part to minimize footprint + +## Reference Files + +- **`references/printer_specs.md`** - Elegoo Neptune 4 Pro specifications and design constraints +- **`references/cadquery_patterns.md`** - Common CadQuery patterns and examples + +Always read `printer_specs.md` when starting a new jig design. + +## Official Documentation + +- [CadQuery Documentation](https://cadquery.readthedocs.io/) +- [Elegoo Neptune 4 Pro Specifications](https://www.elegoo.com/products/elegoo-neptune-4-pro-fdm-3d-printer) +- [OpenSCAD Documentation](https://openscad.org/documentation.html) (alternative CAD tool) + +## License + +Created by Ivan Histand (ihistand@rotoplas.com) + +## Contributing + +This plugin follows engineering best practices: +- All designs must fit within printer build volume +- Minimum feature sizes must be printable (≥1.0mm) +- Include structural integrity considerations +- Provide clear dimension labels and markings +- Test scripts before committing +- Document new jig patterns in references + +For questions or contributions, contact Ivan Histand. diff --git a/plugins/stl-generator-toolkit/commands/stl-angle-wedge.md b/plugins/stl-generator-toolkit/commands/stl-angle-wedge.md new file mode 100644 index 0000000..72c6990 --- /dev/null +++ b/plugins/stl-generator-toolkit/commands/stl-angle-wedge.md @@ -0,0 +1,23 @@ +--- +description: Generate angle guide wedge for compound cuts +--- + +You are generating an angle wedge STL file using the stl-generator skill and pre-built script. + +**Workflow:** + +1. Invoke the stl-generator skill +2. Ask the user for: + - Angle in degrees (1-60°) + - Optional: output filename +3. Run the angle wedge script: + ```bash + python /home/ivan/ihistand-projects/claude-plugins/stl-generator-toolkit/scripts/angle_wedge.py output.stl + ``` +4. Move STL to `/mnt/user-data/outputs/` +5. Provide: + - Download link: `[View your file](computer:///mnt/user-data/outputs/filename.stl)` + - Angle confirmation + - Suggested print settings (orient flat side on bed, no supports needed) + +**Use case**: Compound miter cuts, angled assembly work, saw blade setup verification. diff --git a/plugins/stl-generator-toolkit/commands/stl-circle-jig.md b/plugins/stl-generator-toolkit/commands/stl-circle-jig.md new file mode 100644 index 0000000..6c8bc60 --- /dev/null +++ b/plugins/stl-generator-toolkit/commands/stl-circle-jig.md @@ -0,0 +1,24 @@ +--- +description: Generate circle cutting jig for router work +--- + +You are generating a circle cutting jig STL file using the stl-generator skill and pre-built script. + +**Workflow:** + +1. Invoke the stl-generator skill +2. Ask the user for: + - Outer diameter (mm) + - Inner diameter (mm) + - Optional: output filename +3. Run the circle cutting jig script: + ```bash + python /home/ivan/ihistand-projects/claude-plugins/stl-generator-toolkit/scripts/circle_cutting_jig.py output.stl + ``` +4. Move STL to `/mnt/user-data/outputs/` +5. Provide: + - Download link: `[View your file](computer:///mnt/user-data/outputs/filename.stl)` + - Dimensions summary + - Suggested print settings (3-4 perimeter walls, 20% infill) + +**Use case**: Perfect for lampshade rings, circular frames, and router compass cutting. diff --git a/plugins/stl-generator-toolkit/commands/stl-generate.md b/plugins/stl-generator-toolkit/commands/stl-generate.md new file mode 100644 index 0000000..2831d47 --- /dev/null +++ b/plugins/stl-generator-toolkit/commands/stl-generate.md @@ -0,0 +1,25 @@ +--- +description: Generate custom 3D printable STL files for woodworking jigs +--- + +You are generating a custom STL file for 3D printing using the stl-generator skill. + +**Workflow:** + +1. Invoke the stl-generator skill +2. Ask the user what type of jig or fixture they need +3. Gather requirements: + - Dimensions and specifications + - Functional requirements + - Any special features needed +4. Check if a pre-built script exists (circle cutting jig, angle wedge, spacing block) +5. If pre-built script exists: + - Run the appropriate script with user's parameters + - Move STL to `/mnt/user-data/outputs/` +6. If custom design needed: + - Write CadQuery code following patterns from references + - Export STL file + - Move to `/mnt/user-data/outputs/` +7. Provide download link and print settings recommendations + +**Critical**: Always verify design fits within 225×225×265mm build volume (Elegoo Neptune 4 Pro). diff --git a/plugins/stl-generator-toolkit/commands/stl-spacing-block.md b/plugins/stl-generator-toolkit/commands/stl-spacing-block.md new file mode 100644 index 0000000..23becd5 --- /dev/null +++ b/plugins/stl-generator-toolkit/commands/stl-spacing-block.md @@ -0,0 +1,28 @@ +--- +description: Generate precision spacing blocks for assembly +--- + +You are generating spacing block STL file(s) using the stl-generator skill and pre-built script. + +**Workflow:** + +1. Invoke the stl-generator skill +2. Ask the user for spacing requirements: + - Single block: height (required), width, depth + - Set of blocks: comma-separated heights (e.g., "5,10,15,20") + - Optional: output filename +3. Run the spacing block script: + ```bash + # Single block + python /home/ivan/ihistand-projects/claude-plugins/stl-generator-toolkit/scripts/spacing_block.py [width_mm] [depth_mm] output.stl + + # Set of blocks + python /home/ivan/ihistand-projects/claude-plugins/stl-generator-toolkit/scripts/spacing_block.py set

,

,

output.stl + ``` +4. Move STL to `/mnt/user-data/outputs/` +5. Provide: + - Download link: `[View your file](computer:///mnt/user-data/outputs/filename.stl)` + - Block dimensions + - Suggested print settings (100% infill for accuracy, 4 perimeters) + +**Use case**: Consistent assembly gaps, router bit height setup, dado spacing verification. diff --git a/plugins/stl-generator-toolkit/references/cadquery_patterns.md b/plugins/stl-generator-toolkit/references/cadquery_patterns.md new file mode 100644 index 0000000..c415838 --- /dev/null +++ b/plugins/stl-generator-toolkit/references/cadquery_patterns.md @@ -0,0 +1,298 @@ +# CadQuery Reference for STL Generation + +## Core Concepts + +### Workplane-Based Modeling +CadQuery uses a fluent API with method chaining. Start with a workplane, build 2D sketches, then extrude to 3D. + +```python +import cadquery as cq + +# Basic box +box = cq.Workplane("XY").box(10, 20, 30) + +# Sketch then extrude +part = ( + cq.Workplane("XY") + .rect(50, 50) + .extrude(10) +) +``` + +### Coordinate Systems +- **XY plane**: Standard horizontal plane (default for most operations) +- **XZ plane**: Vertical plane (front view) +- **YZ plane**: Vertical plane (side view) + +## Common Patterns for Jigs + +### Pattern 1: Base Plate with Holes + +```python +def create_base_with_holes(width, depth, thickness, hole_positions): + """ + Create a rectangular base plate with mounting holes. + + Args: + width, depth, thickness: Dimensions in mm + hole_positions: List of (x, y, diameter) tuples + """ + base = cq.Workplane("XY").box(width, depth, thickness) + + # Add holes + for x, y, dia in hole_positions: + base = ( + base.faces(">Z") + .workplane() + .center(x, y) + .circle(dia / 2) + .cutThruAll() + ) + + return base +``` + +### Pattern 2: Raised Guide Walls + +```python +def add_guide_walls(base, wall_thickness, wall_height): + """ + Add perimeter walls to a base for guiding workpieces. + """ + # Get base dimensions + bb = base.val().BoundingBox() + width = bb.xlen + depth = bb.ylen + base_height = bb.zlen + + walls = ( + cq.Workplane("XY") + .workplane(offset=base_height) + .rect(width + 2 * wall_thickness, depth + 2 * wall_thickness) + .rect(width, depth) + .extrude(wall_height) + ) + + return base.union(walls) +``` + +### Pattern 3: Angled Slots for Bits/Blades + +```python +def add_tool_slot(part, slot_width, slot_depth, angle_degrees=0): + """ + Add a slot for router bit or saw blade clearance. + + Args: + part: Base CadQuery object + slot_width: Width of slot (mm) + slot_depth: How deep to cut (mm) + angle_degrees: Angle from horizontal (for beveled slots) + """ + bb = part.val().BoundingBox() + base_height = bb.zlen + + slot = ( + cq.Workplane("XY") + .workplane(offset=base_height / 2) + .rect(bb.xlen + 10, slot_width) + .extrude(slot_depth) + ) + + if angle_degrees != 0: + slot = slot.rotate((0, 0, 0), (1, 0, 0), angle_degrees) + + return part.cut(slot) +``` + +### Pattern 4: Alignment Pins/Locators + +```python +def add_alignment_pins(base, positions, pin_diameter=6, pin_height=10): + """ + Add cylindrical alignment pins at specified positions. + + Args: + base: Base part + positions: List of (x, y) tuples for pin centers + pin_diameter: Diameter of pins (mm) + pin_height: Height of pins above base (mm) + """ + bb = base.val().BoundingBox() + base_height = bb.zlen + + for x, y in positions: + pin = ( + cq.Workplane("XY") + .workplane(offset=base_height) + .center(x, y) + .circle(pin_diameter / 2) + .extrude(pin_height) + ) + base = base.union(pin) + + return base +``` + +### Pattern 5: Chamfers and Fillets + +```python +# Add chamfer to all edges +part = part.edges().chamfer(1.0) + +# Add fillet to specific edges (top edges only) +part = part.edges("|Z").fillet(2.0) + +# Fillet selection by position +part = part.edges(">Z").fillet(2.0) # Edges on top face +``` + +## Selection Techniques + +### Face Selection +```python +.faces(">Z") # Top face (highest Z) +.faces("X") # Right face +.faces("Z") # Edges on top face +``` + +## Boolean Operations + +```python +# Union (combine) +result = part1.union(part2) + +# Cut (subtract) +result = part1.cut(part2) + +# Intersection +result = part1.intersect(part2) +``` + +## Transformations + +```python +# Translate +part = part.translate((10, 20, 5)) + +# Rotate (center point, axis vector, angle in degrees) +part = part.rotate((0, 0, 0), (0, 0, 1), 45) + +# Mirror +part = part.mirror("XY") +``` + +## Arrays and Patterns + +### Linear Pattern +```python +# Create 5 copies spaced 20mm apart in X +for i in range(5): + copy = part.translate((i * 20, 0, 0)) + if i == 0: + result = copy + else: + result = result.union(copy) +``` + +### Circular Pattern +```python +import math + +def circular_pattern(part, count, radius): + """Create circular pattern of parts.""" + result = None + for i in range(count): + angle = (360 / count) * i + x = radius * math.cos(math.radians(angle)) + y = radius * math.sin(math.radians(angle)) + + copy = part.translate((x, y, 0)) + + if result is None: + result = copy + else: + result = result.union(copy) + + return result +``` + +## Text and Labels + +```python +# Embossed text (raised) +part = ( + part.faces(">Z") + .workplane() + .text("LABEL", fontsize=10, distance=1) +) + +# Debossed text (recessed) +part = ( + part.faces(">Z") + .workplane() + .text("LABEL", fontsize=10, distance=-1) +) +``` + +## Common Mistakes to Avoid + +1. **Forgetting workplane offset**: When adding features to top of part, offset workplane + ```python + # Wrong + .workplane().circle(5) # Starts at Z=0 + + # Right + .faces(">Z").workplane().circle(5) # Starts at top face + ``` + +2. **Wrong boolean order**: Order matters for cuts + ```python + # Creates hole + base.faces(">Z").circle(5).cutThruAll() + + # Doesn't work (no face selected yet) + base.circle(5).cutThruAll() + ``` + +3. **Lost reference**: Need to chain or reassign + ```python + # Wrong (original 'part' unchanged) + part.faces(">Z").circle(5).cutThruAll() + + # Right + part = part.faces(">Z").circle(5).cutThruAll() + ``` + +## Export Options + +```python +import cadquery as cq + +# Export to STL (for 3D printing) +cq.exporters.export(part, "output.stl") + +# Export to STEP (for CAD interchange) +cq.exporters.export(part, "output.step") + +# Export to DXF (2D drawings) +cq.exporters.export(part, "output.dxf") +``` + +## Woodworking Jig Specific Tips + +1. **Add draft angles for easier removal**: Use `.extrude(height, taper=2)` for parts that nest +2. **Clearance holes**: Always add 0.3-0.5mm to hardware diameter +3. **Reference edges**: Raised by 3-5mm for easy visual alignment +4. **Finger reliefs**: Semicircular cutouts for picking up spacers +5. **Orientation marks**: Small notch or chamfer to indicate "front" +6. **Material-friendly features**: Avoid sharp internal corners that might mark wood diff --git a/plugins/stl-generator-toolkit/references/printer_specs.md b/plugins/stl-generator-toolkit/references/printer_specs.md new file mode 100644 index 0000000..ba26f99 --- /dev/null +++ b/plugins/stl-generator-toolkit/references/printer_specs.md @@ -0,0 +1,90 @@ +# Elegoo Neptune 4 Pro - Printer Specifications + +## Build Volume +- **X-axis**: 225 mm +- **Y-axis**: 225 mm +- **Z-axis**: 265 mm +- **Effective print area**: ~220 x 220 x 260 mm (accounting for margins) + +## Print Settings +- **Layer height**: 0.2 mm (standard) +- **Nozzle diameter**: 0.4 mm (standard) +- **Minimum wall thickness**: 0.8 mm (2 perimeters) +- **Maximum overhang angle**: 45° without supports +- **Bridging capability**: ~30 mm for PLA + +## Material Properties (PLA) +- **Typical use case**: Functional jigs and fixtures +- **Layer adhesion**: Good at 0.2mm layers +- **Dimensional accuracy**: ±0.2 mm +- **Heat resistance**: Up to ~60°C +- **Recommended wall count**: 3-4 for structural parts + +## Design Constraints for Woodworking Jigs + +### General Guidelines +1. **Minimum feature size**: 1.0 mm (2.5x nozzle diameter) +2. **Hole diameters**: Add 0.3-0.5 mm clearance for hardware +3. **Text depth**: 0.4-0.6 mm for embossed text +4. **Fillet radius**: Minimum 1.0 mm for internal corners +5. **Wall thickness**: 2.0-3.0 mm minimum for structural integrity + +### Functional Tolerances +- **Tight fit**: -0.1 to 0.0 mm (for press-fit parts) +- **Slide fit**: +0.1 to +0.2 mm (for moving parts) +- **Loose fit**: +0.3 to +0.5 mm (for assembly clearance) + +### Specific to Woodworking Jigs +1. **Base stability**: Minimum 5mm thickness for flat reference surfaces +2. **Router bit clearance**: 10-12mm slots for standard 1/4" and 1/2" bits +3. **Clamp access**: 25mm+ clearance for standard clamps +4. **Screw holes**: + - M3: 3.3 mm hole + - M4: 4.3 mm hole + - M5: 5.3 mm hole + - #8 wood screw: 4.5 mm hole +5. **Material contact surfaces**: Smooth finish, avoid text/features that mar wood + +### Print Orientation Recommendations +- **Maximum strength**: Layer lines perpendicular to load direction +- **Best surface finish**: Print face-down on bed +- **Overhangs**: Orient to minimize supports (keep < 45° angle) +- **Functional surfaces**: Print against bed for best flatness + +### Support Requirements +- **Angles > 45°**: Require supports +- **Bridging**: Keep spans < 30 mm +- **Support gap**: 0.2 mm for easy removal +- **Avoid supports on**: Functional reference surfaces + +## Common Hardware Sizes (for reference holes) + +### Metric Hardware +- M3 x 0.5: 3.3 mm clearance hole +- M4 x 0.7: 4.3 mm clearance hole +- M5 x 0.8: 5.3 mm clearance hole +- M6 x 1.0: 6.4 mm clearance hole + +### Imperial Hardware +- #6 wood screw: 3.7 mm clearance hole +- #8 wood screw: 4.5 mm clearance hole +- #10 wood screw: 5.1 mm clearance hole +- 1/4"-20: 6.6 mm clearance hole + +### Router Bits (for slot sizing) +- 1/4" shank: 6.35 mm (use 7-8 mm slots) +- 1/2" shank: 12.7 mm (use 13-14 mm slots) +- Template guides: Typically 5/8" (16mm) OD + +## Material Usage Estimation +- **PLA density**: ~1.24 g/cm³ +- **Typical infill**: 20% for jigs (good strength/material balance) +- **Wall lines**: 3-4 perimeters +- **Top/bottom layers**: 4-5 layers (0.8-1.0 mm) + +## Print Time Estimation (rough guidelines) +- Small jig (50x50x10mm): ~1-2 hours +- Medium jig (100x100x20mm): ~4-6 hours +- Large jig (200x200x30mm): ~12-18 hours + +*These are estimates; actual time depends on geometry complexity and print settings.* diff --git a/plugins/stl-generator-toolkit/scripts/angle_wedge.py b/plugins/stl-generator-toolkit/scripts/angle_wedge.py new file mode 100644 index 0000000..5b5edda --- /dev/null +++ b/plugins/stl-generator-toolkit/scripts/angle_wedge.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +""" +Generate angle guide wedges for compound cuts and assembly jigs. +Useful for lampshade frames and angled joinery. +""" + +import cadquery as cq +import sys +import math + + +def create_angle_wedge( + angle_degrees: float, + width: float = 80.0, + depth: float = 60.0, + height: float = 30.0, + add_reference_edge: bool = True, +): + """ + Create an angle guide wedge. + + Args: + angle_degrees: Angle of the wedge (degrees from horizontal) + width: Width of the wedge base (mm) + depth: Depth of the wedge (mm) + height: Maximum height of the wedge (mm) + add_reference_edge: Add a raised reference edge + """ + angle_rad = math.radians(angle_degrees) + + # Calculate the wedge profile + wedge_height = min(depth * math.tan(angle_rad), height) + + # Create wedge body using loft + base = cq.Workplane("XY").rect(width, depth) + + # Create top profile (angled) + top = ( + cq.Workplane("XY") + .workplane(offset=wedge_height) + .center(0, -depth / 2 + depth) + .rect(width, 0.1) + ) + + # Create the wedge using a simple extrude with taper + wedge = ( + cq.Workplane("XY") + .rect(width, depth) + .extrude(wedge_height, taper=-angle_degrees) + ) + + # Alternative: Create wedge as a solid using points + points = [ + (-width / 2, -depth / 2, 0), + (width / 2, -depth / 2, 0), + (width / 2, depth / 2, 0), + (-width / 2, depth / 2, 0), + (-width / 2, -depth / 2, wedge_height), + (width / 2, -depth / 2, wedge_height), + (width / 2, depth / 2, 0), + (-width / 2, depth / 2, 0), + ] + + # Simpler approach: Create wedge profile and extrude + wedge = ( + cq.Workplane("XZ") + .moveTo(-depth / 2, 0) + .lineTo(depth / 2, 0) + .lineTo(depth / 2, wedge_height) + .lineTo(-depth / 2, 0) + .close() + .extrude(width) + .translate((0, 0, -width / 2)) + .rotate((0, 0, 0), (0, 0, 1), 90) + ) + + if add_reference_edge: + # Add raised reference edge along hypotenuse + edge_thickness = 3 + edge_height = 5 + + # Calculate edge position along the sloped surface + edge = ( + cq.Workplane("XY") + .center(0, 0) + .rect(edge_thickness, depth) + .extrude(edge_height) + .translate((0, 0, wedge_height / 2)) + .rotate((0, -depth / 2, wedge_height / 2), (0, depth / 2, 0), -angle_degrees) + ) + + wedge = wedge.union(edge) + + # Add text label with angle + try: + wedge = ( + wedge.faces(">Z") + .workplane() + .text( + f"{angle_degrees}°", + fontsize=8, + distance=-1, + halign="center", + valign="center", + ) + ) + except: + pass # Text might fail in some CadQuery versions + + return wedge + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: angle_wedge.py [output.stl]") + print("Example: angle_wedge.py 15 wedge_15deg.stl") + sys.exit(1) + + angle = float(sys.argv[1]) + output = sys.argv[2] if len(sys.argv) > 2 else f"wedge_{int(angle)}deg.stl" + + print(f"Generating {angle}° angle wedge") + + wedge = create_angle_wedge(angle_degrees=angle) + + # Export to STL + cq.exporters.export(wedge, output) + print(f"✓ STL saved to: {output}") diff --git a/plugins/stl-generator-toolkit/scripts/circle_cutting_jig.py b/plugins/stl-generator-toolkit/scripts/circle_cutting_jig.py new file mode 100644 index 0000000..027a105 --- /dev/null +++ b/plugins/stl-generator-toolkit/scripts/circle_cutting_jig.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +""" +Generate a circle cutting jig for router or trim tools. +Perfect for creating lampshade rings and circular frames. +""" + +import cadquery as cq +import sys + + +def create_circle_jig( + outer_diameter: float, + inner_diameter: float, + thickness: float = 10.0, + guide_width: float = 20.0, + guide_height: float = 8.0, + slot_width: float = 8.0, + center_hole_diameter: float = 8.0, +): + """ + Create a circle cutting jig. + + Args: + outer_diameter: Outer diameter of the circle to cut (mm) + inner_diameter: Inner diameter of the circle to cut (mm) + thickness: Base plate thickness (mm) + guide_width: Width of the guide ring (mm) + guide_height: Height of guide walls (mm) + slot_width: Width of router bit slot (mm) + center_hole_diameter: Diameter of center pivot hole (mm) + """ + # Create base plate + base = ( + cq.Workplane("XY") + .circle(outer_diameter / 2 + guide_width) + .extrude(thickness) + ) + + # Cut out inner circle + base = base.faces(">Z").circle(inner_diameter / 2).cutThruAll() + + # Cut center pivot hole + base = base.faces(">Z").workplane().circle(center_hole_diameter / 2).cutThruAll() + + # Create guide ring on top + guide = ( + cq.Workplane("XY") + .workplane(offset=thickness) + .circle(outer_diameter / 2 + guide_width) + .circle(outer_diameter / 2) + .extrude(guide_height) + ) + + # Add alignment marks every 45 degrees + for angle in range(0, 360, 45): + mark = ( + cq.Workplane("XY") + .workplane(offset=thickness) + .transformed(rotate=(0, 0, angle)) + .center(outer_diameter / 2 + guide_width / 2, 0) + .rect(2, guide_width) + .extrude(guide_height + 1) + ) + guide = guide.cut(mark) + + # Add router bit slot (radial) + slot = ( + cq.Workplane("XY") + .workplane(offset=thickness) + .center(0, 0) + .rect((outer_diameter / 2 + guide_width), slot_width) + .extrude(guide_height + thickness + 1) + ) + + result = base.union(guide).cut(slot) + + return result + + +if __name__ == "__main__": + if len(sys.argv) < 3: + print("Usage: circle_cutting_jig.py [output.stl]") + print("Example: circle_cutting_jig.py 300 250 lampshade_jig.stl") + sys.exit(1) + + outer_d = float(sys.argv[1]) + inner_d = float(sys.argv[2]) + output = sys.argv[3] if len(sys.argv) > 3 else "circle_jig.stl" + + print(f"Generating circle cutting jig: OD={outer_d}mm, ID={inner_d}mm") + + jig = create_circle_jig(outer_diameter=outer_d, inner_diameter=inner_d) + + # Export to STL + cq.exporters.export(jig, output) + print(f"✓ STL saved to: {output}") diff --git a/plugins/stl-generator-toolkit/scripts/spacing_block.py b/plugins/stl-generator-toolkit/scripts/spacing_block.py new file mode 100644 index 0000000..d728c36 --- /dev/null +++ b/plugins/stl-generator-toolkit/scripts/spacing_block.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +""" +Generate precision spacing blocks for assembly and alignment. +Perfect for consistent spacing in lampshade frames and joinery setup. +""" + +import cadquery as cq +import sys + + +def create_spacing_block( + width: float, + depth: float, + height: float, + add_finger_relief: bool = True, + add_label: bool = True, +): + """ + Create a spacing/setup block. + + Args: + width: Block width (mm) + depth: Block depth (mm) + height: Block height/thickness (mm) + add_finger_relief: Add cutouts for easy pickup + add_label: Emboss dimensions on top + """ + # Create main block + block = cq.Workplane("XY").box(width, depth, height) + + if add_finger_relief: + # Add semicircular cutouts on opposite sides for grip + relief_diameter = min(height * 1.2, 20) + + for side in [-1, 1]: + relief = ( + cq.Workplane("YZ") + .workplane(offset=side * width / 2) + .center(0, -height / 2) + .circle(relief_diameter / 2) + .extrude(10) + ) + block = block.cut(relief) + + if add_label: + # Emboss dimension label on top surface + label_text = f"{height}mm" + try: + block = ( + block.faces(">Z") + .workplane() + .text( + label_text, + fontsize=min(6, height / 2), + distance=-0.5, + halign="center", + valign="center", + ) + ) + except: + pass # Text might fail in some CadQuery versions + + # Add orientation marker (small notch on one corner) + marker = ( + cq.Workplane("XY") + .workplane(offset=height / 2) + .center(-width / 2 + 3, -depth / 2 + 3) + .rect(3, 3) + .extrude(2) + ) + block = block.cut(marker) + + return block + + +def create_spacing_set(heights: list, width: float = 50.0, depth: float = 30.0): + """ + Create a set of spacing blocks with different heights. + Arranged in a row for printing. + + Args: + heights: List of heights in mm + width: Block width (mm) + depth: Block depth (mm) + """ + spacing = 5 # Gap between blocks + result = None + x_offset = 0 + + for height in sorted(heights): + block = create_spacing_block(width, depth, height) + block = block.translate((x_offset, 0, 0)) + + if result is None: + result = block + else: + result = result.union(block) + + x_offset += width + spacing + + return result + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: spacing_block.py [width_mm] [depth_mm] [output.stl]") + print(" Or: spacing_block.py set

,

,

... [output.stl]") + print() + print("Examples:") + print(" spacing_block.py 10 50 30 spacer_10mm.stl") + print(" spacing_block.py set 5,10,15,20 spacer_set.stl") + sys.exit(1) + + if sys.argv[1].lower() == "set": + # Create a set of blocks + if len(sys.argv) < 3: + print("Error: Must specify heights after 'set'") + sys.exit(1) + + heights = [float(h) for h in sys.argv[2].split(",")] + output = sys.argv[3] if len(sys.argv) > 3 else "spacing_set.stl" + + print(f"Generating spacing block set: {heights} mm") + result = create_spacing_set(heights) + else: + # Create single block + height = float(sys.argv[1]) + width = float(sys.argv[2]) if len(sys.argv) > 2 else 50.0 + depth = float(sys.argv[3]) if len(sys.argv) > 3 else 30.0 + output = sys.argv[4] if len(sys.argv) > 4 else f"spacer_{int(height)}mm.stl" + + print(f"Generating spacing block: {width}x{depth}x{height} mm") + result = create_spacing_block(width, depth, height) + + # Export to STL + cq.exporters.export(result, output) + print(f"✓ STL saved to: {output}") diff --git a/plugins/stl-generator-toolkit/skills/stl-generator.md b/plugins/stl-generator-toolkit/skills/stl-generator.md new file mode 100644 index 0000000..344d7b3 --- /dev/null +++ b/plugins/stl-generator-toolkit/skills/stl-generator.md @@ -0,0 +1,285 @@ +--- +name: stl-generator +description: Generate 3D printable STL files for woodworking jigs and fixtures using CadQuery. Use when the user requests lampshade jigs, circle cutting guides, angle wedges, spacing blocks, alignment fixtures, router jigs, or any custom 3D-printed woodworking aid. Optimized for Elegoo Neptune 4 Pro (225x225x265mm build volume, 0.2mm layer height). Always use metric measurements. +--- + +# STL Generator for Woodworking Jigs + +Generate parametric 3D printable jigs and fixtures for woodworking projects using CadQuery. + +## Target Printer Specifications + +- **Printer**: Elegoo Neptune 4 Pro +- **Build volume**: 225mm × 225mm × 265mm +- **Layer height**: 0.2mm standard +- **Units**: Metric (millimeters) + +For complete specifications and design constraints, read `references/printer_specs.md`. + +## Available Pre-Built Scripts + +### 1. Circle Cutting Jig (`scripts/circle_cutting_jig.py`) + +Creates router jigs for cutting perfect circles - ideal for lampshade rings and circular frames. + +**Usage**: +```bash +python scripts/circle_cutting_jig.py [output.stl] +``` + +**Example**: +```bash +python scripts/circle_cutting_jig.py 300 250 lampshade_jig.stl +``` + +**Features**: +- Adjustable inner/outer diameters +- Built-in guide ring for router stability +- Center pivot hole for compass-style cutting +- Radial slot for router bit clearance +- Alignment marks every 45° + +### 2. Angle Wedge (`scripts/angle_wedge.py`) + +Creates angle guide wedges for compound cuts and angled assembly work. + +**Usage**: +```bash +python scripts/angle_wedge.py [output.stl] +``` + +**Example**: +```bash +python scripts/angle_wedge.py 15 wedge_15deg.stl +``` + +**Features**: +- Any angle from 1-60 degrees +- Raised reference edge on hypotenuse +- Embossed angle label +- Stable base for accurate positioning + +### 3. Spacing Blocks (`scripts/spacing_block.py`) + +Creates precision spacing blocks for consistent assembly gaps and setup. + +**Usage**: +```bash +# Single block +python scripts/spacing_block.py [width_mm] [depth_mm] [output.stl] + +# Set of multiple heights +python scripts/spacing_block.py set

,

,

[output.stl] +``` + +**Examples**: +```bash +python scripts/spacing_block.py 10 50 30 spacer_10mm.stl +python scripts/spacing_block.py set 5,10,15,20 spacer_set.stl +``` + +**Features**: +- Embossed dimension labels +- Finger relief cutouts for easy pickup +- Orientation markers +- Can generate matched sets + +## Creating Custom Jigs + +For custom jig designs not covered by pre-built scripts, write Python code using CadQuery. Read `references/cadquery_patterns.md` for common patterns and best practices. + +### Workflow for Custom Jigs + +1. **Understand requirements**: Get dimensions, constraints, and functional needs +2. **Check printer limits**: Verify design fits within 225×225×265mm build volume +3. **Apply design constraints**: Use guidelines from `references/printer_specs.md`: + - Minimum wall thickness: 2-3mm for structural parts + - Hole clearances: +0.3-0.5mm for hardware + - Minimum feature size: 1.0mm + - Text depth: 0.4-0.6mm +4. **Write CadQuery code**: Use patterns from `references/cadquery_patterns.md` +5. **Export to STL**: Use `cq.exporters.export(part, "filename.stl")` +6. **Save to outputs**: Move STL file to `/mnt/user-data/outputs/` for user access + +### Example: Custom Router Template + +```python +import cadquery as cq + +def create_router_template(length, width, inset, guide_height): + """Create router template with guide bushings.""" + + # Base plate + base = ( + cq.Workplane("XY") + .rect(length, width) + .extrude(6) + ) + + # Cut out center area + base = ( + base.faces(">Z") + .workplane() + .rect(length - 2 * inset, width - 2 * inset) + .cutThruAll() + ) + + # Add guide walls + walls = ( + cq.Workplane("XY") + .workplane(offset=6) + .rect(length, width) + .rect(length - 2 * inset, width - 2 * inset) + .extrude(guide_height) + ) + + result = base.union(walls) + + # Add mounting holes (corners) + for x in [-length/2 + 15, length/2 - 15]: + for y in [-width/2 + 15, width/2 - 15]: + result = ( + result.faces(">Z") + .workplane() + .center(x, y) + .circle(2.5) # M5 clearance + .cutThruAll() + ) + + return result + +# Generate and export +template = create_router_template(200, 150, 30, 8) +cq.exporters.export(template, "router_template.stl") +``` + +## Common Jig Types and Approaches + +### Lampshade Jigs +- **Circle cutting**: Use `circle_cutting_jig.py` for ring frames +- **Angle guides**: Use `angle_wedge.py` for tapered shade angles +- **Spacing**: Use `spacing_block.py` for consistent rib spacing + +### Router Jigs +- **Edge guides**: Rectangular frame with adjustable fence +- **Template guides**: Match standard template bushing sizes (16mm OD common) +- **Bit clearance**: 7-8mm slots for 1/4" shanks, 13-14mm for 1/2" + +### Assembly Jigs +- **Right angle corners**: 90° blocks with reference edges +- **Spacing sets**: Multiple blocks for consistent gaps +- **Alignment pins**: 6mm diameter pins, 10mm height standard + +### Clamping Aids +- **Cauls**: Flat plates with finger reliefs +- **Pressure distributors**: Curved or stepped surfaces +- **Clamp blocks**: Sacrificial blocks with protective surfaces + +## Design Best Practices + +### Structural Integrity +- Use 3-4 perimeter walls for strength +- Add chamfers/fillets (1-2mm) to reduce stress concentrations +- Orient layer lines perpendicular to primary load direction +- Minimum 5mm base thickness for flatness + +### Printability +- Keep overhangs under 45° to avoid supports +- Add 0.2mm draft angle for parts that nest +- Avoid unsupported bridges over 30mm +- Orient largest flat surface on print bed + +### Woodworking Functionality +- Smooth reference surfaces (no text or features on work contact areas) +- Add visual alignment marks (notches, text, contrasting surfaces) +- Include finger reliefs on small parts for easy handling +- Consider clamping access (25mm+ clearance) + +### Hardware Integration +Common hole sizes (add 0.3-0.5mm clearance): +- M3: 3.3mm hole +- M4: 4.3mm hole +- M5: 5.3mm hole +- #8 wood screw: 4.5mm hole +- 1/4"-20 bolt: 6.6mm hole + +## File Organization + +When generating STL files: + +1. **Work in** `/home/claude/` during development +2. **Test scripts** by running them to verify output +3. **Copy final STLs** to `/mnt/user-data/outputs/` before presenting to user +4. **Name files descriptively**: Include key dimensions or purpose + - Good: `lampshade_jig_300mm_OD.stl` + - Good: `wedge_22.5_degrees.stl` + - Poor: `jig1.stl` + +## CadQuery Quick Reference + +For detailed patterns and examples, read `references/cadquery_patterns.md`. + +**Basic structure**: +```python +import cadquery as cq + +# Create base +part = cq.Workplane("XY").box(50, 30, 10) + +# Add features on top +part = ( + part.faces(">Z") + .workplane() + .circle(5) + .cutThruAll() +) + +# Export +cq.exporters.export(part, "output.stl") +``` + +**Essential methods**: +- `.box(w, d, h)` - rectangular solid +- `.circle(r)` - circle sketch +- `.rect(w, h)` - rectangle sketch +- `.extrude(height)` - extrude 2D to 3D +- `.cutThruAll()` - cut through entire part +- `.fillet(radius)` - round edges +- `.chamfer(distance)` - bevel edges +- `.translate((x, y, z))` - move part +- `.rotate((cx,cy,cz), (ax,ay,az), angle)` - rotate around axis + +## Troubleshooting + +### "Module 'cadquery' not found" +```bash +pip install --break-system-packages cadquery +``` + +### STL appears hollow in slicer +- This is normal - slicers add infill during slicing +- The generated STL is a shell (surface model) + +### Features too small to print +- Check minimum feature size: 1.0mm +- Increase wall thickness to at least 2-3mm +- Verify hole diameters are >= 2mm + +### Part doesn't fit on print bed +- Check dimensions against 220×220mm effective area +- Consider splitting large jigs into sections +- Rotate part to minimize footprint + +## When to Read Reference Files + +- **Always read** `references/printer_specs.md` when starting a new jig design +- **Read** `references/cadquery_patterns.md` when writing custom CadQuery code +- **Refer to** examples in pattern files for complex geometries + +## Output Format + +After generating STL file(s), always: +1. Move final STLs to `/mnt/user-data/outputs/` +2. Provide download link: `[View your file](computer:///mnt/user-data/outputs/filename.stl)` +3. Include brief summary: dimensions, purpose, estimated print time +4. Suggest print settings if relevant (infill %, supports, orientation)