@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,97 @@
|
|
|
1
|
+
<!-- JULIA:START -->
|
|
2
|
+
# Julia 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
|
+
julia -e 'using JuliaFormatter; format(".", overwrite=false)' # Format check
|
|
11
|
+
julia -e 'using Lint; lintpkg(".")' # Linting
|
|
12
|
+
julia --project=. -e 'using Pkg; Pkg.test()' # All tests
|
|
13
|
+
|
|
14
|
+
# Security audit:
|
|
15
|
+
julia -e 'using Pkg; Pkg.update()' # Update deps
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Julia Configuration
|
|
19
|
+
|
|
20
|
+
**CRITICAL**: Use Julia 1.9+ with JuliaFormatter and testing.
|
|
21
|
+
|
|
22
|
+
- **Version**: Julia 1.9+
|
|
23
|
+
- **Formatter**: JuliaFormatter.jl
|
|
24
|
+
- **Linter**: Lint.jl
|
|
25
|
+
- **Testing**: Test.jl (standard library)
|
|
26
|
+
- **Documentation**: Documenter.jl
|
|
27
|
+
|
|
28
|
+
### Project.toml Requirements
|
|
29
|
+
|
|
30
|
+
```toml
|
|
31
|
+
name = "YourPackage"
|
|
32
|
+
uuid = "12345678-1234-1234-1234-123456789012"
|
|
33
|
+
authors = ["Your Name <you@example.com>"]
|
|
34
|
+
version = "0.1.0"
|
|
35
|
+
|
|
36
|
+
[deps]
|
|
37
|
+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
|
38
|
+
|
|
39
|
+
[compat]
|
|
40
|
+
julia = "1.9"
|
|
41
|
+
|
|
42
|
+
[extras]
|
|
43
|
+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
|
44
|
+
|
|
45
|
+
[targets]
|
|
46
|
+
test = ["Test"]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Code Quality Standards
|
|
50
|
+
|
|
51
|
+
### Mandatory Quality Checks
|
|
52
|
+
|
|
53
|
+
**IMPORTANT**: These commands MUST match your GitHub Actions workflows!
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Pre-Commit Checklist (MUST match .github/workflows/*.yml)
|
|
57
|
+
|
|
58
|
+
# 1. Format check (matches workflow)
|
|
59
|
+
julia -e 'using JuliaFormatter; format(".", overwrite=false)'
|
|
60
|
+
|
|
61
|
+
# 2. Lint (matches workflow)
|
|
62
|
+
julia -e 'using Lint; lintpkg("YourPackage")'
|
|
63
|
+
|
|
64
|
+
# 3. Run all tests (MUST pass 100% - matches workflow)
|
|
65
|
+
julia --project=. -e 'using Pkg; Pkg.test()'
|
|
66
|
+
|
|
67
|
+
# 4. Check coverage (matches workflow)
|
|
68
|
+
julia --project=. --code-coverage=user -e 'using Pkg; Pkg.test()'
|
|
69
|
+
|
|
70
|
+
# If ANY fails: ❌ DO NOT COMMIT - Fix first!
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Why This Matters:**
|
|
74
|
+
- Example: Using `format(..., overwrite=true)` locally but `overwrite=false` in CI = failure
|
|
75
|
+
|
|
76
|
+
### Testing Example
|
|
77
|
+
|
|
78
|
+
```julia
|
|
79
|
+
using Test
|
|
80
|
+
using YourPackage
|
|
81
|
+
|
|
82
|
+
@testset "DataProcessor tests" begin
|
|
83
|
+
@testset "process function" begin
|
|
84
|
+
@test process([1, 2, 3]) == [2, 4, 6]
|
|
85
|
+
@test process([]) == []
|
|
86
|
+
@test_throws ArgumentError process(nothing)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
@testset "validate function" begin
|
|
90
|
+
@test validate("test") == true
|
|
91
|
+
@test validate("") == false
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
<!-- JULIA:END -->
|
|
97
|
+
|
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
<!-- KOTLIN:START -->
|
|
2
|
+
# Kotlin 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 (Gradle):
|
|
10
|
+
./gradlew ktlintCheck # Format check
|
|
11
|
+
./gradlew detekt # Linting
|
|
12
|
+
./gradlew test # All tests (100% pass)
|
|
13
|
+
./gradlew build # Build verification
|
|
14
|
+
./gradlew koverVerify # Coverage (95%+ required)
|
|
15
|
+
|
|
16
|
+
# Security audit:
|
|
17
|
+
./gradlew dependencyCheckAnalyze # Vulnerability scan
|
|
18
|
+
./gradlew dependencyUpdates # Check outdated deps
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Kotlin Configuration
|
|
22
|
+
|
|
23
|
+
**CRITICAL**: Use Kotlin 2.0+ with strict null safety.
|
|
24
|
+
|
|
25
|
+
- **Version**: Kotlin 2.0+
|
|
26
|
+
- **JVM Target**: 17+
|
|
27
|
+
- **Language Features**: All enabled
|
|
28
|
+
- **Compiler**: K2 compiler
|
|
29
|
+
- **Null Safety**: Strict
|
|
30
|
+
|
|
31
|
+
### build.gradle.kts Requirements
|
|
32
|
+
|
|
33
|
+
```kotlin
|
|
34
|
+
plugins {
|
|
35
|
+
kotlin("jvm") version "2.0.0"
|
|
36
|
+
id("org.jetbrains.dokka") version "1.9.20"
|
|
37
|
+
id("io.gitlab.arturbosch.detekt") version "1.23.5"
|
|
38
|
+
id("org.jlleitschuh.gradle.ktlint") version "12.1.0"
|
|
39
|
+
`maven-publish`
|
|
40
|
+
signing
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
group = "io.github.your-username"
|
|
44
|
+
version = "1.0.0"
|
|
45
|
+
|
|
46
|
+
repositories {
|
|
47
|
+
mavenCentral()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dependencies {
|
|
51
|
+
implementation(kotlin("stdlib"))
|
|
52
|
+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
|
|
53
|
+
|
|
54
|
+
testImplementation(kotlin("test"))
|
|
55
|
+
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0")
|
|
56
|
+
testImplementation("io.mockk:mockk:1.13.9")
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
kotlin {
|
|
60
|
+
jvmToolchain(17)
|
|
61
|
+
|
|
62
|
+
compilerOptions {
|
|
63
|
+
freeCompilerArgs.add("-Xjsr305=strict")
|
|
64
|
+
freeCompilerArgs.add("-Xcontext-receivers")
|
|
65
|
+
allWarningsAsErrors.set(true)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
tasks.test {
|
|
70
|
+
useJUnitPlatform()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
|
74
|
+
kotlinOptions {
|
|
75
|
+
jvmTarget = "17"
|
|
76
|
+
freeCompilerArgs = listOf(
|
|
77
|
+
"-Xjsr305=strict",
|
|
78
|
+
"-Xcontext-receivers"
|
|
79
|
+
)
|
|
80
|
+
allWarningsAsErrors = true
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
detekt {
|
|
85
|
+
config.setFrom(files("$rootDir/detekt.yml"))
|
|
86
|
+
buildUponDefaultConfig = true
|
|
87
|
+
allRules = false
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
ktlint {
|
|
91
|
+
version.set("1.1.0")
|
|
92
|
+
android.set(false)
|
|
93
|
+
ignoreFailures.set(false)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Code Quality Standards
|
|
98
|
+
|
|
99
|
+
### Mandatory Quality Checks
|
|
100
|
+
|
|
101
|
+
**CRITICAL**: After implementing ANY feature, you MUST run these commands in order.
|
|
102
|
+
|
|
103
|
+
**IMPORTANT**: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures!
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Pre-Commit Checklist (MUST match .github/workflows/*.yml)
|
|
107
|
+
|
|
108
|
+
# 1. Format check (matches workflow - use Check, not Format!)
|
|
109
|
+
./gradlew ktlintCheck
|
|
110
|
+
|
|
111
|
+
# 2. Lint (matches workflow)
|
|
112
|
+
./gradlew detekt
|
|
113
|
+
|
|
114
|
+
# 3. Build (MUST pass with no warnings - matches workflow)
|
|
115
|
+
./gradlew build -x test
|
|
116
|
+
|
|
117
|
+
# 4. Run all tests (MUST pass 100% - matches workflow)
|
|
118
|
+
./gradlew test
|
|
119
|
+
|
|
120
|
+
# 5. Check coverage (MUST meet threshold)
|
|
121
|
+
./gradlew koverVerify
|
|
122
|
+
|
|
123
|
+
# If ANY fails: ❌ DO NOT COMMIT - Fix first!
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**If ANY of these fail, you MUST fix the issues before committing.**
|
|
127
|
+
|
|
128
|
+
**Why This Matters:**
|
|
129
|
+
- CI/CD failures happen when local commands differ from workflows
|
|
130
|
+
- Example: Using `ktlintFormat` locally but `ktlintCheck` in CI = failure
|
|
131
|
+
- Example: Using `koverHtmlReport` locally but `koverVerify` in CI = coverage failures
|
|
132
|
+
|
|
133
|
+
### Code Style
|
|
134
|
+
|
|
135
|
+
Use ktlint with `.editorconfig`:
|
|
136
|
+
|
|
137
|
+
```ini
|
|
138
|
+
root = true
|
|
139
|
+
|
|
140
|
+
[*]
|
|
141
|
+
charset = utf-8
|
|
142
|
+
end_of_line = lf
|
|
143
|
+
indent_size = 4
|
|
144
|
+
indent_style = space
|
|
145
|
+
insert_final_newline = true
|
|
146
|
+
max_line_length = 120
|
|
147
|
+
tab_width = 4
|
|
148
|
+
|
|
149
|
+
[*.{kt,kts}]
|
|
150
|
+
ij_kotlin_allow_trailing_comma = true
|
|
151
|
+
ij_kotlin_allow_trailing_comma_on_call_site = true
|
|
152
|
+
|
|
153
|
+
# Imports
|
|
154
|
+
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
|
|
155
|
+
|
|
156
|
+
# Wrapping
|
|
157
|
+
ij_kotlin_line_break_after_multiline_when_entry = true
|
|
158
|
+
ij_kotlin_wrap_expression_body_functions = 1
|
|
159
|
+
ij_kotlin_wrap_first_method_in_call_chain = false
|
|
160
|
+
|
|
161
|
+
# Spacing
|
|
162
|
+
ij_kotlin_space_after_type_colon = true
|
|
163
|
+
ij_kotlin_space_before_type_colon = false
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Static Analysis
|
|
167
|
+
|
|
168
|
+
Use Detekt. Configuration in `detekt.yml`:
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
build:
|
|
172
|
+
maxIssues: 0
|
|
173
|
+
weights:
|
|
174
|
+
complexity: 2
|
|
175
|
+
LongParameterList: 1
|
|
176
|
+
style: 1
|
|
177
|
+
comments: 1
|
|
178
|
+
|
|
179
|
+
complexity:
|
|
180
|
+
active: true
|
|
181
|
+
ComplexMethod:
|
|
182
|
+
threshold: 15
|
|
183
|
+
LongMethod:
|
|
184
|
+
threshold: 60
|
|
185
|
+
LongParameterList:
|
|
186
|
+
functionThreshold: 6
|
|
187
|
+
TooManyFunctions:
|
|
188
|
+
thresholdInFiles: 15
|
|
189
|
+
|
|
190
|
+
naming:
|
|
191
|
+
active: true
|
|
192
|
+
FunctionNaming:
|
|
193
|
+
active: true
|
|
194
|
+
ClassNaming:
|
|
195
|
+
active: true
|
|
196
|
+
VariableNaming:
|
|
197
|
+
active: true
|
|
198
|
+
|
|
199
|
+
style:
|
|
200
|
+
active: true
|
|
201
|
+
MagicNumber:
|
|
202
|
+
active: true
|
|
203
|
+
ReturnCount:
|
|
204
|
+
max: 3
|
|
205
|
+
|
|
206
|
+
coroutines:
|
|
207
|
+
active: true
|
|
208
|
+
GlobalCoroutineUsage:
|
|
209
|
+
active: true
|
|
210
|
+
SuspendFunWithFlowReturnType:
|
|
211
|
+
active: true
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Testing
|
|
215
|
+
|
|
216
|
+
- **Framework**: JUnit 5 (Jupiter)
|
|
217
|
+
- **Mocking**: MockK
|
|
218
|
+
- **Coroutines**: kotlinx-coroutines-test
|
|
219
|
+
- **Coverage**: Kover
|
|
220
|
+
- **Coverage Threshold**: 95%+
|
|
221
|
+
|
|
222
|
+
Example test:
|
|
223
|
+
|
|
224
|
+
```kotlin
|
|
225
|
+
import io.mockk.*
|
|
226
|
+
import kotlinx.coroutines.test.runTest
|
|
227
|
+
import org.junit.jupiter.api.Test
|
|
228
|
+
import org.junit.jupiter.api.assertThrows
|
|
229
|
+
import kotlin.test.assertEquals
|
|
230
|
+
|
|
231
|
+
class DataProcessorTest {
|
|
232
|
+
|
|
233
|
+
@Test
|
|
234
|
+
fun `process valid input returns uppercase`() {
|
|
235
|
+
val processor = DataProcessor()
|
|
236
|
+
val result = processor.process("hello")
|
|
237
|
+
|
|
238
|
+
assertEquals("HELLO", result)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@Test
|
|
242
|
+
fun `process empty input throws exception`() {
|
|
243
|
+
val processor = DataProcessor()
|
|
244
|
+
|
|
245
|
+
assertThrows<IllegalArgumentException> {
|
|
246
|
+
processor.process("")
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
@Test
|
|
251
|
+
fun `processAsync works correctly`() = runTest {
|
|
252
|
+
val processor = DataProcessor()
|
|
253
|
+
val result = processor.processAsync("test")
|
|
254
|
+
|
|
255
|
+
assertEquals("TEST", result)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
@Test
|
|
259
|
+
fun `test with mocking`() {
|
|
260
|
+
val repository = mockk<UserRepository>()
|
|
261
|
+
every { repository.findById(1) } returns User(1, "John")
|
|
262
|
+
|
|
263
|
+
val service = UserService(repository)
|
|
264
|
+
val user = service.getUser(1)
|
|
265
|
+
|
|
266
|
+
assertEquals("John", user?.name)
|
|
267
|
+
verify { repository.findById(1) }
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Null Safety
|
|
273
|
+
|
|
274
|
+
- Use non-null types by default
|
|
275
|
+
- Use `?` for nullable types
|
|
276
|
+
- Use safe calls `?.` and Elvis operator `?:`
|
|
277
|
+
- Avoid `!!` operator (use only when absolutely necessary)
|
|
278
|
+
|
|
279
|
+
Example:
|
|
280
|
+
|
|
281
|
+
```kotlin
|
|
282
|
+
data class User(
|
|
283
|
+
val id: Int,
|
|
284
|
+
val name: String,
|
|
285
|
+
val email: String?,
|
|
286
|
+
val phone: String? = null
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
class UserService(private val repository: UserRepository) {
|
|
290
|
+
|
|
291
|
+
fun findUser(id: Int): User? {
|
|
292
|
+
return repository.findById(id)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
fun getUserName(id: Int): String {
|
|
296
|
+
val user = findUser(id) ?: throw UserNotFoundException(id)
|
|
297
|
+
return user.name
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
fun getUserEmail(id: Int): String {
|
|
301
|
+
val user = findUser(id) ?: return "unknown@example.com"
|
|
302
|
+
return user.email ?: "no-email@example.com"
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
fun processUsers(ids: List<Int>): List<String> {
|
|
306
|
+
return ids.mapNotNull { id ->
|
|
307
|
+
findUser(id)?.name
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Coroutines
|
|
314
|
+
|
|
315
|
+
- Use structured concurrency
|
|
316
|
+
- Prefer `suspend` functions over callbacks
|
|
317
|
+
- Use `Flow` for reactive streams
|
|
318
|
+
- Handle cancellation properly
|
|
319
|
+
|
|
320
|
+
Example:
|
|
321
|
+
|
|
322
|
+
```kotlin
|
|
323
|
+
import kotlinx.coroutines.*
|
|
324
|
+
import kotlinx.coroutines.flow.*
|
|
325
|
+
|
|
326
|
+
class DataService(private val api: ApiClient) {
|
|
327
|
+
|
|
328
|
+
suspend fun fetchData(id: Int): Result<Data> = withContext(Dispatchers.IO) {
|
|
329
|
+
try {
|
|
330
|
+
val data = api.getData(id)
|
|
331
|
+
Result.success(data)
|
|
332
|
+
} catch (e: Exception) {
|
|
333
|
+
Result.failure(e)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
fun observeData(id: Int): Flow<Data> = flow {
|
|
338
|
+
while (currentCoroutineContext().isActive) {
|
|
339
|
+
val data = api.getData(id)
|
|
340
|
+
emit(data)
|
|
341
|
+
delay(1000)
|
|
342
|
+
}
|
|
343
|
+
}.flowOn(Dispatchers.IO)
|
|
344
|
+
|
|
345
|
+
suspend fun fetchMultiple(ids: List<Int>): List<Data> = coroutineScope {
|
|
346
|
+
ids.map { id ->
|
|
347
|
+
async { fetchData(id).getOrNull() }
|
|
348
|
+
}.awaitAll().filterNotNull()
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Data Classes & Sealed Classes
|
|
354
|
+
|
|
355
|
+
- Use `data class` for value objects
|
|
356
|
+
- Use `sealed class`/`sealed interface` for restricted hierarchies
|
|
357
|
+
- Use `value class` for single-property wrappers
|
|
358
|
+
|
|
359
|
+
Example:
|
|
360
|
+
|
|
361
|
+
```kotlin
|
|
362
|
+
// Data class for DTOs
|
|
363
|
+
data class User(
|
|
364
|
+
val id: Int,
|
|
365
|
+
val name: String,
|
|
366
|
+
val email: String
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
// Sealed hierarchy for results
|
|
370
|
+
sealed interface Result<out T> {
|
|
371
|
+
data class Success<T>(val data: T) : Result<T>
|
|
372
|
+
data class Error(val exception: Exception) : Result<Nothing>
|
|
373
|
+
data object Loading : Result<Nothing>
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Value class for type safety
|
|
377
|
+
@JvmInline
|
|
378
|
+
value class UserId(val value: Int)
|
|
379
|
+
|
|
380
|
+
@JvmInline
|
|
381
|
+
value class Email(val value: String) {
|
|
382
|
+
init {
|
|
383
|
+
require(value.contains("@")) { "Invalid email format" }
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Documentation
|
|
389
|
+
|
|
390
|
+
- Use KDoc for documentation
|
|
391
|
+
- Document all public APIs
|
|
392
|
+
- Include examples with `@sample`
|
|
393
|
+
|
|
394
|
+
Example:
|
|
395
|
+
|
|
396
|
+
```kotlin
|
|
397
|
+
/**
|
|
398
|
+
* A processor that transforms input data.
|
|
399
|
+
*
|
|
400
|
+
* This class provides methods for processing strings synchronously and asynchronously.
|
|
401
|
+
* All processing is done in a thread-safe manner.
|
|
402
|
+
*
|
|
403
|
+
* @property config Configuration for the processor
|
|
404
|
+
* @constructor Creates a processor with the given configuration
|
|
405
|
+
*/
|
|
406
|
+
class DataProcessor(private val config: ProcessorConfig = ProcessorConfig()) {
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Processes the input string synchronously.
|
|
410
|
+
*
|
|
411
|
+
* @param input The string to process. Must not be empty.
|
|
412
|
+
* @return The processed string in uppercase.
|
|
413
|
+
* @throws IllegalArgumentException if [input] is empty.
|
|
414
|
+
* @sample samples.DataProcessorSamples.processExample
|
|
415
|
+
*/
|
|
416
|
+
fun process(input: String): String {
|
|
417
|
+
require(input.isNotEmpty()) { "Input cannot be empty" }
|
|
418
|
+
return input.uppercase()
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Processes the input string asynchronously.
|
|
423
|
+
*
|
|
424
|
+
* This is a suspending function that can be called from a coroutine.
|
|
425
|
+
*
|
|
426
|
+
* @param input The string to process.
|
|
427
|
+
* @return The processed string in uppercase.
|
|
428
|
+
*/
|
|
429
|
+
suspend fun processAsync(input: String): String = withContext(Dispatchers.Default) {
|
|
430
|
+
process(input)
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Sample code for documentation
|
|
435
|
+
object samples {
|
|
436
|
+
object DataProcessorSamples {
|
|
437
|
+
fun processExample() {
|
|
438
|
+
val processor = DataProcessor()
|
|
439
|
+
val result = processor.process("hello")
|
|
440
|
+
println(result) // Prints: HELLO
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Project Structure
|
|
447
|
+
|
|
448
|
+
```
|
|
449
|
+
project/
|
|
450
|
+
├── build.gradle.kts # Gradle build configuration
|
|
451
|
+
├── settings.gradle.kts # Gradle settings
|
|
452
|
+
├── detekt.yml # Detekt configuration
|
|
453
|
+
├── .editorconfig # EditorConfig for ktlint
|
|
454
|
+
├── README.md # Project overview (allowed in root)
|
|
455
|
+
├── CHANGELOG.md # Version history (allowed in root)
|
|
456
|
+
├── LICENSE # Project license (allowed in root)
|
|
457
|
+
├── src/
|
|
458
|
+
│ ├── main/
|
|
459
|
+
│ │ └── kotlin/
|
|
460
|
+
│ │ └── com/yourorg/yourproject/
|
|
461
|
+
│ │ └── YourClass.kt
|
|
462
|
+
│ └── test/
|
|
463
|
+
│ └── kotlin/
|
|
464
|
+
│ └── com/yourorg/yourproject/
|
|
465
|
+
│ └── YourClassTest.kt
|
|
466
|
+
└── docs/ # Project documentation
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## CI/CD Requirements
|
|
470
|
+
|
|
471
|
+
Must include GitHub Actions workflows for:
|
|
472
|
+
|
|
473
|
+
1. **Testing** (`kotlin-test.yml`):
|
|
474
|
+
- Test on ubuntu-latest, windows-latest
|
|
475
|
+
- Test on Java 17, 21
|
|
476
|
+
- Upload coverage reports
|
|
477
|
+
|
|
478
|
+
2. **Linting** (`kotlin-lint.yml`):
|
|
479
|
+
- Detekt: `./gradlew detekt`
|
|
480
|
+
- ktlint: `./gradlew ktlintCheck`
|
|
481
|
+
- Build with warnings as errors
|
|
482
|
+
|
|
483
|
+
## Package Publication
|
|
484
|
+
|
|
485
|
+
### Publishing to Maven Central
|
|
486
|
+
|
|
487
|
+
Same process as Java (see JAVA.md), but with Kotlin-specific configuration.
|
|
488
|
+
|
|
489
|
+
**Publishing Checklist:**
|
|
490
|
+
|
|
491
|
+
- ✅ All tests passing
|
|
492
|
+
- ✅ Detekt passes
|
|
493
|
+
- ✅ ktlint passes
|
|
494
|
+
- ✅ Build succeeds with warnings as errors
|
|
495
|
+
- ✅ Version updated in build.gradle.kts
|
|
496
|
+
- ✅ CHANGELOG.md updated
|
|
497
|
+
- ✅ README.md up to date
|
|
498
|
+
- ✅ LICENSE file present
|
|
499
|
+
- ✅ Dokka documentation generated
|
|
500
|
+
- ✅ Artifacts signed with GPG
|
|
501
|
+
|
|
502
|
+
**Dokka Documentation:**
|
|
503
|
+
|
|
504
|
+
```kotlin
|
|
505
|
+
tasks.dokkaHtml.configure {
|
|
506
|
+
outputDirectory.set(buildDir.resolve("dokka"))
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
<!-- KOTLIN:END -->
|
|
511
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<!-- LISP:START -->
|
|
2
|
+
# Common Lisp 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
|
+
sbcl --eval '(ql:quickload :sblint)' --eval '(sblint:run-lint "src/")' # Linting
|
|
11
|
+
sbcl --load tests/run-tests.lisp # All tests
|
|
12
|
+
sbcl --eval '(asdf:make :your-system)' # Build with ASDF
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Common Lisp Configuration
|
|
16
|
+
|
|
17
|
+
**CRITICAL**: Use SBCL 2.3+ or CCL with ASDF3 and modern tooling.
|
|
18
|
+
|
|
19
|
+
- **Implementation**: SBCL 2.3+ (recommended) or CCL
|
|
20
|
+
- **Build System**: ASDF3
|
|
21
|
+
- **Testing**: FiveAM or Prove
|
|
22
|
+
- **Linter**: sblint
|
|
23
|
+
|
|
24
|
+
### System Definition (your-system.asd)
|
|
25
|
+
|
|
26
|
+
```lisp
|
|
27
|
+
(defsystem "your-system"
|
|
28
|
+
:description "Your system description"
|
|
29
|
+
:version "0.1.0"
|
|
30
|
+
:author "Your Name <you@example.com>"
|
|
31
|
+
:license "MIT"
|
|
32
|
+
:depends-on (:alexandria
|
|
33
|
+
:cl-ppcre
|
|
34
|
+
:str)
|
|
35
|
+
:components ((:module "src"
|
|
36
|
+
:components
|
|
37
|
+
((:file "package")
|
|
38
|
+
(:file "main" :depends-on ("package")))))
|
|
39
|
+
:in-order-to ((test-op (test-op "your-system/tests"))))
|
|
40
|
+
|
|
41
|
+
(defsystem "your-system/tests"
|
|
42
|
+
:depends-on ("your-system"
|
|
43
|
+
"fiveam")
|
|
44
|
+
:components ((:module "tests"
|
|
45
|
+
:components
|
|
46
|
+
((:file "package")
|
|
47
|
+
(:file "main-tests" :depends-on ("package")))))
|
|
48
|
+
:perform (test-op (o c) (symbol-call :fiveam :run! :your-system-tests)))
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Code Quality Standards
|
|
52
|
+
|
|
53
|
+
### Mandatory Quality Checks
|
|
54
|
+
|
|
55
|
+
**IMPORTANT**: These commands MUST match your GitHub Actions workflows!
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Pre-Commit Checklist (MUST match .github/workflows/*.yml)
|
|
59
|
+
|
|
60
|
+
# 1. Lint (matches workflow)
|
|
61
|
+
sblint your-system.asd
|
|
62
|
+
|
|
63
|
+
# 2. Load system (check for errors - matches workflow)
|
|
64
|
+
sbcl --non-interactive --load your-system.asd \
|
|
65
|
+
--eval '(ql:quickload :your-system)' \
|
|
66
|
+
--eval '(quit)'
|
|
67
|
+
|
|
68
|
+
# 3. Run tests (matches workflow)
|
|
69
|
+
sbcl --non-interactive \
|
|
70
|
+
--eval '(ql:quickload :your-system/tests)' \
|
|
71
|
+
--eval '(asdf:test-system :your-system)' \
|
|
72
|
+
--eval '(quit)'
|
|
73
|
+
|
|
74
|
+
# If ANY fails: ❌ DO NOT COMMIT - Fix first!
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Testing Example (FiveAM)
|
|
78
|
+
|
|
79
|
+
```lisp
|
|
80
|
+
(in-package :your-system/tests)
|
|
81
|
+
|
|
82
|
+
(def-suite your-system-tests
|
|
83
|
+
:description "Main test suite")
|
|
84
|
+
|
|
85
|
+
(in-suite your-system-tests)
|
|
86
|
+
|
|
87
|
+
(test process-data-test
|
|
88
|
+
"Test data processing"
|
|
89
|
+
(is (equal '(2 4 6) (process-data '(1 2 3))))
|
|
90
|
+
(is (null (process-data '())))
|
|
91
|
+
(signals error (process-data nil)))
|
|
92
|
+
|
|
93
|
+
(test validate-input-test
|
|
94
|
+
"Test input validation"
|
|
95
|
+
(is-true (validate-input "test"))
|
|
96
|
+
(is-false (validate-input "")))
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
<!-- LISP:END -->
|
|
100
|
+
|