@hivehub/rulebook 1.2.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/LICENSE +191 -0
- package/README.md +539 -0
- package/dist/agents/claude-code.d.ts +69 -0
- package/dist/agents/claude-code.d.ts.map +1 -0
- package/dist/agents/claude-code.js +180 -0
- package/dist/agents/claude-code.js.map +1 -0
- package/dist/agents/cursor-agent.d.ts +184 -0
- package/dist/agents/cursor-agent.d.ts.map +1 -0
- package/dist/agents/cursor-agent.js +299 -0
- package/dist/agents/cursor-agent.js.map +1 -0
- package/dist/agents/gemini-cli.d.ts +69 -0
- package/dist/agents/gemini-cli.d.ts.map +1 -0
- package/dist/agents/gemini-cli.js +180 -0
- package/dist/agents/gemini-cli.js.map +1 -0
- package/dist/cli/commands.d.ts +57 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +1370 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/docs-prompts.d.ts +3 -0
- package/dist/cli/docs-prompts.d.ts.map +1 -0
- package/dist/cli/docs-prompts.js +45 -0
- package/dist/cli/docs-prompts.js.map +1 -0
- package/dist/cli/prompts.d.ts +6 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +376 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/core/agent-manager.d.ts +89 -0
- package/dist/core/agent-manager.d.ts.map +1 -0
- package/dist/core/agent-manager.js +546 -0
- package/dist/core/agent-manager.js.map +1 -0
- package/dist/core/auto-fixer.d.ts +14 -0
- package/dist/core/auto-fixer.d.ts.map +1 -0
- package/dist/core/auto-fixer.js +207 -0
- package/dist/core/auto-fixer.js.map +1 -0
- package/dist/core/changelog-generator.d.ts +44 -0
- package/dist/core/changelog-generator.d.ts.map +1 -0
- package/dist/core/changelog-generator.js +222 -0
- package/dist/core/changelog-generator.js.map +1 -0
- package/dist/core/cli-bridge.d.ts +113 -0
- package/dist/core/cli-bridge.d.ts.map +1 -0
- package/dist/core/cli-bridge.js +1094 -0
- package/dist/core/cli-bridge.js.map +1 -0
- package/dist/core/config-manager.d.ts +65 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +266 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/coverage-checker.d.ts +14 -0
- package/dist/core/coverage-checker.d.ts.map +1 -0
- package/dist/core/coverage-checker.js +176 -0
- package/dist/core/coverage-checker.js.map +1 -0
- package/dist/core/custom-templates.d.ts +27 -0
- package/dist/core/custom-templates.d.ts.map +1 -0
- package/dist/core/custom-templates.js +122 -0
- package/dist/core/custom-templates.js.map +1 -0
- package/dist/core/dependency-checker.d.ts +21 -0
- package/dist/core/dependency-checker.d.ts.map +1 -0
- package/dist/core/dependency-checker.js +247 -0
- package/dist/core/dependency-checker.js.map +1 -0
- package/dist/core/detector.d.ts +3 -0
- package/dist/core/detector.d.ts.map +1 -0
- package/dist/core/detector.js +1443 -0
- package/dist/core/detector.js.map +1 -0
- package/dist/core/docs-generator.d.ts +9 -0
- package/dist/core/docs-generator.d.ts.map +1 -0
- package/dist/core/docs-generator.js +531 -0
- package/dist/core/docs-generator.js.map +1 -0
- package/dist/core/generator.d.ts +16 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +561 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/gitignore-generator.d.ts +13 -0
- package/dist/core/gitignore-generator.d.ts.map +1 -0
- package/dist/core/gitignore-generator.js +307 -0
- package/dist/core/gitignore-generator.js.map +1 -0
- package/dist/core/health-scorer.d.ts +22 -0
- package/dist/core/health-scorer.d.ts.map +1 -0
- package/dist/core/health-scorer.js +395 -0
- package/dist/core/health-scorer.js.map +1 -0
- package/dist/core/logger.d.ts +116 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +289 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/merger.d.ts +6 -0
- package/dist/core/merger.d.ts.map +1 -0
- package/dist/core/merger.js +131 -0
- package/dist/core/merger.js.map +1 -0
- package/dist/core/migrator.d.ts +19 -0
- package/dist/core/migrator.d.ts.map +1 -0
- package/dist/core/migrator.js +102 -0
- package/dist/core/migrator.js.map +1 -0
- package/dist/core/minimal-scaffolder.d.ts +8 -0
- package/dist/core/minimal-scaffolder.d.ts.map +1 -0
- package/dist/core/minimal-scaffolder.js +51 -0
- package/dist/core/minimal-scaffolder.js.map +1 -0
- package/dist/core/modern-console-new.d.ts +81 -0
- package/dist/core/modern-console-new.d.ts.map +1 -0
- package/dist/core/modern-console-new.js +340 -0
- package/dist/core/modern-console-new.js.map +1 -0
- package/dist/core/modern-console.d.ts +99 -0
- package/dist/core/modern-console.d.ts.map +1 -0
- package/dist/core/modern-console.js +568 -0
- package/dist/core/modern-console.js.map +1 -0
- package/dist/core/openspec-manager.d.ts +133 -0
- package/dist/core/openspec-manager.d.ts.map +1 -0
- package/dist/core/openspec-manager.js +605 -0
- package/dist/core/openspec-manager.js.map +1 -0
- package/dist/core/openspec-migrator.d.ts +27 -0
- package/dist/core/openspec-migrator.d.ts.map +1 -0
- package/dist/core/openspec-migrator.js +255 -0
- package/dist/core/openspec-migrator.js.map +1 -0
- package/dist/core/task-manager.d.ts +65 -0
- package/dist/core/task-manager.d.ts.map +1 -0
- package/dist/core/task-manager.js +318 -0
- package/dist/core/task-manager.js.map +1 -0
- package/dist/core/test-task-manager.d.ts +49 -0
- package/dist/core/test-task-manager.d.ts.map +1 -0
- package/dist/core/test-task-manager.js +121 -0
- package/dist/core/test-task-manager.js.map +1 -0
- package/dist/core/validator.d.ts +21 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +177 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/core/version-bumper.d.ts +19 -0
- package/dist/core/version-bumper.d.ts.map +1 -0
- package/dist/core/version-bumper.js +180 -0
- package/dist/core/version-bumper.js.map +1 -0
- package/dist/core/watcher.d.ts +9 -0
- package/dist/core/watcher.d.ts.map +1 -0
- package/dist/core/watcher.js +22 -0
- package/dist/core/watcher.js.map +1 -0
- package/dist/core/workflow-generator.d.ts +10 -0
- package/dist/core/workflow-generator.d.ts.map +1 -0
- package/dist/core/workflow-generator.js +279 -0
- package/dist/core/workflow-generator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +159 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/handlers/archive-task.d.ts +17 -0
- package/dist/mcp/handlers/archive-task.d.ts.map +1 -0
- package/dist/mcp/handlers/archive-task.js +36 -0
- package/dist/mcp/handlers/archive-task.js.map +1 -0
- package/dist/mcp/handlers/create-task.d.ts +17 -0
- package/dist/mcp/handlers/create-task.d.ts.map +1 -0
- package/dist/mcp/handlers/create-task.js +56 -0
- package/dist/mcp/handlers/create-task.js.map +1 -0
- package/dist/mcp/handlers/list-tasks.d.ts +22 -0
- package/dist/mcp/handlers/list-tasks.d.ts.map +1 -0
- package/dist/mcp/handlers/list-tasks.js +42 -0
- package/dist/mcp/handlers/list-tasks.js.map +1 -0
- package/dist/mcp/handlers/show-task.d.ts +25 -0
- package/dist/mcp/handlers/show-task.d.ts.map +1 -0
- package/dist/mcp/handlers/show-task.js +43 -0
- package/dist/mcp/handlers/show-task.js.map +1 -0
- package/dist/mcp/handlers/update-task.d.ts +17 -0
- package/dist/mcp/handlers/update-task.d.ts.map +1 -0
- package/dist/mcp/handlers/update-task.js +35 -0
- package/dist/mcp/handlers/update-task.js.map +1 -0
- package/dist/mcp/handlers/validate-task.d.ts +15 -0
- package/dist/mcp/handlers/validate-task.d.ts.map +1 -0
- package/dist/mcp/handlers/validate-task.js +27 -0
- package/dist/mcp/handlers/validate-task.js.map +1 -0
- package/dist/mcp/rulebook-config.d.ts +22 -0
- package/dist/mcp/rulebook-config.d.ts.map +1 -0
- package/dist/mcp/rulebook-config.js +65 -0
- package/dist/mcp/rulebook-config.js.map +1 -0
- package/dist/mcp/rulebook-server.d.ts +4 -0
- package/dist/mcp/rulebook-server.d.ts.map +1 -0
- package/dist/mcp/rulebook-server.js +246 -0
- package/dist/mcp/rulebook-server.js.map +1 -0
- package/dist/types.d.ts +190 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file-system.d.ts +9 -0
- package/dist/utils/file-system.d.ts.map +1 -0
- package/dist/utils/file-system.js +51 -0
- package/dist/utils/file-system.js.map +1 -0
- package/dist/utils/git-hooks.d.ts +8 -0
- package/dist/utils/git-hooks.d.ts.map +1 -0
- package/dist/utils/git-hooks.js +440 -0
- package/dist/utils/git-hooks.js.map +1 -0
- package/dist/utils/rulesignore.d.ts +9 -0
- package/dist/utils/rulesignore.d.ts.map +1 -0
- package/dist/utils/rulesignore.js +42 -0
- package/dist/utils/rulesignore.js.map +1 -0
- package/package.json +106 -0
- package/templates/cli/AIDER.md +49 -0
- package/templates/cli/AMAZON_Q.md +25 -0
- package/templates/cli/AUGGIE.md +32 -0
- package/templates/cli/CLAUDE.md +32 -0
- package/templates/cli/CLAUDE_CODE.md +35 -0
- package/templates/cli/CLINE.md +32 -0
- package/templates/cli/CODEBUDDY.md +20 -0
- package/templates/cli/CODEIUM.md +20 -0
- package/templates/cli/CODEX.md +21 -0
- package/templates/cli/CONTINUE.md +34 -0
- package/templates/cli/CURSOR_CLI.md +28 -0
- package/templates/cli/FACTORY.md +18 -0
- package/templates/cli/GEMINI.md +35 -0
- package/templates/cli/KILOCODE.md +18 -0
- package/templates/cli/OPENCODE.md +18 -0
- package/templates/cli/_GENERIC_TEMPLATE.md +29 -0
- package/templates/commands/rulebook-task-apply.md +67 -0
- package/templates/commands/rulebook-task-archive.md +70 -0
- package/templates/commands/rulebook-task-create.md +93 -0
- package/templates/commands/rulebook-task-list.md +42 -0
- package/templates/commands/rulebook-task-show.md +52 -0
- package/templates/commands/rulebook-task-validate.md +53 -0
- package/templates/core/AGENT_AUTOMATION.md +184 -0
- package/templates/core/DAG.md +304 -0
- package/templates/core/DOCUMENTATION_RULES.md +37 -0
- package/templates/core/QUALITY_ENFORCEMENT.md +68 -0
- package/templates/core/RULEBOOK.md +1874 -0
- package/templates/frameworks/ANGULAR.md +36 -0
- package/templates/frameworks/DJANGO.md +83 -0
- package/templates/frameworks/ELECTRON.md +147 -0
- package/templates/frameworks/FLASK.md +38 -0
- package/templates/frameworks/FLUTTER.md +55 -0
- package/templates/frameworks/JQUERY.md +32 -0
- package/templates/frameworks/LARAVEL.md +38 -0
- package/templates/frameworks/NESTJS.md +43 -0
- package/templates/frameworks/NEXTJS.md +127 -0
- package/templates/frameworks/NUXT.md +40 -0
- package/templates/frameworks/RAILS.md +66 -0
- package/templates/frameworks/REACT.md +38 -0
- package/templates/frameworks/REACT_NATIVE.md +47 -0
- package/templates/frameworks/SPRING.md +39 -0
- package/templates/frameworks/SYMFONY.md +36 -0
- package/templates/frameworks/VUE.md +36 -0
- package/templates/frameworks/ZEND.md +35 -0
- package/templates/git/CI_CD_PATTERNS.md +661 -0
- package/templates/git/GITHUB_ACTIONS.md +728 -0
- package/templates/git/GITLAB_CI.md +730 -0
- package/templates/git/GIT_WORKFLOW.md +1157 -0
- package/templates/git/SECRETS_MANAGEMENT.md +585 -0
- package/templates/hooks/COMMIT_MSG.md +530 -0
- package/templates/hooks/POST_CHECKOUT.md +546 -0
- package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -0
- package/templates/hooks/PRE_COMMIT.md +414 -0
- package/templates/hooks/PRE_PUSH.md +601 -0
- package/templates/hooks/csharp-pre-commit.sh +23 -0
- package/templates/hooks/csharp-pre-push.sh +23 -0
- package/templates/hooks/dart-pre-commit.sh +30 -0
- package/templates/hooks/dart-pre-push.sh +25 -0
- package/templates/hooks/elixir-pre-commit.sh +32 -0
- package/templates/hooks/elixir-pre-push.sh +31 -0
- package/templates/hooks/erlang-pre-commit.sh +30 -0
- package/templates/hooks/erlang-pre-push.sh +37 -0
- package/templates/hooks/go-pre-commit.sh +40 -0
- package/templates/hooks/go-pre-push.sh +31 -0
- package/templates/hooks/haskell-pre-commit.sh +41 -0
- package/templates/hooks/haskell-pre-push.sh +37 -0
- package/templates/hooks/java-pre-commit.sh +34 -0
- package/templates/hooks/java-pre-push.sh +24 -0
- package/templates/hooks/kotlin-pre-commit.sh +32 -0
- package/templates/hooks/kotlin-pre-push.sh +16 -0
- package/templates/hooks/php-pre-commit.sh +36 -0
- package/templates/hooks/php-pre-push.sh +26 -0
- package/templates/hooks/python-pre-commit.sh +51 -0
- package/templates/hooks/python-pre-push.sh +25 -0
- package/templates/hooks/ruby-pre-commit.sh +33 -0
- package/templates/hooks/ruby-pre-push.sh +32 -0
- package/templates/hooks/rust-pre-commit.sh +30 -0
- package/templates/hooks/rust-pre-push.sh +30 -0
- package/templates/hooks/scala-pre-commit.sh +32 -0
- package/templates/hooks/scala-pre-push.sh +24 -0
- package/templates/hooks/swift-pre-commit.sh +25 -0
- package/templates/hooks/swift-pre-push.sh +23 -0
- package/templates/hooks/typescript-pre-commit.sh +37 -0
- package/templates/hooks/typescript-pre-push.sh +36 -0
- package/templates/ides/COPILOT.md +37 -0
- package/templates/ides/CURSOR.md +43 -0
- package/templates/ides/JETBRAINS_AI.md +35 -0
- package/templates/ides/REPLIT.md +36 -0
- package/templates/ides/TABNINE.md +29 -0
- package/templates/ides/VSCODE.md +40 -0
- package/templates/ides/WINDSURF.md +36 -0
- package/templates/ides/ZED.md +32 -0
- package/templates/languages/ADA.md +58 -0
- package/templates/languages/C.md +333 -0
- package/templates/languages/CPP.md +743 -0
- package/templates/languages/CSHARP.md +417 -0
- package/templates/languages/DART.md +332 -0
- package/templates/languages/ELIXIR.md +454 -0
- package/templates/languages/ERLANG.md +361 -0
- package/templates/languages/GO.md +645 -0
- package/templates/languages/HASKELL.md +177 -0
- package/templates/languages/JAVA.md +607 -0
- package/templates/languages/JAVASCRIPT.md +631 -0
- package/templates/languages/JULIA.md +97 -0
- package/templates/languages/KOTLIN.md +511 -0
- package/templates/languages/LISP.md +100 -0
- package/templates/languages/LUA.md +74 -0
- package/templates/languages/OBJECTIVEC.md +90 -0
- package/templates/languages/PHP.md +416 -0
- package/templates/languages/PYTHON.md +682 -0
- package/templates/languages/R.md +350 -0
- package/templates/languages/RUBY.md +421 -0
- package/templates/languages/RUST.md +477 -0
- package/templates/languages/SAS.md +73 -0
- package/templates/languages/SCALA.md +348 -0
- package/templates/languages/SOLIDITY.md +580 -0
- package/templates/languages/SQL.md +137 -0
- package/templates/languages/SWIFT.md +466 -0
- package/templates/languages/TYPESCRIPT.md +591 -0
- package/templates/languages/ZIG.md +265 -0
- package/templates/modules/ATLASSIAN.md +255 -0
- package/templates/modules/CONTEXT7.md +54 -0
- package/templates/modules/FIGMA.md +267 -0
- package/templates/modules/GITHUB_MCP.md +64 -0
- package/templates/modules/GRAFANA.md +328 -0
- package/templates/modules/NOTION.md +247 -0
- package/templates/modules/PLAYWRIGHT.md +90 -0
- package/templates/modules/RULEBOOK_MCP.md +156 -0
- package/templates/modules/SERENA.md +337 -0
- package/templates/modules/SUPABASE.md +223 -0
- package/templates/modules/SYNAP.md +69 -0
- package/templates/modules/VECTORIZER.md +63 -0
- package/templates/services/AZURE_BLOB.md +184 -0
- package/templates/services/CASSANDRA.md +239 -0
- package/templates/services/DYNAMODB.md +308 -0
- package/templates/services/ELASTICSEARCH.md +347 -0
- package/templates/services/GCS.md +178 -0
- package/templates/services/INFLUXDB.md +265 -0
- package/templates/services/KAFKA.md +341 -0
- package/templates/services/MARIADB.md +183 -0
- package/templates/services/MEMCACHED.md +242 -0
- package/templates/services/MINIO.md +201 -0
- package/templates/services/MONGODB.md +268 -0
- package/templates/services/MYSQL.md +358 -0
- package/templates/services/NEO4J.md +247 -0
- package/templates/services/ORACLE.md +290 -0
- package/templates/services/POSTGRESQL.md +326 -0
- package/templates/services/RABBITMQ.md +286 -0
- package/templates/services/REDIS.md +292 -0
- package/templates/services/S3.md +298 -0
- package/templates/services/SQLITE.md +294 -0
- package/templates/services/SQLSERVER.md +294 -0
- package/templates/workflows/codespell.yml +31 -0
- package/templates/workflows/cpp-lint.yml +47 -0
- package/templates/workflows/cpp-publish.yml +119 -0
- package/templates/workflows/cpp-test.yml +77 -0
- package/templates/workflows/dotnet-lint.yml +29 -0
- package/templates/workflows/dotnet-publish.yml +40 -0
- package/templates/workflows/dotnet-test.yml +41 -0
- package/templates/workflows/elixir-lint.yml +45 -0
- package/templates/workflows/elixir-publish.yml +49 -0
- package/templates/workflows/elixir-test.yml +54 -0
- package/templates/workflows/erlang-lint.yml +47 -0
- package/templates/workflows/erlang-test.yml +62 -0
- package/templates/workflows/go-lint.yml +39 -0
- package/templates/workflows/go-publish.yml +95 -0
- package/templates/workflows/go-test.yml +59 -0
- package/templates/workflows/java-lint.yml +60 -0
- package/templates/workflows/java-publish.yml +120 -0
- package/templates/workflows/java-test.yml +85 -0
- package/templates/workflows/kotlin-lint.yml +34 -0
- package/templates/workflows/kotlin-publish.yml +56 -0
- package/templates/workflows/kotlin-test.yml +48 -0
- package/templates/workflows/php-lint.yml +39 -0
- package/templates/workflows/php-publish.yml +50 -0
- package/templates/workflows/php-test.yml +54 -0
- package/templates/workflows/python-lint.yml +47 -0
- package/templates/workflows/python-publish.yml +91 -0
- package/templates/workflows/python-test.yml +59 -0
- package/templates/workflows/rust-lint.yml +54 -0
- package/templates/workflows/rust-publish.yml +66 -0
- package/templates/workflows/rust-test.yml +75 -0
- package/templates/workflows/solidity-lint.yml +41 -0
- package/templates/workflows/solidity-test.yml +47 -0
- package/templates/workflows/swift-lint.yml +32 -0
- package/templates/workflows/swift-publish.yml +58 -0
- package/templates/workflows/swift-test.yml +44 -0
- package/templates/workflows/typescript-lint.yml +61 -0
- package/templates/workflows/typescript-publish.yml +60 -0
- package/templates/workflows/typescript-test.yml +73 -0
- package/templates/workflows/zig-lint.yml +27 -0
- package/templates/workflows/zig-test.yml +40 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
<!-- ELIXIR:START -->
|
|
2
|
+
# Elixir Project Rules
|
|
3
|
+
|
|
4
|
+
## Agent Automation Commands
|
|
5
|
+
|
|
6
|
+
**CRITICAL**: Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
# Complete quality check sequence:
|
|
10
|
+
mix format --check-formatted # Format check
|
|
11
|
+
mix credo --strict # Linting
|
|
12
|
+
mix dialyzer # Type checking
|
|
13
|
+
mix test # All tests (100% pass)
|
|
14
|
+
mix test --cover # Coverage (95%+ required)
|
|
15
|
+
mix compile --warnings-as-errors # Build
|
|
16
|
+
|
|
17
|
+
# Security audit:
|
|
18
|
+
mix hex.audit # Vulnerability scan
|
|
19
|
+
mix hex.outdated # Check outdated deps
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Elixir Configuration
|
|
23
|
+
|
|
24
|
+
**CRITICAL**: Use Elixir 1.16+ with OTP 26+.
|
|
25
|
+
|
|
26
|
+
- **Version**: Elixir 1.16+
|
|
27
|
+
- **OTP**: 26+
|
|
28
|
+
- **Formatter**: Built-in `mix format`
|
|
29
|
+
- **Linter**: Credo
|
|
30
|
+
- **Type Checker**: Dialyzer
|
|
31
|
+
|
|
32
|
+
### mix.exs Requirements
|
|
33
|
+
|
|
34
|
+
```elixir
|
|
35
|
+
defmodule YourProject.MixProject do
|
|
36
|
+
use Mix.Project
|
|
37
|
+
|
|
38
|
+
def project do
|
|
39
|
+
[
|
|
40
|
+
app: :your_project,
|
|
41
|
+
version: "1.0.0",
|
|
42
|
+
elixir: "~> 1.16",
|
|
43
|
+
start_permanent: Mix.env() == :prod,
|
|
44
|
+
deps: deps(),
|
|
45
|
+
|
|
46
|
+
# Documentation
|
|
47
|
+
name: "Your Project",
|
|
48
|
+
source_url: "https://github.com/your-org/your-project",
|
|
49
|
+
docs: [
|
|
50
|
+
main: "readme",
|
|
51
|
+
extras: ["README.md", "CHANGELOG.md"]
|
|
52
|
+
],
|
|
53
|
+
|
|
54
|
+
# Testing
|
|
55
|
+
test_coverage: [tool: ExCoveralls],
|
|
56
|
+
preferred_cli_env: [
|
|
57
|
+
coveralls: :test,
|
|
58
|
+
"coveralls.detail": :test,
|
|
59
|
+
"coveralls.post": :test,
|
|
60
|
+
"coveralls.html": :test
|
|
61
|
+
],
|
|
62
|
+
|
|
63
|
+
# Dialyzer
|
|
64
|
+
dialyzer: [
|
|
65
|
+
plt_add_apps: [:mix, :ex_unit],
|
|
66
|
+
plt_file: {:no_warn, "priv/plts/dialyzer.plt"},
|
|
67
|
+
flags: [:error_handling, :underspecs]
|
|
68
|
+
]
|
|
69
|
+
]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def application do
|
|
73
|
+
[
|
|
74
|
+
extra_applications: [:logger],
|
|
75
|
+
mod: {YourProject.Application, []}
|
|
76
|
+
]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
defp deps do
|
|
80
|
+
[
|
|
81
|
+
# Development & Testing
|
|
82
|
+
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
|
|
83
|
+
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
|
|
84
|
+
{:excoveralls, "~> 0.18", only: :test},
|
|
85
|
+
{:ex_doc, "~> 0.31", only: :dev, runtime: false}
|
|
86
|
+
]
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Code Quality Standards
|
|
92
|
+
|
|
93
|
+
### Mandatory Quality Checks
|
|
94
|
+
|
|
95
|
+
**CRITICAL**: After implementing ANY feature, you MUST run these commands in order.
|
|
96
|
+
|
|
97
|
+
**IMPORTANT**: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures!
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Pre-Commit Checklist (MUST match .github/workflows/*.yml)
|
|
101
|
+
|
|
102
|
+
# 1. Format check (matches workflow - use --check-formatted!)
|
|
103
|
+
mix format --check-formatted
|
|
104
|
+
|
|
105
|
+
# 2. Lint (MUST pass with no warnings - matches workflow)
|
|
106
|
+
mix credo --strict
|
|
107
|
+
|
|
108
|
+
# 3. Type check with Dialyzer (matches workflow)
|
|
109
|
+
mix dialyzer
|
|
110
|
+
|
|
111
|
+
# 4. Run all tests (MUST pass 100% - matches workflow)
|
|
112
|
+
mix test --cover
|
|
113
|
+
|
|
114
|
+
# 5. Check coverage (MUST meet threshold)
|
|
115
|
+
mix test --cover --export-coverage default
|
|
116
|
+
mix test.coverage
|
|
117
|
+
|
|
118
|
+
# If ANY fails: ❌ DO NOT COMMIT - Fix first!
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**If ANY of these fail, you MUST fix the issues before committing.**
|
|
122
|
+
|
|
123
|
+
**Why This Matters:**
|
|
124
|
+
- CI/CD failures happen when local commands differ from workflows
|
|
125
|
+
- Example: Using `mix format` locally but `mix format --check-formatted` in CI = failure
|
|
126
|
+
- Example: Missing `--cover` flag = CI coverage failures
|
|
127
|
+
|
|
128
|
+
### Formatting
|
|
129
|
+
|
|
130
|
+
- Use built-in `mix format`
|
|
131
|
+
- Configuration in `.formatter.exs`
|
|
132
|
+
- Format before committing: `mix format`
|
|
133
|
+
|
|
134
|
+
Example `.formatter.exs`:
|
|
135
|
+
```elixir
|
|
136
|
+
[
|
|
137
|
+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
|
|
138
|
+
line_length: 100
|
|
139
|
+
]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Linting
|
|
143
|
+
|
|
144
|
+
- Use Credo for code analysis
|
|
145
|
+
- Configuration in `.credo.exs`
|
|
146
|
+
- Must pass strict mode: `mix credo --strict`
|
|
147
|
+
|
|
148
|
+
Example `.credo.exs`:
|
|
149
|
+
```elixir
|
|
150
|
+
%{
|
|
151
|
+
configs: [
|
|
152
|
+
%{
|
|
153
|
+
name: "default",
|
|
154
|
+
files: %{
|
|
155
|
+
included: ["lib/", "test/"],
|
|
156
|
+
excluded: [~r"/_build/", ~r"/deps/"]
|
|
157
|
+
},
|
|
158
|
+
strict: true,
|
|
159
|
+
color: true,
|
|
160
|
+
checks: %{
|
|
161
|
+
enabled: [
|
|
162
|
+
{Credo.Check.Readability.ModuleDoc, []},
|
|
163
|
+
{Credo.Check.Design.AliasUsage, priority: :low}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Testing
|
|
172
|
+
|
|
173
|
+
- **Framework**: ExUnit (built-in)
|
|
174
|
+
- **Location**: `test/` directory
|
|
175
|
+
- **Coverage**: ExCoveralls
|
|
176
|
+
- **Coverage Threshold**: 95%+
|
|
177
|
+
|
|
178
|
+
Example test structure:
|
|
179
|
+
```elixir
|
|
180
|
+
defmodule YourProject.MyModuleTest do
|
|
181
|
+
use ExUnit.Case, async: true
|
|
182
|
+
|
|
183
|
+
doctest YourProject.MyModule
|
|
184
|
+
|
|
185
|
+
describe "function_name/1" do
|
|
186
|
+
test "handles valid input" do
|
|
187
|
+
assert YourProject.MyModule.function_name("input") == {:ok, "result"}
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
test "returns error for invalid input" do
|
|
191
|
+
assert YourProject.MyModule.function_name("") == {:error, :invalid_input}
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Type Specifications
|
|
198
|
+
|
|
199
|
+
- Use `@spec` for all public functions
|
|
200
|
+
- Use `@type` for custom types
|
|
201
|
+
- Run Dialyzer regularly
|
|
202
|
+
|
|
203
|
+
Example:
|
|
204
|
+
```elixir
|
|
205
|
+
defmodule YourProject.MyModule do
|
|
206
|
+
@moduledoc """
|
|
207
|
+
Documentation for MyModule.
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
@type result :: {:ok, String.t()} | {:error, atom()}
|
|
211
|
+
|
|
212
|
+
@spec process(String.t()) :: result()
|
|
213
|
+
def process(input) when is_binary(input) and input != "" do
|
|
214
|
+
{:ok, String.upcase(input)}
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def process(_), do: {:error, :invalid_input}
|
|
218
|
+
end
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Documentation
|
|
222
|
+
|
|
223
|
+
- Use `@moduledoc` for module documentation
|
|
224
|
+
- Use `@doc` for function documentation
|
|
225
|
+
- Include examples with doctests
|
|
226
|
+
- Generate docs with `mix docs`
|
|
227
|
+
|
|
228
|
+
Example:
|
|
229
|
+
```elixir
|
|
230
|
+
defmodule YourProject.MyModule do
|
|
231
|
+
@moduledoc """
|
|
232
|
+
Provides functionality for processing data.
|
|
233
|
+
|
|
234
|
+
## Examples
|
|
235
|
+
|
|
236
|
+
iex> YourProject.MyModule.process("hello")
|
|
237
|
+
{:ok, "HELLO"}
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
@doc """
|
|
241
|
+
Processes the input string.
|
|
242
|
+
|
|
243
|
+
Returns `{:ok, result}` on success or `{:error, reason}` on failure.
|
|
244
|
+
|
|
245
|
+
## Examples
|
|
246
|
+
|
|
247
|
+
iex> YourProject.MyModule.process("test")
|
|
248
|
+
{:ok, "TEST"}
|
|
249
|
+
|
|
250
|
+
iex> YourProject.MyModule.process("")
|
|
251
|
+
{:error, :invalid_input}
|
|
252
|
+
"""
|
|
253
|
+
@spec process(String.t()) :: {:ok, String.t()} | {:error, atom()}
|
|
254
|
+
def process(input) when is_binary(input) and input != "" do
|
|
255
|
+
{:ok, String.upcase(input)}
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def process(_), do: {:error, :invalid_input}
|
|
259
|
+
end
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Project Structure
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
project/
|
|
266
|
+
├── mix.exs # Project configuration
|
|
267
|
+
├── .formatter.exs # Formatter configuration
|
|
268
|
+
├── .credo.exs # Credo configuration
|
|
269
|
+
├── README.md # Project overview (allowed in root)
|
|
270
|
+
├── CHANGELOG.md # Version history (allowed in root)
|
|
271
|
+
├── LICENSE # Project license (allowed in root)
|
|
272
|
+
├── lib/
|
|
273
|
+
│ ├── your_project.ex # Main module
|
|
274
|
+
│ └── your_project/
|
|
275
|
+
│ ├── application.ex # OTP application
|
|
276
|
+
│ └── ...
|
|
277
|
+
├── test/
|
|
278
|
+
│ ├── test_helper.exs # Test configuration
|
|
279
|
+
│ └── your_project/
|
|
280
|
+
│ └── ...
|
|
281
|
+
├── config/
|
|
282
|
+
│ ├── config.exs # General config
|
|
283
|
+
│ ├── dev.exs # Development config
|
|
284
|
+
│ ├── test.exs # Test config
|
|
285
|
+
│ └── prod.exs # Production config
|
|
286
|
+
├── priv/ # Private assets
|
|
287
|
+
└── docs/ # Project documentation
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Error Handling
|
|
291
|
+
|
|
292
|
+
- Use tagged tuples: `{:ok, value}` and `{:error, reason}`
|
|
293
|
+
- Use `with` for multiple operations
|
|
294
|
+
- Create custom error modules when needed
|
|
295
|
+
|
|
296
|
+
Example:
|
|
297
|
+
```elixir
|
|
298
|
+
defmodule YourProject.Errors do
|
|
299
|
+
defmodule ValidationError do
|
|
300
|
+
defexception [:message, :field]
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
defmodule YourProject.MyModule do
|
|
305
|
+
alias YourProject.Errors.ValidationError
|
|
306
|
+
|
|
307
|
+
def validate(data) do
|
|
308
|
+
with {:ok, cleaned} <- clean_data(data),
|
|
309
|
+
{:ok, validated} <- check_format(cleaned) do
|
|
310
|
+
{:ok, validated}
|
|
311
|
+
else
|
|
312
|
+
{:error, :empty} ->
|
|
313
|
+
raise ValidationError, message: "Data cannot be empty", field: :data
|
|
314
|
+
|
|
315
|
+
{:error, reason} ->
|
|
316
|
+
{:error, reason}
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## OTP Best Practices
|
|
323
|
+
|
|
324
|
+
- Use Supervisors for fault tolerance
|
|
325
|
+
- Implement GenServers for stateful processes
|
|
326
|
+
- Use Task for concurrent operations
|
|
327
|
+
|
|
328
|
+
Example Supervisor:
|
|
329
|
+
```elixir
|
|
330
|
+
defmodule YourProject.Application do
|
|
331
|
+
use Application
|
|
332
|
+
|
|
333
|
+
@impl true
|
|
334
|
+
def start(_type, _args) do
|
|
335
|
+
children = [
|
|
336
|
+
{YourProject.MyWorker, []},
|
|
337
|
+
{Task.Supervisor, name: YourProject.TaskSupervisor}
|
|
338
|
+
]
|
|
339
|
+
|
|
340
|
+
opts = [strategy: :one_for_one, name: YourProject.Supervisor]
|
|
341
|
+
Supervisor.start_link(children, opts)
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## CI/CD Requirements
|
|
347
|
+
|
|
348
|
+
Must include GitHub Actions workflows for:
|
|
349
|
+
|
|
350
|
+
1. **Testing** (`elixir-test.yml`):
|
|
351
|
+
- Test on ubuntu-latest
|
|
352
|
+
- Test on Elixir 1.16, 1.17
|
|
353
|
+
- Test on OTP 26, 27
|
|
354
|
+
- Upload coverage reports
|
|
355
|
+
|
|
356
|
+
2. **Linting** (`elixir-lint.yml`):
|
|
357
|
+
- Format check: `mix format --check-formatted`
|
|
358
|
+
- Credo: `mix credo --strict`
|
|
359
|
+
- Dialyzer: `mix dialyzer`
|
|
360
|
+
|
|
361
|
+
## Package Publication
|
|
362
|
+
|
|
363
|
+
### Publishing to Hex.pm
|
|
364
|
+
|
|
365
|
+
**Prerequisites:**
|
|
366
|
+
1. Create account at https://hex.pm
|
|
367
|
+
2. Generate API key: `mix hex.user auth`
|
|
368
|
+
3. Add `HEX_API_KEY` to GitHub repository secrets
|
|
369
|
+
|
|
370
|
+
**mix.exs Configuration:**
|
|
371
|
+
|
|
372
|
+
```elixir
|
|
373
|
+
def project do
|
|
374
|
+
[
|
|
375
|
+
app: :your_package,
|
|
376
|
+
version: "1.0.0",
|
|
377
|
+
elixir: "~> 1.16",
|
|
378
|
+
description: "A short description of your package",
|
|
379
|
+
package: package(),
|
|
380
|
+
docs: docs()
|
|
381
|
+
]
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
defp package do
|
|
385
|
+
[
|
|
386
|
+
name: :your_package,
|
|
387
|
+
files: ~w(lib .formatter.exs mix.exs README.md LICENSE CHANGELOG.md),
|
|
388
|
+
licenses: ["MIT"],
|
|
389
|
+
links: %{
|
|
390
|
+
"GitHub" => "https://github.com/your-org/your-package",
|
|
391
|
+
"Changelog" => "https://github.com/your-org/your-package/blob/main/CHANGELOG.md"
|
|
392
|
+
},
|
|
393
|
+
maintainers: ["Your Name"]
|
|
394
|
+
]
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
defp docs do
|
|
398
|
+
[
|
|
399
|
+
main: "readme",
|
|
400
|
+
extras: ["README.md", "CHANGELOG.md"],
|
|
401
|
+
source_url: "https://github.com/your-org/your-package"
|
|
402
|
+
]
|
|
403
|
+
end
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Publishing Workflow:**
|
|
407
|
+
|
|
408
|
+
1. Update version in mix.exs
|
|
409
|
+
2. Update CHANGELOG.md
|
|
410
|
+
3. Run quality checks:
|
|
411
|
+
```bash
|
|
412
|
+
mix format
|
|
413
|
+
mix credo --strict
|
|
414
|
+
mix dialyzer
|
|
415
|
+
mix test
|
|
416
|
+
mix coveralls
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
4. Build docs: `mix docs`
|
|
420
|
+
5. Build package: `mix hex.build`
|
|
421
|
+
6. Create git tag: `git tag v1.0.0 && git push --tags`
|
|
422
|
+
7. GitHub Actions automatically publishes to Hex
|
|
423
|
+
8. Or manual publish: `mix hex.publish`
|
|
424
|
+
|
|
425
|
+
**Publishing Checklist:**
|
|
426
|
+
|
|
427
|
+
- ✅ All tests passing (`mix test`)
|
|
428
|
+
- ✅ Coverage meets threshold (`mix coveralls`)
|
|
429
|
+
- ✅ Credo passes strict mode (`mix credo --strict`)
|
|
430
|
+
- ✅ Dialyzer passes (`mix dialyzer`)
|
|
431
|
+
- ✅ Code formatted (`mix format --check-formatted`)
|
|
432
|
+
- ✅ Version updated in mix.exs
|
|
433
|
+
- ✅ CHANGELOG.md updated
|
|
434
|
+
- ✅ README.md up to date
|
|
435
|
+
- ✅ LICENSE file present
|
|
436
|
+
- ✅ Documentation builds (`mix docs`)
|
|
437
|
+
- ✅ Package metadata complete in mix.exs
|
|
438
|
+
- ✅ Verify with `mix hex.build`
|
|
439
|
+
|
|
440
|
+
**Semantic Versioning:**
|
|
441
|
+
|
|
442
|
+
Follow [SemVer](https://semver.org/):
|
|
443
|
+
- **MAJOR**: Breaking API changes
|
|
444
|
+
- **MINOR**: New features (backwards compatible)
|
|
445
|
+
- **PATCH**: Bug fixes (backwards compatible)
|
|
446
|
+
|
|
447
|
+
**Documentation:**
|
|
448
|
+
|
|
449
|
+
HexDocs automatically generates documentation from your code:
|
|
450
|
+
- Published at: `https://hexdocs.pm/your_package`
|
|
451
|
+
- Updated automatically when publishing to Hex
|
|
452
|
+
|
|
453
|
+
<!-- ELIXIR:END -->
|
|
454
|
+
|