@codyswann/lisa 4.74.9 → 4.75.1
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/all/copy-overwrite/scripts/lib/npm-update-github.mjs +73 -40
- package/all/copy-overwrite/scripts/lib/npm-update-invariants.mjs +54 -0
- package/all/copy-overwrite/scripts/npm-updater-helper-graph.json +3 -2
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +6 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- 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 +735 -8
- 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,903 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Put the RESOLVED Lisa configuration in front of the agent, so reading it is
|
|
4
|
+
* not a decision anyone can decline to make.
|
|
5
|
+
*
|
|
6
|
+
* ## The defect this exists against
|
|
7
|
+
*
|
|
8
|
+
* Projects keep "missing" `.lisa.config.json`. The file is present and
|
|
9
|
+
* correct; agents act against what it declares anyway. The file is not
|
|
10
|
+
* missing — it is unread.
|
|
11
|
+
*
|
|
12
|
+
* The mechanism is visible in what SessionStart already ships. `inject-rules.sh`
|
|
13
|
+
* injects RULE TEXT through `hookSpecificOutput.additionalContext`. Nothing
|
|
14
|
+
* injected the resolved VALUES. So an agent received a paragraph saying that
|
|
15
|
+
* configuration lives in a file, and then had to decide, unprompted, to go read
|
|
16
|
+
* that file. That decision is the step that gets skipped.
|
|
17
|
+
*
|
|
18
|
+
* ## Why this is not more prose
|
|
19
|
+
*
|
|
20
|
+
* `config-resolution.md` is already an EAGER rule — auto-loaded into every
|
|
21
|
+
* session — and it already opens with the words "load-bearing". Nine eager
|
|
22
|
+
* rules already name `.lisa.config.json`. A tenth assertion added to a stack
|
|
23
|
+
* that is demonstrably being read past is not a fix; this repository's own
|
|
24
|
+
* measurement is that executable controls land at 100% and prose rules at
|
|
25
|
+
* roughly zero. An agent cannot skip reading what is already in its context.
|
|
26
|
+
*
|
|
27
|
+
* ## Three properties, none of them decoration
|
|
28
|
+
*
|
|
29
|
+
* 1. RESOLVED, not declared. `.lisa.config.local.json` overrides
|
|
30
|
+
* `.lisa.config.json` where they overlap, so nobody can compute an effective
|
|
31
|
+
* value by reading one file — which is part of why the read gets skipped.
|
|
32
|
+
* 2. DECLARED vs DEFAULTED is marked. Without it, a silently absent or
|
|
33
|
+
* partial config is indistinguishable from one that happens to agree with
|
|
34
|
+
* Lisa's built-ins, and a gap has no symptom at all.
|
|
35
|
+
* 3. NO CONFIG is stated out loud. Emitting nothing when there is no config is
|
|
36
|
+
* the original failure mode wearing a new hat.
|
|
37
|
+
*
|
|
38
|
+
* ## Bounded, because this lands in every session
|
|
39
|
+
*
|
|
40
|
+
* {@link CONTEXT_BUDGET} caps the rendered body. Collections are summarised
|
|
41
|
+
* rather than dumped, and `gates` — the largest block in a real config, and the
|
|
42
|
+
* one an agent most often violates — gets its own renderer that groups gate ids
|
|
43
|
+
* by moment and level instead of truncating the list. What does not fit is
|
|
44
|
+
* counted, never silently dropped.
|
|
45
|
+
*
|
|
46
|
+
* ## Fail soft, always
|
|
47
|
+
*
|
|
48
|
+
* Every exit is 0. A malformed or unreadable config emits one line saying so
|
|
49
|
+
* and continues; a hook that kills session start is worse than the problem it
|
|
50
|
+
* was added to solve.
|
|
51
|
+
* @module inject-resolved-config
|
|
52
|
+
*/
|
|
53
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
54
|
+
import { basename, join } from "node:path";
|
|
55
|
+
import { fileURLToPath } from "node:url";
|
|
56
|
+
|
|
57
|
+
/** Committed, project-wide configuration. */
|
|
58
|
+
const MAIN_CONFIG = ".lisa.config.json";
|
|
59
|
+
/** Gitignored per-developer overrides. Wins where the two overlap. */
|
|
60
|
+
const LOCAL_CONFIG = ".lisa.config.local.json";
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Character budget for the rendered value body.
|
|
64
|
+
*
|
|
65
|
+
* This block is injected into EVERY session and every subagent, so it competes
|
|
66
|
+
* with the work for context. 4000 characters is roughly one page: enough for a
|
|
67
|
+
* mature project's full identity, lifecycle, gate and policy picture (this
|
|
68
|
+
* repository's own config renders to about 3KB), and small enough that it can
|
|
69
|
+
* never crowd out the task. Over budget, rendering stops and the number of
|
|
70
|
+
* unrendered keys is reported — a silent truncation would reintroduce exactly
|
|
71
|
+
* the invisible-gap failure this hook exists to remove.
|
|
72
|
+
*/
|
|
73
|
+
const CONTEXT_BUDGET = 4000;
|
|
74
|
+
|
|
75
|
+
/** Most children of one parent object rendered before summarising the rest. */
|
|
76
|
+
const MAX_CHILDREN = 12;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Longest single rendered line.
|
|
80
|
+
*
|
|
81
|
+
* {@link MAX_CHILDREN} bounds how MANY values a line carries, not how long each
|
|
82
|
+
* one is, so a config holding a dozen long strings under one parent could
|
|
83
|
+
* otherwise emit a single line that consumed most of {@link CONTEXT_BUDGET} on
|
|
84
|
+
* its own — and the budget check, which reads a line as indivisible, would let
|
|
85
|
+
* it through whole.
|
|
86
|
+
*/
|
|
87
|
+
const MAX_LINE = 400;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The gate-level vocabulary, copied from `LEVELS` in
|
|
91
|
+
* `all/copy-overwrite/scripts/lisa-gates.mjs` (a shipped script this hook
|
|
92
|
+
* cannot import from inside a host project's plugin payload), and pinned
|
|
93
|
+
* against the real export by this hook's unit test.
|
|
94
|
+
*
|
|
95
|
+
* It is how a MOMENT is recognised without copying the moment vocabulary too:
|
|
96
|
+
* a gate's `pull-request` key resolves to one of these and a gate's `run` key
|
|
97
|
+
* resolves to a task name, so the levels alone separate the two. Copying the
|
|
98
|
+
* smaller list also means a new moment family reaches this renderer for free.
|
|
99
|
+
*/
|
|
100
|
+
const LEVELS = new Set(["required", "optional", "off"]);
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Words that make a key identity- or credential-shaped.
|
|
104
|
+
*
|
|
105
|
+
* Matched against each path segment after splitting on `_`, `-`, `.` and
|
|
106
|
+
* camelCase boundaries, so `atlassian.email`, `apiKey`, `bypass_actors` and
|
|
107
|
+
* `githubToken` are all caught by a single-word entry.
|
|
108
|
+
*
|
|
109
|
+
* Deliberately broad. The instruction for an unclear key is to OMIT it: a
|
|
110
|
+
* config value withheld from context costs one file read, and an identity or
|
|
111
|
+
* credential injected into context cannot be withdrawn. Adding a word here is
|
|
112
|
+
* always safe; removing one is a security change.
|
|
113
|
+
*/
|
|
114
|
+
const SENSITIVE_WORDS = new Set([
|
|
115
|
+
"account",
|
|
116
|
+
"actor",
|
|
117
|
+
"actors",
|
|
118
|
+
"apikey",
|
|
119
|
+
"arn",
|
|
120
|
+
"auth",
|
|
121
|
+
"authorization",
|
|
122
|
+
"bearer",
|
|
123
|
+
"cert",
|
|
124
|
+
"certificate",
|
|
125
|
+
"connection",
|
|
126
|
+
"cookie",
|
|
127
|
+
"credential",
|
|
128
|
+
"credentials",
|
|
129
|
+
"dsn",
|
|
130
|
+
"email",
|
|
131
|
+
"identity",
|
|
132
|
+
"jwt",
|
|
133
|
+
"key",
|
|
134
|
+
"keys",
|
|
135
|
+
"login",
|
|
136
|
+
"mail",
|
|
137
|
+
"mfa",
|
|
138
|
+
"oauth",
|
|
139
|
+
"otp",
|
|
140
|
+
"passphrase",
|
|
141
|
+
"passwd",
|
|
142
|
+
"password",
|
|
143
|
+
"pat",
|
|
144
|
+
"pem",
|
|
145
|
+
"pin",
|
|
146
|
+
"private",
|
|
147
|
+
"secret",
|
|
148
|
+
"session",
|
|
149
|
+
"signature",
|
|
150
|
+
"token",
|
|
151
|
+
"totp",
|
|
152
|
+
"user",
|
|
153
|
+
"username",
|
|
154
|
+
"webhook",
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Second line of defence: a value that LOOKS like a developer identity is
|
|
159
|
+
* redacted wherever it appears, whatever key it arrived under.
|
|
160
|
+
*
|
|
161
|
+
* {@link SENSITIVE_WORDS} guards the keys that exist today. This guards the
|
|
162
|
+
* ones added tomorrow by someone who never read this file.
|
|
163
|
+
*
|
|
164
|
+
* `=` and `,` are excluded from both sides deliberately. `\b[^\s@]+@...`
|
|
165
|
+
* swallows the `key=` prefix a rendered line puts in front of the value, so the
|
|
166
|
+
* redaction erased WHICH key had been redacted — and, worse, made a test
|
|
167
|
+
* asserting the key name was absent pass even with the key-name filter removed.
|
|
168
|
+
*/
|
|
169
|
+
const EMAIL_SHAPED = /[^\s@,=]+@[^\s@,=]+\.[^\s@,=]+/g;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Value shapes that are a credential whatever key they arrived under.
|
|
173
|
+
*
|
|
174
|
+
* {@link SENSITIVE_WORDS} can only ever cover key names somebody thought of.
|
|
175
|
+
* {@link SUBTREE_ORDER} is a SUBTREE allowlist, so a key added under an
|
|
176
|
+
* already-listed parent reaches every session with nobody reviewing it — which
|
|
177
|
+
* is the case these patterns exist for, and the reason the preamble's sentence
|
|
178
|
+
* was made to describe this mechanism rather than promise more than it has.
|
|
179
|
+
*
|
|
180
|
+
* Each pattern is anchored on a structural marker (a scheme with a
|
|
181
|
+
* `user:password@` userinfo, a vendor key prefix, three base64url segments),
|
|
182
|
+
* never on entropy. An entropy heuristic would redact ids a config legitimately
|
|
183
|
+
* carries — routine ids, revisions, digests — and this block exists to make
|
|
184
|
+
* configuration visible, so a false redaction is a real cost, not a free one.
|
|
185
|
+
*/
|
|
186
|
+
const CREDENTIAL_SHAPED = [
|
|
187
|
+
// A private key pasted into a config value.
|
|
188
|
+
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
189
|
+
// Credentials in a connection string's userinfo. The whole URL goes: the
|
|
190
|
+
// host is not worth keeping at the price of splicing a line back together
|
|
191
|
+
// around the part that was cut out. Neither userinfo field may contain `/`,
|
|
192
|
+
// because a path separator means the text is a path and not userinfo:
|
|
193
|
+
// `https://host:8443/repos/main@v2` otherwise reads as password `8443/repos/
|
|
194
|
+
// main` at host `v2`, and an ordinary URL is redacted whole.
|
|
195
|
+
/\b[a-z][a-z0-9+.-]*:\/\/[^\s:@,=/]+:[^\s@,=/]+@[^\s,=]*/g,
|
|
196
|
+
// Vendor-prefixed API keys. The two-letter `xx_live_`/`xx_test_` arm names
|
|
197
|
+
// the prefixes that actually issue keys of that shape rather than accepting
|
|
198
|
+
// any two letters: unconstrained, it matched every snake_case value whose run
|
|
199
|
+
// after `_test_`/`_live_` was 8+ alphanumerics (`us_test_deployment`), and a
|
|
200
|
+
// false redaction is a real cost — the block then reports that a project
|
|
201
|
+
// declared something it did not.
|
|
202
|
+
/\b(?:(?:pk|sk|rk|ak)_(?:live|test)_[A-Za-z0-9]{8,}|github_pat_[A-Za-z0-9_]{20,}|gh[pousr]_[A-Za-z0-9]{16,}|xox[abprs]-[A-Za-z0-9-]{10,}|AKIA[0-9A-Z]{12,}|AIza[0-9A-Za-z_-]{20,}|sk-[A-Za-z0-9_-]{16,})\b/g,
|
|
203
|
+
// A signed token: three base64url segments, header first.
|
|
204
|
+
/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,
|
|
205
|
+
// An ARN carries an account number in its fifth field.
|
|
206
|
+
/\barn:[a-z0-9-]*:[^\s,=]*/g,
|
|
207
|
+
];
|
|
208
|
+
|
|
209
|
+
/** What replaces a redacted value, so the KEY's existence is still visible. */
|
|
210
|
+
const REDACTED = "[redacted]";
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Keys Lisa supplies a built-in value for when a project declares none.
|
|
214
|
+
*
|
|
215
|
+
* Each entry names the module that OWNS the constant. This table is a copy for
|
|
216
|
+
* one reason — the constants live in a TypeScript module and a shipped
|
|
217
|
+
* `all/` script, neither importable from a plugin hook running inside an
|
|
218
|
+
* arbitrary host project — and `tests/unit/hooks/inject-resolved-config.test.ts`
|
|
219
|
+
* imports the real constants and asserts this table still agrees with them, so
|
|
220
|
+
* the copy cannot drift silently.
|
|
221
|
+
*
|
|
222
|
+
* EXPORTED so that test can compare PATH-TO-VALUE PAIRS. Asserting instead that
|
|
223
|
+
* each constant appears somewhere in this file pins only the set of values
|
|
224
|
+
* present: swapping the `harness` and `gates.unproven` entries preserves that
|
|
225
|
+
* set, leaves every test in both suites green, and tells every session with no
|
|
226
|
+
* declared harness that its harness is `warn`.
|
|
227
|
+
* @type {ReadonlyArray<{path: string, value: string, owner: string}>}
|
|
228
|
+
*/
|
|
229
|
+
export const BUILT_IN_DEFAULTS = [
|
|
230
|
+
{ path: "harness", value: "claude", owner: "src/core/config.ts" },
|
|
231
|
+
{
|
|
232
|
+
path: "gates.runner",
|
|
233
|
+
value: "npm run",
|
|
234
|
+
owner: "all/copy-overwrite/scripts/lisa-gates.mjs",
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
path: "gates.unproven",
|
|
238
|
+
value: "warn",
|
|
239
|
+
owner: "all/copy-overwrite/scripts/lisa-gates.mjs",
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
path: "learnings.file",
|
|
243
|
+
value: ".lisa/PROJECT_LEARNINGS.md",
|
|
244
|
+
owner: "src/core/learnings-location.ts",
|
|
245
|
+
},
|
|
246
|
+
];
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Keys with NO built-in fallback, whose absence stops a flow rather than
|
|
250
|
+
* defaulting it. Reported as explicitly undeclared, because "absent" and
|
|
251
|
+
* "happens to match the default" are the two states this hook exists to
|
|
252
|
+
* separate and only one of them has a value to print.
|
|
253
|
+
*/
|
|
254
|
+
const REQUIRED_KEYS = ["tracker", "deploy.branches"];
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Top-level subtrees rendered, in the order an agent needs them.
|
|
258
|
+
*
|
|
259
|
+
* A subtree allowlist rather than a leaf allowlist: a key added to `github` or
|
|
260
|
+
* `policy` upstream reaches the agent without anyone remembering to edit this
|
|
261
|
+
* file. That is also why {@link SENSITIVE_WORDS} is load-bearing rather than
|
|
262
|
+
* belt-and-braces — `atlassian` is on this list, so `atlassian.email` is
|
|
263
|
+
* REACHED here and kept out by the redaction filter alone.
|
|
264
|
+
*/
|
|
265
|
+
const SUBTREE_ORDER = [
|
|
266
|
+
"harness",
|
|
267
|
+
"tracker",
|
|
268
|
+
"source",
|
|
269
|
+
"repo",
|
|
270
|
+
"workItem",
|
|
271
|
+
"deploy",
|
|
272
|
+
"github",
|
|
273
|
+
"jira",
|
|
274
|
+
"linear",
|
|
275
|
+
"notion",
|
|
276
|
+
"confluence",
|
|
277
|
+
"atlassian",
|
|
278
|
+
"gates",
|
|
279
|
+
"policy",
|
|
280
|
+
"quality",
|
|
281
|
+
"learnings",
|
|
282
|
+
"verification",
|
|
283
|
+
"nightlyE2E",
|
|
284
|
+
"intake",
|
|
285
|
+
"monitor",
|
|
286
|
+
"automations",
|
|
287
|
+
"remoteEnv",
|
|
288
|
+
];
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Split a config key into lowercase words for sensitivity matching.
|
|
292
|
+
* @param {string} segment One path segment, e.g. `bypass_actors` or `apiKey`.
|
|
293
|
+
* @returns {string[]} Lowercase words.
|
|
294
|
+
*/
|
|
295
|
+
function words(segment) {
|
|
296
|
+
return segment
|
|
297
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
298
|
+
.split(/[\s._-]+/)
|
|
299
|
+
.filter(Boolean)
|
|
300
|
+
.map(word => word.toLowerCase());
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Whether a dotted config path is identity- or credential-shaped.
|
|
305
|
+
* @param {string} path Dotted path, e.g. `atlassian.email`.
|
|
306
|
+
* @returns {boolean} True when the path must not be rendered.
|
|
307
|
+
*/
|
|
308
|
+
function isSensitivePath(path) {
|
|
309
|
+
return path
|
|
310
|
+
.split(".")
|
|
311
|
+
.some(segment => words(segment).some(word => SENSITIVE_WORDS.has(word)));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Redact anything identity- or credential-shaped in already-rendered text.
|
|
316
|
+
* @param {string} text Rendered line or block.
|
|
317
|
+
* @returns {string} The text with those values replaced.
|
|
318
|
+
*/
|
|
319
|
+
function scrub(text) {
|
|
320
|
+
return CREDENTIAL_SHAPED.reduce(
|
|
321
|
+
(carried, pattern) => carried.replace(pattern, REDACTED),
|
|
322
|
+
text.replace(EMAIL_SHAPED, REDACTED)
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Whether a value is a plain object worth recursing into.
|
|
328
|
+
* @param {unknown} value Any config value.
|
|
329
|
+
* @returns {boolean} True for non-array objects.
|
|
330
|
+
*/
|
|
331
|
+
function isObject(value) {
|
|
332
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Keys that reach an object's prototype rather than its own properties.
|
|
337
|
+
*
|
|
338
|
+
* `JSON.parse` makes `__proto__` an OWN property, so a later `merged[key] =`
|
|
339
|
+
* hands it to the prototype setter — and `key in config` and `node[key]` both
|
|
340
|
+
* read the prototype chain. A local override file carrying nothing but a
|
|
341
|
+
* `__proto__` object could therefore make this block announce a gate that no
|
|
342
|
+
* file declares, while the gate runner (which destructures own properties)
|
|
343
|
+
* enforced something else. The injected view is the one an agent is told to
|
|
344
|
+
* act on, so it is the one that must not be forgeable.
|
|
345
|
+
*/
|
|
346
|
+
const PROTOTYPE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Strip prototype-reaching keys from parsed JSON, at every depth.
|
|
350
|
+
* @param {unknown} value A parsed JSON value.
|
|
351
|
+
* @returns {unknown} The same value with {@link PROTOTYPE_KEYS} removed.
|
|
352
|
+
*/
|
|
353
|
+
function withoutPrototypeKeys(value) {
|
|
354
|
+
if (Array.isArray(value)) return value.map(withoutPrototypeKeys);
|
|
355
|
+
if (!isObject(value)) return value;
|
|
356
|
+
const out = {};
|
|
357
|
+
for (const [key, child] of Object.entries(value)) {
|
|
358
|
+
if (PROTOTYPE_KEYS.has(key)) continue;
|
|
359
|
+
out[key] = withoutPrototypeKeys(child);
|
|
360
|
+
}
|
|
361
|
+
return out;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Deep-merge the local override onto the committed config.
|
|
366
|
+
*
|
|
367
|
+
* Objects merge key by key so a local file naming one leaf does not erase its
|
|
368
|
+
* siblings; every non-object — scalars and arrays alike — is replaced whole.
|
|
369
|
+
* That reproduces the documented per-key resolution (`jq '.a.b' local` falling
|
|
370
|
+
* through to the committed file) for every path, which is the semantics the
|
|
371
|
+
* rest of Lisa reads with.
|
|
372
|
+
* @param {unknown} base Committed config value.
|
|
373
|
+
* @param {unknown} override Local config value.
|
|
374
|
+
* @returns {unknown} The resolved value.
|
|
375
|
+
*/
|
|
376
|
+
function deepMerge(base, override) {
|
|
377
|
+
if (override === undefined) return base;
|
|
378
|
+
if (!isObject(base) || !isObject(override)) return override;
|
|
379
|
+
const merged = { ...base };
|
|
380
|
+
for (const [key, value] of Object.entries(override)) {
|
|
381
|
+
// Belt and braces: `readJson` has already stripped these, and this loop is
|
|
382
|
+
// the assignment that would otherwise reach the prototype setter.
|
|
383
|
+
if (PROTOTYPE_KEYS.has(key)) continue;
|
|
384
|
+
merged[key] = deepMerge(base[key], value);
|
|
385
|
+
}
|
|
386
|
+
return merged;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Why a file could not be read, said without quoting the file or the disk.
|
|
391
|
+
*
|
|
392
|
+
* A `JSON.parse` failure message is not safe to repeat. V8 embeds roughly the
|
|
393
|
+
* first ten characters of the offending input in one of its forms — the entire
|
|
394
|
+
* file when the file is short — and this path runs against the gitignored local
|
|
395
|
+
* override, the one file identity is supposed to live in. There are no keys at
|
|
396
|
+
* that point, so the key-name filter cannot help. An `fs` failure message is
|
|
397
|
+
* not safe either: it carries the absolute path.
|
|
398
|
+
*
|
|
399
|
+
* Only the position is kept, because a line and column number describe the
|
|
400
|
+
* file's SHAPE and can be acted on, while quoting its contents adds nothing a
|
|
401
|
+
* reader with the file in front of them does not already have.
|
|
402
|
+
* @param {unknown} err What was thrown.
|
|
403
|
+
* @returns {string} A reason carrying no content and no path.
|
|
404
|
+
*/
|
|
405
|
+
function safeReason(err) {
|
|
406
|
+
const code = isObject(err) ? err.code : undefined;
|
|
407
|
+
if (typeof code === "string") return `${code} while reading the file`;
|
|
408
|
+
const message =
|
|
409
|
+
isObject(err) && typeof err.message === "string" ? err.message : "";
|
|
410
|
+
const position = /at position \d+(?: \(line \d+ column \d+\))?/.exec(message);
|
|
411
|
+
return position === null
|
|
412
|
+
? "not valid JSON"
|
|
413
|
+
: `not valid JSON ${position[0].replace("at position", "at byte")}`;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Read one JSON file.
|
|
418
|
+
* @param {string} path Absolute path.
|
|
419
|
+
* @returns {{state: "absent"} | {state: "ok", value: unknown} | {state: "bad", reason: string}}
|
|
420
|
+
* What was found. `bad` covers unreadable and unparseable alike — from the
|
|
421
|
+
* agent's seat those are the same fact.
|
|
422
|
+
*/
|
|
423
|
+
function readJson(path) {
|
|
424
|
+
if (!existsSync(path)) return { state: "absent" };
|
|
425
|
+
try {
|
|
426
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
427
|
+
if (!isObject(parsed)) {
|
|
428
|
+
return { state: "bad", reason: "root is not a JSON object" };
|
|
429
|
+
}
|
|
430
|
+
return { state: "ok", value: withoutPrototypeKeys(parsed) };
|
|
431
|
+
} catch (err) {
|
|
432
|
+
return { state: "bad", reason: safeReason(err) };
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Look a dotted path up in the resolved config.
|
|
438
|
+
* @param {object} config Resolved config.
|
|
439
|
+
* @param {string} path Dotted path.
|
|
440
|
+
* @returns {unknown} The value, or undefined when the path is not declared.
|
|
441
|
+
*/
|
|
442
|
+
function at(config, path) {
|
|
443
|
+
return path
|
|
444
|
+
.split(".")
|
|
445
|
+
.reduce(
|
|
446
|
+
(node, key) => (isObject(node) ? node[key] : undefined),
|
|
447
|
+
/** @type {unknown} */ (config)
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Render one leaf value compactly.
|
|
453
|
+
* @param {unknown} value A non-object config value.
|
|
454
|
+
* @returns {string} A one-line rendering.
|
|
455
|
+
*/
|
|
456
|
+
function renderLeaf(value) {
|
|
457
|
+
if (Array.isArray(value)) {
|
|
458
|
+
const scalars = value.filter(
|
|
459
|
+
item => !isObject(item) && !Array.isArray(item)
|
|
460
|
+
);
|
|
461
|
+
return scalars.length === value.length && value.length <= 4
|
|
462
|
+
? `[${scalars.join(", ")}]`
|
|
463
|
+
: `[${value.length} ${value.length === 1 ? "entry" : "entries"}]`;
|
|
464
|
+
}
|
|
465
|
+
return String(value);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Render a subtree as `path: key=value, key=value` lines.
|
|
470
|
+
*
|
|
471
|
+
* One line per leaf-bearing object rather than one line per leaf: a real config
|
|
472
|
+
* has well over a hundred leaves, and a hundred-line block is a dump, not a
|
|
473
|
+
* briefing.
|
|
474
|
+
* @param {unknown} node The subtree.
|
|
475
|
+
* @param {string} path Dotted path of this node.
|
|
476
|
+
* @param {string[]} out Lines accumulated so far (mutated).
|
|
477
|
+
*/
|
|
478
|
+
function renderSubtree(node, path, out) {
|
|
479
|
+
if (isSensitivePath(path)) return;
|
|
480
|
+
if (!isObject(node)) {
|
|
481
|
+
out.push(`${path}: ${renderLeaf(node)}`);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
const visible = Object.entries(node).filter(([key]) => !key.startsWith("_"));
|
|
485
|
+
const entries = visible.filter(([key]) => !isSensitivePath(`${path}.${key}`));
|
|
486
|
+
// A withheld key is COUNTED, never silently dropped. Omitting an
|
|
487
|
+
// identity-shaped value while leaving no trace that it exists would recreate,
|
|
488
|
+
// one level down, the invisible-gap failure this whole hook is against.
|
|
489
|
+
const withheld = visible.length - entries.length;
|
|
490
|
+
const suffix =
|
|
491
|
+
withheld > 0 ? `, +${withheld} withheld (identity-shaped)` : "";
|
|
492
|
+
const leaves = entries.filter(([, value]) => !isObject(value));
|
|
493
|
+
const branches = entries.filter(([, value]) => isObject(value));
|
|
494
|
+
if (leaves.length > 0 || withheld > 0) {
|
|
495
|
+
const shown = leaves.slice(0, MAX_CHILDREN);
|
|
496
|
+
const rest = leaves.length - shown.length;
|
|
497
|
+
const rendered = shown
|
|
498
|
+
.map(([key, value]) => `${key}=${renderLeaf(value)}`)
|
|
499
|
+
.join(", ");
|
|
500
|
+
out.push(
|
|
501
|
+
`${path}: ${rendered}${rest > 0 ? `, +${rest} more` : ""}${suffix}`
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
for (const [key, value] of branches)
|
|
505
|
+
renderSubtree(value, `${path}.${key}`, out);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* The level a gate declares at one moment, whichever shape it used.
|
|
510
|
+
*
|
|
511
|
+
* A moment is either a bare level (`"required"`) or an object carrying `level`
|
|
512
|
+
* alongside `run`/`await`. Both spellings are live in shipped configs.
|
|
513
|
+
* @param {unknown} declaration What the gate declares at that moment.
|
|
514
|
+
* @returns {string|null} The level, or null when this is not a moment.
|
|
515
|
+
*/
|
|
516
|
+
function levelOf(declaration) {
|
|
517
|
+
const declared =
|
|
518
|
+
typeof declaration === "string"
|
|
519
|
+
? declaration
|
|
520
|
+
: isObject(declaration) && typeof declaration.level === "string"
|
|
521
|
+
? declaration.level
|
|
522
|
+
: null;
|
|
523
|
+
return declared !== null && LEVELS.has(declared) ? declared : null;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Render one moment-and-level bucket across as many lines as its ids need.
|
|
528
|
+
*
|
|
529
|
+
* The generic {@link MAX_LINE} cut was being applied to the one line this
|
|
530
|
+
* module promises never elides: at 30 gates in a single bucket, six ids
|
|
531
|
+
* vanished behind `… (line truncated)` while the header above still counted
|
|
532
|
+
* them and the words beside it said not to bypass one. Wrapping is what keeps
|
|
533
|
+
* that promise — a count of what was dropped would still be an agent told the
|
|
534
|
+
* name of 24 gates out of 30 it must not skip.
|
|
535
|
+
* @param {string} bucket The `moment level` label.
|
|
536
|
+
* @param {string[]} ids Gate ids declared at that bucket.
|
|
537
|
+
* @returns {string[]} Lines, each within {@link MAX_LINE}.
|
|
538
|
+
*/
|
|
539
|
+
function bucketLines(bucket, ids) {
|
|
540
|
+
const lines = [];
|
|
541
|
+
let prefix = ` ${bucket}: `;
|
|
542
|
+
let current = [];
|
|
543
|
+
const flush = () => {
|
|
544
|
+
if (current.length === 0) return;
|
|
545
|
+
lines.push(`${prefix}${current.join(", ")}`);
|
|
546
|
+
prefix = ` ${bucket} (cont.): `;
|
|
547
|
+
current = [];
|
|
548
|
+
};
|
|
549
|
+
for (const id of ids) {
|
|
550
|
+
const width =
|
|
551
|
+
prefix.length +
|
|
552
|
+
current.reduce((carried, held) => carried + held.length + 2, 0) +
|
|
553
|
+
id.length;
|
|
554
|
+
if (current.length > 0 && width > MAX_LINE) flush();
|
|
555
|
+
current.push(id);
|
|
556
|
+
}
|
|
557
|
+
flush();
|
|
558
|
+
return lines;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Render the gates block grouped by moment and level.
|
|
563
|
+
*
|
|
564
|
+
* Gates are the largest block in a mature config and the one an agent most
|
|
565
|
+
* often acts against, so truncating the list would drop the answer to the
|
|
566
|
+
* question actually being asked — "what must be green before I push?".
|
|
567
|
+
* Grouping answers it in a handful of lines instead, with nothing elided.
|
|
568
|
+
* @param {unknown} gates The resolved `gates` block.
|
|
569
|
+
* @returns {string[]} Rendered lines.
|
|
570
|
+
*/
|
|
571
|
+
function renderGates(gates) {
|
|
572
|
+
if (!isObject(gates)) return [];
|
|
573
|
+
/** @type {Map<string, string[]>} */
|
|
574
|
+
const grouped = new Map();
|
|
575
|
+
let count = 0;
|
|
576
|
+
for (const [gateId, declaration] of Object.entries(gates)) {
|
|
577
|
+
if (
|
|
578
|
+
gateId === "runner" ||
|
|
579
|
+
gateId === "unproven" ||
|
|
580
|
+
!isObject(declaration)
|
|
581
|
+
) {
|
|
582
|
+
continue;
|
|
583
|
+
}
|
|
584
|
+
count += 1;
|
|
585
|
+
for (const [moment, momentDeclaration] of Object.entries(declaration)) {
|
|
586
|
+
const level = levelOf(momentDeclaration);
|
|
587
|
+
if (level === null) continue;
|
|
588
|
+
const bucket = `${moment} ${level}`;
|
|
589
|
+
grouped.set(bucket, [...(grouped.get(bucket) ?? []), gateId]);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
if (count === 0) return [];
|
|
593
|
+
return [
|
|
594
|
+
`gates (${count} declared) — a gate below is enforced at that moment; do not skip, weaken or bypass one:`,
|
|
595
|
+
...[...grouped.entries()]
|
|
596
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
597
|
+
.flatMap(([bucket, ids]) => bucketLines(bucket, ids)),
|
|
598
|
+
];
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Render the declared-vs-defaulted lines.
|
|
603
|
+
* @param {object} config Resolved config.
|
|
604
|
+
* @returns {string[]} Rendered lines, empty when everything was declared.
|
|
605
|
+
*/
|
|
606
|
+
function renderDefaults(config) {
|
|
607
|
+
const lines = [];
|
|
608
|
+
for (const { path, value, owner } of BUILT_IN_DEFAULTS) {
|
|
609
|
+
if (at(config, path) !== undefined) continue;
|
|
610
|
+
lines.push(
|
|
611
|
+
`${path}: ${value} [Lisa built-in default — this project declares none; owner: ${owner}]`
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
for (const path of REQUIRED_KEYS) {
|
|
615
|
+
if (at(config, path) !== undefined) continue;
|
|
616
|
+
lines.push(
|
|
617
|
+
`${path}: NOT DECLARED — Lisa has no default for this. Flows that dispatch on it stop rather than guess.`
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
return lines;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Render the whole value body, honouring {@link CONTEXT_BUDGET}.
|
|
625
|
+
* @param {object} config Resolved config.
|
|
626
|
+
* @returns {string} The rendered body.
|
|
627
|
+
*/
|
|
628
|
+
function renderBody(config) {
|
|
629
|
+
// The gap lines go FIRST, and that ordering is the whole point rather than a
|
|
630
|
+
// presentation choice. `withinBudget` truncates from the end, so appending
|
|
631
|
+
// them last meant the budget ate them first: a config with a large `policy`
|
|
632
|
+
// block and no `tracker` rendered ZERO `NOT DECLARED` lines and zero
|
|
633
|
+
// built-in-default lines — "a gap has no symptom at all", the failure this
|
|
634
|
+
// hook was built against, reproduced inside the hook. A value that does not
|
|
635
|
+
// fit can be looked up in the file. An absence cannot be looked up anywhere,
|
|
636
|
+
// so it is the line that must survive.
|
|
637
|
+
/** @type {string[]} */
|
|
638
|
+
const lines = renderDefaults(config);
|
|
639
|
+
const gapLines = lines.length;
|
|
640
|
+
// The gates block is the one this module promises never elides, so the lines
|
|
641
|
+
// it produced are named here rather than inferred from their shape later.
|
|
642
|
+
// `bucketLines` keeps every line inside MAX_LINE by wrapping, but it cannot
|
|
643
|
+
// wrap a SINGLE id longer than the line — nothing splits an identifier — so
|
|
644
|
+
// without this the generic cut would come back for exactly the id that most
|
|
645
|
+
// needs reading in full.
|
|
646
|
+
/** @type {Set<string>} */
|
|
647
|
+
const unelidable = new Set();
|
|
648
|
+
const seen = new Set();
|
|
649
|
+
for (const key of SUBTREE_ORDER) {
|
|
650
|
+
if (!(key in config)) continue;
|
|
651
|
+
seen.add(key);
|
|
652
|
+
if (key === "gates") {
|
|
653
|
+
const gates = config.gates;
|
|
654
|
+
const runner = isObject(gates) ? gates.runner : undefined;
|
|
655
|
+
const unproven = isObject(gates) ? gates.unproven : undefined;
|
|
656
|
+
if (runner !== undefined)
|
|
657
|
+
lines.push(`gates.runner: ${renderLeaf(runner)}`);
|
|
658
|
+
if (unproven !== undefined) {
|
|
659
|
+
lines.push(`gates.unproven: ${renderLeaf(unproven)}`);
|
|
660
|
+
}
|
|
661
|
+
const gateLines = renderGates(gates);
|
|
662
|
+
for (const gateLine of gateLines) unelidable.add(gateLine);
|
|
663
|
+
lines.push(...gateLines);
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
renderSubtree(config[key], key, lines);
|
|
667
|
+
}
|
|
668
|
+
const unlisted = Object.keys(config).filter(
|
|
669
|
+
key => !seen.has(key) && !key.startsWith("_")
|
|
670
|
+
);
|
|
671
|
+
if (unlisted.length > 0) {
|
|
672
|
+
lines.push(
|
|
673
|
+
`other declared keys (not summarised here): ${unlisted.join(", ")}`
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
return withinBudget(lines, { unelidable, gapLines });
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* The overflow notice, for a body that kept `keptCount` of `total` lines.
|
|
681
|
+
*
|
|
682
|
+
* Built from the counts rather than held as a constant because the notice is
|
|
683
|
+
* itself part of the body it describes: making room for it changes how many
|
|
684
|
+
* lines were dropped, which changes the sentence, which changes how much room
|
|
685
|
+
* it needs. See {@link withinBudget}.
|
|
686
|
+
* @param {number} total How many lines were rendered in all.
|
|
687
|
+
* @param {number} keptCount How many of them survived the budget.
|
|
688
|
+
* @param {number} gapLines How many leading lines describe gaps and defaults.
|
|
689
|
+
* @returns {string} The notice line.
|
|
690
|
+
*/
|
|
691
|
+
function overflowNotice(total, keptCount, gapLines) {
|
|
692
|
+
// Two things this notice used to get wrong. It counted LINES while reading as
|
|
693
|
+
// if it counted keys — one line carries many leaves — and it sent the reader
|
|
694
|
+
// to the config file for lines that no file can answer. The second is fixed
|
|
695
|
+
// by ordering (`renderBody` renders the declared-vs-default lines first, so
|
|
696
|
+
// they are never the omitted ones); saying so is what makes the advice true.
|
|
697
|
+
// The claim stays CONDITIONAL, because a config whose gap lines alone
|
|
698
|
+
// exhaust the budget would otherwise have this sentence assert a
|
|
699
|
+
// completeness the body does not have — the exact defect this hook exists to
|
|
700
|
+
// remove, committed by the sentence announcing it.
|
|
701
|
+
const completeness =
|
|
702
|
+
keptCount >= gapLines
|
|
703
|
+
? `The declared-vs-default lines above are complete — read ${MAIN_CONFIG} and ${LOCAL_CONFIG} for the omitted values.`
|
|
704
|
+
: `The declared-vs-default lines above are NOT complete, so a gap may be missing entirely — read ${MAIN_CONFIG} and ${LOCAL_CONFIG}.`;
|
|
705
|
+
return `… ${total - keptCount} further rendered line(s) omitted to stay within the session-context budget; a line can carry several keys, so more keys than that are unrendered. ${completeness}`;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Join lines, stopping at the budget and counting what did not fit.
|
|
710
|
+
* @param {string[]} lines Rendered lines.
|
|
711
|
+
* @param {object} [options] Rendering constraints.
|
|
712
|
+
* @param {Set<string>} [options.unelidable] Lines the MAX_LINE cut may not touch.
|
|
713
|
+
* @param {number} [options.gapLines] How many leading lines describe gaps.
|
|
714
|
+
* @returns {string} The joined body.
|
|
715
|
+
*/
|
|
716
|
+
function withinBudget(lines, { unelidable = new Set(), gapLines = 0 } = {}) {
|
|
717
|
+
const kept = [];
|
|
718
|
+
let size = 0;
|
|
719
|
+
for (const raw of lines) {
|
|
720
|
+
// Scrubbed BEFORE truncation: a cut through the middle of an identity would
|
|
721
|
+
// leave a fragment `EMAIL_SHAPED` no longer matches, so redacting the
|
|
722
|
+
// joined body afterwards would be redacting text that had already escaped.
|
|
723
|
+
const scrubbed = scrub(raw);
|
|
724
|
+
const line =
|
|
725
|
+
scrubbed.length > MAX_LINE && !unelidable.has(raw)
|
|
726
|
+
? `${scrubbed.slice(0, MAX_LINE)}… (line truncated)`
|
|
727
|
+
: scrubbed;
|
|
728
|
+
if (size + line.length > CONTEXT_BUDGET) {
|
|
729
|
+
// The notice has to fit INSIDE the budget, not be appended past it. It
|
|
730
|
+
// used to be pushed after the check, so a body that filled the budget
|
|
731
|
+
// exactly overshot it by the length of the sentence explaining that it
|
|
732
|
+
// had not. Lines come off the end until it fits, and the notice is
|
|
733
|
+
// rebuilt each time because dropping one is one more line to admit to.
|
|
734
|
+
while (
|
|
735
|
+
kept.length > 0 &&
|
|
736
|
+
size + overflowNotice(lines.length, kept.length, gapLines).length >
|
|
737
|
+
CONTEXT_BUDGET
|
|
738
|
+
) {
|
|
739
|
+
size -= kept.pop().length + 1;
|
|
740
|
+
}
|
|
741
|
+
kept.push(overflowNotice(lines.length, kept.length, gapLines));
|
|
742
|
+
break;
|
|
743
|
+
}
|
|
744
|
+
kept.push(line);
|
|
745
|
+
size += line.length + 1;
|
|
746
|
+
}
|
|
747
|
+
return kept.join("\n");
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/** Opening tag of the injected block. Tests and readers key off it. */
|
|
751
|
+
const OPEN_TAG = "<lisa-resolved-config>";
|
|
752
|
+
/** Closing tag of the injected block. */
|
|
753
|
+
const CLOSE_TAG = "</lisa-resolved-config>";
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* Wrap a body in the block's tags and preamble.
|
|
757
|
+
* @param {string} body Rendered body.
|
|
758
|
+
* @returns {string} The full injected block.
|
|
759
|
+
*/
|
|
760
|
+
function block(body) {
|
|
761
|
+
return `${OPEN_TAG}\n${body}\n${CLOSE_TAG}`;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Build the injected block for a project directory.
|
|
766
|
+
* @param {string} projectDir Absolute path to the project root.
|
|
767
|
+
* @returns {string} The block to inject.
|
|
768
|
+
*/
|
|
769
|
+
export function buildContext(projectDir) {
|
|
770
|
+
const main = readJson(join(projectDir, MAIN_CONFIG));
|
|
771
|
+
const local = readJson(join(projectDir, LOCAL_CONFIG));
|
|
772
|
+
|
|
773
|
+
if (main.state === "bad" || local.state === "bad") {
|
|
774
|
+
const which = main.state === "bad" ? MAIN_CONFIG : LOCAL_CONFIG;
|
|
775
|
+
const reason = main.state === "bad" ? main.reason : local.reason;
|
|
776
|
+
return block(
|
|
777
|
+
`Lisa configuration could not be read: ${which} (${scrub(reason)}).\n` +
|
|
778
|
+
`Treat every Lisa-configured value as UNKNOWN. Do not assume a default, and do not ` +
|
|
779
|
+
`report this project as unconfigured — the file exists and is broken, which is a ` +
|
|
780
|
+
`different fact. Fixing it is the first task.`
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (main.state === "absent" && local.state === "absent") {
|
|
785
|
+
return block(
|
|
786
|
+
`No Lisa configuration found: neither ${MAIN_CONFIG} nor ${LOCAL_CONFIG} exists here.\n` +
|
|
787
|
+
`Nothing declares this project's tracker, gates, or deploy branches, so any Lisa flow ` +
|
|
788
|
+
`that dispatches on them will stop rather than guess. Run the matching \`/lisa:setup:*\` ` +
|
|
789
|
+
`skill to create one. Do not infer a tracker from the shape of a request.`
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
const resolved = deepMerge(
|
|
794
|
+
main.state === "ok" ? main.value : {},
|
|
795
|
+
local.state === "ok" ? local.value : {}
|
|
796
|
+
);
|
|
797
|
+
const sources =
|
|
798
|
+
local.state === "ok"
|
|
799
|
+
? `${MAIN_CONFIG} + ${LOCAL_CONFIG} (local wins where they overlap)`
|
|
800
|
+
: `${MAIN_CONFIG} (no local override file)`;
|
|
801
|
+
|
|
802
|
+
// The block used to say "this project's" — a possessive with no referent
|
|
803
|
+
// anywhere in its text, so two repositories emitted blocks that were
|
|
804
|
+
// character-identical except for the values. An agent standing in one
|
|
805
|
+
// directory while doing work governed by another read something perfectly
|
|
806
|
+
// true about the directory and wrong about the work, and the next sentence
|
|
807
|
+
// told it not to open the files that would have shown the difference. Six
|
|
808
|
+
// independent agent cycles reached the same false conclusion from one such
|
|
809
|
+
// block (CodySwannGT/lisa#3765).
|
|
810
|
+
//
|
|
811
|
+
// `basename` rather than the git remote: naming the subject must not cost a
|
|
812
|
+
// subprocess on a hook that runs at every session and subagent start, and it
|
|
813
|
+
// must not fail in a directory that is not a git checkout. The absolute path
|
|
814
|
+
// beside it is the unambiguous identifier; the basename is the short name a
|
|
815
|
+
// reader actually compares against the work in front of them.
|
|
816
|
+
const subject = basename(projectDir) || projectDir;
|
|
817
|
+
|
|
818
|
+
return block(
|
|
819
|
+
`These are the EFFECTIVE Lisa configuration values for ${subject}, resolved from ${sources} ` +
|
|
820
|
+
`at ${projectDir}.\n` +
|
|
821
|
+
`Act on them directly and do not act against them. They describe THAT directory: if your ` +
|
|
822
|
+
`work targets a different repository, read that repository's config rather than these. For ` +
|
|
823
|
+
`work in ${subject}, do not re-read the config files to learn these values. A line marked ` +
|
|
824
|
+
`[Lisa built-in default] is NOT something ${subject} declared. A key whose NAME is identity- ` +
|
|
825
|
+
`or credential-shaped is withheld and counted, and a VALUE matching a known credential shape ` +
|
|
826
|
+
`is replaced with ${REDACTED}: a best-effort filter, not proof that anything it left alone ` +
|
|
827
|
+
`is safe to repeat.\n\n` +
|
|
828
|
+
renderBody(resolved)
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* Read the hook event name from the harness's stdin payload.
|
|
834
|
+
* @param {string} raw Raw stdin.
|
|
835
|
+
* @returns {string} The event name, defaulting to `SessionStart`.
|
|
836
|
+
*/
|
|
837
|
+
function eventName(raw) {
|
|
838
|
+
try {
|
|
839
|
+
const parsed = JSON.parse(raw);
|
|
840
|
+
return typeof parsed?.hook_event_name === "string"
|
|
841
|
+
? parsed.hook_event_name
|
|
842
|
+
: "SessionStart";
|
|
843
|
+
} catch {
|
|
844
|
+
return "SessionStart";
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Emit the hook envelope. Always exits 0 — see the module comment.
|
|
850
|
+
* @param {string[]} argv Process arguments.
|
|
851
|
+
* @param {string} stdin Raw stdin.
|
|
852
|
+
* @returns {string} The JSON envelope.
|
|
853
|
+
*/
|
|
854
|
+
export function run(argv, stdin) {
|
|
855
|
+
const flag = argv.indexOf("--project-dir");
|
|
856
|
+
const projectDir = flag >= 0 ? argv[flag + 1] : process.cwd();
|
|
857
|
+
return JSON.stringify({
|
|
858
|
+
hookSpecificOutput: {
|
|
859
|
+
hookEventName: eventName(stdin),
|
|
860
|
+
additionalContext: buildContext(projectDir),
|
|
861
|
+
},
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* Whether this module is the process entry point.
|
|
867
|
+
*
|
|
868
|
+
* Both sides are realpath'd: comparing `fileURLToPath(import.meta.url)` against
|
|
869
|
+
* `path.resolve(process.argv[1])` disagrees whenever the checkout is reached
|
|
870
|
+
* through a symlink — a git worktree, or any `/tmp` path on macOS, `/tmp` being
|
|
871
|
+
* a symlink to `/private/tmp` — because `import.meta.url` is the REAL path
|
|
872
|
+
* while `argv[1]` is whatever the caller typed.
|
|
873
|
+
*
|
|
874
|
+
* The one implementation lives at `scripts/lib/invoked-as-script.mjs`. This
|
|
875
|
+
* file cannot import it: it is materialized into every plugin payload, where
|
|
876
|
+
* there is no `./lib/` to import from — the same accommodation
|
|
877
|
+
* `failure-signature-index.mjs` and `threshold-ratchet.mjs` make.
|
|
878
|
+
* @param {string} moduleUrl The caller's own `import.meta.url`.
|
|
879
|
+
* @param {string | undefined} [argv1] Entry path; defaults to `process.argv[1]`.
|
|
880
|
+
* @returns {boolean} Whether the caller should run its CLI body.
|
|
881
|
+
*/
|
|
882
|
+
export function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
|
|
883
|
+
if (!argv1) return false;
|
|
884
|
+
try {
|
|
885
|
+
return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
|
|
886
|
+
} catch {
|
|
887
|
+
return false;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
if (invokedAsScript(import.meta.url)) {
|
|
892
|
+
let stdin = "";
|
|
893
|
+
try {
|
|
894
|
+
stdin = readFileSync(0, "utf8");
|
|
895
|
+
} catch {
|
|
896
|
+
stdin = "";
|
|
897
|
+
}
|
|
898
|
+
try {
|
|
899
|
+
process.stdout.write(`${run(process.argv.slice(2), stdin)}\n`);
|
|
900
|
+
} catch {
|
|
901
|
+
// Fail soft: a hook that cannot render must never wedge session start.
|
|
902
|
+
}
|
|
903
|
+
}
|