Skip to content

Repository files navigation

@aryrabelo/planqueue-core

npmlicenseCIbun

Pure logic for PlanQueue — AI agent session notes with a markdown prompt queue. Designed for Bun, bundler-compatible with Node.js. Path scheme, persistence, markdown prompt-queue parsing, widget rendering, and a stats line. Used by the PlanQueue plugin for Oh My Pi (@aryrabelo/planqueue); runtime-agnostic so another harness build can reuse the same behavior without duplicating it.

Requirements

Bun ≥ 1.0.0 — the package ships TypeScript source (src/*.ts). Bun transpiles it natively at import time with no extra config. Node.js consumers need a bundler (esbuild, Vite, tsup) configured to handle .ts source imports.

Install

bun add @aryrabelo/planqueue-core

Modules

ModuleWhat it provides
pathsDerive safe filesystem paths for notes, history, config, and the current.md session pointer
storeAsync read / write / append-history / cross-session list, plus a coalescing debounced writer
queueParse and mutate a markdown checkbox prompt queue: find head, mark inflight, complete, append
widgetRender the notes widget as a styled string array (OMP HUD-style, with continuation lines)
statsContext bar + model + +adds/-dels + elapsed as a plain or injected-style string
configParse and validate config.json shortcut overrides; humanize key strings for display
editorDecide whether an editor close should save, discard, or ask — no silent data loss

All modules are re-exported from the package root:

import{findHead,markInflight,notePathFor,renderStatsLine}from"@aryrabelo/planqueue-core";

Usage

Prompt queue — the core use case

import{appendTask,findHead,markInflight,completeInflight,appendQueue,typeQueueStep,}from"@aryrabelo/planqueue-core";// Start with a plain note — loose bullets are normalized automaticallyletnote="- Refactor auth module\n- Write tests";// Append a structured planconststeps: QueueStep[]=[{prompt: "Set up CI",details: ["Add .github/workflows/ci.yml"]},{prompt: "Review PR",barrierAfter: true},// pauses queue until human clears barrier{prompt: "Ship to npm"},];note=appendQueue(note,steps);// Find and dispatch the first pending itemconsthead=findHead(note);// { kind: "prompt", line: 0, text: "Refactor auth module" }note=markInflight(note,head.line);// "- [>] Refactor auth module\n..."// After the agent completes it:note=completeInflight(note);// "- [x] Refactor auth module\n..."

Persist a note with debounced saves

import{resolveLocation,notePathFor,loadNote,saveNote,createDebouncedSaver,}from"@aryrabelo/planqueue-core";constloc=resolveLocation({cwd: "/path/to/my-repo",repoToplevel: "/path/to/my-repo",branch: "main",sessionId: "abc123"});constpath=notePathFor(loc);// ~/.planqueue/my-repo/main/abc123.mdconstcontent=awaitloadNote(path);// "" when file doesn't exist yetconstsaver=createDebouncedSaver((c)=>saveNote(path,c));saver.schedule(content+"\n- [ ] New task");// coalesces rapid updatesawaitsaver.flush();

Reading legacy notes

New notes always write under ~/.planqueue/. To keep notes from before the rename visible, read through the legacy roots in order (~/.free-text/ first, then ~/.omp-free-text/):

import{legacyNotePathsFor,loadNoteWithFallback,notePathFor}from"@aryrabelo/planqueue-core";constcontent=awaitloadNoteWithFallback(notePathFor(loc),// new root: ~/.planqueue/...legacyNotePathsFor(loc),// read-only fallback chain: ~/.free-text, then ~/.omp-free-text);

Stats line

import{renderStatsLine}from"@aryrabelo/planqueue-core";constline=renderStatsLine({modelName: "claude-sonnet-4-5",contextRemainingPct: 42,linesAdded: 120,linesRemoved: 30,durationMs: 185_000,});// "▓▓▓▓▓▓░░░░ 69% | claude-sonnet-4-5 | +120/-30 | 3m 05s"

Widget rendering

import{renderWidgetLines,PLAIN_STYLE}from"@aryrabelo/planqueue-core";constnote="- [x] Done task\n- [>] In-flight task\n- [ ] Pending task";constlines=renderWidgetLines(note,{maxLines: 6,style: PLAIN_STYLE});// [" └ ✓ Done task", " └ ▸ In-flight task", " └ ☐ Pending task", "(Ctrl+N)"]

Path scheme

Notes live under ~/.planqueue/<repo>/<branch>/<sessionId>.md. For back-compat, reads fall back through the legacy roots ~/.free-text/ then ~/.omp-free-text/ when the new path does not exist yet; writes always go to the new root.

~/.planqueue/
my-repo/
main/
current.md ← pointer to the active session id
abc123.md ← session note
abc123.history.md ← append-only history log

API

Full TSDoc on every export. Key functions and types:

pathsROOT_DIR_NAME, LEGACY_ROOT_DIR_NAMES, resolveLocation, notePathFor, historyPathFor, sessionsDirFor, configPathFor, legacyNotePathsFor, legacySessionsDirsFor, legacyConfigPathsFor, currentPointerPathFor · Types: RawLocation, ResolvedLocation

storeloadNote, loadConfigText, saveNote, listNotes, appendHistory, createDebouncedSaver, writeCurrentPointer, readCurrentPointer, loadNoteWithFallback · Types: DebouncedSaver, NoteSummary

queueparseTaskLine, findHead, markInflight, completeInflight, normalizeQueue, appendTask, appendQueue, prependQueue, removeBarrier, hasHeading, hasDoneTask, isEmptyOrHeadingOnly, isQueueSpent, deriveHeading, ensureHeadingFromMessage · Types: QueueStep, QueueHead, TaskState

statscomputeContext, contextLevel, formatDuration, buildContextBar, renderStatsLine · Types: StatsSnapshot, StatsStyle, ContextLevel

widgetrenderWidgetLines, PLAIN_STYLE, SHORTCUT_HINT, EMPTY_HINT · Types: WidgetStyle, WidgetOptions

configparseShortcutConfig, humanizeKey, queueHint · Types: ShortcutConfig, ParsedShortcuts, DEFAULT_SHORTCUTS

editorresolveCloseAction · Types: CloseAction

Ecosystem

PackageDescription
@aryrabelo/planqueueOh My Pi plugin — session notes + prompt queue in the OMP HUD

Contributing

git clone https://github.com/aryrabelo/planqueue-core.git
cd planqueue-core
bun install
bun test# run tests
bun run typecheck # type check
bun run lint # lint (biome)
bun run format # auto-fix formatting

PRs welcome. Please include tests for new behavior and TSDoc on any new exports.

Changelog

See CHANGELOG.md.

License

MIT — Ary Rabelo

About

Runtime-agnostic core for free-text session notes — shared by the Oh My Pi and Claude Code free-text plugins

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages