@kendoo.agentdesk/agentdesk 0.18.0 → 0.18.1
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/CHANGELOG.md +5 -0
- package/cli/tracker-check.mjs +24 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,11 @@ All user-facing changes to AgentDesk. Each entry is tagged:
|
|
|
8
8
|
|
|
9
9
|
Internal refactors, infrastructure changes, and architectural notes are not listed here.
|
|
10
10
|
|
|
11
|
+
## [0.18.1] — 2026-04-18
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- `[CLI]` Jira permission check now trims a trailing slash from the stored base URL (a leftover double-slash could produce a spurious 404) and falls back to REST API v2 if v3 isn't exposed. The error message now includes the exact URL called so misconfigs are easier to diagnose.
|
|
15
|
+
|
|
11
16
|
## [0.18.0] — 2026-04-18
|
|
12
17
|
|
|
13
18
|
### Changed
|
package/cli/tracker-check.mjs
CHANGED
|
@@ -94,9 +94,13 @@ async function checkJira({ baseUrl, project }, creds) {
|
|
|
94
94
|
let identity = null;
|
|
95
95
|
const auth = "Basic " + Buffer.from(`${email}:${token}`).toString("base64");
|
|
96
96
|
|
|
97
|
+
// Normalize the base URL: trim trailing slashes, so `...net/` doesn't
|
|
98
|
+
// produce `...net//rest/...` which some Atlassian paths reject.
|
|
99
|
+
const cleanBase = String(baseUrl || "").replace(/\/+$/, "");
|
|
100
|
+
|
|
97
101
|
// Fetch the authenticated user so we can report "Posting as X".
|
|
98
102
|
try {
|
|
99
|
-
const meRes = await fetch(`${
|
|
103
|
+
const meRes = await fetch(`${cleanBase}/rest/api/3/myself`, {
|
|
100
104
|
headers: { Authorization: auth, Accept: "application/json" },
|
|
101
105
|
signal: AbortSignal.timeout(10000),
|
|
102
106
|
});
|
|
@@ -106,15 +110,24 @@ async function checkJira({ baseUrl, project }, creds) {
|
|
|
106
110
|
}
|
|
107
111
|
} catch {}
|
|
108
112
|
|
|
109
|
-
// Use Jira's mypermissions endpoint to check all permissions at once
|
|
113
|
+
// Use Jira's mypermissions endpoint to check all permissions at once.
|
|
114
|
+
// Try REST v3 first (Jira Cloud), fall back to v2 on 404 (older tenants /
|
|
115
|
+
// Data Center installs where v3 isn't exposed).
|
|
110
116
|
const permissionsToCheck = "BROWSE_PROJECTS,CREATE_ISSUES,EDIT_ISSUES,ADD_COMMENTS,TRANSITION_ISSUES";
|
|
117
|
+
const tryVersions = ["3", "2"];
|
|
118
|
+
let res = null;
|
|
119
|
+
let lastUrl = "";
|
|
111
120
|
try {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
for (const v of tryVersions) {
|
|
122
|
+
const url = `${cleanBase}/rest/api/${v}/mypermissions?permissions=${permissionsToCheck}` +
|
|
123
|
+
(project ? `&projectKey=${project}` : "");
|
|
124
|
+
lastUrl = url;
|
|
125
|
+
res = await fetch(url, {
|
|
126
|
+
headers: { Authorization: auth, Accept: "application/json" },
|
|
127
|
+
signal: AbortSignal.timeout(10000),
|
|
128
|
+
});
|
|
129
|
+
if (res.status !== 404) break;
|
|
130
|
+
}
|
|
118
131
|
|
|
119
132
|
if (res.status === 401) {
|
|
120
133
|
return { ok: false, errors: ["Jira authentication failed — check JIRA_EMAIL and JIRA_API_TOKEN"] };
|
|
@@ -123,7 +136,7 @@ async function checkJira({ baseUrl, project }, creds) {
|
|
|
123
136
|
return { ok: false, errors: ["Jira access forbidden — your account may lack access to this project"] };
|
|
124
137
|
}
|
|
125
138
|
if (!res.ok) {
|
|
126
|
-
return { ok: false, errors: [`Jira API error (${res.status}) — check
|
|
139
|
+
return { ok: false, errors: [`Jira API error (${res.status}) calling ${lastUrl} — check that the base URL is the Atlassian tenant root (e.g. https://yourco.atlassian.net) without a path.`] };
|
|
127
140
|
}
|
|
128
141
|
|
|
129
142
|
const data = await res.json();
|
|
@@ -144,9 +157,9 @@ async function checkJira({ baseUrl, project }, creds) {
|
|
|
144
157
|
}
|
|
145
158
|
} catch (e) {
|
|
146
159
|
if (e.name === "AbortError" || e.name === "TimeoutError") {
|
|
147
|
-
return { ok: false, errors: [`Cannot reach Jira at ${
|
|
160
|
+
return { ok: false, errors: [`Cannot reach Jira at ${cleanBase} — request timed out`] };
|
|
148
161
|
}
|
|
149
|
-
return { ok: false, errors: [`Cannot reach Jira at ${
|
|
162
|
+
return { ok: false, errors: [`Cannot reach Jira at ${cleanBase}: ${e.message}`] };
|
|
150
163
|
}
|
|
151
164
|
|
|
152
165
|
return { ok: errors.length === 0, errors, identity };
|