@aholbreich/agent-skills 0.9.0 → 1.1.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.
Files changed (29) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/README.md +85 -13
  3. package/bin/agent-skills.js +11 -5
  4. package/bin/check.js +80 -0
  5. package/bin/vendor.js +24 -0
  6. package/package.json +6 -3
  7. package/skills/bitbucket-browser-fetch/SKILL.md +14 -0
  8. package/skills/bitbucket-browser-fetch/scripts/atlassian-browser.js +261 -0
  9. package/skills/bitbucket-browser-fetch/scripts/bitbucket-browser-fetch.js +20 -201
  10. package/skills/confluence-browser-fetch/SKILL.md +15 -4
  11. package/skills/confluence-browser-fetch/references/distribution.md +5 -1
  12. package/skills/confluence-browser-fetch/references/usage.md +2 -2
  13. package/skills/confluence-browser-fetch/scripts/atlassian-browser.js +261 -0
  14. package/skills/confluence-browser-fetch/scripts/confluence-browser-fetch.js +32 -215
  15. package/skills/confluence-update/SKILL.md +13 -2
  16. package/skills/confluence-update/references/usage.md +2 -2
  17. package/skills/confluence-update/scripts/atlassian-browser.js +261 -0
  18. package/skills/confluence-update/scripts/confluence-update.js +144 -257
  19. package/skills/jira-browser-fetch/SKILL.md +15 -3
  20. package/skills/jira-browser-fetch/references/distribution.md +5 -1
  21. package/skills/jira-browser-fetch/scripts/atlassian-browser.js +261 -0
  22. package/skills/jira-browser-fetch/scripts/jira-browser-fetch.js +58 -232
  23. package/skills/jira-browser-fetch/scripts/lib.js +26 -0
  24. package/skills/jira-update/SKILL.md +132 -0
  25. package/skills/jira-update/references/distribution.md +5 -0
  26. package/skills/jira-update/references/usage.md +75 -0
  27. package/skills/jira-update/scripts/atlassian-browser.js +261 -0
  28. package/skills/jira-update/scripts/jira-update.js +505 -0
  29. package/skills/jira-update/scripts/lib.js +291 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,49 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 1.1.0 - 2026-05-11
4
+
5
+ Added:
6
+
7
+ - `jira-browser-fetch --skip-existing` skips issues that already have a valid `raw/<KEY>/issue.json`, reading the saved `connected-keys.json` so `--connected --scan-text` traversal still resumes correctly.
8
+ - `jira-browser-fetch` prints aggregate progress (`[N/total] pct%`) and a trailing ETA line during multi-issue runs.
9
+ - `confluence-update` and `confluence-browser-fetch` emit a clearer error when Confluence probes return 404. After all wikiBase probes 404, the verifier does one sanity probe against the Jira API at the same site root; if that succeeds, the error specifically says "cookies are valid for ${site} but Confluence at ${wikiBase} returned 404", pointing to either a wrong `--site` or a tenant without Confluence enabled.
10
+ - README gains a "Project status" section flagging the opinionated browser-only auth approach, Linux-Fedora-only end-to-end testing, and a feedback request.
11
+ - Every SKILL.md's "Shared Atlassian SSO Session" section now teaches calling agents three things: (i) the script-Chrome is a separate window from the user's regular browser, cookies from the user's Chrome are not read; (ii) reuse signal — `Reusing Chrome DevTools on port 9223` / `Found existing tab for <host>` means do not re-prompt SSO; (iii) `CHROME=/path/to/launcher` env var for Flatpak/Snap/non-PATH installs. The Typical Workflow's SSO step is clarified to be first-run-or-expired-only.
12
+
13
+ Changed:
14
+
15
+ - The "Reuse one Atlassian browser login" section in README now reflects the unified-defaults behavior — no env vars required for the default sharing.
16
+ - **Unified Chrome profile and DevTools port across all five Atlassian skills.** Defaults are now `~/.local/share/atlassian-browser-chrome` and port `9223` for `jira-browser-fetch`, `jira-update`, `confluence-browser-fetch`, `confluence-update`, and `bitbucket-browser-fetch`. One SSO login persists across all skills — no env vars required. Skill-specific `*_CHROME_PROFILE` / `*_CHROME_DEBUG_PORT` env vars still override for isolation. Each SKILL.md gains a "Shared Atlassian SSO Session" section near the top.
17
+ - `confluence-update` and `confluence-browser-fetch` now strip a trailing `/wiki` from `--site` (or `CONFLUENCE_SITE`) with a stderr note, instead of building the unreachable `…/wiki/wiki` URL.
18
+ - Replaced the 19-step `npm run check` chain with a `bin/check.js` script that auto-discovers `bin/`, `lib/`, and every `skills/*/scripts/` JS file. Aggregates failures (no longer stops at the first error) and prints a summary line. New skills/scripts are picked up automatically with no `package.json` edit.
19
+
20
+ Migration:
21
+
22
+ - Users who previously logged in via the old per-skill profiles (`~/.local/share/jira-browser-fetch-chrome`, `confluence-browser-fetch-chrome`, `bitbucket-browser-fetch-chrome`) will hit a fresh login on first run after upgrade. To preserve the existing session, move whichever profile you used: `mv ~/.local/share/jira-browser-fetch-chrome ~/.local/share/atlassian-browser-chrome` (only one — pick the one with your live cookies). Or just re-SSO once; the new shared profile then serves all five skills.
23
+
24
+ ## 1.0.1 - 2026-05-09
25
+
26
+ Added:
27
+
28
+ - `jira-update <command> --help` and `confluence-update <command> --help` now print command-specific options instead of falling back to top-level usage.
29
+ - `jira-update transition --help` documents the `--field key=value` heuristics (`priority`/`resolution`/`status` wrap as `{name: VALUE}`; `labels`/`components`/`fixVersions` split on commas; everything else passes through as a string).
30
+ - `jira-update` validates issue keys client-side (`PROJ-123` form). `comment`, `transition`, `update-fields`, `link <FROM>`, and `link --to <TO>` fail fast with exit 2 instead of round-tripping a bad key through SSO and the Jira REST API.
31
+
32
+ Changed:
33
+
34
+ - `jira-update` validation errors (missing manifest fields, unresolved transitions/link types, bad representation) now exit 2 with a clean `error: ...` message instead of dumping a Node stack trace and exiting 1. Implemented via a new `UsageError` class in `skills/jira-update/scripts/lib.js`.
35
+
36
+ ## 1.0.0 - 2026-05-08
37
+
38
+ Added:
39
+
40
+ - New `jira-update` skill for dry-run-first Jira Cloud writes through an authenticated browser session: `create`, `comment`, `transition`, `update-fields`, and `link` commands. Markdown-to-ADF conversion by default; ADF passthrough as escape hatch.
41
+
42
+ Changed:
43
+
44
+ - Extracted browser/CDP/cookie helpers from all four existing skills into a single source-of-truth `lib/atlassian-browser.js`. Vendored at pack time into each `skills/*/scripts/atlassian-browser.js` so each skill folder remains self-contained on disk. Eliminates ~870 lines of duplicated code across the bundle.
45
+
46
+ ## 0.9.0 - 2026-05-07
4
47
 
5
48
  Added:
6
49
 
package/README.md CHANGED
@@ -1,14 +1,31 @@
1
1
  # Agent Skills
2
2
 
3
- Handcrafted [Agent Skills](https://agentskills.io/) for developer and LLM-wiki workflows. The package is intentionally a pure skills package with broad compatibility across Pi, Claude Code, Codex, OpenClaw/generic `.agents` setups, and other Agent Skills-compatible harnesses.
3
+ **Browser-authenticated Atlassian write surface for SSO-locked organizations.** Five [Agent Skills](https://agentskills.io/) covering Jira read+write, Confluence read+write, and Bitbucket read designed for orgs where Microsoft/SSO blocks API-token use.
4
4
 
5
- This repository is a pure skills package. It currently contains browser-authenticated Atlassian fetch/update tools that work well when Jira/Confluence/Bitbucket API-token authentication is unavailable because an organization uses Microsoft/SSO.
5
+ The package is a pure Agent Skills bundle, compatible with Pi, Claude Code, Codex, OpenClaw / generic `.agents` setups, and other Agent Skills-compatible harnesses.
6
+
7
+ ## Why this exists
8
+
9
+ Most Atlassian automation tools assume API tokens. In SSO-locked enterprises, API tokens are often disabled or restricted in ways that make scripted writes painful. These skills route through an authenticated **browser session** instead — you log in to Jira/Confluence/Bitbucket once in Chrome, and the skills replay your cookies via DevTools to make REST calls. No API token required.
10
+
11
+ Beyond the SSO bypass, the skills are built around three differentiators:
12
+
13
+ - **Dry-run-first writes.** Every write command (`jira-update create`, `confluence-update replace-block`, etc.) emits a full audit folder under `raw/` first. You only get a real write when you re-run with `--apply`. Each audit folder contains the proposed payload, the before-state, and a diff summary — review exactly what would happen before it does.
14
+ - **Markdown → ADF conversion.** `jira-update` converts Markdown to Atlassian Document Format (Jira Cloud's structured rich-text representation), so agents write descriptions, comments, and transitions in a familiar format without hand-rolling ADF JSON.
15
+ - **Shared browser session.** All Atlassian skills can reuse a single Chrome profile + DevTools port, so you log in once and every fetch/update skill rides the same SSO session.
16
+
17
+ ## Project status
18
+
19
+ Opinionated bundle: SSO browser-session auth only, no API tokens or app passwords. The whole stack is built around extracting Chrome cookies via the DevTools Protocol — if API tokens already work for your org, you do not need this. All five Atlassian skills share one Chrome profile (`~/.local/share/atlassian-browser-chrome`) and DevTools port (`9223`) by default; log in once and the others reuse the session.
20
+
21
+ **Tested on Linux (Fedora) at the moment.** macOS browser paths exist in the auto-detection logic but are not end-to-end verified; Windows is unsupported. Reports of what works on other distros or OSes are very welcome — open an issue or PR at [github.com/aholbreich/agent-skills/issues](https://github.com/aholbreich/agent-skills/issues). Feedback on SSO flavors, browser detection, profile/port collisions, and unusual Atlassian tenant shapes is especially useful.
6
22
 
7
23
  ## Skills
8
24
 
9
25
  | Skill | Purpose |
10
26
  |---|---|
11
27
  | [`jira-browser-fetch`](skills/jira-browser-fetch/) | Fetch Jira issue JSON, rendered HTML/XML, linked/referenced issues, Jira Software board backlogs, JQL result sets, and attachments through an authenticated Chrome session. |
28
+ | [`jira-update`](skills/jira-update/) | Dry-run-first Jira Cloud writes through an authenticated browser session: create issues, add comments, transition workflows, update fields, and link issues. Markdown-to-ADF conversion by default; ADF passthrough as escape hatch. |
12
29
  | [`confluence-browser-fetch`](skills/confluence-browser-fetch/) | Fetch Confluence page JSON, storage/view HTML, browser HTML, descendants, CQL result sets, and attachments through an authenticated Chrome session. |
13
30
  | [`confluence-update`](skills/confluence-update/) | Dry-run-first Confluence page updates, agent-owned block replacement, Markdown-to-storage conversion, and page creation through an authenticated browser session. |
14
31
  | [`bitbucket-browser-fetch`](skills/bitbucket-browser-fetch/) | Fetch Bitbucket Cloud project repository inventories and clone URL lists through an authenticated browser session. |
@@ -101,18 +118,22 @@ npx @aholbreich/agent-skills
101
118
  Install for a specific target:
102
119
 
103
120
  ```bash
104
- npx @aholbreich/agent-skills install --target agents
105
- npx @aholbreich/agent-skills install --target claude
106
- npx @aholbreich/agent-skills install --target codex
107
- npx @aholbreich/agent-skills install --target project
121
+ npx @aholbreich/agent-skills install --target agents # ~/.agents/skills (default)
122
+ npx @aholbreich/agent-skills install --target claude # ~/.claude/skills
123
+ npx @aholbreich/agent-skills install --target codex # ~/.codex/skills
124
+ npx @aholbreich/agent-skills install --target pi # ~/.pi/agent/skills
125
+ npx @aholbreich/agent-skills install --target project-agents # ./.agents/skills
126
+ npx @aholbreich/agent-skills install --target project-pi # ./.pi/skills
108
127
  ```
109
128
 
129
+ The bare `--target project` is a deprecated alias for `--target project-pi`; use the explicit form. Run `npx @aholbreich/agent-skills paths` to see every target's full path.
130
+
110
131
  Install only selected skills:
111
132
 
112
133
  ```bash
113
134
  npx @aholbreich/agent-skills install --skill jira-browser-fetch
114
135
  npx @aholbreich/agent-skills install --skill confluence-browser-fetch
115
- npx @aholbreich/agent-skills install --skill jira-browser-fetch --target project
136
+ npx @aholbreich/agent-skills install --skill jira-browser-fetch --target project-agents
116
137
  ```
117
138
 
118
139
  Or use the dependency-free interactive picker:
@@ -176,6 +197,7 @@ If installed globally via npm, the package exposes:
176
197
  ```bash
177
198
  agent-skills
178
199
  jira-browser-fetch
200
+ jira-update
179
201
  confluence-browser-fetch
180
202
  confluence-update
181
203
  bitbucket-browser-fetch
@@ -183,14 +205,16 @@ bitbucket-browser-fetch
183
205
 
184
206
  ## Reuse one Atlassian browser login
185
207
 
186
- To avoid separate Jira and Confluence SSO prompts, use one shared automation profile and DevTools port for both fetchers:
208
+ All five skills share one Chrome profile (`~/.local/share/atlassian-browser-chrome`) and DevTools port (`9223`) by default. Log in once via any skill and the others ride the same SSO session — no env vars required.
209
+
210
+ To relocate the shared profile or run on a different port:
187
211
 
188
212
  ```bash
189
- export ATLASSIAN_CHROME_PROFILE="$HOME/.local/share/atlassian-browser-fetch-chrome"
190
- export ATLASSIAN_CHROME_DEBUG_PORT=9223
213
+ export ATLASSIAN_CHROME_PROFILE="$HOME/some/other/path"
214
+ export ATLASSIAN_CHROME_DEBUG_PORT=9333
191
215
  ```
192
216
 
193
- Skill-specific variables such as `JIRA_CHROME_PROFILE`, `CONFLUENCE_CHROME_PROFILE`, or `BITBUCKET_CHROME_PROFILE` still override the shared profile when needed.
217
+ Skill-specific variables (`JIRA_CHROME_PROFILE`, `CONFLUENCE_CHROME_PROFILE`, `BITBUCKET_CHROME_PROFILE`, and the matching `*_CHROME_DEBUG_PORT`) override the shared values when you intentionally want skill isolation.
194
218
 
195
219
  ## Bitbucket examples
196
220
 
@@ -281,6 +305,54 @@ Example user requests that should invoke this skill:
281
305
  - "Pull my assigned Jira issues without asking me for an API token."
282
306
  - "Use this JQL and store the raw Jira evidence under the wiki raw folder."
283
307
 
308
+ ## Jira update examples
309
+
310
+ Dry-run an issue creation from a manifest:
311
+
312
+ ```bash
313
+ jira-update create \
314
+ --server https://example.atlassian.net \
315
+ --file ./new-bug.json
316
+ ```
317
+
318
+ Apply after review:
319
+
320
+ ```bash
321
+ jira-update create \
322
+ --server https://example.atlassian.net \
323
+ --file ./new-bug.json \
324
+ --apply
325
+ ```
326
+
327
+ Add a comment from Markdown:
328
+
329
+ ```bash
330
+ jira-update comment PROJ-123 \
331
+ --server https://example.atlassian.net \
332
+ --file ./reply.md \
333
+ --apply
334
+ ```
335
+
336
+ Transition with a comment:
337
+
338
+ ```bash
339
+ jira-update transition PROJ-123 \
340
+ --server https://example.atlassian.net \
341
+ --to "In Progress" \
342
+ --comment-file ./status.md \
343
+ --apply
344
+ ```
345
+
346
+ Link two issues:
347
+
348
+ ```bash
349
+ jira-update link PROJ-123 \
350
+ --server https://example.atlassian.net \
351
+ --to PROJ-456 \
352
+ --type blocks \
353
+ --apply
354
+ ```
355
+
284
356
  ## Confluence examples
285
357
 
286
358
  Fetch one page by URL:
@@ -325,9 +397,9 @@ Disable the limit:
325
397
  --max-attachment-size unlimited
326
398
  ```
327
399
 
328
- ## Output and LLM wiki use
400
+ ## Example workflow: populating an LLM wiki
329
401
 
330
- The tools are designed to populate a wiki `raw/` folder. They do not synthesize pages themselves. A typical LLM wiki workflow is:
402
+ One common use case for the fetch skills is feeding an LLM-curated knowledge base. The tools populate a `raw/` evidence folder; they do not synthesize pages themselves. A typical pipeline:
331
403
 
332
404
  1. fetch Jira/Confluence sources into `raw/`,
333
405
  2. treat `raw/` as immutable evidence,
@@ -40,7 +40,10 @@ Commands:
40
40
  help Show this help
41
41
 
42
42
  Options for install:
43
- --target NAME pi | agents | claude | codex | openclaw | project | project-agents | project-claude | project-codex (default: agents)
43
+ --target NAME Install destination (default: agents). Run "agent-skills paths" for full paths.
44
+ User-scoped: pi | agents | claude | codex | openclaw
45
+ Project-scoped: project-pi | project-agents | project-claude | project-codex
46
+ Deprecated: project (alias for project-pi)
44
47
  --dir PATH Custom skills directory, overrides --target
45
48
  --skill NAME Install only selected skill(s); repeatable, comma-separated, or '*' for all
46
49
  --pick Interactively choose which bundled skills to install
@@ -54,10 +57,10 @@ Examples:
54
57
  npx @aholbreich/agent-skills install --pick
55
58
  npx @aholbreich/agent-skills install --target agents --force
56
59
  npx @aholbreich/agent-skills install --target pi --force
57
- npx @aholbreich/agent-skills install --target project
60
+ npx @aholbreich/agent-skills install --target project-agents
61
+ npx @aholbreich/agent-skills install --target project-pi
58
62
  npx @aholbreich/agent-skills install --target claude
59
63
  npx @aholbreich/agent-skills install --target codex
60
- npx @aholbreich/agent-skills install --target agents
61
64
  npx @aholbreich/agent-skills install --dir ~/.pi/agent/skills
62
65
  npx @aholbreich/agent-skills list
63
66
 
@@ -160,6 +163,9 @@ async function install(args) {
160
163
  if (!customDir && !TARGETS[target]) {
161
164
  throw new Error(`Unknown target '${target}'. Valid targets: ${Object.keys(TARGETS).join(', ')}`);
162
165
  }
166
+ if (target === 'project' && !customDir) {
167
+ console.warn('warning: --target project is deprecated; it maps to ./.pi/skills. Use --target project-pi for the same path or --target project-agents for ./.agents/skills.');
168
+ }
163
169
  if (pick && skillFilters.length) {
164
170
  throw new Error('Use either --pick or --skill, not both');
165
171
  }
@@ -193,9 +199,9 @@ async function install(args) {
193
199
  }
194
200
 
195
201
  console.log(`Done. Installed: ${installed}. Skipped: ${skipped}.`);
196
- if (target.startsWith('project') && !customDir) {
202
+ if ((target === 'project' || target.startsWith('project-')) && !customDir) {
197
203
  console.log('Project-local skills are available when running an Agent Skills-compatible tool inside this project.');
198
- } else if (target === 'pi' && !customDir) {
204
+ } else if ((target === 'pi' || target === 'project-pi') && !customDir) {
199
205
  console.log('Restart Pi or start a new session to discover newly installed skills.');
200
206
  }
201
207
  }
package/bin/check.js ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { spawnSync } = require('node:child_process');
5
+ const fsp = require('node:fs/promises');
6
+ const path = require('node:path');
7
+
8
+ const repoRoot = path.resolve(__dirname, '..');
9
+
10
+ async function listJsFiles(dir) {
11
+ let entries;
12
+ try {
13
+ entries = await fsp.readdir(dir, { withFileTypes: true });
14
+ } catch (err) {
15
+ if (err.code === 'ENOENT') return [];
16
+ throw err;
17
+ }
18
+ const out = [];
19
+ for (const entry of entries) {
20
+ const full = path.join(dir, entry.name);
21
+ if (entry.isDirectory()) out.push(...await listJsFiles(full));
22
+ else if (entry.isFile() && entry.name.endsWith('.js')) out.push(full);
23
+ }
24
+ return out;
25
+ }
26
+
27
+ async function collectTargets() {
28
+ const files = [];
29
+ for (const d of ['bin', 'lib']) files.push(...await listJsFiles(path.join(repoRoot, d)));
30
+ const skillsDir = path.join(repoRoot, 'skills');
31
+ for (const entry of await fsp.readdir(skillsDir, { withFileTypes: true })) {
32
+ if (!entry.isDirectory()) continue;
33
+ files.push(...await listJsFiles(path.join(skillsDir, entry.name, 'scripts')));
34
+ }
35
+ return files.sort();
36
+ }
37
+
38
+ async function main() {
39
+ const verbose = process.argv.includes('--verbose');
40
+ const skipVendor = process.argv.includes('--no-vendor');
41
+
42
+ if (!skipVendor) {
43
+ const vendor = spawnSync(process.execPath, [path.join(repoRoot, 'bin/vendor.js')], { stdio: 'inherit' });
44
+ if (vendor.status !== 0) process.exit(vendor.status || 1);
45
+ }
46
+
47
+ const targets = await collectTargets();
48
+ const failures = [];
49
+ const start = Date.now();
50
+ for (const file of targets) {
51
+ const rel = path.relative(repoRoot, file);
52
+ const result = spawnSync(process.execPath, ['--check', file], { encoding: 'utf8' });
53
+ if (result.status === 0) {
54
+ if (verbose) console.log(`ok ${rel}`);
55
+ } else {
56
+ console.error(`FAIL ${rel}`);
57
+ failures.push({ rel, stderr: result.stderr });
58
+ }
59
+ }
60
+ const ms = Date.now() - start;
61
+
62
+ if (failures.length) {
63
+ console.error(`\n${failures.length} file(s) failed syntax check:`);
64
+ for (const f of failures) {
65
+ console.error(`\n--- ${f.rel} ---`);
66
+ console.error(f.stderr.trim());
67
+ }
68
+ process.exit(1);
69
+ }
70
+ console.log(`Syntax-checked ${targets.length} file(s) in ${ms}ms.`);
71
+ }
72
+
73
+ module.exports = { collectTargets, listJsFiles };
74
+
75
+ if (require.main === module) {
76
+ main().catch(err => {
77
+ console.error(err.stack || err.message);
78
+ process.exit(1);
79
+ });
80
+ }
package/bin/vendor.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+
7
+ const repoRoot = path.resolve(__dirname, '..');
8
+ const source = path.join(repoRoot, 'lib/atlassian-browser.js');
9
+ const skillsDir = path.join(repoRoot, 'skills');
10
+
11
+ if (!fs.existsSync(source)) {
12
+ console.error(`vendor: source not found at ${source}`);
13
+ process.exit(1);
14
+ }
15
+
16
+ const content = fs.readFileSync(source);
17
+ const skills = fs.readdirSync(skillsDir, { withFileTypes: true }).filter(d => d.isDirectory());
18
+ for (const skill of skills) {
19
+ const scriptsDir = path.join(skillsDir, skill.name, 'scripts');
20
+ if (!fs.existsSync(scriptsDir)) continue;
21
+ const dest = path.join(scriptsDir, 'atlassian-browser.js');
22
+ fs.writeFileSync(dest, content);
23
+ console.log(`vendored -> ${path.relative(repoRoot, dest)}`);
24
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aholbreich/agent-skills",
3
- "version": "0.9.0",
3
+ "version": "1.1.0",
4
4
  "description": "Handcrafted Agent Skills for browser-authenticated Jira and Confluence ingestion, LLM wiki workflows, and developer automation.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -39,10 +39,13 @@
39
39
  "jira-browser-fetch": "skills/jira-browser-fetch/scripts/jira-browser-fetch.js",
40
40
  "confluence-browser-fetch": "skills/confluence-browser-fetch/scripts/confluence-browser-fetch.js",
41
41
  "confluence-update": "skills/confluence-update/scripts/confluence-update.js",
42
- "bitbucket-browser-fetch": "skills/bitbucket-browser-fetch/scripts/bitbucket-browser-fetch.js"
42
+ "bitbucket-browser-fetch": "skills/bitbucket-browser-fetch/scripts/bitbucket-browser-fetch.js",
43
+ "jira-update": "skills/jira-update/scripts/jira-update.js"
43
44
  },
44
45
  "scripts": {
45
- "check": "node --check bin/agent-skills.js && node --check skills/jira-browser-fetch/scripts/jira-browser-fetch.js && node --check skills/jira-browser-fetch/scripts/lib.js && node --check skills/confluence-browser-fetch/scripts/confluence-browser-fetch.js && node --check skills/confluence-browser-fetch/scripts/lib.js && node --check skills/confluence-update/scripts/confluence-update.js && node --check skills/confluence-update/scripts/lib.js && node --check skills/bitbucket-browser-fetch/scripts/bitbucket-browser-fetch.js && node --check skills/bitbucket-browser-fetch/scripts/lib.js",
46
+ "vendor": "node bin/vendor.js",
47
+ "check": "node bin/check.js",
48
+ "pretest": "npm run vendor",
46
49
  "test": "node --test",
47
50
  "ci": "npm run check && npm test && npm pack --dry-run",
48
51
  "pack:dry": "npm pack --dry-run",
@@ -36,6 +36,20 @@ Important options:
36
36
  --profile-dir DIR Chrome profile dir
37
37
  ```
38
38
 
39
+ ## Shared Atlassian SSO Session
40
+
41
+ All five Atlassian skills (`jira-browser-fetch`, `jira-update`, `confluence-browser-fetch`, `confluence-update`, `bitbucket-browser-fetch`) default to the same Chrome profile (`~/.local/share/atlassian-browser-chrome`) and DevTools port (`9223`). Log in once via any skill and the others reuse that session automatically — no env vars needed.
42
+
43
+ Bitbucket sits on `bitbucket.org` rather than `*.atlassian.net`, so its cookies are scoped separately, but sharing one Chrome profile/port still avoids spawning extra browser windows.
44
+
45
+ **This is a separate Chrome window from any browser the user already has open.** The script always launches its own profile with remote-debugging enabled; cookies from the user's regular Chrome are not read. The user logs in inside the window the script opens; that session is then reused by every Atlassian skill until it expires.
46
+
47
+ **Reuse signal.** When attaching to an existing session, the script prints `Reusing Chrome DevTools on port 9223` and (if the target tab is open) `Found existing tab for <host>`. When you see those lines, do not ask the user to re-login — the session is already valid.
48
+
49
+ If Chrome/Chromium is installed via Flatpak, Snap, or another non-PATH location, set `CHROME=/path/to/launcher` (or a wrapper script) so the script can find the binary.
50
+
51
+ Override with `ATLASSIAN_CHROME_PROFILE` and/or `ATLASSIAN_CHROME_DEBUG_PORT` to relocate the shared profile/port, or use skill-specific `*_CHROME_PROFILE` / `*_CHROME_DEBUG_PORT` env vars for isolation.
52
+
39
53
  ## Example
40
54
 
41
55
  ```bash