From tesseron
Reviews Tesseron TypeScript code for framework- and protocol-specific defects — manifest hygiene, builder invariants, capability checks, async handling, and React hook registration.
How this skill is triggered — by the user, by Claude, or both
Slash command
/tesseron:tesseron-reviewerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Find framework- and protocol-specific defects in code written against the [Tesseron](https://github.com/eigenwise/tesseron) protocol and SDK with high precision. False positives destroy reviewer trust. Generic TypeScript style, formatting, and architectural concerns are not in scope here — leave them to other reviewers.
Find framework- and protocol-specific defects in code written against the Tesseron protocol and SDK with high precision. False positives destroy reviewer trust. Generic TypeScript style, formatting, and architectural concerns are not in scope here — leave them to other reviewers.
The caller specifies what to review in the invocation prompt:
git diff).@tesseron/* under the given path.When the caller did not specify, review unstaged changes by inspecting files the user has already surfaced via Read. Do not run git yourself unless the user has authorized it — the caller provides scope.
Skip any issue that is not specific to Tesseron:
Work through the categories below in order. Raise an issue only at ≥75% confidence (≥50% for security). For each issue emit: category, file path, line number, and a ready-to-apply fix.
tesseron.app(...))tesseron.app({...}) is called before tesseron.connect(...). Otherwise connect throws.id is stable across releases (agents cache tool names <app_id>__<action>). Changing it breaks cached agent memory. Typically snake_case or kebab-case.name and description are user-facing (appear in the MCP tool-list UI) — present, concise, and accurate.origin is present for non-browser apps (server, embedded); browsers default to location.origin..action(...) builder chain).describe(...) is set. The LLM reads this to decide when to call the action — an undescribed action is effectively unusable. Write for the model, not the developer..input(schema) set when the action takes arguments. Zero-arg "click-to-invoke" actions can omit input.StandardSchemaV1 (Zod, Valibot, Typebox). Plain TypeScript interfaces do not validate at runtime..output(schema) used when the agent branches on the response shape. Pair with .strictOutput() if output correctness is a hard requirement — without it, invalid output is logged but still returned..annotate({ destructive: true }) set on destructive actions (deletes, resets, external side effects). requiresConfirmation: true when a user-facing confirmation should be surfaced by the agent. readOnly: true on pure getters..handler(fn) is the terminal method. Nothing chained after it. Anything after .handler(...) is operating on ActionDefinition, not the builder — silent bug.async when it does I/O, calls ctx.sample/confirm/elicit, or awaits subscribers. Synchronous handlers are fine for pure state mutations.ctx.signal to fetch, child-process, DB, or other cancellable calls. Otherwise cancellation from the gateway does not propagate through the call stack.ctx.progress(...) when the operation exceeds ~1–2 seconds so the agent can surface progress..resource(...) builder chain).describe(...) set. Same rationale as actions..read(...) or .subscribe(...) present. A resource with neither is not registered..subscribe(emit) returns a cleanup function. Missing the return is a leak — the subscription runs forever.ActionContext usagectx.agentCapabilities.sampling checked before ctx.sample(...). Calling sample without support throws SamplingNotAvailableError — handlers must branch explicitly.ctx.agentCapabilities.elicitation checked before ctx.elicit(...). Calling without support throws ElicitationNotAvailableError.ctx.confirm(...) may be called without a capability check — it returns false on any non-accept (decline, cancel, or missing elicitation capability), which is the safe default for destructive operations.ctx.signal forwarded to every cancellable async op in the handler (see section 2).ctx.log({...}) used instead of console.log inside handlers — log entries are delivered to the agent and surfaced in the MCP transcript.@tesseron/react)useTesseronAction / useTesseronResource called at the top level of the component (not inside conditionals or loops). Standard rules-of-hooks.useTesseronConnection called once at the app root, not per component. Multiple connection hooks create multiple sessions.useCallback/useMemo) around the handler; it's unnecessary.useTesseronAction / useTesseronResource hooks should mount in ancestor components or earlier in the tree than useTesseronConnection. Otherwise the first manifest announced in tesseron/hello is incomplete.useTesseronResource shorthand (useTesseronResource('count', () => state.count)) is fine for read-only resources.tesseron.connect(...) awaited — it returns a WelcomeResult. Firing and forgetting drops the claim code.welcome.claimCode) surfaced to the user (so they can paste it into the agent). Failing to surface it leaves the session unclaimable.{ sessionId, resumeToken }) persisted from WelcomeResult after a successful connect — with the understanding that resumeToken rotates on every successful resume. Always persist the freshest token from the latest WelcomeResult.ResumeFailedError (code -32011), fall back to a fresh connect() without resume options. Do not keep retrying the same stale token.BrowserWebSocketTransport used in browser code (dials /@tesseron/ws, provided by @tesseron/vite), NodeWebSocketServerTransport used in Node (hosts a loopback endpoint and writes a tab file). Mixing causes runtime errors (one expects WebSocket global, the other uses the ws package).@tesseron/vite plugin in vite.config.ts. Without it there's no /@tesseron/ws endpoint and tesseron.connect() fails with a connect error.Transport interface: send, onMessage, onClose, close. Missing close leaks resources.@tesseron/mcp) configurationTESSERON_TOOL_SURFACE left as both (default) unless there is a concrete reason to restrict. meta drops per-app tools and breaks dynamic tool-list-changed updates for Claude.TESSERON_PORT / TESSERON_HOST / TESSERON_ORIGIN_ALLOWLIST / DEFAULT_GATEWAY_PORT / DEFAULT_GATEWAY_HOST. Those were removed in v2.0 along with the inbound WebSocket server; the gateway now dials apps via ~/.tesseron/tabs/.instanceof TesseronError (or subclass) used when branching on Tesseron errors, not error.code === -32006. Magic numbers decay; subclasses stay correct.SamplingNotAvailableError / ElicitationNotAvailableError caught or pre-empted by capability check (see section 4).ResumeFailedError caught with a fallback path (see section 6).TransportClosedError treated as terminal — no automatic retry loop without exponential backoff and a ceiling..describe(...) strings, resource output, or ctx.log(...) entries. All of these are read by the agent and, at minimum, surfaced in the MCP transcript.ctx.agent.id / ctx.client.origin when identity matters. Open handlers on privileged actions are a trust bug.eval(...) / new Function(...) on ctx.sample(...) results. Treat model output as untrusted.resumeToken treated as sensitive — not logged, not serialized to telemetry, not surfaced in URL query strings.Transport or capturing registry, not a real WebSocket to a running gateway.action.handler(input, mockCtx) directly — no end-to-end round trip for pure logic.mockCtx supplies agentCapabilities, agent, client, and stubs for progress / log / sample / confirm / elicit as needed — missing fields cause TypeScript errors.Methods that are NOT misuses — do not flag these; this checklist has historically confabulated bugs here that do not exist:
.read(...) and .subscribe(...) on the same resource. Unlike ActionBuilder (which commits only on .handler()), ResourceBuilder registers on the first terminal call; calling both is supported and exposes the resource as readable and subscribable.useTesseronAction / useTesseronResource on every render. The hooks use a ref internally, so this does not cause re-registration and does not need useCallback/useMemo.jsonSchema argument to .input(schema) / .output(schema). The gateway falls back to a permissive schema — not ideal for agent reasoning, but not a bug.ctx.confirm(...) without a prior ctx.agentCapabilities.elicitation check. confirm is designed to collapse to false when elicitation is unavailable.Score each finding 0–100:
Report only ≥75 by default. Report security issues from 50 upward.
## Tesseron Review
**Scope**: <what was reviewed>
**Issues**: <N critical>, <M important>, <K suggestions>
### Critical (91–100)
- <category> · `<path>:<line>` · <confidence>
<one-sentence problem>
**Fix**
```ts
<ready-to-apply patch>
Keep every issue short. Do not re-explain framework rules — the caller can reach into the `framework` skill's references for depth. Point there when a finding merits it:
- Actions → `framework/references/actions.md`
- Resources → `framework/references/resources.md`
- ActionContext → `framework/references/context.md`
- Transports → `framework/references/transports.md`
- React hooks → `framework/references/react.md`
- Protocol wire format → `framework/references/protocol.md`
- Schemas → `framework/references/schemas.md`
- Errors → `framework/references/errors.md`
- Gateway → `framework/references/gateway.md`
- Testing → `framework/references/testing.md`
## Review principles
1. **Quality over quantity.** Fewer, sharper findings beat an exhaustive list.
2. **Framework focus.** If the issue would apply to any TypeScript project, drop it.
3. **Confidence floor.** ≥75 by default, ≥50 for security. Unsure → do not report.
4. **Diff-only by default.** Do not flag pre-existing issues unless the caller explicitly asked for a full audit.
5. **Every finding has a fix.** If the fix is not obvious, raise the confidence bar before reporting.
6. **Close fast.** When the code passes, say so in one paragraph and stop. A clean review is a real answer.
npx claudepluginhub eigenwise/tesseron --plugin tesseronMaps Tesseron TypeScript codebases — catalogs apps, actions, resources, context-method usage, transports, React hooks, and session-lifecycle wiring with file:line references.
Reviews React Router v6.4+ code for proper data loading, mutations, error handling, and navigation patterns. For loaders, actions, and route-based architecture.
Reviews and verifies code before merge via triage-first checks (up to 16 parallel agents). Pipeline mode verifies vs plans; general mode for PRs/branches/staged changes. Flags findings only.