@codyswann/lisa 4.74.9 → 4.75.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/.claude-plugin/marketplace.json +60 -0
- package/dist/core/lisa-skill-sources.d.ts +3 -3
- package/dist/core/lisa-skill-sources.d.ts.map +1 -1
- package/dist/core/lisa-skill-sources.js +3 -2
- package/dist/core/lisa-skill-sources.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +730 -5
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- 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-cdk-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-cdk-devin/skills/setup-aws-accounts/SKILL.md +292 -0
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-devin/.mcp.json +8 -0
- package/plugins/lisa-devin/agents/architecture-specialist.md +32 -0
- package/plugins/lisa-devin/agents/bug-fixer.md +43 -0
- package/plugins/lisa-devin/agents/builder.md +44 -0
- package/plugins/lisa-devin/agents/confluence-prd-intake.md +65 -0
- package/plugins/lisa-devin/agents/debug-specialist.md +34 -0
- package/plugins/lisa-devin/agents/eval-specialist.md +33 -0
- package/plugins/lisa-devin/agents/git-history-analyzer.md +183 -0
- package/plugins/lisa-devin/agents/github-agent.md +155 -0
- package/plugins/lisa-devin/agents/github-build-intake.md +64 -0
- package/plugins/lisa-devin/agents/github-prd-intake.md +66 -0
- package/plugins/lisa-devin/agents/jira-agent.md +135 -0
- package/plugins/lisa-devin/agents/jira-build-intake.md +64 -0
- package/plugins/lisa-devin/agents/learner.md +85 -0
- package/plugins/lisa-devin/agents/learning-judge.md +119 -0
- package/plugins/lisa-devin/agents/learnings-synthesizer.md +155 -0
- package/plugins/lisa-devin/agents/linear-agent.md +138 -0
- package/plugins/lisa-devin/agents/linear-build-intake.md +64 -0
- package/plugins/lisa-devin/agents/linear-prd-intake.md +66 -0
- package/plugins/lisa-devin/agents/notion-prd-intake.md +63 -0
- package/plugins/lisa-devin/agents/performance-specialist.md +26 -0
- package/plugins/lisa-devin/agents/pr-mining-specialist.md +85 -0
- package/plugins/lisa-devin/agents/product-specialist.md +30 -0
- package/plugins/lisa-devin/agents/quality-specialist.md +30 -0
- package/plugins/lisa-devin/agents/security-specialist.md +43 -0
- package/plugins/lisa-devin/agents/skill-evaluator.md +205 -0
- package/plugins/lisa-devin/agents/spec-conformance-specialist.md +56 -0
- package/plugins/lisa-devin/agents/test-specialist.md +32 -0
- package/plugins/lisa-devin/agents/tracker-mining-specialist.md +85 -0
- package/plugins/lisa-devin/agents/verification-specialist.md +145 -0
- package/plugins/lisa-devin/hooks/auto-update.mjs +824 -0
- package/plugins/lisa-devin/hooks/auto-update.sh +31 -0
- package/plugins/lisa-devin/hooks/block-blind-automerge.sh +1242 -0
- package/plugins/lisa-devin/hooks/block-direct-issue-create.sh +2603 -0
- package/plugins/lisa-devin/hooks/block-host-name-leak.mjs +412 -0
- package/plugins/lisa-devin/hooks/block-host-name-leak.sh +61 -0
- package/plugins/lisa-devin/hooks/block-instruction-file-edits.sh +207 -0
- package/plugins/lisa-devin/hooks/block-managed-file-edits.sh +1175 -0
- package/plugins/lisa-devin/hooks/block-no-verify.sh +2288 -0
- package/plugins/lisa-devin/hooks/block-shell-json-parsing.sh +263 -0
- package/plugins/lisa-devin/hooks/cleanup-stale-worktrees.sh +122 -0
- package/plugins/lisa-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-devin/hooks/discharge-work-item-gates.sh +90 -0
- package/plugins/lisa-devin/hooks/enforce-verification-gate.sh +506 -0
- package/plugins/lisa-devin/hooks/enforcement-vintage-npm.mjs +320 -0
- package/plugins/lisa-devin/hooks/enforcement-vintage.mjs +472 -0
- package/plugins/lisa-devin/hooks/enforcement-vintage.sh +48 -0
- package/plugins/lisa-devin/hooks/failure-signature-index.mjs +717 -0
- package/plugins/lisa-devin/hooks/failure-signature-index.sh +26 -0
- package/plugins/lisa-devin/hooks/guard-dedupe.bash +374 -0
- package/plugins/lisa-devin/hooks/inject-resolved-config.mjs +903 -0
- package/plugins/lisa-devin/hooks/inject-resolved-config.sh +107 -0
- package/plugins/lisa-devin/hooks/inject-rules.sh +49 -0
- package/plugins/lisa-devin/hooks/install-pkgs.sh +84 -0
- package/plugins/lisa-devin/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-devin/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-devin/hooks/parity-safety-net-heredoc.py +1004 -0
- package/plugins/lisa-devin/hooks/parity-safety-net.sh +3275 -0
- package/plugins/lisa-devin/hooks/secrets-preflight.sh +72 -0
- package/plugins/lisa-devin/hooks/setup-jira-cli.sh +205 -0
- package/plugins/lisa-devin/hooks/shell-write-nudge.sh +86 -0
- package/plugins/lisa-devin/hooks/sonar-secrets.sh +205 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet-compare.mjs +518 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet-families.mjs +543 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet.mjs +568 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet.sh +22 -0
- package/plugins/lisa-devin/hooks/withdrawn-rulings.mjs +600 -0
- package/plugins/lisa-devin/hooks/withdrawn-rulings.sh +24 -0
- package/plugins/lisa-devin/hooks/worktree-binding-guard.mjs +1383 -0
- package/plugins/lisa-devin/hooks/worktree-binding-guard.sh +79 -0
- package/plugins/lisa-devin/hooks.json +247 -0
- package/plugins/lisa-devin/rules/eager/00-rule-index.md +82 -0
- package/plugins/lisa-devin/rules/eager/base-rules.md +85 -0
- package/plugins/lisa-devin/rules/eager/coding-philosophy.md +27 -0
- package/plugins/lisa-devin/rules/eager/config-resolution.md +37 -0
- package/plugins/lisa-devin/rules/eager/do-it-now.md +11 -0
- package/plugins/lisa-devin/rules/eager/empirical-inquiry.md +24 -0
- package/plugins/lisa-devin/rules/eager/falsifiable-checks.md +48 -0
- package/plugins/lisa-devin/rules/eager/history-audit.md +27 -0
- package/plugins/lisa-devin/rules/eager/integration-access-layer.md +19 -0
- package/plugins/lisa-devin/rules/eager/intent-routing.md +18 -0
- package/plugins/lisa-devin/rules/eager/learnings-ladder.md +18 -0
- package/plugins/lisa-devin/rules/eager/local-ci-first.md +15 -0
- package/plugins/lisa-devin/rules/eager/measurement-integrity.md +18 -0
- package/plugins/lisa-devin/rules/eager/never-name-a-downstream-project.md +9 -0
- package/plugins/lisa-devin/rules/eager/not-blocked-just-waiting.md +13 -0
- package/plugins/lisa-devin/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa-devin/rules/eager/report-actionability.md +26 -0
- package/plugins/lisa-devin/rules/eager/security-audit-handling.md +40 -0
- package/plugins/lisa-devin/rules/eager/session-status-updates.md +20 -0
- package/plugins/lisa-devin/rules/eager/settled-decisions.md +75 -0
- package/plugins/lisa-devin/rules/eager/stale-state-claims.md +26 -0
- package/plugins/lisa-devin/rules/eager/tool-access-gate.md +23 -0
- package/plugins/lisa-devin/rules/eager/tracked-work.md +9 -0
- package/plugins/lisa-devin/rules/eager/upstream-to-lisa.md +14 -0
- package/plugins/lisa-devin/rules/eager/verification.md +33 -0
- package/plugins/lisa-devin/rules/eager/wiki-knowledge-source.md +13 -0
- package/plugins/lisa-devin/rules/eager/withdrawn-rulings.md +102 -0
- package/plugins/lisa-devin/rules/reference/automation-runbook-contract.md +355 -0
- package/plugins/lisa-devin/rules/reference/base-rules.md +136 -0
- package/plugins/lisa-devin/rules/reference/bdd-e2e-coverage.md +301 -0
- package/plugins/lisa-devin/rules/reference/blocker-containment.md +165 -0
- package/plugins/lisa-devin/rules/reference/claim-archaeology.md +184 -0
- package/plugins/lisa-devin/rules/reference/claim-evidence-mapping.md +362 -0
- package/plugins/lisa-devin/rules/reference/claim-time-guards.md +135 -0
- package/plugins/lisa-devin/rules/reference/coding-philosophy.md +428 -0
- package/plugins/lisa-devin/rules/reference/config-resolution.md +1225 -0
- package/plugins/lisa-devin/rules/reference/control-reachability.md +166 -0
- package/plugins/lisa-devin/rules/reference/convergent-review.md +145 -0
- package/plugins/lisa-devin/rules/reference/credential-substrate-precedence.md +249 -0
- package/plugins/lisa-devin/rules/reference/dependency-decision-records.md +177 -0
- package/plugins/lisa-devin/rules/reference/dependency-internalization-kit.md +244 -0
- package/plugins/lisa-devin/rules/reference/dependency-trust-classes.md +291 -0
- package/plugins/lisa-devin/rules/reference/deployed-state-readback.md +142 -0
- package/plugins/lisa-devin/rules/reference/derived-branch-plan.md +214 -0
- package/plugins/lisa-devin/rules/reference/design-source-of-truth.md +260 -0
- package/plugins/lisa-devin/rules/reference/design-value-binding.md +311 -0
- package/plugins/lisa-devin/rules/reference/do-it-now.md +19 -0
- package/plugins/lisa-devin/rules/reference/documentation-source-paths.md +31 -0
- package/plugins/lisa-devin/rules/reference/empirical-inquiry.md +28 -0
- package/plugins/lisa-devin/rules/reference/factory-model.md +111 -0
- package/plugins/lisa-devin/rules/reference/falsifiable-checks.md +275 -0
- package/plugins/lisa-devin/rules/reference/history-audit.md +42 -0
- package/plugins/lisa-devin/rules/reference/integration-access-layer.md +89 -0
- package/plugins/lisa-devin/rules/reference/intent-routing.md +428 -0
- package/plugins/lisa-devin/rules/reference/leaf-only-lifecycle.md +227 -0
- package/plugins/lisa-devin/rules/reference/learnings-ladder.md +41 -0
- package/plugins/lisa-devin/rules/reference/local-ci-first.md +34 -0
- package/plugins/lisa-devin/rules/reference/measurement-integrity.md +119 -0
- package/plugins/lisa-devin/rules/reference/never-name-a-downstream-project.md +37 -0
- package/plugins/lisa-devin/rules/reference/not-blocked-just-waiting.md +41 -0
- package/plugins/lisa-devin/rules/reference/observability-audit.md +146 -0
- package/plugins/lisa-devin/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa-devin/rules/reference/prd-definition-of-ready.md +118 -0
- package/plugins/lisa-devin/rules/reference/prd-lifecycle-rollup.md +192 -0
- package/plugins/lisa-devin/rules/reference/pre-flight-autofill.md +250 -0
- package/plugins/lisa-devin/rules/reference/project-learnings.md +159 -0
- package/plugins/lisa-devin/rules/reference/promotion-contract.md +148 -0
- package/plugins/lisa-devin/rules/reference/readiness-rubric.md +242 -0
- package/plugins/lisa-devin/rules/reference/ready-role-filing.md +212 -0
- package/plugins/lisa-devin/rules/reference/rejection-detection.md +308 -0
- package/plugins/lisa-devin/rules/reference/repo-scope-split.md +119 -0
- package/plugins/lisa-devin/rules/reference/report-actionability.md +61 -0
- package/plugins/lisa-devin/rules/reference/reset-seed-coverage.md +286 -0
- package/plugins/lisa-devin/rules/reference/security-audit-handling.md +55 -0
- package/plugins/lisa-devin/rules/reference/session-status-updates.md +111 -0
- package/plugins/lisa-devin/rules/reference/settled-decisions.md +39 -0
- package/plugins/lisa-devin/rules/reference/stale-state-claims.md +88 -0
- package/plugins/lisa-devin/rules/reference/tool-access-gate.md +114 -0
- package/plugins/lisa-devin/rules/reference/tracked-work.md +49 -0
- package/plugins/lisa-devin/rules/reference/upstream-to-lisa.md +26 -0
- package/plugins/lisa-devin/rules/reference/usage-accounting.md +261 -0
- package/plugins/lisa-devin/rules/reference/verification.md +278 -0
- package/plugins/lisa-devin/rules/reference/wiki-knowledge-source.md +37 -0
- package/plugins/lisa-devin/rules/reference/withdrawn-rulings.md +148 -0
- package/plugins/lisa-devin/rules/reference/work-item-definition-of-ready.md +177 -0
- package/plugins/lisa-devin/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa-devin/scripts/automation-run-record.mjs +678 -0
- package/plugins/lisa-devin/scripts/automation-status-claude-adapter.mjs +804 -0
- package/plugins/lisa-devin/scripts/automation-status-codex-adapter.mjs +1081 -0
- package/plugins/lisa-devin/scripts/automation-status-contract-drift.mjs +392 -0
- package/plugins/lisa-devin/scripts/automation-status-expected-fleet.mjs +508 -0
- package/plugins/lisa-devin/scripts/automation-status-report.mjs +200 -0
- package/plugins/lisa-devin/scripts/automation-status-run-history.mjs +216 -0
- package/plugins/lisa-devin/scripts/automation-status-unrecorded-runs.mjs +127 -0
- package/plugins/lisa-devin/scripts/blocker-edge-resolution.mjs +150 -0
- package/plugins/lisa-devin/scripts/cross-pollinate.mjs +763 -0
- package/plugins/lisa-devin/scripts/design-bindings-probe.mjs +713 -0
- package/plugins/lisa-devin/scripts/design-intake-gate.mjs +470 -0
- package/plugins/lisa-devin/scripts/design-source-gate.mjs +610 -0
- package/plugins/lisa-devin/scripts/design-variable-ids.mjs +567 -0
- package/plugins/lisa-devin/scripts/doctor-report.mjs +635 -0
- package/plugins/lisa-devin/scripts/install-remote-agent-aws.mjs +443 -0
- package/plugins/lisa-devin/scripts/intake-blocker-reprobe.mjs +1065 -0
- package/plugins/lisa-devin/scripts/intake-prework-denominator.mjs +249 -0
- package/plugins/lisa-devin/scripts/lifecycle-label-trust.mjs +593 -0
- package/plugins/lisa-devin/scripts/linear-state-write-target.mjs +362 -0
- package/plugins/lisa-devin/scripts/plugin-sync-explain.mjs +654 -0
- package/plugins/lisa-devin/scripts/pr-arming-sweep.mjs +561 -0
- package/plugins/lisa-devin/scripts/project-ideation-idempotency-harness.mjs +338 -0
- package/plugins/lisa-devin/scripts/qa-signal-lifecycle.mjs +523 -0
- package/plugins/lisa-devin/scripts/queue-contract-resolution.mjs +583 -0
- package/plugins/lisa-devin/scripts/queue-health-classification.mjs +157 -0
- package/plugins/lisa-devin/scripts/queue-status-build-readers.mjs +561 -0
- package/plugins/lisa-devin/scripts/queue-status-prd-readers.mjs +452 -0
- package/plugins/lisa-devin/scripts/remote-agent-aws-setup.sh +677 -0
- package/plugins/lisa-devin/scripts/repo-scope-vocabulary-audit.mjs +458 -0
- package/plugins/lisa-devin/scripts/resolve-lifecycle-role.mjs +347 -0
- package/plugins/lisa-devin/scripts/rollup-blocker-classification.mjs +616 -0
- package/plugins/lisa-devin/scripts/scoping-label-audit.mjs +474 -0
- package/plugins/lisa-devin/skills/lisa-acceptance-criteria/SKILL.md +73 -0
- package/plugins/lisa-devin/skills/lisa-agent-design-best-practices/SKILL.md +242 -0
- package/plugins/lisa-devin/skills/lisa-agent-ready/SKILL.md +271 -0
- package/plugins/lisa-devin/skills/lisa-analyze-claude-remote/SKILL.md +434 -0
- package/plugins/lisa-devin/skills/lisa-atlassian-access/SKILL.md +469 -0
- package/plugins/lisa-devin/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +236 -0
- package/plugins/lisa-devin/skills/lisa-attribute-failure/SKILL.md +142 -0
- package/plugins/lisa-devin/skills/lisa-automation-status/SKILL.md +149 -0
- package/plugins/lisa-devin/skills/lisa-bug-triage/SKILL.md +23 -0
- package/plugins/lisa-devin/skills/lisa-capability-drift/SKILL.md +71 -0
- package/plugins/lisa-devin/skills/lisa-codebase-research/SKILL.md +87 -0
- package/plugins/lisa-devin/skills/lisa-codify-verification/SKILL.md +213 -0
- package/plugins/lisa-devin/skills/lisa-confluence-prd-intake/SKILL.md +417 -0
- package/plugins/lisa-devin/skills/lisa-confluence-to-tracker/SKILL.md +469 -0
- package/plugins/lisa-devin/skills/lisa-confluence-write-prd/SKILL.md +111 -0
- package/plugins/lisa-devin/skills/lisa-cross-pollinate/SKILL.md +175 -0
- package/plugins/lisa-devin/skills/lisa-debrief/SKILL.md +96 -0
- package/plugins/lisa-devin/skills/lisa-debrief-apply/SKILL.md +106 -0
- package/plugins/lisa-devin/skills/lisa-delivery-effectiveness/SKILL.md +62 -0
- package/plugins/lisa-devin/skills/lisa-design-intake/SKILL.md +198 -0
- package/plugins/lisa-devin/skills/lisa-detect-tooling/SKILL.md +110 -0
- package/plugins/lisa-devin/skills/lisa-detect-tooling/scripts/commands.mjs +479 -0
- package/plugins/lisa-devin/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +658 -0
- package/plugins/lisa-devin/skills/lisa-doctor/SKILL.md +743 -0
- package/plugins/lisa-devin/skills/lisa-drive-pr-to-merge/SKILL.md +1587 -0
- package/plugins/lisa-devin/skills/lisa-epic-triage/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-evaluation-suite/SKILL.md +63 -0
- package/plugins/lisa-devin/skills/lisa-exploratory-qa/SKILL.md +185 -0
- package/plugins/lisa-devin/skills/lisa-fix-linter-error/SKILL.md +45 -0
- package/plugins/lisa-devin/skills/lisa-generate-claude-remote-build-script/SKILL.md +235 -0
- package/plugins/lisa-devin/skills/lisa-git-commit/SKILL.md +53 -0
- package/plugins/lisa-devin/skills/lisa-git-prune/SKILL.md +35 -0
- package/plugins/lisa-devin/skills/lisa-git-submit-pr/SKILL.md +170 -0
- package/plugins/lisa-devin/skills/lisa-github-add-journey/SKILL.md +118 -0
- package/plugins/lisa-devin/skills/lisa-github-build-intake/SKILL.md +745 -0
- package/plugins/lisa-devin/skills/lisa-github-claim/SKILL.md +27 -0
- package/plugins/lisa-devin/skills/lisa-github-create/SKILL.md +105 -0
- package/plugins/lisa-devin/skills/lisa-github-evidence/SKILL.md +120 -0
- package/plugins/lisa-devin/skills/lisa-github-journey/SKILL.md +134 -0
- package/plugins/lisa-devin/skills/lisa-github-prd-intake/SKILL.md +424 -0
- package/plugins/lisa-devin/skills/lisa-github-project-v2/SKILL.md +227 -0
- package/plugins/lisa-devin/skills/lisa-github-read-issue/SKILL.md +305 -0
- package/plugins/lisa-devin/skills/lisa-github-sync/SKILL.md +201 -0
- package/plugins/lisa-devin/skills/lisa-github-to-tracker/SKILL.md +456 -0
- package/plugins/lisa-devin/skills/lisa-github-validate-issue/SKILL.md +598 -0
- package/plugins/lisa-devin/skills/lisa-github-verify/SKILL.md +60 -0
- package/plugins/lisa-devin/skills/lisa-github-write-issue/SKILL.md +531 -0
- package/plugins/lisa-devin/skills/lisa-github-write-prd/SKILL.md +156 -0
- package/plugins/lisa-devin/skills/lisa-health/SKILL.md +142 -0
- package/plugins/lisa-devin/skills/lisa-health-drift-cron/SKILL.md +80 -0
- package/plugins/lisa-devin/skills/lisa-implement/SKILL.md +372 -0
- package/plugins/lisa-devin/skills/lisa-improve-code-complexity/SKILL.md +44 -0
- package/plugins/lisa-devin/skills/lisa-improve-harness/SKILL.md +487 -0
- package/plugins/lisa-devin/skills/lisa-improve-max-lines/SKILL.md +45 -0
- package/plugins/lisa-devin/skills/lisa-improve-max-lines-per-function/SKILL.md +46 -0
- package/plugins/lisa-devin/skills/lisa-improve-test-coverage/SKILL.md +47 -0
- package/plugins/lisa-devin/skills/lisa-improve-tests/SKILL.md +50 -0
- package/plugins/lisa-devin/skills/lisa-intake/SKILL.md +208 -0
- package/plugins/lisa-devin/skills/lisa-intake-explain/SKILL.md +279 -0
- package/plugins/lisa-devin/skills/lisa-jam-access/SKILL.md +128 -0
- package/plugins/lisa-devin/skills/lisa-jira-add-journey/SKILL.md +139 -0
- package/plugins/lisa-devin/skills/lisa-jira-build-intake/SKILL.md +556 -0
- package/plugins/lisa-devin/skills/lisa-jira-claim/SKILL.md +27 -0
- package/plugins/lisa-devin/skills/lisa-jira-create/SKILL.md +157 -0
- package/plugins/lisa-devin/skills/lisa-jira-evidence/SKILL.md +106 -0
- package/plugins/lisa-devin/skills/lisa-jira-evidence/scripts/post-evidence.sh +262 -0
- package/plugins/lisa-devin/skills/lisa-jira-journey/SKILL.md +168 -0
- package/plugins/lisa-devin/skills/lisa-jira-journey/scripts/generate-templates.py +239 -0
- package/plugins/lisa-devin/skills/lisa-jira-journey/scripts/parse-plan.py +570 -0
- package/plugins/lisa-devin/skills/lisa-jira-read-ticket/SKILL.md +199 -0
- package/plugins/lisa-devin/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +211 -0
- package/plugins/lisa-devin/skills/lisa-jira-sync/SKILL.md +117 -0
- package/plugins/lisa-devin/skills/lisa-jira-validate-ticket/SKILL.md +525 -0
- package/plugins/lisa-devin/skills/lisa-jira-verify/SKILL.md +61 -0
- package/plugins/lisa-devin/skills/lisa-jira-write-ticket/SKILL.md +440 -0
- package/plugins/lisa-devin/skills/lisa-jsdoc-best-practices/SKILL.md +491 -0
- package/plugins/lisa-devin/skills/lisa-kane-browser/SKILL.md +80 -0
- package/plugins/lisa-devin/skills/lisa-learnings-audit/SKILL.md +490 -0
- package/plugins/lisa-devin/skills/lisa-linear-access/SKILL.md +483 -0
- package/plugins/lisa-devin/skills/lisa-linear-add-journey/SKILL.md +109 -0
- package/plugins/lisa-devin/skills/lisa-linear-build-intake/SKILL.md +548 -0
- package/plugins/lisa-devin/skills/lisa-linear-claim/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-linear-create/SKILL.md +150 -0
- package/plugins/lisa-devin/skills/lisa-linear-evidence/SKILL.md +124 -0
- package/plugins/lisa-devin/skills/lisa-linear-journey/SKILL.md +147 -0
- package/plugins/lisa-devin/skills/lisa-linear-prd-intake/SKILL.md +411 -0
- package/plugins/lisa-devin/skills/lisa-linear-read-issue/SKILL.md +201 -0
- package/plugins/lisa-devin/skills/lisa-linear-sync/SKILL.md +164 -0
- package/plugins/lisa-devin/skills/lisa-linear-to-tracker/SKILL.md +454 -0
- package/plugins/lisa-devin/skills/lisa-linear-validate-issue/SKILL.md +504 -0
- package/plugins/lisa-devin/skills/lisa-linear-verify/SKILL.md +65 -0
- package/plugins/lisa-devin/skills/lisa-linear-write-issue/SKILL.md +448 -0
- package/plugins/lisa-devin/skills/lisa-linear-write-prd/SKILL.md +98 -0
- package/plugins/lisa-devin/skills/lisa-monitor/SKILL.md +224 -0
- package/plugins/lisa-devin/skills/lisa-nightly-add-test-coverage/SKILL.md +40 -0
- package/plugins/lisa-devin/skills/lisa-nightly-improve-tests/SKILL.md +29 -0
- package/plugins/lisa-devin/skills/lisa-nightly-lower-code-complexity/SKILL.md +42 -0
- package/plugins/lisa-devin/skills/lisa-notion-access/SKILL.md +301 -0
- package/plugins/lisa-devin/skills/lisa-notion-prd-intake/SKILL.md +360 -0
- package/plugins/lisa-devin/skills/lisa-notion-to-tracker/SKILL.md +467 -0
- package/plugins/lisa-devin/skills/lisa-notion-write-prd/SKILL.md +111 -0
- package/plugins/lisa-devin/skills/lisa-parity-code-review/SKILL.md +83 -0
- package/plugins/lisa-devin/skills/lisa-parity-code-simplifier/SKILL.md +76 -0
- package/plugins/lisa-devin/skills/lisa-parity-coderabbit/SKILL.md +87 -0
- package/plugins/lisa-devin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +375 -0
- package/plugins/lisa-devin/skills/lisa-parity-sentry-seer/SKILL.md +168 -0
- package/plugins/lisa-devin/skills/lisa-parity-skill-creator/SKILL.md +155 -0
- package/plugins/lisa-devin/skills/lisa-performance-review/SKILL.md +94 -0
- package/plugins/lisa-devin/skills/lisa-persist-learning/SKILL.md +247 -0
- package/plugins/lisa-devin/skills/lisa-plan/SKILL.md +64 -0
- package/plugins/lisa-devin/skills/lisa-plugin-sync-explain/SKILL.md +53 -0
- package/plugins/lisa-devin/skills/lisa-posthog-access/SKILL.md +140 -0
- package/plugins/lisa-devin/skills/lisa-prd-backlink/SKILL.md +274 -0
- package/plugins/lisa-devin/skills/lisa-prd-source-write/SKILL.md +104 -0
- package/plugins/lisa-devin/skills/lisa-prd-ticket-coverage/SKILL.md +187 -0
- package/plugins/lisa-devin/skills/lisa-product-walkthrough/SKILL.md +106 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/SKILL.md +417 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/evidence-card-format.md +21 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/host-project-only.md +22 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/idempotency-verification-harness.md +57 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/public-external-inspiration.md +22 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/unavailable-data-rejection.md +22 -0
- package/plugins/lisa-devin/skills/lisa-pull-request-review/SKILL.md +132 -0
- package/plugins/lisa-devin/skills/lisa-quality-review/SKILL.md +63 -0
- package/plugins/lisa-devin/skills/lisa-queue-status/SKILL.md +215 -0
- package/plugins/lisa-devin/skills/lisa-remote-dispatch/SKILL.md +109 -0
- package/plugins/lisa-devin/skills/lisa-remote-dispatch/scripts/dispatch.mjs +535 -0
- package/plugins/lisa-devin/skills/lisa-repair-intake/SKILL.md +1621 -0
- package/plugins/lisa-devin/skills/lisa-reproduce-bug/SKILL.md +75 -0
- package/plugins/lisa-devin/skills/lisa-research/SKILL.md +92 -0
- package/plugins/lisa-devin/skills/lisa-review-implementation/SKILL.md +209 -0
- package/plugins/lisa-devin/skills/lisa-review-local/SKILL.md +141 -0
- package/plugins/lisa-devin/skills/lisa-rework-triage/SKILL.md +206 -0
- package/plugins/lisa-devin/skills/lisa-root-cause-analysis/SKILL.md +135 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/SKILL.md +430 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +433 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +288 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +273 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/envfile.mjs +80 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/inspect-vault.mjs +142 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +1085 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/note-format.mjs +179 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/owner.mjs +96 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +342 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/prompt-secret.mjs +79 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/providers.mjs +805 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +680 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/read-secret-note.mjs +105 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/resolve-expo-token.mjs +90 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/resolve-secret.mjs +285 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/rotate-secret.mjs +297 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/routing-floor.mjs +153 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/surfaces.mjs +480 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +510 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/tools-from-notes.mjs +63 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/validate-config.mjs +550 -0
- package/plugins/lisa-devin/skills/lisa-security-review/SKILL.md +124 -0
- package/plugins/lisa-devin/skills/lisa-security-zap-scan/SKILL.md +53 -0
- package/plugins/lisa-devin/skills/lisa-sentry-access/SKILL.md +140 -0
- package/plugins/lisa-devin/skills/lisa-setup-atlassian/SKILL.md +407 -0
- package/plugins/lisa-devin/skills/lisa-setup-automations/SKILL.md +430 -0
- package/plugins/lisa-devin/skills/lisa-setup-automations/scripts/generate-workflow.mjs +288 -0
- package/plugins/lisa-devin/skills/lisa-setup-confluence/SKILL.md +254 -0
- package/plugins/lisa-devin/skills/lisa-setup-github/SKILL.md +319 -0
- package/plugins/lisa-devin/skills/lisa-setup-github-repo/SKILL.md +128 -0
- package/plugins/lisa-devin/skills/lisa-setup-jira/SKILL.md +198 -0
- package/plugins/lisa-devin/skills/lisa-setup-kane/SKILL.md +96 -0
- package/plugins/lisa-devin/skills/lisa-setup-linear/SKILL.md +375 -0
- package/plugins/lisa-devin/skills/lisa-setup-local-env/SKILL.md +95 -0
- package/plugins/lisa-devin/skills/lisa-setup-local-env/scripts/local-env.mjs +196 -0
- package/plugins/lisa-devin/skills/lisa-setup-notion/SKILL.md +376 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-aws/SKILL.md +149 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/SKILL.md +382 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/assets/materialized-env-authority.mjs +262 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/assets/session-start.sh +87 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/assets/setup.sh +216 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/environment.mjs +227 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +378 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +1632 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/tool-floor.mjs +94 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/toolchain.mjs +448 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +250 -0
- package/plugins/lisa-devin/skills/lisa-setup-sonar/SKILL.md +153 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/SKILL.md +143 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/bounded-child.mjs +168 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/catalogue.mjs +293 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/cli.mjs +333 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/workstation.mjs +511 -0
- package/plugins/lisa-devin/skills/lisa-sonarcloud-access/SKILL.md +202 -0
- package/plugins/lisa-devin/skills/lisa-spec-conformance/SKILL.md +205 -0
- package/plugins/lisa-devin/skills/lisa-starter-sync/SKILL.md +35 -0
- package/plugins/lisa-devin/skills/lisa-sync-down/SKILL.md +209 -0
- package/plugins/lisa-devin/skills/lisa-task-decomposition/SKILL.md +195 -0
- package/plugins/lisa-devin/skills/lisa-task-triage/SKILL.md +23 -0
- package/plugins/lisa-devin/skills/lisa-tdd-implementation/SKILL.md +91 -0
- package/plugins/lisa-devin/skills/lisa-tear-down-automations/SKILL.md +85 -0
- package/plugins/lisa-devin/skills/lisa-test-strategy/SKILL.md +66 -0
- package/plugins/lisa-devin/skills/lisa-ticket-triage/SKILL.md +214 -0
- package/plugins/lisa-devin/skills/lisa-track/SKILL.md +129 -0
- package/plugins/lisa-devin/skills/lisa-tracker-add-journey/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-tracker-build-intake/SKILL.md +134 -0
- package/plugins/lisa-devin/skills/lisa-tracker-claim/SKILL.md +35 -0
- package/plugins/lisa-devin/skills/lisa-tracker-create/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-tracker-evidence/SKILL.md +63 -0
- package/plugins/lisa-devin/skills/lisa-tracker-journey/SKILL.md +27 -0
- package/plugins/lisa-devin/skills/lisa-tracker-read/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-tracker-source-artifacts/SKILL.md +111 -0
- package/plugins/lisa-devin/skills/lisa-tracker-sync/SKILL.md +150 -0
- package/plugins/lisa-devin/skills/lisa-tracker-validate/SKILL.md +37 -0
- package/plugins/lisa-devin/skills/lisa-tracker-verify/SKILL.md +29 -0
- package/plugins/lisa-devin/skills/lisa-tracker-write/SKILL.md +55 -0
- package/plugins/lisa-devin/skills/lisa-usage-accounting/SKILL.md +205 -0
- package/plugins/lisa-devin/skills/lisa-usage-accounting/references/effectiveness.md +63 -0
- package/plugins/lisa-devin/skills/lisa-use-the-product/SKILL.md +86 -0
- package/plugins/lisa-devin/skills/lisa-validate-tracker-mapping/SKILL.md +467 -0
- package/plugins/lisa-devin/skills/lisa-verification-lifecycle/SKILL.md +384 -0
- package/plugins/lisa-devin/skills/lisa-verify/SKILL.md +55 -0
- package/plugins/lisa-devin/skills/lisa-verify-prd/SKILL.md +394 -0
- package/plugins/lisa-devin/skills/lisa-verify-workflow-change/SKILL.md +154 -0
- package/plugins/lisa-devin/skills/lisa-wiki-install/SKILL.md +101 -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-expo-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-expo-devin/.mcp.json +8 -0
- package/plugins/lisa-expo-devin/THIRD-PARTY-NOTICES.md +84 -0
- package/plugins/lisa-expo-devin/agents/ops-specialist.md +124 -0
- package/plugins/lisa-expo-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-expo-devin/hooks/register-maestro-mcp.sh +84 -0
- package/plugins/lisa-expo-devin/hooks.json +14 -0
- package/plugins/lisa-expo-devin/skills/add-app-clip/SKILL.md +280 -0
- package/plugins/lisa-expo-devin/skills/add-app-clip/references/native-module.md +96 -0
- package/plugins/lisa-expo-devin/skills/apollo-client/SKILL.md +238 -0
- package/plugins/lisa-expo-devin/skills/apollo-client/references/mutation-patterns.md +360 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/SKILL.md +369 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/scripts/test_validate_atomic_structure.py +240 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +438 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/SKILL.md +321 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/animations.md +220 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/controls.md +272 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/form-sheet.md +253 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/gradients.md +106 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/icons.md +213 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/media.md +198 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/route-structure.md +229 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/search.md +248 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/storage.md +121 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/tabs.md +433 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/visual-effects.md +197 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/webgpu-three.md +605 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/zoom-transitions.md +158 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/SKILL.md +355 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/references/examples.md +749 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/references/patterns.md +318 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/scripts/create_component.py +200 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/scripts/validate_component.py +332 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/SKILL.md +268 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/references/common-issues.md +619 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/references/platform-api.md +276 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +416 -0
- package/plugins/lisa-expo-devin/skills/directory-structure/SKILL.md +214 -0
- package/plugins/lisa-expo-devin/skills/directory-structure/scripts/validate_structure.py +454 -0
- package/plugins/lisa-expo-devin/skills/e2e-coverage-gaps/SKILL.md +117 -0
- package/plugins/lisa-expo-devin/skills/eas-update-insights/SKILL.md +228 -0
- package/plugins/lisa-expo-devin/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/plugins/lisa-expo-devin/skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/plugins/lisa-expo-devin/skills/expo-api-routes/SKILL.md +369 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/SKILL.md +54 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/comparison.md +63 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/SKILL.md +92 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/scripts/package.json +11 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/scripts/validate.js +85 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/SKILL.md +193 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/app-store-metadata.md +479 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/ios-app-store.md +355 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/play-store.md +264 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/testflight.md +58 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/workflows.md +200 -0
- package/plugins/lisa-expo-devin/skills/expo-dev-client/SKILL.md +164 -0
- package/plugins/lisa-expo-devin/skills/expo-env-config/SKILL.md +309 -0
- package/plugins/lisa-expo-devin/skills/expo-env-config/references/validation-patterns.md +417 -0
- package/plugins/lisa-expo-devin/skills/expo-module/SKILL.md +141 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/config-plugin.md +90 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/create-expo-module.md +206 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/lifecycle.md +127 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/module-config.md +48 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/native-module.md +286 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/native-view.md +171 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/SKILL.md +432 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/references/official-docs.md +290 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/references/static-export-verification.md +54 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/scripts/generate-route.py +171 -0
- package/plugins/lisa-expo-devin/skills/expo-tailwind-setup/SKILL.md +487 -0
- package/plugins/lisa-expo-devin/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
- package/plugins/lisa-expo-devin/skills/expo-ui-swift-ui/SKILL.md +39 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/SKILL.md +419 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/references/color-tokens.md +343 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/references/component-mapping.md +307 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/scripts/test_validate_styling.py +240 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/scripts/validate_styling.py +424 -0
- package/plugins/lisa-expo-devin/skills/jira-add-journey/SKILL.md +140 -0
- package/plugins/lisa-expo-devin/skills/jira-create/SKILL.md +161 -0
- package/plugins/lisa-expo-devin/skills/jira-evidence/SKILL.md +84 -0
- package/plugins/lisa-expo-devin/skills/jira-evidence/scripts/post-evidence.sh +262 -0
- package/plugins/lisa-expo-devin/skills/jira-journey/SKILL.md +196 -0
- package/plugins/lisa-expo-devin/skills/jira-journey/scripts/generate-templates.py +281 -0
- package/plugins/lisa-expo-devin/skills/jira-journey/scripts/parse-plan.py +400 -0
- package/plugins/lisa-expo-devin/skills/jira-verify/SKILL.md +27 -0
- package/plugins/lisa-expo-devin/skills/local-state/SKILL.md +362 -0
- package/plugins/lisa-expo-devin/skills/local-state/references/async-storage.md +505 -0
- package/plugins/lisa-expo-devin/skills/local-state/references/persistence-patterns.md +711 -0
- package/plugins/lisa-expo-devin/skills/local-state/references/reactive-variables.md +446 -0
- package/plugins/lisa-expo-devin/skills/maestro-mcp-setup/SKILL.md +144 -0
- package/plugins/lisa-expo-devin/skills/native-data-fetching/SKILL.md +507 -0
- package/plugins/lisa-expo-devin/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
- package/plugins/lisa-expo-devin/skills/ops-browser-uat/SKILL.md +124 -0
- package/plugins/lisa-expo-devin/skills/ops-check-logs/SKILL.md +217 -0
- package/plugins/lisa-expo-devin/skills/ops-db-ops/SKILL.md +214 -0
- package/plugins/lisa-expo-devin/skills/ops-deploy/SKILL.md +123 -0
- package/plugins/lisa-expo-devin/skills/ops-monitor-errors/SKILL.md +99 -0
- package/plugins/lisa-expo-devin/skills/ops-performance/SKILL.md +165 -0
- package/plugins/lisa-expo-devin/skills/ops-run-local/SKILL.md +169 -0
- package/plugins/lisa-expo-devin/skills/ops-verify-health/SKILL.md +101 -0
- package/plugins/lisa-expo-devin/skills/owasp-zap/SKILL.md +61 -0
- package/plugins/lisa-expo-devin/skills/play-store-access/SKILL.md +226 -0
- package/plugins/lisa-expo-devin/skills/playwright-ci-debugging/SKILL.md +140 -0
- package/plugins/lisa-expo-devin/skills/playwright-selectors/SKILL.md +496 -0
- package/plugins/lisa-expo-devin/skills/reduce-complexity/SKILL.md +251 -0
- package/plugins/lisa-expo-devin/skills/reduce-complexity/references/extraction-strategies.md +456 -0
- package/plugins/lisa-expo-devin/skills/reduce-complexity/references/refactoring-patterns.md +557 -0
- package/plugins/lisa-expo-devin/skills/testing-library/SKILL.md +314 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/async-patterns.md +420 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/expo-router-testing.md +556 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/mocking-patterns.md +612 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/query-priority.md +291 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/SKILL.md +134 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/native-tabs.md +124 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/new-architecture.md +79 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/react-19.md +79 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/react-compiler.md +59 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
- package/plugins/lisa-expo-devin/skills/use-dom/SKILL.md +417 -0
- 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-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-harper-fabric-devin/generated-artifact-globs.txt +5 -0
- package/plugins/lisa-harper-fabric-devin/hooks/block-generated-artifact-edits.sh +141 -0
- package/plugins/lisa-harper-fabric-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-harper-fabric-devin/hooks/enforce-config-extensions.mjs +196 -0
- package/plugins/lisa-harper-fabric-devin/hooks/enforce-config-extensions.sh +46 -0
- package/plugins/lisa-harper-fabric-devin/hooks/inject-rules.sh +27 -0
- package/plugins/lisa-harper-fabric-devin/hooks.json +36 -0
- package/plugins/lisa-harper-fabric-devin/rules/eager/harper-fabric.md +31 -0
- package/plugins/lisa-harper-fabric-devin/rules/reference/harper-fabric.md +52 -0
- package/plugins/lisa-harper-fabric-devin/skills/e2e-coverage-gaps/SKILL.md +117 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-auth/SKILL.md +368 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-build-and-deploy/SKILL.md +198 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-caching/SKILL.md +265 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-component-model/SKILL.md +87 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-config-yaml/SKILL.md +283 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-operations/SKILL.md +239 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-realtime/SKILL.md +187 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-resources/SKILL.md +142 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-rest-queries/SKILL.md +403 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-schema-graphql/SKILL.md +123 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-testing/SKILL.md +254 -0
- 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-nestjs-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-nestjs-devin/hooks/block-migration-edits.sh +125 -0
- package/plugins/lisa-nestjs-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-nestjs-devin/hooks/lisa-edit-gate.sh +152 -0
- package/plugins/lisa-nestjs-devin/hooks.json +15 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/SKILL.md +176 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/advanced-features.md +527 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/project-patterns.md +531 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/quick-start.md +257 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/types-scalars.md +513 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-rules/SKILL.md +560 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/SKILL.md +275 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/references/entity-patterns.md +450 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/references/observability-patterns.md +536 -0
- 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-openclaw-devin/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-repo-topic/SKILL.md +163 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-repo-topic/references/repo-topic-config.md +185 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-staff/SKILL.md +175 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-staff/references/platform-routing.md +123 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-staff/references/prompts.md +78 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-setup/SKILL.md +141 -0
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-phaser-devin/agents/accessibility-advocate.md +55 -0
- package/plugins/lisa-phaser-devin/agents/art-director.md +90 -0
- package/plugins/lisa-phaser-devin/agents/audio-director.md +65 -0
- package/plugins/lisa-phaser-devin/agents/combat-designer.md +61 -0
- package/plugins/lisa-phaser-devin/agents/economy-designer.md +59 -0
- package/plugins/lisa-phaser-devin/agents/game-designer.md +62 -0
- package/plugins/lisa-phaser-devin/agents/game-feel-specialist.md +56 -0
- package/plugins/lisa-phaser-devin/agents/level-designer.md +59 -0
- package/plugins/lisa-phaser-devin/agents/localization-manager.md +61 -0
- package/plugins/lisa-phaser-devin/agents/marketing-strategist.md +59 -0
- package/plugins/lisa-phaser-devin/agents/monetization-designer.md +59 -0
- package/plugins/lisa-phaser-devin/agents/narrative-designer.md +56 -0
- package/plugins/lisa-phaser-devin/agents/onboarding-advocate.md +59 -0
- package/plugins/lisa-phaser-devin/agents/player-advocate.md +57 -0
- package/plugins/lisa-phaser-devin/agents/producer.md +61 -0
- package/plugins/lisa-phaser-devin/agents/product-analyst.md +62 -0
- package/plugins/lisa-phaser-devin/agents/publisher.md +59 -0
- package/plugins/lisa-phaser-devin/agents/qa-playtester.md +57 -0
- package/plugins/lisa-phaser-devin/agents/target-player.md +52 -0
- package/plugins/lisa-phaser-devin/agents/ux-ui-designer.md +60 -0
- package/plugins/lisa-phaser-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-phaser-devin/hooks/inject-rules.sh +27 -0
- package/plugins/lisa-phaser-devin/hooks.json +14 -0
- package/plugins/lisa-phaser-devin/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-devin/rules/reference/phaser.md +184 -0
- package/plugins/lisa-phaser-devin/skills/phaser-accessibility/SKILL.md +135 -0
- package/plugins/lisa-phaser-devin/skills/phaser-asset-pipeline/SKILL.md +222 -0
- package/plugins/lisa-phaser-devin/skills/phaser-asset-sourcing/SKILL.md +151 -0
- package/plugins/lisa-phaser-devin/skills/phaser-build-deploy/SKILL.md +153 -0
- package/plugins/lisa-phaser-devin/skills/phaser-i18n/SKILL.md +122 -0
- package/plugins/lisa-phaser-devin/skills/phaser-project-structure/SKILL.md +89 -0
- package/plugins/lisa-phaser-devin/skills/phaser-services/SKILL.md +208 -0
- package/plugins/lisa-phaser-devin/skills/phaser-testing/SKILL.md +192 -0
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-rails-devin/agents/ops-specialist.md +226 -0
- package/plugins/lisa-rails-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-rails-devin/hooks/inject-rules.sh +40 -0
- package/plugins/lisa-rails-devin/hooks/lisa-edit-gate.sh +152 -0
- package/plugins/lisa-rails-devin/hooks/rubocop-on-edit.sh +101 -0
- package/plugins/lisa-rails-devin/hooks/sg-scan-on-edit.sh +97 -0
- package/plugins/lisa-rails-devin/hooks.json +29 -0
- package/plugins/lisa-rails-devin/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-devin/rules/reference/rails-conventions.md +176 -0
- package/plugins/lisa-rails-devin/skills/action-controller-best-practices/SKILL.md +374 -0
- package/plugins/lisa-rails-devin/skills/action-view-best-practices/SKILL.md +335 -0
- package/plugins/lisa-rails-devin/skills/active-record-model-best-practices/SKILL.md +166 -0
- package/plugins/lisa-rails-devin/skills/e2e-coverage-gaps/SKILL.md +117 -0
- package/plugins/lisa-rails-devin/skills/fix-linter-error/SKILL.md +45 -0
- package/plugins/lisa-rails-devin/skills/improve-code-complexity/SKILL.md +51 -0
- package/plugins/lisa-rails-devin/skills/improve-max-lines/SKILL.md +46 -0
- package/plugins/lisa-rails-devin/skills/improve-max-lines-per-function/SKILL.md +46 -0
- package/plugins/lisa-rails-devin/skills/improve-test-coverage/SKILL.md +48 -0
- package/plugins/lisa-rails-devin/skills/jira-add-journey/SKILL.md +79 -0
- package/plugins/lisa-rails-devin/skills/jira-create/SKILL.md +100 -0
- package/plugins/lisa-rails-devin/skills/jira-evidence/SKILL.md +76 -0
- package/plugins/lisa-rails-devin/skills/jira-evidence/scripts/post-evidence.sh +262 -0
- package/plugins/lisa-rails-devin/skills/jira-journey/SKILL.md +65 -0
- package/plugins/lisa-rails-devin/skills/jira-verify/SKILL.md +26 -0
- package/plugins/lisa-rails-devin/skills/ops-check-logs/SKILL.md +191 -0
- package/plugins/lisa-rails-devin/skills/ops-deploy/SKILL.md +153 -0
- package/plugins/lisa-rails-devin/skills/ops-run-local/SKILL.md +169 -0
- package/plugins/lisa-rails-devin/skills/ops-verify-jobs/SKILL.md +157 -0
- package/plugins/lisa-rails-devin/skills/ops-verify-telemetry/SKILL.md +226 -0
- 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-typescript-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-typescript-devin/hooks/block-suppress-directives.sh +141 -0
- package/plugins/lisa-typescript-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-typescript-devin/hooks/format-on-edit.sh +102 -0
- package/plugins/lisa-typescript-devin/hooks/lint-on-edit.sh +117 -0
- package/plugins/lisa-typescript-devin/hooks/lisa-edit-gate.sh +152 -0
- package/plugins/lisa-typescript-devin/hooks/sg-scan-on-edit.sh +94 -0
- package/plugins/lisa-typescript-devin/hooks.json +34 -0
- 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/lisa-wiki-devin/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-wiki-devin/ci/lisa-wiki-validate.yml +33 -0
- package/plugins/lisa-wiki-devin/schema/lisa-wiki-config.schema.json +162 -0
- package/plugins/lisa-wiki-devin/schema/wiki-structure.schema.json +51 -0
- package/plugins/lisa-wiki-devin/scripts/_wiki-lib.mjs +204 -0
- package/plugins/lisa-wiki-devin/scripts/diff-guard.mjs +117 -0
- package/plugins/lisa-wiki-devin/scripts/ensure-gitignore.mjs +131 -0
- package/plugins/lisa-wiki-devin/scripts/ensure-wiki.mjs +268 -0
- package/plugins/lisa-wiki-devin/scripts/ingest-git.mjs +198 -0
- package/plugins/lisa-wiki-devin/scripts/ingest-memory.mjs +135 -0
- package/plugins/lisa-wiki-devin/scripts/ingest-roles.mjs +95 -0
- package/plugins/lisa-wiki-devin/scripts/ingest_slack_channel.py +361 -0
- package/plugins/lisa-wiki-devin/scripts/lib/bounded-child.mjs +159 -0
- package/plugins/lisa-wiki-devin/scripts/lint-wiki.mjs +513 -0
- package/plugins/lisa-wiki-devin/scripts/mcp-doctor.mjs +72 -0
- package/plugins/lisa-wiki-devin/scripts/render-contract.mjs +107 -0
- package/plugins/lisa-wiki-devin/scripts/rewrite-refs.mjs +144 -0
- package/plugins/lisa-wiki-devin/scripts/slack_oauth_user.py +179 -0
- package/plugins/lisa-wiki-devin/scripts/validate-config.mjs +321 -0
- package/plugins/lisa-wiki-devin/scripts/verify-migration.mjs +203 -0
- package/plugins/lisa-wiki-devin/scripts/verify-wiki-safety.mjs +126 -0
- package/plugins/lisa-wiki-devin/scripts/wiki-safety.mjs +378 -0
- package/plugins/lisa-wiki-devin/scripts/wiki-status.mjs +345 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-add-ingest/SKILL.md +34 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-add-role/SKILL.md +35 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-confluence/SKILL.md +25 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-docs/SKILL.md +30 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-git/SKILL.md +25 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-jira/SKILL.md +28 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-memory/SKILL.md +28 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-notion/SKILL.md +25 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-roles/SKILL.md +22 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-slack/SKILL.md +30 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-web/SKILL.md +23 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-doctor/SKILL.md +47 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-ingest/SKILL.md +106 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-lint/SKILL.md +32 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-migrate/SKILL.md +43 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-onboard-me/SKILL.md +33 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-query/SKILL.md +40 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-setup/SKILL.md +75 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-setup-automations/SKILL.md +83 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-status/SKILL.md +47 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-tear-down-automations/SKILL.md +34 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-usage/SKILL.md +50 -0
- package/plugins/lisa-wiki-devin/templates/agents/role-agent.claude.md +16 -0
- package/plugins/lisa-wiki-devin/templates/agents/role-agent.codex.toml +15 -0
- package/plugins/lisa-wiki-devin/templates/index.md +17 -0
- package/plugins/lisa-wiki-devin/templates/llm-wiki-contract.md +72 -0
- package/plugins/lisa-wiki-devin/templates/log.md +8 -0
- package/plugins/lisa-wiki-devin/templates/page-types/architecture.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/concept.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/decision.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/entity.md +19 -0
- package/plugins/lisa-wiki-devin/templates/page-types/open-question.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/playbook.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/project.md +19 -0
- package/plugins/lisa-wiki-devin/templates/page-types/requirement.md +19 -0
- package/plugins/lisa-wiki-devin/templates/page-types/staff.md +26 -0
- package/plugins/lisa-wiki-devin/templates/start-here.md +24 -0
- package/plugins/lisa-wiki-devin/templates/state-readme.md +20 -0
- package/plugins/lisa-wiki-devin/templates/wrapper-gitignore.txt +19 -0
- package/scripts/build-plugins.sh +2 -2
- package/scripts/deployed-guard-advice.mjs +1 -0
- package/scripts/generate-devin-plugin-artifacts.mjs +263 -0
- package/scripts/lib/hook-registration-audit.mjs +3 -1
- package/scripts/lib/per-agent-hook-filter.mjs +174 -5
- package/scripts/lib/plugin-rule-citations.mjs +2 -2
|
@@ -0,0 +1,805 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Provider reads and boundary enforcement for `lisa-secrets-access`.
|
|
4
|
+
*
|
|
5
|
+
* Retrieval and selection are separated deliberately. `fetchRaw` is the only
|
|
6
|
+
* function that touches a provider; everything downstream operates on plain
|
|
7
|
+
* rows, which is what makes the boundary rules testable with synthetic data and
|
|
8
|
+
* without granting a test process access to any real secret.
|
|
9
|
+
* @module providers
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { listBootstrapFiles, readBootstrapFile } from "./bootstrap-store.mjs";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
boundedChildOutput,
|
|
16
|
+
isChildTimeout,
|
|
17
|
+
SETUP_OPERATION_BUDGET_MS,
|
|
18
|
+
rethrowIfChildTimeout,
|
|
19
|
+
} from "../../lisa-setup-workstation/scripts/bounded-child.mjs";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A provider key becomes a shell variable name on materializing surfaces, so
|
|
23
|
+
* only names valid in every POSIX-like shell are accepted. Anything else stays
|
|
24
|
+
* in the provider and is intentionally not exported.
|
|
25
|
+
*/
|
|
26
|
+
export const ENV_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The provider entry holding rotation leases.
|
|
30
|
+
*
|
|
31
|
+
* Leases live in the provider because it is the only substrate every surface
|
|
32
|
+
* shares — a CI concurrency group and a laptop lockfile cannot see each other,
|
|
33
|
+
* but both can see this. It is coordination state rather than a credential, so
|
|
34
|
+
* it is excluded from every selection: nothing should resolve or materialize it.
|
|
35
|
+
*/
|
|
36
|
+
export const LEASE_KEY = "LISA_ROTATION_LEASES";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Prefix reserved for provider-side coordination records.
|
|
40
|
+
*
|
|
41
|
+
* These records contain no credential material. They exist only long enough
|
|
42
|
+
* to serialize a provider mutation and must never cross the exposure boundary
|
|
43
|
+
* into a shell, file, hook, or CI environment.
|
|
44
|
+
*/
|
|
45
|
+
export const COORDINATION_KEY_PREFIX = "LISA_COORDINATION_";
|
|
46
|
+
|
|
47
|
+
const COORDINATION_VALUE = "coordination-only";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The environment variable each provider's CLI reads its own bootstrap from.
|
|
51
|
+
*
|
|
52
|
+
* This is deliberately *not* configurable, and separating it from
|
|
53
|
+
* `bootstrap.key` is the whole point. Two different questions were previously
|
|
54
|
+
* answered by one value:
|
|
55
|
+
*
|
|
56
|
+
* - **Where do we find the bootstrap?** A keychain service or environment
|
|
57
|
+
* variable name. That must be configurable, because one workstation serves
|
|
58
|
+
* several tenants and each needs its own token stored under its own name.
|
|
59
|
+
* - **What does the provider CLI call it?** Fixed by the vendor. `bws` reads
|
|
60
|
+
* `BWS_ACCESS_TOKEN` and nothing else.
|
|
61
|
+
*
|
|
62
|
+
* Conflating them worked only while every project used the default name, where
|
|
63
|
+
* the two happen to coincide. The moment a project set
|
|
64
|
+
* `bootstrap.key: "BWS_ACCESS_TOKEN_<tenant>"` the CLI was handed a variable it
|
|
65
|
+
* has never heard of and failed with "Missing access token".
|
|
66
|
+
*/
|
|
67
|
+
const PROVIDER_BOOTSTRAP_ENV = {
|
|
68
|
+
bitwarden: "BWS_ACCESS_TOKEN",
|
|
69
|
+
doppler: "DOPPLER_TOKEN",
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The tenant-scoped bootstrap variable a provider expects, by convention.
|
|
74
|
+
*
|
|
75
|
+
* Exists so the repo-less path cannot invent one. It used to compose
|
|
76
|
+
* `BWS_ACCESS_TOKEN_<namespace>` literally, ignoring the provider it had just
|
|
77
|
+
* resolved — so a Doppler tenant with no checkout was told to set a Bitwarden
|
|
78
|
+
* variable, and its CLI failed with "Missing access token". That is precisely
|
|
79
|
+
* the confusion the two questions above are separated to prevent, reintroduced
|
|
80
|
+
* on the one surface with no config file to correct it.
|
|
81
|
+
*
|
|
82
|
+
* `null` for a provider with no env-var bootstrap — 1Password, Vault and AWS
|
|
83
|
+
* authenticate by other means — because a name invented for them would be a
|
|
84
|
+
* variable nothing reads, which is worse than admitting there is none.
|
|
85
|
+
* `providerEnv` already treats an unmapped provider as "inject nothing".
|
|
86
|
+
* @param {string} provider Provider name.
|
|
87
|
+
* @param {string} namespace Tenant namespace.
|
|
88
|
+
* @returns {string|null} The variable to set, or null when the provider has none.
|
|
89
|
+
*/
|
|
90
|
+
export function bootstrapKeyFor(provider, namespace) {
|
|
91
|
+
const canonical = PROVIDER_BOOTSTRAP_ENV[provider];
|
|
92
|
+
return canonical ? `${canonical}_${namespace}` : null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Build the child environment for a provider CLI, injecting the bootstrap under
|
|
97
|
+
* the name that CLI actually reads.
|
|
98
|
+
*
|
|
99
|
+
* Both the read path and the rotation write path need this, and they previously
|
|
100
|
+
* carried separate copies of the same line — which is how they would eventually
|
|
101
|
+
* have drifted. One helper, one place to be wrong.
|
|
102
|
+
* @param {object} cfg Resolved configuration.
|
|
103
|
+
* @returns {NodeJS.ProcessEnv} Environment for the child process.
|
|
104
|
+
*/
|
|
105
|
+
export function providerEnv(cfg) {
|
|
106
|
+
const env = { ...process.env };
|
|
107
|
+
const canonical = PROVIDER_BOOTSTRAP_ENV[cfg.provider];
|
|
108
|
+
if (!canonical) return env;
|
|
109
|
+
const token = bootstrapToken(cfg.bootstrap);
|
|
110
|
+
if (token) env[canonical] = token;
|
|
111
|
+
// Drop the tenant-scoped name once its value has been placed under the one
|
|
112
|
+
// the CLI reads. Inheriting it would leave two variables holding the same
|
|
113
|
+
// bootstrap in the child, which is how a tool that probes for a
|
|
114
|
+
// similarly-named credential binds to the wrong tenant on a workstation
|
|
115
|
+
// serving several. The child needs exactly one.
|
|
116
|
+
if (cfg.bootstrap.key && cfg.bootstrap.key !== canonical) {
|
|
117
|
+
delete env[cfg.bootstrap.key];
|
|
118
|
+
}
|
|
119
|
+
return env;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Obtain the one credential that unlocks the provider.
|
|
124
|
+
*
|
|
125
|
+
* Walks `sources` in order, environment first, so a CI run where the pipeline
|
|
126
|
+
* injects the bootstrap never reaches for a local store. This is the only
|
|
127
|
+
* credential permitted in an OS keychain — it is a bootstrap, not a cached copy
|
|
128
|
+
* of anything downstream.
|
|
129
|
+
* @param {{sources: string[], key: string|null}} bootstrap Bootstrap config.
|
|
130
|
+
* @returns {string|null} The token, or null when the provider needs none.
|
|
131
|
+
*/
|
|
132
|
+
export function bootstrapToken(bootstrap) {
|
|
133
|
+
if (!bootstrap.key) return null;
|
|
134
|
+
for (const source of bootstrap.sources) {
|
|
135
|
+
const found =
|
|
136
|
+
source === "env"
|
|
137
|
+
? (process.env[bootstrap.key] ?? "").trim()
|
|
138
|
+
: source === "keychain"
|
|
139
|
+
? fromKeychain(bootstrap.key)
|
|
140
|
+
: "";
|
|
141
|
+
if (found) return found;
|
|
142
|
+
}
|
|
143
|
+
throw new Error(describeMissingBootstrap(bootstrap));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The name Lisa looked up, reduced to the provider prefix it was built from.
|
|
148
|
+
*
|
|
149
|
+
* `BWS_ACCESS_TOKEN_lisa` → `BWS_ACCESS_TOKEN`. Used to find the SIBLINGS of a
|
|
150
|
+
* missing key: names that differ only in their tenant suffix are the ones an
|
|
151
|
+
* operator can actually point this project at.
|
|
152
|
+
* @param {string} key The bootstrap variable name that was looked up.
|
|
153
|
+
* @returns {string} The provider prefix, or the key when it carries no suffix.
|
|
154
|
+
*/
|
|
155
|
+
function bootstrapPrefix(key) {
|
|
156
|
+
for (const canonical of Object.values(PROVIDER_BOOTSTRAP_ENV)) {
|
|
157
|
+
if (key === canonical || key.startsWith(`${canonical}_`)) return canonical;
|
|
158
|
+
}
|
|
159
|
+
return key;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Keychain SERVICE NAMES on this machine. Never a password.
|
|
164
|
+
*
|
|
165
|
+
* `dump-keychain` without `-d` prints metadata only, so this cannot carry a
|
|
166
|
+
* credential into an error message. Bounded and wrapped: it runs on a path that
|
|
167
|
+
* is already failing, where a throw would replace the real message with its own
|
|
168
|
+
* and a hang would replace it with nothing.
|
|
169
|
+
* @returns {string[]} Service names, or empty when unavailable.
|
|
170
|
+
*/
|
|
171
|
+
function keychainServiceNames() {
|
|
172
|
+
if (process.platform !== "darwin") return [];
|
|
173
|
+
try {
|
|
174
|
+
const dump = boundedChildOutput("security", ["dump-keychain"], {
|
|
175
|
+
encoding: "utf8",
|
|
176
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
177
|
+
timeout: 5000,
|
|
178
|
+
});
|
|
179
|
+
return [...String(dump).matchAll(/"svce"<blob>="([^"]*)"/g)].map(
|
|
180
|
+
([, name]) => name
|
|
181
|
+
);
|
|
182
|
+
} catch {
|
|
183
|
+
// probe-direction: neutral — the names only enrich a diagnostic message on a
|
|
184
|
+
// path that has already failed; no verdict reads them.
|
|
185
|
+
// A locked, absent, or oversized keychain leaves the list empty.
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Bootstrap NAMES this machine holds under the same provider prefix.
|
|
192
|
+
*
|
|
193
|
+
* Names only — no value is read, and none is ever reported.
|
|
194
|
+
*
|
|
195
|
+
* Every source is injectable because the alternative is a test that asserts
|
|
196
|
+
* against whatever credentials the developer's own workstation happens to hold.
|
|
197
|
+
* Such a test passes or fails by accident, and it fails on the one machine that
|
|
198
|
+
* reproduces the bug (CodySwannGT/lisa#3555).
|
|
199
|
+
* @param {string} prefix Provider bootstrap prefix, e.g. `BWS_ACCESS_TOKEN`.
|
|
200
|
+
* @param {object} [deps] Injected sources for testing.
|
|
201
|
+
* @returns {Array<{name: string, where: string}>} What exists, sorted by name.
|
|
202
|
+
*/
|
|
203
|
+
export function discoverBootstrapNames(prefix, deps = {}) {
|
|
204
|
+
const env = deps.env ?? process.env;
|
|
205
|
+
const matches = name => name === prefix || name.startsWith(`${prefix}_`);
|
|
206
|
+
const found = new Map();
|
|
207
|
+
const note = (name, where) => {
|
|
208
|
+
if (matches(name) && !found.has(name)) found.set(name, where);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
for (const name of Object.keys(env)) {
|
|
212
|
+
if ((env[name] ?? "").trim()) note(name, "env");
|
|
213
|
+
}
|
|
214
|
+
for (const name of (deps.listFiles ?? listBootstrapFiles)()) {
|
|
215
|
+
note(name, "bootstrap file");
|
|
216
|
+
}
|
|
217
|
+
for (const name of (deps.keychainNames ?? keychainServiceNames)()) {
|
|
218
|
+
note(name, "keychain");
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return [...found.entries()]
|
|
222
|
+
.map(([name, where]) => ({ name, where }))
|
|
223
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Whether the provider's own CLI is resolvable on PATH.
|
|
228
|
+
*
|
|
229
|
+
* Asked because the failure this message replaces was read as a MISSING BINARY
|
|
230
|
+
* by two separate sessions, one of which turned that reading into a standing
|
|
231
|
+
* instruction telling other agents not to bother installing it. The binary was
|
|
232
|
+
* on PATH the whole time. Stating which of the two is true costs one
|
|
233
|
+
* `command -v` and removes the wrong reading entirely.
|
|
234
|
+
*
|
|
235
|
+
* **Presence only, and the message says exactly that.** `command -v` proves the
|
|
236
|
+
* name resolves, never that the binary runs, is the right architecture, or is
|
|
237
|
+
* authorised. Reporting it as "installed and working" would be a second
|
|
238
|
+
* confidently-worded overclaim in the same message whose first overclaim is the
|
|
239
|
+
* defect being fixed. Actually proving "working" means executing the provider
|
|
240
|
+
* CLI on a path that is already failing, which is a cost and a side effect this
|
|
241
|
+
* diagnostic has no business incurring.
|
|
242
|
+
* @param {string} prefix Provider bootstrap prefix.
|
|
243
|
+
* @returns {boolean|null} PATH presence, or null when the provider has no CLI.
|
|
244
|
+
*/
|
|
245
|
+
export function providerCliPresent(prefix) {
|
|
246
|
+
const cli = { BWS_ACCESS_TOKEN: "bws", DOPPLER_TOKEN: "doppler" }[prefix];
|
|
247
|
+
if (!cli) return null;
|
|
248
|
+
try {
|
|
249
|
+
return Boolean(
|
|
250
|
+
String(
|
|
251
|
+
boundedChildOutput("command", ["-v", cli], {
|
|
252
|
+
encoding: "utf8",
|
|
253
|
+
shell: true,
|
|
254
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
255
|
+
timeout: 5000,
|
|
256
|
+
})
|
|
257
|
+
).trim()
|
|
258
|
+
);
|
|
259
|
+
} catch {
|
|
260
|
+
// probe-direction: neutral — PATH presence is reported in the explanation of
|
|
261
|
+
// an already-failing lookup; it gates nothing on its own.
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Explain a bootstrap that was not found, distinguishing the two causes.
|
|
268
|
+
*
|
|
269
|
+
* The message this replaces was accurate and still produced a wrong conclusion
|
|
270
|
+
* twice, because it answered only "what was missing" and never "what is here".
|
|
271
|
+
* Lisa looks up `<PREFIX>_<namespace>` where the namespace defaults to the
|
|
272
|
+
* project's own name, so a workstation holding one credential provisioned for
|
|
273
|
+
* one project fails closed in every OTHER project — and reads, from inside
|
|
274
|
+
* those projects, as though the provider were unavailable on the machine.
|
|
275
|
+
* @param {{sources: string[], key: string}} bootstrap Bootstrap config.
|
|
276
|
+
* @param {object} [deps] Injected sources for testing.
|
|
277
|
+
* @returns {string} The operator-facing explanation.
|
|
278
|
+
*/
|
|
279
|
+
export function describeMissingBootstrap(bootstrap, deps = {}) {
|
|
280
|
+
const prefix = bootstrapPrefix(bootstrap.key);
|
|
281
|
+
const siblings = (deps.discover ?? discoverBootstrapNames)(
|
|
282
|
+
prefix,
|
|
283
|
+
deps
|
|
284
|
+
).filter(entry => entry.name !== bootstrap.key);
|
|
285
|
+
const cli = (deps.cliPresent ?? providerCliPresent)(prefix);
|
|
286
|
+
|
|
287
|
+
const lines = [
|
|
288
|
+
`${bootstrap.key} not found in: ${bootstrap.sources.join(", ")}.`,
|
|
289
|
+
`It is the bootstrap credential — without it no other secret can be read.`,
|
|
290
|
+
``,
|
|
291
|
+
];
|
|
292
|
+
|
|
293
|
+
if (siblings.length === 0) {
|
|
294
|
+
lines.push(
|
|
295
|
+
`No bootstrap credential of any name was found on this machine, so none`,
|
|
296
|
+
`is provisioned here yet. Store one with:`,
|
|
297
|
+
``,
|
|
298
|
+
` lisa secrets bootstrap --key ${bootstrap.key}`
|
|
299
|
+
);
|
|
300
|
+
} else {
|
|
301
|
+
lines.push(
|
|
302
|
+
`This is a NAME MISMATCH, not a missing credential. ${siblings.length === 1 ? "A bootstrap credential exists" : "Bootstrap credentials exist"} here`,
|
|
303
|
+
`under ${siblings.length === 1 ? "a different name" : "different names"}:`,
|
|
304
|
+
``,
|
|
305
|
+
...siblings.map(entry => ` ${entry.name} (${entry.where})`),
|
|
306
|
+
``,
|
|
307
|
+
`Lisa looks up ${prefix}_<namespace>, where <namespace> defaults to this`,
|
|
308
|
+
`project's own name — so a credential provisioned for one project is not`,
|
|
309
|
+
`found from any other. Point this project at an existing one by setting`,
|
|
310
|
+
`its name in .lisa.config.json:`,
|
|
311
|
+
``,
|
|
312
|
+
` { "secrets": { "bootstrap": { "key": "${siblings[0].name}" } } }`,
|
|
313
|
+
``,
|
|
314
|
+
`or by exporting ${bootstrap.key} in the environment.`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (cli !== null) {
|
|
319
|
+
lines.push(``);
|
|
320
|
+
lines.push(
|
|
321
|
+
...(cli
|
|
322
|
+
? [
|
|
323
|
+
`The provider CLI was found on PATH, so this is not a missing-binary`,
|
|
324
|
+
`problem and reinstalling it will not help. Only the credential NAME`,
|
|
325
|
+
`is wrong.`,
|
|
326
|
+
]
|
|
327
|
+
: [
|
|
328
|
+
`Separately, the provider CLI was NOT found on PATH. Both that and the`,
|
|
329
|
+
`credential name above need resolving.`,
|
|
330
|
+
])
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return lines.join("\n");
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Read one value from this machine's credential store, treating absence as
|
|
339
|
+
* empty.
|
|
340
|
+
*
|
|
341
|
+
* The `keychain` source names a role, not a macOS API: "wherever this machine
|
|
342
|
+
* keeps its bootstrap". On macOS that is the keychain. Elsewhere there is no
|
|
343
|
+
* store that can be assumed present — libsecret needs a daemon and a desktop
|
|
344
|
+
* session, which a server or container does not have — so it is a `0600` file,
|
|
345
|
+
* the same protection the materialized secrets file already relies on.
|
|
346
|
+
*
|
|
347
|
+
* Returning empty on the other platform, as this did before, meant a Linux
|
|
348
|
+
* machine could store a bootstrap and never read it back.
|
|
349
|
+
* @param {string} key Bootstrap variable name.
|
|
350
|
+
* @returns {string} The value, or an empty string when unavailable.
|
|
351
|
+
*/
|
|
352
|
+
function fromKeychain(key) {
|
|
353
|
+
try {
|
|
354
|
+
// Inside the `try`, not before it. `readBootstrapFile` uses `readFileSync`,
|
|
355
|
+
// which throws on a permission error, on EISDIR, and when the file is
|
|
356
|
+
// removed between the existence check and the read. This function's
|
|
357
|
+
// contract is to return empty when the value is unavailable, and
|
|
358
|
+
// `bootstrapToken` has no handler — so a raw filesystem error would
|
|
359
|
+
// replace the curated "not found in: ..." message with a stack trace.
|
|
360
|
+
if (process.platform !== "darwin") return readBootstrapFile(key);
|
|
361
|
+
return boundedChildOutput(
|
|
362
|
+
"security",
|
|
363
|
+
["find-generic-password", "-s", key, "-a", process.env.USER ?? "", "-w"],
|
|
364
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }
|
|
365
|
+
).trim();
|
|
366
|
+
} catch (error) {
|
|
367
|
+
// A killed child must not read as "this provider has no such
|
|
368
|
+
// secret" — that is a claim about the vault, and the caller acts on it.
|
|
369
|
+
rethrowIfChildTimeout(error);
|
|
370
|
+
return "";
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Read every secret the provider grants, as unfiltered rows.
|
|
376
|
+
*
|
|
377
|
+
* Deliberately reads all rather than one: the provider already scopes what this
|
|
378
|
+
* caller may see, so the set it returns *is* the permitted set. Restating that
|
|
379
|
+
* as a list in config would duplicate a boundary the provider already enforces.
|
|
380
|
+
* @param {object} cfg Resolved configuration.
|
|
381
|
+
* @returns {Array<{key: string, value: string, note: string, projectId: string|null, id?: string|null, creationDate?: string|null, revisionDate?: string|null}>} Rows.
|
|
382
|
+
*/
|
|
383
|
+
export function fetchRaw(cfg) {
|
|
384
|
+
const env = providerEnv(cfg);
|
|
385
|
+
|
|
386
|
+
if (cfg.provider === "env") {
|
|
387
|
+
return Object.entries(process.env)
|
|
388
|
+
.filter(([k]) => /^[A-Z][A-Z0-9_]*$/.test(k))
|
|
389
|
+
.map(([key, value]) => ({
|
|
390
|
+
key,
|
|
391
|
+
value: value ?? "",
|
|
392
|
+
note: "",
|
|
393
|
+
projectId: null,
|
|
394
|
+
}));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (cfg.provider === "bitwarden") {
|
|
398
|
+
const raw = run(
|
|
399
|
+
"bws",
|
|
400
|
+
["secret", "list", "--output", "json"],
|
|
401
|
+
env,
|
|
402
|
+
"reading secrets from Bitwarden"
|
|
403
|
+
);
|
|
404
|
+
return JSON.parse(raw || "[]").map(s => ({
|
|
405
|
+
key: s.key,
|
|
406
|
+
value: s.value,
|
|
407
|
+
note: s.note ?? "",
|
|
408
|
+
projectId: s.projectId ?? null,
|
|
409
|
+
id: s.id ?? null,
|
|
410
|
+
creationDate: s.creationDate ?? null,
|
|
411
|
+
revisionDate: s.revisionDate ?? null,
|
|
412
|
+
}));
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (cfg.provider === "doppler") {
|
|
416
|
+
const args = ["secrets", "download", "--no-file", "--format", "json"];
|
|
417
|
+
const raw = run("doppler", args, env, "reading secrets from Doppler");
|
|
418
|
+
return Object.entries(JSON.parse(raw || "{}")).map(([key, value]) => ({
|
|
419
|
+
key,
|
|
420
|
+
value: String(value),
|
|
421
|
+
note: "",
|
|
422
|
+
projectId: null,
|
|
423
|
+
}));
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
throw new Error(
|
|
427
|
+
`provider "${cfg.provider}" has no bulk read implemented yet.\n` +
|
|
428
|
+
`Add one in providers.mjs — see the dispatch table in SKILL.md.`
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* The argument vector a provider CLI is actually spawned with.
|
|
434
|
+
*
|
|
435
|
+
* `bws` 2.1.0 colours its output even into a pipe and ignores `NO_COLOR`,
|
|
436
|
+
* `TERM=dumb` and `CLICOLOR=0` alike, so `bws secret list --output json`
|
|
437
|
+
* arrives as ANSI-wrapped JSON and `JSON.parse` fails on the first escape
|
|
438
|
+
* byte — for EVERY secret, including a known-good control. Its own `--color`
|
|
439
|
+
* flag is the one switch it honours, and it is a global option that must
|
|
440
|
+
* precede the subcommand. It is applied here rather than at each call site
|
|
441
|
+
* because a call site that forgets it reproduces the outage in silence.
|
|
442
|
+
* @param {string} bin Executable name.
|
|
443
|
+
* @param {readonly string[]} args Arguments the caller composed.
|
|
444
|
+
* @returns {string[]} Arguments with the CLI's colour switched off.
|
|
445
|
+
*/
|
|
446
|
+
export function providerArgs(bin, args) {
|
|
447
|
+
return bin === "bws" ? ["--color", "no", ...args] : [...args];
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Run a provider CLI, keeping its output off any shared stream.
|
|
452
|
+
* @param {string} bin Executable name.
|
|
453
|
+
* @param {string[]} args Arguments.
|
|
454
|
+
* @param {NodeJS.ProcessEnv} env Environment for the child.
|
|
455
|
+
* @returns {string} Captured stdout.
|
|
456
|
+
*/
|
|
457
|
+
function run(bin, args, env, operation = "talking to the secrets provider") {
|
|
458
|
+
try {
|
|
459
|
+
return boundedChildOutput(bin, providerArgs(bin, args), {
|
|
460
|
+
encoding: "utf8",
|
|
461
|
+
env,
|
|
462
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
463
|
+
// THE OPERATION BUDGET, not the probe budget (#4045). Passing none fell
|
|
464
|
+
// back to `CHILD_BUDGET_MS`, which its own docstring calls "a hang
|
|
465
|
+
// detector, not a performance budget" — while the sibling budget's
|
|
466
|
+
// docstring names "secret-provider calls" explicitly. A round trip to a
|
|
467
|
+
// hosted vault over someone's network is neither a hang nor a local
|
|
468
|
+
// probe, and this is the one function every Bitwarden and Doppler call
|
|
469
|
+
// in the tree passes through.
|
|
470
|
+
timeout: PROVIDER_BUDGET_MS,
|
|
471
|
+
});
|
|
472
|
+
} catch (error) {
|
|
473
|
+
const timedOut = describeProviderTimeout(bin, operation, error);
|
|
474
|
+
// Rethrow UNCHANGED when it is not a timeout. Relabelling every failure as
|
|
475
|
+
// a deadline would be this defect with the sign flipped: a genuinely
|
|
476
|
+
// missing binary would then read as a slow one.
|
|
477
|
+
if (timedOut === null) throw error;
|
|
478
|
+
throw new Error(timedOut);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* The deadline a provider CLI call is given.
|
|
484
|
+
*
|
|
485
|
+
* `SETUP_OPERATION_BUDGET_MS` rather than `CHILD_BUDGET_MS`, because
|
|
486
|
+
* `bounded-child.mjs` documents that budget as covering "downloads, package
|
|
487
|
+
* installation, secret-provider calls, or a project-declared hook", and the
|
|
488
|
+
* probe budget as a hang detector. Re-exported under a local name so the value
|
|
489
|
+
* a message quotes and the value the call enforces cannot drift apart.
|
|
490
|
+
*/
|
|
491
|
+
export const PROVIDER_BUDGET_MS = SETUP_OPERATION_BUDGET_MS;
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* An operator-readable account of a provider CLI killed at its deadline.
|
|
495
|
+
*
|
|
496
|
+
* ## What the old message did
|
|
497
|
+
*
|
|
498
|
+
* The entire operator-facing output was `spawnSync bws ETIMEDOUT` — a binary
|
|
499
|
+
* name and an errno, which is the exact shape Node produces for `ENOENT`.
|
|
500
|
+
* MEASURED: every reader concluded the binary was missing or broken. In the
|
|
501
|
+
* reported session `bws 2.1.0` was installed and answering in 365–725 ms, a
|
|
502
|
+
* direct `bws secret list` succeeded moments later, and the operator was one
|
|
503
|
+
* step from routing live work to `blocked` over a working credential path.
|
|
504
|
+
*
|
|
505
|
+
* ## What this says instead, and why each part is there
|
|
506
|
+
*
|
|
507
|
+
* The operation, so the reader knows what was in flight. That the CLI RAN, in
|
|
508
|
+
* as many words, because that is the belief being corrected. The deadline and
|
|
509
|
+
* whose it is — an operator needs both: the number tells them whether a retry
|
|
510
|
+
* is plausible, and "Lisa's" tells them the vault reported nothing at all. A
|
|
511
|
+
* next step, because a message at a gate that a non-technical operator cannot
|
|
512
|
+
* act on is not finished.
|
|
513
|
+
*
|
|
514
|
+
* Returns null for anything that is not a killed child, so the caller rethrows
|
|
515
|
+
* the original untouched.
|
|
516
|
+
* @param {string} bin The provider executable that was run.
|
|
517
|
+
* @param {string} operation What the call was doing, in operator words.
|
|
518
|
+
* @param {unknown} error The caught value.
|
|
519
|
+
* @returns {string|null} The message, or null when this is not a timeout.
|
|
520
|
+
*/
|
|
521
|
+
export function describeProviderTimeout(bin, operation, error) {
|
|
522
|
+
if (!isChildTimeout(error)) return null;
|
|
523
|
+
const seconds = Math.round(PROVIDER_BUDGET_MS / 1000);
|
|
524
|
+
return (
|
|
525
|
+
`${operation}: the \`${bin}\` CLI ran for ${seconds}s and Lisa stopped it ` +
|
|
526
|
+
`at its own deadline. This is NOT a missing or broken \`${bin}\` — the ` +
|
|
527
|
+
`binary was found and started, which is what separates this from the ` +
|
|
528
|
+
`similar-looking "spawnSync ${bin} ENOENT" you get when it is absent. The ` +
|
|
529
|
+
`deadline is Lisa's, so the provider reported nothing either way: no ` +
|
|
530
|
+
`secret was read, and nothing says your vault is unreachable. Most often ` +
|
|
531
|
+
`this is transient network latency — retry the command, and if it keeps ` +
|
|
532
|
+
`hitting the deadline check that \`${bin}\` answers on its own before ` +
|
|
533
|
+
`concluding the credential path is unavailable.`
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Apply the exposure boundary and reject an ambiguous set.
|
|
539
|
+
*
|
|
540
|
+
* The provider's own scoping is the default allowlist. The optional controls
|
|
541
|
+
* may only *narrow* it — there is intentionally no way to widen access from
|
|
542
|
+
* config, because that boundary belongs to the provider grant.
|
|
543
|
+
*
|
|
544
|
+
* A duplicate exact-name key is fatal rather than last-wins. Silently choosing
|
|
545
|
+
* one would make which credential gets used depend on provider response order,
|
|
546
|
+
* which is neither stable nor visible at the call site.
|
|
547
|
+
* @param {Array<object>} rows Raw provider rows.
|
|
548
|
+
* @param {{projectIds: string[], excludeKeys: string[]}} narrow Narrowing controls.
|
|
549
|
+
* @returns {Map<string, {value: string, note: string, id: string|null, projectId: string|null, creationDate: string|null, revisionDate: string|null}>} Selected secrets by name.
|
|
550
|
+
*/
|
|
551
|
+
export function normalizeRows(
|
|
552
|
+
rows,
|
|
553
|
+
narrow = { projectIds: [], excludeKeys: [] }
|
|
554
|
+
) {
|
|
555
|
+
const projects = new Set(narrow.projectIds ?? []);
|
|
556
|
+
const excluded = new Set([...(narrow.excludeKeys ?? []), LEASE_KEY]);
|
|
557
|
+
const out = new Map();
|
|
558
|
+
|
|
559
|
+
for (const row of rows) {
|
|
560
|
+
if (projects.size && !projects.has(row.projectId)) continue;
|
|
561
|
+
if (
|
|
562
|
+
typeof row.key === "string" &&
|
|
563
|
+
row.key.startsWith(COORDINATION_KEY_PREFIX)
|
|
564
|
+
) {
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
if (typeof row.key !== "string" || !ENV_KEY.test(row.key)) continue;
|
|
568
|
+
if (excluded.has(row.key)) continue;
|
|
569
|
+
if (out.has(row.key)) {
|
|
570
|
+
throw new Error(
|
|
571
|
+
`duplicate secret key across visible projects: ${row.key}.\n` +
|
|
572
|
+
`Resolve it at the provider — choosing one here would make credential ` +
|
|
573
|
+
`use depend on response order.`
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
if (typeof row.value !== "string") {
|
|
577
|
+
throw new Error(`secret value is not a string: ${row.key}`);
|
|
578
|
+
}
|
|
579
|
+
out.set(row.key, {
|
|
580
|
+
value: row.value,
|
|
581
|
+
note: row.note ?? "",
|
|
582
|
+
id: row.id ?? null,
|
|
583
|
+
projectId: row.projectId ?? null,
|
|
584
|
+
creationDate: row.creationDate ?? null,
|
|
585
|
+
revisionDate: row.revisionDate ?? null,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
return out;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Apply the reviewed `secrets.require` allowlist to the ordinary provider view.
|
|
593
|
+
*
|
|
594
|
+
* Omitted `require` keeps the provider grant as the boundary. Once a project
|
|
595
|
+
* names a required set, every other visible record is outside that project's
|
|
596
|
+
* declared need and must not resolve or materialize. Missing required names are
|
|
597
|
+
* refused here rather than becoming a smaller, apparently successful view.
|
|
598
|
+
* @param {Map<string, {value: string, note: string, id: string|null}>} selected Provider rows after grant narrowing.
|
|
599
|
+
* @param {string[]|null|undefined} required Exact required names, or no project allowlist.
|
|
600
|
+
* @returns {Map<string, {value: string, note: string, id: string|null}>} The declared provider view.
|
|
601
|
+
*/
|
|
602
|
+
export function selectRequired(selected, required) {
|
|
603
|
+
if (required === null || required === undefined) return selected;
|
|
604
|
+
|
|
605
|
+
const missing = required.filter(name => !selected.has(name));
|
|
606
|
+
if (missing.length > 0) {
|
|
607
|
+
throw new Error(
|
|
608
|
+
`required secret${missing.length === 1 ? "" : "s"} not found: ` +
|
|
609
|
+
`${missing.join(", ")}.\n` +
|
|
610
|
+
`Check the provider grant, secrets.narrow, and the exact names in ` +
|
|
611
|
+
`secrets.require.`
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
return new Map(required.map(name => [name, selected.get(name)]));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Read the provider grant through the ordinary narrowing controls, then expose
|
|
620
|
+
* exactly the names authorised by one consumer.
|
|
621
|
+
*
|
|
622
|
+
* This does not widen the provider grant and deliberately does not reuse
|
|
623
|
+
* `cfg.require`: that declaration controls ordinary resolution and
|
|
624
|
+
* materialization, while specialized consumers such as propagation carry
|
|
625
|
+
* their own reviewed exact-name authorization. Keeping those views separate
|
|
626
|
+
* prevents a propagating-only credential from being written to a materialized
|
|
627
|
+
* secrets file merely to make the propagation command able to read it.
|
|
628
|
+
*
|
|
629
|
+
* Provider retrieval itself remains bounded by the provider account's grant.
|
|
630
|
+
* Supported bulk-read providers return that granted view before this process
|
|
631
|
+
* applies the narrower consumer allowlist.
|
|
632
|
+
* @param {object} cfg Resolved configuration.
|
|
633
|
+
* @param {string[]|null|undefined} required Exact names authorised for this consumer.
|
|
634
|
+
* @returns {Map<string, {value: string, note: string, id: string|null}>} The consumer-specific provider view.
|
|
635
|
+
*/
|
|
636
|
+
export function fetchNamed(cfg, required) {
|
|
637
|
+
return selectRequired(normalizeRows(fetchRaw(cfg), cfg.narrow), required);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Read and select in one step — the normal entry point for consumers.
|
|
642
|
+
* @param {object} cfg Resolved configuration.
|
|
643
|
+
* @returns {Map<string, {value: string, note: string, id: string|null}>} Selected secrets.
|
|
644
|
+
*/
|
|
645
|
+
export function fetchAll(cfg) {
|
|
646
|
+
return fetchNamed(cfg, cfg.require);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* The provider view the rotation path reads.
|
|
651
|
+
*
|
|
652
|
+
* `excludeKeys` keeps a credential off a **surface's disk**. Applying it here
|
|
653
|
+
* too hid the provider record, making `rotating` and `excludeKeys` mutually
|
|
654
|
+
* exclusive — and a credential you cannot see is one you cannot write back to.
|
|
655
|
+
* That is backwards for a consumable credential: the kind you least want
|
|
656
|
+
* materialized is the kind that most needs a proven write path.
|
|
657
|
+
*
|
|
658
|
+
* Nothing here materializes anything. `fetchAll` remains the only view feeding
|
|
659
|
+
* a surface, so an excluded rotating credential still never reaches disk.
|
|
660
|
+
* @param {object} cfg Resolved configuration.
|
|
661
|
+
* @returns {Map<string, {value: string, note: string, id: string|null}>} Selected secrets by name.
|
|
662
|
+
*/
|
|
663
|
+
export function fetchRotatable(cfg) {
|
|
664
|
+
return normalizeRows(fetchRaw(cfg), rotationNarrow(cfg));
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Narrowing for the rotation view: project grants intact, `excludeKeys` waived
|
|
669
|
+
* for declared rotating names only.
|
|
670
|
+
*
|
|
671
|
+
* The waiver reaches only names in `secrets.rotating` — config, and therefore
|
|
672
|
+
* reviewed, the same declared-never-inferred rule the write path enforces.
|
|
673
|
+
* Project narrowing is the provider's own boundary and is never widened. Split
|
|
674
|
+
* from {@link fetchRotatable} so the decision is testable without a provider.
|
|
675
|
+
* @param {object} cfg Resolved configuration.
|
|
676
|
+
* @returns {{projectIds: string[], excludeKeys: string[]}} Narrowing controls.
|
|
677
|
+
*/
|
|
678
|
+
export function rotationNarrow(cfg) {
|
|
679
|
+
const rotating = new Set(cfg.rotating ?? []);
|
|
680
|
+
return {
|
|
681
|
+
projectIds: cfg.narrow?.projectIds ?? [],
|
|
682
|
+
excludeKeys: (cfg.narrow?.excludeKeys ?? []).filter(
|
|
683
|
+
key => !rotating.has(key)
|
|
684
|
+
),
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Find one raw row by exact key, bypassing the exposure boundary.
|
|
690
|
+
*
|
|
691
|
+
* Only the rotation path uses this, and only to reach the lease record, which
|
|
692
|
+
* is deliberately excluded from every normal selection. Reading a *credential*
|
|
693
|
+
* must always go through {@link fetchAll} so the boundary applies.
|
|
694
|
+
* @param {object} cfg Resolved configuration.
|
|
695
|
+
* @param {string} key Exact key name.
|
|
696
|
+
* @returns {object|null} The raw row, or null when absent.
|
|
697
|
+
*/
|
|
698
|
+
export function rawByKey(cfg, key) {
|
|
699
|
+
const matches = fetchRaw(cfg).filter(row => row.key === key);
|
|
700
|
+
if (matches.length > 1) throw new Error(`duplicate secret key: ${key}`);
|
|
701
|
+
return matches[0] ?? null;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Write a replacement value back to the provider.
|
|
706
|
+
*
|
|
707
|
+
* Passing a value as an argument is normally forbidden, because process
|
|
708
|
+
* arguments are visible to anyone who can run `ps` on the same host. The
|
|
709
|
+
* Bitwarden CLI exposes no stdin path for an edit, so this is a documented
|
|
710
|
+
* exception rather than an oversight: it is confined to the one operation that
|
|
711
|
+
* cannot be expressed otherwise, and `execFileSync` at least keeps the value
|
|
712
|
+
* out of a shell and therefore out of shell history.
|
|
713
|
+
* @param {object} cfg Resolved configuration.
|
|
714
|
+
* @param {string} id Provider-side identifier for the secret.
|
|
715
|
+
* @param {string} value Replacement value.
|
|
716
|
+
*/
|
|
717
|
+
export function writeSecret(cfg, id, value) {
|
|
718
|
+
const env = providerEnv(cfg);
|
|
719
|
+
|
|
720
|
+
if (cfg.provider === "bitwarden") {
|
|
721
|
+
run(
|
|
722
|
+
"bws",
|
|
723
|
+
["secret", "edit", id, "--value", value],
|
|
724
|
+
env,
|
|
725
|
+
"updating a secret in Bitwarden"
|
|
726
|
+
);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
throw new Error(
|
|
730
|
+
`provider "${cfg.provider}" has no write implemented.\n` +
|
|
731
|
+
`Rotation requires a proven write path; add one in providers.mjs.`
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Create one provider-issued publication contender in the target project.
|
|
737
|
+
*
|
|
738
|
+
* The deliberately constrained interface accepts no value: coordination
|
|
739
|
+
* records always contain the same public sentinel, which prevents this helper
|
|
740
|
+
* from becoming an alternate credential-write path.
|
|
741
|
+
* @param {object} cfg Resolved configuration.
|
|
742
|
+
* @param {string} key Unique coordination key.
|
|
743
|
+
* @param {string} projectId Project containing the target provider record.
|
|
744
|
+
* @param {string} note Non-sensitive lifecycle metadata.
|
|
745
|
+
* @returns {object} The provider-issued coordination row.
|
|
746
|
+
*/
|
|
747
|
+
export function createCoordinationRecord(cfg, key, projectId, note) {
|
|
748
|
+
const env = providerEnv(cfg);
|
|
749
|
+
|
|
750
|
+
if (cfg.provider === "bitwarden") {
|
|
751
|
+
const raw = run(
|
|
752
|
+
"bws",
|
|
753
|
+
[
|
|
754
|
+
"secret",
|
|
755
|
+
"create",
|
|
756
|
+
key,
|
|
757
|
+
COORDINATION_VALUE,
|
|
758
|
+
projectId,
|
|
759
|
+
"--note",
|
|
760
|
+
note,
|
|
761
|
+
"--output",
|
|
762
|
+
"json",
|
|
763
|
+
],
|
|
764
|
+
env,
|
|
765
|
+
"creating a coordination record in Bitwarden"
|
|
766
|
+
);
|
|
767
|
+
const created = JSON.parse(raw);
|
|
768
|
+
return {
|
|
769
|
+
key: created.key,
|
|
770
|
+
value: created.value,
|
|
771
|
+
note: created.note ?? "",
|
|
772
|
+
projectId: created.projectId ?? null,
|
|
773
|
+
id: created.id ?? null,
|
|
774
|
+
creationDate: created.creationDate ?? null,
|
|
775
|
+
revisionDate: created.revisionDate ?? null,
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
throw new Error(
|
|
779
|
+
`provider "${cfg.provider}" has no coordination-record creation implemented.\n` +
|
|
780
|
+
`AWS bootstrap publication requires a provider-backed single-writer lock.`
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Remove one provider-side coordination record by its provider identifier.
|
|
786
|
+
* @param {object} cfg Resolved configuration.
|
|
787
|
+
* @param {string} id Provider-side identifier for the coordination record.
|
|
788
|
+
*/
|
|
789
|
+
export function removeCoordinationRecord(cfg, id) {
|
|
790
|
+
const env = providerEnv(cfg);
|
|
791
|
+
|
|
792
|
+
if (cfg.provider === "bitwarden") {
|
|
793
|
+
run(
|
|
794
|
+
"bws",
|
|
795
|
+
["secret", "delete", id, "--output", "none"],
|
|
796
|
+
env,
|
|
797
|
+
"deleting a secret in Bitwarden"
|
|
798
|
+
);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
throw new Error(
|
|
802
|
+
`provider "${cfg.provider}" has no coordination-record deletion implemented.\n` +
|
|
803
|
+
`AWS bootstrap publication requires verified lock cleanup.`
|
|
804
|
+
);
|
|
805
|
+
}
|