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

@zhchxiao123/dsh-devflow

v0.2.0

Published

Service Definition for the ctx.devflow task-card capability seam of the DeepSeek Harness

Readme

@zhchxiao123/dsh-devflow

English | 中文

Service Definition for the ctx.devflow capability seam: file-backed task cards moving through a fixed development pipeline. This package owns the card vocabulary (DevCard, DevStage, journal entry types, the branded DevflowCardId) and the journal decode/replay shared by every consumer. Storage belongs to a provider such as dsh-devflow-filesystem; the model-facing tools are dsh-tool-devflow.

Service

DevflowStore is an abstract Cordis Service on ctx.devflow (one implementation per context; a second registration throws).

Every operation carries an explicit devflow root dimension: reads take an optional trailing root, requests carry an optional root field resolved into their spec, and ClaimOptions carries one for the lease. An omitted root falls back to the implementation's configured default, so single-root deployments never mention it; a returned DevCard always names the resolved root it belongs to, and cards with equal ids under different roots are different cards. Which root a caller passes is the caller's decision — the model tools and /devflow derive <session cwd>/.devflow from the invoking session, and the seam itself never maps workspaces to directories. The session-scoped reads are the one exception, because their caller is a browser that must never send paths: listForSession and detailForSession take the viewing session's id and resolve it host-side (the live or persisted session's header cwd, through the optionally composed sessions/sessionPersistence services) into the same root dimension; an unknown session is a stable rejection. detailForSession aggregates one card's read value, its decoded journal, and its lease holder (DevCardDetail) in a single round trip for the board's detail view, re-reading once when a transition tears the pair. dsh-devflow-web is what puts those two on a browser channel.

| Method | Behavior | |---|---| | list(filter?, root?) | One root's cards ordered by id; filter.stage narrows to one current location, filter.parent to one card's children. | | read(id, root?) | One card with journal-derived state; a missing card throws. | | history(id, root?) | The card's complete decoded journal, oldest first, stream-validated like a read (a structurally invalid journal fails loudly, naming file and line). | | holder(id, root?) | The card's current lease holder (ClaimHolder: owner plus last heartbeat), undefined while unclaimed; a corrupt claim record fails loudly. | | resolveCreate(request) | Explicit defaulting: turns a caller CreateRequest (title, Markdown body, optional slug, actor, optional parent, optional root) into the fully specified CreateSpec — the slug derived from the title when omitted, the root resolved, plus the creation timestamp. | | create(spec) | Creates one card: parent validation → sequence-number allocation (continuing past archived cards, so an id is never reissued) → exclusive directory creation → the journal's first created entry (the only commit point) → projection write → devflow/card-created. Domain rejections resolve ok: false with a stable code (empty-title, invalid-slug, exists, unknown-parent, nested-parent, parent-settled); only infrastructure failures reject. | | resolve(request) | Explicit defaulting: turns a caller TransitionRequest into the fully specified TransitionSpec with its resolved root and commit timestamp. | | transition(spec) | Commits one move: revision CAS → edge check → devflow/transition waterfall → cross-process commit lock and journal append (the only commit point) → projection rewrite → devflow/stage-changed. Domain rejections resolve ok: false with a stable code (revision-mismatch, illegal-edge, reason-required, vetoed, write-contended); only infrastructure failures reject. | | claim(id, owner, options?) | Takes the card's exclusive lease; a held lease resolves with the current holder, unless options.staleAfterMs marks its heartbeat lapsed — then one concurrent caller journals claim-expired and replaces the lease under the commit lock. Lock contention leaves the observed holder in place. | | attachArtifact(request) | Registers a stage deliverable in the journal against the current stage, in one of two mutually exclusive forms: the reference form records a path the caller already wrote under the card directory, and the store-written form hands over kind plus content for the implementation to write artifacts/<rev>-<kind>.md itself before the journal append — still the only commit point, so a lost commit registers nothing and its unreferenced file is overwritten by a same-revision retry. Registrations are immutable: the newest record of one kind is that kind's current content. Rejected while blocked or done, with revision-mismatch, illegal-edge, invalid-kind, or write-contended; the outcome carries the registered ArtifactRecord. | | archiveDone(root?) | Moves every archivable done card of one root out of the active set into that root's archive, keyed by the month of its last journal entry; a decomposed requirement archives as one family (a done child waits for its parent, then joins the parent's month bucket). Archived cards leave list but keep their complete journal. Returns the archived ids in id order. |

Current state always comes from journal replay; a card file's frontmatter is a rebuildable projection. Implementations must fail a read loudly on a structurally invalid journal (naming file and line), warn-and-override on projection drift, and publish state and notifications only after the journal committed. Legal edges (isLegalTransition): the pipeline order, rework from reviewing/testing back to whichever stage owns the fault — developing for the implementation, designing for the design — blocked entry from any non-terminal location, and recovery only to the exact interrupted stage. done is terminal in both directions: a delivered card is not reopened, because its history may already have been archived and the seam has no operation that reads the archive. A rework edge (isReworkEdge) without a reason is rejected reason-required, so the next holder always learns what to fix.

Stages and journal

DevStage is the closed union draft | designing | ready | developing | reviewing | testing | done; blocked is a bypass location that remembers the stage it interrupted (CardLocation = DevStage | 'blocked'). The journal entry union is created | transition | artifact | claim-expired, decoded by decodeJournalEntry (the durable-boundary validator) and folded by foldJournal, which enforces: contiguous revisions from 1, created first and only first, transitions departing the current location, and blocked recovery returning exactly to the remembered stage.

An artifact entry may carry a kind naming the deliverable of a store-written registration; entries without one decode and fold exactly as before. foldArtifactRecords derives every registration as an ArtifactRecord (path, optional kind, journal revision, registering stage), surfaced as DevCard.artifactRecords with DevCard.artifacts remaining its path projection. A transition entry's gate records what permitted the move: the human approval signature (approvedBy) and/or the gate verdicts (checks) a policy listener attached to its permitting waterfall decision — both fields optional, so existing { approvedBy } entries decode unchanged.

A requirement too big for one card becomes a parent card plus one child card per slice. The edge is the created entry's parent, so it is fixed at creation, replayable, and never re-pointed; foldJournal surfaces it as DevCard.parent and the frontmatter parent: is its projection. The breakdown is one level deep — a card carrying parent is never itself a parent — and parent and children always share a root. Which cards may take children is the provider's creation-time decision (unknown-parent, nested-parent, parent-settled); the seam holds no rule about how a parent's own stage relates to its children's.

Events

| Event | Mode | Meaning | |---|---|---| | devflow/transition | waterfall | Single-decision pipeline before the commit, dispatched with the complete TransitionAttempt (spec plus departure); a policy listener that owns the decision returns { allowed: false, reason } without calling next(), and a permitting decision may carry approvedBy and checks, recorded as the committed entry's gate. dsh-devflow-gates runs command policies here. | | devflow/card-created | emit | A new card entered the active set: its journal committed the first created entry. | | devflow/stage-changed | emit | A card settled at a new location after a committed transition. |

The invariant companion validates the emit streams: card-created announces only fresh drafts at revision 1 for never-seen ids and never hangs a card under one the stream already knows to be a child, and per card, stage-changed revisions strictly increase while every notification reports an actual move.

Model Experience

Indirectly, through the model-facing tools in dsh-tool-devflow: the service interface itself registers no prompt or schema.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

  • The archive is write-onlyarchiveDone removes done cards from the active set; no seam operation lists or restores archived cards.
  • No card editing after creationcreate fixes the title and body once; changing a card's content remains a direct edit of its card.md in the provider's on-disk format.