DeepSeek Harness Plugin

liu3734/jira-tasks-dsh-plugin#profile-package

Stars ★ 1 Downloads (30d) 852 Category UI Enhancements Added 2026-09-11 npm dsh-jira-tasks

JIRA task panel under the DSH composer: per-workspace project key and optional JQL, listing the issues assigned to the current user with status, priority and issue-type chips, a total count, collapse and refresh, links to JIRA, plus a settings card for the base URL and token with a connection probe.

Install

# from npm (prebuilt)

dsh plugin --profile web add dsh-jira-tasks

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:liu3734/jira-tasks-dsh-plugin#path:/profile-package

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

中文 · English

Shows the current JIRA project's open / reopened issues assigned to the current user below the DSH composer input. The JIRA base URL and token are configured in Settings → Plugins → JIRA (JIRA_BASE_URL / JIRA_API_TOKEN act as fallback); the project key and JQL are configured per workspace and persisted.

Features

  • 📋 Panel shown below the composer in both new and active sessions (aligned with the input width in new sessions)
  • 👤 Defaults to the current user (assignee = currentUser()) with status 开启 / 重新开启 (Open / Reopened)
  • ⚙️ Settings → Plugins → JIRA edits the base URL and access token (the token is written to the credential store and never sent back to the browser)
  • 🟢 The card auto-probes the connection and shows a status light: green = usable, red = unusable, grey = unconfigured; Test connection verifies unsaved drafts immediately
  • ⚙️ Project key and JQL are saved per workspace; unconfigured workspaces show "unconfigured"
  • 🔄 Auto-query on every new session, with a one-click refresh (⟳)
  • 🔗 Click an issue to open its JIRA detail in a new tab
  • 🎨 Uses DSH theme tokens; adapts to light / dark themes

Install

Published to npm:

dsh plugin --profile web add dsh-jira-tasks

Restart DSH to activate.

  1. Copy the repo's profile-package/ to ~/.dsh/profiles/web/packages/dsh-jira-tasks/
  2. Edit ~/.dsh/profiles/web/package.json:
    • Add to dependencies: "dsh-jira-tasks": "file:./packages/dsh-jira-tasks"
    • Append to dsh.profile.bundles: "dsh-jira-tasks"
  3. Run pnpm install in the profile directory
  4. Restart DSH

Note: pnpm install copies the package into node_modules/ (not a symlink) — after editing sources, sync node_modules/dsh-jira-tasks or re-run install.

In a DSH session, use the Cordis tools: cordis_define (kind: new, idPrefix: "jira", sources in plugin/host.js / plugin/client.js) → cordis_run to activate. Dynamic plugins live only in process memory and disappear on restart — for trial use only.

Configuration

1. JIRA base URL and token

Open Settings → Plugins → Plugin configuration → JIRA and fill in:

  • JIRA base URL: e.g. http://jira.example.com/ (stored in the user settings document and read back by the form)
  • Access token / PAT: written to the credential store ($DSH_HOME/.credentials.yaml); the browser only ever sees "configured", never the token itself

Leaving the token blank on save keeps the existing one; clearing the address on save removes the override and falls back to the environment. Auth is auto-detected: tokens containing : use Basic, otherwise Bearer (JIRA PAT).

Connection test

The card's footer carries a status light and a Test connection button:

  • Opening the card auto-probes once (against JIRA /rest/api/2/myself), and saving re-probes
  • Green = address and token work (the current user is shown); red = unusable (JIRA's reason, e.g. 401, is shown); grey = address or token not configured
  • Test connection probes what is currently in the fields, saved or not, so you can check before saving

Environment variables / credentials still work as a fallback (used when the settings card is empty), hot-reloaded without a restart:

JIRA_BASE_URL: "http://jira.example.com/"
JIRA_API_TOKEN: "<PAT or user:token>"
  • Base URL aliases: JIRA_BASE_URL / JIRA_URL
  • Token aliases: JIRA_API_TOKEN / JIRA_TOKEN

2. Project key and JQL (per workspace)

  • Click on the panel header to open settings (the form shows the target workspace)
  • Project key: e.g. HCPFYH1 — saved and queried immediately; auto-loaded for new sessions in that workspace
  • JQL: leave empty for the default, or write a custom JQL where {projectKey} (or {key}) is replaced by the project key

Default query:

project = "{projectKey}" AND status in ("开启", "重新开启") AND assignee = currentUser() ORDER BY updated DESC

The status names follow the Chinese workflow (开启/重新开启). For English statuses (Open/Reopened), set a custom JQL in ⚙.

Uninstall

dsh plugin --profile web remove dsh-jira-tasks

Troubleshooting

Message Fix
JIRA base URL not configured Address missing — see "Configuration 1" above
JIRA token not configured Token missing — see "Configuration 1" above
401 … Invalid token or wrong auth scheme; verify with curl -H "Authorization: Bearer <token>" <base>/rest/api/2/myself
Cannot parse JIRA response Network / proxy issue, curl produced no output
  • Make sure it is installed and DSH was restarted; in new sessions the panel sits below the input
  • Check the DSH startup log for profile plugin load errors

Architecture & Implementation Details

┌─────────── Browser (Client) ───────────┐      ┌──────────── Host ──────────────┐
│ conversation.composer.dock (active)        │      │ webServer route /jira/api/search │
│ conversation.input.dock (new, order:99)    │      │   ↓                            │
│   ↓ on mount/refresh fetch POST            │      │ settings.get("jira-tasks")      │
│ render: list / error / unconfigured        │      │ credentials.resolve(JIRA_*)     │
│ localStorage per-workspace key/JQL         │      │ subprocess.spawn(curl …)        │
│ settings.plugin.item (Settings card)       │      │   ↓ stdout JSON                 │
└────────────────────────────────────────────┘      │ parse issues → {ok,issues}      │
                                                    └────────────────────────────────┘
  • Host: registers the jira-tasks settings namespace (baseUrl, readable) and a webServer route POST /jira/api/search; the address comes from the settings document, the token from the credentials service (Settings card / env / $DSH_HOME/.credentials.yaml, hot-reloaded); queries run through subprocess spawning curl directly, with the auth header passed via stdin (--config -) so the token never appears in argv.
  • Client: a standard window.__ModuleLoader__.load({ id, factory }) web bundle; registers conversation.composer.dock (active sessions) and conversation.input.dock (new sessions, flex order: 99 below the input, aligned width), plus settings.plugin.item (key: "jira-tasks") for the Settings card — the address is written through settingsScope and the token through remote.credentials.
  • Why not the shell service: shell wraps commands with sandbox-exec, which is broken on some macOS versions (sandbox_apply: Operation not permitted); subprocess is the raw process seam without this issue.
  • New-session display: the DSH shell does not render composer.dock during the hero (blank session) phase, so the plugin also registers input.dock and de-duplicates by "session has messages".

Differences from the dynamic version

Aspect Dynamic plugin Persistent install (this package)
Persistence Lost on restart Survives restart
Client→Host host.call / harness.handle webServer route + fetch
Client bundle Injected per session /plugins/dsh-jira-tasks/client.js
Config / credentials Env / .credentials.yaml only (no Settings card) Settings card + same .credentials.yaml fallback

License

MIT

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.