dshplugin.devDeepSeek Harness Plugins
DSH Dashboard plugin logo
DeepSeek Harness Plugin

DSH Dashboard

1
Published by Uddoo

Symphony-compatible Linear issue orchestrator and native operations dashboard for DeepSeek Harness.

Developer Toolsai-agentsdashboarddeepseek-harnessdsh

Get this plugin

Review the source, then continue to the publisher.

Get this plugin
Share on X ↗

About this plugin

Source snapshot 8/14/2026

dsh-dashboard

English | 简体中文

dsh-dashboard is a Symphony-compatible task orchestrator and operational board for DeepSeek Harness. It turns tasks from Linear, GitHub, Jira, Asana, GitLab, or a Host-local task store into isolated Harness Agent runs while preserving the native Harness shell, sidebar, sessions, tools, model selection, and permission system.

Task board running inside the native DeepSeek Harness shell

Features

  • Loads a WORKFLOW.md with YAML frontmatter and a Liquid prompt. Invalid hot reloads are rejected while the last valid definition remains active.
  • Supports Linear, GitHub Issues, Jira Cloud, Asana projects, GitLab project issues, and credential-free local tasks.
  • Applies deterministic priority ordering, required labels, global concurrency, and per-state concurrency limits.
  • Creates one persistent workspace per task and runs configurable after_create, before_run, after_run, and before_remove lifecycle hooks.
  • Runs through native Harness Agents and continues the same Harness session up to the configured turn limit.
  • Retries failed runs with bounded exponential backoff and rechecks source state before every dispatch.
  • Adds a Dashboard entry to the native Harness sidebar. Board, Runtime, Projects, and Configuration expose task state, session, workspace, turns, tokens, Agent events, retries, blockers, registered projects, and credential health.
  • Maintains a durable Project Catalog in Harness storage. Projects can be registered explicitly or discovered within bounded roots; scanned candidates are never registered without confirmation.
  • Models a Project separately from its Git Repository. Git projects use a worktree workspace strategy, while non-Git projects use controlled directories; autonomous task claims remain off.
  • Shows Linear-style + controls for the Local source, with create, edit, state, priority, description, and delete operations backed by an atomic Host-side JSON store.
  • Keeps external credentials on the trusted Host; credential values never enter Dashboard RPC payloads or browser state.

The Provider · Project control beside the Dashboard title is dynamic. Examples include Linear · ENG, GitHub · openai/example, and Local · Personal.

Provider support

ProviderTask identityDashboard state sourceHost credentialsAgent tool
LinearProject issuesNative Linear workflow stateAPI keylinear_graphql
GitHubRepository issues; pull requests are excludedConfigured state labels; open/closed fallbackFine-grained or classic tokengithub_api
Jira CloudProject issues selected with enhanced JQLNative Jira statusAccount email + API tokenjira_api
AsanaTasks in one projectProject section; completed tasks use a terminal statePersonal access tokenasana_api
GitLabIssues in one projectConfigured state labels; opened/closed fallbackPersonal/project access tokengitlab_api
LocalTasks in one named local projectStates declared in WORKFLOW.mdNonelocal_task

Only one task source is active for a WORKFLOW.md. Switching tracker.kind changes the board context and scheduler source after the validated workflow reload succeeds.

How it works

flowchart LR
    P["Linear / GitHub / Jira / Asana / GitLab"] --> S["TaskSource adapter"]
    L["Host-local task store"] --> S
    W["WORKFLOW.md"] --> O["Orchestrator"]
    C["Project Catalog\nHarness storage domain"] --> O
    X["Explicit registration / bounded scan"] --> C
    S --> O
    O --> M["Per-task workspace"]
    O --> A["Harness Agent session"]
    A --> R["Events and token usage"]
    M --> H["Lifecycle hooks"]
    O --> D["Trusted Host RPC"]
    R --> D
    D --> U["Native Harness Dashboard"]

The Host plugin owns provider access, scheduling, workspaces, hooks, Agent sessions, Project Catalog persistence, local-task persistence, and runtime state. The browser receives a constrained state projection and exposes only pause/resume, stop, refresh, Catalog operations, and Local task mutations.

Requirements

  • Node.js 22.19+ or 24+
  • pnpm 11.19+ for source builds
  • DeepSeek Harness Web profile 0.1.0-rc.6
  • An existing Harness permission preset; the bundled row uses workspace-write
  • Credentials for the selected remote provider, or no credentials for Local tasks

This repository compiles and tests against the published Harness 0.1.0-rc.6 packages. See Compatibility for the reviewed interface boundary.

Installation

npm

dsh plugin --profile web add dsh-dashboard@0.3.0
dsh web --dump-config
dsh web

Without a global CLI:

npx --yes @deepseek-ai/dsh@0.1.0-rc.6 plugin --profile web add dsh-dashboard@0.3.0
npx --yes @deepseek-ai/dsh@0.1.0-rc.6 web --dump-config
npx --yes @deepseek-ai/dsh@0.1.0-rc.6 web

The npm package contains prebuilt Host and browser entries and does not require install-time build permission.

Source or tarball

pnpm install --ignore-scripts
pnpm run typecheck
pnpm test
pnpm run build
Copy-Item -LiteralPath WORKFLOW.example.md -Destination WORKFLOW.md
pnpm pack
dsh plugin --profile web add ./dsh-dashboard-0.3.0.tgz
dsh web

Open the address printed by dsh web, then select Dashboard in the native Harness sidebar.

To uninstall:

dsh plugin --profile web remove dsh-dashboard

Plugin configuration

The package provides a standard dsh.bundle.patch; defaults live in cordis.patch.yml.

SettingPurpose
currentProject.rootHarness-selected project root. Relative paths resolve from the Harness process directory.
currentProject.policyPathProject WORKFLOW.md, resolved from currentProject.root.
currentProject.registerInCatalogRegisters the selected workspace in the Project Catalog at startup.
agentProfile.idStable profile id referenced by project.agent_profile in the project policy.
agentProfile.permissionPresetExplicit Harness permission preset applied to orchestrated Agents. Required.
agentProfile.agentPresetOptional Harness Agent preset; omission selects the available roster default.
agentProfile.workerHostHost label shown in runtime observability. Defaults to local.
policyDefaults.*Global defaults for polling, workspace root, hook timeout, concurrency, turns, and retry backoff. A project's policy block may override them.
discovery.rootsBounded scan roots seeded into the Project Catalog. Each entry has an absolute path and maxDepth from 1 to 8.
linear.endpoint / linear.apiKeyRefLinear GraphQL endpoint and API-key reference.
github.endpoint / github.tokenRefGitHub REST endpoint and token reference; the endpoint can target GitHub Enterprise.
jira.emailRef / jira.apiTokenRefJira Cloud account-email and API-token references. The site URL belongs in WORKFLOW.md.
asana.endpoint / asana.tokenRefAsana REST endpoint and token reference.
gitlab.endpoint / gitlab.tokenRefGitLab API v4 endpoint and token reference. Override the endpoint for self-managed GitLab.
local.storePathHost-side JSON task store. Defaults to ~/.dsh-dashboard/tasks.json.

Example Web profile override:

- id: dsh-dashboard
  config:
    currentProject:
      root: C:\work\my-project
      policyPath: WORKFLOW.md
      registerInCatalog: true
    agentProfile:
      id: default
      permissionPreset: workspace-write
      workerHost: workstation-01
    policyDefaults:
      pollingIntervalMs: 5000
      workspaceRoot: .dsh-dashboard/workspaces
      hookTimeoutMs: 60000
      maxConcurrentAgents: 10
      maxTurns: 20
      maxRetryBackoffMs: 300000
    discovery:
      roots:
        - path: C:\work
          maxDepth: 4
    github:
      tokenRef: GITHUB_TOKEN
      endpoint: https://api.github.com
    jira:
      emailRef: JIRA_EMAIL
      apiTokenRef: JIRA_API_TOKEN
    gitlab:
      tokenRef: GITLAB_TOKEN
      endpoint: https://gitlab.example.com/api/v4
    local:
      storePath: C:\work\dsh-dashboard\tasks.json

agentProfile.permissionPreset is deliberately explicit: unattended orchestration must never silently select or elevate a sandbox or approval policy. Project discovery does not authorize execution; every stored Project has autonomous claims disabled.

Credentials

Set only the references needed by the active provider:

$env:LINEAR_API_KEY = 'lin_api_replace_me'
$env:GITHUB_TOKEN = 'github_pat_replace_me'
$env:JIRA_EMAIL = 'user@example.com'
$env:JIRA_API_TOKEN = 'replace_me'
$env:ASANA_ACCESS_TOKEN = 'replace_me'
$env:GITLAB_TOKEN = 'glpat-replace_me'
dsh web

The same names can be stored in $DSH_HOME/.credentials.yaml:

LINEAR_API_KEY: lin_api_replace_me
GITHUB_TOKEN: github_pat_replace_me
JIRA_EMAIL: user@example.com
JIRA_API_TOKEN: replace_me
ASANA_ACCESS_TOKEN: replace_me
GITLAB_TOKEN: glpat_replace_me

Do not commit that file, real tokens, or logs containing credentials. Each provider resolves its references at operation time. Dashboard displays only the reference name, configuration status, and credential source.

WORKFLOW.md

Start with the Linear-oriented WORKFLOW.example.md or a provider-specific example:

  • GitHub
  • Jira
  • Asana
  • GitLab
  • Local tasks

Common fields:

FieldDescription
versionPolicy schema version. The current format requires 1.
project.nameHuman-readable Project name shown in Configuration.
project.agent_profileAgent Profile id; it must exactly match the configured agentProfile.id.
tracker.kindlinear, github, jira, asana, gitlab, or local.
tracker.provider.context_labelOptional short project label beside the Dashboard title.
tracker.required_labelsLabels that must all be present before dispatch.
tracker.active_statesStates eligible for Agent execution.
tracker.terminal_statesStates that stop execution and trigger safe workspace cleanup.
policy.polling.interval_msProject override for the global polling interval.
policy.workspace.rootParent directory containing one persistent workspace per task. Relative paths resolve from the policy file's directory.
policy.hooks.timeout_msTimeout applied independently to each lifecycle hook.
policy.agent.max_concurrent_agentsProject Agent concurrency limit.
policy.agent.max_concurrent_agents_by_stateOptional concurrency limits for individual source states.
policy.agent.max_turnsMaximum turns continued in one Harness session.
policy.agent.max_retry_backoff_msUpper bound for retry backoff.
policy.dashboard.visible_statesBoard columns shown before the Hidden columns group.

Provider routing fields:

ProviderRequired fieldsOptional routing
Linearproject_slugassignee: me or a Linear assignee id
GitHubowner, repoassignee, state_labels
Jirasite_url, project_keyassignee: me or account id, additional jql
Asanaproject_gidassignee: me or user gid
GitLabproject_id as numeric id or namespace pathassignee, state_labels
Localproject_id defaults to localcontext_label

For GitHub and GitLab, state_labels maps workflow-state names to provider labels. A label whose name directly equals a declared state is also recognized. Opened issues without a matching label fall back to the first active state; closed issues without a matching terminal label fall back to the first terminal state.

Jira uses native status names. Asana uses the task's section in the configured project; completed Asana tasks use the first terminal state.

The Liquid prompt can reference issue.identifier, issue.title, issue.description, issue.state, issue.labels, issue.url, and the retry attempt.

Local task controls

When tracker.kind is local, each visible column header shows a + button. New tasks are created directly in the selected column. Opening a card exposes edit and delete controls; title, description, state, and priority are editable.

Local tasks are persisted by the Host, not localStorage. Writes are serialized and committed through a same-directory temporary file and atomic rename. Dashboard edits use the task's opened revision and are rejected if an Agent or another editor has already changed it. A malformed or unsupported store is rejected instead of being overwritten. Dashboard deletion removes only the task record; an existing Agent workspace is preserved.

Lifecycle hooks

  • after_create runs only after a new task workspace is created.
  • before_run runs before every Agent attempt.
  • after_run runs after an Agent attempt while the workspace still exists.
  • before_remove runs before terminal workspace cleanup.

Hooks run as trusted local commands inside the task workspace. Review them with the same care as build or deployment scripts.

For a Git current project, the workspace is already a detached worktree of the selected repository before after_create runs; do not clone the repository again in that hook. A non-Git current project receives a controlled empty directory that after_create may initialize explicitly.

Scheduling and workspace safety

  • Eligible tasks are ordered by priority, creation time, and identifier.
  • Linear blocks relations and Jira “is blocked by” links are projected as blockers when available.
  • Missing tasks stop running without being classified as terminal, so a transient query or provider change does not delete their workspace.
  • Workspace identifiers are normalized and containment-checked before filesystem mutation.
  • Workspace roots and task directories must be real directories, not symbolic links.
  • Deletion targets are resolved again after before_remove; cleanup is refused if the root or target changed while the hook ran.
  • A failed after_create removes the incomplete workspace so a later attempt can initialize it again.
  • Runtime claims and workspace names include the provider project scope, so equal issue numbers in different repositories or projects remain isolated.
  • Hook stdout and stderr are retained as bounded tails.
  • Remote Agent tools keep endpoints and credentials on the Host and restrict operations to the configured repository, project, or issue namespace where the provider API permits it.

See Security and Architecture for the complete trust model and component boundaries.

Dashboard

The plugin registers through Harness-native UI slots:

  • sidebar.footer.action adds the Dashboard entry to the existing Harness sidebar.
  • shell.overlay renders the Dashboard in the main Harness content area.

The plugin does not replace or duplicate the Harness sidebar.

  • Board — source-native task columns, hidden states, filtering, Local task controls, and task inspection.
  • Runtime — running, retrying, and blocked records with turns, token usage, worker host, and update time.
  • Projects — durable registered Projects and separate Repository metadata, workspace strategy, current-workspace marker, discovery roots, bounded scans, and explicit candidate confirmation.
  • Configuration — last-good workflow, provider context, each credential reference's health, workspace root, polling, permission preset, and Agent limits.

The execution surface remains bound to the Harness-selected currentProject. Registering or discovering another Project makes it available in the Catalog but does not enable autonomous cross-project task claims.

Durable Project Catalog loaded through the native Harness Dashboard entry:

Project Catalog inside DeepSeek Harness

Bounded discovery keeps candidates behind an explicit review step:

Project discovery confirmation inside DeepSeek Harness

Local task board loaded through the native Harness Dashboard entry:

Local task board loaded inside DeepSeek Harness

Create and edit Local tasks without an external Tracker:

Local task editor inside DeepSeek Harness

Development and verification

pnpm run typecheck
pnpm test
pnpm run build

For deterministic component development:

pnpm run dev:dashboard

http://127.0.0.1:4173/dev/ uses fixtures and is useful for component-level visual and interaction checks. It is not evidence that the packaged plugin loads correctly in Harness.

Integration verification must build or pack the plugin, install that artifact into a Harness Web profile, start dsh web from a dedicated workspace, enter Dashboard from the native sidebar, and check provider data, Local mutations, browser console output, and Host logs.

Design references are kept in docs/design.

Upstream API references

  • GitHub Issues REST API
  • Jira Cloud REST v3 enhanced issue search
  • Asana tasks in a project
  • GitLab Issues API

Relationship to Symphony

This project reproduces Symphony's orchestration contract rather than embedding its Elixir/OTP implementation:

  • TaskSource is the provider boundary.
  • HarnessAgentRunner maps execution and continuation onto native Harness sessions.
  • Persistent per-task workspaces and lifecycle hooks follow Symphony-compatible semantics with additional fail-closed filesystem checks.
  • Trusted Host RPC projects observable state and bounded controls into the browser.
  • The UI combines Symphony's operational signals with a Linear-style board inside the native Harness shell.

Upstream reference: openai/symphony.

License

MIT