用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/CodySwannGT/lisa --skill lisa-setup-atlassian命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
This skill should be used for any non-trivial request — features, bugs, stories, epics, spikes, or multi-step tasks. It accepts a ticket URL (Jira, Linear, GitHub), a file path containing a spec, or a plain-text prompt. It assembles an agent team, breaks the work into structured tasks, and manages the full lifecycle from research through implementation, code review, deploy, and empirical verification.
any non-trivial request —…
This skill should be used for any non-trivial request — features, bugs, stories, epics, spikes, or multi-step tasks. It accepts a ticket URL (Jira, Linear, GitHub), a file path containing a spec, or a plain-text prompt. It assembles an agent team, breaks the work into structured tasks, and manages the full lifecycle from research through implementation, code review, deploy, and empirical verification.
正在显示 SKILL.md
| name | lisa-setup-atlassian |
| description | Configure Atlassian access for… |
| allowed-tools | ["Bash","Read","Write","Edit","Skill","AskUserQuestion"] |
Resolve and persist Atlassian access for this project. After this skill, .lisa.config.json contains atlassian.cloudId (required) and optionally atlassian.site / atlassian.email for multi-account disambiguation.
Ask via AskUserQuestion:
How do you want lisa to talk to Atlassian for this project?
- MCP-only (simplest) — authenticate the Atlassian MCP once via browser OAuth; lisa uses it for every operation. Best for: single-Atlassian-account developers on a personal laptop. New developers onboard with one OAuth flow, no token management. Skip the rest of this setup.
- acli (CLI) + MCP fallback — install acli, authenticate per-profile, MCP picks up anything acli can't do. Best for: developers who work across multiple Atlassian accounts and need profile switching. Continue with acli install.
- API-token path (headless / CI) — store a per-user API token in the OS keychain; lisa uses curl for everything. Best for: CI pipelines, headless dev containers, or any case where browser OAuth is impossible. Continue through token-create steps.
If the user picks (1) and the MCP is already authenticated to the right workspace (verify by calling getAccessibleAtlassianResources and checking atlassian.cloudId is in the result), write only atlassian.cloudId and atlassian.site into .lisa.config.json and skip to Step 6 (cloudId resolution). If the MCP isn't authed yet, instruct the user to run mcp__plugin_atlassian_atlassian__authenticate (or the claude.ai equivalent) and complete the OAuth flow in their browser, then re-verify.
If the user picks (2) or (3), continue through the rest of the steps; acli and/or the API token become available alongside the MCP.
if ! command -v acli >/dev/null 2>&1; then
if command -v brew >/dev/null 2>&1; then
brew tap atlassian/homebrew-acli
brew install acli
else
cat >&2 <<'EOF'
Error: Homebrew not found. Install acli manually:
https://developer.atlassian.com/cloud/acli/guides/install-macos/
or skip acli and rely on the Atlassian MCP only (CI/remote envs need acli).
EOF
# Continue — acli is preferred but MCP-only is acceptable.
fi
fi
If acli install fails or is skipped, the project will operate in MCP mode. Surface this clearly to the user.
If acli is installed: prefer acli auth login --web for interactive environments; for headless, instruct the user to obtain a Rovo MCP-scoped API token and pipe via:
echo "$ATLASSIAN_TOKEN" | acli jira auth login --site "<site>.atlassian.net" --email "<email>" --token
After login, verify with acli auth status.
acli covers most JIRA operations but no Confluence page writes (only space-level commands, and page view). The classic-vs-granular OAuth scope mismatch (see config-resolution rule) also blocks acli's bearer token from working against the v2 Confluence REST API. So lisa needs a second substrate — curl with Basic auth + API token — for everything Confluence-write-related.
Per-product tokens: Atlassian's scoped API token UI is per-product, so the easiest path is one Confluence-scoped token. JIRA operations remain on acli (no JIRA token needed). If a future lisa op turns out to need a JIRA-scoped token (e.g., reading transition metadata or remote links — neither is required by the current dispatch), make a second token then.
Security posture: the token is stored in the OS keychain when available (macOS/Linux/Windows native backends) so it never lives in plaintext on disk and never flows through chat history. Env-var fallback exists for headless / CI / Linux-without-libsecret.
Use the same ladder atlassian-access uses (env var → email-suffixed env var → keychain):
EMAIL=$(jq -r '.atlassian.email // empty' .lisa.config.local.json 2>/dev/null)
SITE=$(jq -r '.atlassian.site // empty' .lisa.config.json)
CLOUDID=$(jq -r '.atlassian.cloudId // empty' .lisa.config.json)
read_token() {
local email="$1"
[ -n "$ATLASSIAN_API_TOKEN" ] && { echo "$ATLASSIAN_API_TOKEN"; return; }
local slug=$(echo "$email" | tr '[:upper:]@.' '[:lower:]__')
local varname="ATLASSIAN_API_TOKEN_${slug}"
[ -n "${!varname}" ] && { echo "${!varname}"; return; }
# Preferred path: the single secrets chokepoint. It owns the one-store rule
# and the surface ladder, so anything it can answer must not be read out of an
# OS keychain here — a second reader is how the same credential ends up living
# in two places and drifting. Keep the LADDER below identical to
# `atlassian-access`; the tail may differ, because this skill falls through to a
# legacy keychain rung and that one does not. Saying "the ladder" rather
# than "this function" is deliberate — the old wording asked for something
# unachievable, and an unachievable rule is one that gets quietly dropped.
#
# Ordered across trusted machine-managed substrates, ending at the installed
# package. Checkout-local paths are deliberately absent: a familiar generated
candidates=()
[ -n ];
candidates+=()
[ -n ];
candidates+=()
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
resolver
tried=()
resolver ;
tried+=()
[ -f ];
via_lisa
via_lisa=$(node get ATLASSIAN_API_TOKEN 2>/dev/null) \
&& [ -n ] && { ; ; }
from_keychain=
Darwin) from_keychain=$(security find-generic-password -s lisa-atlassian -a -w 2>/dev/null) ;;
Linux) -v secret-tool >/dev/null && \
from_keychain=$(secret-tool lookup service lisa-atlassian account 2>/dev/null) ;;
MINGW*|MSYS*|CYGWIN*)
from_keychain=$(LISA_CRED_TARGET= powershell.exe -NoProfile -NonInteractive -Command 2>/dev/null | -d ) ;;
[ -n ] && { ; ; }
>&2
>&2
>&2
>&2
1
}
EXISTING=$(read_token )
[ -n ];
AUTH=$( | )
CODE=$(curl -s -o /dev/null -w \
-H \
)
[ = ];
If validation fails or no token is found, continue.
Open the token-creation page in their browser:
case "$(uname -s)" in
Darwin) open "https://id.atlassian.com/manage-profile/security/api-tokens" ;;
Linux) xdg-open "https://id.atlassian.com/manage-profile/security/api-tokens" 2>/dev/null ;;
MINGW*|MSYS*|CYGWIN*) start "https://id.atlassian.com/manage-profile/security/api-tokens" ;;
esac
Then print these instructions for the user:
1. Click "Create API token with scopes" (NOT the legacy unscoped form).
2. Label it: lisa-confluence-<machine-name> (anything; just for revocation traceability)
3. App: Confluence
4. Select EXACTLY these scopes:
Read: read:page:confluence
read:hierarchical-content:confluence
read:comment:confluence
read:space:confluence
Write: write:page:confluence
write:comment:confluence
write:label:confluence
Search: search:confluence
5. Set an expiry (1 year max).
6. Click "Create token" and copy the value.
Critical: don't use the interactive prompt form of security / secret-tool / cmdkey. Atlassian scoped tokens end with =<CRC> (a checksum); terminal getpass-style prompts on macOS Terminal.app and iTerm have been observed to silently truncate the paste at the = sign, storing a 128-byte prefix instead of the full ~192-byte token. The result authenticates as 401 because the CRC fails. Symptom: the stored token validates against printf length checks (the prefix is well-formed) but every API call returns 401 with x-failure-category: FAILURE_CLIENT_AUTH.
Always pipe from the clipboard instead. Print platform-specific commands that take $(pbpaste) / $(xsel) / $(Get-Clipboard) directly into the -w / store arg:
case "$(uname -s)" in
Darwin)
cat <<EOF
1. Click "Copy" in the Atlassian token-create modal so the token is in your clipboard.
2. Run this single line in your terminal — leading space keeps it out of zsh history:
security delete-generic-password -s lisa-atlassian -a "$EMAIL" 2>/dev/null; TOK="\$(pbpaste)"; security add-generic-password -U -s lisa-atlassian -a "$EMAIL" -w "\$TOK"; unset TOK
The token is piped from clipboard straight to keychain — no prompt, no truncation.
EOF
;;
Linux)
if command -v secret-tool >/dev/null 2>&1; then
# Pick whichever clipboard tool is available.
if command -v wl-paste >/dev/null 2>&1; then CLIP=wl-paste
elif command -v xclip >/dev/null 2>&1; then CLIP="xclip -selection clipboard -o"
elif command -v xsel >/dev/null 2>&1; then CLIP="xsel --clipboard --output"
else CLIP="cat" # caller will have to paste; fallback path below
fi
cat <<EOF
1. Click "Copy" in the Atlassian token modal so the token is in your clipboard.
2. Run this single line in your terminal:
secret-tool clear service lisa-atlassian account "$EMAIL" 2>/dev/null; printf '%s' "\$($CLIP)" | secret-tool store --label="Lisa Atlassian ($EMAIL)" service lisa-atlassian account "$EMAIL"
(If no clipboard tool is installed, the command will read from stdin — paste your token, press Ctrl-D.)
EOF
else
cat <<EOF
libsecret / secret-tool is not installed. Options:
1. Install it (recommended on desktop Linux):
Debian/Ubuntu: sudo apt install libsecret-tools
Fedora/RHEL: sudo dnf install libsecret
Then re-run /lisa:setup:atlassian.
2. Fall back to env-var storage (headless / CI / Docker):
Add this line to your shell rc (.bashrc / .zshrc):
export ATLASSIAN_API_TOKEN_$(echo "$EMAIL" | tr '[:upper:]@.' '[:lower:]__')="<paste-token-here>"
Reload shell. Be aware: token will be in plaintext on disk.
EOF
;;
MINGW*|MSYS*|CYGWIN*)
<<
;;
*)
<<
;;
Do NOT accept the token via chat or stdin into this skill. The user runs the command themselves; the token enters only the OS keychain. The clipboard-pipe form is mandatory — never advise the interactive -w (no-arg) prompt form, which truncates scoped tokens at the = sign on multiple terminal/readline combos.
Wait for the user to confirm they've stored it.
After the user confirms storage, retrieve via the same read_token ladder and validate. Use a v2 endpoint (not v1) since v1 returns 410 Gone — and v2 is what atlassian-access actually uses at runtime.
NEW=$(read_token "$EMAIL")
if [ -z "$NEW" ]; then
echo "Error: token not retrievable from any source. Re-check the storage command and try again." >&2
exit 1
fi
# Length probe — Atlassian scoped tokens are ~192 chars (token body + '=' + CRC).
# A stored value shorter than ~150 chars almost certainly means the terminal truncated
# the paste at the '=' separator before the CRC.
if [ ${#NEW} -lt 150 ]; then
echo "Error: token is ${#NEW} chars — too short. Scoped tokens are ~192 chars and end with '=<CRC>'." >&2
echo "Likely your terminal truncated the paste. Use the clipboard-pipe form in Step 3c." >&2
exit 1
fi
AUTH=$(printf '%s:%s' "$EMAIL" "$NEW" | base64)
PROBE=$(curl -s -o /tmp/lisa-probe -w "%{http_code}" \
-H "Authorization: Basic $AUTH" \
"https://api.atlassian.com/ex/confluence/${CLOUDID}/wiki/api/v2/pages/$(jq -r '.confluence.parentPageId // empty' .lisa.config.json)")
# If no parentPageId in config, fall back to a generic spaces list (also v2).
if [ -z "$(jq -r '.confluence.parentPageId // empty' .lisa.config.json)" ]; then
PROBE=$(curl -s -o /tmp/lisa-probe -w "%{http_code}" \
-H "Authorization: Basic " \
)
[ != ];
>&2
/tmp/lisa-probe >&2
>&2
>&2
1
-f /tmp/lisa-probe
For pipelines that can't use keychain: the token comes in via ATLASSIAN_API_TOKEN as a pipeline secret env var. No setup-skill changes needed; the lookup ladder already prefers env. Document this in the project's CI README rather than the skill.
If acli is installed and authenticated:
acli auth status --output json
# Returns { "site": "...", "email": "...", ... } — but cloudId is not always returned by acli.
If the MCP is available, call mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources and pick the entry whose url matches the desired site. Its id is the cloudId.
If the user has multiple sites under their account, use AskUserQuestion to disambiguate, presenting each site's URL + cloudId as an option.
Shared fields → .lisa.config.json (committed). Developer-specific fields → .lisa.config.local.json (gitignored). This is non-negotiable: a developer's email pinned in the committed file would break every other developer on the project.
Shared fields (committed):
touch .lisa.config.json
[ -s .lisa.config.json ] || echo '{}' > .lisa.config.json
jq --arg cloudid "$CLOUDID" \
--arg site "$SITE" \
'.atlassian = ((.atlassian // {}) | .cloudId = $cloudid | .site = $site)' \
.lisa.config.json > .lisa.config.json.tmp \
&& mv .lisa.config.json.tmp .lisa.config.json
Developer-specific fields (local override, gitignored):
touch .lisa.config.local.json
[ -s .lisa.config.local.json ] || echo '{}' > .lisa.config.local.json
jq --arg email "$EMAIL" \
'.atlassian = ((.atlassian // {}) | .email = $email)' \
.lisa.config.local.json > .lisa.config.local.json.tmp \
&& mv .lisa.config.local.json.tmp .lisa.config.local.json
Confirm .lisa.config.local.json is gitignored (it should already be — lisa's bootstrap template adds it). If not, surface the issue and add it. NEVER write email to the committed file under any circumstances; if a user explicitly insists, refuse and explain why.
jq -e '.atlassian.cloudId' .lisa.config.json >/dev/null
acli auth status # if acli installed
Report success with the resolved cloudId and site. Direct the user to /lisa:setup:jira and/or /lisa:setup:confluence next, depending on what they need.
atlassian section's fields rather than appending. Use jq merge semantics (above) — never raw-append JSON.AskUserQuestion whether to overwrite or abort..lisa.config.json. Tokens stay in env / acli's ~/.config/acli/ / the MCP's keychain entry..claude/settings.json by hand-concatenation — always use jq to preserve the JSON shape.tracker or source from this skill — that is the job of setup-jira / setup-confluence.