kyro-lens
v0.11.0
Published
Read-only web UI that makes a Kyro workspace legible to humans.
Maintainers
Readme
Kyro Lens
Read-only web UI that makes a Kyro workspace legible to humans.
Kyro is an AI-agent orchestration runtime. It produces structured JSON artifacts (sprints, tasks, debts, findings, verdicts) across multiple scopes. Kyro Lens renders that data in a browsable interface — and never writes to your workspace.
Published on npm as kyro-lens.
Developers / contributors: see README.developer.md and the as-built architecture ADR.
Quick start
Preferred: run with npx, then choose a Kyro repository in the browser. No install, always a current published build.
npx kyro-lensThat will:
- Start a local server in the background (default
http://127.0.0.1:56789/) - Open your browser when possible
- Restore your last browser-selected workspace when permission remains available
- Otherwise show the workspace folder picker
The current terminal directory is not selected implicitly. To bind and auto-open a specific repository, pass --workspace /path/to/project.
Bare kyro-lens / npx kyro-lens is equivalent to kyro-lens run.
Requirements
| Requirement | Notes |
|---|---|
| Node.js ≥ 20 | Used only to run the CLI |
| Kyro workspace | Manifest at .agents/kyro/kyro.json (schemaVersion 4) |
| Browser | Chromium-based browser for the default folder picker; any modern browser with explicit --workspace |
npx vs global install
| | npx kyro-lens (recommended default) | Global install |
|---|---|---|
| Best for | One-shot viewing, trying Lens, docs | Daily multi-repo use + verify / stop from other terminals |
| Setup | None | npm install -g kyro-lens or pnpm add -g kyro-lens |
| Version | Fresh package each run (or cache of latest) | Stays on the version you installed until you update |
| Command | npx kyro-lens | kyro-lens / kyro-lens run |
Use npx unless you already know you want a long-lived install and lifecycle commands. A stale global package is a common source of “my workspace won’t open” bugs that are already fixed on npm.
# Stay current without a global install
npx kyro-lens@latest
# Pin only when you need a reproducible version
npx [email protected]Global install (daily driver)
When you open many Kyro projects and want health-check / stop from another terminal:
npm install -g kyro-lens
# or: pnpm add -g kyro-lens
kyro-lens runUpdate periodically so you are not stuck on an old release:
npm update -g kyro-lens
# or: npm install -g kyro-lens@latest
kyro-lens --versionLifecycle (run / serve / verify / stop)
run starts Lens in the background and returns the terminal. serve keeps the process in the foreground when you want terminal-attached logs or a one-shot session.
| Command | Role |
|---|---|
| kyro-lens run [options] | Start the viewer in the background |
| kyro-lens serve [options] | Start the viewer in the foreground (Ctrl+C stops) |
| kyro-lens verify [options] | Report whether instance(s) are running |
| kyro-lens stop [options] | Stop targeted instance(s) cleanly |
| kyro-lens / bare flags | Same as run (backward compatible) |
# Start
npx kyro-lens
# or, after global install:
kyro-lens run --workspace /path/to/project --no-open
# Foreground mode
kyro-lens serve --workspace /path/to/project --no-open
# Another terminal (global install) — health check
kyro-lens verify
kyro-lens verify --json
# exit 0 = running, 1 = not running, 2 = tool error
# Stop
kyro-lens stop # single instance only; else --port / --all
kyro-lens stop --port 56789
kyro-lens stop --allInstance registry: on successful listen, Lens writes a small JSON record under $XDG_RUNTIME_DIR/kyro-lens/instances/ (or a per-user directory under the OS temp dir). Records and background logs are never written into the inspected Kyro workspace (.agents/kyro/** stays read-only). verify / stop use the registry plus a live GET /__kyro__/session check; stop never kills a PID that is not in a validated registry record.
Useful options
npx kyro-lens --workspace /path/to/your-kyro-project
npx kyro-lens serve --workspace /path/to/your-kyro-project --no-open
npx kyro-lens --port 5173
npx kyro-lens --host 127.0.0.1 --no-open
npx kyro-lens --help
npx kyro-lens --version| Flag | Description |
|---|---|
| -w, --workspace <path> | Explicit workspace to bind and auto-open; also filters verify / stop |
| -p, --port <number> | Port (default: 56789, or $PORT); also filters verify / stop |
| -H, --host <host> | Bind address for run / serve (default: 127.0.0.1) |
| --no-open | Do not open a browser tab (run / serve) |
| --json | Machine-readable output (verify) |
| --all | Stop every registered instance (stop) |
| -h, --help | Show help |
| -v, --version | Show package version |
Tips
- Run from any directory and choose a workspace in the browser, or pass an explicit
--workspacepath. - If port
56789is busy (EADDRINUSE), pass--port 56790(or free the other process). - If the browser opens blank, open the
Local:URL printed in the terminal (or hard-refresh). With--no-open, open that URL yourself once the server has started. - Prefer
npx kyro-lens(ornpx kyro-lens@latest) so you are not debugging an outdated global install. - Global users: run
kyro-lens --versionand compare with npm; update when you are behind. - Appearance: use the theme control for light or dark (default dark). Your choice is remembered in this browser only — Kyro Lens never writes it into your workspace.
- Recent workspaces (browser File System Access): folders you open are listed on the home screen and the last one restores on reload when permission is still granted. Handles live in IndexedDB; the index is browser-local only.
What you can inspect
- Overview — Scope status, selected-sprint metrics, handoff, phases, definition of done
- Sprint Board — Kanban for the selected active or archived sprint (read-only), search, task detail
- Task Detail — Description, context, dependencies, scenario refs, acceptance criteria, evidence, maker/checker verdict
- Spec & Traceability — Current specification plus selected-sprint task links, non-goals, open questions
- Roadmap & History — Sprint timeline, sizing rationale, closed-sprint outcomes
- Debt Tracker — Filterable debts with priority, status, origin, and target sprint
- Knowledge — Principles, clarifications, and learned conventions
- Sprint history selector — Active sprint and ledger-listed archives as first-class, inspectable contexts
How workspace loading works
Default browser-picker mode
When you run npx kyro-lens, the CLI serves the UI without binding the process working directory. Lens restores the last browser-selected workspace when permission is available; otherwise it shows the folder picker.
Passing --workspace /path/to/project enables the local read-only workspace API and auto-opens that explicit repository without a picker. In both modes, Lens never writes to the inspected workspace.
What gets loaded
- Project manifest:
.agents/kyro/kyro.json - Each declared scope’s
sprint.jsonunder the configured artifact root - Archived sprint snapshots on demand when you select them in history (ledger metadata only for the option list)
Invalid or unreadable scopes fail loudly for that scope; other valid scopes still load. Lens never invents progress metrics for missing or broken history.
Selected sprint vs current scope
| | Source | Drives |
|---|---|---|
| Current scope | Live sprint.json | Status, handoff, debt, roadmap, knowledge, specification text |
| Selected sprint | Active sprint or a demand-loaded archive | Board tasks, progress, verdicts, phases, Spec task links |
Switching history does not rewrite current-scope debt, roadmap, handoff, or specification ownership.
Read-only guarantee
Kyro Lens only reads files. It does not write, repair, migrate, or mutate Kyro state.
AI assistant (experimental)
Lens ships a read-only AI assistant on top of the private package kyro-lens-ts-sdk (git dependency pinned to a release tag; not published to npm). Open the Assistant nav item after loading a workspace.
Install requirements: SSH access to SynapSync/kyro-lens-ts-sdk (or a machine with that deploy key). CI uses the SSH_PRIVATE_KEY secret (read-only deploy key on the SDK repo). For local co-development of the SDK without retagging, use an uncommitted pnpm.overrides / pnpm link — never commit link:../.
| Piece | Path | Role |
|---|---|---|
| Scope corpus adapter | src/data/ai-scope-corpus.ts | Maps workspace readFile (+ optional listDirectory) → SDK corpus; containment-safe archives via sprint-history rules |
| AI client composition | src/data/ai-client.ts | createLensAiClient / createDefaultLensAiClient around createKyroLensAiClient |
| Encrypted secret vault | src/data/ai-secret-vault.ts | Device wrapping key + AES-GCM ciphertext in IndexedDB |
| Chat session store | src/data/ai-chat-session-store.ts | Multi-turn history in IndexedDB, filtered by workspace + scope |
| Assistant UI | src/components/kyro/views/assistant*.tsx | Connect, chat (markdown replies), diagnostics |
| Live model catalog | src/data/assistant-model-catalog-*.ts | Provider model lists via SDK listModels; 24h localStorage cache |
Model picker: On Assistant load, Lens refreshes each provider’s model list when the cache is missing or older than 24 hours (OpenRouter needs no key; OpenAI/Gemini only when a vault key exists). One list per provider is stored in localStorage (kyro-lens:assistant:model-catalog.v1); each row is source: "remote" | "custom". Remote refresh replaces only remote rows and keeps custom / operator-entered ids. There is no hardcoded product shortlist of model ids. Context-window budget chrome uses a window only when the provider reported one on a list entry — never invented.
Secrets (product decision): Durable encrypted vault is the browser default for Assistant credentials (createDefaultLensAiClient). OpenRouter keys are AES-GCM encrypted and stored as ciphertext in IndexedDB so they survive page reloads. A non-extractable device wrapping key lives in a separate IndexedDB database. If Web Crypto or IndexedDB is unavailable, Lens falls back to session-only in-memory storage. Credentials are never stored in document.cookie, plain localStorage, or under .agents/kyro/**. Disconnect deletes the vault entry. Residual risk: same-origin XSS can still use an unlocked vault. A user-managed passphrase is not required for v1; it remains optional future hardening, not a secret-storage gap.
Chat history: turns persist in IndexedDB per (workspaceKey, scopeId). Switching scopes isolates transcripts; reloading restores the latest session for the current scope. History is not written under .agents/kyro/**.
Corpus: load-only. Lens does not write findings, sprints, traces, or any other Kyro artifact when packing context for the model. When the workspace reader supports directory listing (File System Access API or CLI /__kyro__/list), safe files under findings/ are included; without listing, findings stay empty honestly rather than inventing paths.
Honesty chrome: incomplete corpus or budget gaps show as high-level failure / omitted / truncated counts and paths (never invented file bodies). Auth, provider, and pack errors stay distinct. Incomplete context surfaces when the scope binds, not only after a send.
Accessibility: primary Assistant controls (open settings, connect/save/disconnect, composer, send, close settings) have accessible names; error diagnostics use role="alert"; incomplete context uses a live status region. Disabled send states include a reason in the accessible name.
Architecture invariant: React views never call OpenRouter (or any LLM HTTP) directly — only the SDK facade via createLensAiClient / createDefaultLensAiClient.
Package details
| | |
|---|---|
| Name | kyro-lens |
| CLI | kyro-lens (via npx kyro-lens) |
| License | Apache-2.0 |
| Runtime deps | None on npm — the UI is pre-bundled |
| Changelog | CHANGELOG.md |
npm view kyro-lens version
npx kyro-lens --versionTroubleshooting
| Symptom | What to try |
|---|---|
| command not found with npx kyro-lens | Use a fresh shell and try again with npx kyro-lens@latest. |
| Browser tab is blank | Use the Local: URL from the terminal; hard-refresh (Cmd/Ctrl+Shift+R); or start with --no-open and open the URL manually after the server prints it. |
| Workspace could not be loaded | Confirm .agents/kyro/kyro.json exists and is schema v4; check the path with --workspace. |
| Port already in use | npx kyro-lens --port 56790 |
License
Apache-2.0 — see LICENSE.
