@codyswann/lisa 2.119.1 → 2.121.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +18 -0
- package/dist/agy/agents-md-installer.d.ts +24 -0
- package/dist/agy/agents-md-installer.d.ts.map +1 -0
- package/dist/agy/agents-md-installer.js +126 -0
- package/dist/agy/agents-md-installer.js.map +1 -0
- package/dist/agy/mcp-installer.d.ts +84 -0
- package/dist/agy/mcp-installer.d.ts.map +1 -0
- package/dist/agy/mcp-installer.js +134 -0
- package/dist/agy/mcp-installer.js.map +1 -0
- package/dist/agy/plugin-installer.d.ts +21 -0
- package/dist/agy/plugin-installer.d.ts.map +1 -0
- package/dist/agy/plugin-installer.js +84 -0
- package/dist/agy/plugin-installer.js.map +1 -0
- package/dist/claude/claude-md-installer.d.ts +18 -0
- package/dist/claude/claude-md-installer.d.ts.map +1 -0
- package/dist/claude/claude-md-installer.js +62 -0
- package/dist/claude/claude-md-installer.js.map +1 -0
- package/dist/codex/lisa-plugin-detection.d.ts +69 -0
- package/dist/codex/lisa-plugin-detection.d.ts.map +1 -0
- package/dist/codex/lisa-plugin-detection.js +135 -0
- package/dist/codex/lisa-plugin-detection.js.map +1 -0
- package/dist/copilot/copilot-instructions-installer.d.ts +18 -0
- package/dist/copilot/copilot-instructions-installer.d.ts.map +1 -0
- package/dist/copilot/copilot-instructions-installer.js +61 -0
- package/dist/copilot/copilot-instructions-installer.js.map +1 -0
- package/dist/copilot/plugin-installer.d.ts +29 -0
- package/dist/copilot/plugin-installer.d.ts.map +1 -0
- package/dist/copilot/plugin-installer.js +140 -0
- package/dist/copilot/plugin-installer.js.map +1 -0
- package/dist/core/config.d.ts +8 -4
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +4 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/lisa.d.ts +35 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +93 -0
- package/dist/core/lisa.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/hooks/block-no-verify.sh +37 -0
- package/plugins/lisa/.codex-plugin/hooks/inject-flow-context.sh +12 -0
- package/plugins/lisa/.codex-plugin/hooks/inject-rules.sh +33 -0
- package/plugins/lisa/.codex-plugin/hooks/install-pkgs.sh +69 -0
- package/plugins/lisa/.codex-plugin/hooks/notify-ntfy.sh +183 -0
- package/plugins/lisa/.codex-plugin/hooks/setup-jira-cli.sh +51 -0
- package/plugins/lisa/.codex-plugin/hooks.json +75 -0
- package/plugins/lisa/.codex-plugin/plugin.json +2 -1
- package/plugins/lisa-agy/agents/architecture-specialist.md +47 -0
- package/plugins/lisa-agy/agents/bug-fixer.md +39 -0
- package/plugins/lisa-agy/agents/builder.md +40 -0
- package/plugins/lisa-agy/agents/confluence-prd-intake.md +65 -0
- package/plugins/lisa-agy/agents/debug-specialist.md +114 -0
- package/plugins/lisa-agy/agents/git-history-analyzer.md +183 -0
- package/plugins/lisa-agy/agents/github-agent.md +148 -0
- package/plugins/lisa-agy/agents/github-build-intake.md +64 -0
- package/plugins/lisa-agy/agents/github-prd-intake.md +66 -0
- package/plugins/lisa-agy/agents/jira-agent.md +129 -0
- package/plugins/lisa-agy/agents/jira-build-intake.md +64 -0
- package/plugins/lisa-agy/agents/learner.md +43 -0
- package/plugins/lisa-agy/agents/learnings-synthesizer.md +135 -0
- package/plugins/lisa-agy/agents/linear-agent.md +134 -0
- package/plugins/lisa-agy/agents/linear-build-intake.md +64 -0
- package/plugins/lisa-agy/agents/linear-prd-intake.md +66 -0
- package/plugins/lisa-agy/agents/notion-prd-intake.md +63 -0
- package/plugins/lisa-agy/agents/performance-specialist.md +85 -0
- package/plugins/lisa-agy/agents/pr-mining-specialist.md +85 -0
- package/plugins/lisa-agy/agents/product-specialist.md +63 -0
- package/plugins/lisa-agy/agents/quality-specialist.md +56 -0
- package/plugins/lisa-agy/agents/security-specialist.md +51 -0
- package/plugins/lisa-agy/agents/skill-evaluator.md +245 -0
- package/plugins/lisa-agy/agents/spec-conformance-specialist.md +49 -0
- package/plugins/lisa-agy/agents/test-specialist.md +49 -0
- package/plugins/lisa-agy/agents/tracker-mining-specialist.md +85 -0
- package/plugins/lisa-agy/agents/verification-specialist.md +135 -0
- package/plugins/lisa-agy/commands/automation-status.md +12 -0
- package/plugins/lisa-agy/commands/codify-verification.md +6 -0
- package/plugins/lisa-agy/commands/debrief/apply.md +6 -0
- package/plugins/lisa-agy/commands/debrief.md +6 -0
- package/plugins/lisa-agy/commands/doctor.md +6 -0
- package/plugins/lisa-agy/commands/fix/linter-error.md +7 -0
- package/plugins/lisa-agy/commands/git/commit.md +7 -0
- package/plugins/lisa-agy/commands/git/prune.md +6 -0
- package/plugins/lisa-agy/commands/git/submit-pr.md +7 -0
- package/plugins/lisa-agy/commands/implement.md +6 -0
- package/plugins/lisa-agy/commands/improve/code-complexity.md +6 -0
- package/plugins/lisa-agy/commands/improve/max-lines-per-function.md +7 -0
- package/plugins/lisa-agy/commands/improve/max-lines.md +7 -0
- package/plugins/lisa-agy/commands/improve/test-coverage.md +7 -0
- package/plugins/lisa-agy/commands/improve/tests.md +7 -0
- package/plugins/lisa-agy/commands/intake-explain.md +31 -0
- package/plugins/lisa-agy/commands/intake.md +6 -0
- package/plugins/lisa-agy/commands/monitor.md +6 -0
- package/plugins/lisa-agy/commands/plan.md +6 -0
- package/plugins/lisa-agy/commands/plugin-sync-explain.md +8 -0
- package/plugins/lisa-agy/commands/product-walkthrough.md +7 -0
- package/plugins/lisa-agy/commands/project-ideation.md +6 -0
- package/plugins/lisa-agy/commands/pull-request/review.md +7 -0
- package/plugins/lisa-agy/commands/queue-status.md +34 -0
- package/plugins/lisa-agy/commands/repair-intake.md +6 -0
- package/plugins/lisa-agy/commands/research.md +6 -0
- package/plugins/lisa-agy/commands/review/local.md +6 -0
- package/plugins/lisa-agy/commands/security/zap-scan.md +6 -0
- package/plugins/lisa-agy/commands/setup/atlassian.md +7 -0
- package/plugins/lisa-agy/commands/setup/confluence.md +7 -0
- package/plugins/lisa-agy/commands/setup/github.md +7 -0
- package/plugins/lisa-agy/commands/setup/jira.md +7 -0
- package/plugins/lisa-agy/commands/setup/linear.md +7 -0
- package/plugins/lisa-agy/commands/setup/notion.md +7 -0
- package/plugins/lisa-agy/commands/setup-automations.md +6 -0
- package/plugins/lisa-agy/commands/tear-down-automations.md +6 -0
- package/plugins/lisa-agy/commands/verify-prd.md +6 -0
- package/plugins/lisa-agy/commands/verify.md +6 -0
- package/plugins/lisa-agy/commands/wiki/install.md +7 -0
- package/plugins/lisa-agy/plugin.json +8 -0
- package/plugins/lisa-agy/scripts/automation-status-claude-adapter.mjs +672 -0
- package/plugins/lisa-agy/scripts/automation-status-codex-adapter.mjs +697 -0
- package/plugins/lisa-agy/scripts/automation-status-contract-drift.mjs +392 -0
- package/plugins/lisa-agy/scripts/automation-status-expected-fleet.mjs +319 -0
- package/plugins/lisa-agy/scripts/automation-status-report.mjs +170 -0
- package/plugins/lisa-agy/scripts/doctor-report.mjs +143 -0
- package/plugins/lisa-agy/scripts/plugin-sync-explain.mjs +512 -0
- package/plugins/lisa-agy/scripts/project-ideation-idempotency-harness.mjs +319 -0
- package/plugins/lisa-agy/scripts/queue-contract-resolution.mjs +453 -0
- package/plugins/lisa-agy/scripts/queue-health-classification.mjs +157 -0
- package/plugins/lisa-agy/scripts/queue-status-build-readers.mjs +509 -0
- package/plugins/lisa-agy/scripts/queue-status-prd-readers.mjs +452 -0
- package/plugins/lisa-agy/skills/acceptance-criteria/SKILL.md +71 -0
- package/plugins/lisa-agy/skills/agent-design-best-practices/SKILL.md +219 -0
- package/plugins/lisa-agy/skills/atlassian-access/SKILL.md +293 -0
- package/plugins/lisa-agy/skills/automation-status/SKILL.md +111 -0
- package/plugins/lisa-agy/skills/bug-triage/SKILL.md +23 -0
- package/plugins/lisa-agy/skills/codebase-research/SKILL.md +87 -0
- package/plugins/lisa-agy/skills/codify-verification/SKILL.md +152 -0
- package/plugins/lisa-agy/skills/confluence-prd-intake/SKILL.md +417 -0
- package/plugins/lisa-agy/skills/confluence-to-tracker/SKILL.md +360 -0
- package/plugins/lisa-agy/skills/confluence-write-prd/SKILL.md +109 -0
- package/plugins/lisa-agy/skills/debrief/SKILL.md +94 -0
- package/plugins/lisa-agy/skills/debrief-apply/SKILL.md +63 -0
- package/plugins/lisa-agy/skills/doctor/SKILL.md +317 -0
- package/plugins/lisa-agy/skills/epic-triage/SKILL.md +28 -0
- package/plugins/lisa-agy/skills/fix-linter-error/SKILL.md +45 -0
- package/plugins/lisa-agy/skills/git-commit/SKILL.md +48 -0
- package/plugins/lisa-agy/skills/git-prune/SKILL.md +35 -0
- package/plugins/lisa-agy/skills/git-submit-pr/SKILL.md +105 -0
- package/plugins/lisa-agy/skills/github-add-journey/SKILL.md +115 -0
- package/plugins/lisa-agy/skills/github-build-intake/SKILL.md +377 -0
- package/plugins/lisa-agy/skills/github-create/SKILL.md +101 -0
- package/plugins/lisa-agy/skills/github-evidence/SKILL.md +110 -0
- package/plugins/lisa-agy/skills/github-journey/SKILL.md +121 -0
- package/plugins/lisa-agy/skills/github-prd-intake/SKILL.md +432 -0
- package/plugins/lisa-agy/skills/github-project-v2/SKILL.md +227 -0
- package/plugins/lisa-agy/skills/github-read-issue/SKILL.md +248 -0
- package/plugins/lisa-agy/skills/github-sync/SKILL.md +119 -0
- package/plugins/lisa-agy/skills/github-to-tracker/SKILL.md +345 -0
- package/plugins/lisa-agy/skills/github-validate-issue/SKILL.md +331 -0
- package/plugins/lisa-agy/skills/github-verify/SKILL.md +29 -0
- package/plugins/lisa-agy/skills/github-write-issue/SKILL.md +339 -0
- package/plugins/lisa-agy/skills/github-write-prd/SKILL.md +157 -0
- package/plugins/lisa-agy/skills/implement/SKILL.md +145 -0
- package/plugins/lisa-agy/skills/improve-code-complexity/SKILL.md +44 -0
- package/plugins/lisa-agy/skills/improve-max-lines/SKILL.md +45 -0
- package/plugins/lisa-agy/skills/improve-max-lines-per-function/SKILL.md +46 -0
- package/plugins/lisa-agy/skills/improve-test-coverage/SKILL.md +44 -0
- package/plugins/lisa-agy/skills/improve-tests/SKILL.md +47 -0
- package/plugins/lisa-agy/skills/intake/SKILL.md +132 -0
- package/plugins/lisa-agy/skills/intake-explain/SKILL.md +279 -0
- package/plugins/lisa-agy/skills/jira-add-journey/SKILL.md +121 -0
- package/plugins/lisa-agy/skills/jira-build-intake/SKILL.md +286 -0
- package/plugins/lisa-agy/skills/jira-create/SKILL.md +154 -0
- package/plugins/lisa-agy/skills/jira-evidence/SKILL.md +90 -0
- package/plugins/lisa-agy/skills/jira-evidence/scripts/post-evidence.sh +163 -0
- package/plugins/lisa-agy/skills/jira-journey/SKILL.md +127 -0
- package/plugins/lisa-agy/skills/jira-journey/scripts/generate-templates.py +233 -0
- package/plugins/lisa-agy/skills/jira-journey/scripts/parse-plan.py +368 -0
- package/plugins/lisa-agy/skills/jira-read-ticket/SKILL.md +198 -0
- package/plugins/lisa-agy/skills/jira-read-ticket/scripts/download-attachment.sh +110 -0
- package/plugins/lisa-agy/skills/jira-sync/SKILL.md +95 -0
- package/plugins/lisa-agy/skills/jira-validate-ticket/SKILL.md +318 -0
- package/plugins/lisa-agy/skills/jira-verify/SKILL.md +30 -0
- package/plugins/lisa-agy/skills/jira-write-ticket/SKILL.md +265 -0
- package/plugins/lisa-agy/skills/jsdoc-best-practices/SKILL.md +432 -0
- package/plugins/lisa-agy/skills/linear-add-journey/SKILL.md +105 -0
- package/plugins/lisa-agy/skills/linear-build-intake/SKILL.md +283 -0
- package/plugins/lisa-agy/skills/linear-create/SKILL.md +146 -0
- package/plugins/lisa-agy/skills/linear-evidence/SKILL.md +103 -0
- package/plugins/lisa-agy/skills/linear-journey/SKILL.md +134 -0
- package/plugins/lisa-agy/skills/linear-prd-intake/SKILL.md +383 -0
- package/plugins/lisa-agy/skills/linear-read-issue/SKILL.md +200 -0
- package/plugins/lisa-agy/skills/linear-sync/SKILL.md +114 -0
- package/plugins/lisa-agy/skills/linear-to-tracker/SKILL.md +342 -0
- package/plugins/lisa-agy/skills/linear-validate-issue/SKILL.md +313 -0
- package/plugins/lisa-agy/skills/linear-verify/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/linear-write-issue/SKILL.md +292 -0
- package/plugins/lisa-agy/skills/linear-write-prd/SKILL.md +96 -0
- package/plugins/lisa-agy/skills/lisa-review-implementation/SKILL.md +209 -0
- package/plugins/lisa-agy/skills/monitor/SKILL.md +48 -0
- package/plugins/lisa-agy/skills/nightly-add-test-coverage/SKILL.md +40 -0
- package/plugins/lisa-agy/skills/nightly-improve-tests/SKILL.md +29 -0
- package/plugins/lisa-agy/skills/nightly-lower-code-complexity/SKILL.md +28 -0
- package/plugins/lisa-agy/skills/notion-access/SKILL.md +226 -0
- package/plugins/lisa-agy/skills/notion-prd-intake/SKILL.md +360 -0
- package/plugins/lisa-agy/skills/notion-to-tracker/SKILL.md +357 -0
- package/plugins/lisa-agy/skills/notion-write-prd/SKILL.md +109 -0
- package/plugins/lisa-agy/skills/performance-review/SKILL.md +94 -0
- package/plugins/lisa-agy/skills/plan/SKILL.md +60 -0
- package/plugins/lisa-agy/skills/plugin-sync-explain/SKILL.md +53 -0
- package/plugins/lisa-agy/skills/prd-backlink/SKILL.md +265 -0
- package/plugins/lisa-agy/skills/prd-source-write/SKILL.md +101 -0
- package/plugins/lisa-agy/skills/prd-ticket-coverage/SKILL.md +170 -0
- package/plugins/lisa-agy/skills/product-walkthrough/SKILL.md +129 -0
- package/plugins/lisa-agy/skills/project-ideation/SKILL.md +315 -0
- package/plugins/lisa-agy/skills/project-ideation/examples/evidence-card-format.md +21 -0
- package/plugins/lisa-agy/skills/project-ideation/examples/host-project-only.md +22 -0
- package/plugins/lisa-agy/skills/project-ideation/examples/idempotency-verification-harness.md +57 -0
- package/plugins/lisa-agy/skills/project-ideation/examples/public-external-inspiration.md +22 -0
- package/plugins/lisa-agy/skills/project-ideation/examples/unavailable-data-rejection.md +22 -0
- package/plugins/lisa-agy/skills/pull-request-review/SKILL.md +68 -0
- package/plugins/lisa-agy/skills/quality-review/SKILL.md +54 -0
- package/plugins/lisa-agy/skills/queue-status/SKILL.md +133 -0
- package/plugins/lisa-agy/skills/repair-intake/SKILL.md +584 -0
- package/plugins/lisa-agy/skills/reproduce-bug/SKILL.md +96 -0
- package/plugins/lisa-agy/skills/research/SKILL.md +68 -0
- package/plugins/lisa-agy/skills/review-local/SKILL.md +88 -0
- package/plugins/lisa-agy/skills/root-cause-analysis/SKILL.md +155 -0
- package/plugins/lisa-agy/skills/security-review/SKILL.md +57 -0
- package/plugins/lisa-agy/skills/security-zap-scan/SKILL.md +33 -0
- package/plugins/lisa-agy/skills/setup-atlassian/SKILL.md +347 -0
- package/plugins/lisa-agy/skills/setup-automations/SKILL.md +99 -0
- package/plugins/lisa-agy/skills/setup-confluence/SKILL.md +254 -0
- package/plugins/lisa-agy/skills/setup-github/SKILL.md +268 -0
- package/plugins/lisa-agy/skills/setup-jira/SKILL.md +198 -0
- package/plugins/lisa-agy/skills/setup-linear/SKILL.md +251 -0
- package/plugins/lisa-agy/skills/setup-notion/SKILL.md +316 -0
- package/plugins/lisa-agy/skills/spec-conformance/SKILL.md +159 -0
- package/plugins/lisa-agy/skills/task-decomposition/SKILL.md +127 -0
- package/plugins/lisa-agy/skills/task-triage/SKILL.md +23 -0
- package/plugins/lisa-agy/skills/tdd-implementation/SKILL.md +83 -0
- package/plugins/lisa-agy/skills/tear-down-automations/SKILL.md +34 -0
- package/plugins/lisa-agy/skills/test-strategy/SKILL.md +63 -0
- package/plugins/lisa-agy/skills/ticket-triage/SKILL.md +182 -0
- package/plugins/lisa-agy/skills/tracker-add-journey/SKILL.md +26 -0
- package/plugins/lisa-agy/skills/tracker-build-intake/SKILL.md +64 -0
- package/plugins/lisa-agy/skills/tracker-create/SKILL.md +26 -0
- package/plugins/lisa-agy/skills/tracker-evidence/SKILL.md +52 -0
- package/plugins/lisa-agy/skills/tracker-journey/SKILL.md +26 -0
- package/plugins/lisa-agy/skills/tracker-read/SKILL.md +27 -0
- package/plugins/lisa-agy/skills/tracker-source-artifacts/SKILL.md +107 -0
- package/plugins/lisa-agy/skills/tracker-sync/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/tracker-validate/SKILL.md +36 -0
- package/plugins/lisa-agy/skills/tracker-verify/SKILL.md +27 -0
- package/plugins/lisa-agy/skills/tracker-write/SKILL.md +53 -0
- package/plugins/lisa-agy/skills/usage-accounting/SKILL.md +170 -0
- package/plugins/lisa-agy/skills/verification-lifecycle/SKILL.md +339 -0
- package/plugins/lisa-agy/skills/verify/SKILL.md +49 -0
- package/plugins/lisa-agy/skills/verify-prd/SKILL.md +392 -0
- package/plugins/lisa-agy/skills/wiki-install/SKILL.md +101 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +72 -0
- package/plugins/lisa-copilot/agents/architecture-specialist.agent.md +47 -0
- package/plugins/lisa-copilot/agents/bug-fixer.agent.md +39 -0
- package/plugins/lisa-copilot/agents/builder.agent.md +40 -0
- package/plugins/lisa-copilot/agents/confluence-prd-intake.agent.md +65 -0
- package/plugins/lisa-copilot/agents/debug-specialist.agent.md +114 -0
- package/plugins/lisa-copilot/agents/git-history-analyzer.agent.md +183 -0
- package/plugins/lisa-copilot/agents/github-agent.agent.md +148 -0
- package/plugins/lisa-copilot/agents/github-build-intake.agent.md +64 -0
- package/plugins/lisa-copilot/agents/github-prd-intake.agent.md +66 -0
- package/plugins/lisa-copilot/agents/jira-agent.agent.md +129 -0
- package/plugins/lisa-copilot/agents/jira-build-intake.agent.md +64 -0
- package/plugins/lisa-copilot/agents/learner.agent.md +43 -0
- package/plugins/lisa-copilot/agents/learnings-synthesizer.agent.md +135 -0
- package/plugins/lisa-copilot/agents/linear-agent.agent.md +134 -0
- package/plugins/lisa-copilot/agents/linear-build-intake.agent.md +64 -0
- package/plugins/lisa-copilot/agents/linear-prd-intake.agent.md +66 -0
- package/plugins/lisa-copilot/agents/notion-prd-intake.agent.md +63 -0
- package/plugins/lisa-copilot/agents/performance-specialist.agent.md +85 -0
- package/plugins/lisa-copilot/agents/pr-mining-specialist.agent.md +85 -0
- package/plugins/lisa-copilot/agents/product-specialist.agent.md +63 -0
- package/plugins/lisa-copilot/agents/quality-specialist.agent.md +56 -0
- package/plugins/lisa-copilot/agents/security-specialist.agent.md +51 -0
- package/plugins/lisa-copilot/agents/skill-evaluator.agent.md +245 -0
- package/plugins/lisa-copilot/agents/spec-conformance-specialist.agent.md +49 -0
- package/plugins/lisa-copilot/agents/test-specialist.agent.md +49 -0
- package/plugins/lisa-copilot/agents/tracker-mining-specialist.agent.md +85 -0
- package/plugins/lisa-copilot/agents/verification-specialist.agent.md +135 -0
- package/plugins/lisa-copilot/commands/automation-status.md +12 -0
- package/plugins/lisa-copilot/commands/codify-verification.md +6 -0
- package/plugins/lisa-copilot/commands/debrief/apply.md +6 -0
- package/plugins/lisa-copilot/commands/debrief.md +6 -0
- package/plugins/lisa-copilot/commands/doctor.md +6 -0
- package/plugins/lisa-copilot/commands/fix/linter-error.md +7 -0
- package/plugins/lisa-copilot/commands/git/commit.md +7 -0
- package/plugins/lisa-copilot/commands/git/prune.md +6 -0
- package/plugins/lisa-copilot/commands/git/submit-pr.md +7 -0
- package/plugins/lisa-copilot/commands/implement.md +6 -0
- package/plugins/lisa-copilot/commands/improve/code-complexity.md +6 -0
- package/plugins/lisa-copilot/commands/improve/max-lines-per-function.md +7 -0
- package/plugins/lisa-copilot/commands/improve/max-lines.md +7 -0
- package/plugins/lisa-copilot/commands/improve/test-coverage.md +7 -0
- package/plugins/lisa-copilot/commands/improve/tests.md +7 -0
- package/plugins/lisa-copilot/commands/intake-explain.md +31 -0
- package/plugins/lisa-copilot/commands/intake.md +6 -0
- package/plugins/lisa-copilot/commands/monitor.md +6 -0
- package/plugins/lisa-copilot/commands/plan.md +6 -0
- package/plugins/lisa-copilot/commands/plugin-sync-explain.md +8 -0
- package/plugins/lisa-copilot/commands/product-walkthrough.md +7 -0
- package/plugins/lisa-copilot/commands/project-ideation.md +6 -0
- package/plugins/lisa-copilot/commands/pull-request/review.md +7 -0
- package/plugins/lisa-copilot/commands/queue-status.md +34 -0
- package/plugins/lisa-copilot/commands/repair-intake.md +6 -0
- package/plugins/lisa-copilot/commands/research.md +6 -0
- package/plugins/lisa-copilot/commands/review/local.md +6 -0
- package/plugins/lisa-copilot/commands/security/zap-scan.md +6 -0
- package/plugins/lisa-copilot/commands/setup/atlassian.md +7 -0
- package/plugins/lisa-copilot/commands/setup/confluence.md +7 -0
- package/plugins/lisa-copilot/commands/setup/github.md +7 -0
- package/plugins/lisa-copilot/commands/setup/jira.md +7 -0
- package/plugins/lisa-copilot/commands/setup/linear.md +7 -0
- package/plugins/lisa-copilot/commands/setup/notion.md +7 -0
- package/plugins/lisa-copilot/commands/setup-automations.md +6 -0
- package/plugins/lisa-copilot/commands/tear-down-automations.md +6 -0
- package/plugins/lisa-copilot/commands/verify-prd.md +6 -0
- package/plugins/lisa-copilot/commands/verify.md +6 -0
- package/plugins/lisa-copilot/commands/wiki/install.md +7 -0
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +37 -0
- package/plugins/lisa-copilot/hooks/inject-rules.sh +33 -0
- package/plugins/lisa-copilot/hooks/install-pkgs.sh +69 -0
- package/plugins/lisa-copilot/hooks/notify-ntfy.sh +183 -0
- package/plugins/lisa-copilot/hooks/setup-jira-cli.sh +51 -0
- package/plugins/lisa-copilot/rules/eager/base-rules.md +70 -0
- package/plugins/lisa-copilot/rules/eager/coding-philosophy.md +27 -0
- package/plugins/lisa-copilot/rules/eager/config-resolution.md +28 -0
- package/plugins/lisa-copilot/rules/eager/documentation-source-paths.md +13 -0
- package/plugins/lisa-copilot/rules/eager/empirical-inquiry.md +22 -0
- package/plugins/lisa-copilot/rules/eager/intent-routing.md +18 -0
- package/plugins/lisa-copilot/rules/eager/leaf-only-lifecycle.md +39 -0
- package/plugins/lisa-copilot/rules/eager/prd-lifecycle-rollup.md +31 -0
- package/plugins/lisa-copilot/rules/eager/repo-scope-split.md +39 -0
- package/plugins/lisa-copilot/rules/eager/security-audit-handling.md +29 -0
- package/plugins/lisa-copilot/rules/eager/usage-accounting.md +28 -0
- package/plugins/lisa-copilot/rules/eager/verification.md +21 -0
- package/plugins/lisa-copilot/rules/eager/wiki-knowledge-source.md +16 -0
- package/plugins/lisa-copilot/rules/reference/base-rules.md +133 -0
- package/plugins/lisa-copilot/rules/reference/coding-philosophy.md +428 -0
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +691 -0
- package/plugins/lisa-copilot/rules/reference/documentation-source-paths.md +13 -0
- package/plugins/lisa-copilot/rules/reference/empirical-inquiry.md +27 -0
- package/plugins/lisa-copilot/rules/reference/intent-routing.md +407 -0
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +120 -0
- package/plugins/lisa-copilot/rules/reference/prd-lifecycle-rollup.md +156 -0
- package/plugins/lisa-copilot/rules/reference/repo-scope-split.md +58 -0
- package/plugins/lisa-copilot/rules/reference/security-audit-handling.md +30 -0
- package/plugins/lisa-copilot/rules/reference/usage-accounting.md +144 -0
- package/plugins/lisa-copilot/rules/reference/verification.md +124 -0
- package/plugins/lisa-copilot/rules/reference/wiki-knowledge-source.md +14 -0
- package/plugins/lisa-copilot/scripts/automation-status-claude-adapter.mjs +672 -0
- package/plugins/lisa-copilot/scripts/automation-status-codex-adapter.mjs +697 -0
- package/plugins/lisa-copilot/scripts/automation-status-contract-drift.mjs +392 -0
- package/plugins/lisa-copilot/scripts/automation-status-expected-fleet.mjs +319 -0
- package/plugins/lisa-copilot/scripts/automation-status-report.mjs +170 -0
- package/plugins/lisa-copilot/scripts/doctor-report.mjs +143 -0
- package/plugins/lisa-copilot/scripts/plugin-sync-explain.mjs +512 -0
- package/plugins/lisa-copilot/scripts/project-ideation-idempotency-harness.mjs +319 -0
- package/plugins/lisa-copilot/scripts/queue-contract-resolution.mjs +453 -0
- package/plugins/lisa-copilot/scripts/queue-health-classification.mjs +157 -0
- package/plugins/lisa-copilot/scripts/queue-status-build-readers.mjs +509 -0
- package/plugins/lisa-copilot/scripts/queue-status-prd-readers.mjs +452 -0
- package/plugins/lisa-copilot/skills/acceptance-criteria/SKILL.md +71 -0
- package/plugins/lisa-copilot/skills/agent-design-best-practices/SKILL.md +219 -0
- package/plugins/lisa-copilot/skills/atlassian-access/SKILL.md +293 -0
- package/plugins/lisa-copilot/skills/automation-status/SKILL.md +111 -0
- package/plugins/lisa-copilot/skills/bug-triage/SKILL.md +23 -0
- package/plugins/lisa-copilot/skills/codebase-research/SKILL.md +87 -0
- package/plugins/lisa-copilot/skills/codify-verification/SKILL.md +152 -0
- package/plugins/lisa-copilot/skills/confluence-prd-intake/SKILL.md +417 -0
- package/plugins/lisa-copilot/skills/confluence-to-tracker/SKILL.md +360 -0
- package/plugins/lisa-copilot/skills/confluence-write-prd/SKILL.md +109 -0
- package/plugins/lisa-copilot/skills/debrief/SKILL.md +94 -0
- package/plugins/lisa-copilot/skills/debrief-apply/SKILL.md +63 -0
- package/plugins/lisa-copilot/skills/doctor/SKILL.md +317 -0
- package/plugins/lisa-copilot/skills/epic-triage/SKILL.md +28 -0
- package/plugins/lisa-copilot/skills/fix-linter-error/SKILL.md +45 -0
- package/plugins/lisa-copilot/skills/git-commit/SKILL.md +48 -0
- package/plugins/lisa-copilot/skills/git-prune/SKILL.md +35 -0
- package/plugins/lisa-copilot/skills/git-submit-pr/SKILL.md +105 -0
- package/plugins/lisa-copilot/skills/github-add-journey/SKILL.md +115 -0
- package/plugins/lisa-copilot/skills/github-build-intake/SKILL.md +377 -0
- package/plugins/lisa-copilot/skills/github-create/SKILL.md +101 -0
- package/plugins/lisa-copilot/skills/github-evidence/SKILL.md +110 -0
- package/plugins/lisa-copilot/skills/github-journey/SKILL.md +121 -0
- package/plugins/lisa-copilot/skills/github-prd-intake/SKILL.md +432 -0
- package/plugins/lisa-copilot/skills/github-project-v2/SKILL.md +227 -0
- package/plugins/lisa-copilot/skills/github-read-issue/SKILL.md +248 -0
- package/plugins/lisa-copilot/skills/github-sync/SKILL.md +119 -0
- package/plugins/lisa-copilot/skills/github-to-tracker/SKILL.md +345 -0
- package/plugins/lisa-copilot/skills/github-validate-issue/SKILL.md +331 -0
- package/plugins/lisa-copilot/skills/github-verify/SKILL.md +29 -0
- package/plugins/lisa-copilot/skills/github-write-issue/SKILL.md +339 -0
- package/plugins/lisa-copilot/skills/github-write-prd/SKILL.md +157 -0
- package/plugins/lisa-copilot/skills/implement/SKILL.md +145 -0
- package/plugins/lisa-copilot/skills/improve-code-complexity/SKILL.md +44 -0
- package/plugins/lisa-copilot/skills/improve-max-lines/SKILL.md +45 -0
- package/plugins/lisa-copilot/skills/improve-max-lines-per-function/SKILL.md +46 -0
- package/plugins/lisa-copilot/skills/improve-test-coverage/SKILL.md +44 -0
- package/plugins/lisa-copilot/skills/improve-tests/SKILL.md +47 -0
- package/plugins/lisa-copilot/skills/intake/SKILL.md +132 -0
- package/plugins/lisa-copilot/skills/intake-explain/SKILL.md +279 -0
- package/plugins/lisa-copilot/skills/jira-add-journey/SKILL.md +121 -0
- package/plugins/lisa-copilot/skills/jira-build-intake/SKILL.md +286 -0
- package/plugins/lisa-copilot/skills/jira-create/SKILL.md +154 -0
- package/plugins/lisa-copilot/skills/jira-evidence/SKILL.md +90 -0
- package/plugins/lisa-copilot/skills/jira-evidence/scripts/post-evidence.sh +163 -0
- package/plugins/lisa-copilot/skills/jira-journey/SKILL.md +127 -0
- package/plugins/lisa-copilot/skills/jira-journey/scripts/generate-templates.py +233 -0
- package/plugins/lisa-copilot/skills/jira-journey/scripts/parse-plan.py +368 -0
- package/plugins/lisa-copilot/skills/jira-read-ticket/SKILL.md +198 -0
- package/plugins/lisa-copilot/skills/jira-read-ticket/scripts/download-attachment.sh +110 -0
- package/plugins/lisa-copilot/skills/jira-sync/SKILL.md +95 -0
- package/plugins/lisa-copilot/skills/jira-validate-ticket/SKILL.md +318 -0
- package/plugins/lisa-copilot/skills/jira-verify/SKILL.md +30 -0
- package/plugins/lisa-copilot/skills/jira-write-ticket/SKILL.md +265 -0
- package/plugins/lisa-copilot/skills/jsdoc-best-practices/SKILL.md +432 -0
- package/plugins/lisa-copilot/skills/linear-add-journey/SKILL.md +105 -0
- package/plugins/lisa-copilot/skills/linear-build-intake/SKILL.md +283 -0
- package/plugins/lisa-copilot/skills/linear-create/SKILL.md +146 -0
- package/plugins/lisa-copilot/skills/linear-evidence/SKILL.md +103 -0
- package/plugins/lisa-copilot/skills/linear-journey/SKILL.md +134 -0
- package/plugins/lisa-copilot/skills/linear-prd-intake/SKILL.md +383 -0
- package/plugins/lisa-copilot/skills/linear-read-issue/SKILL.md +200 -0
- package/plugins/lisa-copilot/skills/linear-sync/SKILL.md +114 -0
- package/plugins/lisa-copilot/skills/linear-to-tracker/SKILL.md +342 -0
- package/plugins/lisa-copilot/skills/linear-validate-issue/SKILL.md +313 -0
- package/plugins/lisa-copilot/skills/linear-verify/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/linear-write-issue/SKILL.md +292 -0
- package/plugins/lisa-copilot/skills/linear-write-prd/SKILL.md +96 -0
- package/plugins/lisa-copilot/skills/lisa-review-implementation/SKILL.md +209 -0
- package/plugins/lisa-copilot/skills/monitor/SKILL.md +48 -0
- package/plugins/lisa-copilot/skills/nightly-add-test-coverage/SKILL.md +40 -0
- package/plugins/lisa-copilot/skills/nightly-improve-tests/SKILL.md +29 -0
- package/plugins/lisa-copilot/skills/nightly-lower-code-complexity/SKILL.md +28 -0
- package/plugins/lisa-copilot/skills/notion-access/SKILL.md +226 -0
- package/plugins/lisa-copilot/skills/notion-prd-intake/SKILL.md +360 -0
- package/plugins/lisa-copilot/skills/notion-to-tracker/SKILL.md +357 -0
- package/plugins/lisa-copilot/skills/notion-write-prd/SKILL.md +109 -0
- package/plugins/lisa-copilot/skills/performance-review/SKILL.md +94 -0
- package/plugins/lisa-copilot/skills/plan/SKILL.md +60 -0
- package/plugins/lisa-copilot/skills/plugin-sync-explain/SKILL.md +53 -0
- package/plugins/lisa-copilot/skills/prd-backlink/SKILL.md +265 -0
- package/plugins/lisa-copilot/skills/prd-source-write/SKILL.md +101 -0
- package/plugins/lisa-copilot/skills/prd-ticket-coverage/SKILL.md +170 -0
- package/plugins/lisa-copilot/skills/product-walkthrough/SKILL.md +129 -0
- package/plugins/lisa-copilot/skills/project-ideation/SKILL.md +315 -0
- package/plugins/lisa-copilot/skills/project-ideation/examples/evidence-card-format.md +21 -0
- package/plugins/lisa-copilot/skills/project-ideation/examples/host-project-only.md +22 -0
- package/plugins/lisa-copilot/skills/project-ideation/examples/idempotency-verification-harness.md +57 -0
- package/plugins/lisa-copilot/skills/project-ideation/examples/public-external-inspiration.md +22 -0
- package/plugins/lisa-copilot/skills/project-ideation/examples/unavailable-data-rejection.md +22 -0
- package/plugins/lisa-copilot/skills/pull-request-review/SKILL.md +68 -0
- package/plugins/lisa-copilot/skills/quality-review/SKILL.md +54 -0
- package/plugins/lisa-copilot/skills/queue-status/SKILL.md +133 -0
- package/plugins/lisa-copilot/skills/repair-intake/SKILL.md +584 -0
- package/plugins/lisa-copilot/skills/reproduce-bug/SKILL.md +96 -0
- package/plugins/lisa-copilot/skills/research/SKILL.md +68 -0
- package/plugins/lisa-copilot/skills/review-local/SKILL.md +88 -0
- package/plugins/lisa-copilot/skills/root-cause-analysis/SKILL.md +155 -0
- package/plugins/lisa-copilot/skills/security-review/SKILL.md +57 -0
- package/plugins/lisa-copilot/skills/security-zap-scan/SKILL.md +33 -0
- package/plugins/lisa-copilot/skills/setup-atlassian/SKILL.md +347 -0
- package/plugins/lisa-copilot/skills/setup-automations/SKILL.md +99 -0
- package/plugins/lisa-copilot/skills/setup-confluence/SKILL.md +254 -0
- package/plugins/lisa-copilot/skills/setup-github/SKILL.md +268 -0
- package/plugins/lisa-copilot/skills/setup-jira/SKILL.md +198 -0
- package/plugins/lisa-copilot/skills/setup-linear/SKILL.md +251 -0
- package/plugins/lisa-copilot/skills/setup-notion/SKILL.md +316 -0
- package/plugins/lisa-copilot/skills/spec-conformance/SKILL.md +159 -0
- package/plugins/lisa-copilot/skills/task-decomposition/SKILL.md +127 -0
- package/plugins/lisa-copilot/skills/task-triage/SKILL.md +23 -0
- package/plugins/lisa-copilot/skills/tdd-implementation/SKILL.md +83 -0
- package/plugins/lisa-copilot/skills/tear-down-automations/SKILL.md +34 -0
- package/plugins/lisa-copilot/skills/test-strategy/SKILL.md +63 -0
- package/plugins/lisa-copilot/skills/ticket-triage/SKILL.md +182 -0
- package/plugins/lisa-copilot/skills/tracker-add-journey/SKILL.md +26 -0
- package/plugins/lisa-copilot/skills/tracker-build-intake/SKILL.md +64 -0
- package/plugins/lisa-copilot/skills/tracker-create/SKILL.md +26 -0
- package/plugins/lisa-copilot/skills/tracker-evidence/SKILL.md +52 -0
- package/plugins/lisa-copilot/skills/tracker-journey/SKILL.md +26 -0
- package/plugins/lisa-copilot/skills/tracker-read/SKILL.md +27 -0
- package/plugins/lisa-copilot/skills/tracker-source-artifacts/SKILL.md +107 -0
- package/plugins/lisa-copilot/skills/tracker-sync/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/tracker-validate/SKILL.md +36 -0
- package/plugins/lisa-copilot/skills/tracker-verify/SKILL.md +27 -0
- package/plugins/lisa-copilot/skills/tracker-write/SKILL.md +53 -0
- package/plugins/lisa-copilot/skills/usage-accounting/SKILL.md +170 -0
- package/plugins/lisa-copilot/skills/verification-lifecycle/SKILL.md +339 -0
- package/plugins/lisa-copilot/skills/verify/SKILL.md +49 -0
- package/plugins/lisa-copilot/skills/verify-prd/SKILL.md +392 -0
- package/plugins/lisa-copilot/skills/wiki-install/SKILL.md +101 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +52 -0
- package/plugins/lisa-cursor/agents/architecture-specialist.md +47 -0
- package/plugins/lisa-cursor/agents/bug-fixer.md +39 -0
- package/plugins/lisa-cursor/agents/builder.md +40 -0
- package/plugins/lisa-cursor/agents/confluence-prd-intake.md +65 -0
- package/plugins/lisa-cursor/agents/debug-specialist.md +114 -0
- package/plugins/lisa-cursor/agents/git-history-analyzer.md +183 -0
- package/plugins/lisa-cursor/agents/github-agent.md +148 -0
- package/plugins/lisa-cursor/agents/github-build-intake.md +64 -0
- package/plugins/lisa-cursor/agents/github-prd-intake.md +66 -0
- package/plugins/lisa-cursor/agents/jira-agent.md +129 -0
- package/plugins/lisa-cursor/agents/jira-build-intake.md +64 -0
- package/plugins/lisa-cursor/agents/learner.md +43 -0
- package/plugins/lisa-cursor/agents/learnings-synthesizer.md +135 -0
- package/plugins/lisa-cursor/agents/linear-agent.md +134 -0
- package/plugins/lisa-cursor/agents/linear-build-intake.md +64 -0
- package/plugins/lisa-cursor/agents/linear-prd-intake.md +66 -0
- package/plugins/lisa-cursor/agents/notion-prd-intake.md +63 -0
- package/plugins/lisa-cursor/agents/performance-specialist.md +85 -0
- package/plugins/lisa-cursor/agents/pr-mining-specialist.md +85 -0
- package/plugins/lisa-cursor/agents/product-specialist.md +63 -0
- package/plugins/lisa-cursor/agents/quality-specialist.md +56 -0
- package/plugins/lisa-cursor/agents/security-specialist.md +51 -0
- package/plugins/lisa-cursor/agents/skill-evaluator.md +245 -0
- package/plugins/lisa-cursor/agents/spec-conformance-specialist.md +49 -0
- package/plugins/lisa-cursor/agents/test-specialist.md +49 -0
- package/plugins/lisa-cursor/agents/tracker-mining-specialist.md +85 -0
- package/plugins/lisa-cursor/agents/verification-specialist.md +135 -0
- package/plugins/lisa-cursor/commands/automation-status.md +12 -0
- package/plugins/lisa-cursor/commands/codify-verification.md +6 -0
- package/plugins/lisa-cursor/commands/debrief/apply.md +6 -0
- package/plugins/lisa-cursor/commands/debrief.md +6 -0
- package/plugins/lisa-cursor/commands/doctor.md +6 -0
- package/plugins/lisa-cursor/commands/fix/linter-error.md +7 -0
- package/plugins/lisa-cursor/commands/git/commit.md +7 -0
- package/plugins/lisa-cursor/commands/git/prune.md +6 -0
- package/plugins/lisa-cursor/commands/git/submit-pr.md +7 -0
- package/plugins/lisa-cursor/commands/implement.md +6 -0
- package/plugins/lisa-cursor/commands/improve/code-complexity.md +6 -0
- package/plugins/lisa-cursor/commands/improve/max-lines-per-function.md +7 -0
- package/plugins/lisa-cursor/commands/improve/max-lines.md +7 -0
- package/plugins/lisa-cursor/commands/improve/test-coverage.md +7 -0
- package/plugins/lisa-cursor/commands/improve/tests.md +7 -0
- package/plugins/lisa-cursor/commands/intake-explain.md +31 -0
- package/plugins/lisa-cursor/commands/intake.md +6 -0
- package/plugins/lisa-cursor/commands/monitor.md +6 -0
- package/plugins/lisa-cursor/commands/plan.md +6 -0
- package/plugins/lisa-cursor/commands/plugin-sync-explain.md +8 -0
- package/plugins/lisa-cursor/commands/product-walkthrough.md +7 -0
- package/plugins/lisa-cursor/commands/project-ideation.md +6 -0
- package/plugins/lisa-cursor/commands/pull-request/review.md +7 -0
- package/plugins/lisa-cursor/commands/queue-status.md +34 -0
- package/plugins/lisa-cursor/commands/repair-intake.md +6 -0
- package/plugins/lisa-cursor/commands/research.md +6 -0
- package/plugins/lisa-cursor/commands/review/local.md +6 -0
- package/plugins/lisa-cursor/commands/security/zap-scan.md +6 -0
- package/plugins/lisa-cursor/commands/setup/atlassian.md +7 -0
- package/plugins/lisa-cursor/commands/setup/confluence.md +7 -0
- package/plugins/lisa-cursor/commands/setup/github.md +7 -0
- package/plugins/lisa-cursor/commands/setup/jira.md +7 -0
- package/plugins/lisa-cursor/commands/setup/linear.md +7 -0
- package/plugins/lisa-cursor/commands/setup/notion.md +7 -0
- package/plugins/lisa-cursor/commands/setup-automations.md +6 -0
- package/plugins/lisa-cursor/commands/tear-down-automations.md +6 -0
- package/plugins/lisa-cursor/commands/verify-prd.md +6 -0
- package/plugins/lisa-cursor/commands/verify.md +6 -0
- package/plugins/lisa-cursor/commands/wiki/install.md +7 -0
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +37 -0
- package/plugins/lisa-cursor/hooks/install-pkgs.sh +69 -0
- package/plugins/lisa-cursor/hooks/notify-ntfy.sh +183 -0
- package/plugins/lisa-cursor/hooks/setup-jira-cli.sh +51 -0
- package/plugins/lisa-cursor/rules/eager/base-rules.md +70 -0
- package/plugins/lisa-cursor/rules/eager/coding-philosophy.md +27 -0
- package/plugins/lisa-cursor/rules/eager/config-resolution.md +28 -0
- package/plugins/lisa-cursor/rules/eager/documentation-source-paths.md +13 -0
- package/plugins/lisa-cursor/rules/eager/empirical-inquiry.md +22 -0
- package/plugins/lisa-cursor/rules/eager/intent-routing.md +18 -0
- package/plugins/lisa-cursor/rules/eager/leaf-only-lifecycle.md +39 -0
- package/plugins/lisa-cursor/rules/eager/prd-lifecycle-rollup.md +31 -0
- package/plugins/lisa-cursor/rules/eager/repo-scope-split.md +39 -0
- package/plugins/lisa-cursor/rules/eager/security-audit-handling.md +29 -0
- package/plugins/lisa-cursor/rules/eager/usage-accounting.md +28 -0
- package/plugins/lisa-cursor/rules/eager/verification.md +21 -0
- package/plugins/lisa-cursor/rules/eager/wiki-knowledge-source.md +16 -0
- package/plugins/lisa-cursor/rules/reference/base-rules.md +133 -0
- package/plugins/lisa-cursor/rules/reference/coding-philosophy.md +428 -0
- package/plugins/lisa-cursor/rules/reference/config-resolution.md +691 -0
- package/plugins/lisa-cursor/rules/reference/documentation-source-paths.md +13 -0
- package/plugins/lisa-cursor/rules/reference/empirical-inquiry.md +27 -0
- package/plugins/lisa-cursor/rules/reference/intent-routing.md +407 -0
- package/plugins/lisa-cursor/rules/reference/leaf-only-lifecycle.md +120 -0
- package/plugins/lisa-cursor/rules/reference/prd-lifecycle-rollup.md +156 -0
- package/plugins/lisa-cursor/rules/reference/repo-scope-split.md +58 -0
- package/plugins/lisa-cursor/rules/reference/security-audit-handling.md +30 -0
- package/plugins/lisa-cursor/rules/reference/usage-accounting.md +144 -0
- package/plugins/lisa-cursor/rules/reference/verification.md +124 -0
- package/plugins/lisa-cursor/rules/reference/wiki-knowledge-source.md +14 -0
- package/plugins/lisa-cursor/scripts/automation-status-claude-adapter.mjs +672 -0
- package/plugins/lisa-cursor/scripts/automation-status-codex-adapter.mjs +697 -0
- package/plugins/lisa-cursor/scripts/automation-status-contract-drift.mjs +392 -0
- package/plugins/lisa-cursor/scripts/automation-status-expected-fleet.mjs +319 -0
- package/plugins/lisa-cursor/scripts/automation-status-report.mjs +170 -0
- package/plugins/lisa-cursor/scripts/doctor-report.mjs +143 -0
- package/plugins/lisa-cursor/scripts/plugin-sync-explain.mjs +512 -0
- package/plugins/lisa-cursor/scripts/project-ideation-idempotency-harness.mjs +319 -0
- package/plugins/lisa-cursor/scripts/queue-contract-resolution.mjs +453 -0
- package/plugins/lisa-cursor/scripts/queue-health-classification.mjs +157 -0
- package/plugins/lisa-cursor/scripts/queue-status-build-readers.mjs +509 -0
- package/plugins/lisa-cursor/scripts/queue-status-prd-readers.mjs +452 -0
- package/plugins/lisa-cursor/skills/acceptance-criteria/SKILL.md +71 -0
- package/plugins/lisa-cursor/skills/agent-design-best-practices/SKILL.md +219 -0
- package/plugins/lisa-cursor/skills/atlassian-access/SKILL.md +293 -0
- package/plugins/lisa-cursor/skills/automation-status/SKILL.md +111 -0
- package/plugins/lisa-cursor/skills/bug-triage/SKILL.md +23 -0
- package/plugins/lisa-cursor/skills/codebase-research/SKILL.md +87 -0
- package/plugins/lisa-cursor/skills/codify-verification/SKILL.md +152 -0
- package/plugins/lisa-cursor/skills/confluence-prd-intake/SKILL.md +417 -0
- package/plugins/lisa-cursor/skills/confluence-to-tracker/SKILL.md +360 -0
- package/plugins/lisa-cursor/skills/confluence-write-prd/SKILL.md +109 -0
- package/plugins/lisa-cursor/skills/debrief/SKILL.md +94 -0
- package/plugins/lisa-cursor/skills/debrief-apply/SKILL.md +63 -0
- package/plugins/lisa-cursor/skills/doctor/SKILL.md +317 -0
- package/plugins/lisa-cursor/skills/epic-triage/SKILL.md +28 -0
- package/plugins/lisa-cursor/skills/fix-linter-error/SKILL.md +45 -0
- package/plugins/lisa-cursor/skills/git-commit/SKILL.md +48 -0
- package/plugins/lisa-cursor/skills/git-prune/SKILL.md +35 -0
- package/plugins/lisa-cursor/skills/git-submit-pr/SKILL.md +105 -0
- package/plugins/lisa-cursor/skills/github-add-journey/SKILL.md +115 -0
- package/plugins/lisa-cursor/skills/github-build-intake/SKILL.md +377 -0
- package/plugins/lisa-cursor/skills/github-create/SKILL.md +101 -0
- package/plugins/lisa-cursor/skills/github-evidence/SKILL.md +110 -0
- package/plugins/lisa-cursor/skills/github-journey/SKILL.md +121 -0
- package/plugins/lisa-cursor/skills/github-prd-intake/SKILL.md +432 -0
- package/plugins/lisa-cursor/skills/github-project-v2/SKILL.md +227 -0
- package/plugins/lisa-cursor/skills/github-read-issue/SKILL.md +248 -0
- package/plugins/lisa-cursor/skills/github-sync/SKILL.md +119 -0
- package/plugins/lisa-cursor/skills/github-to-tracker/SKILL.md +345 -0
- package/plugins/lisa-cursor/skills/github-validate-issue/SKILL.md +331 -0
- package/plugins/lisa-cursor/skills/github-verify/SKILL.md +29 -0
- package/plugins/lisa-cursor/skills/github-write-issue/SKILL.md +339 -0
- package/plugins/lisa-cursor/skills/github-write-prd/SKILL.md +157 -0
- package/plugins/lisa-cursor/skills/implement/SKILL.md +145 -0
- package/plugins/lisa-cursor/skills/improve-code-complexity/SKILL.md +44 -0
- package/plugins/lisa-cursor/skills/improve-max-lines/SKILL.md +45 -0
- package/plugins/lisa-cursor/skills/improve-max-lines-per-function/SKILL.md +46 -0
- package/plugins/lisa-cursor/skills/improve-test-coverage/SKILL.md +44 -0
- package/plugins/lisa-cursor/skills/improve-tests/SKILL.md +47 -0
- package/plugins/lisa-cursor/skills/intake/SKILL.md +132 -0
- package/plugins/lisa-cursor/skills/intake-explain/SKILL.md +279 -0
- package/plugins/lisa-cursor/skills/jira-add-journey/SKILL.md +121 -0
- package/plugins/lisa-cursor/skills/jira-build-intake/SKILL.md +286 -0
- package/plugins/lisa-cursor/skills/jira-create/SKILL.md +154 -0
- package/plugins/lisa-cursor/skills/jira-evidence/SKILL.md +90 -0
- package/plugins/lisa-cursor/skills/jira-evidence/scripts/post-evidence.sh +163 -0
- package/plugins/lisa-cursor/skills/jira-journey/SKILL.md +127 -0
- package/plugins/lisa-cursor/skills/jira-journey/scripts/generate-templates.py +233 -0
- package/plugins/lisa-cursor/skills/jira-journey/scripts/parse-plan.py +368 -0
- package/plugins/lisa-cursor/skills/jira-read-ticket/SKILL.md +198 -0
- package/plugins/lisa-cursor/skills/jira-read-ticket/scripts/download-attachment.sh +110 -0
- package/plugins/lisa-cursor/skills/jira-sync/SKILL.md +95 -0
- package/plugins/lisa-cursor/skills/jira-validate-ticket/SKILL.md +318 -0
- package/plugins/lisa-cursor/skills/jira-verify/SKILL.md +30 -0
- package/plugins/lisa-cursor/skills/jira-write-ticket/SKILL.md +265 -0
- package/plugins/lisa-cursor/skills/jsdoc-best-practices/SKILL.md +432 -0
- package/plugins/lisa-cursor/skills/linear-add-journey/SKILL.md +105 -0
- package/plugins/lisa-cursor/skills/linear-build-intake/SKILL.md +283 -0
- package/plugins/lisa-cursor/skills/linear-create/SKILL.md +146 -0
- package/plugins/lisa-cursor/skills/linear-evidence/SKILL.md +103 -0
- package/plugins/lisa-cursor/skills/linear-journey/SKILL.md +134 -0
- package/plugins/lisa-cursor/skills/linear-prd-intake/SKILL.md +383 -0
- package/plugins/lisa-cursor/skills/linear-read-issue/SKILL.md +200 -0
- package/plugins/lisa-cursor/skills/linear-sync/SKILL.md +114 -0
- package/plugins/lisa-cursor/skills/linear-to-tracker/SKILL.md +342 -0
- package/plugins/lisa-cursor/skills/linear-validate-issue/SKILL.md +313 -0
- package/plugins/lisa-cursor/skills/linear-verify/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/linear-write-issue/SKILL.md +292 -0
- package/plugins/lisa-cursor/skills/linear-write-prd/SKILL.md +96 -0
- package/plugins/lisa-cursor/skills/lisa-review-implementation/SKILL.md +209 -0
- package/plugins/lisa-cursor/skills/monitor/SKILL.md +48 -0
- package/plugins/lisa-cursor/skills/nightly-add-test-coverage/SKILL.md +40 -0
- package/plugins/lisa-cursor/skills/nightly-improve-tests/SKILL.md +29 -0
- package/plugins/lisa-cursor/skills/nightly-lower-code-complexity/SKILL.md +28 -0
- package/plugins/lisa-cursor/skills/notion-access/SKILL.md +226 -0
- package/plugins/lisa-cursor/skills/notion-prd-intake/SKILL.md +360 -0
- package/plugins/lisa-cursor/skills/notion-to-tracker/SKILL.md +357 -0
- package/plugins/lisa-cursor/skills/notion-write-prd/SKILL.md +109 -0
- package/plugins/lisa-cursor/skills/performance-review/SKILL.md +94 -0
- package/plugins/lisa-cursor/skills/plan/SKILL.md +60 -0
- package/plugins/lisa-cursor/skills/plugin-sync-explain/SKILL.md +53 -0
- package/plugins/lisa-cursor/skills/prd-backlink/SKILL.md +265 -0
- package/plugins/lisa-cursor/skills/prd-source-write/SKILL.md +101 -0
- package/plugins/lisa-cursor/skills/prd-ticket-coverage/SKILL.md +170 -0
- package/plugins/lisa-cursor/skills/product-walkthrough/SKILL.md +129 -0
- package/plugins/lisa-cursor/skills/project-ideation/SKILL.md +315 -0
- package/plugins/lisa-cursor/skills/project-ideation/examples/evidence-card-format.md +21 -0
- package/plugins/lisa-cursor/skills/project-ideation/examples/host-project-only.md +22 -0
- package/plugins/lisa-cursor/skills/project-ideation/examples/idempotency-verification-harness.md +57 -0
- package/plugins/lisa-cursor/skills/project-ideation/examples/public-external-inspiration.md +22 -0
- package/plugins/lisa-cursor/skills/project-ideation/examples/unavailable-data-rejection.md +22 -0
- package/plugins/lisa-cursor/skills/pull-request-review/SKILL.md +68 -0
- package/plugins/lisa-cursor/skills/quality-review/SKILL.md +54 -0
- package/plugins/lisa-cursor/skills/queue-status/SKILL.md +133 -0
- package/plugins/lisa-cursor/skills/repair-intake/SKILL.md +584 -0
- package/plugins/lisa-cursor/skills/reproduce-bug/SKILL.md +96 -0
- package/plugins/lisa-cursor/skills/research/SKILL.md +68 -0
- package/plugins/lisa-cursor/skills/review-local/SKILL.md +88 -0
- package/plugins/lisa-cursor/skills/root-cause-analysis/SKILL.md +155 -0
- package/plugins/lisa-cursor/skills/security-review/SKILL.md +57 -0
- package/plugins/lisa-cursor/skills/security-zap-scan/SKILL.md +33 -0
- package/plugins/lisa-cursor/skills/setup-atlassian/SKILL.md +347 -0
- package/plugins/lisa-cursor/skills/setup-automations/SKILL.md +99 -0
- package/plugins/lisa-cursor/skills/setup-confluence/SKILL.md +254 -0
- package/plugins/lisa-cursor/skills/setup-github/SKILL.md +268 -0
- package/plugins/lisa-cursor/skills/setup-jira/SKILL.md +198 -0
- package/plugins/lisa-cursor/skills/setup-linear/SKILL.md +251 -0
- package/plugins/lisa-cursor/skills/setup-notion/SKILL.md +316 -0
- package/plugins/lisa-cursor/skills/spec-conformance/SKILL.md +159 -0
- package/plugins/lisa-cursor/skills/task-decomposition/SKILL.md +127 -0
- package/plugins/lisa-cursor/skills/task-triage/SKILL.md +23 -0
- package/plugins/lisa-cursor/skills/tdd-implementation/SKILL.md +83 -0
- package/plugins/lisa-cursor/skills/tear-down-automations/SKILL.md +34 -0
- package/plugins/lisa-cursor/skills/test-strategy/SKILL.md +63 -0
- package/plugins/lisa-cursor/skills/ticket-triage/SKILL.md +182 -0
- package/plugins/lisa-cursor/skills/tracker-add-journey/SKILL.md +26 -0
- package/plugins/lisa-cursor/skills/tracker-build-intake/SKILL.md +64 -0
- package/plugins/lisa-cursor/skills/tracker-create/SKILL.md +26 -0
- package/plugins/lisa-cursor/skills/tracker-evidence/SKILL.md +52 -0
- package/plugins/lisa-cursor/skills/tracker-journey/SKILL.md +26 -0
- package/plugins/lisa-cursor/skills/tracker-read/SKILL.md +27 -0
- package/plugins/lisa-cursor/skills/tracker-source-artifacts/SKILL.md +107 -0
- package/plugins/lisa-cursor/skills/tracker-sync/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/tracker-validate/SKILL.md +36 -0
- package/plugins/lisa-cursor/skills/tracker-verify/SKILL.md +27 -0
- package/plugins/lisa-cursor/skills/tracker-write/SKILL.md +53 -0
- package/plugins/lisa-cursor/skills/usage-accounting/SKILL.md +170 -0
- package/plugins/lisa-cursor/skills/verification-lifecycle/SKILL.md +339 -0
- package/plugins/lisa-cursor/skills/verify/SKILL.md +49 -0
- package/plugins/lisa-cursor/skills/verify-prd/SKILL.md +392 -0
- package/plugins/lisa-cursor/skills/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-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/hooks/inject-rules.sh +16 -0
- package/plugins/lisa-harper-fabric/.codex-plugin/hooks.json +26 -0
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +2 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/hooks/block-migration-edits.sh +60 -0
- package/plugins/lisa-nestjs/.codex-plugin/hooks.json +15 -0
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +2 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/hooks/inject-rules.sh +22 -0
- package/plugins/lisa-rails/.codex-plugin/hooks/rubocop-on-edit.sh +78 -0
- package/plugins/lisa-rails/.codex-plugin/hooks/sg-scan-on-edit.sh +74 -0
- package/plugins/lisa-rails/.codex-plugin/hooks.json +41 -0
- package/plugins/lisa-rails/.codex-plugin/plugin.json +2 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/hooks/block-suppress-directives.sh +73 -0
- package/plugins/lisa-typescript/.codex-plugin/hooks/format-on-edit.sh +79 -0
- package/plugins/lisa-typescript/.codex-plugin/hooks/lint-on-edit.sh +134 -0
- package/plugins/lisa-typescript/.codex-plugin/hooks/sg-scan-on-edit.sh +71 -0
- package/plugins/lisa-typescript/.codex-plugin/hooks.json +34 -0
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +2 -1
- package/plugins/lisa-typescript/hooks/format-on-edit.sh +5 -3
- package/plugins/lisa-typescript/hooks/lint-on-edit.sh +5 -2
- package/plugins/lisa-typescript/hooks/sg-scan-on-edit.sh +5 -2
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/src/typescript/hooks/format-on-edit.sh +5 -3
- package/plugins/src/typescript/hooks/lint-on-edit.sh +5 -2
- package/plugins/src/typescript/hooks/sg-scan-on-edit.sh +5 -2
- package/scripts/build-plugins.sh +24 -0
- package/scripts/generate-agy-plugin-artifacts.mjs +168 -0
- package/scripts/generate-codex-plugin-artifacts.mjs +170 -12
- package/scripts/generate-copilot-plugin-artifacts.mjs +230 -0
- package/scripts/generate-cursor-plugin-artifacts.mjs +173 -0
- package/scripts/internal-agy-skill-policy.json +3 -0
- package/scripts/internal-copilot-runtime-probe.json +7 -0
- package/scripts/internal-copilot-skill-policy.json +3 -0
- package/scripts/internal-cursor-skill-policy.json +3 -0
- package/scripts/lib/per-agent-hook-filter.mjs +249 -0
- package/scripts/probes/wave3-verification.sh +106 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Parse the Validation Journey section from a JIRA ticket description.
|
|
3
|
+
|
|
4
|
+
Fetches the ticket via REST API, extracts the Validation Journey section
|
|
5
|
+
(ADF or wiki markup), and outputs structured JSON to stdout.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python3 parse-plan.py <TICKET_ID>
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
python3 parse-plan.py SE-3820
|
|
12
|
+
|
|
13
|
+
Output (JSON):
|
|
14
|
+
{
|
|
15
|
+
"ticket": "SE-3820",
|
|
16
|
+
"prerequisites": ["Backend running", "Admin user"],
|
|
17
|
+
"steps": [
|
|
18
|
+
{"number": 1, "text": "Navigate to page", "screenshot": null},
|
|
19
|
+
{"number": 2, "text": "Click button [EVIDENCE: btn]", "screenshot": "btn"}
|
|
20
|
+
],
|
|
21
|
+
"viewports": [
|
|
22
|
+
{"name": "Desktop", "width": 1512, "height": 768}
|
|
23
|
+
],
|
|
24
|
+
"assertions": ["Modal fills screen"]
|
|
25
|
+
}
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
import json
|
|
29
|
+
import os
|
|
30
|
+
import re
|
|
31
|
+
import subprocess
|
|
32
|
+
import sys
|
|
33
|
+
import urllib.request
|
|
34
|
+
from base64 import b64encode
|
|
35
|
+
from pathlib import Path
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_jira_config():
|
|
39
|
+
"""Read JIRA server and login from jira-cli config."""
|
|
40
|
+
config_path = Path.home() / ".config" / ".jira" / ".config.yml"
|
|
41
|
+
if not config_path.exists():
|
|
42
|
+
print(f"ERROR: jira-cli config not found at {config_path}", file=sys.stderr)
|
|
43
|
+
sys.exit(1)
|
|
44
|
+
|
|
45
|
+
server = ""
|
|
46
|
+
login = ""
|
|
47
|
+
with open(config_path) as f:
|
|
48
|
+
for line in f:
|
|
49
|
+
if line.startswith("server:"):
|
|
50
|
+
server = line.split(":", 1)[1].strip()
|
|
51
|
+
elif line.startswith("login:"):
|
|
52
|
+
login = line.split(":", 1)[1].strip()
|
|
53
|
+
|
|
54
|
+
token = os.environ.get("JIRA_API_TOKEN", "")
|
|
55
|
+
if not token:
|
|
56
|
+
print("ERROR: JIRA_API_TOKEN env var not set", file=sys.stderr)
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
|
|
59
|
+
return server, login, token
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def fetch_ticket(server, login, token, ticket_id):
|
|
63
|
+
"""Fetch JIRA ticket via REST API v3 (returns ADF description)."""
|
|
64
|
+
url = f"{server}/rest/api/3/issue/{ticket_id}?fields=description"
|
|
65
|
+
auth = b64encode(f"{login}:{token}".encode()).decode()
|
|
66
|
+
|
|
67
|
+
req = urllib.request.Request(url, headers={
|
|
68
|
+
"Authorization": f"Basic {auth}",
|
|
69
|
+
"Accept": "application/json",
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
with urllib.request.urlopen(req) as resp:
|
|
74
|
+
return json.loads(resp.read().decode())
|
|
75
|
+
except urllib.error.HTTPError as e:
|
|
76
|
+
print(f"ERROR: JIRA API returned {e.code} for {ticket_id}", file=sys.stderr)
|
|
77
|
+
sys.exit(1)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def extract_text_from_adf(node):
|
|
81
|
+
"""Recursively extract plain text from an ADF node."""
|
|
82
|
+
if isinstance(node, str):
|
|
83
|
+
return node
|
|
84
|
+
|
|
85
|
+
if isinstance(node, dict):
|
|
86
|
+
node_type = node.get("type", "")
|
|
87
|
+
|
|
88
|
+
if node_type == "text":
|
|
89
|
+
return node.get("text", "")
|
|
90
|
+
|
|
91
|
+
if node_type == "hardBreak":
|
|
92
|
+
return "\n"
|
|
93
|
+
|
|
94
|
+
parts = []
|
|
95
|
+
for child in node.get("content", []):
|
|
96
|
+
parts.append(extract_text_from_adf(child))
|
|
97
|
+
return "".join(parts)
|
|
98
|
+
|
|
99
|
+
if isinstance(node, list):
|
|
100
|
+
return "".join(extract_text_from_adf(item) for item in node)
|
|
101
|
+
|
|
102
|
+
return ""
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def find_heading_index(content, heading_text, level=None):
|
|
106
|
+
"""Find the index of a heading node matching the given text."""
|
|
107
|
+
for i, node in enumerate(content):
|
|
108
|
+
if node.get("type") != "heading":
|
|
109
|
+
continue
|
|
110
|
+
if level is not None and node.get("attrs", {}).get("level") != level:
|
|
111
|
+
continue
|
|
112
|
+
text = extract_text_from_adf(node).strip().lower()
|
|
113
|
+
if heading_text.lower() in text:
|
|
114
|
+
return i
|
|
115
|
+
return -1
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def extract_section_content(content, start_idx, same_level=True):
|
|
119
|
+
"""Extract all nodes between a heading and the next heading of same or higher level."""
|
|
120
|
+
if start_idx < 0 or start_idx >= len(content):
|
|
121
|
+
return []
|
|
122
|
+
|
|
123
|
+
heading_level = content[start_idx].get("attrs", {}).get("level", 2)
|
|
124
|
+
nodes = []
|
|
125
|
+
|
|
126
|
+
for i in range(start_idx + 1, len(content)):
|
|
127
|
+
node = content[i]
|
|
128
|
+
if node.get("type") == "heading":
|
|
129
|
+
node_level = node.get("attrs", {}).get("level", 2)
|
|
130
|
+
if same_level and node_level <= heading_level:
|
|
131
|
+
break
|
|
132
|
+
nodes.append(node)
|
|
133
|
+
|
|
134
|
+
return nodes
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def parse_prerequisites(nodes):
|
|
138
|
+
"""Extract prerequisite strings from ADF nodes (bullet lists or paragraphs)."""
|
|
139
|
+
prerequisites = []
|
|
140
|
+
for node in nodes:
|
|
141
|
+
if node.get("type") == "bulletList":
|
|
142
|
+
for item in node.get("content", []):
|
|
143
|
+
text = extract_text_from_adf(item).strip()
|
|
144
|
+
if text:
|
|
145
|
+
prerequisites.append(text)
|
|
146
|
+
elif node.get("type") == "paragraph":
|
|
147
|
+
text = extract_text_from_adf(node).strip()
|
|
148
|
+
if text:
|
|
149
|
+
prerequisites.append(text)
|
|
150
|
+
return prerequisites
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def clean_step_text(text, screenshot_name):
|
|
154
|
+
"""Remove [SCREENSHOT: ...] or [EVIDENCE: ...] marker from step text and deduplicate."""
|
|
155
|
+
# Remove the marker itself
|
|
156
|
+
cleaned = re.sub(r'\[(SCREENSHOT|EVIDENCE):\s*[^\]]+\]\s*', '', text).strip()
|
|
157
|
+
|
|
158
|
+
# Deduplicate: if the same phrase appears twice consecutively, keep one
|
|
159
|
+
# This handles ADF text node concatenation artifacts
|
|
160
|
+
words = cleaned.split()
|
|
161
|
+
mid = len(words) // 2
|
|
162
|
+
if mid > 2 and words[:mid] == words[mid:2 * mid]:
|
|
163
|
+
cleaned = " ".join(words[:mid] + words[2 * mid:])
|
|
164
|
+
|
|
165
|
+
return cleaned
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def parse_steps(nodes):
|
|
169
|
+
"""Extract ordered steps with optional [SCREENSHOT: name] or [EVIDENCE: name] markers."""
|
|
170
|
+
steps = []
|
|
171
|
+
step_number = 0
|
|
172
|
+
|
|
173
|
+
for node in nodes:
|
|
174
|
+
if node.get("type") == "orderedList":
|
|
175
|
+
for item in node.get("content", []):
|
|
176
|
+
step_number += 1
|
|
177
|
+
text = extract_text_from_adf(item).strip()
|
|
178
|
+
|
|
179
|
+
screenshot = None
|
|
180
|
+
match = re.search(r'\[(SCREENSHOT|EVIDENCE):\s*([^\]]+)\]', text)
|
|
181
|
+
if match:
|
|
182
|
+
screenshot = match.group(2).strip()
|
|
183
|
+
|
|
184
|
+
display_text = clean_step_text(text, screenshot) if screenshot else text
|
|
185
|
+
|
|
186
|
+
steps.append({
|
|
187
|
+
"number": step_number,
|
|
188
|
+
"text": display_text,
|
|
189
|
+
"screenshot": screenshot,
|
|
190
|
+
})
|
|
191
|
+
elif node.get("type") == "paragraph":
|
|
192
|
+
text = extract_text_from_adf(node).strip()
|
|
193
|
+
if text and re.match(r'^\d+\.?\s', text):
|
|
194
|
+
step_number += 1
|
|
195
|
+
screenshot = None
|
|
196
|
+
match = re.search(r'\[(SCREENSHOT|EVIDENCE):\s*([^\]]+)\]', text)
|
|
197
|
+
if match:
|
|
198
|
+
screenshot = match.group(2).strip()
|
|
199
|
+
|
|
200
|
+
clean_text = re.sub(r'^\d+\.?\s*', '', text)
|
|
201
|
+
display_text = clean_step_text(clean_text, screenshot) if screenshot else clean_text
|
|
202
|
+
steps.append({
|
|
203
|
+
"number": step_number,
|
|
204
|
+
"text": display_text,
|
|
205
|
+
"screenshot": screenshot,
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
return steps
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def parse_viewports(nodes):
|
|
212
|
+
"""Extract viewport definitions from ADF table nodes.
|
|
213
|
+
|
|
214
|
+
Supports two table formats:
|
|
215
|
+
- 3 columns: Name | Width | Height
|
|
216
|
+
- 2 columns: Name | Resolution (WxH)
|
|
217
|
+
"""
|
|
218
|
+
viewports = []
|
|
219
|
+
|
|
220
|
+
for node in nodes:
|
|
221
|
+
if node.get("type") == "table":
|
|
222
|
+
rows = node.get("content", [])
|
|
223
|
+
for row in rows:
|
|
224
|
+
if row.get("type") != "tableRow":
|
|
225
|
+
continue
|
|
226
|
+
|
|
227
|
+
cells = row.get("content", [])
|
|
228
|
+
if not cells:
|
|
229
|
+
continue
|
|
230
|
+
|
|
231
|
+
# Skip header row (tableHeader cells)
|
|
232
|
+
if cells[0].get("type") == "tableHeader":
|
|
233
|
+
continue
|
|
234
|
+
|
|
235
|
+
cell_texts = [extract_text_from_adf(c).strip() for c in cells]
|
|
236
|
+
|
|
237
|
+
# 3-column format: Name | Width | Height
|
|
238
|
+
if len(cell_texts) >= 3:
|
|
239
|
+
name = cell_texts[0]
|
|
240
|
+
try:
|
|
241
|
+
width = int(cell_texts[1])
|
|
242
|
+
height = int(cell_texts[2])
|
|
243
|
+
viewports.append({
|
|
244
|
+
"name": name,
|
|
245
|
+
"width": width,
|
|
246
|
+
"height": height,
|
|
247
|
+
})
|
|
248
|
+
continue
|
|
249
|
+
except ValueError:
|
|
250
|
+
pass
|
|
251
|
+
|
|
252
|
+
# 2-column format: Name | WxH (e.g., "1512x768")
|
|
253
|
+
if len(cell_texts) >= 2:
|
|
254
|
+
name = cell_texts[0]
|
|
255
|
+
resolution = cell_texts[1]
|
|
256
|
+
match = re.match(r'(\d+)\s*[xX×]\s*(\d+)', resolution)
|
|
257
|
+
if match:
|
|
258
|
+
viewports.append({
|
|
259
|
+
"name": name,
|
|
260
|
+
"width": int(match.group(1)),
|
|
261
|
+
"height": int(match.group(2)),
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
return viewports
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def parse_assertions(nodes):
|
|
268
|
+
"""Extract assertion strings from ADF nodes."""
|
|
269
|
+
assertions = []
|
|
270
|
+
for node in nodes:
|
|
271
|
+
if node.get("type") == "bulletList":
|
|
272
|
+
for item in node.get("content", []):
|
|
273
|
+
text = extract_text_from_adf(item).strip()
|
|
274
|
+
if text:
|
|
275
|
+
assertions.append(text)
|
|
276
|
+
elif node.get("type") == "orderedList":
|
|
277
|
+
for item in node.get("content", []):
|
|
278
|
+
text = extract_text_from_adf(item).strip()
|
|
279
|
+
if text:
|
|
280
|
+
assertions.append(text)
|
|
281
|
+
elif node.get("type") == "paragraph":
|
|
282
|
+
text = extract_text_from_adf(node).strip()
|
|
283
|
+
if text and text.startswith("-"):
|
|
284
|
+
assertions.append(text.lstrip("- ").strip())
|
|
285
|
+
elif text:
|
|
286
|
+
assertions.append(text)
|
|
287
|
+
return assertions
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def parse_adf_journey(description_adf):
|
|
291
|
+
"""Parse the Validation Journey from an ADF description object."""
|
|
292
|
+
content = description_adf.get("content", [])
|
|
293
|
+
|
|
294
|
+
# Find the "Validation Journey" h2 heading
|
|
295
|
+
journey_idx = find_heading_index(content, "validation journey", level=2)
|
|
296
|
+
if journey_idx < 0:
|
|
297
|
+
# Try without level constraint
|
|
298
|
+
journey_idx = find_heading_index(content, "validation journey")
|
|
299
|
+
|
|
300
|
+
if journey_idx < 0:
|
|
301
|
+
print("ERROR: No 'Validation Journey' section found in ticket description", file=sys.stderr)
|
|
302
|
+
sys.exit(1)
|
|
303
|
+
|
|
304
|
+
# Extract sub-sections
|
|
305
|
+
prereq_idx = find_heading_index(content, "prerequisites", level=3)
|
|
306
|
+
steps_idx = find_heading_index(content, "steps", level=3)
|
|
307
|
+
viewports_idx = find_heading_index(content, "viewports", level=3)
|
|
308
|
+
assertions_idx = find_heading_index(content, "assertions", level=3)
|
|
309
|
+
|
|
310
|
+
prerequisites = []
|
|
311
|
+
if prereq_idx >= 0:
|
|
312
|
+
prereq_nodes = extract_section_content(content, prereq_idx)
|
|
313
|
+
prerequisites = parse_prerequisites(prereq_nodes)
|
|
314
|
+
|
|
315
|
+
steps = []
|
|
316
|
+
if steps_idx >= 0:
|
|
317
|
+
steps_nodes = extract_section_content(content, steps_idx)
|
|
318
|
+
steps = parse_steps(steps_nodes)
|
|
319
|
+
|
|
320
|
+
viewports = []
|
|
321
|
+
if viewports_idx >= 0:
|
|
322
|
+
viewport_nodes = extract_section_content(content, viewports_idx)
|
|
323
|
+
viewports = parse_viewports(viewport_nodes)
|
|
324
|
+
|
|
325
|
+
assertions = []
|
|
326
|
+
if assertions_idx >= 0:
|
|
327
|
+
assertion_nodes = extract_section_content(content, assertions_idx)
|
|
328
|
+
assertions = parse_assertions(assertion_nodes)
|
|
329
|
+
|
|
330
|
+
# Fallback: if no viewports defined, use Desktop as default
|
|
331
|
+
if not viewports:
|
|
332
|
+
viewports = [{"name": "Desktop", "width": 1512, "height": 768}]
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
"prerequisites": prerequisites,
|
|
336
|
+
"steps": steps,
|
|
337
|
+
"viewports": viewports,
|
|
338
|
+
"assertions": assertions,
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def main():
|
|
343
|
+
if len(sys.argv) < 2:
|
|
344
|
+
print("Usage: parse-plan.py <TICKET_ID>", file=sys.stderr)
|
|
345
|
+
sys.exit(1)
|
|
346
|
+
|
|
347
|
+
ticket_id = sys.argv[1]
|
|
348
|
+
server, login, token = get_jira_config()
|
|
349
|
+
ticket_data = fetch_ticket(server, login, token, ticket_id)
|
|
350
|
+
|
|
351
|
+
description = ticket_data.get("fields", {}).get("description")
|
|
352
|
+
if not description:
|
|
353
|
+
print(f"ERROR: Ticket {ticket_id} has no description", file=sys.stderr)
|
|
354
|
+
sys.exit(1)
|
|
355
|
+
|
|
356
|
+
# ADF description is a dict, wiki markup is a string
|
|
357
|
+
if isinstance(description, dict):
|
|
358
|
+
result = parse_adf_journey(description)
|
|
359
|
+
else:
|
|
360
|
+
print("ERROR: Wiki markup parsing not implemented. Use JIRA API v3 (ADF format).", file=sys.stderr)
|
|
361
|
+
sys.exit(1)
|
|
362
|
+
|
|
363
|
+
result["ticket"] = ticket_id
|
|
364
|
+
print(json.dumps(result, indent=2))
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
if __name__ == "__main__":
|
|
368
|
+
main()
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jira-read-ticket
|
|
3
|
+
description: "Fetches the full scope of a JIRA ticket — metadata, description, acceptance criteria, all comments, remote links (PRs, Confluence, dashboards), issue links (blocks/is blocked by/relates to/duplicates/clones), epic parent with siblings, and subtasks. Produces a consolidated context bundle that downstream agents consume so they never act on a single ticket in isolation."
|
|
4
|
+
allowed-tools: ["Bash", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Read JIRA Ticket: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
|
|
10
|
+
|
|
11
|
+
Fetch the full scope of the ticket AND its related graph. Downstream agents must never act on a ticket in isolation — always call this skill first so they see blockers, epic siblings, linked PRs, and historical comments.
|
|
12
|
+
|
|
13
|
+
Repository name for scoped comments and logs: `basename $(git rev-parse --show-toplevel)`.
|
|
14
|
+
|
|
15
|
+
## Phase 1 — Resolve Context
|
|
16
|
+
|
|
17
|
+
1. Invoke `lisa:atlassian-access` via the Skill tool with `operation: list-sites` to confirm the configured site is reachable and resolve the cloud ID.
|
|
18
|
+
2. If $ARGUMENTS is not a ticket key (e.g. `PROJ-123`), stop and report. Do NOT guess.
|
|
19
|
+
|
|
20
|
+
## Phase 2 — Fetch Primary Ticket
|
|
21
|
+
|
|
22
|
+
Invoke `lisa:atlassian-access` via the Skill tool with `operation: read-ticket key: <TICKET-KEY>` for the target ticket. Extract and preserve:
|
|
23
|
+
|
|
24
|
+
### Metadata
|
|
25
|
+
|
|
26
|
+
- Key, summary, issue type, status, resolution
|
|
27
|
+
- Priority, assignee, reporter, creator
|
|
28
|
+
- Labels, components, fix versions, affects versions
|
|
29
|
+
- Sprint, story points, original/remaining estimate
|
|
30
|
+
- Created, updated, resolved dates
|
|
31
|
+
- Parent (epic link or parent issue)
|
|
32
|
+
- Custom fields relevant to the project (read every custom field — do not filter)
|
|
33
|
+
|
|
34
|
+
### Body
|
|
35
|
+
|
|
36
|
+
- Full description (preserve formatting)
|
|
37
|
+
- Acceptance criteria section if separately structured
|
|
38
|
+
- **Validation Journey** section if present (pass verbatim to downstream)
|
|
39
|
+
- Attachments list — capture `id`, `filename`, `mimeType`, `size`, and `content` URL for each. Do not download unless a downstream task needs the bytes (see "Downloading attachments" below).
|
|
40
|
+
|
|
41
|
+
#### Downloading attachments (opt-in)
|
|
42
|
+
|
|
43
|
+
The Atlassian MCP exposes attachment metadata but no binary-fetch tool ([JRACLOUD-97830](https://jira.atlassian.com/browse/JRACLOUD-97830), [ECO-1265](https://jira.atlassian.com/browse/ECO-1265)). Fetch attachment bytes only when a downstream task explicitly needs them — e.g., a design-fidelity check on an image, log-file analysis, PDF text extraction. For everything else, keep the URL reference and move on.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bash .claude/skills/jira-read-ticket/scripts/download-attachment.sh <id-or-content-url> <output-path>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Requires `JIRA_SERVER`, `JIRA_LOGIN`, and `JIRA_API_TOKEN` in the environment (same contract as `jira-evidence`). If those are not set the helper exits with code 2 and a clear remediation message — record the URL only and continue.
|
|
50
|
+
|
|
51
|
+
After download, branch on `mimeType`:
|
|
52
|
+
- `image/*` — pass the local path to image-aware downstream tools
|
|
53
|
+
- `text/*`, `application/json`, `application/xml`, `application/x-yaml` — read inline as text
|
|
54
|
+
- `application/pdf` — extract text via downstream tooling if needed
|
|
55
|
+
- everything else — record path only; do not attempt to inline binary content
|
|
56
|
+
|
|
57
|
+
### Comments
|
|
58
|
+
|
|
59
|
+
Fetch ALL comments in chronological order. Do not truncate. For each:
|
|
60
|
+
- Author, timestamp, body
|
|
61
|
+
- Flag comments that contain: credentials, reproduction steps, status updates from stakeholders, decisions, or triage headers like `[repo-name]`
|
|
62
|
+
|
|
63
|
+
## Phase 3 — Fetch Remote Links
|
|
64
|
+
|
|
65
|
+
The primary ticket payload returned by `lisa:atlassian-access` `operation: read-ticket` includes the issue's remote links. If the substrate returns remote links separately, request them via `lisa:atlassian-access` with `operation: read-ticket key: <K>` (the operation MUST return remote links — extend `atlassian-access` if it doesn't). For each remote link:
|
|
66
|
+
|
|
67
|
+
- **GitHub PR or commit** (`github.com/.../(pull|commit)/...`): run `gh pr view <url> --json title,state,body,mergedAt,reviewDecision,comments,reviews` (for PRs) or `gh api repos/<owner>/<repo>/commits/<sha>` (for commits). Capture title, state, body, unresolved review comments, merge status.
|
|
68
|
+
- **Confluence page**: capture title and URL. Do not fetch body unless a downstream task explicitly needs it.
|
|
69
|
+
- **Dashboard, log link, or external URL**: capture title and URL only.
|
|
70
|
+
|
|
71
|
+
If `gh` is not authenticated, note "gh auth required" and continue — do not abort.
|
|
72
|
+
|
|
73
|
+
## Phase 4 — Fetch Issue Links (Relationships)
|
|
74
|
+
|
|
75
|
+
Every linked ticket must be fetched. Do not skip any link type. For each link in the primary ticket's `issuelinks` field, group by type:
|
|
76
|
+
|
|
77
|
+
- `blocks` / `is blocked by`
|
|
78
|
+
- `relates to`
|
|
79
|
+
- `duplicates` / `is duplicated by`
|
|
80
|
+
- `clones` / `is cloned by`
|
|
81
|
+
- Any other custom link types configured in the project
|
|
82
|
+
|
|
83
|
+
For each linked ticket, invoke `lisa:atlassian-access` with `operation: read-ticket key: <LINKED-KEY>` and capture:
|
|
84
|
+
|
|
85
|
+
- Key, summary, type, status, resolution
|
|
86
|
+
- Description (full, unless closed with resolution `Won't Do`/`Duplicate` — then summary only)
|
|
87
|
+
- Acceptance criteria
|
|
88
|
+
- Last 10 comments (chronological)
|
|
89
|
+
- Remote links (PR URLs and state only — skip deep fetch unless the link is `blocks` or `is blocked by`)
|
|
90
|
+
|
|
91
|
+
**Special handling for `is blocked by`:** fetch the full PR/commit details via `gh` for each blocker's remote links so the agent knows whether the blocker is actually shipped.
|
|
92
|
+
|
|
93
|
+
## Phase 5 — Fetch Epic Context
|
|
94
|
+
|
|
95
|
+
If the primary ticket has an epic parent (or IS an epic):
|
|
96
|
+
|
|
97
|
+
1. Fetch the epic itself via `lisa:atlassian-access` `operation: read-ticket key: <EPIC-KEY>` — full description, acceptance criteria, all comments, Validation Journey.
|
|
98
|
+
2. Find epic siblings via JQL:
|
|
99
|
+
```jql
|
|
100
|
+
"Epic Link" = <EPIC-KEY> AND key != <TICKET-KEY>
|
|
101
|
+
```
|
|
102
|
+
Invoke `lisa:atlassian-access` with `operation: search-issues jql: "<above-JQL>"`. For each sibling capture: key, summary, type, status, assignee, priority.
|
|
103
|
+
3. Read each sibling's description at a SUMMARY level (first paragraph only) — the goal is to surface related in-flight work, not duplicate full content. If a sibling is `In Progress` or `In Review` with an assignee different from the current ticket, flag it prominently.
|
|
104
|
+
|
|
105
|
+
If the primary ticket IS an epic, also fetch all children via the JQL above.
|
|
106
|
+
|
|
107
|
+
## Phase 6 — Fetch Subtasks
|
|
108
|
+
|
|
109
|
+
If the primary ticket has subtasks, fetch each via `lisa:atlassian-access` `operation: read-ticket key: <SUBTASK-KEY>`: key, summary, type, status, assignee, description (first paragraph), acceptance criteria.
|
|
110
|
+
|
|
111
|
+
## Phase 7 — Assemble Context Bundle
|
|
112
|
+
|
|
113
|
+
Produce a single structured output that the caller can pass verbatim to downstream agents. Use this format:
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
# Ticket Context: <KEY>
|
|
117
|
+
|
|
118
|
+
## Primary Ticket
|
|
119
|
+
- Key: <KEY>
|
|
120
|
+
- Type: <type>
|
|
121
|
+
- Status: <status>
|
|
122
|
+
- Priority: <priority>
|
|
123
|
+
- Assignee: <name>
|
|
124
|
+
- Epic: <epic-key> — <epic-summary>
|
|
125
|
+
- Sprint: <sprint>
|
|
126
|
+
- Labels: <labels>
|
|
127
|
+
- Components: <components>
|
|
128
|
+
|
|
129
|
+
### Description
|
|
130
|
+
<full description>
|
|
131
|
+
|
|
132
|
+
### Acceptance Criteria
|
|
133
|
+
<criteria>
|
|
134
|
+
|
|
135
|
+
### Validation Journey
|
|
136
|
+
<section or "None">
|
|
137
|
+
|
|
138
|
+
### Comments (<count>)
|
|
139
|
+
<chronological comments, flagged items called out>
|
|
140
|
+
|
|
141
|
+
### Attachments
|
|
142
|
+
<list with id, filename, mimeType, size, content URL — note any that were downloaded and their local paths>
|
|
143
|
+
|
|
144
|
+
## Remote Links
|
|
145
|
+
### Pull Requests (<count>)
|
|
146
|
+
- <url> — <title> — <state> — <reviewDecision>
|
|
147
|
+
<body summary + unresolved review comments>
|
|
148
|
+
|
|
149
|
+
### Confluence
|
|
150
|
+
- <title> — <url>
|
|
151
|
+
|
|
152
|
+
### Other
|
|
153
|
+
- <title> — <url>
|
|
154
|
+
|
|
155
|
+
## Issue Links
|
|
156
|
+
### Blocks (<count>)
|
|
157
|
+
<per-ticket block>
|
|
158
|
+
|
|
159
|
+
### Is Blocked By (<count>)
|
|
160
|
+
<per-ticket block with PR state>
|
|
161
|
+
|
|
162
|
+
### Relates To (<count>)
|
|
163
|
+
<per-ticket block>
|
|
164
|
+
|
|
165
|
+
### Duplicates / Clones
|
|
166
|
+
<per-ticket block>
|
|
167
|
+
|
|
168
|
+
## Epic Context
|
|
169
|
+
### Epic <EPIC-KEY> — <summary>
|
|
170
|
+
- Status: <status>
|
|
171
|
+
- Description: <full>
|
|
172
|
+
- Comments: <chronological>
|
|
173
|
+
- Validation Journey: <section or None>
|
|
174
|
+
|
|
175
|
+
### Siblings In-Flight (<count>)
|
|
176
|
+
- <KEY> — <status> — <assignee> — <summary> **[FLAG: in progress by other assignee]**
|
|
177
|
+
|
|
178
|
+
### Other Siblings (<count>)
|
|
179
|
+
- <KEY> — <status> — <summary>
|
|
180
|
+
|
|
181
|
+
## Subtasks (<count>)
|
|
182
|
+
- <KEY> — <status> — <assignee> — <summary>
|
|
183
|
+
|
|
184
|
+
## Summary for Downstream
|
|
185
|
+
- Full ticket count pulled: <N>
|
|
186
|
+
- Blockers still open: <list>
|
|
187
|
+
- Related in-flight work: <list>
|
|
188
|
+
- Relevant PRs: <list with state>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Rules
|
|
192
|
+
|
|
193
|
+
- Never summarize or truncate the primary ticket's description or Validation Journey.
|
|
194
|
+
- Never skip a link type, even if it seems unrelated — the agent downstream decides relevance.
|
|
195
|
+
- If a linked ticket returns an access error, capture the error and continue. Do not abort the read.
|
|
196
|
+
- Flag in-flight sibling work prominently so the caller can avoid duplicate implementation.
|
|
197
|
+
- If the ticket has no epic parent, state this explicitly — do not silently skip Phase 5.
|
|
198
|
+
- Output is pure context. This skill never modifies the ticket.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# download-attachment.sh — Download a JIRA attachment to a local file.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# bash download-attachment.sh <ATTACHMENT_ID_OR_URL> <OUTPUT_PATH>
|
|
6
|
+
#
|
|
7
|
+
# Why this helper exists:
|
|
8
|
+
# The Atlassian MCP server (mcp__atlassian__*) returns attachment metadata
|
|
9
|
+
# (id, filename, mimeType, size, content URL) on getJiraIssue but provides
|
|
10
|
+
# no tool to fetch the binary content. This script closes the gap by
|
|
11
|
+
# hitting the Jira REST API directly with Basic auth, mirroring the
|
|
12
|
+
# env-var contract already used by jira-evidence/scripts/post-evidence.sh.
|
|
13
|
+
#
|
|
14
|
+
# See https://jira.atlassian.com/browse/JRACLOUD-97830 for the upstream
|
|
15
|
+
# gap; remove this helper once Atlassian ships a download tool in the MCP.
|
|
16
|
+
#
|
|
17
|
+
# Required env vars:
|
|
18
|
+
# JIRA_SERVER - https://<your-tenant>.atlassian.net
|
|
19
|
+
# JIRA_LOGIN - login email
|
|
20
|
+
# JIRA_API_TOKEN - API token (https://id.atlassian.com/manage-profile/security/api-tokens)
|
|
21
|
+
#
|
|
22
|
+
# Exit codes:
|
|
23
|
+
# 0 success
|
|
24
|
+
# 1 download failed (HTTP error)
|
|
25
|
+
# 2 missing required env var
|
|
26
|
+
# 3 invalid arguments
|
|
27
|
+
|
|
28
|
+
set -euo pipefail
|
|
29
|
+
|
|
30
|
+
if [[ $# -lt 2 ]]; then
|
|
31
|
+
echo "Usage: download-attachment.sh <ATTACHMENT_ID_OR_URL> <OUTPUT_PATH>" >&2
|
|
32
|
+
exit 3
|
|
33
|
+
fi
|
|
34
|
+
ID_OR_URL="$1"
|
|
35
|
+
OUTPUT_PATH="$2"
|
|
36
|
+
|
|
37
|
+
# Resolve credentials: prefer env, fall back to jira-cli config for server/login.
|
|
38
|
+
JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
|
|
39
|
+
if [[ -z "${JIRA_SERVER:-}" && -f "$JIRA_CONFIG" ]]; then
|
|
40
|
+
JIRA_SERVER=$(grep '^server:' "$JIRA_CONFIG" | awk '{print $2}')
|
|
41
|
+
fi
|
|
42
|
+
if [[ -z "${JIRA_LOGIN:-}" && -f "$JIRA_CONFIG" ]]; then
|
|
43
|
+
JIRA_LOGIN=$(grep '^login:' "$JIRA_CONFIG" | awk '{print $2}')
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
for VAR in JIRA_SERVER JIRA_LOGIN JIRA_API_TOKEN; do
|
|
47
|
+
if [[ -z "${!VAR:-}" ]]; then
|
|
48
|
+
echo "ERROR: $VAR is not set." >&2
|
|
49
|
+
echo "Required env vars: JIRA_SERVER, JIRA_LOGIN, JIRA_API_TOKEN." >&2
|
|
50
|
+
echo "Generate an API token: https://id.atlassian.com/manage-profile/security/api-tokens" >&2
|
|
51
|
+
exit 2
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
OUTPUT_DIR=$(dirname "$OUTPUT_PATH")
|
|
56
|
+
if [[ ! -d "$OUTPUT_DIR" ]]; then
|
|
57
|
+
echo "ERROR: Output directory does not exist: $OUTPUT_DIR" >&2
|
|
58
|
+
exit 3
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
if [[ "$ID_OR_URL" == http*://* ]]; then
|
|
62
|
+
ATTACHMENT_URL="$ID_OR_URL"
|
|
63
|
+
else
|
|
64
|
+
ATTACHMENT_URL="${JIRA_SERVER%/}/rest/api/3/attachment/content/$ID_OR_URL"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
JIRA_AUTH=$(printf '%s' "$JIRA_LOGIN:$JIRA_API_TOKEN" | base64 | tr -d '\n')
|
|
68
|
+
|
|
69
|
+
# Atlassian responds 302 to a signed URL on media.atlassian.com that has its
|
|
70
|
+
# own auth and rejects Basic. Two-step: capture Location, then GET unauthed.
|
|
71
|
+
HEADERS_FILE=$(mktemp)
|
|
72
|
+
trap 'rm -f "$HEADERS_FILE"' EXIT
|
|
73
|
+
|
|
74
|
+
HTTP_CODE=$(curl -sS -o /dev/null -w '%{http_code}' \
|
|
75
|
+
--max-redirs 0 \
|
|
76
|
+
-D "$HEADERS_FILE" \
|
|
77
|
+
-H "Authorization: Basic $JIRA_AUTH" \
|
|
78
|
+
-H "Accept: */*" \
|
|
79
|
+
"$ATTACHMENT_URL" || true)
|
|
80
|
+
|
|
81
|
+
case "$HTTP_CODE" in
|
|
82
|
+
302|303|307)
|
|
83
|
+
SIGNED_URL=$(awk '/^[Ll]ocation:/{sub(/^[Ll]ocation:[ \t]*/,""); sub(/\r$/,""); print; exit}' "$HEADERS_FILE")
|
|
84
|
+
if [[ -z "$SIGNED_URL" ]]; then
|
|
85
|
+
echo "ERROR: Got HTTP $HTTP_CODE but no Location header in response." >&2
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
curl -sSf -o "$OUTPUT_PATH" "$SIGNED_URL" || { echo "ERROR: Download from signed URL failed." >&2; exit 1; }
|
|
89
|
+
;;
|
|
90
|
+
200)
|
|
91
|
+
curl -sSf -o "$OUTPUT_PATH" \
|
|
92
|
+
-H "Authorization: Basic $JIRA_AUTH" \
|
|
93
|
+
-H "Accept: */*" \
|
|
94
|
+
"$ATTACHMENT_URL" || { echo "ERROR: Direct download from $ATTACHMENT_URL failed." >&2; exit 1; }
|
|
95
|
+
;;
|
|
96
|
+
401|403)
|
|
97
|
+
echo "ERROR: Authentication failed (HTTP $HTTP_CODE). Verify JIRA_LOGIN and JIRA_API_TOKEN." >&2
|
|
98
|
+
exit 1
|
|
99
|
+
;;
|
|
100
|
+
404)
|
|
101
|
+
echo "ERROR: Attachment not found at $ATTACHMENT_URL (HTTP 404). Verify the ID and your access." >&2
|
|
102
|
+
exit 1
|
|
103
|
+
;;
|
|
104
|
+
*)
|
|
105
|
+
echo "ERROR: Unexpected HTTP $HTTP_CODE from $ATTACHMENT_URL" >&2
|
|
106
|
+
exit 1
|
|
107
|
+
;;
|
|
108
|
+
esac
|
|
109
|
+
|
|
110
|
+
echo " ✓ Downloaded -> $OUTPUT_PATH"
|