tosijs-virta

Where the ecosystem's tasks live and die: one store — tags, boards-as-filters, append-only events — replacing GitHub issues, TODO.md, UPSTREAM.md, and deferred-findings lists, with GitHub demoted to an I/O adapter for external reporters. First third-party consumer of service-compris (formerly tosijs-services); component <tosi-virta>.

The plan is DESIGN.md, in the repo (design-private; not a published page). Platform-side prerequisites are filed as tosijs-platform#5–9.

For agents

virta query "project:tosijs-ui status:backlog", virta create …, virta comment #38 … — the agent API is a shell command per verb (--json for programs), or the same verbs over MCP (virta-mcp). One virta login per machine; every write is yours, unforgeably. The commands need bun on the PATH (macOS and Linux; Windows is untested).

The one idea

Jira and Linear make process schema. Trello makes process invisible. Virta makes process data: every task is a fold over an append-only log of attributed events, structure is tags, every view is one primitive — tag filter plus sort — and workflow is a convention visible in the event log, never a state machine the tool enforces.

What is built

The client side of the architecture, built against a local sync log so it is kept, not thrown away, when the service-compris transport lands:

Still stubbed until the platform lands: token minting and real attribution, subscription notifications, the GitHub adapter, the install manifest.

Quick start

bun add tosijs-virta tosijs tosijs-schema
import { MemoryLog, VirtaStore, tosiVirta } from 'tosijs-virta'

const store = new VirtaStore({ log: new MemoryLog(), identity: 'me' })
await store.load()
const task = await store.create({ title: 'try virta', tags: ['status:in-progress'] })
await store.comment(task.id, 'it works')

const board = tosiVirta({ lane: 'status', style: { height: '360px' } })
board.store = store
preview.append(board)
const board = preview.querySelector('tosi-virta')
await new Promise((r) => setTimeout(r, 100))
test('the quick start renders one card, in the in-progress lane', () => {
  expect(board.querySelectorAll('.card').length).toBe(1)
  const lane = board.querySelector('.card').closest('.lane')
  expect(lane.querySelector('h3 .name').textContent).toBe('in-progress')
})

tosijs-virta/core is the same library without the component — no DOM, no tosijs — for Bun, Node, workers, and the MCP server process (virta-mcp, which runs on bun).

Working on it

task command
dev server (HTTPS, live examples, edit-in-situ) bun start
build the site + library bun run make
unit tests bun test
types bun run typecheck
stop this project's dev server only bun run stop

First run: bun run tls (mkcert, needs sudo once). The dev server serves https://localhost:8791.