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

@f12o/dsh-dots

v0.1.1

Published

Persistent named agents (dots) for DeepSeek Harness: a root-level panel, private workspaces, home sessions, memory, schedules, and multi-host control.

Readme

@f12o/dsh-dots

Persistent named agents ("dots") for DeepSeek Harness, with a root-level Dots panel and a controller that can bundle multiple DSH hosts into one dot list.

A dot is a durable home session plus its own workspace:

$DSH_HOME/dots/
  registry.json                 # local dot records
  hosts.json                    # optional remote host list (controller only)
  dot-researcher-a1b2c3/
    AGENTS.md                   # managed operating contract
    MEMORY.md                   # durable semantic memory
    report.md                   # optional output
    .dsh-dot/manifest.json

Each dot gets:

  • a private workspace and sandbox root;
  • a home session that survives restarts;
  • an operating contract loaded through the normal AGENTS.md mechanism;
  • bounded MEMORY.md injection on every assignment;
  • durable schedules that wake a cold session;
  • an execution-time tool allowlist;
  • a host attribution so one controller can manage dots on several DSH machines;
  • a root-level sidebar panel with creation, status, assignment, memory, schedule, and archive actions.

Repository: https://github.com/f4ah6o/dsh-dots

This package is experimental and targets DSH 0.2.1-rc.2.

日本語クイックスタート

  1. 各ホスト(マシン)の Web プロファイルへこのバンドルを入れます。
  2. リモートにしたいホストだけ peer.enabled: true と bearer token を設定します。
  3. 制御側ホストの $DSH_HOME/dots/hosts.json に、各ホストの URL と token を書きます。
  4. 制御側の DSH で「mac-mini に researcher という dot を作って」と依頼します。
  5. 左サイドバーの Dots から、全ホストの dot と到達性を確認できます。新規作成・依頼・記憶の追記・ 定期実行・アーカイブはパネルから行えます。UI は DSH の言語設定に従い、日本語と英語を切り替えます。 モデル向けには dot_list / dot_assign / dot_schedule も同じ操作を提供します。

「複数の dsh を束ねる」は、制御側 1 台 + 各ホストに同じプラグイン、という構成です。各ホストが落ちても 他のホストの dot は動き続けます。制御側が落ちても、各ホストのスケジュールは動き続けます。

Install

Build the bundle, then install it into a profile:

git clone https://github.com/f4ah6o/dsh-dots.git
cd dsh-dots
pnpm install
pnpm build

dsh plugin --profile web add "$PWD"

The row is inserted by cordis.patch.yml as id: dots. Rebuild and restart the host after code changes. The host needs the Web composition (the Session controller and ctx.webServer for peer mode).

For another machine, build a tarball once and install that:

pnpm pack
# copy f12o-dsh-dots-0.1.1.tgz to the peer, then:
dsh plugin --profile web add ./f12o-dsh-dots-0.1.1.tgz

Peer host configuration

On every host that the controller should reach, enable peer mode in $DSH_HOME/profiles/web/cordis.patch.yml:

- id: dots
  config:
    peer:
      enabled: true
      name: mac-mini
      tokenFile: /Users/you/.dsh/dots/peer-token

Create the token file with owner-only permissions:

mkdir -p ~/.dsh/dots
openssl rand -hex 32 > ~/.dsh/dots/peer-token
chmod 600 ~/.dsh/dots/peer-token

The peer route is POST /dots-peer/rpc. It is authenticated only by the bearer token; it is not the browser /api auth. Bind the host Web server to a trusted network (Tailscale/WireGuard/LAN) and, for anything beyond a trusted tailnet, terminate TLS in front of it. Do not expose the route to the public internet with plain HTTP.

Controller host configuration

On the controller, create $DSH_HOME/dots/hosts.json (mode 0600):

{
  "version": 1,
  "hosts": [
    {
      "id": "mac-mini",
      "label": "Mac mini",
      "url": "http://100.64.0.7:8080",
      "token": "paste-the-peer-token-here"
    }
  ]
}
  • id: [A-Za-z0-9_.-]{1,64}; local is reserved.
  • url: no trailing slash; http or https; no embedded credentials.
  • token: at least 16 characters; use the peer's token file contents.
  • path: optional, defaults to /dots-peer/rpc.
  • timeoutMs: optional per-host deadline.

The controller also owns local dots, so local is always present in dot_list. A malformed hosts.json fails plugin activation instead of silently dropping hosts.

Dots panel

The bundle ships a browser panel as well as Host tools. Installing it adds a root-level Dots entry to the sidebar beside Workspaces and Automation tasks, and a main panel that:

  • shows every local and remote dot with host reachability and live status;
  • creates a dot on a local or remote host, including its model and reasoning effort;
  • opens a local dot's Session, or a remote host's own DSH UI;
  • queues assignments, appends durable memory, creates an every-N-seconds schedule, and archives a dot;
  • follows the DSH locale: English and Japanese copy are bundled, with the shipped language selector switching both live.

The panel reads its data from POST /dots/api, an owner-authenticated route using the same browser login-token cookie and Host/Origin fence as the rest of the Web UI. The machine-to-machine peer route remains /dots-peer/rpc with a bearer token; the browser never receives that token.

The client half is bundled into lib/client.js during pnpm build and is served by the normal client-module graph. The UI state is page-local and polls every 8 seconds; it is not part of the Session log.

Use

The tools are model-facing. Ask the assistant to create/inspect/assign, or call the tools directly.

| Tool | Meaning | |---|---| | dot_create | Create a dot on host (omit for local) with name, purpose, preset, permission preset, allowlist, and optional provider/model/reasoning effort. | | dot_list | Merge local and remote dots, including per-host reachability and live status. | | dot_assign | Queue a task. Returns when the assignment enters the inbox; it is not completion. | | dot_update | Replace purpose/contract, append memory, or replace the allowlist. | | dot_schedule | Create a durable schedule on the dot's host; one timing selector is required. | | dot_archive | Delete active schedules, cancel the live turn, and remove the dot from the active list. Per-schedule or cancellation failures are returned as warnings. |

References accept an id, a name, or host:name / host:id. A bare name is resolved local-first; if multiple remote hosts have that name, the call fails and lists the candidates. Remote lists are fetched on every dot_list and on bare-name resolution; offline hosts are reported, not cached.

Examples:

Create a dot named "release-notes" on mac-mini. Its job is to keep the release notes aligned with
the approved changelog. Use the standard preset and allow only read, grep, web_search, and web_fetch.
Assign release-notes: compare the draft against the approved changelog and write report.md.
Schedule release-notes every weekday at 09:00 Asia/Tokyo with this prompt: check the changelog and
prepare a short delta report.

Dot settings

The panel and dot_create expose these per-dot settings:

| Setting | Meaning | |---|---| | Name | Stable dot identity and Workspace/Session title. | | Purpose | The managed AGENTS.md contract: outcome, sources of truth, quality bar, escalation. | | Host | Local or a configured remote DSH host; the dot's workspace, session, and schedules live there. | | Agent preset | DSH preset composition (tools, persona, delegation). Defaults to standard. | | Permission preset | DSH sandbox + approval bundle, for example workspace-write. | | Allowed tools | Execution allowlist of exact tool names or trailing-* prefixes. Empty denies all. | | Model / reasoning effort | Session-level provider/model/effort. Omit for the deployment default. | | Assignment | One queued task; it enters the dot's inbox and is processed serially. | | Memory note | A dated entry appended to MEMORY.md, injected into later assignments. | | Schedule | Title, task prompt, and an every-N-seconds interval in the panel; dot_schedule adds cron/daily/weekly/one-shot. |

Host and deployment settings live outside the dot:

  • $DSH_HOME/dots/hosts.json: remote host ids, labels, URLs, tokens, paths, timeouts.
  • Profile peer config: peer enabled flag, bearer token/token file, route path, body limit.
  • Plugin config: root, defaultPreset, defaultPermissionPreset, maxDots, maxTaskBytes, maxPurposeBytes, maxMemoryBytes, enforceToolAllowlist, hostsFile, requestTimeoutMs, peer.*.

Model selection

A model belongs to the home Session, not to an individual assignment. dot_create accepts provider, model, and optional reasoning_effort; the Host validates them against its live model catalog and applies sessionController.selectModel() after creating the Session. The choice persists on that Session, so every later dot_assign and scheduled wake uses the same route. It is not re-selected per assignment.

If no model is supplied, the Session uses the deployment default. Existing dots created before this field existed have no stored model and keep using the deployment default. You can still change the model from the dot Session's own composer model picker; the Dots panel's Model row records the selection made at creation.

The UI catalog is host-specific: a local dot uses this host's providers, while a remote dot uses the peer's catalog. If a catalog is empty or unreachable, the form offers only “Deployment default”.

How it works

Creation

  1. Validate name/purpose/allowlist and the local cap.
  2. Create $DSH_HOME/dots/<id>/, AGENTS.md, MEMORY.md, and .dsh-dot/manifest.json.
  3. Register a Workspace for the directory (when available).
  4. Create a home Session with the configured preset and attach it to the Workspace.
  5. Rename the Session, apply the permission preset, select the requested model, and persist the dot record.

If Workspace registration fails, the dot still runs from its directory. If Session creation fails after a Workspace was created, the partial directory is kept and the error names it; retry with a new dot or clean up manually.

Assignment

dot_assign resolves the dot, resumes a cold session through the Session controller, reads the tail of MEMORY.md (up to maxMemoryBytes), and queues a [DOT ASSIGNMENT] message through agent.followup(). The source kind is dot. A running dot receives the assignment on a later turn; one dot processes assignments serially. The controller records lastAssignedAt and assignmentCount.

Scheduling

dot_schedule calls the Host Schedule service on the dot's host. The stored prompt is framed with [DOT SCHEDULED TASK] and instructs the dot to read AGENTS.md and MEMORY.md first. The Host Schedule service restores a cold Session when the target is due, so a schedule survives host restarts. Recurring schedules keep only their latest missed occurrence, which is the underlying Schedule contract.

Memory

AGENTS.md is managed by this package and is regenerated when dot_update changes the purpose or allowlist. Put durable learned facts in MEMORY.md; the dot is instructed to append dated entries. Giving feedback through the controller:

Tell release-notes to remember that the user prefers a one-paragraph summary with links.

The controller calls dot_update(add_memory: ...); the next assignment injects that memory even after compaction or a cold resume.

Permissions and guardrails

  • A dot's home session can carry any configured permission preset (sandbox mode + approval policy).
  • allowedTools is enforced by a tools/pre-execute listener: exact names or trailing * prefixes. An empty array denies every tool. Tool schemas remain visible; only execution is denied.
  • A dot can never call dot_* tools, so dots cannot create or manage other dots.
  • bash in the allowlist still permits arbitrary commands inside the sandbox; the allowlist is not a shell-level policy.
  • When no approval answerer is available, the existing approval seam fails closed. Unattended dots should use a permission preset appropriate for autonomous work, or keep work read/draft-only.

Multiple hosts

Each host has its own registry, dot directories, sessions, schedules, and credentials. The controller does not copy remote state; it calls the peer RPC. A remote dot continues to run when the controller is offline, as long as its own host is running. The controller sees it again on the next dot_list. If a host is offline, listing reports it and operations that need that host fail with dots/peer-offline; nothing is queued for later delivery.

Configuration

All fields are optional except where noted.

| Field | Default | Meaning | |---|---|---| | root | $DSH_HOME/dots | Local dot root (registry, workspaces, host list). | | defaultPreset | standard | Agent preset for a new dot when dot_create omits one. | | defaultPermissionPreset | unset | Permission preset applied to new dots. | | maxDots | 32 | Maximum active local dots. Each host enforces its own cap. | | maxTaskBytes | 20000 | Maximum UTF-8 bytes in one assignment or memory note. | | maxPurposeBytes | 4000 | Maximum UTF-8 bytes in a purpose. | | maxMemoryBytes | 8192 | MEMORY.md UTF-8 bytes injected per assignment. | | enforceToolAllowlist | true | Enforce allowedTools at execution time. | | hostsFile | $DSH_HOME/dots/hosts.json | Controller remote host list. | | requestTimeoutMs | 15000 | Default per-remote-call deadline. | | peer.enabled | false | Register POST /dots-peer/rpc. | | peer.token | unset | Inline bearer token (prefer tokenFile). | | peer.tokenFile | unset | File containing the bearer token. | | peer.path | /dots-peer/rpc | Exact peer route path. | | peer.name | unset | Diagnostic name returned by ping. | | peer.maxBodyBytes | 1048576 | Maximum peer request body. |

Security

  • The peer route runs in the DSH host process with the host user's permissions. Treat the token as a host administrator credential.
  • Use a unique token per host, store it in a 0600 file, and rotate it by restarting the peer.
  • Prefer a tailnet/WireGuard network or TLS. The route has no rate limiting, CSRF protection, or browser auth; it is a machine-to-machine API.
  • Remote dots execute with the remote host's sandbox and permission presets; their AGENTS.md and MEMORY.md live on that host.
  • Do not put secrets in MEMORY.md, AGENTS.md, or assignments. Memory is model-visible.

Limitations

  • One home session per dot; assignments are serial. Create more dots or use subagents inside a dot for parallelism.
  • Archiving hides the dot from the Dots panel but retains its Workspace and Session in the Workspaces sidebar. Remove those separately if you want the sidebar clean.
  • The panel's schedule form creates fixed every-N-seconds schedules. Use dot_schedule or the dot itself for cron, daily, weekly, or one-shot schedules.
  • The panel polls every 8 seconds and has no live push feed; status changes can lag briefly.
  • No automatic cloud VM provisioning. This is a local-foreground/host-machine model. A dot's workspace is on its host.
  • No Slack/Teams/SMS/email channels.
  • A model changed later in the dot Session's composer is not written back to the dot record; the panel's Model row shows the creation-time selection.
  • No automatic token/cost quota. Schedules and autonomous work consume model tokens.
  • The controller loads hosts.json at activation; edit and restart to add a host.
  • Remote dot names are resolved by listing every host; a large fleet makes bare-name resolution proportional to fleet size. Use host:name for deterministic routing.
  • Archiving is not transactional across hosts: a schedule that cannot be deleted, or a turn that cannot be cancelled, is reported in warnings while the dot record is still archived. Inspect the remote host if a warning appears.

Development

pnpm install
pnpm build
pnpm typecheck
pnpm test
npm pack --dry-run

The tests use a structural FakeHost; no live DSH process or model key is required. Integration checks against live hosts should use a separate DSH_HOME and a non-default port.

License

MIT