New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@tangle-network/harness-sessions

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tangle-network/harness-sessions

One reader for every coding-agent harness's native session (Claude Code, Codex, OpenCode, Pi): store layouts, a normalized session with messages, tool calls, served models, usage and ending errors, and projections to chat messages, OTLP spans and turns

Source
npmnpm
Version
0.1.2
Version published
Weekly downloads
1.8K
121.18%
Maintainers
1
Weekly downloads
 
Created
Source

@tangle-network/harness-sessions

One reader for every coding-agent harness's native session.

Each harness persists its session in its own store: Claude Code and Pi append JSONL, Codex appends a rollout JSONL, and OpenCode writes SQLite. This package declares each store's layout once and parses each format into one normalized HarnessSession. The session holds the messages, the tool calls with their inputs and results, every model call with the model that served it and its usage, and the error the session ended with.

npm install @tangle-network/harness-sessions

Where this fits

  • The sidecar's harness session contract (agent-container packages/cli-agent-registry) imports STORES and SessionFormatId from here; it keeps no second copy of where a harness writes.
  • The capture path reads captures through listCapture / readCapture.
  • Discovery's trace gate, agent-eval, agent-record and the blog read sessions only through this package.
  • Its only dependencies are @tangle-network/agent-trace-contract and Node built-ins (node:sqlite for OpenCode).

Formats

HarnessFormatStore under HOMEServed model fromUsage
claude-codeclaude-code.projects-jsonl.claude/projects/*/{id}.jsonl, subagents at */{id}/subagents/**/*.jsonlprovider response (message.model)per response, counted once per message.id
codexcodex.rollout-jsonl.codex/sessions/*/*/*/rollout-*-{id}.jsonlturn context (the configured model)per response (last_token_usage); session total from total_token_usage
opencodeopencode.sqlite.local/share/opencode/opencode.db (shared by every session)session record (providerID/modelID)per step (step-finish)
pipi.session-jsonl.pi/agent/sessions/**/*_{id}.jsonlsession record (provider/model)per assistant message

Readers for Kimi, Factory, Gemini, Amp, Qwen, Copilot, Forge, Hermes, Prime and OpenClaw are added with the same real-data proof.

Use

import { readerFor, listCapture, toChatMessages, toOtlpSpans, toTurns } from '@tangle-network/harness-sessions'

// Sessions in a HOME, through the harness's declared store
const reader = readerFor('pi')
for (const ref of await reader.locate('/home/agent')) {
  const summary = await reader.summarize(ref) // constant memory; a 537 MB rollout reads in ~200 MB RSS
  const session = await reader.read(ref)      // full fidelity: nothing is truncated
}

// Sessions in a capture (provider retention layout today, raw-evidence archive v2 when given)
const { sessions, missing } = await listCapture(captureDir)

Projections trim; the reader never does:

  • toChatMessages(session): agent-eval's chat-with-tools messages.
  • toOtlpSpans(session): contract spans (@tangle-network/agent-trace-contract), one LLM span per model call and one TOOL span per tool call.
  • toTurns(session): the blog's turns, with the model, usage and error of each assistant turn.

For callers that are not JavaScript:

harness-sessions read <file|home|capture> [--harness h] [--session id] [--summary] [--json]

Rules the readers keep

  • The served model comes only from the provider response or the session record, never from the profile or the request. A failed request has no served model; requestedModel says which model it was sent to.
  • usage is null when the harness recorded none; it is never reported as zero. input excludes cache reads and cache writes, which have their own fields.
  • A session with zero model calls is not the trace of a turn.
  • An unparsable record is counted in integrity.unparsedRecords and never stops a read (corruption: 'strict' throws instead). A record cut off at the end of a live copy is reported as a torn tail, not as corruption.
  • ending.status is completed, error, aborted or open. open means the records stop mid-turn: the turn was still running or the process died.
  • An OpenCode store is read from a private copy, never in place.

Tests

The fixtures are sessions that the real harness CLIs wrote while talking to the trace-proof scripted model; the tests assert that script. The proof against the readers this package replaces is a comparison over stored sessions, recorded with each release.

FAQs

Package last updated on 15 Oct 2026

Related posts