| name | catalog-codex-threads |
| description | Build and use a local metadata catalog for Codex tasks. Use when finding an old Codex task, searching by project/subproject/PR/ticket/tag/context, annotating a task, backfilling Codex task history, or installing optional hooks that automatically accumulate references and searchable turn context across long-running coding tasks. |
Catalog Codex Threads
Use the bundled stdlib-only CLI. Set SKILL_DIR to the actual directory that
contains this SKILL.md; the standard personal-skill installation is:
SKILL_DIR="${CODEX_HOME:-$HOME/.codex}/skills/catalog-codex-threads"
SCRIPT="$SKILL_DIR/scripts/catalog.py"
python3 "$SCRIPT" status
Keep the catalog outside Codex-owned databases. The CLI writes only to
${CODEX_THREAD_CATALOG_HOME:-${CODEX_HOME:-$HOME/.codex}/thread-catalog} and
reads Codex state/rollouts without modifying them.
Find a task
- Run
sync to refresh titles, repositories, branches, archive state, and
initial task text from Codex's read-only state database.
- Run
find with ordinary words, structured filters, or both.
- If metadata search misses, run
content for literal transcript fallback.
- Use
open <thread-id> only when the user asks to open the result.
python3 "$SCRIPT" sync
python3 "$SCRIPT" find 'project:lindy subproject:slack routing'
python3 "$SCRIPT" find 'pr:24456 reminder regression'
python3 "$SCRIPT" content 'exact phrase from the task' --archive both
python3 "$SCRIPT" open 019f61e9-c331-7d32-a6e5-79978fad5869
Treat kind:value terms as exact filters. Free words are typo-tolerant fuzzy
terms. Search results explain whether metadata, title/repository/branch, turn
context, or structured filters matched, and echo the exact values that
satisfied structured filters even when a task has dozens of values.
Repository-scope stored pull requests (owner/repo#123). A numeric query such
as pr:123 may match multiple repositories and must display each repository.
Annotate the current task
annotate uses $CODEX_THREAD_ID when --thread is omitted. Facts are
additive: never delete earlier PRs, tickets, projects, or contexts merely
because the task moved to new work. One task may legitimately accumulate many
values of each kind.
python3 "$SCRIPT" annotate --source agent \
--project lindy \
--subproject 'Slack routing' \
--context 'Reminder delivery regression in shared channels' \
--pr owner/repo#123 \
--pr owner/repo#124 \
--ticket ENG-80 \
--ticket ENG-83
Use --source agent for model-inferred facts. Use the default manual only
for values explicitly supplied or corrected by the user. Manual provenance
outranks agent, hook, parsed, Git, and Codex provenance and must not be
downgraded by later syncs.
Use repeated --context, --project, --subproject, --pr, --ticket,
--issue, and --tag arguments. Use --fact kind=value for other domains
such as customers or incidents. Use --remove kind=value only for an exact,
confirmed correction.
When this skill is active during coding work, add a compact semantic context
once the scope is clear. Do not invent a single "primary PR" or "primary
ticket"; capture every durable reference that appears.
Install automatic capture hooks
Install hooks only after the user explicitly opts in. The installer merges
three handlers into ~/.codex/hooks.json, preserves unrelated hooks, creates a
timestamped backup, and can remove only its own handlers. Restart Codex after
installation or removal, and approve/trust the hooks if Codex prompts. The
installer does not and must not bypass Codex's trust controls.
python3 "$SCRIPT" install-hooks --capture user-assistant
python3 "$SCRIPT" uninstall-hooks
Capture modes:
identifiers: store recognized references and Git/Codex snapshots only.
user: additionally store bounded user prompts for fuzzy context search.
user-assistant: additionally store bounded assistant messages. The live
Stop hook supplies the final message; deep backfill may include intermediate
assistant updates. This is the default and gives the best retrieval.
Hooks are fail-open and never block coding work. They recognize every observed
GitHub pull-request/issue URL, repository-scoped reference, bare PR #123
when the current repository is known, Linear URL/key, learned ticket key, and
explicit project:, subproject:, context:, tag:, customer:, or
incident: marker. A ticket prefix is learned from a Linear URL, an explicit
ticket:ENG-123 marker, a manual/agent --ticket, or configuration. Once
learned, matching keys in later prompts and Git branches are recognized
automatically. Uncorroborated forms such as RFC-3339 stay generic references
instead of polluting ticket metadata. Repeated turns accumulate facts instead
of replacing them.
Ordinary sync also recognizes repository-scoped PR numbers prepended to task
titles, including 22617 - ..., #22620 ..., and 22600, 22630 - .... This
preserves title-based workflows while every later PR accumulates as metadata.
The stored passages exclude tool output, are truncated per turn, and retain at
most 200 recent passages per task by default. A compact deduplicated token
vocabulary preserves fuzzy recall when old raw passages rotate out. Capture
settings apply only to future ingestion; they do not rewrite already captured
data. Configure the local privacy/size tradeoff or explicitly purge all stored
passages and context vocabulary with:
python3 "$SCRIPT" configure --capture identifiers
python3 "$SCRIPT" configure --capture user-assistant \
--max-passage-chars 4000 --max-passages-per-thread 200
python3 "$SCRIPT" configure --ticket-prefix ENG --ticket-prefix OPS
python3 "$SCRIPT" configure --purge-passages
Backfill existing tasks
Use ordinary sync first; it discovers a compatible state_*.sqlite by
schema and reads it in read-only mode. The first import can take several
seconds on a large history; later runs skip unchanged snapshots. Use
sync --deep only when the user wants historical turn-level fuzzy search and
understands that the first scan may read a large rollout corpus.
Deep sync stores only bounded user/assistant passages and recognized facts,
tracks per-file offsets, and processes later appends incrementally.
python3 "$SCRIPT" sync
python3 "$SCRIPT" sync --deep
Do not write to state_5.sqlite, session_index.jsonl, session rollouts, or
archived rollouts. Do not add embeddings or remote services unless lexical
search has demonstrated a real failure and the user accepts the privacy cost.
Distribution and validation
Distribute the entire catalog-codex-threads folder. It requires Python 3.9 or
newer; rg is optional and used only by content. The hook installer resolves
the copied skill's absolute script path at installation time.
After modifying the skill, run:
python3 -m unittest discover -s "$(dirname "$SCRIPT")" -p 'test_catalog.py' -v
python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/skill-creator/scripts/quick_validate.py" \
"$SKILL_DIR"