dsh-atlassian-plugin 0.3.3 → 0.4.0

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.md CHANGED
@@ -1,20 +1,31 @@
1
1
  # dsh-atlassian-plugin
2
2
 
3
- Jira and Confluence for DeepSeek Harness, over Atlassian's remote MCP server,
4
- signed in through a browser OAuth flow.
3
+ Jira and Confluence inside DeepSeek Harness, over Atlassian's remote MCP server,
4
+ signed in through a browser.
5
+
6
+ Part of **[DeepSeek Harness Plugins](https://github.com/k0ndrateff/dsh-plugins)**
7
+ by [@k0ndrateff](https://github.com/k0ndrateff) — Jira, Confluence, Sentry, GitLab
8
+ and Figma integrations for
9
+ [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), plus a digest,
10
+ a cross-provider correlation and project checks built on top of them. Everything is
11
+ in the [market index](https://k0ndrateff.github.io/dsh-plugins/market.json) and
12
+ listed in the [collection README](https://github.com/k0ndrateff/dsh-plugins#packages).
13
+
14
+ ## What you get
5
15
 
6
16
  - The server's tools as ordinary harness tools — `mcp__atlassian__searchJiraIssuesUsingJql`,
7
17
  `getJiraIssue`, `createJiraIssue`, `searchConfluenceUsingCql`, `getConfluencePage` —
8
18
  with the normal permission, approval and cancellation pipeline.
9
- - `atlassian_present` shows one issue, a shortlist or a set of Confluence pages as
10
- a card under the answer.
11
- - Clicking a row opens the issue in the harness's own right panel, where its status
12
- can be moved through the transitions the workflow offers and it can be handed to
13
- somebody else.
19
+ - `atlassian_present`: one issue, a shortlist, or Confluence pages as a card under
20
+ the agent's answer.
21
+ - A panel for the whole issue: description, comments, its transitions, and a
22
+ different assignee.
14
23
  - `/atlassian status|login|logout|sync`, and one tab on the Settings
15
24
  **Integrations** page.
16
25
 
17
- Configuration, overriding the row the bundle's patch inserts:
26
+ ## Configuration
27
+
28
+ The bundle inserts one row; override it in the profile's `cordis.patch.yml`:
18
29
 
19
30
  ```yaml
20
31
  - id: atlassian
@@ -24,5 +35,5 @@ Configuration, overriding the row the bundle's patch inserts:
24
35
  debug: false
25
36
  ```
26
37
 
27
- `redirectPort` is the first loopback port tried for the OAuth callback. `debug`
28
- logs the raw payload of every tool result.
38
+ `redirectPort` is the first loopback port tried for the OAuth callback; the next
39
+ free port is used if it is taken. `debug` logs the raw payload of every tool result.
package/lib/client.js CHANGED
@@ -202,6 +202,10 @@ var Chip = ({ label, value, tone = "outline" }) => {
202
202
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives.Tag, { tone, children: label === void 0 ? value : `${label}: ${value}` });
203
203
  };
204
204
 
205
+ // ../integration-host/src/status.ts
206
+ var CLIENT_REQUEST_HEADER = "x-dsh-client";
207
+ var CLIENT_REQUEST_VALUE = "1";
208
+
205
209
  // ../integration-ui/src/host-api.ts
206
210
  var createHostRequest = (basePath) => {
207
211
  const failureOf = async (response) => {
@@ -216,8 +220,12 @@ var createHostRequest = (basePath) => {
216
220
  return async (path, method, body, signal) => {
217
221
  const response = await fetch(`${basePath}${path}`, {
218
222
  method,
219
- headers: body === void 0 ? { accept: "application/json" } : { accept: "application/json", "content-type": "application/json" },
220
- ...body === void 0 ? {} : { body: JSON.stringify(body) },
223
+ headers: {
224
+ accept: "application/json",
225
+ [CLIENT_REQUEST_HEADER]: CLIENT_REQUEST_VALUE,
226
+ ...method === "POST" ? { "content-type": "application/json" } : {}
227
+ },
228
+ ...method === "POST" ? { body: JSON.stringify(body ?? {}) } : {},
221
229
  ...signal === void 0 ? {} : { signal }
222
230
  });
223
231
  if (!response.ok) throw new Error(await failureOf(response));
@@ -278,6 +286,10 @@ var createPanelBody = (provider2) => {
278
286
  (write) => {
279
287
  const wanted = current.current;
280
288
  if (wanted === void 0) return;
289
+ const stillWanted = () => {
290
+ const now = current.current;
291
+ return now !== void 0 && provider2.identity(now) === provider2.identity(wanted);
292
+ };
281
293
  setBusy(true);
282
294
  setFailure(void 0);
283
295
  write(wanted).then((answer) => {
@@ -286,9 +298,10 @@ var createPanelBody = (provider2) => {
286
298
  throw new Error(
287
299
  "the host answered with a document this version cannot draw"
288
300
  );
289
- setLoad({ status: "ready", data, params: wanted });
301
+ if (stillWanted())
302
+ setLoad({ status: "ready", data, params: wanted });
290
303
  }).catch((error2) => {
291
- setFailure(messageOf(error2));
304
+ if (stillWanted()) setFailure(messageOf(error2));
292
305
  void fetchPanel();
293
306
  }).finally(() => {
294
307
  setBusy(false);
@@ -385,6 +398,8 @@ var connectionState = (status) => {
385
398
  };
386
399
  var stateText = (status, credentials) => {
387
400
  if (status.inFlight === true) return "Connecting";
401
+ if (status.error != null && status.connected !== true)
402
+ return "Connection failed";
388
403
  if (credentials === "none")
389
404
  return status.connected === true ? "Connected" : "Not connected";
390
405
  return status.signedIn === true ? "Signed in" : "Not signed in";
@@ -786,10 +801,36 @@ function asPresentation(value) {
786
801
  ...typeof value.title === "string" && value.title !== "" ? { title: value.title } : {},
787
802
  layout,
788
803
  ...typeof value.total === "number" && Number.isFinite(value.total) && value.total > items.length ? { total: value.total } : {},
804
+ ...value.truncated === true ? { truncated: true } : {},
789
805
  items
790
806
  };
791
807
  }
792
808
 
809
+ // src/client/styles/styles.css.ts
810
+ var actions2 = "_9d1h6n8";
811
+ var badges = "_9d1h6n6";
812
+ var caption2 = "_9d1h6n7";
813
+ var comment = "d9jrn16";
814
+ var commentAuthor = "d9jrn18";
815
+ var commentHead = "d9jrn17";
816
+ var comments = "d9jrn15";
817
+ var item = "_9d1h6ni";
818
+ var itemHead = "_9d1h6nj";
819
+ var itemLink = "_9d1h6nl";
820
+ var itemText = "d9jrn10";
821
+ var link2 = "_9d1h6nn";
822
+ var panelBody = "d9jrn11";
823
+ var panelHead = "_9d1h6n12";
824
+ var panelKey = "_9d1h6n15";
825
+ var panelSection = "_9d1h6n17";
826
+ var panelSectionTitle = "_9d1h6n18";
827
+ var panelSummary = "_9d1h6n16";
828
+ var panelTitleRow = "_9d1h6n14";
829
+ var people = "d9jrn12";
830
+ var person = "d9jrn14";
831
+ var personSearch = "d9jrn13";
832
+ var row2 = "_9d1h6n9";
833
+
793
834
  // src/shared/tone.ts
794
835
  var TYPE_TONES = {
795
836
  bug: "danger",
@@ -886,31 +927,6 @@ var installPanelOpener = (ctx) => {
886
927
  };
887
928
  var openPanel = (target) => opener?.open(target) ?? false;
888
929
 
889
- // src/client/styles/styles.css.ts
890
- var actions2 = "_9d1h6n8";
891
- var badges = "_9d1h6n6";
892
- var caption2 = "_9d1h6n7";
893
- var comment = "d9jrn16";
894
- var commentAuthor = "d9jrn18";
895
- var commentHead = "d9jrn17";
896
- var comments = "d9jrn15";
897
- var item = "_9d1h6ni";
898
- var itemHead = "_9d1h6nj";
899
- var itemLink = "_9d1h6nl";
900
- var itemText = "d9jrn10";
901
- var link2 = "_9d1h6nn";
902
- var panelBody = "d9jrn11";
903
- var panelHead = "_9d1h6n12";
904
- var panelKey = "_9d1h6n15";
905
- var panelSection = "_9d1h6n17";
906
- var panelSectionTitle = "_9d1h6n18";
907
- var panelSummary = "_9d1h6n16";
908
- var panelTitleRow = "_9d1h6n14";
909
- var people = "d9jrn12";
910
- var person = "d9jrn14";
911
- var personSearch = "d9jrn13";
912
- var row2 = "_9d1h6n9";
913
-
914
930
  // src/client/components/issue-item.tsx
915
931
  var import_jsx_runtime6 = require("react/jsx-runtime");
916
932
  var IssueItem = ({ issue }) => {
@@ -1018,7 +1034,8 @@ var atlassianCard = {
1018
1034
  },
1019
1035
  item2.issue.key ?? `issue-${index}`
1020
1036
  ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PageItem, { page: item2.page }, item2.page.id ?? `page-${index}`)
1021
- )
1037
+ ),
1038
+ footer: (presentation2) => presentation2.truncated === true ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: caption2, children: "The search had more results than this card read." }) : null
1022
1039
  };
1023
1040
 
1024
1041
  // src/client/conversation/presentation-definition.ts
@@ -1412,6 +1429,7 @@ var Assignee = ({
1412
1429
  const trimmed = query.trim();
1413
1430
  if (trimmed.length < 2) {
1414
1431
  setPeople([]);
1432
+ setFetching(false);
1415
1433
  return;
1416
1434
  }
1417
1435
  const controller = new AbortController();