@codyswann/lisa 4.54.13 → 4.55.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/all/copy-contents/.gitattributes +8 -0
- package/all/copy-overwrite/scripts/check-orphaned-branches.mjs +78 -9
- package/all/copy-overwrite/scripts/check-third-party-action-pins.mjs +17 -1
- package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +194 -7
- package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +31 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-blind-automerge.sh +81 -2
- package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +293 -8
- package/all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +78 -15
- package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/guard-dedupe.bash +340 -0
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +29 -1
- package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.mjs +183 -1
- package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-postinstall.mjs +21 -1
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +100 -5
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +1085 -80
- package/all/create-only/.github/workflows/continuous-gates.yml +7 -0
- package/cdk/create-only/.github/workflows/ci.yml +7 -0
- package/cdk/create-only/.github/workflows/deploy.yml +21 -0
- package/dist/cli/apply.d.ts.map +1 -1
- package/dist/cli/apply.js +9 -1
- package/dist/cli/apply.js.map +1 -1
- package/dist/cli/doctor-apply-deletions.d.ts +61 -0
- package/dist/cli/doctor-apply-deletions.d.ts.map +1 -0
- package/dist/cli/doctor-apply-deletions.js +137 -0
- package/dist/cli/doctor-apply-deletions.js.map +1 -0
- package/dist/cli/doctor-cdk-preset-adoption.d.ts +15 -0
- package/dist/cli/doctor-cdk-preset-adoption.d.ts.map +1 -0
- package/dist/cli/doctor-cdk-preset-adoption.js +316 -0
- package/dist/cli/doctor-cdk-preset-adoption.js.map +1 -0
- package/dist/cli/doctor-config-shadowing.d.ts +22 -0
- package/dist/cli/doctor-config-shadowing.d.ts.map +1 -0
- package/dist/cli/doctor-config-shadowing.js +123 -0
- package/dist/cli/doctor-config-shadowing.js.map +1 -0
- package/dist/cli/doctor-rails-deploy-intent.d.ts +15 -0
- package/dist/cli/doctor-rails-deploy-intent.d.ts.map +1 -0
- package/dist/cli/doctor-rails-deploy-intent.js +197 -0
- package/dist/cli/doctor-rails-deploy-intent.js.map +1 -0
- package/dist/cli/doctor-seeded-artifacts.d.ts +12 -0
- package/dist/cli/doctor-seeded-artifacts.d.ts.map +1 -0
- package/dist/cli/doctor-seeded-artifacts.js +54 -0
- package/dist/cli/doctor-seeded-artifacts.js.map +1 -0
- package/dist/cli/doctor-stale-banner-scan.d.ts +44 -0
- package/dist/cli/doctor-stale-banner-scan.d.ts.map +1 -0
- package/dist/cli/doctor-stale-banner-scan.js +152 -0
- package/dist/cli/doctor-stale-banner-scan.js.map +1 -0
- package/dist/cli/doctor-stale-managed-banner.d.ts +19 -0
- package/dist/cli/doctor-stale-managed-banner.d.ts.map +1 -0
- package/dist/cli/doctor-stale-managed-banner.js +198 -0
- package/dist/cli/doctor-stale-managed-banner.js.map +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +16 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/ui-detected-stacks.d.ts.map +1 -1
- package/dist/cli/ui-detected-stacks.js +3 -2
- package/dist/cli/ui-detected-stacks.js.map +1 -1
- package/dist/cli/update-check.d.ts.map +1 -1
- package/dist/cli/update-check.js +14 -0
- package/dist/cli/update-check.js.map +1 -1
- package/dist/cli/worktree-liveness.d.ts +5 -0
- package/dist/cli/worktree-liveness.d.ts.map +1 -1
- package/dist/cli/worktree-liveness.js +7 -6
- package/dist/cli/worktree-liveness.js.map +1 -1
- package/dist/cli/worktree-ownership.d.ts +13 -0
- package/dist/cli/worktree-ownership.d.ts.map +1 -1
- package/dist/cli/worktree-ownership.js +14 -0
- package/dist/cli/worktree-ownership.js.map +1 -1
- package/dist/configs/eslint/base.d.ts +34 -0
- package/dist/configs/eslint/base.d.ts.map +1 -1
- package/dist/configs/eslint/base.js +34 -0
- package/dist/configs/eslint/base.js.map +1 -1
- package/dist/core/apply-receipt.d.ts +65 -0
- package/dist/core/apply-receipt.d.ts.map +1 -1
- package/dist/core/apply-receipt.js +62 -2
- package/dist/core/apply-receipt.js.map +1 -1
- package/dist/core/cdk-preset-adoption.d.ts +136 -0
- package/dist/core/cdk-preset-adoption.d.ts.map +1 -0
- package/dist/core/cdk-preset-adoption.js +135 -0
- package/dist/core/cdk-preset-adoption.js.map +1 -0
- package/dist/core/config-shadowing.d.ts +36 -0
- package/dist/core/config-shadowing.d.ts.map +1 -1
- package/dist/core/config-shadowing.js +38 -0
- package/dist/core/config-shadowing.js.map +1 -1
- package/dist/core/config.d.ts +11 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/learnings-merge-driver.d.ts +10 -0
- package/dist/core/learnings-merge-driver.d.ts.map +1 -1
- package/dist/core/learnings-merge-driver.js +18 -0
- package/dist/core/learnings-merge-driver.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +136 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +9 -1
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts +5 -5
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +7 -7
- package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/ownership-header.d.ts +74 -0
- package/dist/core/ownership-header.d.ts.map +1 -0
- package/dist/core/ownership-header.js +76 -0
- package/dist/core/ownership-header.js.map +1 -0
- package/dist/core/rails-deploy-production-intent.d.ts +36 -0
- package/dist/core/rails-deploy-production-intent.d.ts.map +1 -0
- package/dist/core/rails-deploy-production-intent.js +79 -0
- package/dist/core/rails-deploy-production-intent.js.map +1 -0
- package/dist/core/stale-managed-banner.d.ts +78 -0
- package/dist/core/stale-managed-banner.d.ts.map +1 -0
- package/dist/core/stale-managed-banner.js +118 -0
- package/dist/core/stale-managed-banner.js.map +1 -0
- package/dist/core/two-channel-delivery-scan.d.ts +33 -1
- package/dist/core/two-channel-delivery-scan.d.ts.map +1 -1
- package/dist/core/two-channel-delivery-scan.js +133 -6
- package/dist/core/two-channel-delivery-scan.js.map +1 -1
- package/dist/core/two-channel-delivery.d.ts +101 -4
- package/dist/core/two-channel-delivery.d.ts.map +1 -1
- package/dist/core/two-channel-delivery.js +121 -13
- package/dist/core/two-channel-delivery.js.map +1 -1
- package/dist/core/two-channel-staleness.d.ts +137 -0
- package/dist/core/two-channel-staleness.d.ts.map +1 -0
- package/dist/core/two-channel-staleness.js +268 -0
- package/dist/core/two-channel-staleness.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +265 -121
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/core/workflow-deletion-ownership.d.ts +6 -24
- package/dist/core/workflow-deletion-ownership.d.ts.map +1 -1
- package/dist/core/workflow-deletion-ownership.js +22 -42
- package/dist/core/workflow-deletion-ownership.js.map +1 -1
- package/dist/detection/detectors/cdk.d.ts.map +1 -1
- package/dist/detection/detectors/cdk.js +2 -1
- package/dist/detection/detectors/cdk.js.map +1 -1
- package/dist/health/template-inspection.d.ts.map +1 -1
- package/dist/health/template-inspection.js +2 -1
- package/dist/health/template-inspection.js.map +1 -1
- package/dist/migrations/ensure-lisa-postinstall.d.ts +16 -0
- package/dist/migrations/ensure-lisa-postinstall.d.ts.map +1 -1
- package/dist/migrations/ensure-lisa-postinstall.js +16 -0
- package/dist/migrations/ensure-lisa-postinstall.js.map +1 -1
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts +2 -2
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts.map +1 -1
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.js +98 -34
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.js.map +1 -1
- package/dist/migrations/ensure-playwright-dedicated-caller.d.ts.map +1 -1
- package/dist/migrations/ensure-playwright-dedicated-caller.js +1 -0
- package/dist/migrations/ensure-playwright-dedicated-caller.js.map +1 -1
- package/dist/opencode/hooks-installer.d.ts.map +1 -1
- package/dist/opencode/hooks-installer.js +1 -0
- package/dist/opencode/hooks-installer.js.map +1 -1
- package/dist/opencode/plugin-templates/block-managed-file-edits.sh +78 -15
- package/dist/opencode/plugin-templates/block-no-verify.sh +21 -0
- package/dist/opencode/plugin-templates/guard-dedupe.bash +337 -0
- package/dist/opencode/plugin-templates/lisa-block-direct-issue-create.ts +242 -55
- package/dist/opencode/plugin-templates/parity-safety-net.sh +29 -1
- package/dist/strategies/package-lisa.d.ts.map +1 -1
- package/dist/strategies/package-lisa.js +2 -1
- package/dist/strategies/package-lisa.js.map +1 -1
- package/dist/utils/path-utils.d.ts +29 -0
- package/dist/utils/path-utils.d.ts.map +1 -1
- package/dist/utils/path-utils.js +41 -0
- package/dist/utils/path-utils.js.map +1 -1
- package/expo/create-only/.github/workflows/ci.yml +21 -0
- package/expo/create-only/.github/workflows/deploy.yml +28 -0
- package/expo/create-only/.github/workflows/maestro-e2e.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +124 -13
- package/expo/create-only/.github/workflows/nightly-e2e-health.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-report.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-tracking.yml +8 -0
- package/expo/create-only/.github/workflows/playwright-e2e.yml +7 -0
- package/harper-fabric/copy-overwrite/.github/workflows/ci.yml +7 -0
- package/harper-fabric/create-only/.github/workflows/deploy.yml +14 -0
- package/nestjs/create-only/.github/workflows/ci.yml +14 -0
- package/nestjs/create-only/.github/workflows/deploy.yml +28 -0
- package/package.json +10 -5
- package/phaser/copy-overwrite/.github/workflows/ci.yml +7 -0
- package/plugins/lisa/.claude-plugin/plugin.json +28 -1
- package/plugins/lisa/.codex-plugin/hooks.json +27 -0
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-prd-intake/SKILL.md +47 -30
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +4 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/lisa/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa/hooks/inject-rules.sh +13 -5
- package/plugins/lisa/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa/rules/eager/tracked-work.md +1 -1
- package/plugins/lisa/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-agy/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa-agy/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-agy/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-agy/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-agy/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-agy/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-agy/hooks.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-agy/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-agy/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-agy/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-agy/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +19 -1
- package/plugins/lisa-copilot/agents/linear-prd-intake.agent.md +8 -8
- package/plugins/lisa-copilot/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-copilot/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-copilot/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa-copilot/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-copilot/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa-copilot/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-copilot/hooks/inject-rules.sh +13 -5
- package/plugins/lisa-copilot/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-copilot/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-copilot/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa-copilot/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa-copilot/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa-copilot/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa-copilot/rules/eager/tracked-work.md +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa-copilot/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa-copilot/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-copilot/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-copilot/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-copilot/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-copilot/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa-cursor/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa-cursor/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-cursor/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa-cursor/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-cursor/hooks/hooks.json +10 -0
- package/plugins/lisa-cursor/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-cursor/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-cursor/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa-cursor/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa-cursor/rules/00-rule-index.mdc +1 -0
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/operational-hazards-reference.mdc +120 -0
- package/plugins/lisa-cursor/rules/operational-hazards.mdc +55 -0
- package/plugins/lisa-cursor/rules/tracked-work.mdc +1 -1
- package/plugins/lisa-cursor/rules/work-item-trailer-definition-reference.mdc +134 -0
- package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-cursor/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-cursor/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-cursor/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-cursor/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-harper-fabric/rules/eager/harper-fabric.md +31 -0
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-harper-fabric-copilot/rules/eager/harper-fabric.md +31 -0
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric-reference.mdc +57 -0
- package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric.mdc +32 -53
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-phaser/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-phaser-copilot/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/rules/phaser-reference.mdc +189 -0
- package/plugins/lisa-phaser-cursor/rules/phaser.mdc +45 -185
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/hooks/inject-rules.sh +14 -4
- package/plugins/lisa-rails/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/hooks/inject-rules.sh +14 -4
- package/plugins/lisa-rails-copilot/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/rules/rails-conventions-reference.mdc +181 -0
- package/plugins/lisa-rails-cursor/rules/rails-conventions.mdc +24 -177
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/materialized-artifacts.json +1 -0
- package/plugins/src/base/.claude-plugin/plugin.json +27 -0
- package/plugins/src/base/agents/linear-prd-intake.md +8 -8
- package/plugins/src/base/hooks/block-blind-automerge.sh +81 -2
- package/plugins/src/base/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/src/base/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/src/base/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/src/base/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/src/base/hooks/block-no-verify.sh +21 -0
- package/plugins/src/base/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/src/base/hooks/failure-signature-index.mjs +240 -5
- package/plugins/src/base/hooks/guard-dedupe.bash +337 -0
- package/plugins/src/base/hooks/inject-rules.sh +13 -5
- package/plugins/src/base/hooks/operational-hazards.mjs +736 -0
- package/plugins/src/base/hooks/operational-hazards.sh +28 -0
- package/plugins/src/base/hooks/parity-safety-net.sh +29 -1
- package/plugins/src/base/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/src/base/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/src/base/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/src/base/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/src/base/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/src/base/rules/eager/00-rule-index.md +1 -0
- package/plugins/src/base/rules/eager/operational-hazards.md +50 -0
- package/plugins/src/base/rules/eager/tracked-work.md +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +1 -1
- package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/src/base/rules/reference/operational-hazards.md +115 -0
- package/plugins/src/base/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/src/base/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/src/base/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/src/base/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/src/base/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/src/base/skills/lisa-track/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/src/harper-fabric/hooks/inject-rules.sh +14 -3
- package/plugins/src/harper-fabric/rules/eager/harper-fabric.md +31 -0
- package/plugins/src/phaser/hooks/inject-rules.sh +14 -3
- package/plugins/src/phaser/rules/eager/phaser.md +44 -0
- package/plugins/src/rails/hooks/inject-rules.sh +14 -4
- package/plugins/src/rails/rules/eager/rails-conventions.md +23 -0
- package/rails/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
- package/rails/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
- package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
- package/rails/create-only/.github/workflows/ci.yml +8 -0
- package/rails/create-only/.github/workflows/deploy.yml +22 -0
- package/scripts/build-plugins.sh +2 -1
- package/scripts/check-engine-floor.mjs +361 -0
- package/scripts/check-guard-parity-notes.mjs +709 -0
- package/scripts/check-template-workflow-refs.mjs +9 -0
- package/scripts/check-third-party-action-pins.mjs +17 -1
- package/scripts/check-workflow-contract-assertions.mjs +480 -0
- package/scripts/copy-opencode-plugin-templates.mjs +1 -0
- package/scripts/deployed-guard-advice.mjs +636 -0
- package/scripts/generate-agy-plugin-artifacts.mjs +35 -10
- package/scripts/generate-export-surface.mjs +105 -19
- package/scripts/generate-two-channel-couplings.ts +143 -212
- package/scripts/lisa-enforcement-fallback.sh +31 -0
- package/scripts/measure-scripts-profile-gap.mts +361 -0
- package/scripts/mutation-performance-measure.mjs +21 -5
- package/scripts/reconcile-release-tags.mjs +65 -84
- package/scripts/two-channel-couplings.json +302 -70
- package/scripts/workflow-contract-assertion.sh +47 -0
- package/typescript/copy-overwrite/.lintstagedrc.json +1 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +1 -0
- package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +527 -53
- package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +301 -13
- package/typescript/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
- package/typescript/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
- package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
- package/typescript/create-only/.github/workflows/ci.yml +7 -0
- /package/plugins/lisa-harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/lisa-harper-fabric-copilot/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/lisa-phaser/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/lisa-phaser-copilot/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/lisa-rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
- /package/plugins/lisa-rails-copilot/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
- /package/plugins/src/harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/src/phaser/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/src/rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
|
@@ -1,189 +1,49 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Phaser 4 Project Rules"
|
|
2
|
+
description: "Phaser 4 Project Rules (load-bearing)"
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Phaser 4 Project Rules
|
|
7
|
-
|
|
8
|
-
This is a **Phaser 4** (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
**
|
|
12
|
-
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
Phaser ships
|
|
16
|
-
|
|
17
|
-
`
|
|
18
|
-
|
|
19
|
-
`
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
4. **Determinism.** No `Math.random()`, `Date.now()`, or `performance.now()` in
|
|
51
|
-
game code. Use the seeded `Phaser.Math.RandomDataGenerator` (`Phaser.Math.RND`
|
|
52
|
-
or a local instance seeded from one place) so replays and tests reproduce.
|
|
53
|
-
5. **State and events.** Global state goes through a **typed wrapper over the
|
|
54
|
-
registry**; cross-cutting events go through a **single dedicated
|
|
55
|
-
EventsCenter** (`new Phaser.Events.EventEmitter()`) — **never reuse
|
|
56
|
-
`game.events`**. Every external `.on()` (`this.input` / `scale` / `time` /
|
|
57
|
-
`window` / the custom bus) must have a matching `.off()` in the scene's
|
|
58
|
-
`shutdown`. See `phaser-services`.
|
|
59
|
-
6. **Performance.** Pool transient objects via `Group`s; make **no allocations
|
|
60
|
-
and create no objects/tweens/timers inside `update()`**; atlas everything; use
|
|
61
|
-
`BitmapText` for high-churn text; use `SpriteGPULayer` / `TilemapGPULayer` for
|
|
62
|
-
mass rendering. See the official `game-object-components` skill.
|
|
63
|
-
7. **Baked-in asset pipeline with REAL art.** Raw art in `assets/src` is packed
|
|
64
|
-
at build time (free-tex-packer-core atlases, audiosprite, BMFont) into
|
|
65
|
-
`public/assets`, and a codegen step emits typed keys to `src/assets.ts` so a
|
|
66
|
-
missing or renamed key is a **compile error**. No raw string asset / scene /
|
|
67
|
-
event keys anywhere. The art itself must be **real and licensed** — sourced
|
|
68
|
-
per `phaser-asset-sourcing` (CC0-or-equivalent only, with an exact license
|
|
69
|
-
quote + evidence URL in `assets/LICENSES.md` and committed provenance).
|
|
70
|
-
Procedural `generateTexture` placeholders are **tracked art debt**: a scene
|
|
71
|
-
may ship them **only** with a linked art-debt issue, never as the finished
|
|
72
|
-
state and never described as "zero-asset best practice." Characters ship real
|
|
73
|
-
idle+walk animation, not static frames. See `phaser-asset-sourcing` and
|
|
74
|
-
`phaser-asset-pipeline`.
|
|
75
|
-
8. **PWA on by default** via `vite-plugin-pwa` (`registerType: "autoUpdate"`,
|
|
76
|
-
`globPatterns` extended to cover game assets). See `phaser-build-deploy`.
|
|
77
|
-
9. **Cross-cutting services are scaffolded** in `src/services/**`: SoundService
|
|
78
|
-
(mobile audio unlock on first gesture), InputService (semantic actions, not
|
|
79
|
-
raw keys), SaveService (typed `localStorage` with a schema `VERSION` +
|
|
80
|
-
migration chain — never raw `localStorage`), a typed i18n string catalog (no
|
|
81
|
-
hardcoded user-facing strings), accessibility (prefers-reduced-motion,
|
|
82
|
-
pause-on-blur, keyboard-navigable menus, screen-reader live region), and a
|
|
83
|
-
vendor-neutral telemetry/analytics abstraction. In-game errors are wired to
|
|
84
|
-
the observability sink. See `phaser-services`, `phaser-i18n`,
|
|
85
|
-
`phaser-accessibility`.
|
|
86
|
-
10. **Testing is a pyramid.** Pure logic is unit-tested with Vitest;
|
|
87
|
-
scenes/entities are excluded from unit coverage and verified by **runtime
|
|
88
|
-
gates** in CI (boot smoke, allocation/perf budget, leak gate, determinism
|
|
89
|
-
gate, deterministic visual regression, bundle-size budget). See
|
|
90
|
-
`phaser-testing`. Build pins: `phaser ^4.2.0`, Vite, TypeScript 6.
|
|
91
|
-
|
|
92
|
-
## Enforced lint rules (prose must match machine enforcement)
|
|
93
|
-
|
|
94
|
-
The lint config enforces the rules below. Each exists because the prose above
|
|
95
|
-
relies on it — keep them in sync.
|
|
96
|
-
|
|
97
|
-
**`no-restricted-imports`**
|
|
98
|
-
|
|
99
|
-
- Importing `phaser` anywhere under `src/logic/**` is banned. The logic core
|
|
100
|
-
stays engine-free so Vitest runs it without a browser.
|
|
101
|
-
|
|
102
|
-
**`no-restricted-syntax`** bans:
|
|
103
|
-
|
|
104
|
-
- Removed v3 idioms: `setPipeline` / `setPostPipeline` / `resetPipeline`,
|
|
105
|
-
`setTintFill`, `preFX` / `postFX`, `Phaser.Geom.Point`, `Phaser.Struct`,
|
|
106
|
-
`BitmapMask`, `Mesh`, `Plane`, `Camera3D`. Use the v4 replacements
|
|
107
|
-
(RenderNodes, Filters, `Phaser.Math.Vector2`, native `Set`/`Map`, GPU layers).
|
|
108
|
-
- `Math.random()` / `Date.now()` / `performance.now()` in `src` game code — use
|
|
109
|
-
the seeded RND and the scene clock (`this.time.now`).
|
|
110
|
-
- Reusing `game.events` for app messaging — use the dedicated EventsCenter.
|
|
111
|
-
- `debug: true` inside a physics/game config object literal — debug stays off in
|
|
112
|
-
committed code (toggle locally, never commit it on).
|
|
113
|
-
|
|
114
|
-
**Direct-`localStorage` ban**
|
|
115
|
-
|
|
116
|
-
- Direct `localStorage` access outside `src/services/**` is banned. Persist
|
|
117
|
-
through SaveService (versioned + migrated).
|
|
118
|
-
|
|
119
|
-
**Custom `eslint-plugin-phaser` rules**
|
|
120
|
-
|
|
121
|
-
- `no-create-in-update` — no `this.add.*`, `tweens.add`, `time.addEvent`,
|
|
122
|
-
`physics.add.*`, or `new Phaser.*` inside an `update()` method. Create in
|
|
123
|
-
`create()`; in the loop, reuse and pool.
|
|
124
|
-
- `no-allocation-in-update` — no object/array literals, closures, or
|
|
125
|
-
`.map`/`.filter`/`.reduce` chains inside `update()`. Hoist scratch objects.
|
|
126
|
-
- `require-shutdown-cleanup` — a `Scene` that registers persistent external
|
|
127
|
-
listeners must define a `shutdown` handler that removes them.
|
|
128
|
-
|
|
129
|
-
## Architecture
|
|
130
|
-
|
|
131
|
-
- **One scene class per file** under `src/scenes/`, named after the scene key.
|
|
132
|
-
The scene flow is `Boot → Preloader → MainMenu → Game` (plus overlays). Boot
|
|
133
|
-
loads only what the Preloader needs; the Preloader loads everything else.
|
|
134
|
-
- **Pure game logic lives in `src/logic/**`** with no `phaser` imports — plain
|
|
135
|
-
TypeScript that takes and returns data. Scenes/entities are thin orchestrators
|
|
136
|
-
that wire that logic to GameObjects. See `phaser-testing`.
|
|
137
|
-
- **Keys are typed constants** generated into `src/assets.ts` — never inline
|
|
138
|
-
magic strings for texture/audio/animation/scene/event keys. Load via asset-pack
|
|
139
|
-
manifests (`this.load.pack`), not ad-hoc `load.image` lists.
|
|
140
|
-
|
|
141
|
-
## Performance
|
|
142
|
-
|
|
143
|
-
- **No allocations in `update()`** and **no object/tween/timer creation in
|
|
144
|
-
`update()`** (both lint-enforced) — hoist scratch objects, reuse vectors.
|
|
145
|
-
- **Pool, don't churn.** Bullets, enemies, particles, and pickups come from
|
|
146
|
-
`Group` pools (`get` / `killAndHide`), never `new` / `destroy` per spawn.
|
|
147
|
-
- **Mass rendering uses the GPU layers.** Large sprite fields → `SpriteGPULayer`;
|
|
148
|
-
large tile maps → `TilemapGPULayer`. Atlas everything (see
|
|
149
|
-
`phaser-asset-pipeline`); `BitmapText` for high-churn text.
|
|
150
|
-
- Target WebGL; the Canvas renderer is deprecated in v4 and acceptable only as an
|
|
151
|
-
explicit, documented fallback.
|
|
152
|
-
|
|
153
|
-
## Verification
|
|
154
|
-
|
|
155
|
-
Before reporting any change complete: run `bun run typecheck`, `bun run lint`,
|
|
156
|
-
`bun run test`, and `bun run build`. For changes that affect rendering or input,
|
|
157
|
-
verify in the real browser — `bun run dev` plus a Playwright check (the game
|
|
158
|
-
boots, the canvas renders, no console errors). CI additionally runs the runtime
|
|
159
|
-
gates (`phaser-testing`). A green typecheck alone is not proof a game works.
|
|
160
|
-
|
|
161
|
-
## Game-development personas (subagents)
|
|
162
|
-
|
|
163
|
-
This plugin ships **game-development persona subagents** under `agents/` —
|
|
164
|
-
reusable *roles* (a publisher, a game designer, a target player, …) that
|
|
165
|
-
critique the game from a non-engineering seat. They complement, and never
|
|
166
|
-
duplicate, Lisa's engineering specialists (architecture, quality, test,
|
|
167
|
-
security, performance). Most are **critics** (they review the design and report
|
|
168
|
-
findings); a couple (`narrative-designer`, `target-player`) also **generate**
|
|
169
|
-
content.
|
|
170
|
-
|
|
171
|
-
**Role vs. instance.** The persona *role* lives here (genre-neutral, reusable
|
|
172
|
-
across every Phaser game). The persona *instance data* — this game's actual
|
|
173
|
-
target-player archetypes, art direction, economy spec, publisher constraints —
|
|
174
|
-
lives in the project's wiki. Each subagent reads its source-of-truth wiki docs
|
|
175
|
-
(`wiki/design/**`, `wiki/narrative/**`, `wiki/production/**`,
|
|
176
|
-
`wiki/personas/**`, …) and degrades to genre-neutral best practice, saying so,
|
|
177
|
-
when those docs are absent.
|
|
178
|
-
|
|
179
|
-
| Tier | Personas |
|
|
180
|
-
|------|----------|
|
|
181
|
-
| **Core** (most games) | `game-designer`, `player-advocate`, `narrative-designer`, `level-designer`, `ux-ui-designer`, `game-feel-specialist`, `qa-playtester`, `producer` |
|
|
182
|
-
| **Business & audience** | `publisher`, `marketing-strategist`, `target-player`, `accessibility-advocate` |
|
|
183
|
-
| **Specialist** (opt-in per project) | `combat-designer`, `economy-designer`, `art-director`, `audio-director`, `monetization-designer`, `localization-manager`, `onboarding-advocate`, `product-analyst` |
|
|
184
|
-
|
|
185
|
-
Invoke a persona as a subagent (e.g. via the Agent tool / `@`-mention) during
|
|
186
|
-
planning and review. Specialist personas are opt-in — enable the ones the
|
|
187
|
-
project's genre warrants (a puzzle game does not need a `combat-designer`); the
|
|
188
|
-
`monetization-designer` should stay off for premium/offline titles.
|
|
189
|
-
|
|
6
|
+
# Phaser 4 Project Rules (load-bearing)
|
|
7
|
+
|
|
8
|
+
This is a **Phaser 4** (npm `phaser@^4.2.0`) TypeScript game project on the
|
|
9
|
+
official `template-vite-ts` layout. Phaser 4 is the only supported target —
|
|
10
|
+
never introduce Phaser 3 idioms. These decisions are **locked** and most are
|
|
11
|
+
**lint-enforced**; do not disable a rule, fix the code.
|
|
12
|
+
|
|
13
|
+
## Read the official skills first
|
|
14
|
+
|
|
15
|
+
Phaser ships 28 authoritative agent skills inside the installed package at
|
|
16
|
+
`node_modules/phaser/skills/<topic>/SKILL.md` (`scenes`, `physics-arcade`,
|
|
17
|
+
`tweens`, `tilemaps`, `v3-to-v4-migration`, …). **For any Phaser API or
|
|
18
|
+
subsystem question, read the matching official skill rather than relying on
|
|
19
|
+
memory.** The `lisa-phaser` skills deliberately cover only the opinionated,
|
|
20
|
+
lint-enforced project layer.
|
|
21
|
+
|
|
22
|
+
## Mandatory
|
|
23
|
+
|
|
24
|
+
1. **Thin scenes over a pure-logic core.** All game rules live in `src/logic/**`
|
|
25
|
+
as plain TypeScript with **zero `phaser` imports** — lint-enforced, and it is
|
|
26
|
+
what makes the game unit-testable.
|
|
27
|
+
2. **Determinism.** No `Math.random()`, `Date.now()`, or `performance.now()` in
|
|
28
|
+
game code. Use the seeded `Phaser.Math.RND` and the scene clock.
|
|
29
|
+
3. **Nothing created or allocated inside `update()`** — no `this.add.*`,
|
|
30
|
+
`tweens.add`, `time.addEvent`, `new Phaser.*`, object/array literals, or
|
|
31
|
+
`map`/`filter`/`reduce` chains. Create in `create()`; pool via `Group`s.
|
|
32
|
+
4. **Events and state.** Cross-cutting events go through one dedicated
|
|
33
|
+
`EventsCenter`; **never reuse `game.events`**. Every external `.on()` needs a
|
|
34
|
+
matching `.off()` in the scene's `shutdown`. Global state goes through the
|
|
35
|
+
typed registry wrapper; persistence goes through SaveService, never raw
|
|
36
|
+
`localStorage`.
|
|
37
|
+
5. **No raw keys, no placeholder art.** Texture/audio/animation/scene/event keys
|
|
38
|
+
are typed constants generated into `src/assets.ts`. Art must be real and
|
|
39
|
+
licensed per `phaser-asset-sourcing`; procedural `generateTexture`
|
|
40
|
+
placeholders are tracked art debt and need a linked issue.
|
|
41
|
+
6. **No hardcoded user-facing strings** — use the typed i18n catalog.
|
|
42
|
+
7. **Verify before reporting complete:** `bun run typecheck`, `bun run lint`,
|
|
43
|
+
`bun run test`, `bun run build`. For rendering or input changes, also verify
|
|
44
|
+
in a real browser (`bun run dev` plus a Playwright check). A green typecheck
|
|
45
|
+
alone is not proof a game works.
|
|
46
|
+
|
|
47
|
+
Full prose — the ten locked architecture decisions, the enforced lint rules, the
|
|
48
|
+
performance contract, and the game-development persona subagents:
|
|
49
|
+
[reference/phaser.md](phaser-reference.mdc).
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Reads
|
|
3
|
-
#
|
|
4
|
-
#
|
|
2
|
+
# Reads the plugin's EAGER rules and injects them into the session context.
|
|
3
|
+
#
|
|
4
|
+
# `rules/eager/` only, and deliberately with NO fallback to a flat `rules/`.
|
|
5
|
+
# This plugin's rules and this script ship in the same directory and are
|
|
6
|
+
# installed as one unit, so there is no vintage in which a split script meets an
|
|
7
|
+
# unsplit rules tree. A fallback here would buy nothing and cost the thing it
|
|
8
|
+
# already cost once: this plugin shipped its whole rule body flat for months and
|
|
9
|
+
# no surface complained, because a fallback that quietly succeeds is
|
|
10
|
+
# indistinguishable from a tree that was never split (#3993). With the branch
|
|
11
|
+
# gone, an unsplit tree injects nothing and is noticed.
|
|
12
|
+
#
|
|
13
|
+
# Reference bodies under `rules/reference/` install alongside and are read only
|
|
14
|
+
# when an eager breadcrumb points at one.
|
|
5
15
|
set -euo pipefail
|
|
6
16
|
|
|
7
17
|
INPUT=$(cat 2>/dev/null || true)
|
|
@@ -12,7 +22,7 @@ else
|
|
|
12
22
|
fi
|
|
13
23
|
|
|
14
24
|
ROOT="${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}}"
|
|
15
|
-
RULES_DIR="$ROOT/rules"
|
|
25
|
+
RULES_DIR="$ROOT/rules/eager"
|
|
16
26
|
|
|
17
27
|
# Bail silently if no rules directory
|
|
18
28
|
[ -d "$RULES_DIR" ] || exit 0
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Rails Coding Conventions (load-bearing)
|
|
2
|
+
|
|
3
|
+
Rails-specific standards for this project. The head below is what changes
|
|
4
|
+
behaviour in a session that never asks for it; the worked examples for every
|
|
5
|
+
point live in the reference body.
|
|
6
|
+
|
|
7
|
+
## Mandatory
|
|
8
|
+
|
|
9
|
+
1. **Fat models, skinny controllers.** Controllers handle HTTP concerns only.
|
|
10
|
+
Business logic belongs in a model or a service object under `app/services/`.
|
|
11
|
+
2. **Strong parameters always, `permit!` never.** Enumerate the permitted keys.
|
|
12
|
+
3. **No N+1 queries.** Use `includes` / `preload` / `eager_load` on any
|
|
13
|
+
association you iterate. Bullet is installed to catch the ones you miss.
|
|
14
|
+
4. **Never edit `db/schema.rb` by hand.** Change it through a migration, honour
|
|
15
|
+
the `strong_migrations` constraints, and index every foreign key and
|
|
16
|
+
commonly-queried column.
|
|
17
|
+
5. **Scopes, not class methods,** for chainable queries. Prefer built-in
|
|
18
|
+
validators; keep callbacks to simple normalization and push complex side
|
|
19
|
+
effects into a service object.
|
|
20
|
+
6. **RSpec with `factory_bot` and `shoulda-matchers`,** not fixtures. Use
|
|
21
|
+
`described_class` and keep one assertion concept per example.
|
|
22
|
+
|
|
23
|
+
Full prose and Ruby examples: [reference/rails-conventions.md](../reference/rails-conventions.md).
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Reads
|
|
3
|
-
#
|
|
4
|
-
#
|
|
2
|
+
# Reads the plugin's EAGER rules and injects them into the session context.
|
|
3
|
+
#
|
|
4
|
+
# `rules/eager/` only, and deliberately with NO fallback to a flat `rules/`.
|
|
5
|
+
# This plugin's rules and this script ship in the same directory and are
|
|
6
|
+
# installed as one unit, so there is no vintage in which a split script meets an
|
|
7
|
+
# unsplit rules tree. A fallback here would buy nothing and cost the thing it
|
|
8
|
+
# already cost once: this plugin shipped its whole rule body flat for months and
|
|
9
|
+
# no surface complained, because a fallback that quietly succeeds is
|
|
10
|
+
# indistinguishable from a tree that was never split (#3993). With the branch
|
|
11
|
+
# gone, an unsplit tree injects nothing and is noticed.
|
|
12
|
+
#
|
|
13
|
+
# Reference bodies under `rules/reference/` install alongside and are read only
|
|
14
|
+
# when an eager breadcrumb points at one.
|
|
5
15
|
set -euo pipefail
|
|
6
16
|
|
|
7
17
|
INPUT=$(cat 2>/dev/null || true)
|
|
@@ -12,7 +22,7 @@ else
|
|
|
12
22
|
fi
|
|
13
23
|
|
|
14
24
|
ROOT="${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}}"
|
|
15
|
-
RULES_DIR="$ROOT/rules"
|
|
25
|
+
RULES_DIR="$ROOT/rules/eager"
|
|
16
26
|
|
|
17
27
|
# Bail silently if no rules directory
|
|
18
28
|
[ -d "$RULES_DIR" ] || exit 0
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Rails Coding Conventions (load-bearing)
|
|
2
|
+
|
|
3
|
+
Rails-specific standards for this project. The head below is what changes
|
|
4
|
+
behaviour in a session that never asks for it; the worked examples for every
|
|
5
|
+
point live in the reference body.
|
|
6
|
+
|
|
7
|
+
## Mandatory
|
|
8
|
+
|
|
9
|
+
1. **Fat models, skinny controllers.** Controllers handle HTTP concerns only.
|
|
10
|
+
Business logic belongs in a model or a service object under `app/services/`.
|
|
11
|
+
2. **Strong parameters always, `permit!` never.** Enumerate the permitted keys.
|
|
12
|
+
3. **No N+1 queries.** Use `includes` / `preload` / `eager_load` on any
|
|
13
|
+
association you iterate. Bullet is installed to catch the ones you miss.
|
|
14
|
+
4. **Never edit `db/schema.rb` by hand.** Change it through a migration, honour
|
|
15
|
+
the `strong_migrations` constraints, and index every foreign key and
|
|
16
|
+
commonly-queried column.
|
|
17
|
+
5. **Scopes, not class methods,** for chainable queries. Prefer built-in
|
|
18
|
+
validators; keep callbacks to simple normalization and push complex side
|
|
19
|
+
effects into a service object.
|
|
20
|
+
6. **RSpec with `factory_bot` and `shoulda-matchers`,** not fixtures. Use
|
|
21
|
+
`described_class` and keep one assertion concept per example.
|
|
22
|
+
|
|
23
|
+
Full prose and Ruby examples: [reference/rails-conventions.md](../reference/rails-conventions.md).
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Rails Coding Conventions"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Rails Coding Conventions
|
|
7
|
+
|
|
8
|
+
This rule enforces Rails-specific coding standards for consistency, maintainability, and performance.
|
|
9
|
+
|
|
10
|
+
## Fat Models, Skinny Controllers
|
|
11
|
+
|
|
12
|
+
Controllers handle HTTP concerns only. Business logic belongs in models or service objects.
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
# Correct — controller delegates to model
|
|
16
|
+
class OrdersController < ApplicationController
|
|
17
|
+
def create
|
|
18
|
+
@order = Order.place(order_params, current_user)
|
|
19
|
+
redirect_to @order
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Wrong — business logic in controller
|
|
24
|
+
class OrdersController < ApplicationController
|
|
25
|
+
def create
|
|
26
|
+
@order = Order.new(order_params)
|
|
27
|
+
@order.user = current_user
|
|
28
|
+
@order.total = @order.line_items.sum(&:price)
|
|
29
|
+
@order.apply_discount(current_user.discount_rate)
|
|
30
|
+
@order.save!
|
|
31
|
+
OrderMailer.confirmation(@order).deliver_later
|
|
32
|
+
redirect_to @order
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Service Objects
|
|
38
|
+
|
|
39
|
+
Extract complex business logic into service objects when a model method would be too large or spans multiple models.
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
# app/services/order_placement_service.rb
|
|
43
|
+
class OrderPlacementService
|
|
44
|
+
def initialize(user:, params:)
|
|
45
|
+
@user = user
|
|
46
|
+
@params = params
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def call
|
|
50
|
+
order = Order.new(@params)
|
|
51
|
+
order.user = @user
|
|
52
|
+
order.calculate_total
|
|
53
|
+
order.save!
|
|
54
|
+
OrderMailer.confirmation(order).deliver_later
|
|
55
|
+
order
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Concerns
|
|
61
|
+
|
|
62
|
+
Use concerns to share behavior across models or controllers. Keep concerns focused on a single responsibility.
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
# app/models/concerns/searchable.rb
|
|
66
|
+
module Searchable
|
|
67
|
+
extend ActiveSupport::Concern
|
|
68
|
+
|
|
69
|
+
included do
|
|
70
|
+
scope :search, ->(query) { where("name ILIKE ?", "%#{query}%") }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## ActiveRecord Patterns
|
|
76
|
+
|
|
77
|
+
### Scopes over class methods for chainable queries
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
# Correct — scope
|
|
81
|
+
scope :active, -> { where(active: true) }
|
|
82
|
+
scope :recent, -> { order(created_at: :desc) }
|
|
83
|
+
|
|
84
|
+
# Wrong — class method for simple query
|
|
85
|
+
def self.active
|
|
86
|
+
where(active: true)
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Validations
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
# Use built-in validators
|
|
94
|
+
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
|
|
95
|
+
validates :age, numericality: { greater_than: 0 }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Callbacks — use sparingly
|
|
99
|
+
|
|
100
|
+
Prefer explicit service objects over callbacks for complex side effects. Callbacks are acceptable for simple data normalization.
|
|
101
|
+
|
|
102
|
+
```ruby
|
|
103
|
+
# Acceptable — simple normalization
|
|
104
|
+
before_validation :normalize_email
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def normalize_email
|
|
109
|
+
self.email = email&.downcase&.strip
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## N+1 Query Prevention
|
|
114
|
+
|
|
115
|
+
Always use `includes`, `preload`, or `eager_load` to prevent N+1 queries. The Bullet gem is included to detect these in development.
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
# Correct — eager loading
|
|
119
|
+
@posts = Post.includes(:author, :comments).where(published: true)
|
|
120
|
+
|
|
121
|
+
# Wrong — N+1 query
|
|
122
|
+
@posts = Post.where(published: true)
|
|
123
|
+
@posts.each { |post| post.author.name } # N+1!
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Strong Parameters
|
|
127
|
+
|
|
128
|
+
Always use strong parameters in controllers. Never use `permit!`.
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
# Correct
|
|
132
|
+
def order_params
|
|
133
|
+
params.require(:order).permit(:product_id, :quantity, :notes)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Wrong — permits everything
|
|
137
|
+
def order_params
|
|
138
|
+
params.require(:order).permit!
|
|
139
|
+
end
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Database Migrations
|
|
143
|
+
|
|
144
|
+
- Use `strong_migrations` gem constraints (included via Gemfile.lisa)
|
|
145
|
+
- Never modify `db/schema.rb` directly
|
|
146
|
+
- Always add indexes for foreign keys and commonly queried columns
|
|
147
|
+
- Use `change` method when the migration is reversible; use `up`/`down` when it is not
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
class AddIndexToOrdersUserId < ActiveRecord::Migration[7.2]
|
|
151
|
+
def change
|
|
152
|
+
add_index :orders, :user_id
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Testing with RSpec
|
|
158
|
+
|
|
159
|
+
- Use `let` and `let!` for test setup
|
|
160
|
+
- Use `described_class` instead of repeating the class name
|
|
161
|
+
- Use `factory_bot` for test data, not fixtures
|
|
162
|
+
- Use `shoulda-matchers` for model validation tests
|
|
163
|
+
- Keep tests focused — one assertion concept per example
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
RSpec.describe Order, type: :model do
|
|
167
|
+
describe "validations" do
|
|
168
|
+
it { is_expected.to validate_presence_of(:user) }
|
|
169
|
+
it { is_expected.to validate_numericality_of(:total).is_greater_than(0) }
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe ".recent" do
|
|
173
|
+
it "returns orders in descending creation order" do
|
|
174
|
+
old_order = create(:order, created_at: 1.day.ago)
|
|
175
|
+
new_order = create(:order, created_at: 1.hour.ago)
|
|
176
|
+
|
|
177
|
+
expect(described_class.recent).to eq([new_order, old_order])
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
```
|