Every AI coding session starts with amnesia. The agent does not know what issue #123 is about, what was decided in its comments, which PRs are open against it, or what changed in the feature branch yesterday. For a real task in a multi-repo product, that context lives in at least four places: the issue tracker, pull requests, git branches, and the working copies themselves.

The usual workaround is copy-pasting fragments into the prompt until the agent stops asking questions. It works, but it is slow, lossy, and different every time. I got tired of doing it and built taskctx — a small CLI that assembles the whole context of a task into one deterministic Markdown file. This post covers what goes into a pack and the design decisions that make it work in daily agent-driven development.


The idea: a context pack, not a prompt

A context pack is a snapshot of everything an agent needs to start working on an issue, rendered as a single context-pack.md:

taskctx collect 123
# → .taskctx/123/context-pack.md

The agent does not get a giant prompt. It gets a file with stable paths to everything else — full per-commit diffs, raw GitHub JSON, the repository map — so it can read deeper only where needed. Context assembly stops being part of the prompt and becomes part of the workspace.


What goes into a pack

1. Delta first

The pack opens with what changed since the last collect, because that is what a returning session actually needs:

- api: 3 new commits (a1b2c3d..e4f5g6h)
- web: no new commits
- web#8636 state: open → merged
- issue: +2 comments

New commits are computed against the previous manifest, PR changes are rendered as ready-made transition lines, and the comment delta is a simple count. An agent that worked on the task yesterday reads five lines and is caught up.

2. Issue snapshot

Title, state, labels, body, and comments — the raw material. On top of that, one extraction proved surprisingly valuable: open checkboxes. The renderer scans the issue body and every comment for - [ ] items and lists them with their source:

- [ ] Verify timer state after re-login _(issue body)_
- [ ] Add retry backoff test _(@reviewer 2026-07-30)_

Checkbox items are usually the actual remaining work, scattered across a long thread. Collected in one place, they become the agent's implicit todo list.

3. Repository map and branch state

The config describes the workspace: each repo's local path (or null for remote-only), its GitHub slug, base branch, and branch naming pattern like issue-{N}. For every repo the pack shows the matched branch, the merge-base with the base branch, and the commit list with file statistics — additions and deletions per file, aggregated over the branch.

Full per-commit diffs are cached to disk during collect; the pack only carries their paths. The agent opens a diff when it needs one instead of paying for every diff in tokens up front.

4. PR states

For each linked PR: number, title, state, merged flag, review decision, and URL. Enough for the agent to know whether its previous work is under review, merged, or sent back.


Design decisions

Cache everything, render deterministically

Collect writes raw GitHub JSON, a manifest, and per-commit diffs into a .taskctx/<N>/ store. Rendering reads only the store:

  • taskctx pack 123 re-renders with zero network access — on a plane, in CI, or when the API rate limit says no.
  • The same store renders the same pack, byte for byte. Packs are diffable and safe to commit, and a changed pack is a signal, not noise.
  • --offline goes further and recomputes from local git refs only, without even gh.

Delta over snapshot

A pack that only describes current state forces the agent (and the human) to diff mentally against yesterday. Keeping the previous manifest makes the delta computable, and computing it makes the top section of the pack the most valuable one. This mirrors how I think about test reports: "what changed" beats "what is".

Instruction file over convention

taskctx init writes an instruction.md telling any agent how to consume packs: read the pack first, use the diff directory for details, search the working copies via the repo map, never re-run git diffs by hand. Any agent that picks up the repo inherits the workflow — no tribal knowledge in my head or in a chat history.

Graceful degradation per repo

Branches get deleted after merges; repos are not always checked out. Each repo entry in the pack is independent: a missing branch says "branch not found", a deleted one says "branch gone", a remote-only repo works through the API alone. One broken piece never fails the whole pack — same principle as classifying failures in the monitoring watchdog, applied to context collection.


Implementation notes

The tool is about 1,300 lines of TypeScript running on Bun, with Vitest covering the four risky seams: collection, git plumbing, GitHub API parsing, and pack rendering. The renderer is a pure function over the store — no I/O — which makes it trivial to test with fixtures and keeps the determinism promise enforceable.

The commands:

taskctx init                 # seed config + agent instruction.md
taskctx collect 123          # fetch + render the pack
taskctx pack 123             # re-render from cache
taskctx status 123           # delta only, to stdout
taskctx collect 123 --repo web --offline

What changed in practice

Session startup went from "ten minutes of copy-paste and one thing always forgotten" to one command and a file link. The unexpected win was continuity: because packs are deterministic and delta-first, an agent resuming a task after three days behaves like a colleague who read the thread, not like a new hire. And as a QA habit, I now treat stale context as a test failure — if the pack is old, you refresh it before trusting anything the agent says about the task.

Key takeaways

  • Every agent session starts with amnesia — context assembly should be a tool, not a prompt ritual.
  • Render the delta first: a returning session needs "what changed," not the whole history.
  • Cache everything and keep rendering deterministic, so packs are diffable and safe to commit.
  • Integrate via an instruction file any agent can read — no platform-specific plugin API required.
  • Degrade gracefully per repo: one missing branch should never fail the whole pack.

Project page: taskctx — Task Context Packs for LLM Sessions.