Webapp Builder
sidequery/sidemantic
Build interactive analytics webapps, demos, dashboards, or embedded app surfaces from Sidemantic semantic models using copyable component primitives and deterministic query inspection.
Integrate a new AI coding-agent harness into txcript — native Body types, Codec, TextCodec, Store, wiring, and tests.
$ npx skills add skillsynchq/txcript --skill harness -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install skillsynchq/txcript harness --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/skillsynchq/txcript.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/harness .claude/skills/harness && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "harness" agent skill from https://github.com/skillsynchq/txcript/tree/main/.claude/skills/harness into .claude/skills/harness/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "harness", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/skillsynchq/txcript/tree/main/.claude/skills/harnessType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add skillsynchq/txcript --skill harness -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install skillsynchq/txcript harness --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skillsynchq/txcript.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/harness .agents/skills/harness && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "harness" agent skill from https://github.com/skillsynchq/txcript/tree/main/.claude/skills/harness into .agents/skills/harness/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "harness", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add skillsynchq/txcript --skill harness -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install skillsynchq/txcript harness --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skillsynchq/txcript.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/harness .cursor/skills/harness && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "harness" agent skill from https://github.com/skillsynchq/txcript/tree/main/.claude/skills/harness into .cursor/skills/harness/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "harness", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/skillsynchq/txcript.git --path .claude/skills/harness--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add skillsynchq/txcript --skill harness -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install skillsynchq/txcript harness --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skillsynchq/txcript.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/harness .gemini/skills/harness && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "harness" agent skill from https://github.com/skillsynchq/txcript/tree/main/.claude/skills/harness into .gemini/skills/harness/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "harness", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install skillsynchq/txcript harnessInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add skillsynchq/txcript --skill harness -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/skillsynchq/txcript.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/harness .github/skills/harness && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "harness" agent skill from https://github.com/skillsynchq/txcript/tree/main/.claude/skills/harness into .github/skills/harness/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "harness", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add skillsynchq/txcript --skill harness -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install skillsynchq/txcript harness --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/skillsynchq/txcript.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/harness .opencode/skills/harness && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "harness" agent skill from https://github.com/skillsynchq/txcript/tree/main/.claude/skills/harness into .opencode/skills/harness/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "harness", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
harnessIntegrate a new AI coding-agent harness into txcript — native Body types, Codec, TextCodec, Store, wiring, and tests.
Harness is an agent skill from skillsynchq/txcript. Integrate a new AI coding-agent harness into txcript — native Body types, Codec, TextCodec, Store, wiring, and tests. Use when asked to add or integrate a new harness or transcript format. Takes the harness name, its format docs (URL or path), and one real local session id to anchor implementation and verification on.
Its SKILL.md is about 4.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/patterns.md`).
It works with Rust, Model Context Protocol and WebAssembly. The repository describes itself as: Pandoc for AI chats. Move ai chats across harnesses: Claude Code, Codex, OpenCode, Cursor, and more. Rust library, CLI, and WASM. The licence is Apache-2.0.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 8cd3b0e. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
cargoopencodeclaudeFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Harness loads about 4.2k tokens when it runs, and up to ~8.1k if it reads all its reference files. Until then it costs about 82 tokens; SKILL.md has 2,240 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from skillsynchq/txcript at commit 8cd3b0e, republished under its Apache-2.0 licence (© skillsynchq). 2,240 words, ~4,226 tokens.
.claude/skills/harness/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.You are adding a harness to txcript, the transcript converter in this repo. The
work is one flat file src/harness/<name>.rs plus wiring and tests, but the
quality bar is set by two fidelity contracts (below) and by the fact that the
output must actually resume in the native app — a session that loads but
shows an empty conversation is a failed integration.
$ARGUMENTS: <name> <docs> <sample-session-id>
name — the harness (e.g. gemini, amp). Derive the snake_case id from it.docs — URL or file path describing the native transcript format.sample-session-id — a real session of that harness on this machine. This is
your ground truth. If any input is missing, ask before starting.src/lib.rs)Body holds a faithful typed
representation; Store/TextCodec round-trip it without loss. This is
value-level, not byte-level: serde_json is built without preserve_order,
so key order canonicalizes — tests assert record equality, never string
equality of the file.Common is semantically lossless. to_common may canonicalize
representation (so the thread works in another harness) but must never
discard what a same-harness round trip needs. The testable form is the
fixpoint: to_common(from_common(c)) == c for any c in the
harness-representable subset of Common.Corollary: from_common must be pure and deterministic — synthetic ids are
UUIDv5 over a fixed namespace and stable keys like "{session_id}:{i}:{j}",
never Uuid::new_v4() (sole exception: generating a session id when meta.id
is empty), never clock reads.
Before writing any Rust:
<docs>.~/.<name>/…, XDG data dirs, an SQLite DB, app-support dirs) until you
locate the file/rows for <sample-session-id>.<name> export, sessions list, a
--print resume) and use it as a load oracle: copy the sample under a
fresh id, then delete files/records until it stops loading. What survives
deletion is bookkeeping; what breaks the load is the regeneration contract
for from_common — learned before writing any code, at zero model cost.--prompt-json-style flag reveals content-block encodings). The same
trick answers optionality questions: to learn whether the native parser
treats a field as optional, load a session without it.to_common is then a join across carriers and from_common a fan-out —
knowing the carrier map is most of the codec design.Where docs and bytes disagree, model the bytes. Keep the dump — it becomes your
test fixture material and the final verification anchor. Copy the sample
session out of the live root NOW: save() derives its path from Meta, so
converting a session back into its source harness reuses the original id and
silently overwrites your ground truth.
Pick the closest existing codec as your reference and re-read it before implementing (don't work from memory of it):
| Native format | Reference | Body pattern |
|---|---|---|
| JSONL, one envelope kind | codex.rs | Single Line { timestamp, type, payload: Value, #[serde(flatten)] extra } |
| JSONL, a few typed kinds | claude_code.rs, pi.rs | Enum with manual serde via From<Value> dispatch on the type tag; parse failure → Other(Value); tagged() helper re-inserts the tag on render |
| One JSON export document | opencode.rs | Body = the harness's own export/import shape; typed two-level envelope, everything inside stays Value, navigated with .get() |
| SQLite with opaque blobs | cursor.rs | Body = raw rows (Vec<u8> blob bytes with hex serde + meta rows); losslessness at the blob level; only parse what you understand |
| Session directory, multiple logs | grok.rs | Body = struct of per-file fields (typed model log, raw Vec<Value> display/telemetry logs, Option<Value> sidecars); "text" is a JSON bundle of the directory |
| Sibling of an existing harness | campfire.rs | Thin delegate: reuse the donor's pub(crate) helpers, change only identity and storage root |
Details and per-harness idioms: read references/patterns.md in this skill
directory now.
Value inside a typed envelope.#[serde(flatten)] extra: Map<String, Value> for
unknown keys, and #[serde(default, skip_serializing_if = "Option::is_none")]
on every optional field — absent must not round-trip as null.extra.Value variant
(Record::Other(v)) — never an error, never a dropped line. One corrupt line
must not sink the session (jsonl::parse already skips unparseable lines for
the line-based path).deny_unknown_fields on harness record types. It exists only on
the canonical tool-arg structs in common.rs, where it forces the lossless
Tool::Raw fallback.normalize_tool(name, input) that maps native tool names and argument keys
onto it (bash→Bash, path→file_path, …), then call
Tool::from_canonical. Its deny_unknown_fields→Raw fallback is the
safety net — never bypass it, never pre-drop keys. mcp__* passes through.
Write denormalize_tool at the same time; they must be a real inverse pair,
including shape changes (e.g. pi's multi-hunk edit → Edit/MultiEdit by
hunk count).Role::User messages (Anthropic convention). Errored
calls → is_error: true; in-flight calls → ToolUse with no result.<user_query>-style wrappers — strip on read, re-wrap on write).
Skip empty/whitespace-only blocks and messages that end up empty. Unknown
block types drop from Common — they still live in the native body.meta.timestamp; never error.null (codex refuses sessions missing model_provider/
base_instructions keys). Regenerate both logs of a dual-log format, and any
internal structures the app needs (Cursor's protobuf turn graph, sidecar
meta.json). The failure mode here is silent: the app starts a fresh or
empty session. Only end-to-end resume testing catches it.ToolOutput::Json into a
string field, an image block into a text-only log), flatten to the observed
shape (block arrays → joined text, other JSON → compact string, image →
its display-log carrier plus a placeholder) and document the loss.tool_use_id → native tool name map while emitting tool calls so
redundant result fields can be reconstructed; give orphans a fallback.totalTokens) and comment that they are
best-effort historical reconstruction.Some(default) (e.g. omit an all-zero cache object entirely).replace_all, StopReason::Other). Accept the loss, document it in the
module doc, and keep the fixpoint fixture inside the representable subset.meta_from_records: per-field fallback chains with explicit keep-first or
last-wins semantics (e.g. latest model_change wins; custom-title beats
summary). Filter placeholder titles. Leave id empty when the text has none —
the Store fills it from the filename/row. Timestamp fallback: Utc::now().
TextCodec is pure text↔records, zero I/O — it is the WASM boundary. For a
DB-backed harness, "text" is a JSON dump of the Body (binary as hex), not
anything the native tool emits; it must round-trip to an identical Body.Store: default_root() returns Option<Self> honoring env overrides then
$HOME paths (match the pattern in pi::resolve_sessions_dir). discover()
is tolerant: missing root → Ok(vec![]), unreadable files silently skipped,
and sniff the format (e.g. first record must be the session header) —
extension alone doesn't identify a harness. load() backfills an empty
meta.id from the file stem (jsonl::file_id). save() derives a
deterministic path from Meta — copy the native app's directory encoding
exactly (Claude maps both / and . to -; pi wraps --{cwd}--; Cursor
uses md5(cwd)). fingerprints() is cheap: "{mtime_nanos}:{len}" or a
MAX(time) query; failures → empty string, never an error.dep: only),
keep the codec and Body compiling featureless, and stub the Store without the
feature (empty discover, Unconvertible load/save). Open another tool's DB
READ_ONLY; prefer delegating writes to the harness's own CLI importer if
one exists (opencode import pattern) over reverse-engineering schema
defaults.Every item, in order; the exhaustive matches make most omissions compile errors:
src/harness/<name>.rs — the whole harness, one flat file, module doc
explaining format + known losses.src/harness/mod.rs — pub mod <name>;src/transcript.rs — HarnessId variant, ALL array (bump its length),
as_str, FromStr with friendly aliases.src/bin/cli.rs — resume_command default, a discover_all block, a
load_common arm, a save_target arm.src/wasm.rs — both dispatch matches (parse_to_common,
render_from_common) and the doc-comment harness list.Cargo.toml — feature entry if a new dep; keep it out of the wasm build.README.md — supported-harness list, string id, WASM text-format note.tests/integration/<name>.rs (declared in tests/integration/main.rs),
a new hop in tests/integration/cross_harness.rs, and a new
assert_fixpoint line in tests/integration/properties.rs — see
tests/README.md for the taxonomy.Repo style: hierarchical imports — import modules and qualify (common::Tool,
jsonl::parse), never flatten items to the crate root. Clippy pedantic is on
and unwrap/expect/panic are denied in src/ (allowed in tests via the
file-top #![allow]).
Standard invariants, one test each, named as behavior sentences. Fixtures are
inline json! + tempfile — no checked-in fixture files. Build the native
fixture from the real sample session's shapes (anonymized), covering every
record kind you cataloged in Phase 0, including one unmodeled record that must
survive.
store_round_trip_is_lossless_on_disk — load→save→load, record equality
including unknown records; assert the save path shape.discover_extracts_metadata — every populated Meta field.to_common_… — faithful extraction: typed tools with renamed keys,
bookkeeping skipped, result pairing, usage/stop backfill, message count
asserted exactly.codec_fixpoint_through_common_loses_nothing —
to_common(from_common(c)) == c. Shape the Common fixture at the harness's
native granularity (message grouping, which fields are mandatory, result
timestamps) — this is the direction that holds; from_common ∘ to_common
need not be byte-identical.from_common_is_deterministic — two runs serialize identically.Plus one test per quirk you handled (error results, pending calls, legacy
shapes, format sniffing), and extend the cross_harness.rs chain with the new
harness so the block signature survives the extra hop. Store tests that need
the native dep go #[cfg(feature = …)] inside the gated module against a real
temp DB — never mocks.
All must pass before you call it done:
cargo test and cargo test --no-default-features.cargo clippy --all-targets — pedantic-clean, no unwrap/expect in
src/.<sample-session-id> through the new Store,
to_common, and inspect the conversation end to end — no dropped turns, no
scaffolding leaking in as user text, tools typed where expected. Then run
the fixpoint on this real transcript, and convert it to claude_code and
back, checking the cross-harness block signature.txcript continue <id> --with <name> --no-resume (or --out
plus a copy into the live root), then resume it with the harness's own CLI
and confirm the conversation renders and the session continues. Also do the
reverse direction: sample → claude_code, resume with claude --resume.
Two rules learned the hard way:meta.id before
from_common) so they can't collide with — and overwrite — real
sessions; clean them out of the live roots afterward.
Order the resume work by cost: the read-only export/list oracle first
(validates the display log), then one headless -p-style resume turn
(validates the model log actually carries the context), then the TUI.Report the result with: record kinds handled vs passed-through, tool mappings, known losses, and the resume verification outcome for both directions.
© skillsynchq, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (references) in .claude/skills/harness of skillsynchq/txcript.
Open the folder on GitHubat commit 8cd3b0e
Harness next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Harness this skillskillsynchq/txcript | 153 | — | ~4.2k | Automated safety check: Pass | Apache-2.0 | |
| Webapp Buildersidequery/sidemantic | 129 | — | ~5.5k | Automated safety check: Pass | AGPL-3.0 | |
| Build And Profilingpikax/verter | 112 | — | ~4.3k | Automated safety check: Pass | MIT | |
| Service App CreatorPeiiii/nextclaw | 260 | — | ~1k | Automated safety check: Pass | MIT | |
| Nextclaw App CreatorPeiiii/nextclaw | 260 | — | ~1.6k | Automated safety check: Pass | MIT | |
| Creating Zed Extensionspr-pm/prpm | 122 | — | ~3.1k | Automated safety check: Notes | MIT |
sidequery/sidemantic
Build interactive analytics webapps, demos, dashboards, or embedded app surfaces from Sidemantic semantic models using copyable component primitives and deterministic query inspection.
pikax/verter
Build dependency chains, rebuild sequences, profiling with MCP, and Analysis MCP server setup for Verter
Peiiii/nextclaw
Create or update the Service component of a NextClaw Mini App, choosing between Portable Rust/WASI Components and native-process MCP services.
Peiiii/nextclaw
Create or update complete NextClaw Mini Apps by first choosing a Panel-only, Service-only, or Panel + Service composition, then choosing Portable WASI or native-process only when a Service exists.
pr-pm/prpm
A skill your agent uses when creating Zed extensions with custom slash commands, language support, themes, or MCP servers - provides Rust/WASM extension structure, slash command API…
yvgude/lean-ctx
Review how the lean-ctx ctx MCP tools performed in the current session and file upstream issues for confirmed problems.
skillsynchq/txcript
Cut a txcript release — dispatch the prepare-release workflow, approve the plan, watch the tag publish to crates.io, npm, and GitHub Releases, and verify.
skillsynchq/txcript
Validate a txcript parsing, discovery, or search change against every real agent session on this machine — old-vs-new parity, no panics, and release-build timings.
Works with
Integrate a new AI coding-agent harness into txcript — native Body types, Codec, TextCodec, Store, wiring, and tests. Harness is an agent skill from skillsynchq/txcript. Integrate a new AI coding-agent harness into txcript — native Body types, Codec, TextCodec, Store, wiring, and tests.
Harness fits situations like: integrate a new harness; transcript format.
Run `npx skills add skillsynchq/txcript --skill harness -a claude-code`. Or copy the skill folder (.claude/skills/harness in skillsynchq/txcript) into .claude/skills/harness in your project. Claude Code loads it when a task matches its description.
Run `npx skills add skillsynchq/txcript --skill harness -a codex`. Or copy the skill folder (.claude/skills/harness in skillsynchq/txcript) into .agents/skills/harness in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add skillsynchq/txcript --skill harness -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/harness, .gemini/skills/harness, .github/skills/harness and .opencode/skills/harness in your project.
Going by SKILL.md and its folder, Harness needs the command-line tools its instructions call (cargo, opencode and claude).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Harness is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.2k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3.9k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Harness: Webapp Builder (sidequery/sidemantic, 129 stars), Build And Profiling (pikax/verter, 112 stars), Service App Creator (Peiiii/nextclaw, 260 stars) and Nextclaw App Creator (Peiiii/nextclaw, 260 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
skillsynchq (a GitHub organization) maintains it in skillsynchq/txcript, which has 153 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on September 29, 2026.
Source: skillsynchq/txcript on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.