@mrciphersmith/keryx 0.2.9
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 +21 -0
- package/README.md +351 -0
- package/dist/cli.js +48427 -0
- package/dist/proxy-worker.js +381 -0
- package/package.json +63 -0
- package/src/gdgraph/affected.test.ts +100 -0
- package/src/gdgraph/affected.ts +135 -0
- package/src/gdgraph/build-integrity.test.ts +193 -0
- package/src/gdgraph/build-lang.test.ts +399 -0
- package/src/gdgraph/build.test.ts +120 -0
- package/src/gdgraph/build.ts +804 -0
- package/src/gdgraph/config.test.ts +47 -0
- package/src/gdgraph/config.ts +113 -0
- package/src/gdgraph/core-sources.test.ts +99 -0
- package/src/gdgraph/core-sources.ts +20 -0
- package/src/gdgraph/enrich.ts +79 -0
- package/src/gdgraph/fallback.test.ts +153 -0
- package/src/gdgraph/find.test.ts +78 -0
- package/src/gdgraph/find.ts +107 -0
- package/src/gdgraph/pagerank.ts +129 -0
- package/src/gdgraph/path.test.ts +56 -0
- package/src/gdgraph/path.ts +112 -0
- package/src/gdgraph/query.ts +133 -0
- package/src/gdgraph/repomap.test.ts +110 -0
- package/src/gdgraph/repomap.ts +193 -0
- package/src/gdgraph/service.test.ts +59 -0
- package/src/gdgraph/service.ts +51 -0
- package/src/gdgraph/staleness.ts +20 -0
- package/src/gdgraph/symbol.test.ts +89 -0
- package/src/gdgraph/symbol.ts +123 -0
- package/src/gdgraph/symbols-capability.test.ts +41 -0
- package/src/gdgraph/symbols-capability.ts +49 -0
- package/src/gdgraph/target.ts +56 -0
- package/src/gdgraph/treesitter/adapter.test.ts +249 -0
- package/src/gdgraph/treesitter/adapter.ts +213 -0
- package/src/gdgraph/treesitter/extract.test.ts +278 -0
- package/src/gdgraph/treesitter/extract.ts +389 -0
- package/src/gdgraph/treesitter/grammars.ts +110 -0
- package/src/gdgraph/treesitter/no-treesitter-import.test.ts +51 -0
- package/src/gdgraph/treesitter/resolve-calls.test.ts +38 -0
- package/src/gdgraph/types.ts +63 -0
- package/src/gdskills/bundled/rules/core/api-contracts.mdc +148 -0
- package/src/gdskills/bundled/rules/core/async-patterns.mdc +185 -0
- package/src/gdskills/bundled/rules/core/clean-architecture.mdc +163 -0
- package/src/gdskills/bundled/rules/core/code-review-ai-assistant.mdc +49 -0
- package/src/gdskills/bundled/rules/core/code-review-b091-profile.mdc +48 -0
- package/src/gdskills/bundled/rules/core/code-style-patterns.mdc +54 -0
- package/src/gdskills/bundled/rules/core/commit-message-formatting.mdc +25 -0
- package/src/gdskills/bundled/rules/core/database-patterns.mdc +162 -0
- package/src/gdskills/bundled/rules/core/documentation-management.mdc +106 -0
- package/src/gdskills/bundled/rules/core/error-handling.mdc +163 -0
- package/src/gdskills/bundled/rules/core/execution-metrics.md +99 -0
- package/src/gdskills/bundled/rules/core/frontend-assistant.mdc +40 -0
- package/src/gdskills/bundled/rules/core/git-rules.mdc +37 -0
- package/src/gdskills/bundled/rules/core/gproject-contracts.mdc +198 -0
- package/src/gdskills/bundled/rules/core/implementation-doc-mandate.mdc +149 -0
- package/src/gdskills/bundled/rules/core/implementation-plans.mdc +58 -0
- package/src/gdskills/bundled/rules/core/jobs-documentation.mdc +221 -0
- package/src/gdskills/bundled/rules/core/mobx-store-template.mdc +561 -0
- package/src/gdskills/bundled/rules/core/model-selection.mdc +53 -0
- package/src/gdskills/bundled/rules/core/nestjs-dto.mdc +50 -0
- package/src/gdskills/bundled/rules/core/playwright-testing.mdc +321 -0
- package/src/gdskills/bundled/rules/core/requirements-management.mdc +35 -0
- package/src/gdskills/bundled/rules/core/requirements-package-standard.mdc +103 -0
- package/src/gdskills/bundled/rules/core/review-agent-profile.mdc +49 -0
- package/src/gdskills/bundled/rules/core/review-strict-profile.mdc +44 -0
- package/src/gdskills/bundled/rules/core/rule-management-workflow.mdc +62 -0
- package/src/gdskills/bundled/rules/core/security-baseline.mdc +155 -0
- package/src/gdskills/bundled/rules/core/shared-definitions.mdc +79 -0
- package/src/gdskills/bundled/rules/core/skill-lifecycle.mdc +55 -0
- package/src/gdskills/bundled/rules/core/skills-storage-workflow.mdc +88 -0
- package/src/gdskills/bundled/rules/core/solid-principles.mdc +149 -0
- package/src/gdskills/bundled/rules/core/storybook-guidelines.mdc +36 -0
- package/src/gdskills/bundled/rules/core/subagent-context-construction.md +107 -0
- package/src/gdskills/bundled/rules/core/subagent-status-protocol.md +169 -0
- package/src/gdskills/bundled/rules/core/tdd-workflow.mdc +96 -0
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.codex.md +47 -0
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.cursor.md +55 -0
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.md +352 -0
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.opencode.md +39 -0
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.zed.md +29 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.codex.md +567 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.cursor.md +567 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.md +655 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.opencode.md +567 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.zed.md +567 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/input-contract.schema.json +134 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/orchestrator-prompt.md +183 -0
- package/src/gdskills/bundled/skills/orchestration/context-collector/output-contract.schema.json +208 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.codex.md +1412 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.cursor.md +1412 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.detail.md +735 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.md +468 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.opencode.md +1412 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.zed.md +1412 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/analysis-request.md +62 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/analysis-request.template.md +79 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/input-contract.schema.json +247 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/orchestrator-prompt.md +362 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/output-contract.schema.json +87 -0
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.codex.md +105 -0
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.cursor.md +105 -0
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.md +165 -0
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +379 -0
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/input-contract.schema.json +33 -0
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/output-contract.schema.json +41 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.codex.md +307 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.cursor.md +307 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.md +373 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.opencode.md +307 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.zed.md +307 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/input-contract.schema.json +130 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/issue-request.template.md +50 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/orchestrator-prompt.md +155 -0
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/output-contract.schema.json +61 -0
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.codex.md +365 -0
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.cursor.md +365 -0
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.md +373 -0
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.opencode.md +365 -0
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.zed.md +365 -0
- package/src/gdskills/bundled/skills/orchestration/job-documenter/input-contract.schema.json +55 -0
- package/src/gdskills/bundled/skills/orchestration/job-documenter/output-contract.schema.json +58 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.codex.md +1701 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.cursor.md +1701 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +1734 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.opencode.md +1701 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.zed.md +1701 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/input-contract.schema.json +188 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/orchestrator-prompt.md +179 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/output-contract.schema.json +103 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/state.schema.json +164 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.codex.md +395 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.cursor.md +395 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.md +556 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.opencode.md +395 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.zed.md +395 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/input-contract.schema.json +204 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/orchestrator-prompt.md +206 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/output-contract.schema.json +51 -0
- package/src/gdskills/bundled/skills/orchestration/task-implementer/task-request.template.md +111 -0
- package/src/gdskills/bundled/skills/planning/autodoc-analyst/SKILL.md +163 -0
- package/src/gdskills/bundled/skills/planning/autodoc-architect/SKILL.md +161 -0
- package/src/gdskills/bundled/skills/planning/autodoc-assembler/SKILL.md +128 -0
- package/src/gdskills/bundled/skills/planning/autodoc-orchestrator/SKILL.md +321 -0
- package/src/gdskills/bundled/skills/planning/autodoc-scanner/SKILL.md +166 -0
- package/src/gdskills/bundled/skills/planning/autodoc-writer/SKILL.md +253 -0
- package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.claude.md +46 -0
- package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.codex.md +90 -0
- package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.cursor.md +90 -0
- package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.md +90 -0
- package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.codex.md +33 -0
- package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.cursor.md +33 -0
- package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.md +190 -0
- package/src/gdskills/bundled/skills/planning/docpack-orchestrator/SKILL.md +142 -0
- package/src/gdskills/bundled/skills/planning/docpack-orchestrator/input-contract.schema.json +31 -0
- package/src/gdskills/bundled/skills/planning/docpack-orchestrator/output-contract.schema.json +31 -0
- package/src/gdskills/bundled/skills/planning/docpack-review/SKILL.md +80 -0
- package/src/gdskills/bundled/skills/planning/docpack-review/input-contract.schema.json +20 -0
- package/src/gdskills/bundled/skills/planning/docpack-review/output-contract.schema.json +36 -0
- package/src/gdskills/bundled/skills/planning/interview/SKILL.codex.md +181 -0
- package/src/gdskills/bundled/skills/planning/interview/SKILL.cursor.md +181 -0
- package/src/gdskills/bundled/skills/planning/interview/SKILL.md +187 -0
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.claude.md +94 -0
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.codex.md +99 -0
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.cursor.md +99 -0
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.md +105 -0
- package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.codex.md +33 -0
- package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.cursor.md +33 -0
- package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.md +237 -0
- package/src/gdskills/bundled/skills/planning/planner/SKILL.codex.md +33 -0
- package/src/gdskills/bundled/skills/planning/planner/SKILL.cursor.md +33 -0
- package/src/gdskills/bundled/skills/planning/planner/SKILL.md +190 -0
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.codex.md +193 -0
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.cursor.md +193 -0
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.md +193 -0
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.opencode.md +193 -0
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.zed.md +193 -0
- package/src/gdskills/bundled/skills/planning/prd-creator/input-contract.schema.json +63 -0
- package/src/gdskills/bundled/skills/planning/prd-creator/output-contract.schema.json +175 -0
- package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.codex.md +31 -0
- package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.cursor.md +31 -0
- package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.md +153 -0
- package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.codex.md +32 -0
- package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.cursor.md +32 -0
- package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.md +166 -0
- package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.codex.md +44 -0
- package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.cursor.md +44 -0
- package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.md +243 -0
- package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.codex.md +43 -0
- package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.cursor.md +43 -0
- package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.md +193 -0
- package/src/gdskills/bundled/skills/platform/agent-entrypoint-distiller/SKILL.md +47 -0
- package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.codex.md +87 -0
- package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.cursor.md +87 -0
- package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.md +87 -0
- package/src/gdskills/bundled/skills/platform/hookify/SKILL.codex.md +100 -0
- package/src/gdskills/bundled/skills/platform/hookify/SKILL.cursor.md +100 -0
- package/src/gdskills/bundled/skills/platform/hookify/SKILL.md +100 -0
- package/src/gdskills/bundled/skills/quality/changelog/SKILL.claude.md +45 -0
- package/src/gdskills/bundled/skills/quality/changelog/SKILL.codex.md +84 -0
- package/src/gdskills/bundled/skills/quality/changelog/SKILL.cursor.md +84 -0
- package/src/gdskills/bundled/skills/quality/changelog/SKILL.md +84 -0
- package/src/gdskills/bundled/skills/quality/commit/SKILL.codex.md +66 -0
- package/src/gdskills/bundled/skills/quality/commit/SKILL.cursor.md +66 -0
- package/src/gdskills/bundled/skills/quality/commit/SKILL.md +66 -0
- package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.claude.md +40 -0
- package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.codex.md +66 -0
- package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.cursor.md +66 -0
- package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.md +66 -0
- package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.claude.md +45 -0
- package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.codex.md +81 -0
- package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.cursor.md +81 -0
- package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.md +81 -0
- package/src/gdskills/bundled/skills/quality/deploy/SKILL.claude.md +42 -0
- package/src/gdskills/bundled/skills/quality/deploy/SKILL.codex.md +70 -0
- package/src/gdskills/bundled/skills/quality/deploy/SKILL.cursor.md +70 -0
- package/src/gdskills/bundled/skills/quality/deploy/SKILL.md +70 -0
- package/src/gdskills/bundled/skills/quality/metaproject-security/SKILL.md +103 -0
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.claude.md +48 -0
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.codex.md +83 -0
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.cursor.md +83 -0
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.md +83 -0
- package/src/gdskills/bundled/skills/quality/pr/SKILL.codex.md +75 -0
- package/src/gdskills/bundled/skills/quality/pr/SKILL.cursor.md +75 -0
- package/src/gdskills/bundled/skills/quality/pr/SKILL.md +75 -0
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.codex.md +364 -0
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.cursor.md +295 -0
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.md +378 -0
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.opencode.md +364 -0
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.zed.md +38 -0
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/input-contract.schema.json +53 -0
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/output-contract.schema.json +46 -0
- package/src/gdskills/bundled/skills/quality/push/SKILL.codex.md +52 -0
- package/src/gdskills/bundled/skills/quality/push/SKILL.cursor.md +52 -0
- package/src/gdskills/bundled/skills/quality/push/SKILL.md +52 -0
- package/src/gdskills/bundled/skills/quality/security-audit/SKILL.claude.md +40 -0
- package/src/gdskills/bundled/skills/quality/security-audit/SKILL.codex.md +61 -0
- package/src/gdskills/bundled/skills/quality/security-audit/SKILL.cursor.md +61 -0
- package/src/gdskills/bundled/skills/quality/security-audit/SKILL.md +61 -0
- package/src/gdskills/bundled/skills/quality/test-gen/SKILL.claude.md +30 -0
- package/src/gdskills/bundled/skills/quality/test-gen/SKILL.codex.md +75 -0
- package/src/gdskills/bundled/skills/quality/test-gen/SKILL.cursor.md +75 -0
- package/src/gdskills/bundled/skills/quality/test-gen/SKILL.md +75 -0
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.codex.md +64 -0
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.cursor.md +74 -0
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.md +339 -0
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.opencode.md +48 -0
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.zed.md +44 -0
- package/src/gdskills/bundled/skills/quality/tests-creator/input-contract.schema.json +121 -0
- package/src/gdskills/bundled/skills/quality/tests-creator/output-contract.schema.json +127 -0
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.codex.md +204 -0
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.cursor.md +204 -0
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.md +203 -0
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.opencode.md +204 -0
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.zed.md +204 -0
- package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.codex.md +209 -0
- package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.cursor.md +209 -0
- package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.md +208 -0
- package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.opencode.md +209 -0
- package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.zed.md +209 -0
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.codex.md +263 -0
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.cursor.md +263 -0
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.md +258 -0
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.opencode.md +263 -0
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.zed.md +263 -0
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.codex.md +175 -0
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.cursor.md +175 -0
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.md +168 -0
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.opencode.md +175 -0
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.zed.md +175 -0
- package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +360 -0
- package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +337 -0
- package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +477 -0
- package/src/gdskills/bundled/skills/review/review-core-boundaries/SKILL.md +93 -0
- package/src/gdskills/bundled/skills/review/review-flow-graph/SKILL.md +119 -0
- package/src/gdskills/bundled/skills/review/review-frontend/SKILL.md +595 -0
- package/src/gdskills/bundled/skills/review/review-frontend-conventions/SKILL.md +144 -0
- package/src/gdskills/bundled/skills/review/review-highload/SKILL.md +519 -0
- package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +323 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +927 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/input-contract.schema.json +153 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/output-contract.schema.json +77 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/review-context.schema.json +389 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +189 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +241 -0
- package/src/gdskills/bundled/skills/review/review-performance/SKILL.md +344 -0
- package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +327 -0
- package/src/gdskills/bundled/skills/review/review-security-code/SKILL.md +348 -0
- package/src/gdskills/bundled/skills/review/review-strict/SKILL.md +328 -0
- package/src/gdskills/bundled/skills/review/review-style/SKILL.md +343 -0
- package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +134 -0
- package/src/gdskills/bundled/skills/shared/git-merge-base.md +33 -0
- package/src/gdskills/contracts/agent-event.schema.json +32 -0
- package/src/gdskills/contracts/orchestrator-state.schema.json +58 -0
- package/src/gdskills/contracts/review-finding.schema.json +59 -0
- package/src/gdskills/contracts/subagent-dispatch.schema.json +123 -0
- package/src/gdskills/contracts/subagent-result.schema.json +136 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Reference template and checklist for MobX store structure and async state handling."
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
globs:
|
|
5
|
+
- "**/*store*.ts"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# MobX Store Template
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
Provide a reliable baseline for MobX stores and context wiring.
|
|
12
|
+
|
|
13
|
+
## When To Apply
|
|
14
|
+
Apply when creating or reviewing a MobX store file (`*.store.ts`, `*Store.ts`).
|
|
15
|
+
|
|
16
|
+
## Required Store Elements
|
|
17
|
+
- `makeObservable(this)` in constructor.
|
|
18
|
+
- Observable state fields.
|
|
19
|
+
- Computed getters for derived state.
|
|
20
|
+
- Public `@action.bound` actions for mutations triggered from UI.
|
|
21
|
+
- `runInAction` in private async/orchestration methods, especially for post-`await` mutations.
|
|
22
|
+
- Context + hook with null-check error.
|
|
23
|
+
|
|
24
|
+
## Member Accessibility Modifiers
|
|
25
|
+
|
|
26
|
+
ESLint enforces `@typescript-eslint/explicit-member-accessibility: ["error", { accessibility: "no-public" }]` — the `public` keyword is **forbidden**. Public members have no modifier.
|
|
27
|
+
|
|
28
|
+
| Modifier | When to use |
|
|
29
|
+
|----------|-------------|
|
|
30
|
+
| *(no modifier)* | Public observable state, `@computed` getters, lifecycle methods (`dispose()`, `init()`), public non-mutating helpers/selectors, and public `@action.bound` UI methods |
|
|
31
|
+
| `private` | Internal state (`disposed`, `initialized`, `_value`), helper methods, API-calling methods (`fetchX`, `performX`), inter-store callbacks (`onChangeX`, `onFireX`, `handleX`, `syncX`) |
|
|
32
|
+
| `private readonly` | Constructor-injected dependencies, immutable config (`service`, `context`, `id`) |
|
|
33
|
+
| `readonly` | Immutable identity fields that are public (`pipelineType`, `contextActions`) |
|
|
34
|
+
| `protected` | Only in abstract base classes for extension points |
|
|
35
|
+
|
|
36
|
+
## Member Ordering
|
|
37
|
+
|
|
38
|
+
Follow the project convention below for predictable store layout:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
1. private fields
|
|
42
|
+
2. public fields
|
|
43
|
+
3. constructor
|
|
44
|
+
4. public methods
|
|
45
|
+
- @computed getters
|
|
46
|
+
- lifecycle methods (`dispose()`, `init()`, `onMount()`, `onUnmount()`)
|
|
47
|
+
- public non-mutating helpers/selectors (`getById`, `findX`, `uniqueElement`)
|
|
48
|
+
- public `@action.bound` UI entrypoints (`onChangeX`, `onClickX`, `onSave`, `onSubmit`)
|
|
49
|
+
5. private methods
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The exact naming can vary by module, but the shape should stay stable: internal state first, public state next, constructor once, public API grouped together, private orchestration last.
|
|
53
|
+
|
|
54
|
+
## Public UI Actions
|
|
55
|
+
|
|
56
|
+
- Methods invoked from React components or route/UI event handlers MUST be `@action.bound`.
|
|
57
|
+
- These methods are typically named with an `on...` prefix when they represent UI events: `onChangeName`, `onSave`, `onSubmit`, `onToggleExpanded`.
|
|
58
|
+
- Public sync `@action.bound` methods may mutate store state directly. Do **not** wrap those direct mutations in `runInAction` — the action boundary already exists.
|
|
59
|
+
- Public async `@action.bound` methods should stay thin: optional guard check → delegate to a `private async` method.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
@action.bound
|
|
63
|
+
async onSave() {
|
|
64
|
+
if (this.saving) return;
|
|
65
|
+
await this.performSave();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@action.bound
|
|
69
|
+
onChangeName(value: string) {
|
|
70
|
+
this.name = value;
|
|
71
|
+
this.error = null;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Public Helper and Selector Methods
|
|
76
|
+
|
|
77
|
+
Public methods that do **not** mutate store state are not actions:
|
|
78
|
+
|
|
79
|
+
- helpers/selectors such as `getById`, `findBySlug`, `hasItem`, `uniqueElement`
|
|
80
|
+
- read-only utility methods used by components or sibling stores
|
|
81
|
+
|
|
82
|
+
Rules:
|
|
83
|
+
- no `@action.bound`
|
|
84
|
+
- no `runInAction`
|
|
85
|
+
- arrow methods are acceptable and often preferred when a method reference can escape the class instance
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
getById = (id: string) => {
|
|
89
|
+
return this.items.find((item) => item.id === id);
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Private Methods and Async Orchestration
|
|
94
|
+
|
|
95
|
+
- API/IO, persistence, sockets, background orchestration, and internal synchronization belong in `private` methods.
|
|
96
|
+
- Private methods are often best expressed as arrow fields when preserving `this` matters.
|
|
97
|
+
- `private async` methods should usually use `try/catch/finally`.
|
|
98
|
+
- State mutations inside private methods should happen inside `runInAction` blocks.
|
|
99
|
+
- After every `await`, any state mutation must re-enter MobX via `runInAction`.
|
|
100
|
+
- If the method owns `loading` / `saving` / `processing` flags, set them via `runInAction` in `try` and clear them in `finally`.
|
|
101
|
+
- Avoid `@action.bound` on private methods by default.
|
|
102
|
+
- **Exception**: `@action.bound private` is acceptable when a private method is passed as a bound callback reference to a child/sibling store constructor.
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
private performSave = async () => {
|
|
106
|
+
try {
|
|
107
|
+
runInAction(() => {
|
|
108
|
+
this.saving = true;
|
|
109
|
+
this.error = null;
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const saved = await SomeApi.save(this.draft);
|
|
113
|
+
|
|
114
|
+
runInAction(() => {
|
|
115
|
+
if (this.disposed) return;
|
|
116
|
+
this.item = saved;
|
|
117
|
+
});
|
|
118
|
+
} catch (err: unknown) {
|
|
119
|
+
runInAction(() => {
|
|
120
|
+
if (this.disposed) return;
|
|
121
|
+
this.error = err instanceof Error ? err.message : 'Save failed';
|
|
122
|
+
});
|
|
123
|
+
} finally {
|
|
124
|
+
runInAction(() => {
|
|
125
|
+
if (this.disposed) return;
|
|
126
|
+
this.saving = false;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Inter-Store Callbacks and Internal Handlers
|
|
133
|
+
|
|
134
|
+
Methods that serve as **internal callbacks** between stores or internal event handlers MUST be `private`. These are NOT part of the store's public API — they are internal synchronization glue.
|
|
135
|
+
|
|
136
|
+
**Common patterns that MUST be `private`:**
|
|
137
|
+
- `onChangeEditorState(state)` — callback receiving state from child/sibling store
|
|
138
|
+
- `onFireExecutorChange()` — internal sync handler when executor changes
|
|
139
|
+
- `onChangeX(value)` — handler for internal state propagation between stores when not called from React UI
|
|
140
|
+
- `handleX()`, `syncX()` — any internal coordination method
|
|
141
|
+
|
|
142
|
+
**Decision rule:** Ask "Is this method called from a React component via JSX/event handler?" If NO — it is `private`.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// WRONG — public inter-store callback
|
|
146
|
+
@action.bound
|
|
147
|
+
onChangeEditorState(editorState: ICodeEditorState) {
|
|
148
|
+
this.setRawScript(editorState.script);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// CORRECT — private inter-store callback passed to another store
|
|
152
|
+
@action.bound
|
|
153
|
+
private onChangeEditorState(editorState: ICodeEditorState) {
|
|
154
|
+
this.setRawScript(editorState.script);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Note:** `@action.bound` on a `private` callback is acceptable in the callback-reference pattern because it preserves `this` and MobX action tracking when handing the method to another store.
|
|
159
|
+
|
|
160
|
+
## Bidirectional Sync Bounce Protection
|
|
161
|
+
|
|
162
|
+
When two stores synchronize state bidirectionally (Store A writes to Store B and Store B writes back to Store A), an **equality guard** is required in the reverse-sync path to prevent infinite callback loops.
|
|
163
|
+
|
|
164
|
+
**Pattern:** Before propagating a value back to the source store, check that the value actually changed:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Store A → Store B (forward sync, triggered by user action)
|
|
168
|
+
@action.bound
|
|
169
|
+
private onChangeEditorState(editorState: ICodeEditorState) {
|
|
170
|
+
this.setRawScript(editorState.script);
|
|
171
|
+
const codeExecutorId = this.codeExecutor?.id;
|
|
172
|
+
if (this.codeEditorStore.executorId !== codeExecutorId) {
|
|
173
|
+
this.codeEditorStore.setExecutorId(codeExecutorId);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Anti-pattern — missing equality guard causes infinite loop:**
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// WRONG — no guard, will bounce back and forth
|
|
182
|
+
private onChangeEditorState(editorState: ICodeEditorState) {
|
|
183
|
+
this.setRawScript(editorState.script);
|
|
184
|
+
const codeExecutorId = this.codeExecutor?.id;
|
|
185
|
+
this.codeEditorStore.setExecutorId(codeExecutorId); // triggers onChangeX → back to here
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Rule:** In any bidirectional sync between stores, at least one direction MUST have `if (newValue !== currentValue)` before writing to the other store.
|
|
190
|
+
|
|
191
|
+
## Truthy vs Equality Guards for Optional Values
|
|
192
|
+
|
|
193
|
+
When guarding state updates, prefer **equality comparison** (`!==`) over **truthy checks** (`if (value && ...)`) for optional/nullable fields. A truthy guard blocks propagation of legitimate `undefined`/`null`/`0`/`""` values.
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// WRONG — truthy guard blocks clearing (undefined cannot propagate)
|
|
197
|
+
if (executor && executor.id !== this.executorId) {
|
|
198
|
+
this.setExecutorId(executor.id);
|
|
199
|
+
}
|
|
200
|
+
// If executor is undefined (user cleared it), nothing happens — stale value remains
|
|
201
|
+
|
|
202
|
+
// CORRECT — equality guard allows clearing
|
|
203
|
+
if (executor?.id !== this.executorId) {
|
|
204
|
+
this.setExecutorId(executor?.id);
|
|
205
|
+
}
|
|
206
|
+
// If executor is undefined, executorId becomes undefined — field is properly cleared
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Rule:** Use `if (value !== currentValue)` instead of `if (value && value !== currentValue)` when `undefined`/`null` is a valid state that should propagate. Reserve truthy guards only for fields that must never be falsy.
|
|
210
|
+
|
|
211
|
+
## Lifecycle Initialization
|
|
212
|
+
|
|
213
|
+
- `init()` / `onMount()` is called by the **parent store**, not from component `useEffect`.
|
|
214
|
+
- Components should **not** trigger store data loading via `useEffect`. Parent store orchestrates child store lifecycle.
|
|
215
|
+
- `dispose()` is called by the parent store in its `onUnmount()` to prevent stale-state updates.
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
@action.bound
|
|
219
|
+
onMount() {
|
|
220
|
+
void this.variablesStore.init();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@action.bound
|
|
224
|
+
onUnmount() {
|
|
225
|
+
this.variablesStore?.dispose();
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## API Calls in Private Methods
|
|
230
|
+
|
|
231
|
+
API/IO calls must live in **private** store methods, never in components and never as the main body of a public UI action:
|
|
232
|
+
|
|
233
|
+
- public `@action.bound` methods are thin: guard check → delegate to private method
|
|
234
|
+
- private methods handle: API call → `runInAction` mutation blocks → toast/error handling → cleanup
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
## Observable Type Variants
|
|
238
|
+
|
|
239
|
+
MobX provides different levels of observation depth:
|
|
240
|
+
|
|
241
|
+
| Decorator | Behavior |
|
|
242
|
+
|-----------|----------|
|
|
243
|
+
| `@observable` | Deep observation — nested objects and arrays are made observable recursively |
|
|
244
|
+
| `@observable.ref` | Reference only — only the reference itself is tracked, inner contents are NOT observable |
|
|
245
|
+
| `@observable.shallow` | One level deep — array/object items are not made observable, but the container is |
|
|
246
|
+
| `@observable.struct` | Structural comparison — triggers only when the value structurally differs from the previous |
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
// Deep observable (default) — full reactivity on nested data
|
|
250
|
+
@observable items: IItem[] = [];
|
|
251
|
+
@observable config: IConfig = { ... };
|
|
252
|
+
|
|
253
|
+
// Reference observable — use when you own the object reactivity elsewhere
|
|
254
|
+
// or when it's a large external object you don't want deeply proxied
|
|
255
|
+
@observable.ref items: IItem[] = [];
|
|
256
|
+
@observable.ref editorInstance: EditorType | null = null;
|
|
257
|
+
|
|
258
|
+
// Shallow observable — container is reactive, items are plain
|
|
259
|
+
@observable.shallow list: IItem[] = [];
|
|
260
|
+
|
|
261
|
+
// Structural — only triggers reaction when value structurally changes
|
|
262
|
+
@observable.struct position: { x: number; y: number } = { x: 0, y: 0 };
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Private Observable with Getter/Setter
|
|
266
|
+
|
|
267
|
+
Use a private backing field `_value` with a public getter (and optional setter action) when you need to control access or add side effects on mutation:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
@observable private _value: string = "";
|
|
271
|
+
|
|
272
|
+
@computed get value() {
|
|
273
|
+
return this._value;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@action.bound
|
|
277
|
+
setValue(value: string) {
|
|
278
|
+
this._value = value;
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### MobX Observable Collections (IObservableArray / ObservableMap)
|
|
283
|
+
|
|
284
|
+
Use `IObservableArray` and `ObservableMap` when you need access to MobX-specific collection methods (`.replace()`, `.remove()`, `.clear()`, `.has()`, `.merge()`). Plain arrays/maps assigned to `@observable` are also deeply observed but lack these utility methods.
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { IObservableArray, ObservableMap, observable } from "mobx";
|
|
288
|
+
|
|
289
|
+
// IObservableArray — MobX-enhanced array
|
|
290
|
+
@observable someListsByMobx: IObservableArray<IItem> = observable([]);
|
|
291
|
+
|
|
292
|
+
// ObservableMap — MobX-enhanced Map
|
|
293
|
+
@observable someMapByMobx: ObservableMap<string, IItem> = observable(new Map());
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### IObservableArray API
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// Mutation — all trigger reactions
|
|
300
|
+
this.someListsByMobx.push(item); // add one or more at end
|
|
301
|
+
this.someListsByMobx.pop(); // remove last
|
|
302
|
+
this.someListsByMobx.splice(index, deleteCount, ...newItems); // in-place splice
|
|
303
|
+
this.someListsByMobx.replace([item1, item2]); // replace all contents atomically
|
|
304
|
+
this.someListsByMobx.remove(item); // remove first matching item (by reference)
|
|
305
|
+
this.someListsByMobx.clear(); // remove all items
|
|
306
|
+
|
|
307
|
+
// Read — standard array methods work normally
|
|
308
|
+
this.someListsByMobx.find(x => x.id === id);
|
|
309
|
+
this.someListsByMobx.filter(x => x.active);
|
|
310
|
+
this.someListsByMobx.map(x => x.name);
|
|
311
|
+
this.someListsByMobx.slice(); // returns plain array snapshot
|
|
312
|
+
this.someListsByMobx.toJSON(); // alias for slice()
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### ObservableMap API
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
// Mutation
|
|
319
|
+
this.someMapByMobx.set('key', value); // add or update
|
|
320
|
+
this.someMapByMobx.delete('key'); // remove by key
|
|
321
|
+
this.someMapByMobx.clear(); // remove all
|
|
322
|
+
this.someMapByMobx.replace(new Map([['k', v]])); // replace all contents atomically
|
|
323
|
+
this.someMapByMobx.merge({ key: value }); // merge object or map into existing
|
|
324
|
+
|
|
325
|
+
// Read
|
|
326
|
+
this.someMapByMobx.get('key'); // value or undefined
|
|
327
|
+
this.someMapByMobx.has('key'); // boolean
|
|
328
|
+
this.someMapByMobx.keys(); // IterableIterator<string>
|
|
329
|
+
this.someMapByMobx.values(); // IterableIterator<V>
|
|
330
|
+
this.someMapByMobx.entries(); // IterableIterator<[string, V]>
|
|
331
|
+
this.someMapByMobx.forEach((value, key) => ...);
|
|
332
|
+
this.someMapByMobx.toJSON(); // plain object snapshot
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Non-Observable Props (passed from parent store)
|
|
336
|
+
|
|
337
|
+
Props injected from outside the store that do not need reactivity are stored as plain class fields (no decorator):
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
somePropValue: IConfig;
|
|
341
|
+
somePropFn: () => void;
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Reactions and Disposers
|
|
345
|
+
|
|
346
|
+
Use `autorun`, `reaction`, and `when` for side effects that respond to observable changes. Always dispose them in `dispose()` to prevent memory leaks and stale callbacks.
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
import { autorun, reaction, when, IReactionDisposer } from "mobx";
|
|
350
|
+
|
|
351
|
+
export class ExampleStore {
|
|
352
|
+
private disposed = false;
|
|
353
|
+
private disposers: IReactionDisposer[] = [];
|
|
354
|
+
|
|
355
|
+
constructor() {
|
|
356
|
+
makeObservable(this);
|
|
357
|
+
// Set up reactions after makeObservable
|
|
358
|
+
this.disposers.push(
|
|
359
|
+
// autorun — runs immediately and on every dependency change
|
|
360
|
+
autorun(() => {
|
|
361
|
+
if (this.items.length > 0) {
|
|
362
|
+
console.log("items changed:", this.items.length);
|
|
363
|
+
}
|
|
364
|
+
}),
|
|
365
|
+
|
|
366
|
+
// reaction — explicit dependency tracking, runs only on change (not on init)
|
|
367
|
+
reaction(
|
|
368
|
+
() => this.loading,
|
|
369
|
+
(loading) => {
|
|
370
|
+
if (!loading) this.onLoadComplete();
|
|
371
|
+
}
|
|
372
|
+
),
|
|
373
|
+
|
|
374
|
+
// when — runs once when predicate becomes true, then auto-disposes
|
|
375
|
+
when(
|
|
376
|
+
() => this.items.length > 0,
|
|
377
|
+
() => { /* one-time side effect */ }
|
|
378
|
+
)
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
dispose() {
|
|
383
|
+
this.disposed = true;
|
|
384
|
+
this.disposers.forEach(d => d());
|
|
385
|
+
this.disposers = [];
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**Rule:** Every `autorun`, `reaction`, or `when` created in the store MUST have its disposer stored and called in `dispose()`.
|
|
391
|
+
|
|
392
|
+
## Constructor Variants
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
// Basic — no dependencies
|
|
396
|
+
constructor() {
|
|
397
|
+
makeObservable(this);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// With private injected dependency
|
|
401
|
+
constructor(private readonly service: SomeService) {
|
|
402
|
+
makeObservable(this);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// With public readonly identity (no `public` keyword — ESLint forbids it)
|
|
406
|
+
// Use `readonly` instead:
|
|
407
|
+
constructor(readonly id: string) {
|
|
408
|
+
makeObservable(this);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// With value prop + callback prop (from parent store)
|
|
412
|
+
constructor(somePropValue: IConfig, somePropFn: () => void) {
|
|
413
|
+
makeObservable(this);
|
|
414
|
+
this.somePropValue = somePropValue;
|
|
415
|
+
this.somePropFn = somePropFn;
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
## Minimal Template
|
|
420
|
+
```typescript
|
|
421
|
+
import { action, computed, createContext, IObservableArray, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from "mobx";
|
|
422
|
+
import { useContext } from "react";
|
|
423
|
+
|
|
424
|
+
export class ExampleStore {
|
|
425
|
+
// 1. Private fields
|
|
426
|
+
private readonly service: SomeService;
|
|
427
|
+
@observable private _value = "";
|
|
428
|
+
private disposed = false;
|
|
429
|
+
private disposers: IReactionDisposer[] = [];
|
|
430
|
+
|
|
431
|
+
// 2. Public fields
|
|
432
|
+
@observable loading = false;
|
|
433
|
+
@observable saving = false;
|
|
434
|
+
@observable error: string | null = null;
|
|
435
|
+
@observable.ref items: IItem[] = [];
|
|
436
|
+
@observable someListsByMobx: IObservableArray<IItem> = observable([]);
|
|
437
|
+
@observable someMapByMobx: ObservableMap<string, IItem> = observable(new Map());
|
|
438
|
+
readonly pipelineType = "example";
|
|
439
|
+
|
|
440
|
+
// 3. Constructor
|
|
441
|
+
constructor(service: SomeService) {
|
|
442
|
+
this.service = service;
|
|
443
|
+
makeObservable(this);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// 4. Public methods
|
|
447
|
+
@computed get isEmpty() {
|
|
448
|
+
return this.items.length === 0;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
@computed get value() {
|
|
452
|
+
return this._value;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
getById = (id: string) => {
|
|
456
|
+
return this.items.find((item) => item.id === id);
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
dispose() {
|
|
460
|
+
this.disposed = true;
|
|
461
|
+
this.disposers.forEach((dispose) => dispose());
|
|
462
|
+
this.disposers = [];
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
@action.bound
|
|
466
|
+
async init() {
|
|
467
|
+
await this.fetchItems();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
@action.bound
|
|
471
|
+
onChangeValue(value: string) {
|
|
472
|
+
this._value = value;
|
|
473
|
+
this.error = null;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
@action.bound
|
|
477
|
+
async onCreateItem(name: string) {
|
|
478
|
+
if (this.saving) return;
|
|
479
|
+
await this.performCreate(name);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// 5. Private methods
|
|
483
|
+
private registerReactions = () => {
|
|
484
|
+
this.disposers.push(
|
|
485
|
+
reaction(
|
|
486
|
+
() => this.items.length,
|
|
487
|
+
() => {
|
|
488
|
+
// side effect
|
|
489
|
+
},
|
|
490
|
+
),
|
|
491
|
+
);
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
private fetchItems = async () => {
|
|
495
|
+
try {
|
|
496
|
+
runInAction(() => {
|
|
497
|
+
this.loading = true;
|
|
498
|
+
this.error = null;
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
const items = await this.service.getAll();
|
|
502
|
+
|
|
503
|
+
runInAction(() => {
|
|
504
|
+
if (this.disposed) return;
|
|
505
|
+
this.items = items;
|
|
506
|
+
});
|
|
507
|
+
} catch (err: unknown) {
|
|
508
|
+
runInAction(() => {
|
|
509
|
+
if (this.disposed) return;
|
|
510
|
+
this.error = err instanceof Error ? err.message : "Fetch failed";
|
|
511
|
+
});
|
|
512
|
+
} finally {
|
|
513
|
+
runInAction(() => {
|
|
514
|
+
if (this.disposed) return;
|
|
515
|
+
this.loading = false;
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
private performCreate = async (name: string) => {
|
|
521
|
+
try {
|
|
522
|
+
runInAction(() => {
|
|
523
|
+
this.saving = true;
|
|
524
|
+
this.error = null;
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
const created = await this.service.create({ name });
|
|
528
|
+
|
|
529
|
+
runInAction(() => {
|
|
530
|
+
if (this.disposed) return;
|
|
531
|
+
this.items = [...this.items, created];
|
|
532
|
+
});
|
|
533
|
+
} catch (err: unknown) {
|
|
534
|
+
runInAction(() => {
|
|
535
|
+
if (this.disposed) return;
|
|
536
|
+
this.error = err instanceof Error ? err.message : "Create failed";
|
|
537
|
+
});
|
|
538
|
+
} finally {
|
|
539
|
+
runInAction(() => {
|
|
540
|
+
if (this.disposed) return;
|
|
541
|
+
this.saving = false;
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
private syncCollections = () => {
|
|
547
|
+
runInAction(() => {
|
|
548
|
+
this.someListsByMobx.replace([{ id: "1", name: "Item 1" }]);
|
|
549
|
+
this.someMapByMobx.set("1", { id: "1", name: "Item 1" });
|
|
550
|
+
});
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
export const ExampleStoreContext = createContext<ExampleStore | null>(null);
|
|
555
|
+
|
|
556
|
+
export const useExampleStore = () => {
|
|
557
|
+
const store = useContext(ExampleStoreContext);
|
|
558
|
+
if (!store) throw new Error("useExampleStore must be used within provider");
|
|
559
|
+
return store;
|
|
560
|
+
};
|
|
561
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Model selection workflow for sub-agents. Detects available models and allows user to choose."
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Model Selection for Sub-Agents
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
When launching a sub-agent or skill, detect available models in the current environment and allow the user to choose.
|
|
10
|
+
|
|
11
|
+
## Trigger
|
|
12
|
+
When you need to launch a sub-agent/skill and want to use a different model than the current one.
|
|
13
|
+
|
|
14
|
+
## Available Models Detection
|
|
15
|
+
|
|
16
|
+
Run to detect available models:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
.metaproject/scripts/detect-models.sh
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Current Environment Models
|
|
23
|
+
|
|
24
|
+
### Codex
|
|
25
|
+
- `gpt-5.2-codex` - Frontier agentic coding model (recommended)
|
|
26
|
+
- `gpt-5.3-codex` - Latest frontier agentic coding model
|
|
27
|
+
- `gpt-5.1-codex-max` - Codex-optimized flagship for deep reasoning
|
|
28
|
+
- `gpt-5.1-codex-mini` - Cheaper, faster, less capable
|
|
29
|
+
- `gpt-5.2` - Latest frontier model
|
|
30
|
+
|
|
31
|
+
### Cursor
|
|
32
|
+
Uses OpenAI models (GPT-4, GPT-4o, etc.)
|
|
33
|
+
|
|
34
|
+
### Antigravity
|
|
35
|
+
Check configuration in `~/.antigravity/`
|
|
36
|
+
|
|
37
|
+
### OpenCode
|
|
38
|
+
Check configuration in `~/.config/opencode/`
|
|
39
|
+
|
|
40
|
+
### Zed
|
|
41
|
+
Uses AI models configured in Zed settings
|
|
42
|
+
|
|
43
|
+
## Workflow
|
|
44
|
+
|
|
45
|
+
1. **Detect available models** - Run `detect-models.sh` or check known configurations
|
|
46
|
+
2. **Present options** - Show user available models with descriptions
|
|
47
|
+
3. **Get confirmation** - Ask user which model to use
|
|
48
|
+
4. **Launch sub-agent** - Use selected model for the sub-agent
|
|
49
|
+
|
|
50
|
+
## Mandatory Behavior
|
|
51
|
+
- Always ask user before changing model for sub-agents
|
|
52
|
+
- Show model descriptions to help user decide
|
|
53
|
+
- Default to current model unless user explicitly chooses otherwise
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "NestJS DTO standards for Swagger decorators, validation, and typing."
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
globs:
|
|
5
|
+
- "**/*dto*.ts"
|
|
6
|
+
- "**/dto/**/*.ts"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# NestJS DTO Rules
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Ensure DTOs are explicit, validated, and API-documented.
|
|
13
|
+
|
|
14
|
+
## When To Apply
|
|
15
|
+
Apply when creating or reviewing NestJS DTO files (`*dto*.ts`, `dto/**/*.ts`) in the backend project.
|
|
16
|
+
|
|
17
|
+
## Mandatory Standards
|
|
18
|
+
- Use `@ApiProperty()` for required fields.
|
|
19
|
+
- Use `@ApiPropertyOptional()` for optional fields.
|
|
20
|
+
- Use class-validator decorators (`@IsString`, `@IsNumber`, `@IsEnum`, etc.).
|
|
21
|
+
- Use `@IsOptional()` only for truly optional fields.
|
|
22
|
+
- Keep decorator descriptions in English.
|
|
23
|
+
|
|
24
|
+
## Example DTO
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { IsString, IsEmail, IsOptional, IsUUID, Length } from 'class-validator';
|
|
28
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
29
|
+
import { Transform } from 'class-transformer';
|
|
30
|
+
|
|
31
|
+
export class CreateUserDto {
|
|
32
|
+
@ApiProperty({ description: 'User display name', maxLength: 100 })
|
|
33
|
+
@IsString()
|
|
34
|
+
@Length(1, 100)
|
|
35
|
+
name: string;
|
|
36
|
+
|
|
37
|
+
@ApiProperty({ description: 'User email address' })
|
|
38
|
+
@IsEmail()
|
|
39
|
+
@Transform(({ value }) => value.toLowerCase().trim())
|
|
40
|
+
email: string;
|
|
41
|
+
|
|
42
|
+
@ApiPropertyOptional({ description: 'External ID from identity provider' })
|
|
43
|
+
@IsOptional()
|
|
44
|
+
@IsUUID()
|
|
45
|
+
externalId?: string;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Output Contract
|
|
50
|
+
- DTO examples in responses must be Markdown code blocks.
|