Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here
claude-issueops logo

claude-issueops

claude-issueops

developmentClaude Codeby etoyama

Summary

Persist session context and decisions across Claude Code sessions via GitHub Issues

Install to Claude Code

/plugin install claude-issueops@claude-issueops

Run in Claude Code. Add the marketplace first with /plugin marketplace add etoyama/claude-issueops if you haven't already.

README.md

claude-issueops

Persist session context and decisions across Claude Code sessions via GitHub Issues.

English | 日本語

> Status: v0.1.0 released — continuity hooks, the session-closer skill (capture / close), the decision marker protocol, and cross-issue memory escalation are all on master. L3 acceptance verified (Epic #7 closed). A marketplace listing will follow. Origin: this is the OSS extraction of insight-blueprint#132.

What & Why

Claude Code sessions lose context at five predictable boundaries: session start, mid-session drift, automatic compaction, session end, and the next session start. Existing memory mechanisms cover personal preferences but not "what was I doing on this issue, and why did we decide X instead of Y?". claude-issueops makes the GitHub Issue itself the persistent memory layer: hooks read recent comments at session start and after compaction, and a skill captures decisions back to the issue when the session ends. Cross-issue knowledge escalates to Claude's standard memory as reference entries.

Install

Via Claude Code marketplace (recommended)

/plugin marketplace add etoyama/claude-issueops
/plugin install claude-issueops@claude-issueops

(etoyama/claude-issueops is shorthand for the GitHub repo; the SSH form git@github.com:etoyama/claude-issueops.git also works.)

Skills are namespaced under the plugin name, so commands appear as /claude-issueops:<skill> once installed.

Locally for development

git clone https://github.com/etoyama/claude-issueops.git
claude --plugin-dir ./claude-issueops

--plugin-dir loads the plugin without going through the marketplace machinery; useful when iterating on the plugin itself.

A community marketplace listing (Anthropic's claude-plugins-community) is tracked in #60.

Quickstart

1. Work on a branch named after an issue, e.g. feat/132-session-continuity. 2. Open Claude Code. The first prompt of the session triggers a briefing: a one-line list of in-progress issues, plus the current issue's body excerpt and any prior decisions. 3. Make decisions. When you reach a meaningful conclusion, run /claude-issueops:session-closer --capture to extract and post the decision as a comment on the current issue. 4. End the session with /claude-issueops:session-closer (no flag). The skill captures any remaining decisions, posts a session summary, and escalates cross-issue learnings to Claude's standard memory.

If you forget to invoke the skill, a SessionEnd hook posts a minimal summary as a fallback.

Decision marker protocol

Decisions are recorded as issue comments using a frozen format. The format is part of the protocol and must not be customized; downstream tooling depends on the exact shape.

## Decision: <kebab-case-slug>

**What:** <one sentence describing what was decided>
**Why:** <reasoning, constraints, or motivation>
**Alternatives considered:**
- <option> -> <reason for rejection>
**Consequences:** <what this gains, what this gives up, what may break later>

Extraction uses two combined regexes: ^## Decision: (?<slug>[a-z0-9-]+)\s$ for the heading, immediately followed by ^\\What:\\* to reject false positives (quoted text, code blocks).

A slug is kebab-case, unique within the issue. Re-using a slug requires deleting or rewriting the prior comment by hand; the capture flow refuses to overwrite.

Configuration

Defaults ship with the plugin. Override per-project in .claude/settings.json:

{
  "issueops": {
    "stateDir": "${CLAUDE_PROJECT_DIR}/session-state",
    "branch": {
      "issuePattern": "(?:feat|fix|chore|refactor)/(\\d+)-",
      "fallback": "latest-in-progress"
    },
    "projects": {
      "enabled": false
    },
    "memory": {
      "escalate": true,
      "type": "reference"
    }
  }
}

| Key | Default | Purpose | |---|---|---| | stateDir | ${CLAUDE_PROJECT_DIR}/session-state | Per-session state file location. Must be gitignored. CLAUDE_PROJECT_DIR is the env var Claude Code exposes to plugin scripts. | | branch.issuePattern | (?:feat\|fix\|chore\|refactor)/(\d+)- | Regex with one capture group for the issue number. | | branch.fallback | latest-in-progress | What to do when the pattern does not match. Alternative: none. | | projects.enabled | false | Opt in to GitHub Projects v2 integration (added in v0.2). | | memory.escalate | true | Whether cross-issue decisions are written to Claude's standard memory. | | memory.type | reference | Memory type to use when escalating. |

Hooks behavior

Three hooks ship in v0.1:

| Event | Role | Injects context? | |---|---|---| | UserPromptSubmit | Session briefing on the first prompt; restore current-issue context after a compaction. | Yes (additionalContext) | | PreCompact | Save the current-issue snapshot to the state file so restore works. | No (save only) | | SessionEnd | Fallback summary post when the user did not invoke /claude-issueops:session-closer. | No (post only) |

SessionStart is intentionally not used: UserPromptSubmit runs at the same effective moment for context purposes and is the only hook that supports additionalContext injection both at session start and after compaction. A single hook keeps the lifecycle debuggable.

On additionalContext durability (Claude Code docs): the injected briefing is saved to the session transcript and replayed verbatim when the session is resumed via --continue or --resume. The briefing is therefore frozen at the moment it was first injected — the in-progress issues list and prior-decisions excerpt seen on resume are the snapshot from the original session start, not a fresh fetch. This is by design (the briefing is meant to anchor the session, not to track live state); when you want fresh data, end the session and start a new one. The hook's exact position relative to CLAUDE.md in the assembled prompt is implementation-detail and not part of the contract — we treat it as "alongside the user prompt" per the documented wording.

Skills

session-closer

The skill that closes the loop: captures decisions back to the issue and (optionally) escalates cross-issue learnings to Claude's standard memory. Two modes:

| Mode | Invocation | What it does | |---|---|---| | capture | /claude-issueops:session-closer --capture | Reads the recent transcript, asks for confirmation on each detected Decision via AskUserQuestion, posts approved Decisions as issue comments with the frozen marker, updates state.captured_slugs. Run mid-session whenever you reach a meaningful conclusion. | | close (default) | /claude-issueops:session-closer | Runs capture plus an idempotent session-summary comment, plus memory escalation for final_scope = cross-issue Decisions. Run at session end. |

Key guarantees:

  • Two-tier dedup: a slug already in state.captured_slugs (Tier 1) or already present as a decision:<slug> marker on the issue (Tier 2) is skipped. Re-running the skill is safe.
  • Subcommand separation: posts are committed to GitHub before state is written. If state-write fails after a successful post, the next run sees the post via Tier 2 dedup and skips it. The state file always reflects what was actually posted.
  • gh failure → 3-choice fallback: on gh error the skill asks save / discard / abort. "save" persists the unposted Decisions to <sid>.pending-decisions.json so they can be retried in a later session.
  • AmbiguousResolution: when the branch + status:in-progress label combination yields multiple candidate issues, the skill prompts to pick one before posting.

If the user forgets to invoke the skill, the SessionEnd fallback hook posts a minimal summary (no decision extraction — that requires interactive confirmation).

State file shape (<stateDir>/<session_id>.json):

{
  "session_id": "abc123",
  "issue_number": 132,
  "briefing_done": true,
  "pending_restore": null,
  "compact_count": 0,
  "last_processed_offset": 1234,
  "captured_slugs": ["two-layer-architecture"]
}

Roadmap

| Release | Scope | |---|---| | v0.1 | Session continuity hooks, decision capture skill, marker protocol, branch-to-issue regex, memory escalation. | | v0.2 | GitHub Projects v2 integration as an opt-in feature (default off). Adds an "in progress" tier to the briefing. | | v0.3 | Issue rule engine. Reads .claude-issueops/issue-rules.yaml and intercepts gh issue create / gh issue edit to suggest fixes for missing labels, parent links, or template fields. Violations surface via additionalContext and permissionDecision: ask rather than hard blocks. |

The marker protocol is frozen across releases. Settings keys may evolve in v0.x but will follow semver from v1.0.

Project layout

claude-issueops/
├── .claude-plugin/
│   └── plugin.json           # plugin manifest
├── skills/
│   └── session-closer/
│       └── SKILL.md          # capture + close orchestration
├── bin/                      # subprocess entrypoints invoked by hooks and skill
│   ├── userpromptsubmit_hook.py
│   ├── precompact_hook.py
│   ├── sessionend_hook.py
│   └── session_closer.py     # 8-subcommand JSON dispatcher for the skill
├── src/issueops/             # pure Python modules (no I/O, callable-injection)
│   ├── path_utils.py         # session-id validation + atomic-write primitives
│   ├── state_writer.py       # single window for state-file writes
│   ├── pending_decisions.py  # gh-failure "save" branch
│   ├── transcript_reader.py
│   ├── decision_extractor.py
│   ├── dedup_checker.py
│   ├── issue_resolver.py     # branch + status:in-progress → issue number
│   ├── gh_adapters.py        # subprocess wrappers + failure classification
│   ├── verification_fixture.py  # AskUserQuestion bypass for L3 verification
│   ├── session_closer.py     # orchestrator (run_capture / run_close)
│   ├── marker_parser.py
│   ├── memory_escalate.py
│   └── branch_resolver.py
├── tests/                    # pytest suite (217 unit tests, ~82% coverage)
│   └── fixtures/transcripts/ # L3 verification transcripts (LLM-extractable)
├── verification-fixtures/    # JSON fixtures for L3 verification recipes
├── VERIFICATION.md           # V-1〜V-15 Bash verification recipes
├── scripts/
│   ├── l3-acceptance.sh             # bash-only V-X driver (V-3, V-9 Run 1, V-10 Run 2, V-14)
│   └── cleanup-l3-verification-issues.sh  # sweep [V- prefix open issues
├── README.md
├── CONTRIBUTING.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
└── LICENSE

Implementation lands incrementally. See the v0.1 Epic for the open work.

License

MIT (c) 2026 etoyama.

Related plugins

Browse all →