@alwith/module-chat
v0.1.4
Published
Desktop-first shared chat implementation. Distributed under the proprietary license included in this package.
Readme
@alwith/module-chat
Desktop-first shared chat implementation. Distributed under the proprietary license included in this package.
Desktop and U share turn virtualization, Desktop's Markdown renderer, activity groups, work sections, plans, user messages, assistant turn layout and edited-file cards. Both apps also consume the composer, completion menu, model/effort/permission selectors, attachments, approval components, search interaction and turn navigation with audio. U maps existing API state to presentation blocks; it does not maintain a second session state. Extraction is not yet a complete product acceptance: source-to-rendered search mapping and end-to-end visual/selection/scroll verification remain outstanding.
Ownership
| Package owns | Application supplies | | --- | --- | | Message layout, Markdown, activity and tool presentation | Message projection, theme, translations, file/artifact opening and business-specific cards | | Composer, attachments, completion and selectors | Controlled draft, available commands/files/models/options, submission and error handling | | Approval and elicitation interaction | Original request identity, protocol response, replay and product-specific actions | | Virtual list, search UI and turn navigation | Session identity, viewport, source matches, reveal callback and navigation preferences |
Application navigation, settings, login pages, update UI and general-purpose product controls are not part of this package. Runtime owns execution; @alwith/api owns protocol folding. Applications must not reconstruct run state from the chat presentation.
Import @alwith/module-chat/markdown.css for Markdown styling and include the package source in Tailwind's @source scan. Local linked development requires React deduplication in the app bundler; React is a peer, never bundled into chat. Bun component tests alias linked React to the real consumer React exports without installing a global DOM.
Run bun install at the workspace root, then bun run --cwd packages/chat typecheck and bun run test:chat. Consumer DOM tests live in both apps and cover the shared implementations through their real app adapters.
ACP session folding stays in @alwith/api. This package owns chat presentation and interaction, not Agent processes or a second session database.
update-scheduler exports the optional, framework-independent ChatUpdateScheduler<Snapshot>.
The host folds every protocol update immediately, then calls enqueue(sessionId, snapshot)
with the complete immutable snapshot. One 16ms window publishes the latest snapshot for each
pending session in a single callback; incoming chunks never reset the deadline. Call flush()
after enqueueing a lifecycle/configuration change or finishing history replay, remove(sessionId)
when dropping a session, and cancel() on disconnect/disposal. The callback should publish the
batch to the UI store once. This schedules store notifications, not protocol processing or
Markdown parsing. It retains only pending snapshot references, has no React/DOM/ACP dependency,
and does not change existing components or enable batching unless the host opts in.
search provides Desktop's complete find bar, DOM matching, highlights and navigation. The host supplies its viewport, labels and native-menu subscription; virtualized callers also supply source matches and an async turn-reveal callback. Key the component by session identity to discard the previous search on a session switch. Highlight ownership is per mounted search, and cancelled navigation cannot repaint after close. Source projection stays with the application's message model; the search component never reads a private store.
search-source shares Unicode-aware literal matching and original UTF-16 offsets with DOM matching. This does not make raw tool fields, Markdown source or folded content equivalent to rendered text: the current per-turn occurrence index still requires a complete source-to-rendered mapping. Do not treat the current search counter as proof that every indexed match can be revealed. Automatic expansion of folded matches has not been agreed.
permission-view supplies Desktop's approval list, sorting, keyboard selection and optional input-anchored portal. Without an anchor it renders inline. Applications supply request identity, details and the response callback; Desktop replay/pet actions and U's ACP pending-request routing remain in their hosts. Inline callers can select autoFocus="if-idle" to avoid taking focus from a draft.
choice-elicitation-form preserves Desktop's choice questions, Other inputs, previews and notes. schema-elicitation-form handles standard schema fields, including text, numbers and booleans. Applications answer the original pending request; the package does not send protocol messages. The latter reuses the API's property guards; local unpublished development resolves @alwith/api through the workspace root dependency and override.
url-elicitation-card provides U's inline pending-link presentation. The host opens the supplied URL and handles decline/cancel; opening a browser does not synthesize an acceptance response. Desktop's separate native URL-consent and authorization flow is unchanged, not replaced by this card.
Tool results use Desktop defaults; optional Output/Patch/image actions preserve inline terminal, diff and media behavior. The package includes TerminalOutput and PatchView implementations.
For i18next, wrap the application resources once with withChatResources(resources) from @alwith/module-chat/locales. This adds the alwithChat namespace without mutating application resources or choosing its active/fallback language. ActivityHost receives the translator for that namespace. Existing Desktop translations are included; unavailable entries follow the application i18n fallback policy.
The composer form comes from @alwith/module-chat/composer, with the controller/provider in composer-context and the textarea in composer-textarea. It owns file selection, drag/drop, image limits and preparation, and clears the draft after successful submission. Supply onSubmit and onSubmitError; application commands and local file identity are optional host policies. Desktop enables its bash border explicitly. Controls remain internal Desktop-derived primitives, not a general UI component kit. Locally linked apps deduplicate @base-ui/react as well as React to keep primitive contexts and hooks on the consumer instance.
composer-attachments provides the attachment list and chips, with Desktop's hover preview, removal and zoomable image dialog. The chip takes a translator for its three input labels. image-preview-dialog exposes the same preview for other chat image entry points; zoom, viewport fitting and pointer-centered scrolling remain package-owned.
completion-menu owns keyboard selection, focus, insertion and the anchored/inline menu; the host supplies completion data and async file search. model-select, effort-slider and permission-mode-select are controlled: callbacks request a change, while the host supplies the authoritative selected value. Provider catalogs, subscriptions, billing and settings navigation remain application policy.
navigation-rail owns Desktop's turn markers, preview, observation and scrubbing, and imports its CSS. The host projects turns, releases scroll following before reveal, supplies the virtualizer callback and injects navigation audio actions. navigation-audio and navigation-instruments share Desktop's sample cache, unlock lifecycle, instrument catalog and playback scheduling. Preferences and native diagnostics remain in the application. Linked consumer tests that mock smplr must resolve the same module instance as the package; Desktop deduplicates it alongside React and Base UI. Automated tests do not establish audible playback in a packaged application.
License and redistribution
See LICENSE and third-party notices. ALwith-owned code is proprietary, not open source. You may build, customize, host, charge for and distribute your own WorkBuddy applications under the included license, without per-application registration. This does not grant hosted-service access or rights to separately distributed Rust libraries or Runtime binaries. The npm artifact includes compiled/minified JS, declarations and necessary assets, not the private TS/TSX implementation or source maps. Minification is not encryption.
