dnotitia/akb/session-ingest

Claude Code and agent skill by dnotitia/akb

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Ingest a coding session JSONL into AKB as structured notes — session report + parallel-drafted TIL / task / idea / decision sub-notes. Auto-discovers the current session's JSONL when no positional path is given (Claude / Codex). `--delegate {target}` fires the work to another target's CLI and exits.

Install

npx vskill@latest install dnotitia/akb/session-ingest

SKILL.md

AKB Session Ingest

Resource identity. Retain the canonical uri returned by search, browse, get, or put alongside every document ID/path. Use it unchanged for akb_get, akb_update, relations, and graph edges; collection-scoped URIs cannot be reconstructed by prefixing a path with /doc/. Capture matched URIs as matched_uri, dedup_uri, existing_uri, or existing_session_uri; draft targets carry append_uri / supersedes_uri, tasks carry task_uri, and newly written documents carry doc_uri / session_uri. IDs remain display/tag values only.

Multi-agent workflow that analyzes a session JSONL file and writes structured notes to an AKB vault.

Workflow classification. LLM-wiki Ingest workflow. Cognitive-debt layer — it captures the in-flight reasoning of a coding session (how the team arrived at an understanding, the decisions and dead ends), turning ephemeral working context into persistent compiled-truth notes (TIL / decision / idea / task) before it evaporates. The four drafter subagents share this classification.

Prerequisites

  • AKB MCP server is accessible.
  • --vault {name} provided.

Execution Flow

text
Phase 0 — Resolve parse args, resolve JSONL path (auto or explicit), maybe delegate & exit
Phase 1 — Prepare detect duplicates, fetch open tasks
Phase 2 — Draft read JSONL, identify commits/repo, draft session note
Phase 3 — Sub-Draft launch til / task / idea / decision drafters; triage ideas
Phase 4 — Write dedup ↔ finalize ↔ write session, sub-notes, resolve tasks

Phase 0 — Resolve & Maybe Delegate

Resolve invocation arguments and the JSONL path. Optionally fire-and-forget to a different target's CLI and exit early. All Phase 1+ work assumes $VAULT and $JSONL_PATH are set and the JSONL file exists.

0-1. Parse Arguments

Parse positional [jsonl_path] (optional) and flags:

  • --vault {name} (required) — hard-fail with --vault {name} required. if absent
  • --lang {language} (optional) — preferred language for synthesized note body
  • --delegate {claude|codex} (optional) — fire-and-forget to a different target's CLI and exit early

Store as $JSONL_PATH, $VAULT, $LANG_FLAG, $DELEGATE.

0-2. Reject Self-Delegate

The current target was baked in at build time. If --delegate matches it, abort to prevent infinite recursion.

bash
SELF="codex"
if [ -n "$DELEGATE" ] && [ "$DELEGATE" = "$SELF" ]; then
echo "Refusing $SELF -> $SELF delegate (would recurse)." >&2
exit 2
fi
0-3. Resolve JSONL Path

If $JSONL_PATH was supplied positionally, use it. Otherwise discover the current session's JSONL automatically — discovery is target-specific.

Codex target — `$CODEX_THREAD_ID` env var + `find` across active and archived sessions.

bash
if [ -z "$JSONL_PATH" ]; then
if [ -z "${CODEX_THREAD_ID:-}" ]; then
echo "CODEX_THREAD_ID empty — not inside a Codex thread. Pass <jsonl_path> explicitly." >&2
exit 2
fi
CODEX_ROOT="${CODEX_HOME:-$HOME/.codex}"
JSONL_PATH=$(find "$CODEX_ROOT/sessions" "$CODEX_ROOT/archived_sessions" \
-type f -name "*${CODEX_THREAD_ID}.jsonl" -print 2>/dev/null | head -1)
if [ -z "$JSONL_PATH" ]; then
echo "No JSONL found for thread ${CODEX_THREAD_ID} under $CODEX_ROOT" >&2
exit 2
fi
fi

Verify the resolved path exists before proceeding:

bash
if [ ! -f "$JSONL_PATH" ]; then
echo "JSONL path not readable: $JSONL_PATH" >&2
exit 2
fi
0-4. Delegate Fire-and-Forget (Optional)

If $DELEGATE is set, hand the ingest work to a different target and exit. The current session does no ingest work — the receiver runs Phase 1+ on the same JSONL. claude / codex spawn the target's CLI in the background.

Each target runs the receiver unattended while limiting blast radius if the JSONL contains injected content:

  • claude: --permission-mode acceptEdits auto-approves file edits; Bash/MCP rely on the skill's allowed-tools.
  • codex: -s workspace-write -c approval_policy="never" — confines file writes to the workspace AND skips approval pauses. --skip-git-repo-check lets the receiver start in a non-git pwd (delegate does not require the JSONL's project to be checked out). Avoid --dangerously-bypass-approvals-and-sandbox: that drops the sandbox entirely, letting prompt-injection in the JSONL escalate to arbitrary shell.
bash
LOG="${TMPDIR:-/tmp}/session-ingest-delegate-$(date +%s)-$$.log"
ARGS="\"$JSONL_PATH\" --vault \"$VAULT\""
[ -n "$LANG_FLAG" ] && ARGS="$ARGS --lang \"$LANG_FLAG\""
case "$DELEGATE" in
claude)
nohup claude -p "/session-ingest $ARGS" --permission-mode acceptEdits \
>"$LOG" 2>&1 &
echo "Delegated to claude (pid $!, log $LOG)."
;;
codex)
# $session-ingest must NOT shell-expand. Single-quote the literal,
# then concatenate the double-quoted $ARGS so the file path stays quoted.
# --skip-git-repo-check: the receiver may run in a non-git pwd (delegate
# does not require the JSONL's project to be checked out); codex exec
# otherwise aborts before starting.
PROMPT='$session-ingest '"$ARGS"
nohup codex exec --skip-git-repo-check -s workspace-write -c 'approval_policy="never"' "$PROMPT" \
>"$LOG" 2>&1 &
echo "Delegated to codex (pid $!, log $LOG)."
;;
"")
: ;;
*)
echo "Unknown --delegate target: $DELEGATE (expected: claude, codex)" >&2
exit 2
;;
esac
if [ -n "$DELEGATE" ]; then
exit 0
fi

Phase 1 — Prepare

1-1. Detect Duplicates

Before reading the full JSONL, check whether this session was already ingested.

Detect JSONL Schema

Read the first ~10 lines of the JSONL (Read with limit: 10). The opening line may be a noise event without identifying fields (CC sessions sometimes start with permission-mode or file-history-snapshot, neither of which carries sessionId); scan all 10 to find the first line that decisively identifies the schema:

  • If any of those lines has a top-level sessionId field (e.g., {"type": "worktree-state", "sessionId": "..."} or {"type": "user", "sessionId": "..."}), the JSONL is CC schema (flat per-line events). Set jsonl_schema = "cc".
  • If any line has a top-level payload object containing id (e.g., {"timestamp": "...", "type": "session_meta", "payload": {"id": "...", "cwd": "..."}}), the JSONL is Codex schema (event-wrapped). Set jsonl_schema = "codex".
  • If none of the first 10 lines yields either signal, hard-fail with "Unrecognized JSONL schema: $JSONL_PATH" — do not guess.

Schema detection is independent of runtime.target: a Codex JSONL ingested from a Claude harness still uses Codex parsing, and vice versa.

Extract Session ID, Timestamps, and Source CWD

Reuse the first-10-lines window from schema detection and read the last few lines of the JSONL. Capture everything the head window carries in one pass — later phases reuse these values rather than re-scanning. Field lookup is schema-aware:

For jsonl_schema == "cc":

  • Store the first encountered sessionId field as session_id. (Lines without sessionId such as file-history-snapshot are skipped — they precede the first content event in some sessions.)
  • If a worktree-state entry is present, store worktreeSession.originalCwd as session_cwd; otherwise leave session_cwd unset.

For jsonl_schema == "codex":

  • Find the entry with type == "session_meta" (typically the first line). Store payload.id as session_id and payload.cwd as session_cwd.

For both schemas:

  • Last entry's top-level timestamp → jsonl_last_timestamp.

Store:

  • session_id — the resolved session/thread id
  • jsonl_last_timestamp — the ISO 8601 timestamp of the final entry
  • session_cwd — the source session's working directory (or unset)
Search Vault for Existing Session
text
mcp__akb__akb_search(
query="{session_id}",
vault="{vault_name}",
collection="sessions",
tags=["session:{session_id}"],
type="session",
limit=1
)

No match → sync_mode = "new", proceed to Phase 2.

Match found → read the existing session note:

text
mcp__akb__akb_get(uri="{matched_uri}")
→ existing_session_doc_id, existing_tags, existing_session_content

Extract the last-synced:{timestamp} tag value from the existing note's tags. Store as last_synced_timestamp. Preserve existing_session_content (the full markdown body) for Phase 2-3 and Phase 4-1.

Compare Timestamps
  • jsonl_last_timestamp <= last_synced_timestamp → no new content since last sync → stop:

"Session {session_id} already synced up to {last_synced_timestamp}. No new content. Skipping."

  • jsonl_last_timestamp > last_synced_timestamp → proceed to the new-content assessment below.
Assess New Content

Read the JSONL entries with timestamps after last_synced_timestamp. Filter out noise. The filter list is schema-aware:

For jsonl_schema == "cc":

  • type: "system" messages
  • type: "permission-mode" entries
  • type: "file-history-snapshot" entries
  • User messages containing only /exit, /quit, or session-end signals
  • isMeta: true entries

For jsonl_schema == "codex":

  • type: "turn_context" entries (per-turn configuration)
  • type: "event_msg" with payload.type in {task_started, token_count} (system markers and telemetry)
  • type: "response_item" with payload.type == "reasoning" (model-internal thinking, analogous to CC thinking blocks)
  • User messages (type: "event_msg" with payload.type == "user_message") containing only /exit, /quit, or session-end signals
  • type: "session_meta" (metadata-only, already consumed for session_id extraction)

After filtering, judge whether the remaining entries represent meaningful work — substantive user messages, assistant responses with real content, tool calls that changed files, or decisions made.

Not meaningful (e.g., resume then immediately exit, only system noise) → stop: "Session {session_id} has entries after {last_synced_timestamp} but no meaningful new work. Skipping."

Meaningful → set sync_mode = "update", store existing_session_doc_id and last_synced_timestamp, proceed to Phase 1-2.

1-2. Retrieve Open Tasks

Before reading the full JSONL, retrieve project-scoped open tasks from the vault so the session drafter can identify which tasks this session resolved.

Parallel execution with Phase 1-1: the project-name parse step below runs immediately (no MCP), and the akb_search for open tasks is independent of Phase 1-1's duplicate-detection search. Issue Phase 1-1's existing-session search and Phase 1-2's open-task search in a single parallel tool-use block. Act on Phase 1-2 results only after Phase 1-1 greenlights continuation (otherwise discard).

Derive Project Name

Project name is the basename of the source session's working directory. Use session_cwd (captured in Phase 1-1) when set — it is authoritative metadata from the JSONL, and cross-target delegate (e.g. Claude → Codex) puts the receiver in a different pwd than where the session originated, so pwd is not a reliable fallback.

  • session_cwd set → project_name is its basename. (For CC worktree sessions this is originalCwd, the unworktreed project root, not the worktree name.)
  • session_cwd unset (CC session with no worktree-state entry) → use the current working directory's basename. The CC JSONL parent directory uses a lossy encoding (/ and . both map to -), so decoding it is unreliable and not used.

If derivation fails entirely, set project_name to the empty string. The downstream open-tasks query becomes a no-op (no project: tag match) — degraded but safe.

Query Open Tasks
text
mcp__akb__akb_search(
query="open task",
vault="{vault_name}",
collection="sessions/tasks",
type="task",
tags=["project:{project_name}"],
limit=20
)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
75
Repository forks
6
7-day trend score
22

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/dnotitia/akb/session-ingest/badge)](https://verified-skill.com/skills/dnotitia/akb/session-ingest)

Something wrong with this skill or its page? Tell us.