@kolatts/pncli 5.3.0 → 6.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/README.md +2 -1
- package/dist/{chunk-2J2HAFKO.js → chunk-4FR4WGNR.js} +100 -13
- package/dist/chunk-4FR4WGNR.js.map +1 -0
- package/dist/chunk-WDWAPTVC.js +1001 -0
- package/dist/chunk-WDWAPTVC.js.map +1 -0
- package/dist/cli.js +3000 -493
- package/dist/cli.js.map +1 -1
- package/dist/{config-Y6IE6GY7.js → config-5LC7ZTEP.js} +4 -2
- package/dist/{http-V7PZD7LE.js → http-DJSGEGD6.js} +2 -2
- package/package.json +1 -1
- package/skills/pncli/SKILL.md +25 -6
- package/skills/pncli/ado.md +4 -0
- package/skills/pncli/bitbucket.md +4 -0
- package/skills/pncli/github.md +37 -0
- package/skills/pncli/jira.md +45 -1
- package/skills/pncli/marketplace.md +53 -1
- package/skills/pncli/saucelabs.md +175 -0
- package/skills/pncli/skills-guide.md +169 -0
- package/dist/chunk-2J2HAFKO.js.map +0 -1
- package/dist/chunk-QHJ2HM5J.js +0 -466
- package/dist/chunk-QHJ2HM5J.js.map +0 -1
- /package/dist/{config-Y6IE6GY7.js.map → config-5LC7ZTEP.js.map} +0 -0
- /package/dist/{http-V7PZD7LE.js.map → http-DJSGEGD6.js.map} +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: How skills management works
|
|
3
|
+
description: The mental model behind pncli skills — where skills come from, where they go, how they stay current, and how private marketplaces authenticate.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# How skills management works
|
|
7
|
+
|
|
8
|
+
pncli puts **skills** — folders of instructions an AI coding agent loads on demand — where your agents will find them, and keeps them current. Read this once; after that, `pncli skills --help` and `pncli doctor` cover the day-to-day.
|
|
9
|
+
|
|
10
|
+
Print any section on its own with `pncli skills guide <section>` (for example `pncli skills guide auth`). `pncli skills guide --sections` lists them all.
|
|
11
|
+
|
|
12
|
+
## The big picture
|
|
13
|
+
|
|
14
|
+
Skills reach your machine from two sources, and both end up in the same place:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
pncli (npm package) your org's marketplace repo (git)
|
|
18
|
+
└─ bundled "pncli" skill └─ plugins/<plugin>/skills/<skill>/SKILL.md
|
|
19
|
+
│ │ + instructions/AGENTS.md, CLAUDE.md
|
|
20
|
+
│ pncli skills install │ pncli skills marketplace add | sync
|
|
21
|
+
▼ ▼
|
|
22
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
23
|
+
│ agent skills directories (.agents/skills, .claude/skills, …) │
|
|
24
|
+
│ each skill carries a provenance record: source, plugin, marketplace │
|
|
25
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
26
|
+
▲
|
|
27
|
+
└── Codex, GitHub Copilot, and Claude Code read from here
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- The **bundled skill** is pncli's own command reference. It ships inside the npm package, so it changes when pncli does.
|
|
31
|
+
- **Marketplace plugins** are your org's skills, published in a git repository. pncli clones the repo once and pulls it whenever you sync.
|
|
32
|
+
- Every skill pncli installs is stamped with **provenance** — where it came from and which pncli version put it there. That is how `status`, `sync`, and `doctor` can tell your org's skills, pncli's own, and anything you dropped in by hand apart.
|
|
33
|
+
|
|
34
|
+
## Agent hosts and where skills live
|
|
35
|
+
|
|
36
|
+
Each agent host reads its own directories. `--agent` picks one; `--all-agents` covers every host in one run.
|
|
37
|
+
|
|
38
|
+
| `--agent` | Project scope | User scope | Read by |
|
|
39
|
+
|---|---|---|---|
|
|
40
|
+
| `codex` (default) | `.agents/skills` | `~/.agents/skills` | Codex and GitHub Copilot |
|
|
41
|
+
| `github-copilot` | `.github/skills` | `~/.copilot/skills` | GitHub Copilot |
|
|
42
|
+
| `claude-code` (`--claude`) | `.claude/skills` | `~/.claude/skills` | Claude Code |
|
|
43
|
+
|
|
44
|
+
**Project scope** lives in the repository — commit it and everyone who clones the repo gets the skills. **User scope** lives in your home directory and applies to every repository on the machine.
|
|
45
|
+
|
|
46
|
+
- The bundled skill installs at project scope by default. Add `--scope user` to have it everywhere.
|
|
47
|
+
- Marketplace plugins always install at user scope. They are org-wide, not repo-specific.
|
|
48
|
+
|
|
49
|
+
`pncli skills locations` prints every one of these paths with a count of what's in it.
|
|
50
|
+
|
|
51
|
+
## The bundled pncli skill
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
pncli skills install --all-agents # this repo, every agent host
|
|
55
|
+
pncli skills install --all-agents --scope user # every repo on this machine
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The bundled skill is versioned with pncli. After `npm update -g @kolatts/pncli`, the copies on disk are one version behind; `pncli doctor` flags them as stale, and re-running `pncli skills install` refreshes them.
|
|
59
|
+
|
|
60
|
+
## Marketplaces
|
|
61
|
+
|
|
62
|
+
A marketplace is a git repository your org publishes plugins from. The lifecycle is:
|
|
63
|
+
|
|
64
|
+
1. **Add** — register, clone, and install every plugin:
|
|
65
|
+
`pncli skills marketplace add https://ghe.imagile.dev/ai/skills.git --all-agents`
|
|
66
|
+
2. **Sync** — pull the latest and refresh what you already have. With no arguments this is non-interactive, which makes it safe for a login script or a scheduled task:
|
|
67
|
+
`pncli skills marketplace sync --all-agents`
|
|
68
|
+
3. **Browse** — see what's there without installing anything:
|
|
69
|
+
`pncli skills marketplace plugins internal-ai`
|
|
70
|
+
4. **Pick up something new** — plain `sync` only refreshes plugins you already have. Run `sync --force` for the interactive picker, or name the plugin:
|
|
71
|
+
`pncli skills marketplace sync new-plugin --all-agents`
|
|
72
|
+
|
|
73
|
+
You can register as many marketplaces as you like. Clones live in `~/.agents/marketplaces/`, and `marketplace remove` unregisters one without deleting its clone.
|
|
74
|
+
|
|
75
|
+
**What a marketplace repo looks like:** `.claude-plugin/marketplace.json` (or a `plugins/` directory), with each plugin holding a `skills/` folder of skill directories. That's the same layout Claude Code's own plugin marketplaces use, so one repo serves both.
|
|
76
|
+
|
|
77
|
+
## Turning plugins on and off
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
pncli skills marketplace disable some-plugin
|
|
81
|
+
pncli skills marketplace enable some-plugin
|
|
82
|
+
pncli skills marketplace manage # interactive: checkbox list of every plugin
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`disable` moves a plugin's skills into a hidden `.pncli-disabled/` folder next to them, so agents stop loading them. Nothing is deleted and nothing needs re-downloading. A disabled plugin stays disabled across syncs, but it still gets refreshed while it sits there.
|
|
86
|
+
|
|
87
|
+
To remove a plugin for good, use `marketplace purge-plugin`. `skills purge-user` clears an agent's whole user-level skills folder.
|
|
88
|
+
|
|
89
|
+
## Shipped instructions (AGENTS.md / CLAUDE.md)
|
|
90
|
+
|
|
91
|
+
A marketplace can also ship org-wide agent instructions in `instructions/AGENTS.md` and `instructions/CLAUDE.md`. `add` and `sync` merge them into each agent's **user-level** instructions file (`~/.codex/AGENTS.md`, `~/.copilot/copilot-instructions.md`, `~/.claude/CLAUDE.md`).
|
|
92
|
+
|
|
93
|
+
They go in as a marked block. Your own content in that file is never touched, the block is replaced in place on every sync, and `marketplace instructions remove` strips it cleanly. Don't edit inside the markers, because the next sync overwrites them.
|
|
94
|
+
|
|
95
|
+
## Where did this skill come from?
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
pncli skills status # every skill → plugin → marketplace → clone URL
|
|
99
|
+
pncli skills status --source untracked # skills pncli did not install
|
|
100
|
+
pncli skills locations # every path, with counts
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The counts in `locations` always add up: `marketplaceSkills + bundledSkills + untrackedSkills = totalSkills`.
|
|
104
|
+
|
|
105
|
+
## Private repos and auth
|
|
106
|
+
|
|
107
|
+
A private marketplace needs a credential in two places, and they're easy to confuse:
|
|
108
|
+
|
|
109
|
+
1. **pncli's own clone and pull.** Pass `--token` to `marketplace add`, or let pncli fall back to the token it already has for the provider: `github.token` for GitHub and GitHub Enterprise, `bitbucket.pat` for your Bitbucket host, `ado.pat` for your Azure DevOps host. pncli hands the token to git through the environment for each call, so it never shows up on git's command line and is never left in the clone's `.git/config`.
|
|
110
|
+
2. **Everyone else's git.** An agent host that clones a marketplace itself — Claude Code's `/plugin marketplace add`, for instance — runs plain `git`, and plain git has no idea about pncli's token. `git-auth` fixes that:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
pncli skills git-auth enable # every marketplace that has a credential
|
|
114
|
+
pncli skills git-auth status # per marketplace: mode, and whether git sends pncli's token
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`git-auth` has two modes:
|
|
118
|
+
|
|
119
|
+
| Mode | How it works | After a token rotation |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `helper` (default) | git asks `pncli skills git-credential --marketplace <name>` on each operation | Nothing to do — git always gets pncli's current token |
|
|
122
|
+
| `keychain` | the token is stored in git's own credential store (Git Credential Manager, macOS Keychain, libsecret) | Re-run `git-auth enable --mode keychain`; `doctor` flags the stale copy |
|
|
123
|
+
|
|
124
|
+
Use `helper` unless something runs git without pncli on its `PATH`. Some GUI git clients and containers do that, and for those `keychain` is the right mode.
|
|
125
|
+
|
|
126
|
+
Entries are scoped to each marketplace's own repository URL, so every other repo on the same host keeps your usual login (`gh`, Git Credential Manager, the macOS Keychain), untouched. `git-auth disable` puts your previous setup back exactly. A whole-host entry (`--host`) is available, but only when you ask for it.
|
|
127
|
+
|
|
128
|
+
**Which GitHub token?** A classic personal access token (`ghp_…`) with the `repo` scope works across every repository your account can see, which suits a marketplace. A fine-grained token (`github_pat_…`) also works, but only for the repositories you selected when you created it. If your org uses SAML single sign-on, authorize the token for the org (Settings → Developer settings → Tokens → Configure SSO). `pncli doctor` checks the scope, the SSO authorization, and the expiry date for you.
|
|
129
|
+
|
|
130
|
+
**Several marketplaces, several secrets.** Each marketplace keeps its own `--token` (and `--username`), and every git path — pncli's clone and pull, the git helper, doctor's access check — uses exactly that pair. Rotate one with `pncli skills marketplace update <name> --token <new-token>`.
|
|
131
|
+
|
|
132
|
+
**Bitbucket and Azure DevOps.** Both work like GitHub. Bitbucket Data Center personal access tokens are usually sent with your Bitbucket username, so give the marketplace `--username <you>`. Azure DevOps PATs need the Code (Read) scope and accept any username. `pncli doctor` tries an authenticated `git ls-remote` for each marketplace, so a wrong username shows up the same way an expired token does.
|
|
133
|
+
|
|
134
|
+
## Keeping credentials in the OS keychain
|
|
135
|
+
|
|
136
|
+
Diagrams of both storage options, and of both git-auth modes, are on the website: https://kolatts.github.io/pncli/credentials/
|
|
137
|
+
|
|
138
|
+
Any secret in `~/.pncli/config.json` can live in your operating system's credential store instead: the macOS Keychain, Windows Credential Manager, or the Secret Service on Linux. The config file then holds only a reference such as `"token": "keychain:github.token"`.
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
pncli config keychain migrate --dry-run # what would move
|
|
142
|
+
pncli config keychain migrate # config → keychain, every plaintext secret
|
|
143
|
+
pncli config keychain set github.token # store one (prompts; or pipe it with --stdin)
|
|
144
|
+
pncli config keychain status # every reference, and whether it resolves
|
|
145
|
+
pncli config keychain migrate --to config # keychain → config (entries kept)
|
|
146
|
+
pncli config keychain migrate --to config --purge # …and delete the keychain entries
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- `PNCLI_*` environment variables still win over everything, so CI is unaffected. Set `PNCLI_KEYCHAIN_BACKEND=none` on a machine that should ignore references altogether.
|
|
150
|
+
- `migrate` reads each secret back before it rewrites your config, and leaves a `config.json.pre-keychain.bak` behind. Delete that file once `pncli config check` passes.
|
|
151
|
+
- `marketplace add --token … --keychain` stores a marketplace token the same way from the start.
|
|
152
|
+
- Lookups cost a little time. On Windows each pncli command that needs a keychain secret starts PowerShell once (typically well under a second); macOS and Linux are faster.
|
|
153
|
+
- The keychain and `git-auth` helper mode work together. Git asks pncli, pncli reads the keychain, and the token never sits in a file anywhere.
|
|
154
|
+
|
|
155
|
+
## Troubleshooting
|
|
156
|
+
|
|
157
|
+
| Symptom | Try |
|
|
158
|
+
|---|---|
|
|
159
|
+
| The agent doesn't see a skill | `pncli skills status`, then check the host's directory in `pncli skills locations` |
|
|
160
|
+
| "I ran marketplace add but nothing shows up" | `pncli doctor` — it flags marketplaces with nothing installed from them |
|
|
161
|
+
| `sync` fails with "Invalid username or token" | `pncli doctor`: look for an expired token, a missing `repo` scope, or SSO not authorized |
|
|
162
|
+
| Claude Code's `/plugin marketplace add` can't clone | `pncli skills git-auth enable --host ghe.imagile.dev` |
|
|
163
|
+
| The bundled skill is out of date after an upgrade | `pncli skills install` (add `--all-agents` / `--scope user` as before) |
|
|
164
|
+
| A plugin added upstream never arrived | `pncli skills marketplace sync --force`, or name it explicitly |
|
|
165
|
+
| A command says "not configured" but the token is in the keychain | `pncli config keychain status` — the reference may point at a missing entry |
|
|
166
|
+
| Some ordinary clone (not a marketplace) says "repository not found" | `pncli git credentials inspect` in that clone, or `pncli git credentials inspect --scan ~/src --problems-only` |
|
|
167
|
+
| git keeps using the wrong account or an old token | `pncli git credentials stored` — shows shadowed and stale stored credentials, then `pncli git credentials forget` |
|
|
168
|
+
|
|
169
|
+
`pncli doctor` runs every one of these checks at once and prints a fix command next to each problem it finds.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/http.ts","../src/lib/adoFetch.ts","../src/lib/checkmarxFetch.ts","../src/lib/alationFetch.ts"],"sourcesContent":["import fs from 'fs';\nimport type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\nimport { ExitCode } from './exitCodes.js';\nimport { log, debug, isDebugEnabled } from './output.js';\nimport { buildAdoFetcher } from './adoFetch.js';\nimport { buildCheckmarxFetcher } from './checkmarxFetch.js';\nimport { buildAlationFetcher } from './alationFetch.js';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface HttpRequestOptions {\n method?: HttpMethod;\n body?: unknown;\n params?: Record<string, string | number | boolean | undefined>;\n timeoutMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface HttpError {\n error: true;\n status: number;\n message: string;\n url: string;\n}\n\nconst SENSITIVE_HEADERS = new Set(['authorization', 'api-key', 'x-figma-token', 'token']);\n\n// A Retry-After above this would otherwise block the process for that long — long\n// enough that a large value (misconfigured server, abuse-prevention lockout) makes\n// the CLI look hung rather than rate-limited. Fail fast with a structured error instead.\nconst MAX_RETRY_AFTER_SECONDS = 30;\n\nfunction parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (/^\\d+$/.test(trimmed)) {\n // Keep even overflowing delays above the cap and JSON-serializable.\n return Math.min(Number(trimmed), Number.MAX_VALUE);\n }\n // HTTP dates start with a weekday. Avoid Date.parse's permissive handling\n // of malformed numeric delays such as \"-1\" or \"1.5\".\n if (!/^[A-Za-z]+[, ]/.test(trimmed)) return undefined;\n const date = Date.parse(trimmed);\n return Number.isFinite(date) ? Math.max(0, Math.ceil((date - Date.now()) / 1000)) : undefined;\n}\n\nfunction redactHeaders(headers: RequestInit['headers']): Record<string, string> {\n if (!headers) return {};\n let entries: [string, string][];\n if (headers instanceof Headers) {\n entries = [...headers.entries()];\n } else if (Array.isArray(headers)) {\n entries = (headers as string[][]) as [string, string][];\n } else {\n entries = Object.entries(headers as Record<string, string>);\n }\n return Object.fromEntries(\n entries.map(([k, v]) => [k, SENSITIVE_HEADERS.has(k.toLowerCase()) ? '[REDACTED]' : v])\n );\n}\n\nfunction buildUrl(base: string, path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const normalizedBase = base.endsWith('/') ? base : base + '/';\n // Strip a leading '/' so that new URL(path, base) resolves relative to base's full\n // path rather than the origin. Per the WHATWG URL spec, an absolute-path reference\n // (starting with '/') resolves against the origin and discards any path already\n // present in base — which silently drops path segments like '/e/<environment-id>'\n // from Dynatrace Managed or Artifactory-with-context-root base URLs.\n const normalizedPath = path.startsWith('/') ? path.slice(1) : path;\n const url = new URL(normalizedPath, normalizedBase);\n if (params) {\n for (const [key, val] of Object.entries(params)) {\n if (val !== undefined) {\n url.searchParams.set(key, String(val));\n }\n }\n }\n // URLSearchParams serializes via application/x-www-form-urlencoded, which\n // encodes commas as %2C. REST APIs like Confluence's /rest/api/content require\n // literal commas for multi-value params such as ?expand=body.storage,version.\n // Commas are valid unencoded characters in URL query strings (RFC 3986 §3.4),\n // so restoring them here is safe for all services. Scope the replacement to the\n // query string only — a percent-encoded comma in a path segment is significant\n // and must be left alone.\n if (url.search) {\n url.search = url.search.replace(/%2C/gi, ',');\n }\n return url.toString();\n}\n\nasync function fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number, fetcher: typeof fetch = fetch): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetcher(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function requestRaw<T>(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n fetcher: typeof fetch = fetch\n): Promise<{ data: T; headers: Headers }> {\n let lastError: unknown;\n\n if (isDebugEnabled()) {\n const method = (init.method ?? 'GET').toUpperCase();\n const safeHeaders = redactHeaders(init.headers);\n debug(`→ ${method} ${url}`);\n debug(` Headers: ${JSON.stringify(safeHeaders)}`);\n }\n\n for (let attempt = 0; attempt < 3; attempt++) {\n let response: Response;\n const reqStart = Date.now();\n try {\n response = await fetchWithTimeout(url, init, timeoutMs, fetcher);\n } catch (err) {\n const topMsg = err instanceof Error ? err.message : String(err);\n // Node's built-in fetch wraps network errors: err.message is \"fetch failed\"\n // and the real cause (ECONNREFUSED, TLS error, DNS failure, etc.) is in\n // err.cause. Surface it so users can distinguish a proxy-routing problem\n // from bad credentials without having to reproduce the request externally.\n const causeMsg = err instanceof Error && err.cause instanceof Error ? err.cause.message : undefined;\n const fullMsg = causeMsg ? `${topMsg}: ${causeMsg}` : topMsg;\n debug(` Error: ${fullMsg}`);\n throw new PncliError(`Request failed: ${fullMsg}`, 0, url);\n }\n\n debug(`← ${response.status} ${response.statusText} (${Date.now() - reqStart}ms)`);\n\n if (response.status === 429) {\n const retryAfterSeconds = parseRetryAfter(response.headers.get('Retry-After'));\n\n if (retryAfterSeconds !== undefined && retryAfterSeconds > MAX_RETRY_AFTER_SECONDS) {\n throw new PncliError(\n `Rate limited: server requested a ${retryAfterSeconds}s retry delay, which exceeds the ${MAX_RETRY_AFTER_SECONDS}s cap`,\n 429,\n url,\n retryAfterSeconds\n );\n }\n\n lastError = new PncliError('Rate limited', 429, url, retryAfterSeconds);\n if (attempt === 2) break;\n\n const waitMs = retryAfterSeconds !== undefined ? retryAfterSeconds * 1000 : (attempt + 1) * 1000;\n log(`Rate limited. Retrying after ${waitMs}ms...`);\n await new Promise(resolve => setTimeout(resolve, waitMs));\n continue;\n }\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const body = await response.text();\n const parsed = JSON.parse(body);\n const parts: string[] = [];\n // Jira: errorMessages is string[]\n if (Array.isArray(parsed.errorMessages)) {\n parts.push(...(parsed.errorMessages as string[]).filter(Boolean));\n }\n // errors as object map (Jira: Record<string, string>)\n if (parsed.errors && typeof parsed.errors === 'object' && !Array.isArray(parsed.errors)) {\n for (const [field, msg] of Object.entries(parsed.errors as Record<string, string>)) {\n parts.push(`${field}: ${msg}`);\n }\n }\n // errors as array of objects with message or msg field (SonarQube uses msg)\n if (Array.isArray(parsed.errors)) {\n for (const e of parsed.errors as Array<{ message?: string; msg?: string }>) {\n if (e?.message) parts.push(e.message);\n else if (e?.msg) parts.push(e.msg);\n }\n }\n // Generic APIs: { message: \"...\" }\n if (parts.length === 0 && parsed.message) {\n parts.push(String(parsed.message));\n }\n if (parts.length > 0) message = parts.join('; ');\n } catch {\n // ignore parse errors\n }\n throw new PncliError(message, response.status, url);\n }\n\n if (response.status === 204) {\n return { data: undefined as T, headers: response.headers };\n }\n\n const text = await response.text();\n if (!text) return { data: undefined as T, headers: response.headers };\n return { data: JSON.parse(text) as T, headers: response.headers };\n }\n\n throw lastError ?? new PncliError('Request failed after retries', 1, url);\n}\n\nasync function request<T>(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n fetcher: typeof fetch = fetch\n): Promise<T> {\n const { data } = await requestRaw<T>(url, init, timeoutMs, fetcher);\n return data;\n}\n\nexport class HttpClient {\n private config: ResolvedConfig;\n private dryRun: boolean;\n private adoFetcher: typeof fetch | null = null;\n private checkmarxFetcher: typeof fetch | null = null;\n private alationFetcher: typeof fetch | null = null;\n\n constructor(config: ResolvedConfig, dryRun = false) {\n this.config = config;\n this.dryRun = dryRun;\n }\n\n private jiraToken(): string {\n const { apiToken } = this.config.jira;\n if (!apiToken) throw new PncliError('Jira credentials not configured. Run: pncli config init');\n return apiToken;\n }\n\n private jiraHeaders(): Record<string, string> {\n return {\n 'Authorization': `Bearer ${this.jiraToken()}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private bitbucketHeaders(): Record<string, string> {\n const { pat } = this.config.bitbucket;\n if (!pat) throw new PncliError('Bitbucket credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${pat}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private githubHeaders(): Record<string, string> {\n const { token } = this.config.github;\n if (!token) throw new PncliError('GitHub credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'Connection': 'close'\n };\n }\n\n async jira<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.jira.baseUrl;\n if (!baseUrl) throw new PncliError('Jira baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jiraHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async jiraBuffer(absoluteUrl: string, opts: { timeoutMs?: number } = {}): Promise<Buffer> {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.jiraToken()}`,\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: GET ${absoluteUrl}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(absoluteUrl, { headers }, opts.timeoutMs ?? 60000);\n if (!response.ok) {\n throw new PncliError(`HTTP ${response.status} ${response.statusText}`, response.status, absoluteUrl);\n }\n return Buffer.from(await response.arrayBuffer());\n }\n\n async adoUpload<T>(\n path: string,\n buffer: Buffer,\n contentType: string,\n opts: { timeoutMs?: number } = {}\n ): Promise<T> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: POST ${url}\\nBody: <binary ${buffer.length} bytes>\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n return request<T>(url, {\n method: 'POST',\n headers: { 'Accept': 'application/json', 'Content-Type': contentType },\n body: buffer\n }, opts.timeoutMs ?? 60000, fetcher);\n }\n\n async adoBuffer(absoluteUrl: string, opts: { timeoutMs?: number } = {}): Promise<Buffer> {\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: GET ${absoluteUrl}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const response = await fetchWithTimeout(\n absoluteUrl,\n { headers: { Accept: 'application/octet-stream' } },\n opts.timeoutMs ?? 60000,\n fetcher\n );\n if (!response.ok) {\n throw new PncliError(`HTTP ${response.status} ${response.statusText}`, response.status, absoluteUrl);\n }\n return Buffer.from(await response.arrayBuffer());\n }\n\n async jiraUpload<T>(\n path: string,\n formData: FormData,\n opts: { timeoutMs?: number } = {}\n ): Promise<T> {\n const baseUrl = this.config.jira.baseUrl;\n if (!baseUrl) throw new PncliError('Jira baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.jiraToken()}`,\n 'X-Atlassian-Token': 'no-check',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: POST ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\nBody: <multipart/form-data>\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, { method: 'POST', headers, body: formData }, opts.timeoutMs ?? 60000);\n }\n\n async github<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.github.baseUrl;\n if (!baseUrl) throw new PncliError('GitHub baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.githubHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async githubText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.github.baseUrl;\n if (!baseUrl) throw new PncliError('GitHub baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n // Reuse githubHeaders() (which enforces the token check) and override Accept so\n // GitHub returns the raw unified diff instead of JSON.\n const headers: Record<string, string> = {\n ...this.githubHeaders(),\n 'Accept': 'application/vnd.github.v3.diff'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n async githubGraphQL<T>(query: string, variables?: Record<string, unknown>): Promise<T> {\n const baseUrl = this.config.github.baseUrl;\n if (!baseUrl) throw new PncliError('GitHub baseUrl not configured. Run: pncli config init');\n\n // Derive GraphQL endpoint:\n // github.com: 'https://api.github.com' → 'https://api.github.com/graphql'\n // GHES: 'https://ghe.imagile.dev/api/v3' → 'https://ghe.imagile.dev/api/graphql'\n // Trailing slashes are trimmed first — config does not normalize them away, so\n // '.../api/v3/' must still be recognized as a GHES REST root.\n const trimmed = baseUrl.replace(/\\/+$/, '');\n const stripped = trimmed.endsWith('/v3') ? trimmed.slice(0, -3) : trimmed;\n const url = stripped.endsWith('/') ? `${stripped}graphql` : `${stripped}/graphql`;\n\n const headers = this.githubHeaders();\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: POST ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\nBody: ${JSON.stringify({ query, variables }, null, 2)}\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const result = await request<{ data?: T; errors?: Array<{ message: string }> }>(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({ query, variables })\n },\n 30000\n );\n\n if (result.errors?.length) {\n throw new PncliError(result.errors.map(e => e.message).join('; '), 1, url);\n }\n\n // GitHub can return a null/absent `data` with no `errors` array (e.g. an\n // inaccessible or deleted repository). Fail cleanly instead of letting the\n // caller dereference null.\n if (result.data === null || result.data === undefined) {\n throw new PncliError('GraphQL response contained no data', 1, url);\n }\n\n return result.data;\n }\n\n async githubPaginate<T>(\n fetchPage: (page: number, perPage: number) => Promise<T[]>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const perPage = 100;\n\n while (true) {\n const items = await fetchPage(page, perPage);\n results.push(...items);\n if (items.length < perPage) break;\n page++;\n }\n\n return results;\n }\n\n async bitbucket<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.bitbucket.baseUrl;\n if (!baseUrl) throw new PncliError('Bitbucket baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.bitbucketHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n /**\n * Same as {@link bitbucket}, but also returns the raw response headers.\n * Bitbucket Server stamps every authenticated response with X-AUSERNAME,\n * which is how getCurrentUser() resolves the caller.\n */\n async bitbucketRaw<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ data: T; headers: Headers }> {\n const baseUrl = this.config.bitbucket.baseUrl;\n if (!baseUrl) throw new PncliError('Bitbucket baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.bitbucketHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return requestRaw<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private confluenceToken(): string {\n const { apiToken } = this.config.confluence;\n if (!apiToken) throw new PncliError('Confluence credentials not configured. Run: pncli config init');\n return apiToken;\n }\n\n private confluenceHeaders(): Record<string, string> {\n return {\n 'Authorization': `Bearer ${this.confluenceToken()}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async confluence<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.confluence.baseUrl;\n if (!baseUrl) throw new PncliError('Confluence baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.confluenceHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private sdeHeaders(): Record<string, string> {\n const { token } = this.config.sde;\n if (!token) throw new PncliError('SDElements credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Token ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sde<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sde.baseUrl;\n if (!baseUrl) throw new PncliError('SDElements baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sdeHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async sdePaginate<T>(\n fetchPage: (page: number, pageSize: number) => Promise<{ count: number; results: T[] }>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const pageSize = 100;\n\n while (true) {\n const response = await fetchPage(page, pageSize);\n results.push(...response.results);\n if (results.length >= response.count || response.results.length === 0) break;\n page++;\n }\n\n return results;\n }\n\n private async getAdoFetcher(): Promise<typeof fetch> {\n if (!this.adoFetcher) {\n this.adoFetcher = await buildAdoFetcher(this.config);\n }\n return this.adoFetcher;\n }\n\n async ado<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const defaultHeaders: Record<string, string> = {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n ...opts.headers\n };\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers: defaultHeaders,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n return request<T>(url, init, opts.timeoutMs ?? 30000, fetcher);\n }\n\n async adoText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'text/plain', ...opts.headers }\n }, opts.timeoutMs ?? 30000, fetcher);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n async adoRaw(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ data: unknown; headers: Headers }> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 30000);\n let response: Response;\n try {\n response = await fetcher(url, {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...opts.headers },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n const text = await response.text();\n const data = text ? JSON.parse(text) : undefined;\n return { data, headers: response.headers };\n }\n\n async adoPaginate<T>(\n fetchPage: (continuationToken?: string) => Promise<{ data: { value: T[] }; headers: Headers }>\n ): Promise<T[]> {\n const results: T[] = [];\n let token: string | undefined;\n\n while (true) {\n const { data, headers } = await fetchPage(token);\n results.push(...(data.value ?? []));\n const next = headers.get('x-ms-continuationtoken');\n if (!next) break;\n token = next;\n }\n\n return results;\n }\n\n private jenkinsHeaders(): Record<string, string> {\n const { username, apiToken } = this.config.jenkins;\n if (!username || !apiToken) throw new PncliError('Jenkins credentials not configured. Run: pncli config init');\n const creds = Buffer.from(`${username}:${apiToken}`).toString('base64');\n return {\n 'Authorization': `Basic ${creds}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private artifactoryHeaders(): Record<string, string> {\n const { token } = this.config.artifactory;\n if (!token) throw new PncliError('Artifactory credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async jenkins<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.jenkins.baseUrl;\n if (!baseUrl) throw new PncliError('Jenkins baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jenkinsHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async jenkinsRaw(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ status: number; headers: Headers; text: string }> {\n const baseUrl = this.config.jenkins.baseUrl;\n if (!baseUrl) throw new PncliError('Jenkins baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jenkinsHeaders();\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return { status: response.status, headers: response.headers, text: await response.text() };\n }\n\n async artifactory<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.artifactory.baseUrl;\n if (!baseUrl) throw new PncliError('Artifactory baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = { ...this.artifactoryHeaders(), ...opts.headers };\n\n // AQL search uses text/plain body — don't JSON-serialize it\n const body = opts.body !== undefined\n ? (typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body))\n : undefined;\n\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async artifactoryText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.artifactory.baseUrl;\n if (!baseUrl) throw new PncliError('Artifactory baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = { ...this.artifactoryHeaders(), Accept: 'text/plain', ...opts.headers };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n\n\n private sonarHeaders(): Record<string, string> {\n const { token } = this.config.sonar;\n if (!token) throw new PncliError('SonarQube credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sonar<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sonar.baseUrl;\n if (!baseUrl) throw new PncliError('SonarQube baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sonarHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async sonarPaginate<T>(\n fetchPage: (page: number, pageSize: number) => Promise<{ total: number; p: number; ps: number; items: T[] }>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const pageSize = 500;\n\n while (true) {\n const response = await fetchPage(page, pageSize);\n results.push(...response.items);\n if (results.length >= response.total || response.items.length === 0) break;\n page++;\n }\n\n return results;\n }\n\n async confluenceBuffer(path: string, opts: { timeoutMs?: number } = {}): Promise<Buffer> {\n const baseUrl = this.config.confluence.baseUrl;\n if (!baseUrl) throw new PncliError('Confluence baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.confluenceToken()}`,\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: GET ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, { headers }, opts.timeoutMs ?? 60000);\n if (!response.ok) {\n throw new PncliError(`HTTP ${response.status} ${response.statusText}`, response.status, url);\n }\n return Buffer.from(await response.arrayBuffer());\n }\n\n async confluenceUpload<T>(\n path: string,\n formData: FormData,\n opts: { timeoutMs?: number } = {}\n ): Promise<T> {\n const baseUrl = this.config.confluence.baseUrl;\n if (!baseUrl) throw new PncliError('Confluence baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.confluenceToken()}`,\n 'X-Atlassian-Token': 'no-check',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: POST ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\nBody: <multipart/form-data>\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, { method: 'POST', headers, body: formData }, opts.timeoutMs ?? 60000);\n }\n\n async confluencePaginate<T>(\n fetchPage: (start: number, limit: number) => Promise<{ results: T[]; start: number; limit: number; size: number; _links: { next?: string } }>,\n maxTotal?: number\n ): Promise<T[]> {\n const results: T[] = [];\n let start = 0;\n const defaultPageSize = 25;\n\n while (true) {\n const pageLimit = maxTotal !== undefined\n ? Math.min(maxTotal - results.length, defaultPageSize)\n : defaultPageSize;\n const page = await fetchPage(start, pageLimit);\n results.push(...page.results);\n if (maxTotal !== undefined && results.length >= maxTotal) break;\n if (!page._links.next) break;\n start += page.size;\n }\n\n return maxTotal !== undefined ? results.slice(0, maxTotal) : results;\n }\n\n async paginate<T>(\n fetchPage: (start: number, limit: number) => Promise<{ values: T[]; isLastPage: boolean; nextPageStart?: number }>\n ): Promise<T[]> {\n const results: T[] = [];\n let start = 0;\n const limit = 100;\n\n while (true) {\n const page = await fetchPage(start, limit);\n results.push(...page.values);\n if (page.isLastPage) break;\n start = page.nextPageStart ?? start + limit;\n }\n\n return results;\n }\n\n async jiraPaginate<T>(\n fetchPage: (startAt: number, maxResults: number) => Promise<{ issues?: T[]; values?: T[]; total: number; startAt: number; maxResults: number }>\n ): Promise<T[]> {\n const results: T[] = [];\n let startAt = 0;\n const maxResults = 100;\n\n while (true) {\n const page = await fetchPage(startAt, maxResults);\n const items = (page.issues ?? page.values ?? []) as T[];\n results.push(...items);\n startAt += items.length;\n if (startAt >= page.total || items.length === 0) break;\n }\n\n return results;\n }\n\n private getCheckmarxFetcher(): typeof fetch {\n if (!this.checkmarxFetcher) {\n this.checkmarxFetcher = buildCheckmarxFetcher(this.config);\n }\n return this.checkmarxFetcher;\n }\n\n private getAlationFetcher(): typeof fetch {\n if (!this.alationFetcher) {\n this.alationFetcher = buildAlationFetcher(this.config);\n }\n return this.alationFetcher;\n }\n\n private contrastHeaders(): Record<string, string> {\n const { apiKey, serviceKey, username } = this.config.contrast;\n if (!apiKey || !serviceKey || !username) {\n throw new PncliError('Contrast credentials not configured. Run: pncli config init');\n }\n const authorization = Buffer.from(`${username}:${serviceKey}`).toString('base64');\n return {\n 'Authorization': authorization,\n 'API-Key': apiKey,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async contrast<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const { baseUrl } = this.config.contrast;\n if (!baseUrl) throw new PncliError('Contrast base URL not configured. Run: pncli config set contrast.baseUrl <url>');\n\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.contrastHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]', 'API-Key': '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private sonatypeiqHeaders(): Record<string, string> {\n const { userCode, passcode } = this.config.sonatypeiq;\n if (!userCode || !passcode) throw new PncliError('Sonatype IQ credentials not configured. Run: pncli config init');\n const encoded = Buffer.from(`${userCode}:${passcode}`).toString('base64');\n return {\n 'Authorization': `Basic ${encoded}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sonatypeiq<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sonatypeiq.baseUrl;\n if (!baseUrl) throw new PncliError('Sonatype IQ Server baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sonatypeiqHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private openshiftHeaders(): Record<string, string> {\n const { token } = this.config.openshift;\n if (!token) throw new PncliError('OpenShift credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async openshift<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.openshift.baseUrl;\n if (!baseUrl) throw new PncliError('OpenShift baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.openshiftHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private dynatraceHeaders(platform = false): Record<string, string> {\n const token = platform ? this.config.dynatrace.platformToken : this.config.dynatrace.apiToken;\n if (!token) {\n throw new PncliError(\n `${platform ? 'Dynatrace platform' : 'Dynatrace'} credentials not configured. Run: pncli config init`\n );\n }\n return {\n 'Authorization': `${platform ? 'Bearer' : 'Api-Token'} ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async dynatrace<T>(path: string, opts: HttpRequestOptions = {}): Promise<T> {\n return this.dynatraceRequest<T>(false, path, opts);\n }\n\n async dynatracePlatform<T>(path: string, opts: HttpRequestOptions = {}): Promise<T> {\n return this.dynatraceRequest<T>(true, path, opts);\n }\n\n private async dynatraceRequest<T>(\n platform: boolean,\n path: string,\n opts: HttpRequestOptions\n ): Promise<T> {\n const baseUrl = platform ? this.config.dynatrace.platformUrl : this.config.dynatrace.baseUrl;\n if (!baseUrl) {\n throw new PncliError(\n `${platform ? 'Dynatrace platformUrl' : 'Dynatrace baseUrl'} not configured. Run: pncli config init`\n );\n }\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.dynatraceHeaders(platform);\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private logscaleHeaders(): Record<string, string> {\n const { token } = this.config.logscale;\n if (!token) throw new PncliError('LogScale credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async logscale<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.logscale.baseUrl;\n if (!baseUrl) throw new PncliError('LogScale baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.logscaleHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private splitioHeaders(): Record<string, string> {\n const { adminApiKey } = this.config.splitio;\n if (!adminApiKey) throw new PncliError('Split.IO credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${adminApiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async splitio<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.splitio.baseUrl;\n if (!baseUrl) throw new PncliError('Split.IO baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.splitioHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async openshiftText(\n path: string,\n opts: HttpRequestOptions & { lines?: number } = {}\n ): Promise<string> {\n const baseUrl = this.config.openshift.baseUrl;\n if (!baseUrl) throw new PncliError('OpenShift baseUrl not configured. Run: pncli config init');\n\n const params: Record<string, string | number | boolean | undefined> = { ...opts.params };\n if (opts.lines !== undefined) params['tailLines'] = opts.lines;\n\n const url = buildUrl(baseUrl, path, params);\n const headers: Record<string, string> = {\n 'Authorization': this.openshiftHeaders()['Authorization'],\n 'Accept': '*/*',\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n fs.writeSync(process.stderr.fd, `DRY RUN: GET ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, { method: 'GET', headers }, opts.timeoutMs ?? 30000);\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n async checkmarx<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.checkmarx.baseUrl;\n if (!baseUrl) throw new PncliError('Checkmarx baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = this.getCheckmarxFetcher();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...opts.headers },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n return request<T>(url, init, opts.timeoutMs ?? 30000, fetcher);\n }\n\n private figmaHeaders(): Record<string, string> {\n const { token } = this.config.figma;\n if (!token) throw new PncliError('Figma credentials not configured. Run: pncli config set figma.token <token>');\n return {\n 'X-Figma-Token': token,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async figma<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.figma.baseUrl;\n if (!baseUrl) throw new PncliError('Figma baseUrl not configured. Run: pncli config set figma.baseUrl https://api.figma.com');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.figmaHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, 'X-Figma-Token': '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n /**\n * Alation. The refresh token configured by the user is exchanged for a\n * short-lived API access token inside the fetcher (see alationFetch.ts) and\n * sent as the `TOKEN` header; no static credential goes on the wire here.\n * Alation's paths are Django routes — keep the trailing slash.\n */\n async alation<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.alation.baseUrl;\n if (!baseUrl) throw new PncliError('Alation baseUrl not configured. Run: pncli config set alation.baseUrl https://alation.imagile.dev');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = this.getAlationFetcher();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...opts.headers },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n return request<T>(url, init, opts.timeoutMs ?? 30000, fetcher);\n }\n}\n\nexport function createHttpClient(config: ResolvedConfig, dryRun = false): HttpClient {\n return new HttpClient(config, dryRun);\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\n\n/**\n * Returns a fetch-compatible function for Azure DevOps Server requests,\n * with Basic auth (PAT) injected into every call.\n */\nexport async function buildAdoFetcher(\n config: ResolvedConfig\n): Promise<typeof fetch> {\n const { pat, baseUrl } = config.ado;\n\n if (!baseUrl) {\n throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init', 1);\n }\n\n if (!pat) {\n throw new PncliError(\n 'Azure DevOps PAT not configured. Set a PAT via pncli config init or PNCLI_ADO_PAT env var.',\n 1\n );\n }\n\n const encoded = Buffer.from(':' + pat).toString('base64');\n const authHeader = `Basic ${encoded}`;\n return (url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) =>\n fetch(url, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...(init?.headers as Record<string, string> | undefined),\n 'Authorization': authHeader\n }\n });\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport type { CxOneTokenResponse } from '../types/checkmarx.js';\nimport { PncliError } from './errors.js';\n\ninterface TokenCache {\n value: string;\n expiresAt: number;\n}\n\n/**\n * Returns a fetch-compatible function for Checkmarx One requests,\n * with Checkmarx API key or OAuth2 client_credentials token exchange and bearer auth\n * injected into every call.\n * The token is cached for the lifetime of the returned fetcher and refreshed\n * when within 60s of expiry.\n */\nexport function buildCheckmarxFetcher(config: ResolvedConfig): typeof fetch {\n const { baseUrl, tenantName, apiKey, clientId, clientSecret } = config.checkmarx;\n\n if (!baseUrl) throw new PncliError('Checkmarx baseUrl not configured. Run: pncli config init', 1);\n if (!tenantName) throw new PncliError('Checkmarx tenantName not configured. Run: pncli config init', 1);\n if (!apiKey && (!clientId || !clientSecret)) {\n throw new PncliError(\n 'Checkmarx credentials not configured. Set apiKey or clientId and clientSecret. Run: pncli config init',\n 1\n );\n }\n\n const apiHost = new URL(baseUrl).hostname;\n const iamHost = apiHost.replace(/(^|\\.)ast\\./, '$1iam.');\n const tokenUrl = `https://${iamHost}/auth/realms/${tenantName}/protocol/openid-connect/token`;\n let cache: TokenCache | null = null;\n\n async function getToken(): Promise<string> {\n const now = Date.now();\n if (cache && cache.expiresAt - now > 60_000) {\n return cache.value;\n }\n\n const body = apiKey\n ? new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: getApiKeyClientId(apiKey),\n refresh_token: apiKey\n })\n : new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: clientId!,\n client_secret: clientSecret!\n });\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new PncliError(\n `Checkmarx token exchange failed (${response.status}): ${text || response.statusText}`,\n response.status\n );\n }\n\n const data = await response.json() as CxOneTokenResponse;\n if (!data.access_token) {\n throw new PncliError('Checkmarx token endpoint returned no access_token', response.status);\n }\n cache = {\n value: data.access_token,\n expiresAt: now + data.expires_in * 1000\n };\n return cache.value;\n }\n\n return async (url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<Response> => {\n const token = await getToken();\n return fetch(url, {\n ...init,\n headers: {\n ...(init?.headers as Record<string, string> | undefined),\n 'Authorization': `Bearer ${token}`\n }\n });\n };\n}\n\nfunction getApiKeyClientId(apiKey: string): string {\n try {\n const payload = apiKey.split('.')[1];\n if (!payload) return 'ast-app';\n const normalized = payload.replace(/-/g, '+').replace(/_/g, '/');\n const claims = JSON.parse(Buffer.from(normalized, 'base64').toString('utf8')) as { azp?: unknown };\n return typeof claims.azp === 'string' && claims.azp ? claims.azp : 'ast-app';\n } catch {\n return 'ast-app';\n }\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\n\n/** Response of POST /integration/v1/createAPIAccessToken/ (and validateAPIAccessToken). */\nexport interface AlationAccessTokenResponse {\n api_access_token: string;\n user_id: number;\n created_at?: string;\n /** Timezone-aware ISO 8601 timestamp; Alation's default lifetime is 24 hours. */\n token_expires_at?: string;\n token_status?: string;\n}\n\ninterface TokenCache {\n value: string;\n expiresAt: number;\n}\n\n/** Re-exchange when the cached token is within this window of expiring. */\nconst REFRESH_MARGIN_MS = 60_000;\n/** Alation's documented default API access token lifetime, used only if the response omits an expiry. */\nconst DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport const ALATION_CONFIG_HINT =\n 'Run: pncli config set alation.baseUrl https://alation.imagile.dev && pncli config set alation.refreshToken <token> && pncli config set alation.userId <id>';\n\n/**\n * Parse the user ID Alation needs alongside the refresh token. Config files\n * written by hand may hold a number or a string; env vars are always strings.\n * Anything that is not a positive integer is a config error with a fix, never a\n * TypeError from deep inside a request.\n */\nexport function parseAlationUserId(raw: string | number | undefined): number | undefined {\n if (raw === undefined || raw === '') return undefined;\n const text = String(raw).trim();\n if (!/^[1-9]\\d*$/.test(text)) {\n throw new PncliError(\n `Alation userId must be a positive integer (the numeric ID Alation returned when the refresh token was created), got \"${text}\". ${ALATION_CONFIG_HINT}`,\n 1\n );\n }\n return Number(text);\n}\n\nfunction requireAlationConfig(config: ResolvedConfig): { baseUrl: string; refreshToken: string; userId: number } {\n const { baseUrl, refreshToken } = config.alation;\n if (!baseUrl) throw new PncliError(`Alation baseUrl not configured. ${ALATION_CONFIG_HINT}`, 1);\n if (!refreshToken) throw new PncliError(`Alation refreshToken not configured. ${ALATION_CONFIG_HINT}`, 1);\n const userId = parseAlationUserId(config.alation.userId);\n if (userId === undefined) throw new PncliError(`Alation userId not configured. ${ALATION_CONFIG_HINT}`, 1);\n return { baseUrl, refreshToken, userId };\n}\n\n/** Alation's endpoints are Django routes: the trailing slash is significant. */\nfunction alationUrl(baseUrl: string, path: string): string {\n return `${baseUrl.replace(/\\/+$/, '')}/${path.replace(/^\\/+/, '')}`;\n}\n\n/**\n * Exchange the long-lived refresh token for a short-lived (default 24h) API\n * access token. This is the one HTTP hop between the credential the user\n * configured and an authenticated data-API request; it is never interactive.\n */\nexport async function createAlationAccessToken(config: ResolvedConfig): Promise<AlationAccessTokenResponse> {\n const { baseUrl, refreshToken, userId } = requireAlationConfig(config);\n const tokenUrl = alationUrl(baseUrl, 'integration/v1/createAPIAccessToken/');\n\n let response: Response;\n try {\n response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify({ refresh_token: refreshToken, user_id: userId })\n });\n } catch (err) {\n throw new PncliError(\n `Alation token exchange failed: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n tokenUrl\n );\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new PncliError(\n `Alation token exchange failed (${response.status}): ${text || response.statusText}. `\n + 'Check alation.refreshToken and alation.userId; refresh tokens expire after 60 days by default.',\n response.status,\n tokenUrl\n );\n }\n\n const data = await response.json() as Partial<AlationAccessTokenResponse>;\n if (!data.api_access_token) {\n throw new PncliError('Alation token endpoint returned no api_access_token', response.status, tokenUrl);\n }\n return data as AlationAccessTokenResponse;\n}\n\n/**\n * Validate the currently minted API access token without exposing it. Used by\n * `alation token status` so a user can see when the short-lived token expires\n * and confirm the refresh token still works.\n */\nexport async function validateAlationAccessToken(config: ResolvedConfig): Promise<Omit<AlationAccessTokenResponse, 'api_access_token'>> {\n const { baseUrl, userId } = requireAlationConfig(config);\n const minted = await createAlationAccessToken(config);\n const validateUrl = alationUrl(baseUrl, 'integration/v1/validateAPIAccessToken/');\n let response: Response;\n try {\n response = await fetch(validateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify({ api_access_token: minted.api_access_token, user_id: userId })\n });\n } catch (err) {\n throw new PncliError(\n `Alation token validation failed: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n validateUrl\n );\n }\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new PncliError(`Alation token validation failed (${response.status}): ${text || response.statusText}`, response.status, validateUrl);\n }\n const data = await response.json() as AlationAccessTokenResponse;\n const { api_access_token: _omit, ...rest } = data;\n void _omit;\n return rest;\n}\n\n/**\n * Returns a fetch-compatible function for Alation requests with the\n * refresh-token → API-access-token exchange and the `TOKEN` header injected\n * into every call. The access token is cached for the lifetime of the returned\n * fetcher and re-minted when within 60s of expiry. It is never persisted.\n */\nexport function buildAlationFetcher(config: ResolvedConfig): typeof fetch {\n requireAlationConfig(config);\n let cache: TokenCache | null = null;\n\n async function getToken(): Promise<string> {\n const now = Date.now();\n if (cache && cache.expiresAt - now > REFRESH_MARGIN_MS) {\n return cache.value;\n }\n const data = await createAlationAccessToken(config);\n const parsedExpiry = data.token_expires_at ? Date.parse(data.token_expires_at) : NaN;\n cache = {\n value: data.api_access_token,\n expiresAt: Number.isNaN(parsedExpiry) ? now + DEFAULT_TTL_MS : parsedExpiry\n };\n return cache.value;\n }\n\n return async (url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<Response> => {\n const token = await getToken();\n return fetch(url, {\n ...init,\n headers: {\n ...(init?.headers as Record<string, string> | undefined),\n 'TOKEN': token\n }\n });\n };\n}\n"],"mappings":"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","names":[]}
|