termDRAW is a Bun-based TypeScript workspace for terminal-native diagramming.
packages/opentuicontains the published@termdraw/opentuiembeddable OpenTUI library.packages/appcontains the published@termdraw/appstandalone CLI.packages/picontains the published@termdraw/piPi integration package that mounts termDRAW throughopentui-island.- The repo root provides shared workspace scripts for formatting, linting, testing, typechecking, build checks, packaging checks, and Pi smoke coverage.
package.json— workspace scripts and maintenance commandstsconfig.json— shared TypeScript defaults for the workspacepackages/opentui/src/draw-state.ts— retained object model, selection, transforms, undo/redo, exportpackages/opentui/src/app.ts— renderable chrome/editor surface and input handlingpackages/opentui/src/react.ts— OpenTUI React component bindingspackages/app/src/main.tsx— standalone CLI runtime entrypointpackages/app/src/cli.tsx— Bun executable wrapper for the standalone apppackages/pi/extensions/overlay.ts— Pi/termdrawcommand and editor insertion flowpackages/pi/islands/termdraw.island.tsx— Pi island bridge component.github/workflows/*— CI and publishing automation
DrawStateowns the drawing document, tool state, selection state, history, and exported output.TermDrawRenderablerenders either the full app chrome or the bare editor surface on top of the shared state model.react.tsexposesTermDrawApp,TermDrawEditor, andTermDrawas OpenTUI React components.cli.tsxwraps the full app for local CLI usage.- The Pi package adapts the same core UI through an island bridge and returns saved art back into the Pi editor.
- Default to using Bun instead of Node.js.
- Use
bun <file>instead ofnode <file>orts-node <file>. - Use
bun testinstead of Jest or Vitest commands. - Use
bun build <file.html|file.ts|file.css>instead of bundlers like webpack or esbuild. - Use
bun installinstead of npm, yarn, or pnpm. - Use
bun run <script>instead of npm/yarn/pnpm script runners. - Use
bunx <package> <command>instead ofnpx <package> <command>. - Bun already loads
.env; do not adddotenv. - Prefer Bun-native APIs when adding platform code:
Bun.serve()instead of Expressbun:sqliteinstead ofbetter-sqlite3Bun.redisinstead ofioredisBun.sqlinstead ofpgorpostgres.js- built-in
WebSocketinstead ofws Bun.fileinstead offs.readFile/writeFilewhen practical
- Keep the workspace split intact: reusable editor behavior belongs in
packages/opentui, the standalone CLI belongs inpackages/app, and Pi-specific integration logic belongs inpackages/pi. - Prefer targeted changes over broad rewrites.
- When changing editor behavior, add or update tests in
packages/opentui. - Run the Pi smoke flow when modifying Pi embed behavior, save messaging, or bridge wiring.
Run the smallest relevant set first, then the broader workspace checks before finishing larger changes.
bun run format:checkbun run lintbun testbun run typecheckbun run buildbun run checkbun run smoke:pifor Pi integration changes
- Maintain the top-level
CHANGELOG.mdas the source of truth for user-visible changes. - Keep upcoming work under
## [Unreleased]with these subsections:### Added### Changed### Fixed
- Append to existing subsections instead of creating duplicates.
- When cutting a release, move the relevant unreleased entries into a new immutable version section and then start a fresh
## [Unreleased]block. - Use the released changelog section as the starting point for GitHub release notes.
- Prefer
gh release create/edit --notes-filefor multi-line release notes. - Do not trust autogenerated GitHub release notes blindly; review and edit them.
- Prefer concise user-visible changelog entries over internal refactor details unless behavior changed.
- Keep all publishable packages on the exact same version at release time.
- When bumping versions, update every publishable package together and also update internal workspace dependency pins to the same version.
- For this repo, release
@termdraw/opentui,@termdraw/app, and@termdraw/pias a coordinated set unless there is an explicit reason not to. - Use repo-level coordinated releases: create one root Git tag and one GitHub release per shared version, in the form
vX.Y.Z. - Publish all three packages for every coordinated release, even if one package had no code changes in that cut.
- Do not use package-specific release tags like
app-vX.Y.Z,opentui-vX.Y.Z, orpi-vX.Y.Zfor official releases. - Before publishing, verify package versions are identical across all publishable packages.
- Use Conventional Commit titles when practical:
<type>[scope]: <description>. - Keep commits focused and easy to review.
- Mention the validation commands you ran in PR descriptions or handoff notes.