@kolatts/pncli 1.18.0 → 1.20.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/NOTICE +404 -0
- package/README.md +5 -3
- package/copilot-instructions.md +22 -5
- package/dist/{chunk-IVUDXPDP.js → chunk-FXY262BR.js} +26 -6
- package/dist/chunk-FXY262BR.js.map +1 -0
- package/dist/{chunk-WX4ZRHIC.js → chunk-PC4AHQCN.js} +115 -22
- package/dist/chunk-PC4AHQCN.js.map +1 -0
- package/dist/cli.js +565 -75
- package/dist/cli.js.map +1 -1
- package/dist/{config-QN7KDHE4.js → config-CPRXY5SN.js} +2 -2
- package/dist/{http-DDY5DLF6.js → http-IXJA4TMS.js} +2 -2
- package/package.json +1 -1
- package/skills/pncli/SKILL.md +2 -1
- package/skills/pncli/ado.md +3 -3
- package/skills/pncli/artifactory.md +3 -3
- package/skills/pncli/bitbucket.md +3 -3
- package/skills/pncli/checkmarx.md +20 -13
- package/skills/pncli/confluence.md +3 -3
- package/skills/pncli/contrast.md +1 -1
- package/skills/pncli/dynatrace.md +46 -0
- package/skills/pncli/jenkins.md +5 -5
- package/skills/pncli/jira.md +3 -3
- package/skills/pncli/marketplace.md +1 -1
- package/skills/pncli/openshift.md +4 -4
- package/skills/pncli/sde.md +3 -3
- package/skills/pncli/servicenow.md +3 -3
- package/skills/pncli/sonarqube.md +3 -3
- package/skills/pncli/sonatypeiq.md +3 -3
- package/skills/pncli/udeploy.md +3 -3
- package/dist/chunk-IVUDXPDP.js.map +0 -1
- package/dist/chunk-WX4ZRHIC.js.map +0 -1
- /package/dist/{config-QN7KDHE4.js.map → config-CPRXY5SN.js.map} +0 -0
- /package/dist/{http-DDY5DLF6.js.map → http-IXJA4TMS.js.map} +0 -0
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
setRepoConfigValue,
|
|
9
9
|
writeGlobalConfig,
|
|
10
10
|
writeRepoConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-FXY262BR.js";
|
|
12
12
|
export {
|
|
13
13
|
getGlobalConfigPath,
|
|
14
14
|
loadConfig,
|
|
@@ -19,4 +19,4 @@ export {
|
|
|
19
19
|
writeGlobalConfig,
|
|
20
20
|
writeRepoConfig
|
|
21
21
|
};
|
|
22
|
-
//# sourceMappingURL=config-
|
|
22
|
+
//# sourceMappingURL=config-CPRXY5SN.js.map
|
package/package.json
CHANGED
package/skills/pncli/SKILL.md
CHANGED
|
@@ -9,7 +9,7 @@ metadata:
|
|
|
9
9
|
services: config
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
pncli gives AI agents and humans unified CLI access to enterprise tools: Jira, Bitbucket, Confluence, SonarQube, SDElements, Azure DevOps, Jenkins, Artifactory, IBM UrbanCode Deploy, Checkmarx, ServiceNow, Contrast Security IAST, Sonatype IQ Server,
|
|
12
|
+
pncli gives AI agents and humans unified CLI access to enterprise tools: Jira, Bitbucket, Confluence, SonarQube, SDElements, Azure DevOps, Jenkins, Artifactory, IBM UrbanCode Deploy, Checkmarx, ServiceNow, Contrast Security IAST, Sonatype IQ Server, OpenShift / Kubernetes, and Dynatrace.
|
|
13
13
|
|
|
14
14
|
## Two config levels
|
|
15
15
|
|
|
@@ -54,6 +54,7 @@ For detailed setup of any service, read the included file for that service.
|
|
|
54
54
|
| Contrast IAST | `contrast.md` | Runtime vulnerability findings |
|
|
55
55
|
| Sonatype IQ | `sonatypeiq.md` | Dependency policy enforcement |
|
|
56
56
|
| OpenShift / Kubernetes | `openshift.md` | Pod health, events, logs, metrics |
|
|
57
|
+
| Dynatrace | `dynatrace.md` | Services, entities, problems, traces, Kubernetes workloads |
|
|
57
58
|
| Skills Marketplace | `marketplace.md` | Install org-internal skills |
|
|
58
59
|
|
|
59
60
|
## Setup walkthrough
|
package/skills/pncli/ado.md
CHANGED
|
@@ -6,13 +6,13 @@ Enables: `pncli ado workitem`, `pncli ado repo`, `pncli ado repo create`, `pncli
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `ado.baseUrl` | `PNCLI_ADO_BASE_URL` | ADO Server root, e.g. `https://tfs.
|
|
9
|
+
| `ado.baseUrl` | `PNCLI_ADO_BASE_URL` | ADO Server root, e.g. `https://tfs.imagile.dev` |
|
|
10
10
|
| `ado.pat` | `PNCLI_ADO_PAT` | Personal access token |
|
|
11
11
|
|
|
12
12
|
## Config file (persistent)
|
|
13
13
|
|
|
14
14
|
```
|
|
15
|
-
pncli config set ado.baseUrl https://tfs.
|
|
15
|
+
pncli config set ado.baseUrl https://tfs.imagile.dev
|
|
16
16
|
pncli config set ado.pat <token>
|
|
17
17
|
pncli config set defaults.ado.collection DefaultCollection
|
|
18
18
|
pncli config set defaults.ado.project MyProject
|
|
@@ -21,7 +21,7 @@ pncli config set defaults.ado.project MyProject
|
|
|
21
21
|
## Env vars (ephemeral / CI)
|
|
22
22
|
|
|
23
23
|
```
|
|
24
|
-
export PNCLI_ADO_BASE_URL=https://tfs.
|
|
24
|
+
export PNCLI_ADO_BASE_URL=https://tfs.imagile.dev
|
|
25
25
|
export PNCLI_ADO_PAT=<token>
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -6,7 +6,7 @@ Enables: `pncli artifactory repo`, `pncli artifactory package` — list reposito
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `artifactory.baseUrl` | `PNCLI_ARTIFACTORY_BASE_URL` | Artifactory root, e.g. `https://artifactory.
|
|
9
|
+
| `artifactory.baseUrl` | `PNCLI_ARTIFACTORY_BASE_URL` | Artifactory root, e.g. `https://artifactory.imagile.dev` |
|
|
10
10
|
| `artifactory.token` | `PNCLI_ARTIFACTORY_TOKEN` | Identity token or API key |
|
|
11
11
|
|
|
12
12
|
## Optional — virtual repo names
|
|
@@ -20,7 +20,7 @@ Enables: `pncli artifactory repo`, `pncli artifactory package` — list reposito
|
|
|
20
20
|
## Config file (persistent)
|
|
21
21
|
|
|
22
22
|
```
|
|
23
|
-
pncli config set artifactory.baseUrl https://artifactory.
|
|
23
|
+
pncli config set artifactory.baseUrl https://artifactory.imagile.dev
|
|
24
24
|
pncli config set artifactory.token <token>
|
|
25
25
|
pncli config set artifactory.npmRepo npm-virtual
|
|
26
26
|
pncli config set artifactory.nugetRepo nuget-virtual
|
|
@@ -30,6 +30,6 @@ pncli config set artifactory.mavenRepo maven-virtual
|
|
|
30
30
|
## Env vars (ephemeral / CI)
|
|
31
31
|
|
|
32
32
|
```
|
|
33
|
-
export PNCLI_ARTIFACTORY_BASE_URL=https://artifactory.
|
|
33
|
+
export PNCLI_ARTIFACTORY_BASE_URL=https://artifactory.imagile.dev
|
|
34
34
|
export PNCLI_ARTIFACTORY_TOKEN=<token>
|
|
35
35
|
```
|
|
@@ -6,20 +6,20 @@ Enables: `pncli bitbucket create-repo`, `pncli bitbucket list-prs`, `pncli bitbu
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `bitbucket.baseUrl` | `PNCLI_BITBUCKET_BASE_URL` | Bitbucket Server root, e.g. `https://bitbucket.
|
|
9
|
+
| `bitbucket.baseUrl` | `PNCLI_BITBUCKET_BASE_URL` | Bitbucket Server root, e.g. `https://bitbucket.imagile.dev` |
|
|
10
10
|
| `bitbucket.pat` | `PNCLI_BITBUCKET_PAT` | Personal access token |
|
|
11
11
|
|
|
12
12
|
## Config file (persistent)
|
|
13
13
|
|
|
14
14
|
```
|
|
15
|
-
pncli config set bitbucket.baseUrl https://bitbucket.
|
|
15
|
+
pncli config set bitbucket.baseUrl https://bitbucket.imagile.dev
|
|
16
16
|
pncli config set bitbucket.pat <token>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Env vars (ephemeral / CI)
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
export PNCLI_BITBUCKET_BASE_URL=https://bitbucket.
|
|
22
|
+
export PNCLI_BITBUCKET_BASE_URL=https://bitbucket.imagile.dev
|
|
23
23
|
export PNCLI_BITBUCKET_PAT=<token>
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -1,31 +1,38 @@
|
|
|
1
1
|
# Checkmarx
|
|
2
2
|
|
|
3
|
-
Enables: `pncli checkmarx
|
|
4
|
-
|
|
5
|
-
> **Not officially supported.** Checkmarx CxSAST on-premise does not expose stable PAT-based authentication on all versions. pncli performs the OAuth2 token exchange using username and password, but behaviour varies across CxSAST versions. Use with caution and test connectivity with `pncli config test` before relying on it.
|
|
3
|
+
Enables: `pncli checkmarx project list/get`, `pncli checkmarx scan list/get/stats` — list projects, scans, and vulnerability statistics in Checkmarx One.
|
|
6
4
|
|
|
7
5
|
## Required config
|
|
8
6
|
|
|
9
7
|
| Key | Env var | Description |
|
|
10
8
|
|-----|---------|-------------|
|
|
11
|
-
| `checkmarx.baseUrl` | `PNCLI_CHECKMARX_BASE_URL` |
|
|
12
|
-
| `checkmarx.
|
|
13
|
-
| `checkmarx.
|
|
9
|
+
| `checkmarx.baseUrl` | `PNCLI_CHECKMARX_BASE_URL` | Checkmarx One API base, e.g. `https://ast.checkmarx.net/api` |
|
|
10
|
+
| `checkmarx.tenantName` | `PNCLI_CHECKMARX_TENANT_NAME` | IAM realm / tenant name, e.g. `imagile` |
|
|
11
|
+
| `checkmarx.apiKey` | `PNCLI_CHECKMARX_API_KEY` | API key created in Checkmarx One IAM (recommended) |
|
|
12
|
+
| `checkmarx.clientId` | `PNCLI_CHECKMARX_CLIENT_ID` | OAuth2 client ID (alternative to API key) |
|
|
13
|
+
| `checkmarx.clientSecret` | `PNCLI_CHECKMARX_CLIENT_SECRET` | OAuth2 client secret (alternative to API key) |
|
|
14
14
|
|
|
15
|
-
pncli
|
|
15
|
+
pncli exchanges either an API key (refresh token) or OAuth client credentials for a
|
|
16
|
+
short-lived bearer token automatically. No external tools are required.
|
|
16
17
|
|
|
17
18
|
## Config file (persistent)
|
|
18
19
|
|
|
19
20
|
```
|
|
20
|
-
pncli config set checkmarx.baseUrl https://
|
|
21
|
-
pncli config set checkmarx.
|
|
22
|
-
pncli config set checkmarx.
|
|
21
|
+
pncli config set checkmarx.baseUrl https://ast.checkmarx.net/api
|
|
22
|
+
pncli config set checkmarx.tenantName imagile
|
|
23
|
+
pncli config set checkmarx.apiKey <api-key>
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
## Env vars (ephemeral / CI)
|
|
26
27
|
|
|
27
28
|
```
|
|
28
|
-
export PNCLI_CHECKMARX_BASE_URL=https://
|
|
29
|
-
export
|
|
30
|
-
export
|
|
29
|
+
export PNCLI_CHECKMARX_BASE_URL=https://ast.checkmarx.net/api
|
|
30
|
+
export PNCLI_CHECKMARX_TENANT_NAME=imagile
|
|
31
|
+
export PNCLI_CHECKMARX_API_KEY=<api-key>
|
|
31
32
|
```
|
|
33
|
+
|
|
34
|
+
## Regional deployments
|
|
35
|
+
|
|
36
|
+
For EU or other regional Checkmarx One instances, use the appropriate API base URL
|
|
37
|
+
(e.g. `https://eu.ast.checkmarx.net/api`). pncli derives the matching regional IAM host
|
|
38
|
+
(e.g. `https://eu.iam.checkmarx.net`) from that URL.
|
|
@@ -6,20 +6,20 @@ Enables: `pncli confluence get-page`, `create-page`, `update-page`, `delete-page
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `confluence.baseUrl` | `PNCLI_CONFLUENCE_BASE_URL` | Confluence server root, e.g. `https://confluence.
|
|
9
|
+
| `confluence.baseUrl` | `PNCLI_CONFLUENCE_BASE_URL` | Confluence server root, e.g. `https://confluence.imagile.dev` |
|
|
10
10
|
| `confluence.apiToken` | `PNCLI_CONFLUENCE_API_TOKEN` | Personal access token |
|
|
11
11
|
|
|
12
12
|
## Config file (persistent)
|
|
13
13
|
|
|
14
14
|
```
|
|
15
|
-
pncli config set confluence.baseUrl https://confluence.
|
|
15
|
+
pncli config set confluence.baseUrl https://confluence.imagile.dev
|
|
16
16
|
pncli config set confluence.apiToken <token>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Env vars (ephemeral / CI)
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
export PNCLI_CONFLUENCE_BASE_URL=https://confluence.
|
|
22
|
+
export PNCLI_CONFLUENCE_BASE_URL=https://confluence.imagile.dev
|
|
23
23
|
export PNCLI_CONFLUENCE_API_TOKEN=<token>
|
|
24
24
|
```
|
|
25
25
|
|
package/skills/pncli/contrast.md
CHANGED
|
@@ -16,7 +16,7 @@ All four credential keys are found in your Contrast account under **User Setting
|
|
|
16
16
|
|
|
17
17
|
**Base URL examples:**
|
|
18
18
|
- Cloud SaaS: `https://app.contrastsecurity.com`
|
|
19
|
-
- On-premise: `https://contrast.
|
|
19
|
+
- On-premise: `https://contrast.imagile.dev`
|
|
20
20
|
|
|
21
21
|
## Config file (persistent)
|
|
22
22
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Dynatrace
|
|
2
|
+
|
|
3
|
+
pncli uses Dynatrace's REST APIs directly; no Dynatrace CLI is required.
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
| Key | Environment variable | Purpose |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `dynatrace.baseUrl` | `PNCLI_DYNATRACE_BASE_URL` | Classic environment URL, such as `https://abc12345.live.dynatrace.com` |
|
|
10
|
+
| `dynatrace.apiToken` | `PNCLI_DYNATRACE_API_TOKEN` | Environment API token with `entities.read` and `problems.read` |
|
|
11
|
+
| `dynatrace.platformUrl` | `PNCLI_DYNATRACE_PLATFORM_URL` | Optional latest-platform URL, such as `https://abc12345.apps.dynatrace.com` |
|
|
12
|
+
| `dynatrace.platformToken` | `PNCLI_DYNATRACE_PLATFORM_TOKEN` | Optional platform token with permission to query spans in Grail |
|
|
13
|
+
|
|
14
|
+
The Environment API token supports entities, services, Kubernetes workloads, and problems. Distributed
|
|
15
|
+
trace data is stored in Grail and requires the separate latest-platform URL and Bearer platform token.
|
|
16
|
+
The classic `traces.lookup` scope only checks whether a trace exists for cross-environment tracing and
|
|
17
|
+
does not grant an API for retrieving its spans.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pncli config set dynatrace.baseUrl https://abc12345.live.dynatrace.com
|
|
21
|
+
pncli config set dynatrace.apiToken dt0c01...
|
|
22
|
+
pncli config set dynatrace.platformUrl https://abc12345.apps.dynatrace.com
|
|
23
|
+
pncli config set dynatrace.platformToken dt0s16...
|
|
24
|
+
pncli config test
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
When platform credentials are present, `config test` and `config check` also run a minimal Grail
|
|
28
|
+
spans query and report it separately as `dynatrace_platform`.
|
|
29
|
+
|
|
30
|
+
## Commands
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pncli dynatrace services --from now-2h
|
|
34
|
+
pncli dynatrace workloads --from now-2h
|
|
35
|
+
pncli dynatrace entities list --selector 'type("HOST")'
|
|
36
|
+
pncli dynatrace entities get --id SERVICE-1234567890ABCDEF
|
|
37
|
+
|
|
38
|
+
pncli dynatrace problems list --from now-24h
|
|
39
|
+
pncli dynatrace problems list --problem-selector 'status("OPEN")'
|
|
40
|
+
pncli dynatrace problems get --id 1234567890_1234567890V2
|
|
41
|
+
|
|
42
|
+
pncli dynatrace trace --id 0123456789abcdef0123456789abcdef
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Entity and problem list commands automatically follow Dynatrace pagination. Use Dynatrace selector
|
|
46
|
+
syntax for advanced filtering.
|
package/skills/pncli/jenkins.md
CHANGED
|
@@ -6,7 +6,7 @@ Enables: `pncli jenkins build`, `pncli jenkins job` — list builds, get build s
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `jenkins.baseUrl` | `PNCLI_JENKINS_BASE_URL` | Jenkins root, e.g. `https://jenkins.
|
|
9
|
+
| `jenkins.baseUrl` | `PNCLI_JENKINS_BASE_URL` | Jenkins root, e.g. `https://jenkins.imagile.dev` |
|
|
10
10
|
| `jenkins.username` | `PNCLI_JENKINS_USERNAME` | Jenkins username |
|
|
11
11
|
| `jenkins.apiToken` | `PNCLI_JENKINS_API_TOKEN` | API token (generated in Jenkins → User → Configure → API Token) |
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ pncli authenticates using HTTP Basic (username + API token).
|
|
|
15
15
|
## Config file (persistent)
|
|
16
16
|
|
|
17
17
|
```
|
|
18
|
-
pncli config set jenkins.baseUrl https://jenkins.
|
|
18
|
+
pncli config set jenkins.baseUrl https://jenkins.imagile.dev
|
|
19
19
|
pncli config set jenkins.username <username>
|
|
20
20
|
pncli config set jenkins.apiToken <token>
|
|
21
21
|
```
|
|
@@ -23,7 +23,7 @@ pncli config set jenkins.apiToken <token>
|
|
|
23
23
|
## Env vars (ephemeral / CI)
|
|
24
24
|
|
|
25
25
|
```
|
|
26
|
-
export PNCLI_JENKINS_BASE_URL=https://jenkins.
|
|
26
|
+
export PNCLI_JENKINS_BASE_URL=https://jenkins.imagile.dev
|
|
27
27
|
export PNCLI_JENKINS_USERNAME=<username>
|
|
28
28
|
export PNCLI_JENKINS_API_TOKEN=<token>
|
|
29
29
|
```
|
|
@@ -36,7 +36,7 @@ Teams with different Jenkins controllers per repo can set `defaults.jenkins.base
|
|
|
36
36
|
{
|
|
37
37
|
"defaults": {
|
|
38
38
|
"jenkins": {
|
|
39
|
-
"baseUrl": "https://jenkins.myteam.
|
|
39
|
+
"baseUrl": "https://jenkins.myteam.imagile.dev"
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -45,7 +45,7 @@ Teams with different Jenkins controllers per repo can set `defaults.jenkins.base
|
|
|
45
45
|
Or via the CLI:
|
|
46
46
|
|
|
47
47
|
```
|
|
48
|
-
pncli config set --repo defaults.jenkins.baseUrl https://jenkins.myteam.
|
|
48
|
+
pncli config set --repo defaults.jenkins.baseUrl https://jenkins.myteam.imagile.dev
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
Resolution order (highest to lowest): project `.pncli.json` → global config → `PNCLI_JENKINS_BASE_URL` env var.
|
package/skills/pncli/jira.md
CHANGED
|
@@ -6,20 +6,20 @@ Enables: `pncli jira get-issue`, `create-issue`, `update-issue`, `search`, `list
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `jira.baseUrl` | `PNCLI_JIRA_BASE_URL` | Jira server root, e.g. `https://jira.
|
|
9
|
+
| `jira.baseUrl` | `PNCLI_JIRA_BASE_URL` | Jira server root, e.g. `https://jira.imagile.dev` |
|
|
10
10
|
| `jira.apiToken` | `PNCLI_JIRA_API_TOKEN` | Personal access token |
|
|
11
11
|
|
|
12
12
|
## Config file (persistent)
|
|
13
13
|
|
|
14
14
|
```
|
|
15
|
-
pncli config set jira.baseUrl https://jira.
|
|
15
|
+
pncli config set jira.baseUrl https://jira.imagile.dev
|
|
16
16
|
pncli config set jira.apiToken <token>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Env vars (ephemeral / CI)
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
export PNCLI_JIRA_BASE_URL=https://jira.
|
|
22
|
+
export PNCLI_JIRA_BASE_URL=https://jira.imagile.dev
|
|
23
23
|
export PNCLI_JIRA_API_TOKEN=<token>
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -12,7 +12,7 @@ Use `--branch main` if the default branch is `main` instead of `master`. Use `--
|
|
|
12
12
|
|
|
13
13
|
**Example:**
|
|
14
14
|
```
|
|
15
|
-
pncli skills marketplace add https://bitbucket.
|
|
15
|
+
pncli skills marketplace add https://bitbucket.imagile.dev/scm/ai/skills.git --name internal-ai
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
You can register as many marketplaces as you like — just run `add` again with a different URL. `marketplace setup` is kept as an alias of `add` for backward compatibility.
|
|
@@ -7,7 +7,7 @@ No `kubectl` or `oc` CLI is required.
|
|
|
7
7
|
|
|
8
8
|
| Key | Env var | Description |
|
|
9
9
|
|-----|---------|-------------|
|
|
10
|
-
| `openshift.baseUrl` | `PNCLI_OPENSHIFT_BASE_URL` | API server URL, e.g. `https://api.cluster.
|
|
10
|
+
| `openshift.baseUrl` | `PNCLI_OPENSHIFT_BASE_URL` | API server URL, e.g. `https://api.cluster.imagile.dev:6443` |
|
|
11
11
|
| `openshift.token` | `PNCLI_OPENSHIFT_TOKEN` | Service account bearer token |
|
|
12
12
|
|
|
13
13
|
## Getting your service account token
|
|
@@ -20,7 +20,7 @@ cat /var/run/secrets/kubernetes.io/serviceaccount/token
|
|
|
20
20
|
**Via OpenShift REST API** (using an existing token):
|
|
21
21
|
```bash
|
|
22
22
|
curl -H "Authorization: Bearer $EXISTING_TOKEN" \
|
|
23
|
-
https://api.cluster.
|
|
23
|
+
https://api.cluster.imagile.dev:6443/api/v1/namespaces/my-ns/serviceaccounts/default/token \
|
|
24
24
|
-X POST -H 'Content-Type: application/json' \
|
|
25
25
|
-d '{"apiVersion":"authentication.k8s.io/v1","kind":"TokenRequest","spec":{"expirationSeconds":3600}}'
|
|
26
26
|
```
|
|
@@ -28,14 +28,14 @@ curl -H "Authorization: Bearer $EXISTING_TOKEN" \
|
|
|
28
28
|
## Set via env vars (ephemeral)
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
export PNCLI_OPENSHIFT_BASE_URL=https://api.cluster.
|
|
31
|
+
export PNCLI_OPENSHIFT_BASE_URL=https://api.cluster.imagile.dev:6443
|
|
32
32
|
export PNCLI_OPENSHIFT_TOKEN=eyJhbGciOiJSUzI1NiI...
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
## Set via config file (persistent)
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
pncli config set openshift.baseUrl https://api.cluster.
|
|
38
|
+
pncli config set openshift.baseUrl https://api.cluster.imagile.dev:6443
|
|
39
39
|
pncli config set openshift.token eyJhbGciOiJSUzI1NiI...
|
|
40
40
|
```
|
|
41
41
|
|
package/skills/pncli/sde.md
CHANGED
|
@@ -8,18 +8,18 @@ Enables: `pncli sde task` — list threat model tasks and their compliance statu
|
|
|
8
8
|
|-----|---------|-------------|
|
|
9
9
|
| `sde.connection` | `PNCLI_SDE_CONNECTION` | Connection string in the format `token@hostname` |
|
|
10
10
|
|
|
11
|
-
The connection string combines your API token and the SDElements hostname into a single value, e.g. `mytoken@sde.
|
|
11
|
+
The connection string combines your API token and the SDElements hostname into a single value, e.g. `mytoken@sde.imagile.dev`.
|
|
12
12
|
|
|
13
13
|
## Config file (persistent)
|
|
14
14
|
|
|
15
15
|
```
|
|
16
|
-
pncli config set sde.connection mytoken@sde.
|
|
16
|
+
pncli config set sde.connection mytoken@sde.imagile.dev
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Env vars (ephemeral / CI)
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
export PNCLI_SDE_CONNECTION=mytoken@sde.
|
|
22
|
+
export PNCLI_SDE_CONNECTION=mytoken@sde.imagile.dev
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Repo defaults
|
|
@@ -6,7 +6,7 @@ Enables: `pncli servicenow change`, `pncli servicenow incident` — list and get
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `servicenow.baseUrl` | `PNCLI_SERVICENOW_BASE_URL` | Instance root, e.g. `https://
|
|
9
|
+
| `servicenow.baseUrl` | `PNCLI_SERVICENOW_BASE_URL` | Instance root, e.g. `https://imagile.service-now.com` |
|
|
10
10
|
| `servicenow.username` | `PNCLI_SERVICENOW_USERNAME` | ServiceNow username |
|
|
11
11
|
|
|
12
12
|
### Auth — password or API token (one required)
|
|
@@ -19,7 +19,7 @@ Enables: `pncli servicenow change`, `pncli servicenow incident` — list and get
|
|
|
19
19
|
## Config file (persistent)
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
pncli config set servicenow.baseUrl https://
|
|
22
|
+
pncli config set servicenow.baseUrl https://imagile.service-now.com
|
|
23
23
|
pncli config set servicenow.username <username>
|
|
24
24
|
pncli config set servicenow.password <password>
|
|
25
25
|
```
|
|
@@ -27,7 +27,7 @@ pncli config set servicenow.password <password>
|
|
|
27
27
|
## Env vars (ephemeral / CI)
|
|
28
28
|
|
|
29
29
|
```
|
|
30
|
-
export PNCLI_SERVICENOW_BASE_URL=https://
|
|
30
|
+
export PNCLI_SERVICENOW_BASE_URL=https://imagile.service-now.com
|
|
31
31
|
export PNCLI_SERVICENOW_USERNAME=<username>
|
|
32
32
|
export PNCLI_SERVICENOW_PASSWORD=<password>
|
|
33
33
|
```
|
|
@@ -6,20 +6,20 @@ Enables: `pncli sonar issue`, `pncli sonar project` — list code quality and se
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `sonar.baseUrl` | `PNCLI_SONAR_BASE_URL` | SonarQube server root, e.g. `https://sonar.
|
|
9
|
+
| `sonar.baseUrl` | `PNCLI_SONAR_BASE_URL` | SonarQube server root, e.g. `https://sonar.imagile.dev` |
|
|
10
10
|
| `sonar.token` | `PNCLI_SONAR_TOKEN` | User token (generated in SonarQube → My Account → Security) |
|
|
11
11
|
|
|
12
12
|
## Config file (persistent)
|
|
13
13
|
|
|
14
14
|
```
|
|
15
|
-
pncli config set sonar.baseUrl https://sonar.
|
|
15
|
+
pncli config set sonar.baseUrl https://sonar.imagile.dev
|
|
16
16
|
pncli config set sonar.token <token>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Env vars (ephemeral / CI)
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
export PNCLI_SONAR_BASE_URL=https://sonar.
|
|
22
|
+
export PNCLI_SONAR_BASE_URL=https://sonar.imagile.dev
|
|
23
23
|
export PNCLI_SONAR_TOKEN=<token>
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -6,7 +6,7 @@ Enables: `pncli sonatypeiq applications`, `pncli deps frisk --source sonatypeiq`
|
|
|
6
6
|
|
|
7
7
|
| Key | Env var | Description |
|
|
8
8
|
|-----|---------|-------------|
|
|
9
|
-
| `sonatypeiq.baseUrl` | `PNCLI_SONATYPEIQ_BASE_URL` | IQ Server root, e.g. `https://iq.
|
|
9
|
+
| `sonatypeiq.baseUrl` | `PNCLI_SONATYPEIQ_BASE_URL` | IQ Server root, e.g. `https://iq.imagile.dev` |
|
|
10
10
|
| `sonatypeiq.userCode` | `PNCLI_SONATYPEIQ_USER_CODE` | User Token code (from User Menu → User Token) |
|
|
11
11
|
| `sonatypeiq.passcode` | `PNCLI_SONATYPEIQ_PASSCODE` | User Token passcode (from User Menu → User Token) |
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ The `userCode` and `passcode` are User Token credentials, not your login passwor
|
|
|
15
15
|
## Config file (persistent)
|
|
16
16
|
|
|
17
17
|
```
|
|
18
|
-
pncli config set sonatypeiq.baseUrl https://iq.
|
|
18
|
+
pncli config set sonatypeiq.baseUrl https://iq.imagile.dev
|
|
19
19
|
pncli config set sonatypeiq.userCode <user-code>
|
|
20
20
|
pncli config set sonatypeiq.passcode <passcode>
|
|
21
21
|
```
|
|
@@ -23,7 +23,7 @@ pncli config set sonatypeiq.passcode <passcode>
|
|
|
23
23
|
## Env vars (ephemeral / CI)
|
|
24
24
|
|
|
25
25
|
```
|
|
26
|
-
export PNCLI_SONATYPEIQ_BASE_URL=https://iq.
|
|
26
|
+
export PNCLI_SONATYPEIQ_BASE_URL=https://iq.imagile.dev
|
|
27
27
|
export PNCLI_SONATYPEIQ_USER_CODE=<user-code>
|
|
28
28
|
export PNCLI_SONATYPEIQ_PASSCODE=<passcode>
|
|
29
29
|
```
|
package/skills/pncli/udeploy.md
CHANGED
|
@@ -8,7 +8,7 @@ Enables: `pncli udeploy component`, `pncli udeploy version`, `pncli udeploy proc
|
|
|
8
8
|
|
|
9
9
|
| Key | Env var | Description |
|
|
10
10
|
|-----|---------|-------------|
|
|
11
|
-
| `udeploy.baseUrl` | `PNCLI_UDEPLOY_BASE_URL` | UCD server root, e.g. `https://ucd.
|
|
11
|
+
| `udeploy.baseUrl` | `PNCLI_UDEPLOY_BASE_URL` | UCD server root, e.g. `https://ucd.imagile.dev` |
|
|
12
12
|
|
|
13
13
|
### Auth option A — PAT
|
|
14
14
|
|
|
@@ -26,7 +26,7 @@ Enables: `pncli udeploy component`, `pncli udeploy version`, `pncli udeploy proc
|
|
|
26
26
|
## Config file (persistent)
|
|
27
27
|
|
|
28
28
|
```
|
|
29
|
-
pncli config set udeploy.baseUrl https://ucd.
|
|
29
|
+
pncli config set udeploy.baseUrl https://ucd.imagile.dev
|
|
30
30
|
pncli config set udeploy.pat <token>
|
|
31
31
|
# or
|
|
32
32
|
pncli config set udeploy.username <username>
|
|
@@ -36,7 +36,7 @@ pncli config set udeploy.password <password>
|
|
|
36
36
|
## Env vars (ephemeral / CI)
|
|
37
37
|
|
|
38
38
|
```
|
|
39
|
-
export PNCLI_UDEPLOY_BASE_URL=https://ucd.
|
|
39
|
+
export PNCLI_UDEPLOY_BASE_URL=https://ucd.imagile.dev
|
|
40
40
|
export PNCLI_UDEPLOY_PAT=<token>
|
|
41
41
|
```
|
|
42
42
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/config.ts"],"sourcesContent":["import fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport type { GlobalConfig, RepoConfig, ResolvedConfig, JiraDefaults, BitbucketDefaults, GitHubDefaults, SonarDefaults, SdeDefaults, AdoDefaults, UdeployDefaults, JenkinsDefaults } from '../types/config.js';\nimport type { CustomFieldDefinition } from '../types/jira.js';\n\nconst ENV_KEYS = {\n EMAIL: 'PNCLI_EMAIL',\n USERID: 'PNCLI_USERID',\n JIRA_BASE_URL: 'PNCLI_JIRA_BASE_URL',\n JIRA_API_TOKEN: 'PNCLI_JIRA_API_TOKEN',\n BITBUCKET_BASE_URL: 'PNCLI_BITBUCKET_BASE_URL',\n BITBUCKET_PAT: 'PNCLI_BITBUCKET_PAT',\n GITHUB_BASE_URL: 'PNCLI_GITHUB_BASE_URL',\n GITHUB_TOKEN: 'PNCLI_GITHUB_TOKEN',\n CONFLUENCE_BASE_URL: 'PNCLI_CONFLUENCE_BASE_URL',\n CONFLUENCE_API_TOKEN: 'PNCLI_CONFLUENCE_API_TOKEN',\n ARTIFACTORY_BASE_URL: 'PNCLI_ARTIFACTORY_BASE_URL',\n ARTIFACTORY_TOKEN: 'PNCLI_ARTIFACTORY_TOKEN',\n ARTIFACTORY_REPO_NPM: 'PNCLI_ARTIFACTORY_REPO_NPM',\n ARTIFACTORY_REPO_NUGET: 'PNCLI_ARTIFACTORY_REPO_NUGET',\n ARTIFACTORY_REPO_MAVEN: 'PNCLI_ARTIFACTORY_REPO_MAVEN',\n SONAR_BASE_URL: 'PNCLI_SONAR_BASE_URL',\n SONAR_TOKEN: 'PNCLI_SONAR_TOKEN',\n SDE_CONNECTION: 'PNCLI_SDE_CONNECTION',\n ADO_BASE_URL: 'PNCLI_ADO_BASE_URL',\n ADO_PAT: 'PNCLI_ADO_PAT',\n JENKINS_BASE_URL: 'PNCLI_JENKINS_BASE_URL',\n JENKINS_USERNAME: 'PNCLI_JENKINS_USERNAME',\n JENKINS_API_TOKEN: 'PNCLI_JENKINS_API_TOKEN',\n UDEPLOY_BASE_URL: 'PNCLI_UDEPLOY_BASE_URL',\n UDEPLOY_PAT: 'PNCLI_UDEPLOY_PAT',\n UDEPLOY_USERNAME: 'PNCLI_UDEPLOY_USERNAME',\n UDEPLOY_PASSWORD: 'PNCLI_UDEPLOY_PASSWORD',\n CHECKMARX_BASE_URL: 'PNCLI_CHECKMARX_BASE_URL',\n CHECKMARX_USERNAME: 'PNCLI_CHECKMARX_USERNAME',\n CHECKMARX_PASSWORD: 'PNCLI_CHECKMARX_PASSWORD',\n SERVICENOW_BASE_URL: 'PNCLI_SERVICENOW_BASE_URL',\n SERVICENOW_USERNAME: 'PNCLI_SERVICENOW_USERNAME',\n SERVICENOW_PASSWORD: 'PNCLI_SERVICENOW_PASSWORD',\n SERVICENOW_API_TOKEN: 'PNCLI_SERVICENOW_API_TOKEN',\n CONTRAST_BASE_URL: 'PNCLI_CONTRAST_BASE_URL',\n CONTRAST_ORG_UUID: 'PNCLI_CONTRAST_ORG_UUID',\n CONTRAST_API_KEY: 'PNCLI_CONTRAST_API_KEY',\n CONTRAST_SERVICE_KEY: 'PNCLI_CONTRAST_SERVICE_KEY',\n CONTRAST_USERNAME: 'PNCLI_CONTRAST_USERNAME',\n SONATYPEIQ_BASE_URL: 'PNCLI_SONATYPEIQ_BASE_URL',\n SONATYPEIQ_USER_CODE: 'PNCLI_SONATYPEIQ_USER_CODE',\n SONATYPEIQ_PASSCODE: 'PNCLI_SONATYPEIQ_PASSCODE',\n OPENSHIFT_BASE_URL: 'PNCLI_OPENSHIFT_BASE_URL',\n OPENSHIFT_TOKEN: 'PNCLI_OPENSHIFT_TOKEN',\n CONFIG_PATH: 'PNCLI_CONFIG_PATH'\n} as const;\n\nfunction getGlobalConfigPath(overridePath?: string): string {\n if (overridePath) return overridePath;\n const envPath = process.env[ENV_KEYS.CONFIG_PATH];\n if (envPath) return envPath;\n return path.join(os.homedir(), '.pncli', 'config.json');\n}\n\nfunction loadJsonFile<T>(filePath: string): T | null {\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nfunction getRepoRoot(): string | null {\n try {\n return execSync('git rev-parse --show-toplevel', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();\n } catch {\n return null;\n }\n}\n\nfunction parseSdeConnection(connection: string): { token: string; baseUrl: string } | null {\n const idx = connection.indexOf('@');\n if (idx <= 0) return null;\n const token = connection.slice(0, idx);\n const host = connection.slice(idx + 1);\n const baseUrl = /^https?:\\/\\//i.test(host) ? host : `https://${host}`;\n return { token, baseUrl };\n}\n\nfunction mergeCustomFields(\n global: CustomFieldDefinition[] | undefined,\n repo: CustomFieldDefinition[] | undefined\n): CustomFieldDefinition[] {\n const map = new Map<string, CustomFieldDefinition>();\n for (const f of global ?? []) map.set(f.id, f);\n for (const f of repo ?? []) map.set(f.id, f); // repo wins\n return Array.from(map.values());\n}\n\nfunction mergeDefaults(\n global: GlobalConfig['defaults'],\n repo: RepoConfig['defaults']\n): { jira: JiraDefaults; bitbucket: BitbucketDefaults; github: GitHubDefaults; sonar: SonarDefaults; sde: SdeDefaults; ado: AdoDefaults; udeploy: UdeployDefaults; jenkins: JenkinsDefaults } {\n return {\n jira: { ...global?.jira, ...repo?.jira },\n bitbucket: { ...global?.bitbucket, ...repo?.bitbucket },\n github: { ...global?.github, ...repo?.github },\n sonar: { ...global?.sonar, ...repo?.sonar },\n sde: { ...global?.sde, ...repo?.sde },\n ado: { ...global?.ado, ...repo?.ado },\n udeploy: { ...global?.udeploy, ...repo?.udeploy },\n jenkins: { ...global?.jenkins, ...repo?.jenkins }\n };\n}\n\nexport interface LoadConfigOptions {\n configPath?: string;\n}\n\nexport function loadConfig(opts: LoadConfigOptions = {}): ResolvedConfig {\n const globalConfigPath = getGlobalConfigPath(opts.configPath);\n const globalConfig = loadJsonFile<GlobalConfig>(globalConfigPath) ?? {};\n\n const repoRoot = getRepoRoot();\n let repoConfig: RepoConfig = {};\n if (repoRoot) {\n repoConfig = loadJsonFile<RepoConfig>(path.join(repoRoot, '.pncli.json')) ?? {};\n }\n\n const mergedDefaults = mergeDefaults(globalConfig.defaults, repoConfig.defaults);\n\n return {\n user: {\n email: process.env[ENV_KEYS.EMAIL] ?? globalConfig.user?.email,\n userId: process.env[ENV_KEYS.USERID] ?? globalConfig.user?.userId\n },\n jira: {\n baseUrl: process.env[ENV_KEYS.JIRA_BASE_URL] ?? globalConfig.jira?.baseUrl,\n apiToken: process.env[ENV_KEYS.JIRA_API_TOKEN] ?? globalConfig.jira?.apiToken,\n customFields: mergeCustomFields(globalConfig.jira?.customFields, repoConfig.jira?.customFields)\n },\n bitbucket: {\n baseUrl: process.env[ENV_KEYS.BITBUCKET_BASE_URL] ?? globalConfig.bitbucket?.baseUrl,\n pat: process.env[ENV_KEYS.BITBUCKET_PAT] ?? globalConfig.bitbucket?.pat\n },\n github: {\n baseUrl: process.env[ENV_KEYS.GITHUB_BASE_URL] ?? globalConfig.github?.baseUrl,\n token: process.env[ENV_KEYS.GITHUB_TOKEN] ?? globalConfig.github?.token\n },\n confluence: {\n baseUrl: process.env[ENV_KEYS.CONFLUENCE_BASE_URL] ?? globalConfig.confluence?.baseUrl,\n apiToken: process.env[ENV_KEYS.CONFLUENCE_API_TOKEN] ?? globalConfig.confluence?.apiToken\n ?? process.env[ENV_KEYS.JIRA_API_TOKEN] ?? globalConfig.jira?.apiToken,\n apiTokenExplicit: !!(\n process.env[ENV_KEYS.CONFLUENCE_API_TOKEN] ?? globalConfig.confluence?.apiToken\n )\n },\n artifactory: {\n baseUrl: process.env[ENV_KEYS.ARTIFACTORY_BASE_URL] ?? globalConfig.artifactory?.baseUrl,\n token: process.env[ENV_KEYS.ARTIFACTORY_TOKEN] ?? globalConfig.artifactory?.token,\n npmRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_NPM] ?? globalConfig.artifactory?.npmRepo,\n nugetRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_NUGET] ?? globalConfig.artifactory?.nugetRepo,\n mavenRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_MAVEN] ?? globalConfig.artifactory?.mavenRepo\n },\n sonar: {\n baseUrl: process.env[ENV_KEYS.SONAR_BASE_URL] ?? globalConfig.sonar?.baseUrl,\n token: process.env[ENV_KEYS.SONAR_TOKEN] ?? globalConfig.sonar?.token\n },\n sde: (() => {\n const raw = process.env[ENV_KEYS.SDE_CONNECTION] ?? globalConfig.sde?.connection;\n const parsed = raw ? parseSdeConnection(raw) : null;\n return { baseUrl: parsed?.baseUrl, token: parsed?.token };\n })(),\n ado: {\n baseUrl: process.env[ENV_KEYS.ADO_BASE_URL] ?? globalConfig.ado?.baseUrl,\n pat: process.env[ENV_KEYS.ADO_PAT] ?? globalConfig.ado?.pat,\n fieldAliases: globalConfig.ado?.fieldAliases ?? {},\n discoveredFields: globalConfig.ado?.discoveredFields ?? [],\n discoveredTypes: globalConfig.ado?.discoveredTypes ?? []\n },\n jenkins: {\n baseUrl: repoConfig.defaults?.jenkins?.baseUrl ?? process.env[ENV_KEYS.JENKINS_BASE_URL] ?? globalConfig.jenkins?.baseUrl,\n username: process.env[ENV_KEYS.JENKINS_USERNAME] ?? globalConfig.jenkins?.username,\n apiToken: process.env[ENV_KEYS.JENKINS_API_TOKEN] ?? globalConfig.jenkins?.apiToken\n },\n udeploy: {\n baseUrl: process.env[ENV_KEYS.UDEPLOY_BASE_URL] ?? globalConfig.udeploy?.baseUrl,\n pat: process.env[ENV_KEYS.UDEPLOY_PAT] ?? globalConfig.udeploy?.pat,\n username: process.env[ENV_KEYS.UDEPLOY_USERNAME] ?? globalConfig.udeploy?.username,\n password: process.env[ENV_KEYS.UDEPLOY_PASSWORD] ?? globalConfig.udeploy?.password,\n },\n checkmarx: {\n baseUrl: process.env[ENV_KEYS.CHECKMARX_BASE_URL] ?? globalConfig.checkmarx?.baseUrl,\n username: process.env[ENV_KEYS.CHECKMARX_USERNAME] ?? globalConfig.checkmarx?.username,\n password: process.env[ENV_KEYS.CHECKMARX_PASSWORD] ?? globalConfig.checkmarx?.password,\n },\n servicenow: {\n baseUrl: process.env[ENV_KEYS.SERVICENOW_BASE_URL] ?? globalConfig.servicenow?.baseUrl,\n username: process.env[ENV_KEYS.SERVICENOW_USERNAME] ?? globalConfig.servicenow?.username,\n password: process.env[ENV_KEYS.SERVICENOW_PASSWORD] ?? globalConfig.servicenow?.password,\n apiToken: process.env[ENV_KEYS.SERVICENOW_API_TOKEN] ?? globalConfig.servicenow?.apiToken,\n },\n contrast: {\n baseUrl: process.env[ENV_KEYS.CONTRAST_BASE_URL] ?? globalConfig.contrast?.baseUrl,\n orgUuid: process.env[ENV_KEYS.CONTRAST_ORG_UUID] ?? globalConfig.contrast?.orgUuid,\n apiKey: process.env[ENV_KEYS.CONTRAST_API_KEY] ?? globalConfig.contrast?.apiKey,\n serviceKey: process.env[ENV_KEYS.CONTRAST_SERVICE_KEY] ?? globalConfig.contrast?.serviceKey,\n username: process.env[ENV_KEYS.CONTRAST_USERNAME] ?? globalConfig.contrast?.username,\n },\n sonatypeiq: {\n baseUrl: process.env[ENV_KEYS.SONATYPEIQ_BASE_URL] ?? globalConfig.sonatypeiq?.baseUrl,\n userCode: process.env[ENV_KEYS.SONATYPEIQ_USER_CODE] ?? globalConfig.sonatypeiq?.userCode,\n passcode: process.env[ENV_KEYS.SONATYPEIQ_PASSCODE] ?? globalConfig.sonatypeiq?.passcode,\n },\n openshift: {\n baseUrl: process.env[ENV_KEYS.OPENSHIFT_BASE_URL] ?? globalConfig.openshift?.baseUrl,\n token: process.env[ENV_KEYS.OPENSHIFT_TOKEN] ?? globalConfig.openshift?.token,\n },\n defaults: mergedDefaults\n };\n}\n\nexport function writeGlobalConfig(config: GlobalConfig, configPath?: string): void {\n const filePath = getGlobalConfigPath(configPath);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + '\\n', 'utf8');\n}\n\nexport function writeRepoConfig(config: RepoConfig): void {\n const repoRoot = getRepoRoot();\n const targetDir = repoRoot ?? process.cwd();\n fs.writeFileSync(path.join(targetDir, '.pncli.json'), JSON.stringify(config, null, 2) + '\\n', 'utf8');\n}\n\nfunction parseConfigValue(value: string): unknown {\n try {\n const parsed = JSON.parse(value);\n if (typeof parsed === 'object' && parsed !== null) {\n return parsed;\n }\n } catch {\n // not valid JSON — fall through to raw string\n }\n return value;\n}\n\nexport function setConfigValue(key: string, value: string, configPath?: string): void {\n const filePath = getGlobalConfigPath(configPath);\n const existing = loadJsonFile<GlobalConfig>(filePath) ?? {};\n\n const parts = key.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = existing;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n if (typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part];\n }\n current[parts[parts.length - 1]!] = parseConfigValue(value);\n\n writeGlobalConfig(existing, configPath);\n}\n\nexport function setRepoConfigValue(key: string, value: string): void {\n const repoRoot = getRepoRoot();\n const targetDir = repoRoot ?? process.cwd();\n const filePath = path.join(targetDir, '.pncli.json');\n const existing = loadJsonFile<RepoConfig>(filePath) ?? {};\n\n const parts = key.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = existing;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n if (typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part];\n }\n current[parts[parts.length - 1]!] = parseConfigValue(value);\n\n writeRepoConfig(existing);\n}\n\nexport function maskConfig(config: ResolvedConfig): unknown {\n return {\n ...config,\n jira: {\n ...config.jira,\n apiToken: config.jira.apiToken ? '***' : undefined,\n customFields: config.jira.customFields\n },\n bitbucket: {\n ...config.bitbucket,\n pat: config.bitbucket.pat ? '***' : undefined\n },\n github: {\n ...config.github,\n token: config.github.token ? '***' : undefined\n },\n confluence: {\n ...config.confluence,\n apiToken: config.confluence.apiToken ? '***' : undefined\n },\n artifactory: {\n ...config.artifactory,\n token: config.artifactory.token ? '***' : undefined\n },\n sonar: {\n ...config.sonar,\n token: config.sonar.token ? '***' : undefined\n },\n sde: {\n baseUrl: config.sde.baseUrl,\n token: config.sde.token ? '***' : undefined\n },\n ado: {\n ...config.ado,\n pat: config.ado.pat ? '***' : undefined\n },\n jenkins: {\n ...config.jenkins,\n apiToken: config.jenkins.apiToken ? '***' : undefined\n },\n udeploy: {\n ...config.udeploy,\n pat: config.udeploy.pat ? '***' : undefined,\n password: config.udeploy.password ? '***' : undefined\n },\n checkmarx: {\n ...config.checkmarx,\n password: config.checkmarx.password ? '***' : undefined\n },\n servicenow: {\n ...config.servicenow,\n password: config.servicenow.password ? '***' : undefined,\n apiToken: config.servicenow.apiToken ? '***' : undefined\n },\n contrast: {\n ...config.contrast,\n apiKey: config.contrast.apiKey ? '***' : undefined,\n serviceKey: config.contrast.serviceKey ? '***' : undefined\n },\n sonatypeiq: {\n ...config.sonatypeiq,\n passcode: config.sonatypeiq.passcode ? '***' : undefined\n },\n openshift: {\n ...config.openshift,\n token: config.openshift.token ? '***' : undefined\n }\n };\n}\n\nexport { getGlobalConfigPath, loadJsonFile };\n"],"mappings":"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","names":[]}
|