npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@haneinfo/collaboration

v0.12.1

Published

Immutable instance comments, merged timelines and following.

Readme

Instance collaboration

Immutable plain-text comments, a read-time activity timeline, and following for StateMachine instances. Install the collaboration plugin with StateMachine, identity, notification inbox, Prisma and optional RBAC capabilities. Include prisma/collaboration.prisma in the App schema and migrate it normally. No separate timeline event table is created. The package starts at 0.0.0 for a first minor release.

Readers and writers must be the submitter, have state-machine:instance:read, or hold a reader grant. Comments cannot be updated or deleted through this package. Text is stored and returned literally: clients render it as text, without HTML or Markdown interpretation. Mentions use @{userId}; recipients must be active and currently able to read the instance. Agent/MCP comments are always marked isAiGenerated.

HTTP routes under /state-machine-instances/:id: GET/POST comments, GET timeline, POST/DELETE follow. Reads accept offset (default 0) and limit (default 50, maximum 200). Timeline events sort by ascending timestamp then stable source-prefixed id, and expose hasMore. Sources are history, CHOICE decisions, issued numbers, notification failures and comments. Concurrent additions may change offset boundaries between separate requests; one request uses a database snapshot.

Register CollaborationMcpTools.registerInto(registry, { scopeNamespace }) in the App's existing internal MCP registry. Tools are get_instance_comments, get_instance_timeline, comment_on_instance, follow_instance, unfollow_instance; all require <namespace>:instance:read transport scope plus live instance-read authorization. User text and timeline details use $userContent wrappers. The package creates no public endpoint or new business permission.

Following is unique per instance/user and covers every subsequent transition and new comment. The approved state-machine.transition.recorded event is consumed through StateMachineListener.onEvent inside the originating transaction, independent of stale state-entry suppression. Transition notifications use the existing state-machine-transition:<historyId> key. Comment notifications use collaboration-comment:<commentId>, union followers, mentions and submitter, exclude the author, and recheck each recipient's active identity and instance-read permission immediately before delivery. The inbox's recipient/key unique constraint handles replay and overlap with transition-action notifications. Transition followers do not add an automatic submitter notification unless that person follows; existing transition notify actions keep their recipient semantics.

Configuration: collaboration: { appName?: string }. App name defaults to app. No subscription rules, event-type filtering, comment editing, or alternate objects are provided.

Mutating tools additionally declare mutates: true. Both the generated catalog and MCP wire annotations then report readOnlyHint: false, even for writes authorized by existing read scopes. This conservative declaration cannot turn a write scope into a read-only operation.

Instance readers and stored query values

Instance readers have the same discussion and following access as the submitter or a holder of state-machine:instance:read. Apply the state-machine reader-table migration and existing-task backfill before upgrading. Reader checks use the caller transaction, including mention validation and delivery; task status does not revoke readership.

Comment recipients are the deduplicated union of followers, mentions and submitter, excluding the author even if they follow or mention themselves. Other recipients receive one notification. Transition notifications keep their existing behavior, including notifications to an actor who follows the instance. ADMIN has no new special case.

Mechanism compatibility

Supports state-machine 0.7 as well as 0.6. Instance readership continues to use the existing StateMachine contract; Collaboration does not implement condition comparison operators.

Frontend contracts

GET /state-machine-instances/:id/mentionable?q= returns { items: [{ id, name }] }, at most 20 active readers other than the caller. Names may be null. Matching uses case-insensitive name containment; an empty q searches all names. q is at most 200 characters. A nonreader receives INSTANCE_NOT_FOUND (404), exactly like a missing instance.

IdentityStorePort.searchActiveByName owns database filtering and keyset pages of at most 20 candidates. Upgrade identity-core with collaboration. Missing optional identity search fails closed with IDENTITY_SEARCH_UNAVAILABLE (503). Collaboration evaluates each candidate through the existing effective RBAC authorization and reader grant check; it does not query role tables or reproduce role policy. Memory is bounded by one candidate page plus 20 results; a sparse query can require many bounded queries. Results are ordered by identity id. Comments revalidate mentions when posted.

GET comments and GET timeline now include following: boolean for the caller, queried in the same transaction as the page. MCP get_instance_comments and get_instance_timeline preserve following. New list_mentionable_users accepts { instanceId, q? }, uses :instance:read, is read-only, and wraps each name in $userContent. The manifest declares all six tools; no confirmation or new mutation tool is added.

Instance privacy alignment

Collaboration already returns identical INSTANCE_NOT_FOUND/404 for missing and unreadable instances before comments, timeline, mentions and follow operations. State-machine now applies the same hiding behavior before human writes; collaboration authorization is unchanged. No general-user people lookup is added.

Delegated transition timeline

History timeline details optionally include actingUserId and onBehalfOfId from the existing history decision JSON, allowing clients to display who acted for whom. actorId, triggerRef and every existing field retain their meanings. No new table, timeline kind, frontend or historical name snapshot is added. Permanent instance readers, including past delegates, retain read/comment access.

Instance access lists (draft implementation)

Implemented against draft decision 202610-c8e3; the decision remains draft.

Comments, mentions, mentionable discovery, follows and notification recipients use the submitter, effective instance:read, or matching USER/ROLE access (READ or WRITE). Losing manual/role access immediately blocks new reads, mentions and notifications; old inbox entries are retained. The existing timeline SQL union classifies triggerType ACCESS as kind ACCESS and preserves the existing details fields, adding decision.access with the action, principal and previous/new levels. No state transition, revision bump or follower transition notification is generated for access changes. MCP wraps decision as $userContent, including access activity. User/grantor names are plain text.

Upgrade the affected mechanisms together after applying the App migration. The maintained model, HTTP routes, read-only list_instance_access MCP tool, errors and permission contract are documented in @haneinfo/state-machine/agent-guide.md. Its prisma/instance-access.sql migrates the existing reader table to USER/ROLE, READ/WRITE and ASSIGNED/DELEGATED/GRANTED rows while retaining timestamps. The maintainer selected (instanceId, principalType, principalId, source) uniqueness. Manual grants are limited to 100 by default; permanent READ entries survive manual removal. See the package repository validation/equipment-loan/instance-access/report.md for SQL, tests and App restoration evidence.

Optional attachments (draft decision 202610-5f3b)

Attachment activity uses existing history with triggerType ATTACHMENT and optional decision.attachment (action, id, plain-text fileName). No storage keys, state/revision changes or notifications are introduced. Collaboration classifies these history rows as ATTACHMENT in its existing SQL union; MCP retains decision $userContent wrapping. See @haneinfo/attachments/agent-guide.md for authorization, storage, scanning, migration and retention. Apps adopting the optional package add its reverse instance relation; the core fragment does not depend on attachments.

Document generation (draft 202610-d4f6)

The optional @haneinfo/document-templates package adds DOCUMENT activity using existing history and decision.document (templateCode, templateVersion, format), attributed by triggerUserId. No tables, state/revision changes or notifications are added. Collaboration classifies the row as DOCUMENT in its existing authorized SQL timeline. Instance history and timeline fields remain unchanged. Read the document-templates agent guide for fonts, configuration, HTTP and read-only MCP.

Instance lifecycle (draft 202610-f1a8)

Implemented from draft decision 202610-f1a8; the decision remains draft. Upgrade state-machine, list-view, collaboration, attachments, import-export, assignment and timer together. No frontend, automatic archive or bulk lifecycle operations are included. Permanently purged data cannot be restored by this API: database and private file backups must cover the entire deletion retention period and be restored consistently.

Apply prisma/instance-lifecycle.sql to add ON DELETE CASCADE foreign keys for comments/follows; add comments CollaborationComment[] and follows CollaborationFollow[] to the App's instance model. Check and reconcile pre-existing orphan rows before applying these constraints; migration does not silently delete them. The core fragment does not depend on this optional package. LIFECYCLE history joins the existing timeline UNION with the original event fields and optional decision.lifecycle. Actions are ARCHIVED, RESTORED, DELETED, UNDELETED; actorId and at retain who/when. Existing MCP decision wrapping applies. Deleted-instance comments, timeline, mentions and follows use the same missing-id 404. Archive does not block them. Lifecycle events produce no collaboration notifications.

Instance tags (draft 202610-2c5d)

Implemented from draft 202610-2c5d; the decision remains draft. See @haneinfo/tags/agent-guide.md for data, migration and authorization. The existing timeline SQL classifies TAG activities and retains all original fields/pagination. decision.tag contains action ADDED/REMOVED, normalizedKey and label; the existing MCP decision wrapper covers this user text. Each actual tag change has one activity and sends no notification.

Unified search (draft 202610-a3d8)

Draft implementation; the decision remains draft. Each comment emits collaboration.comment.added (instanceId, commentId, authorId, isAiGenerated, at; never the body) in the comment transaction. When the optional SEARCH_PROVIDERS registry is present (manifest optionalRequires haneinfo.search), CollaborationService registers CommentsSearchProvider: the newest commentLimit (default 200) comments, newest first, AI-generated included, composed with the shared plugin-api helpers and the configured row limit. Without @haneinfo/search nothing is registered and comments behave as before. The manifest requires plugin API 1.19.0.

Object references (draft 202610-f7a2)

The timeline SQL classifies REFERENCE history entries (written by the optional @haneinfo/references through state-machine) as the REFERENCE kind, with decision.reference (action LINKED or UNLINKED, linkId, kind, direction, other { type, id, number }) in details; original fields, ordering and pagination are unchanged. No notification is sent.

Spaces (draft 202610-b1d6)

The timeline SQL classifies SPACE history entries (written by the optional @haneinfo/spaces through state-machine when an instance is placed, moved or taken out) as the SPACE kind, with decision.space (action PLACED, MOVED or REMOVED, nodeId, previousNodeId) in details; original fields, ordering and pagination are unchanged. No notification is sent.