Link the current Claude Code session to a ticket (Linear, Jira, GitHub Issues, or GitHub Pull Requests) and cache its title/status in karma. Use when the user explicitly asks to link, attach, associate, or connect this session to a ticket, issue, or PR — e.g. "/link-ticket-to-session ABC-123", "link this session to LINEAR-42", "associate this work with issue #15", "attach session to PR octocat/repo#7". Do NOT auto-invoke from passing ticket-key mentions in normal conversation.
npx skills add https://github.com/JayantDevkar/claude-code-karma --skill link-ticket-to-session
You are linking the current Claude Code session (${CLAUDE_SESSION_ID}) to: $ARGUMENTS
Karma is a read-only observer on the user's machine. It stores the link
and caches title/status for display, but never writes back to the ticket
provider. You fetch metadata via the user's already-configured MCP server.
Karma's API URL comes from KARMA_API_URL (set by users on non-default
ports/hosts) with http://localhost:8020 as fallback. Inline
${KARMA_API_URL:-http://localhost:8020} in every curl below — bash
variables don't persist across separate Bash tool calls, so a top-of-script
assignment would be empty by the time the next curl runs.
Recognized forms:
| Provider | Short ref | URL forms |
|--------------------|---------------------|--------------------------------------------------------|
| Linear | LINEAR-123 | https://linear.app/.../issue/ABC-123 |
| Jira | PROJ-45 | https://*.atlassian.net/browse/PROJ-45 |
| GitHub Issue | owner/repo#42 | https://github.com/owner/repo/issues/42 |
| GitHub PR | owner/repo#42 | https://github.com/owner/repo/pull/42 |
GitHub issues and pull requests share a single numbering namespace —
owner/repo#42 could be either. **The URL kind (/issues/ vs /pull/)
is the only signal**, and karma's backend preserves it, so when you have
a URL keep it intact when POSTing (Step 4). For a bare owner/repo#N
with no URL, default to /issues/N — GitHub auto-redirects to /pull/N
when N is actually a PR, so the link still resolves.
A bare #N (no owner/repo) is not accepted — always qualify with
owner/repo#N.
Set two variables you'll use below:
<provider> ∈ linear | jira | github<kind> ∈ issue | pull_request (derived from URL path)For Linear and Jira this collapses to just <provider>.
Pick the right MCP tool for the provider and kind:
| Provider · Kind | MCP tool |
|-----------------------------|---------------------------------------------------------|
| linear | Linear MCP — search/fetch issue by key |
| jira | Atlassian MCP — fetch by key |
| github · issue | mcp__plugin_github_github__issue_read, method get |
| github · pull_request | mcp__plugin_github_github__pull_request_read, method get |
Calling the wrong GitHub method silently returns the wrong thing because
both shapes look superficially similar — so derive the kind first.
If the relevant MCP isn't installed, skip this step and proceed to
Step 4 without title/status. Karma will create the link; the title/status
fields stay NULL and can be refreshed later via Step 5.
Pull at minimum: title, status (or state), url. **Strip large
fields** — karma caps metadata_json at 64 KB and a full PR payload
easily exceeds that. Specifically drop:
body, commits, files, reviewers, comments, labels,requested_reviewers, head / base blobs beyond ref
body, comments, reactions, labelsdescription, comments, subscribers, attachmentsThe status you cache should reflect *what the provider says now*, not a
generic "open/closed". Karma's UI normalizes these to canonical buckets
at render time, so faithful provider language is the right input:
Backlog, In Progress,In Review, Done, Cancelled (workspace-defined; don't normalize).
To Do, In Progress, In Review,Done.
open or closed.| state | draft | merged | Cache as |
|----------|---------|----------|--------------|
| open | true | — | draft |
| open | false | — | open |
| closed | — | true | MERGED |
| closed | — | false | closed |
The url field should be the URL you actually have — /pull/N for PRs,
/issues/N for issues. Don't rewrite it. Karma's parser preserves
the path segment; the UI uses it to distinguish PRs from issues.
curl -s -X POST "${KARMA_API_URL:-http://localhost:8020}/sessions/${CLAUDE_SESSION_ID}/tickets" \
-H 'Content-Type: application/json' \
-d '{"ref":"<key>","provider":"<provider>","url":"<url>","source":"slash_command"}'
For GitHub, <key> is always owner/repo#N regardless of kind — the
URL field carries the issue/PR distinction.
curl -s -X PUT "${KARMA_API_URL:-http://localhost:8020}/tickets/<provider>/<key>" \
-H 'Content-Type: application/json' \
-d '{"title":"<title>","status":"<status>"}'
For GitHub keys with / and #, URL-encode the key in the path:
octocat/repo#42 → octocat%2Frepo%2342.
One line. For GitHub, distinguish the kind so the user knows what they
just attached:
Linked session to LINEAR-123 (Fix login bug, In Progress) — open at https://linear.app/...Linked session to PROJ-45 (Migrate auth, Done) — open at https://acme.atlassian.net/browse/PROJ-45Linked session to octocat/repo#42 [issue] (Empty state lies, open) — open at .../issues/42Linked session to octocat/repo#42 [PR] (Fix linting, MERGED) — open at .../pull/42KARMA_API_URL overrides for customport or remote host.
(session, ticket); re-running upgrades thelink_source if previously set by branch-detect or dashboard. Order:
slash_command > dashboard > branch.
karma not running at ${KARMA_API_URL:-http://localhost:8020} so they
see what was tried. Don't silently succeed.
#N means a single karma row (one(provider, external_key) pair) covers both views of that number.
The URL field is what tells karma's UI which one to render. Send the
URL you actually have.
Use when the user asks to run Gemini CLI for code review, plan review, or big context (>200k) processing. Ideal for comprehensive analysis requiring large context windows. Uses Gemini 3 Pro by default for state-of-the-art reasoning and coding.
Claude Skills meta-skill: extract domain material (docs/APIs/code/specs) into a reusable Skill (SKILL.md + references/scripts/assets), and refactor existing Skills for clarity, activation reliability, and quality gates.
> Pedantic backend pre-commit and atomic commit Skill for Django/Optimo-style repos. Enforces local AGENTS.md / CLAUDE.md, pre-commit hooks, .security/* helpers, and Monty’s backend engineering taste – with no AI signatures in commit messages.
Automatically backs up files, saves diffs, uses agents/skills, and ensures modular code (<200 lines) before any implementation. Use this skill for ALL code changes to ensure safe, reversible, and clean implementations.
Use when you've developed a broadly useful skill and want to contribute it upstream via pull request - guides process of branching, committing, pushing, and creating PR to contribute skills back to upstream repository
Default reference pipeline for the code-migration taskKind — code-import → design-extract → token-map → rewrite-plan → patch-edit ↔ build-test devloop → diff-review → handoff.
Configure human-in-the-loop gating for AI agent review actions in Claude Code. Use when setting up a project where an agent may post PR reviews, comments, merges, or edit CI configuration, and you want a cryptographically auditable approval trail with Cedar-enforced gates.
> Check installed community skills for updates. Shows a diff and requires explicit approval before applying. Use when the user says "check for updates", "update my skills", "anything new for my installed skills", or when invoked from the registry-sync agent.
Take jayantdevkar/link-ticket-to-session from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.