dsh-jira-tasks 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +134 -0
- package/README.md +111 -17
- package/package.json +4 -3
package/README.en.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# JIRA Open Tasks Panel (DeepSeek Harness Plugin)
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
|
|
5
|
+
[中文](README.md) · **English**
|
|
6
|
+
|
|
7
|
+
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 read from credentials; the project key and JQL are **configured per workspace** and persisted.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 📋 Panel shown below the composer in both new and active sessions (aligned with the input width in new sessions)
|
|
12
|
+
- 👤 Defaults to the current user (`assignee = currentUser()`) with status `开启 / 重新开启` (Open / Reopened)
|
|
13
|
+
- ⚙️ Project key and JQL are saved per workspace; unconfigured workspaces show "unconfigured"
|
|
14
|
+
- 🔄 Auto-query on every new session, with a one-click refresh (⟳)
|
|
15
|
+
- 🔗 Click an issue to open its JIRA detail in a new tab
|
|
16
|
+
- 🎨 Uses DSH theme tokens; adapts to light / dark themes
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
Published to npm:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
dsh plugin --profile desktop add dsh-jira-tasks
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Restart DSH** to activate.
|
|
27
|
+
|
|
28
|
+
<details>
|
|
29
|
+
<summary>Manual install (without npm)</summary>
|
|
30
|
+
|
|
31
|
+
1. Copy the repo's `profile-package/` to `~/.dsh/profiles/desktop/packages/dsh-jira-tasks/`
|
|
32
|
+
2. Edit `~/.dsh/profiles/desktop/package.json`:
|
|
33
|
+
- Add to `dependencies`: `"dsh-jira-tasks": "file:./packages/dsh-jira-tasks"`
|
|
34
|
+
- Append to `dsh.profile.bundles`: `"dsh-jira-tasks"`
|
|
35
|
+
3. Run `pnpm install` in the profile directory
|
|
36
|
+
4. Restart DSH
|
|
37
|
+
|
|
38
|
+
> 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.
|
|
39
|
+
</details>
|
|
40
|
+
|
|
41
|
+
<details>
|
|
42
|
+
<summary>Dynamic plugin (temporary, lost on restart)</summary>
|
|
43
|
+
|
|
44
|
+
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.
|
|
45
|
+
</details>
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
### 1. JIRA base URL and token
|
|
50
|
+
|
|
51
|
+
Write to `$DSH_HOME/.credentials.yaml` (recommended, hot-reloaded), or export environment variables before launching DSH:
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
JIRA_BASE_URL: "http://jira.example.com/"
|
|
55
|
+
JIRA_API_TOKEN: "<PAT or user:token>"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- Base URL aliases: `JIRA_BASE_URL` / `JIRA_URL`
|
|
59
|
+
- Token aliases: `JIRA_API_TOKEN` / `JIRA_TOKEN`
|
|
60
|
+
- Auth is auto-detected: tokens containing `:` use Basic, otherwise Bearer (JIRA PAT)
|
|
61
|
+
|
|
62
|
+
### 2. Project key and JQL (per workspace)
|
|
63
|
+
|
|
64
|
+
- Click **⚙** on the panel header to open settings (the form shows the target workspace)
|
|
65
|
+
- **Project key**: e.g. `HCPFYH1` — saved and queried immediately; auto-loaded for new sessions in that workspace
|
|
66
|
+
- **JQL**: leave empty for the default, or write a custom JQL where `{projectKey}` (or `{key}`) is replaced by the project key
|
|
67
|
+
|
|
68
|
+
Default query:
|
|
69
|
+
|
|
70
|
+
```jql
|
|
71
|
+
project = "{projectKey}" AND status in ("开启", "重新开启") AND assignee = currentUser() ORDER BY updated DESC
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> The status names follow the Chinese workflow (`开启`/`重新开启`). For English statuses (Open/Reopened), set a custom JQL in ⚙.
|
|
75
|
+
|
|
76
|
+
## Uninstall
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
dsh plugin --profile desktop remove dsh-jira-tasks
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Troubleshooting
|
|
83
|
+
|
|
84
|
+
<details>
|
|
85
|
+
<summary>Panel shows "query failed"</summary>
|
|
86
|
+
|
|
87
|
+
| Message | Fix |
|
|
88
|
+
|---|---|
|
|
89
|
+
| JIRA_BASE_URL not configured | Credentials missing — see "Configuration 1" above |
|
|
90
|
+
| 401 … | Invalid token or wrong auth scheme; verify with `curl -H "Authorization: Bearer <token>" <base>/rest/api/2/myself` |
|
|
91
|
+
| Cannot parse JIRA response | Network / proxy issue, curl produced no output |
|
|
92
|
+
</details>
|
|
93
|
+
|
|
94
|
+
<details>
|
|
95
|
+
<summary>Panel does not appear</summary>
|
|
96
|
+
|
|
97
|
+
- Make sure it is installed and DSH was **restarted**; in new sessions the panel sits below the input
|
|
98
|
+
- Check the DSH startup log for profile plugin load errors
|
|
99
|
+
</details>
|
|
100
|
+
|
|
101
|
+
## Architecture & Implementation Details
|
|
102
|
+
|
|
103
|
+
<details>
|
|
104
|
+
<summary>Expand</summary>
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
┌─────────── Browser (Client) ───────────┐ ┌──────────── Host ──────────────┐
|
|
108
|
+
│ conversation.composer.dock (active) │ │ webServer route /jira/api/search │
|
|
109
|
+
│ conversation.input.dock (new, order:99) │ │ ↓ │
|
|
110
|
+
│ ↓ on mount/refresh fetch POST │ │ credentials.resolve(JIRA_*) │
|
|
111
|
+
│ render: list / error / unconfigured │ │ subprocess.spawn(curl …) │
|
|
112
|
+
│ localStorage per-workspace config │ │ ↓ stdout JSON │
|
|
113
|
+
└────────────────────────────────────────────┘ │ parse issues → {ok,issues} │
|
|
114
|
+
└────────────────────────────────┘
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- **Host**: registers a `webServer` route `POST /jira/api/search`; credentials resolved via the `credentials` service (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.
|
|
118
|
+
- **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).
|
|
119
|
+
- **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.
|
|
120
|
+
- **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".
|
|
121
|
+
|
|
122
|
+
**Differences from the dynamic version**
|
|
123
|
+
|
|
124
|
+
| Aspect | Dynamic plugin | Persistent install (this package) |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| Persistence | Lost on restart | Survives restart |
|
|
127
|
+
| Client→Host | `host.call` / `harness.handle` | `webServer` route + `fetch` |
|
|
128
|
+
| Client bundle | Injected per session | `/plugins/dsh-jira-tasks/client.js` |
|
|
129
|
+
| Config / credentials | Same `localStorage` key, same `.credentials.yaml` | Identical |
|
|
130
|
+
</details>
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
package/README.md
CHANGED
|
@@ -1,37 +1,81 @@
|
|
|
1
|
-
#
|
|
1
|
+
# JIRA 开启任务面板(DeepSeek Harness 插件)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](LICENSE)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**中文** · [English](README.en.md)
|
|
6
|
+
|
|
7
|
+
在 DSH 会话**输入框下方**展示当前 JIRA 项目**指派给当前用户**的「开启 / 重新开启」任务列表。JIRA 地址与令牌从凭据读取;项目 Key 与 JQL **按工作区配置**并持久化。
|
|
8
|
+
|
|
9
|
+
## 功能
|
|
10
|
+
|
|
11
|
+
- 📋 新会话与活跃会话的输入框下方均展示任务面板(新会话时与输入框等宽)
|
|
12
|
+
|
|
13
|
+
<img width="1898" height="886" alt="image" src="https://github.com/user-attachments/assets/d14d0bd4-4f9f-4aa8-9af8-b8a02a2b7296" />
|
|
14
|
+
<img width="1972" height="746" alt="image" src="https://github.com/user-attachments/assets/9f543e04-a5ad-4b86-85c8-baa2de26f44e" />
|
|
15
|
+
|
|
16
|
+
- 👤 默认仅显示当前用户(`assignee = currentUser()`)的「开启 / 重新开启」任务
|
|
17
|
+
- ⚙️ 项目 Key 与 JQL 按工作区保存;未配置的工作区显示"未配置"
|
|
18
|
+
- 🔄 打开新会话自动查询,面板内支持一键刷新(⟳)
|
|
19
|
+
- 🔗 任务可点击,在新标签页打开 JIRA 详情
|
|
20
|
+
- 🎨 颜色使用 DSH 主题令牌,浅色 / 深色主题自适应
|
|
6
21
|
|
|
7
22
|
## 安装
|
|
8
23
|
|
|
24
|
+
包已发布到 npm:
|
|
25
|
+
|
|
9
26
|
```bash
|
|
10
27
|
dsh plugin --profile desktop add dsh-jira-tasks
|
|
11
|
-
# 或手动安装:见仓库 README「注册方式二:正式安装」
|
|
12
28
|
```
|
|
13
29
|
|
|
14
|
-
|
|
30
|
+
**重启 DSH** 后生效。
|
|
31
|
+
|
|
32
|
+
<details>
|
|
33
|
+
<summary>手动安装(不使用 npm)</summary>
|
|
34
|
+
|
|
35
|
+
1. 将仓库 `profile-package/` 复制为 `~/.dsh/profiles/desktop/packages/dsh-jira-tasks/`
|
|
36
|
+
2. 编辑 `~/.dsh/profiles/desktop/package.json`:
|
|
37
|
+
- `dependencies` 增加:`"dsh-jira-tasks": "file:./packages/dsh-jira-tasks"`
|
|
38
|
+
- `dsh.profile.bundles` 追加:`"dsh-jira-tasks"`
|
|
39
|
+
3. 在 profile 目录执行 `pnpm install`
|
|
40
|
+
4. 重启 DSH
|
|
41
|
+
|
|
42
|
+
> 注:`pnpm install` 会把包**复制**到 `node_modules/`(非符号链接),改动源码后需同步 `node_modules/dsh-jira-tasks` 或重跑 install。
|
|
43
|
+
</details>
|
|
44
|
+
|
|
45
|
+
<details>
|
|
46
|
+
<summary>动态插件方式(临时,重启后消失)</summary>
|
|
47
|
+
|
|
48
|
+
在 DSH 会话中用 Cordis 工具执行:`cordis_define`(`kind: new`,`idPrefix: "jira"`,源码见仓库 `plugin/host.js` / `plugin/client.js`)→ `cordis_run` 激活。动态插件只存在于进程内存,**重启后消失**,仅适合临时试用。
|
|
49
|
+
</details>
|
|
15
50
|
|
|
16
51
|
## 配置
|
|
17
52
|
|
|
18
|
-
1.
|
|
53
|
+
### 1. JIRA 地址与令牌
|
|
19
54
|
|
|
20
|
-
|
|
21
|
-
JIRA_BASE_URL: "http://jira.example.com/"
|
|
22
|
-
JIRA_API_TOKEN: "<PAT 或 user:token>"
|
|
23
|
-
```
|
|
55
|
+
写入 `$DSH_HOME/.credentials.yaml`(推荐,热加载无需重启),或启动 DSH 前导出环境变量:
|
|
24
56
|
|
|
25
|
-
|
|
57
|
+
```yaml
|
|
58
|
+
JIRA_BASE_URL: "http://jira.example.com/"
|
|
59
|
+
JIRA_API_TOKEN: "<PAT 或 user:token>"
|
|
60
|
+
```
|
|
26
61
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
62
|
+
- 地址别名:`JIRA_BASE_URL` / `JIRA_URL`
|
|
63
|
+
- 令牌别名:`JIRA_API_TOKEN` / `JIRA_TOKEN`
|
|
64
|
+
- 认证自动识别:令牌含 `:` 用 Basic,否则用 Bearer(JIRA PAT)
|
|
30
65
|
|
|
31
|
-
|
|
66
|
+
### 2. 项目 Key 与 JQL(按工作区)
|
|
32
67
|
|
|
33
|
-
-
|
|
34
|
-
-
|
|
68
|
+
- 点击面板标题右侧 **⚙** 打开设置(表单顶部提示当前配置归属的工作区)
|
|
69
|
+
- **项目 Key**:如 `HCPFYH1`,保存后立即查询,该工作区后续新会话自动加载
|
|
70
|
+
- **JQL**:留空使用默认查询;也可填写自定义 JQL,`{projectKey}`(或 `{key}`)会被替换为项目 Key
|
|
71
|
+
|
|
72
|
+
默认查询:
|
|
73
|
+
|
|
74
|
+
```jql
|
|
75
|
+
project = "{projectKey}" AND status in ("开启", "重新开启") AND assignee = currentUser() ORDER BY updated DESC
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> 状态名按中文工作流("开启"/"重新开启")配置;若 JIRA 用英文状态(Open/Reopened),在 ⚙ 中填写自定义 JQL 即可。
|
|
35
79
|
|
|
36
80
|
## 卸载
|
|
37
81
|
|
|
@@ -39,6 +83,56 @@ dsh plugin --profile desktop add dsh-jira-tasks
|
|
|
39
83
|
dsh plugin --profile desktop remove dsh-jira-tasks
|
|
40
84
|
```
|
|
41
85
|
|
|
86
|
+
## 常见问题
|
|
87
|
+
|
|
88
|
+
<details>
|
|
89
|
+
<summary>面板显示「查询失败」</summary>
|
|
90
|
+
|
|
91
|
+
| 提示 | 处理 |
|
|
92
|
+
|---|---|
|
|
93
|
+
| 未配置环境变量 JIRA_BASE_URL | 凭据未写入,见上文「配置 1」 |
|
|
94
|
+
| 401 … | 令牌无效或认证方式不对;先 `curl -H "Authorization: Bearer <token>" <base>/rest/api/2/myself` 验证 |
|
|
95
|
+
| 无法解析 JIRA 响应 | 网络 / 代理问题,curl 无输出 |
|
|
96
|
+
</details>
|
|
97
|
+
|
|
98
|
+
<details>
|
|
99
|
+
<summary>面板不显示</summary>
|
|
100
|
+
|
|
101
|
+
- 确认已安装并**重启 DSH**;新会话面板位于输入框下方
|
|
102
|
+
- 检查 DSH 启动日志中 profile 插件是否加载成功
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
## 架构与实现细节
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary>点击展开</summary>
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
┌─────────── 浏览器(Client) ───────────┐ ┌──────────── Host ──────────────┐
|
|
112
|
+
│ conversation.composer.dock(活跃会话) │ │ webServer 路由 /jira/api/search │
|
|
113
|
+
│ conversation.input.dock(新会话, order:99)│ │ ↓ │
|
|
114
|
+
│ ↓ 挂载时/刷新时 fetch POST │ │ credentials.resolve(JIRA_*) │
|
|
115
|
+
│ 渲染:任务列表 / 错误 / 未配置 │ │ subprocess.spawn(curl …) │
|
|
116
|
+
│ localStorage 按工作区存取配置 │ │ ↓ stdout JSON │
|
|
117
|
+
└────────────────────────────────────────────┘ │ 解析 issues → 返回 {ok,issues} │
|
|
118
|
+
└────────────────────────────────┘
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- **Host**:注册 `webServer` 路由 `POST /jira/api/search`;凭据经 `credentials` 服务解析(环境变量 / `$DSH_HOME/.credentials.yaml`,热加载);查询用 `subprocess` 直接 `spawn curl`,认证头经 stdin(`--config -`)传入,令牌不进入命令行参数。
|
|
122
|
+
- **Client**:`window.__ModuleLoader__.load({ id, factory })` 标准 web bundle;注册 `conversation.composer.dock`(活跃会话)与 `conversation.input.dock`(新会话,flex `order: 99` 置于输入框下方、与输入框等宽)。
|
|
123
|
+
- **为什么不用 `shell` 服务**:`shell` 会套 `sandbox-exec`,部分 macOS 上不可用(`sandbox_apply: Operation not permitted`);`subprocess` 是原始进程缝,无此问题。
|
|
124
|
+
- **新会话显示**:DSH 壳在 hero(空白会话)阶段不渲染 `composer.dock`,故额外注册 `input.dock`,并用「会话是否已有消息」去重,避免双份面板。
|
|
125
|
+
|
|
126
|
+
**与动态插件版的差异**
|
|
127
|
+
|
|
128
|
+
| 维度 | 动态插件 | 正式安装(本包) |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| 持久性 | 重启丢失 | 重启保留 |
|
|
131
|
+
| Client→Host 通信 | `host.call` / `harness.handle` | `webServer` 路由 + `fetch` |
|
|
132
|
+
| 客户端 bundle | 会话内注入 | `/plugins/dsh-jira-tasks/client.js` |
|
|
133
|
+
| 配置 / 凭据 | 同一 `localStorage` 键、同一 `.credentials.yaml` | 完全相同 |
|
|
134
|
+
</details>
|
|
135
|
+
|
|
42
136
|
## License
|
|
43
137
|
|
|
44
138
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-jira-tasks",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "JIRA open tasks panel for DeepSeek Harness (DSH): shows the current user's open/reopened issues below the composer, per-workspace project key, persistent profile bundle.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"lib",
|
|
14
14
|
"cordis.patch.yml",
|
|
15
15
|
"README.md",
|
|
16
|
-
"LICENSE"
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"README.en.md"
|
|
17
18
|
],
|
|
18
19
|
"keywords": [
|
|
19
20
|
"dsh",
|
|
@@ -39,4 +40,4 @@
|
|
|
39
40
|
]
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
}
|
|
43
|
+
}
|