Issho

Issho β€” Collaboration for Phoenix

Hex Version HexDocs CI Status

Issho (δΈ€η·’, "together") is an open-source collaboration toolkit for Phoenix that makes it easier to build applications where people and AI agents work together in real time.

It provides the shared foundations (rooms, participants, presence, authorization, documents, synchronization and agent participation), so that developers can focus on their applications instead of rebuilding collaboration features. Bring your own components, your own agents and your own application logic.

Issho owns collaboration semantics. Applications and component libraries own their behavior and presentation.

Status: early release. Rooms, documents, LiveView sessions, grants, the browser client, the people list and theme, the page's pointers and following, agents however they connect (MCP, your app's own model) and how they move, undo across a page, blocks of other rooms in a page (live embeds), the room's events, shared state without an engine, comments and threads on any component, agents seen at work and stopped, an agent's inbox, streams of a room, and the bindings of Kotoba, Hakushi and Masu are here. Before 1.0, a minor version may change the API; see the roadmap for what comes next.

Live collaboration in the Hattori libraries is Issho's: Kotoba's shared editing (from 0.6), Masu's grids' people (from 0.4) and Hakushi's canvases. Each library works on its own without it; with it, a page of them has one connection, one list of people, one policy, and agents that work across all of them.

Installation

def deps do
  [
    {:issho, "~> 0.6"}
  ]
end

Issho needs Elixir 1.18 or later, Phoenix 1.7.14 or later and, for Issho.Live, Phoenix LiveView 1.1 or later.

It gives your app:

A sketch

# In your supervision tree, after the PubSub:
{Issho,
 name: MyApp.Issho,
 pubsub: MyApp.PubSub,
 endpoint: MyAppWeb.Endpoint,
 policy: MyApp.Collaboration,
 store: {MyApp.CollabStore, MyApp.Repo}}
defmodule MyApp.Collaboration do
  @behaviour Issho.Policy

  @impl true
  def authorize(who, "board:" <> id, action),
    do: if(MyApp.Boards.allowed?(who.claims["user_id"], id, action), do: :ok, else: {:error, :forbidden})

  @impl true
  def document(_who, "board:" <> id),
    do: {:ok, %{engine: Issho.Engine.Map, initial: MyApp.Boards.content(id)}}
end
# A channel on a socket of your endpoint:
defmodule MyAppWeb.IsshoChannel do
  use Issho.Channel, instance: MyApp.Issho
end

# A LiveView signs the browser's join token:
token = Issho.Token.sign(MyApp.Issho, current_user, "board:42",
  can: :write, claims: %{"user_id" => current_user.id})
<%!-- With `import Issho.Components` in your app's html_helpers: the room's
     people, everyone's pointer over the page, the agents at work, and
     the room's comments (in a LiveView that joined the room). --%>
<.people id="people" grant={@grant} />
<.pointers id="pointers" grant={@grant} />
<.agents id="agents" grant={@grant} />
<.comments id="comments" room="board:42" />
# An agent joins the same room:
{:ok, claude} = Issho.join_as(MyApp.Issho, agent, "board:42", on_behalf_of: current_user)
{:ok, _doc} = Issho.Participant.open(claude, "board:42")
{:ok, _receipt} = Issho.Participant.transact(claude, "board:42", ops)

In the browser

import { joinRoom } from "issho"

const room = await joinRoom("board:42", { token, self: "user:ada" })
const doc = await room.open("board:42")

doc.on((event) => event.type === "change" && render(event.state))
doc.change([{ op: "set", path: ["title"], value: "Q3 plan" }])

room.aware({ place: { doc: "board:42", at: { path: ["title"] } } })
room.awareness.on((peers) => drawCursors(peers))
room.presence.on(() => drawPeople(room.presence.others))

Roadmap

The next step is to let developers define an application capability once: people use it through the UI, agents use it through tools or visible interaction, and everyone works on the same authorized live state.

The roadmap tracking issue keeps the existing priorities, proposals, dependencies, and acceptance criteria. The direction is:

These are planned capabilities, not a release schedule. Getting started, developer tools, scoped agent access, and the existing comments, history, and following improvements remain part of the linked plan.

Issho runs in your Phoenix application. Your data, permissions, behavior, and presentation remain yours; Issho owns the collaboration semantics.

Development

mix deps.get
npm ci --prefix assets
mix test        # includes the end-to-end test of the client on a real endpoint
mix test.js     # the browser client's unit tests
mix precommit   # compile with warnings as errors, format, credo, test
MIX_ENV=dev mix issho.build   # the bundles, into priv/static
MIX_ENV=test mix run --no-halt e2e/server.exs   # a room's pages, on :4097 (/one, ?sumi=smoke for a Sumi theme)

License

MIT. See LICENSE.