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

@aotui/mobile-ai-native

v0.1.0-alpha.3

Published

Alpha host-agnostic core for building Agent Native mobile apps with shared GUI/TUI state and snapshot-scoped tool execution.

Readme

@aotui/mobile-ai-native

This package is the hardened runtime core for building agent-native mobile apps.

It is the core, not the full React Native host layer. React Native / Expo mounting now lives in @aotui/mobile-ai-native-react-native.

It provides the state store, action runtime, trace lifecycle, snapshot registry, and tool bridge needed for a real mobile host.

The current snapshot model is view-based:

State -> static Root view + state-derived mounted views -> SnapshotBundle -> Tool Call(ref_id + snapshotId) -> Action -> Event/Effect -> State -> GUI/TUI refresh

What This Slice Proves

  • one shared state system drives both GUI and TUI
  • the root view is static navigation knowledge, not runtime state
  • business views are mounted from current state and represent runtime reality
  • tools are exposed as a stable manifest, with runtime availability tracked separately
  • the framework builds one atomic SnapshotBundle
  • snapshot markup is composed from ordered <View> fragments
  • tools execute against the exact snapshotId the LLM saw
  • refIndex stores serializable snapshot payloads, not live object references
  • mutated tool results stale the originating snapshot, even when the result is recoverable
  • trace entries record the action lifecycle: started, updated, succeeded, and failed

SnapshotBundle

The LLM-facing read model is:

type SnapshotBundle = {
  snapshotId: string;
  generatedAt: number;
  markup: string;
  views: readonly ViewFragment[];
  tui: string;
  refIndex: Record<string, RefIndexEntry>;
  tools: readonly ToolDefinition[];
  toolAvailability: Record<string, ToolAvailability>;
};

Current behavior to keep in mind:

  • markup is the composed xml+markdown snapshot built from ordered <View> fragments
  • views preserves the ordered fragment list, with the Root fragment first
  • tui is retained as a compatibility readout and may differ from markup, but it should be produced from the same snapshot generation pass
  • refIndex, tools, and toolAvailability are produced and frozen alongside snapshot creation

The bundle is intended to be atomic:

  • markup
  • views
  • tui
  • refIndex
  • tools
  • toolAvailability

Today the runtime hard-validates markup against views, then freezes the associated tui, refIndex, tools, and toolAvailability outputs generated on that same snapshot path.

RootView And Mounted Views

RootView is the conceptual navigation role, and the current runtime emits it as a fragment with type: "Root".

It explains:

  • what view types exist
  • how to enter them
  • what each view type is for

It does not try to narrate runtime state.

Mounted business views are the runtime reality.

They are derived from current state and describe:

  • which concrete views are mounted right now
  • what state each mounted view is showing
  • what refs and actions are relevant in that state

That means the LLM should read the static root first, then read the mounted business views for the live app state.

Tool Model

Tools are defined against a semantic viewType, exposure mode, and runtime availability.

That gives the runtime this rule:

tools = stable tools + currently exposed dynamic tools

Then toolAvailability[name] tells the model whether a listed tool can execute right now. A tool can remain in the manifest and still fail with PRECONDITION_NOT_MET when current state does not satisfy its runtime guard.

Core Contract

The LLM does not operate on guessed ids. It sees semantic markers like:

(Welcome back)[message:messages[0]]

Then it calls a tool with:

await bridge.executeTool("openMessage", { message: "messages[0]" }, snapshotId);

For tools that declare meta.supportsRefs === true, the bridge resolves top-level string inputs as either exact ref_id values or canonical marker strings from that snapshot's refIndex. It does not infer nested field refs or field-level ref metadata.

The low-level React-family host path inside the core is still present because the adapter composes it, but product code should prefer the dedicated RN adapter package.

The adapter-facing runtime path is:

  • createReactAppRuntime() owns the store, action runtime, snapshot registry, trace store, and tool bridge
  • AppRuntimeProvider publishes that runtime through context
  • useRuntimeState(selector) subscribes to store updates with useSyncExternalStore
  • useRuntimeTrace(selector) subscribes to the trace store the same way
  • createReactNativeAppRuntime() in the adapter package wraps that core runtime and exposes runtime.ai.getSnapshot() / runtime.ai.executeTool(...) for host-safe tool execution

That means GUI consumers react to state and trace changes without pulling the whole runtime object into component state.

Ref APIs

useDataRef

Use for a single object:

const pinnedRef = useDataRef("message", message, "messages[0]");
<text>{pinnedRef("Pinned message")}</text>;

useArrayRef

Use for an array:

const [listRef, itemRef] = useArrayRef("message", messages, "messages");
<text>{listRef("Inbox messages")}</text>;
<item>{itemRef(0, "Welcome back")}</item>;

Current Status

This package is the core, not the full app shell.

What it gives you today:

  • shared state core
  • semantic refs with useDataRef and useArrayRef
  • atomic SnapshotBundle
  • static root navigation plus state-derived mounted business views
  • snapshot-scoped tool execution
  • a pure core that can now be mounted by the dedicated RN / Expo adapter
  • structured trace and effect contracts

What you still need for a production iOS app:

  • real GUI components
  • model orchestration and networking
  • product-level trace UI and persistence

Current Demo

The inbox demo exposes:

  • openMessage
  • searchMessages

and proves that GUI and TUI both refresh from the same state after tool execution.

Runtime Boundaries

Keep the framework and app responsibilities separated:

  • framework owns the store, action runtime, snapshot registry, trace runtime, tool bridge, and host adapter
  • business apps own state shape, domain actions, handwritten TUI, and app-specific effect behavior
  • actions can read state, emit events, run effects, and update trace summaries
  • effects can read state, emit events, and report structured success or failure, but they do not write state directly
  • snapshot coherence is enforced for the textual view representation, so markup, views, and tui must agree for the same render tick; refIndex, tools, and toolAvailability are built and frozen alongside that snapshot path but are not yet cross-validated field-by-field