@teamx-ai/dsh-plugin
v0.2.0
Published
teamx deepseek-harness plugin: multi-agent team collaboration with teamx_* tools, /team-* slash commands, and real-time digest injection
Readme
@teamx-ai/dsh-plugin
teamx plugin for deepseek-harness (dsh) — shared-goal human-in-the-loop collaboration across multiple dsh agents.
What it does
- 28
teamx_*tools registered viactx.tools.register(defineTool(...))for team management, goal tracking, member approval, role assignment, and real-time collaboration - 21
/team-*flat slash commands registered viactx.commands.register - Runtime
teamxskill registered viactx.skills.register(...)— provides the collaboration protocol / usage guide so agents know how to use teamx_* tools (Per-Turn Protocol, State Machine, Workflow Guidance) - Per-agent digest injection via
ctx.systemPrompt.variable— each agent sees live team state in its system prompt - Auto-execute: directed tasks wake the target agent via
agent.followup() - Real-time push: WebSocket + poll-based digest refresh (configurable via
pollIntervalMs) - Network mode: mTLS HTTP RPC + WS push when
TEAMX_SERVER_URLis set
Architecture
dsh-plugin/
├── src/
│ ├── index.ts # Plugin entry: Cordis apply(), event hooks, poller, auto-execute, digest
│ ├── client.ts # sessionKey/instanceId/runCli(binary)/runRpc(mTLS)/mtlsFor/member cache
│ ├── tools.ts # teamx_* tools → ctx.tools.register(defineTool(...))
│ ├── commands.ts # /team-* flat slash commands → ctx.commands.register
│ ├── skill.ts # Runtime teamx skill (collaboration protocol) → ctx.skills.register()
│ ├── ws.ts # WebSocket push client (Node ws package, mTLS, reconnect)
│ ├── digest.ts # Per-agent digest cache + sync refresh + formatting
│ ├── auto-execute.ts # Directed task detection → agent.followup()
│ └── i18n.ts # Message strings
├── package.json
├── tsconfig.json
└── README.mdInstallation
The plugin loads via dsh's cordis plugin system and is published to npm in two packages:
# One-command install (bundle mounts the plugin into the profile):
dsh plugin --profile <name> add @teamx-ai/dsh-plugin-bundle
# Alternative: install the plugin package directly, then mount it in the
# profile's cordis.patch.yml:
npm install @teamx-ai/dsh-plugin # into the profile's package.json# $DSH_HOME/profiles/<name>/cordis.patch.yml
- id: teamx
name: '@teamx-ai/dsh-plugin'For development against a local checkout, use a file: dependency in your dsh profile:
{
"dependencies": {
"@teamx-ai/dsh-plugin": "file:/path/to/teamx/dsh-plugin"
}
}The npm package ships a bundled lib/index.js (single-file ESM bundle); the dsh runtime provides the @deepseek-ai/* peer packages it imports. Local file: installs need a build first: cd dsh-plugin && npm run build.
Session identity
Each dsh agent gets a unique key: ${teamxInstance}:${agentSessionID}
teamxInstance= UUID from~/.teamx/instance.jsonagentSessionID= dsh'sagent.session.id
This key is the agent's identity across all teamx operations. dsh agents and opencode sessions can join the same team — they share the same session key format.
Environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| TEAMX_HOME | ~/.teamx | teamx data directory |
| TEAMX_SERVER_URL | (auto) | Network-mode server URL (from letter or env) |
| TEAMX_POLL_INTERVAL | 15000 | Digest refresh interval (ms); 0 disables |
| TEAMX_AUTO_EXECUTE | 1 | Enable auto-execute for directed tasks |
| TEAMX_MTLS_CERT | — | mTLS client certificate path |
| TEAMX_MTLS_KEY | — | mTLS client key path |
| TEAMX_MTLS_CA | — | mTLS CA certificate path |
| TEAMX_BIN | teamx | teamx binary path |
Tools (28)
Team management
teamx_create_team— Create team, get invite tokenteamx_join— Join team via invite tokenteamx_leave— Leave current teamteamx_list_teams— List teams with goal/role overviewteamx_status— Full team status (members, goal, events)teamx_sync— Pull latest state + new eventsteamx_archive— Archive completed team (owner)teamx_team_destroy— Destroy team permanently (owner)teamx_team_invite— Generate invite with roleteamx_team_import— Import invite letterteamx_team_invite_list/teamx_team_invite_revoke— Manage invites
Goal management
teamx_set_goal— Set/update team goal (owner)teamx_share_goal— Share goal, activate team (owner)teamx_close_goal— Close achieved goal (owner)
Member/role management
teamx_approve/teamx_deny— Approve/deny pending membersteamx_set_role— Choose or assign roleteamx_role_propose— Propose custom roleteamx_role_approve/teamx_role_deny— Approve/deny custom roleteamx_role_update— Update role label/descriptionteamx_set_state— Set idle/active state
Interaction
teamx_ask— Ask a member a questionteamx_respond— Answer an open questionteamx_publish— Publish event to team ledger
Slash commands (21)
| Command | Description |
|---------|-------------|
| /team-create <name> | Create a new team |
| /team-join <token> <name> | Join team via invite token |
| /team-status | Show team status |
| /team-sync | Pull latest state |
| /team-goal-set <title> | Set team goal |
| /team-goal-share | Share goal with members |
| /team-goal-close | Close achieved goal |
| /team-approve <member> | Approve pending member |
| /team-deny <member> | Deny pending member |
| /team-invite <role> | Generate invite |
| /team-import <path> | Import invite letter |
| /team-publish <type> | Publish event |
| /team-role-set <role> | Set/assign role |
| /team-state <idle\|active> | Set working state |
| /team-ask <member> <msg> | Ask a question |
| /team-respond <id> <msg> | Answer a question |
| /team-help | Show available commands |
Digest injection
The plugin injects a live team digest into each agent's system prompt via ctx.systemPrompt.variable('teamx_digest', ...). The digest includes:
- Team name and status
- Current goal and its state
- Member list with roles and states
- Recent events (last 3)
- Open questions
Each agent gets its own isolated digest (via agent.ctx.systemPrompt). Refreshed every pollIntervalMs ms (default 15s) via poller or WebSocket push.
Skill (collaboration protocol)
The plugin registers a runtime teamx skill via ctx.skills.register(...) during startup. This skill provides the collaboration protocol that teaches agents how to use teamx_* tools effectively:
- Available Commands — flat slash commands and corresponding tools
- Per-Turn Protocol — sync before acting, report progress, owner summarizes
- State Machine — team/member/goal lifecycle references
- Workflow Guidance — step-by-step flows for create/join/invite/roles
- Auto-execute — directed task handling rules
The skill appears in the agent's <available_skills> catalog (via dsh's dsh-tool-skill consumer, present in standard/code/cordis presets). Agents can also load it on demand via the skill tool. The digest (above) provides live state; the skill provides static protocol — they complement each other.
Auto-execute
When a task is published with --assignee <member>, the plugin detects it and calls agent.followup(message) to wake the target agent. The agent receives a structured message with the task details and digest, then starts working automatically.
Disable with TEAMX_AUTO_EXECUTE=0.
Cordis plugin lifecycle
apply(ctx, config)
├── ctx.on('ready')
│ ├── Discover teamx instance ID
│ ├── Register 28 teamx_* tools
│ ├── Register 21 /team-* commands
│ └── Register teamx skill (ctx.skills.register)
│
├── ctx.on('agent/session-start')
│ ├── Check team membership → markMember()
│ ├── Register systemPrompt.variable('teamx_digest')
│ ├── Register systemPrompt.section('teamx:digest')
│ └── Initial digest refresh
│
├── ctx.on('agent/status')
│ └── On idle: publish heartbeat + refresh digest
│
├── ctx.on('agent/dispose')
│ └── Unregister agent, clear digest
│
├── Poller (every pollIntervalMs)
│ ├── Fetch events for known sessions
│ ├── Process auto-execute for directed tasks
│ └── Refresh digest
│
└── WS push (when TEAMX_SERVER_URL set)
├── Connect to /ws endpoint (mTLS)
└── On event: refresh digest + process auto-executeNetwork mode
When TEAMX_SERVER_URL is set (or discovered from an imported letter), the plugin switches from local binary execution to HTTP mTLS RPC:
- Local mode: spawns
teamxbinary viachild_process.execFilefor each operation - Network mode: POST to
https://server/rpcwith mTLS client cert (Nodehttpsmodule)
WebSocket push provides real-time event notifications via the ws npm package (supports mTLS client certs). Both modes support the full feature set.
Multi-agent collaboration
The key feature: multiple dsh agents can collaborate on the same team goal, just like multiple opencode sessions.
Agent A (owner) Agent B (contributor)
│ │
├── teamx_create_team ──────────► │
├── teamx_set_goal ─────────────► │
├── teamx_share_goal ───────────► │
├── teamx_invite(contributor) ──► │
│ ├── teamx_join(token)
│ ◄──── teamx_approve ────────────┤
│ │
├── teamx_publish(progress, ─────► │
│ assignee=B) │
│ ├── [auto-execute: followup()]
│ ├── teamx_sync()
│ ├── [work on task]
│ ├── teamx_publish(achieved)
│ ◄──── teamx_sync ───────────────┤
├── teamx_close_goal ───────────► │Session key format ${teamxInstance}:${agentSessionID} is shared with opencode-plugin, so dsh agents and opencode sessions can join the same team.
Differences from opencode-plugin
| Feature | opencode-plugin | dsh-plugin |
|---------|----------------|------------|
| Runtime | Bun | Node 22+ |
| Tool registration | ctx.client.tool(...) | ctx.tools.register(defineTool(...)) |
| Command registration | Markdown files in assets/ | ctx.commands.register(...) |
| Agent context / skill | agent/teamx.md file (installed to ~/.config/opencode/agent/) | Runtime skill via ctx.skills.register(...) |
| System prompt injection | experimental.chat.system.transform | ctx.systemPrompt.variable() + .section() |
| Auto-execute | session.promptAsync() | agent.followup() |
| WS client | Bun WebSocket | ws npm package |
| Activity collection | Yes (enterprise) | No (V1 core only) |
| Tunnel/proxy tools | Yes | No (V1 core only) |
Dependencies
@deepseek-ai/cordis— Plugin framework@deepseek-ai/dsh-tools— Tool registration (defineTool)@deepseek-ai/dsh-agent— Agent interface (agent.followup())@deepseek-ai/dsh-session— Session events@deepseek-ai/dsh-system-prompt— System prompt injection@deepseek-ai/dsh-commands— Slash command registration@deepseek-ai/dsh-skill— Skill registration (ctx.skills.register)ws— WebSocket client (mTLS support)
Development
cd dsh-plugin
npm install # installs dsh packages via file: references
npx tsc --noEmit # type-check (noCheck: true for unbuilt dsh packages)The dsh packages must be built first for full type checking:
cd /path/to/deepseek-harness
pnpm install && pnpm buildTesting
Tests are in tests/ (to be implemented). The test plan covers:
client.tsunit tests (sessionKey, runCli mock, member cache)tools.tsintegration (spawn real binary, verify CLI args)- Multi-agent collaboration loop (owner + member, full lifecycle)
- Auto-execute trigger (directed task → followup called)
