SLOPSHOPPER

jira-trim

Atlassian MCP write echoes and transition lists cut to the line the model needs

newguard
v0.1.0no licenseupdated 2026-10-10arowinski/dotfiles/claude/mods/jira-trim
A shopper browsing a rack in a slop shop
README

Dotfiles

Source 1 files
hooks/register.ts 49 lines
1import type { Register, ToolCallResult } from 'claude-code'
2
3const EDIT = 'mcp__atlassian__editJiraIssue'
4const COMMENT = 'mcp__atlassian__addCommentToJiraIssue'
5const TRANSITIONS = 'mcp__atlassian__getTransitionsForJiraIssue'
6
7type Transition = { id: string; name: string; to: { name: string } }
8
9// A denied or failed call keeps the server's answer: its error text is what
10// the model needs to recover.
11const landed = (out: ToolCallResult) => out.deny === undefined && !out.isError
12
13// One `id: name → status` line per transition; null when the text isn't the
14// transitions JSON, so the caller keeps the server's answer.
15function transitionLines(text: string) {
16  try {
17    const { transitions } = JSON.parse(text) as { transitions: Transition[] }
18
19    return transitions.map(t => `${t.id}: ${t.name} → ${t.to.name}`).join('\n')
20  } catch {
21    return null
22  }
23}
24
25export const register: Register = on => {
26  // The server echoes the whole issue after an edit (~1.3k tokens) and the
27  // whole comment after a comment (~1k); the model only needs to know it landed.
28  on('tool.call', { tool: EDIT }, async ($, e, next) => {
29    const out = await next(e)
30
31    return landed(out) ? { result: `Updated ${e.issueIdOrKey}: ${Object.keys(e.fields as object).join(', ')}` } : out
32  })
33
34  on('tool.call', { tool: COMMENT }, async ($, e, next) => {
35    const out = await next(e)
36
37    return landed(out) ? { result: `Commented on ${e.issueIdOrKey}` } : out
38  })
39
40  // The transitions JSON runs ~2.4k tokens, mostly icon URLs and status
41  // categories; transitionJiraIssue needs only the id.
42  on('tool.call', { tool: TRANSITIONS }, async ($, e, next) => {
43    const out = await next(e)
44    const lines = landed(out) && out.text !== undefined ? transitionLines(out.text) : null
45
46    return lines ? { result: lines } : out
47  })
48}
49