Skip to content

Repository files navigation

@leemour/cli-messaging

The messenger-neutral half of a messaging command line tool, shared by tg-cli and, later, max-cli. Built on @leemour/cli-core.

Status: on npm — what each version changed is in CHANGELOG.md. The domain model, message locators, message rendering, name resolution, the SQLite seam that runs under Node and Bun, and the first part of the command skeleton with the shared read commands, the send guard, run records and the message store — see the platform proposal.

The rule this package keeps

Nothing here knows a messenger. An adapter translates its provider's objects into these types, and a lint rule refuses any import of a messenger library or an adapter under src/. What only one provider has travels in providerMetadata.

. Chat, Message, Contact, Page… · formatLocator / parseLocator · renderMessages · pickChat / pickPerson
./store openCache — node:sqlite under Node, bun:sqlite under Bun, WAL and a busy timeout on both · openStore — the shared message store, every method async: one file for every messenger (MESSAGING_STORE overrides where), forward-only migrations with min_compatible, every sender an identity with a person of their own, edits kept as revisions, a message by its id, deletions kept as tombstones, trigram search · find — by text, by sender, or both; together for the chats where every sender wrote, perChat to cap each chat · savePeople and people — usernames and bot flags, and a PeopleLookup for pickPerson
./sends the send guard: a level per command path (permissions: deny, readonly, ask, allow — readOnly and allow read as levels), a recipient list, an hourly limit, and a journal of every attempt that never holds the text; newSendId for a send's identity across retries
./cli the command skeleton: run (never throws, returns an exit code), the global flags, settingsFor (flag → environment → file → default, one strict file schema with each CLI's own fields), the profile as the first word, --timeout that closes what a command holds, paging, and run records: --record keeps a run's ids and timings (never content), a failure is kept unless --no-record, and runsCommand gives runs list|show|path · configCommand(app, config) shows and changes the settings with where each came from · completeCommand(messenger, config) gives shell completion, chat ids from the store and never a connection · doctorCommand(messenger) reports the installation's state from disk (the store, the account, sends, runs, the messenger's own checks), and connects only with --online; doctor report create writes that, the failed run and the recent sends to a file with every id a label · skillCommand(app, url) prints the CLI's own SKILL.md for an agent (skill show) · commandsCommand(app) describes every command as JSON, with contract (CONTRACT, the major version of the output types) and which commands write · the shared read commands: a CLI describes its messenger once (Messenger: its app, a connect that returns a MessengerAdapter, how me maps to a chat) and gets accountCommand, chatsCommand (list, show), contactsCommand (list, show) recipientsCommand, sendsCommand, watchCommand (new messages as they arrive, --jsonl, until Ctrl-C or --timeout; --events adds edits, deletions and reactions, each kept in the store), storeCommand (the local store: store fetch puts a chat's history into it, resumable, FloodWait-aware, --since to stop at a time, --background for a detached job that `store jobs list

⚠ Errors are recognised by shape, not by class (isCliFailure). A package linked during development brings its own copy of cli-core, and an error built by one copy is not an instanceof the other's class.

A message locator names one message across every provider and account: msg:telegram/<account>/<chat>/<message>. A message id alone does not — Telegram numbers messages per chat in channels and per account in private chats.

Where it came from

The files were copied from max-cli at 3ca8874, from the part its lint rule CLI-30 already kept free of MAX. What changed on the way is listed as DEBT-1…DEBT-10 in the proposal.

Checks

pnpm install
pnpm lint && pnpm typecheck && pnpm test
pnpm smoke:bun    # the same exports, run under Bun

Releasing

Raise version in package.json through a pull request, merge it, then on main:

bin/release --local   # from this machine: NPM_TOKEN if exported, else the keyring (service npm, account leemour)
bin/release           # from GitHub Actions, once npm trusts .github/workflows/release.yml

Both refuse a dirty tree, a branch other than main and an unpushed main. When npm already has the version, or a higher one, they commit the next free version to main — the next minor for x.y.0, the next patch otherwise — and publish that. They run every check, and tag v<version> once npm shows it. The token is never printed and never written to a file. The GitHub form publishes from the job in the npm environment, which is what npm's trusted publisher names: leemour / cli-messaging / release.yml / environment npm.

How often, and what may break

At most one release a day. Changes wait under ## Unreleased and ship together. The one exception is a fix a consumer is blocked on today: it ships alone, and the changelog says which consumer and why.

These exports are stable. A change that breaks them waits for a breaking release, at most one a week, whose changelog section says what to change in a consumer; tg-cli and max-cli move to it the same day.

Export Stable
. the domain types (Chat, Message, Contact, Page, …), the message locator
./cli Messenger, MessengerAdapter and its method groups, createProgram, run, messengerContext, the command factories' names and arguments
./store openStore, MessageStore, storePath, and the file format: minCompatible rises only in a breaking release
./sends sendGuard, SendJournal, the journal's line format
./services servicesFor, Override and the service names

Everything else may change in any release, and still goes under "Changed — may break callers" when it does. tg-cli and max-cli take new versions through Dependabot pull requests.

Licence

MIT.

About

CLI messaging module

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages