@assemblyline-agents/jira 2.0.0 → 3.0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 OpenEve contributors
3
+ Copyright (c) 2026 Assembly Line contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Official Assembly Line Jira connection plugin.
4
4
 
5
- It connects agents to Jira, exposing issue-tracking and project tools through Atlassian's MCP server. The package exports `defineJiraConnection(options)` to declare the connection in an agent definition and an `assemblyLinePlugin` module so the Assembly Line CLI and compiler can discover the plugin's connection metadata. A bundled skill under `skills/` teaches agents how to use the connection's tools.
5
+ It connects agents to Jira, exposing issue-tracking and project tools through Atlassian's MCP server. The package exports `defineJiraConnection(options)` to declare the connection in an agent definition and an `assemblyLinePlugin` module so the Assembly Line CLI and compiler can discover the plugin's connection metadata.
6
6
 
7
7
  ## Install
8
8
 
@@ -0,0 +1,3 @@
1
+ import { type ConnectionPluginEventAdapter } from "@assemblyline-agents/core";
2
+ export declare const jiraEvents: ConnectionPluginEventAdapter;
3
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,4BAA4B,EAElC,MAAM,2BAA2B,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,4BAgCxB,CAAC"}
package/dist/events.js ADDED
@@ -0,0 +1,49 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { ConnectionEventError, parseConnectionEventJson, providerJson, stringField } from "@assemblyline-agents/core";
3
+ export const jiraEvents = {
4
+ prepare(context) { return context.state?.verificationToken ? context.state : { ...(context.state ?? {}), verificationToken: randomBytes(32).toString("base64url") }; },
5
+ async reconcile(context) {
6
+ const resources = context.resources.map(jiraResource);
7
+ if (!resources.length)
8
+ return { status: "needs_setup", ...(context.state ? { state: context.state } : {}), instructions: "Add Jira event resources with baseUrl and jql." };
9
+ const baseUrl = resources[0].baseUrl;
10
+ if (resources.some((resource) => resource.baseUrl !== baseUrl))
11
+ throw new Error("One Jira connection event binding cannot span multiple Jira sites.");
12
+ const token = (await context.getToken()).token;
13
+ const priorIds = webhookIds(context.state);
14
+ if (priorIds.length)
15
+ await providerJson(context.fetch, `${baseUrl}/rest/api/3/webhook`, { method: "DELETE", headers: auth(token), body: JSON.stringify({ webhookIds: priorIds.map(Number) }) }, [200, 202, 204, 404]);
16
+ const verificationToken = required(context.state ?? {}, "verificationToken");
17
+ const value = await providerJson(context.fetch, `${baseUrl}/rest/api/3/webhook`, {
18
+ method: "POST", headers: auth(token), body: JSON.stringify({ url: `${context.callbackUrl}?token=${encodeURIComponent(verificationToken)}`, webhooks: resources.map((resource) => ({ events: context.selectedEvents, jqlFilter: resource.jql })) })
19
+ });
20
+ const results = Array.isArray(value.webhookRegistrationResult) ? value.webhookRegistrationResult : [];
21
+ const ids = results.flatMap((item) => item && typeof item === "object" && !Array.isArray(item) && item.createdWebhookId !== undefined ? [String(item.createdWebhookId)] : []);
22
+ if (ids.length !== resources.length)
23
+ throw new Error(`Jira created ${ids.length} of ${resources.length} requested webhooks.`);
24
+ const expiresAt = new Date(Date.now() + 29 * 24 * 60 * 60_000).toISOString();
25
+ return { status: "active", externalId: ids.join(","), state: { verificationToken, baseUrl, webhookIds: ids }, expiresAt, detail: `${ids.length} Jira webhook${ids.length === 1 ? " is" : "s are"} active.` };
26
+ },
27
+ async remove(context) { const ids = webhookIds(context.state); const baseUrl = stringField(context.state ?? {}, "baseUrl"); if (!ids.length || !baseUrl)
28
+ return; await providerJson(context.fetch, `${baseUrl}/rest/api/3/webhook`, { method: "DELETE", headers: auth((await context.getToken()).token), body: JSON.stringify({ webhookIds: ids.map(Number) }) }, [200, 202, 204, 404]); },
29
+ check(context) { return webhookIds(context.state).length ? { status: "active", detail: "Jira dynamic webhooks are configured." } : { status: "needs_setup", detail: "Jira dynamic webhooks are not configured." }; },
30
+ ingress(request, context) {
31
+ if (request.query.token !== stringField(context.state ?? {}, "verificationToken"))
32
+ throw new ConnectionEventError("Jira webhook verification token is invalid.", 401);
33
+ const payload = parseConnectionEventJson(request.body);
34
+ const event = stringField(payload, "webhookEvent");
35
+ if (!event)
36
+ throw new ConnectionEventError("Jira webhook omitted webhookEvent.");
37
+ const occurred = payload.timestamp;
38
+ const occurredAt = typeof occurred === "number" ? new Date(occurred).toISOString() : undefined;
39
+ const eventId = createHash("sha256").update(request.body).digest("hex");
40
+ return { events: [{ event, eventId, payload: payload, ...(occurredAt ? { occurredAt } : {}) }], response: { status: 200, body: { ok: true } }, audit: { event } };
41
+ }
42
+ };
43
+ function jiraResource(resource) { const baseUrl = stringField(resource, "baseUrl")?.replace(/\/+$/u, ""); const jql = stringField(resource, "jql"); if (!baseUrl || !jql)
44
+ throw new Error("Jira event resources require baseUrl and jql."); return { baseUrl, jql }; }
45
+ function webhookIds(state) { return Array.isArray(state?.webhookIds) ? state.webhookIds.filter((value) => typeof value === "string") : []; }
46
+ function auth(token) { return { authorization: `Bearer ${token}`, "content-type": "application/json" }; }
47
+ function required(value, name) { const result = stringField(value, name); if (!result)
48
+ throw new Error(`Jira event state omitted ${name}.`); return result; }
49
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,YAAY,EACZ,WAAW,EAGZ,MAAM,2BAA2B,CAAC;AAEnC,MAAM,CAAC,MAAM,UAAU,GAAiC;IACtD,OAAO,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,iBAAiB,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACtK,KAAK,CAAC,SAAS,CAAC,OAAO;QACrB,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,gDAAgD,EAAE,CAAC;QAC5K,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC;QACtC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACtJ,MAAM,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;QAC/C,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,QAAQ,CAAC,MAAM;YAAE,MAAM,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,qBAAqB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACtN,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,qBAAqB,EAAE;YAC/E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,UAAU,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;SACnP,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;QACtG,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,IAAgC,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAE,IAAgC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxO,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,MAAM,OAAO,SAAS,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAC9H,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,CAAC;IAC/M,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,qBAAqB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1X,KAAK,CAAC,OAAO,IAAI,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,uCAAuC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,2CAA2C,EAAE,CAAC,CAAC,CAAC;IACpN,OAAO,CAAC,OAAO,EAAE,OAAO;QACtB,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,WAAW,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,mBAAmB,CAAC;YAAE,MAAM,IAAI,oBAAoB,CAAC,6CAA6C,EAAE,GAAG,CAAC,CAAC;QACtK,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,oBAAoB,CAAC,oCAAoC,CAAC,CAAC;QACjF,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,MAAM,UAAU,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/F,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAqB,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;IAClL,CAAC;CACF,CAAC;AAEF,SAAS,YAAY,CAAC,QAAoB,IAAsC,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG;IAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AACpT,SAAS,UAAU,CAAC,KAA6B,IAAc,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/L,SAAS,IAAI,CAAC,KAAa,IAA4B,OAAO,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;AACzI,SAAS,QAAQ,CAAC,KAA8B,EAAE,IAAY,IAAY,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;IAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAE/I,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAC/D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,yEAAwD;AAC3H,eAAO,MAAM,kBAAkB,kDAA0C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmG,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAG7K,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAC/D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,yEAAgN;AACnR,eAAO,MAAM,kBAAkB,kDAA0C,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
- import { connectionPluginMetadata, defineMcpPluginConnection, definePlugin } from "@assemblyline-agents/core";
1
+ import { connectionPluginMetadata, defineConnectionPluginEvents, defineMcpPluginConnection, definePlugin } from "@assemblyline-agents/core";
2
+ import { jiraEvents } from "./events.js";
2
3
  const PLUGIN = connectionPluginMetadata("jira");
3
- export function defineJiraConnection(options) { return defineMcpPluginConnection(PLUGIN, options); }
4
+ export function defineJiraConnection(options) { const definition = defineMcpPluginConnection(PLUGIN, options); const events = defineConnectionPluginEvents(PLUGIN, options.events, jiraEvents); if (events)
5
+ definition.events = events; return definition; }
4
6
  export const assemblyLinePlugin = definePlugin({ connections: [PLUGIN] });
5
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,YAAY,EAAmC,MAAM,2BAA2B,CAAC;AAC/I,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,CAAE,CAAC;AAEjD,MAAM,UAAU,oBAAoB,CAAC,OAA8B,IAAI,OAAO,yBAAyB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3H,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,YAAY,EAAmC,MAAM,2BAA2B,CAAC;AAC7K,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,CAAE,CAAC;AAEjD,MAAM,UAAU,oBAAoB,CAAC,OAA8B,IAAI,MAAM,UAAU,GAAG,yBAAyB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,GAAG,4BAA4B,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,MAAM;IAAE,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC;AACnR,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assemblyline-agents/jira",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -9,12 +9,11 @@
9
9
  }
10
10
  },
11
11
  "dependencies": {
12
- "@assemblyline-agents/core": "2.0.0"
12
+ "@assemblyline-agents/core": "3.0.0"
13
13
  },
14
14
  "description": "Official Assembly Line Jira connection plugin.",
15
15
  "files": [
16
- "dist",
17
- "skills"
16
+ "dist"
18
17
  ],
19
18
  "engines": {
20
19
  "node": ">=22.19.0"
@@ -1,8 +0,0 @@
1
- ---
2
- name: jira
3
- description: Use configured Jira tools for issues, projects, transitions, users, and JQL search.
4
- ---
5
- # Jira
6
- Prefer bounded JQL and fetch exact issues only after identifying their keys. Read transition metadata before proposing workflow changes.
7
-
8
- The deployment owner configures Atlassian authorization. The scaffold is read-only; creating, editing, commenting, logging work, or transitioning issues requires writes to be enabled with the configured approval gate.