Skip to content

maggit/interlace

Repository files navigation

Interlace

A cross-project status layer. Interlace deterministically indexes what's pending and what got done across all of your repositories, then answers the one question every multi-project developer keeps asking: "where am I across everything?"

The first surface is a CLI called lace. It scans your tracked repos and ranks what needs attention, so you don't have to mentally re-load the state of a dozen projects every morning.

$ lace status

interlace        ▸ 2 blocking · 5 done this week
imigro-app       ▸ 6 blocking · 51 done this week
neuromint        ▸ 0 blocking · 12 done this week
...

Why

Context lives in too many places: open issues on GitHub, TODO/FIXME markers buried in code, unchecked - [ ] boxes in Markdown plans, branches you pushed and forgot. Interlace collects all of it into one Postgres-backed index and gives you a single ranked view.

Core principle: the collector is a dumb, fast, deterministic indexer. No LLM ever sits in the collection or ranking loop — results are reproducible and auditable. (LLM-powered summaries are an opt-in, on-demand layer planned for later.)

What it collects

Source What it picks up
git repo state, recent commits, pushed branches
code comments TODO / FIXME / HACK markers (via ripgrep), with p0/p1/p2 priority
Markdown - [ ] / - [x] checkboxes in *.md, with priority:: or [P0]/[P1] conventions
GitHub open/closed issues, opened/merged PRs, and deferred @lace / 📌 PR review comments (token-gated)

Items are content-addressed, so editing a line or shifting code around doesn't churn your index — closing a checkbox or deleting a TODO transitions that item to done in place.

Requirements

  • Node.js ≥ 22 and pnpm 10
  • ripgrep (rg) on your PATH — the code-comment collector shells out to it. Install via brew install ripgrep (macOS) or your package manager. Without it, only the code-comment collector is skipped; everything else still runs.
  • A Postgres database reachable via DATABASE_URL (local Postgres, Docker, or Supabase all work).

Install

git clone https://github.com/maggit/interlace.git
cd interlace
pnpm install
pnpm build

The CLI binary is built to packages/cli/dist/index.js and exposed as lace. You can run it via pnpm --filter @interlace/cli exec lace …, or link it onto your PATH:

pnpm --filter @interlace/cli link --global   # makes `lace` available globally

Quickstart

  1. Point at a database. Copy .env.example to .env and set your connection string, or export it directly:

    export DATABASE_URL=postgresql://user:pass@host:5432/postgres

    Need a throwaway Postgres? docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=lace postgres:16-alpine

  2. Apply the schema. A one-time step (re-run after upgrades that ship new migrations — it's idempotent):

    lace db migrate
  3. Register a project.

    lace project add imigro --path /abs/path/to/imigro --github sahara/imigro
  4. Scan — collect the current state of every tracked project (or just one):

    lace scan            # all projects
    lace scan imigro     # one project
  5. Check status.

    lace status                  # super-view: every active project, ranked
    lace project-status imigro   # one project in detail (alias: lace s imigro)
  6. Close an item straight from the CLI — flips its checkbox [ ]→[x] in the source file and re-scans:

    lace close imigro docs/plan.md:42
  7. Run continuously (optional) — watch files and poll on an interval:

    lace daemon

Command reference

Command Description
lace config Show resolved mode, DB target (redacted), and enabled collectors
lace db migrate Apply pending migrations to the configured database
lace project add <slug> --path <abs> [--github <owner/repo>] Register a project
lace project list List registered projects
lace scan [slug] Force a collect now — all projects, or one
lace close <slug> <path:line> Mark a checkbox item done and re-scan
lace status Super-view: all active projects, ranked
lace project-status <slug> (alias s, or lace <slug> status) Single project: repo line, done-this-week, pending
lace daemon Watch projects + poll on an interval, scanning continuously

Run lace config first if a command can't find your database — it prints exactly what Interlace resolved.

Configuration

Configuration is layered (later overrides earlier): built-in defaults → ~/.config/interlace/config.toml.interlace.toml in the repo → environment variables → command flags. The common knobs:

Variable Purpose
DATABASE_URL Postgres connection string (required for local mode)
GITHUB_TOKEN Enables the GitHub collector; absent → GitHub collection is silently disabled
defer_token Marker that turns a PR review comment into a tracked item (default @lace)

See .env.example for the full set.

Two non-sensitive groups can also be overridden from a TOML config file (~/.config/interlace/config.toml or a project-local .interlace.toml):

[daemon]
pollIntervalMs = 60000   # full poll cadence (default 300000)
debounceMs = 1000        # quiet period after a file change before re-scan (default 2000)

[ranking]
p2PressureCap = 30       # saturation cap on low-priority (P2) backlog pressure,
                         # so a big pile of low-priority items can't bury real P0 work

lace config prints the resolved daemon intervals so you can confirm an override took effect.

Architecture

Interlace is a pnpm + Turborepo monorepo:

packages/
├─ core/         Drizzle schema + migrations, config resolution, ranking,
│                idempotent ingest engine, super-view / project-status queries
├─ collectors/   Pure, deterministic collectors: git, code-comment, markdown, github
├─ cli/          The `lace` command (Commander) — runs collectors inline
├─ workers/      Background-job skeleton (reserved for backend mode)
├─ pollers/      Scheduled-poll skeleton (reserved for backend mode)
└─ api/          HTTP API skeleton (reserved for backend mode)
  • core owns the database (Postgres via Drizzle ORM + postgres.js) and the ingest engine, which is transaction-wrapped and idempotent: re-scanning never duplicates work, and items auto-complete when their source disappears.
  • collectors are pure functions over a repo's current state — given a path (and optionally a GitHub token) they return items and activity. They never touch the database directly.
  • Tests run against pglite (in-process Postgres) — no Docker needed in CI — plus real git, rg, and chokidar, and an in-memory fake GitHub client.

Development

pnpm install
pnpm build         # turbo build, respects the dependency graph
pnpm test          # vitest across all packages
pnpm typecheck     # tsc --noEmit across all packages
pnpm lint:deps     # dependency-cruiser: enforce package boundaries

@interlace/core must be built before packages that import it; turbo and the lint:deps script handle that ordering for you.

See CONTRIBUTING.md for the contribution workflow, coding conventions, and how to add a new collector; CHANGELOG.md for the release history; and SECURITY.md for how to report a vulnerability.

Status & roadmap

v1 (local mode) is complete: all collectors, idempotent ingest with auto-completion, ranking, and the lace CLI including a continuous daemon.

Designed-for but not yet built: backend mode (the api/workers/pollers packages deployed with a Redis/BullMQ queue), a menu-bar app, an MCP server, and lace brief (on-demand LLM summaries). Contributions toward any of these are welcome.

License

MIT © Raquel Hernandez

About

A cross-project status layer — deterministically index what's pending and what got done across all your repos. CLI: lace.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors