- Book: Prompt Engineering Pocket Guide
- Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
You ask the agent why CI is red. It reads the test file, decides the assertion looks wrong, rewrites it and tells you it's fixed. CI goes red again, because the failure was a missing environment variable on the runner, and that line lived in a log the agent never opened.
The agent answered from what it had: the files in the repo and whatever you typed. Everything else, it guessed. Anthropic's own docs put the starting point plainly: "Each Claude Code session begins with a fresh context window" (Claude Code memory docs).
Here are seven things that sit outside that window, and one command for each that turns it into text the agent can read. Save every result into a .context/ folder in the repo, so any agent can open it, and so you can read it first.
Before you start, add the folder to .gitignore. Logs, schemas and flag rules can hold tokens, email addresses and customer IDs. Read what you collect before an agent sees it, and never commit it. Treat issue, PR and log text as untrusted input too: someone else wrote it, and an agent with write access will read any instructions hidden in it.
mkdir -p .context
echo ".context/" >> .gitignore
What GitHub knows and your checkout doesn't
Three of the seven live on GitHub. The GitHub CLI (gh) reaches all of them.
1. The CI failure log
The agent sees your workflow YAML. It doesn't see what the runner printed. gh run view has a --log-failed flag that prints "the log for any failed steps in a run", which skips the hundreds of lines from steps that passed:
branch=$(git branch --show-current)
run=$(gh run list -b "$branch" -s failure -L 1 \
--json databaseId --jq '.[0].databaseId')
gh run view "$run" --log-failed > .context/ci-failed.log
gh run list filters by branch (-b) and status (-s failure), and databaseId is the run ID that gh run view takes. Now the prompt is "read .context/ci-failed.log and explain the failure before you change anything."
For one-off questions you can skip the folder. The Claude Code CLI reference shows piped input with cat logs.txt | claude -p "explain", so you can send the log straight in:
gh run view "$run" --log-failed \
| claude -p "Why did this CI run fail?"
2. The issue it's supposed to fix
You paste the issue title. The repro steps, the stack trace someone attached and the maintainer comment that says "don't touch the retry logic" stay on GitHub. gh issue view with --comments brings the thread:
gh issue view 482 --comments > .context/issue-482.md
If you want structure instead, --json takes fields such as body, comments, labels and state.
3. The PR review thread
This one catches people. Line comments left during a review are a separate thing from the PR's conversation comments. GitHub's REST docs describe review comments as "comments made on a portion of the unified diff during a pull request review", distinct from issue comments on the PR, with their own endpoint (GitHub docs). gh api fills in {owner} and {repo} from the repo you're in:
gh api --paginate \
"repos/{owner}/{repo}/pulls/57/comments" \
--jq '.[] | {path, line, user: .user.login, body}' \
> .context/pr-57-review.json
Each comment carries the path and line it refers to, so the agent can go to the exact spot. The endpoint returns 30 comments per page by default, which is why --paginate is there.
Production state that never lands in git
Your migrations describe the schema you meant to have. Your code reads flags by name. Neither tells the agent what is true right now.
4. The live database schema
A migration that ran by hand, an index someone added during an incident, a column type that drifted: the agent can't know. pg_dump with --schema-only dumps object definitions and no table data:
pg_dump --schema-only --no-owner --no-privileges \
-t 'orders*' -d "$REPLICA_URL" > .context/schema.sql
--no-owner and --no-privileges drop the ALTER OWNER and GRANT lines, which are noise for this job. -t takes a pattern, so you send the tables that matter rather than the whole database. The PostgreSQL docs warn that -t doesn't pull in dependent objects, so if the agent's question is about a foreign key, include the other table too. Point it at a read replica with a read-only role, not at your primary.
5. What the service printed at runtime
The stack trace from the request that failed ten minutes ago is in the container's output, not in any file the agent can open. docker logs takes --since (a relative duration like 30m or a timestamp), --tail and -t for timestamps:
docker logs --since 30m --tail 300 -t api \
> .context/api.log 2>&1
The 2>&1 matters: without it, anything the container wrote to stderr goes to your terminal and not into the file, because docker logs keeps the container's stdout and stderr separate.
6. The current feature-flag state
The code says if (flags.isOn("new-checkout")). Whether that's on in production, and for whom, lives in your flag service. With LaunchDarkly, GET /api/v2/flags/{projectKey}/{featureFlagKey} with env=production returns one flag, and the environment's on, rules and fallthrough sit under environments.production:
LD=https://app.launchdarkly.com/api/v2/flags
curl -s -H "Authorization: $LD_API_TOKEN" \
"$LD/default/new-checkout?env=production" \
| jq '.environments.production | {on, rules, fallthrough}' \
> .context/flag-new-checkout.json
Replace default with your project key and use a read-only token. If you're on a different flag service, find its read call for one flag in one environment. Targeting rules often name real customers or segments, so this is the file to read most carefully before you hand it over.
The browser is its own world
7. The browser console and network tab
A blank page with a red error in DevTools looks fine from the source code. The agent needs to load the page. The Playwright MCP server gives it a browser, and its README has the Claude Code install line:
claude mcp add playwright npx @playwright/mcp@latest
Two of its tools do this job. browser_console_messages "returns all console messages", and browser_network_requests returns "a numbered list of network requests since loading the page." Ask the agent to open the page on your dev server, then read both before it edits a component. Claude Code also has a --chrome flag for its own Chrome integration if you'd rather not add an MCP server.
Make it outlast the session
The commands fix today's session. Tomorrow's starts with a fresh context window again, and you're pasting the same schema for the third time.
Without any extra tool, you have two options. Put the standing facts in CLAUDE.md, which Claude Code loads at the start of every session, or in AGENTS.md, which it reads instead when the repo has no CLAUDE.md (memory docs). And when the context sits in another repo, --add-dir gives Claude access to more folders, with permissions.additionalDirectories in settings to keep them across sessions (CLI reference).
I build Hermes IDE, so weigh this part with that in mind. Two of its features are aimed at this problem. Memory and context pins: facts and pinned files you save for a project reach every later session's agent, even after a restart. Pin the schema file once and you stop pasting it. And extra folders: since 2.3.0, when you start a Claude Code task with ⌘N (Ctrl+Shift+N on Windows and Linux) you can tick up to 5 extra folders next to the main project, such as the repo that holds your shared types or your infra config.

The ⌘N New task sheet with the project picker open: main project orders-api plus two ticked extra folders, orders-types on branch rename-ship-to and web-app on main with 2 uncommitted changes, and the "Also:" chips noting extra folders are edited in place.
Know the trade-off before you tick one. Only the main project gets the task's new branch. The release notes say extra folders "are worked on where they are, on the branch they are on", so an agent can edit them in place.
Since 2.3.3, when you attach a project to a running terminal session, the agent gets a message to read the updated project context. Hermes keeps context around once you have it; the seven commands above are still yours to run. Hermes is free, source-available under BSL 1.1, on macOS, Windows and Linux, and it isn't affiliated with Anthropic, OpenAI or Nous Research. Download it or read the code on GitHub.
The short version
| Agent can't see | Command |
|---|---|
| CI failure | gh run view <id> --log-failed |
| Issue thread | gh issue view <n> --comments |
| PR line comments | gh api repos/{owner}/{repo}/pulls/<n>/comments |
| Live schema | pg_dump --schema-only -t <pattern> |
| Runtime logs | docker logs --since 30m |
| Flag state | flag service API, one flag, one env |
| Browser console | Playwright MCP browser_console_messages
|
Which one does your agent guess about most often? I'd bet on the PR review thread. Tell me in the comments if I'm wrong.
If this was useful
Every command in this post is context engineering in its smallest form: decide what the model needs, fetch exactly that, and cut the noise before it reaches the prompt. The Prompt Engineering Pocket Guide covers the rest of that craft, from system prompts and instruction files to structured output and prompt injection, the risk that comes with pasting text from logs and issues you didn't write. If you want the context to survive between sessions, that's what I'm building Hermes IDE for.

Top comments (0)