npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ottimis/jack-chat-core

v0.5.5

Published

Transport-agnostic message reducer and types for Jack chat (desktop + mobile).

Readme

@ottimis/jack-chat-core

Transport-agnostic reducer and type definitions for the Jack chat UI. Shared between the Electron desktop app (jack/) and the React Native / Expo mobile app (jack-mobile/).

What this package contains

  • TypesChatMessage, ChatState, TaskItem, the provider-neutral message contract (NormalizedMessage, NormalizedBlock, NormalizedToolRef, ToolShape, …), plus the preload-level contracts (FileChangeData, PermissionRequestData, ContextUsageInfo, SlashCommandDef).
  • Pure helpersisJackTaskTool, isTaskTool (deprecated), pickStr. Slash-command parsing is no longer in this package — see ReduceContext.parseSlashEnvelope / ReduceContext.isCliMarkerOnly callbacks for the provider injection point.
  • ReducercreateInitialState() + reduce(state, event, ctx?) that consumes provider-neutral NormalizedMessages plus out-of-band events (permission, file change, error) and produces the list of message bubbles the UI renders. ctx carries the host clock and optional provider-specific text parsers.
  • History loaderloadHistory(rawMessages, sessionId, ctx?) that replays a transcript expressed as NormalizedMessage[] into a starting ChatMessage[]. Slash envelope detection and CLI-marker filtering happen only when the matching ctx callbacks are injected.

AgentEvent actions

| kind | Origin | Purpose | |-----------------------|---------|-------------------------------------------------------------------------| | sdk | backend | Provider-neutral NormalizedMessage (assistant, user, partial_event, turn_result, session_state, …) | | permission-request | backend | Inline pending-permission card (only when inlineFileDiff present) | | file-change | backend | Replace a tool card with a file-diff card after PostToolUse hook | | agent-error | backend | Append an error result card, clear running flag | | slash-feedback | host | Append a slash feedback chip (host-side slash executor output) | | context-usage | host | Append a context-usage chip | | user-prompt | client | User typed and submitted a prompt | | turn-started | server | A new user turn just started; passive observers render the bubble + flip running | | reset | client | Reset to an empty state, optionally switching session | | load-history | client | Replace state entirely with a replayed transcript for a session | | slash-invocation | client | User invoked a slash command (built-in or unknown), append chip | | permission-resolved | client | User decided an inline permission: deny removes card, allow marks streaming | | interrupt | client | User stopped the turn — reset runtime flags, keep messages |

0.5.0

Breaking: parseSlashEnvelope, isCliMarkerOnly, expandCommandBody, and SLASH_ENVELOPE_START are no longer exported. The reducer's slash-command envelope detection is now optional and provider-driven via two new ReduceContext callbacks:

  • parseSlashEnvelope?: (text: string) => ParsedSlashEnvelope | null
  • isCliMarkerOnly?: (text: string) => boolean

Hosts targeting Claude must inject those callbacks at runtime; hosts targeting providers without a slash convention (Codex, Gemini, …) omit them and the reducer renders user messages without slash chip detection or marker filtering.

Renamed (with deprecated alias): ClaudeCommandDefSlashCommandDef. The old name remains as a @deprecated alias and will be removed in 0.6.0.

Reasoning: chat-core is provider-neutral; Claude-specific text parsing belongs in the provider package, not in the rendering layer. This change unblocks the multi-provider integration on the host side.

Migration:

  • Hosts that consume Claude: re-implement parseSlashEnvelope / isCliMarkerOnly in your provider layer (the previous logic is ~30 lines, see Jack's providers/claude/slashCommands.ts) and pass them via ReduceContext.
  • Type imports: replace ClaudeCommandDef with SlashCommandDef.
  • expandCommandBody: re-implement in the host slash-command executor; the body-expansion logic is host-specific anyway.

0.4.1

Additive: ChatMessage gains optional toolShape, toolRefKind, toolMcpServerSlug fields. The reducer populates them from NormalizedBlock.tool_use.toolRef when the final assistant message arrives (and during history replay). Renderers can switch from toolName-keyed card selection to shape-keyed dispatch; back-compat preserved since the fields are optional.

  • Native tools carry their canonical shape from the provider's tool catalog ('fs.read' | 'fs.write' | …).
  • MCP-routed tools always map to toolShape: 'mcp' and carry toolMcpServerSlug so the renderer can show the MCP badge + server slug without re-parsing toolName.
  • Streaming-only states (between content_block_start and the final assistant message) leave the fields undefined — only the wire name is on the wire there. Renderers should fall back to toolName matching for that window.
  • 'unknown' shapes (native tools without a catalog entry) are preserved verbatim, not coerced to undefined, so the renderer can pick a generic JSON view rather than fall back to provider-name pattern matching.

No breaking changes — existing 0.4.0 consumers keep compiling.

Breaking changes in 0.4.0

  • AgentEvent.kind = 'sdk' now carries a provider-neutral NormalizedMessage instead of an Anthropic-shaped SdkMessage. Hosts must translate provider-native streams to NormalizedMessage before dispatching; Jack ≥ 1.3 ships a Claude translator at src/main/providers/claude/normalize.ts.
  • loadHistory and the load-history action now consume NormalizedMessage[] (was SdkMessage[]).
  • The Anthropic-shaped block types (AnthropicContentBlock, AnthropicTextBlock, AnthropicThinkingBlock, AnthropicToolUseBlock, AnthropicToolResultBlock, AnthropicStreamEvent, StreamEventDelta, SdkMessage, HistorySdkMessage) are no longer exported.
  • Streaming token-level events still expect a Claude stream_event shape inside NormalizedMessage.partial_event.raw. A normalized partial-block event will land in a follow-up release once a second provider drives the design.
  • Use the new isJackTaskTool(ref: NormalizedToolRef) helper to detect Jack's task-family MCP tools. The legacy isTaskTool(name) helper remains exported but is deprecated.
  • The Claude system/status:compacting signal is not currently mapped to a normalized kind; the 'Compacting' status label is unreachable until a follow-up contract update introduces a dedicated state.

What this package does NOT contain

  • React components (desktop uses DOM, mobile uses RN primitives — components are host-specific).
  • Transport (desktop uses Electron IPC, mobile will use SSE).
  • Slash-command execution (host-specific side effects).
  • Provider-native translators. The host (Jack main process) owns those — chat-core only consumes the normalized payload.

Consumers

  • jack/ (desktop, Electron): link via "@ottimis/jack-chat-core": "file:../jack-chat-core".
  • jack-mobile/ (Expo RN): same link; requires metro.config.js watchFolders addition.