vouchington-tooling 0.3.2 → 0.3.4
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 -0
- package/dist/agent-blackboard/index.d.mts +1 -0
- package/dist/agent-blackboard/index.mjs +27 -8
- package/dist/gha-post-review/github.mjs +10 -4
- package/package.json +1 -9
- package/skills/github-actions-checklist/SKILL.md +32 -2
- package/skills/manifest.json +22 -16
- package/skills/npm-publishing/SKILL.md +64 -0
package/README.md
CHANGED
|
@@ -89,6 +89,8 @@ as not merged to main, and a missing base is unavailable.
|
|
|
89
89
|
|
|
90
90
|
Agent Blackboard support is optional: only the `agent-blackboard` subpath and its CLI commands
|
|
91
91
|
need `agent-blackboard@^0.3.1`. Snapshot cleanup accepts only package-generated temporary paths.
|
|
92
|
+
Programmatic callers launched from a different workspace directory pass their own module URL as
|
|
93
|
+
`dependencies: { resolveFrom: import.meta.url }`; the CLI defaults to the current package context.
|
|
92
94
|
It captures a target under a private tombstone, validates partition names, permissions, JSONL,
|
|
93
95
|
ordering, terminal manifests, and the identity-bound cleanup receipt before deleting files, and
|
|
94
96
|
restores the original path on a validation failure. Once deletion begins, it retains a private
|
|
@@ -24,6 +24,7 @@ export type BlackboardClientModule = {
|
|
|
24
24
|
type BlackboardClientLoader = () => Promise<BlackboardClientModule>;
|
|
25
25
|
export type BlackboardClientDependencies = {
|
|
26
26
|
loadClient?: BlackboardClientLoader;
|
|
27
|
+
resolveFrom?: string | URL;
|
|
27
28
|
};
|
|
28
29
|
export declare function resolveBlackboardConnection(env?: NodeJS.ProcessEnv): BlackboardConnection;
|
|
29
30
|
export declare function probeBlackboard(env?: NodeJS.ProcessEnv, dependencies?: BlackboardClientDependencies): Promise<void>;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
1
9
|
import { readFile } from 'node:fs/promises';
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
11
|
+
import { resolve } from 'node:path';
|
|
12
|
+
import { pathToFileURL } from 'node:url';
|
|
2
13
|
import { assertSessionId } from './session-id.mjs';
|
|
3
14
|
export { cleanupSnapshotPartitions, partitionSnapshot } from './snapshot.mjs';
|
|
4
15
|
export { assertSessionId } from './session-id.mjs';
|
|
@@ -12,7 +23,7 @@ export function resolveBlackboardConnection(env = process.env) {
|
|
|
12
23
|
return { baseUrl, token, readRetry: {} };
|
|
13
24
|
}
|
|
14
25
|
export async function probeBlackboard(env, dependencies) {
|
|
15
|
-
const { Sessions } = await loadClient(dependencies
|
|
26
|
+
const { Sessions } = await loadClient(dependencies);
|
|
16
27
|
await new Sessions(resolveBlackboardConnection(env)).list({ limit: 1 });
|
|
17
28
|
}
|
|
18
29
|
export async function appendJournal(input) {
|
|
@@ -32,7 +43,7 @@ export async function appendJournal(input) {
|
|
|
32
43
|
if (!markdown)
|
|
33
44
|
throw new Error(`note file is empty: ${input.markdownFile}`);
|
|
34
45
|
const connection = resolveBlackboardConnection(input.env);
|
|
35
|
-
const { Sessions, Entries } = await loadClient(input.dependencies
|
|
46
|
+
const { Sessions, Entries } = await loadClient(input.dependencies);
|
|
36
47
|
await new Sessions(connection).ensure({
|
|
37
48
|
id: input.sessionId,
|
|
38
49
|
parentSessionId: input.parentSessionId ?? null,
|
|
@@ -47,7 +58,7 @@ export async function appendJournal(input) {
|
|
|
47
58
|
}
|
|
48
59
|
export async function readJournal(sessionId, env, dependencies) {
|
|
49
60
|
assertSessionId(sessionId);
|
|
50
|
-
const { Entries } = await loadClient(dependencies
|
|
61
|
+
const { Entries } = await loadClient(dependencies);
|
|
51
62
|
const entries = [];
|
|
52
63
|
for await (const entry of new Entries(resolveBlackboardConnection(env)).get({
|
|
53
64
|
sessionId,
|
|
@@ -79,16 +90,24 @@ export function formatJournalEntries(sessionId, entries) {
|
|
|
79
90
|
.map(({ createdAt, markdown }) => `## ${createdAt}\n\n${markdown}`)
|
|
80
91
|
.join('\n\n');
|
|
81
92
|
}
|
|
82
|
-
async function loadClient(
|
|
93
|
+
async function loadClient(dependencies = {}) {
|
|
94
|
+
const loader = dependencies.loadClient ?? (() => defaultClientLoader(dependencies.resolveFrom));
|
|
83
95
|
try {
|
|
84
96
|
return await loader();
|
|
85
97
|
}
|
|
86
98
|
catch (error) {
|
|
87
|
-
if (error
|
|
88
|
-
throw new Error('agent-blackboard is not installed; install
|
|
99
|
+
if (isMissingModuleError(error))
|
|
100
|
+
throw new Error('agent-blackboard is not installed; install it alongside vouchington-tooling to use this integration', { cause: error });
|
|
89
101
|
throw error;
|
|
90
102
|
}
|
|
91
103
|
}
|
|
92
|
-
async function defaultClientLoader() {
|
|
93
|
-
|
|
104
|
+
async function defaultClientLoader(resolveFrom) {
|
|
105
|
+
const consumerRequire = createRequire(resolveFrom ?? resolve(process.cwd(), 'package.json'));
|
|
106
|
+
const specifier = pathToFileURL(consumerRequire.resolve('agent-blackboard')).href;
|
|
107
|
+
return (await import(__rewriteRelativeImportExtension(specifier)));
|
|
108
|
+
}
|
|
109
|
+
function isMissingModuleError(error) {
|
|
110
|
+
return (error instanceof Error &&
|
|
111
|
+
'code' in error &&
|
|
112
|
+
(error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND'));
|
|
94
113
|
}
|
|
@@ -33,7 +33,7 @@ export function writePostedOutput(posted, outputPath = process.env.GITHUB_OUTPUT
|
|
|
33
33
|
return;
|
|
34
34
|
appendFileSync(outputPath, `posted=${posted ? 'true' : 'false'}\n`);
|
|
35
35
|
}
|
|
36
|
-
function
|
|
36
|
+
function readPullState(repository, prNumber, exec) {
|
|
37
37
|
let lastError;
|
|
38
38
|
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
39
39
|
try {
|
|
@@ -41,7 +41,7 @@ function readPullRefs(repository, prNumber, exec) {
|
|
|
41
41
|
'api',
|
|
42
42
|
`repos/${repository}/pulls/${prNumber}`,
|
|
43
43
|
'--jq',
|
|
44
|
-
'[.head.sha, .base.sha] | @tsv',
|
|
44
|
+
'[.head.sha, .base.sha, .draft, .state] | @tsv',
|
|
45
45
|
]).split('\t');
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
@@ -72,14 +72,20 @@ export function createGhPostReviewIo(options) {
|
|
|
72
72
|
if (expectedBaseSha && !/^[0-9a-f]{40}$/u.test(expectedBaseSha)) {
|
|
73
73
|
throw new ReviewPayloadError('EXPECTED_BASE_SHA must be a full lowercase commit SHA.');
|
|
74
74
|
}
|
|
75
|
-
const
|
|
76
|
-
const [headSha = '', baseSha = ''] =
|
|
75
|
+
const state = readPullState(repository, prNumber, exec);
|
|
76
|
+
const [headSha = '', baseSha = '', draft = '', pullState = ''] = state;
|
|
77
77
|
if (!/^[0-9a-f]{40}$/u.test(headSha)) {
|
|
78
78
|
throw new ReviewPayloadError(`Could not resolve PR head SHA (got "${headSha}").`);
|
|
79
79
|
}
|
|
80
80
|
if (!/^[0-9a-f]{40}$/u.test(baseSha)) {
|
|
81
81
|
throw new ReviewPayloadError(`Could not resolve PR base SHA (got "${baseSha}").`);
|
|
82
82
|
}
|
|
83
|
+
if (draft !== 'false') {
|
|
84
|
+
throw new ReviewPayloadError('Pull request became a draft before posting the review.');
|
|
85
|
+
}
|
|
86
|
+
if (pullState !== 'open') {
|
|
87
|
+
throw new ReviewPayloadError('Pull request closed before posting the review.');
|
|
88
|
+
}
|
|
83
89
|
if (expectedHeadSha && headSha !== expectedHeadSha) {
|
|
84
90
|
throw new ReviewPayloadError('PR head changed before posting the selected review.');
|
|
85
91
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vouchington-tooling",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Vouchington CLI and extractable tooling libraries.",
|
|
5
5
|
"homepage": "https://github.com/vouchington/vouchington-tooling/tree/main/packages/vouchington-tooling#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -252,14 +252,6 @@
|
|
|
252
252
|
"@types/picomatch": "^4.0.3",
|
|
253
253
|
"agent-blackboard": "^0.3.1"
|
|
254
254
|
},
|
|
255
|
-
"peerDependencies": {
|
|
256
|
-
"agent-blackboard": "^0.3.1"
|
|
257
|
-
},
|
|
258
|
-
"peerDependenciesMeta": {
|
|
259
|
-
"agent-blackboard": {
|
|
260
|
-
"optional": true
|
|
261
|
-
}
|
|
262
|
-
},
|
|
263
255
|
"optionalDependencies": {
|
|
264
256
|
"@libpg-query/parser": "^18.0.0"
|
|
265
257
|
},
|
|
@@ -8,13 +8,43 @@ description: Use when editing GitHub Actions workflows or composite actions to k
|
|
|
8
8
|
Use before editing a workflow or composite action. Repository-local instructions own runners,
|
|
9
9
|
approved action pinning, concurrency naming, secrets, permissions, and workflow-only PR rules.
|
|
10
10
|
|
|
11
|
+
Apply this portable baseline unless a stricter repository-local rule overrides it:
|
|
12
|
+
|
|
13
|
+
- Use `pull_request` for pull-request workflows in private repositories. Reserve
|
|
14
|
+
`pull_request_target` for base-owned orchestration in public repositories or narrowly scoped
|
|
15
|
+
Dependabot/Renovate automation. A privileged workflow must never check out or execute untrusted
|
|
16
|
+
pull-request content.
|
|
17
|
+
- Load [github-actions-authoring](../github-actions-authoring/SKILL.md) when changing orchestration.
|
|
18
|
+
Do not poll remote workflow, deployment, lease, service, or health state.
|
|
19
|
+
- Give every concrete job a timeout of no more than 30 minutes. A caller job that invokes a reusable
|
|
20
|
+
workflow through top-level `jobs.<job_id>.uses` cannot accept `timeout-minutes`; enforce the bound
|
|
21
|
+
on every concrete job inside the called workflow. If the underlying operation cannot terminate
|
|
22
|
+
inside that bound, decompose it into event-driven phases; lowering or moving the timeout alone does
|
|
23
|
+
not fix the design. Preserve a required job or check name with a bounded fan-in job when splitting
|
|
24
|
+
work would otherwise change the repository's merge contract. Each underlying phase must also have
|
|
25
|
+
a deadline of no more than 30 minutes and support cancellation, rollback, or an explicit terminal
|
|
26
|
+
retained/recovery state. An event callback may report completion; it must not hide a longer-running
|
|
27
|
+
operation in another service.
|
|
28
|
+
- Use GitHub-hosted runners only for public repositories. Private repositories use the consumer's
|
|
29
|
+
approved self-hosted or disposable runner labels.
|
|
30
|
+
- Pin every repository-backed external `uses:` reference—anything other than a local `./...`
|
|
31
|
+
action—to a full lowercase 40-character Git SHA followed immediately by its machine-maintainable
|
|
32
|
+
version comment, such as `# v4.2.0`, so Dependabot can update both. Pin `docker://...` actions to an
|
|
33
|
+
immutable `@sha256:` image digest instead of a Git SHA. Keep GitHub Actions dependency updates
|
|
34
|
+
enabled.
|
|
35
|
+
- Workflow tests and fixtures must not assert an action dependency's exact SHA or version. Assert
|
|
36
|
+
the action identity and Git SHA shape, or derive the dependency ref from the workflow under test,
|
|
37
|
+
so dependency-update pull requests can change pins without synchronized fixture edits. This does
|
|
38
|
+
not prohibit asserting an exact source revision in `with.ref` when exact-head checkout is a
|
|
39
|
+
workflow security invariant.
|
|
40
|
+
|
|
11
41
|
1. Read every applicable `AGENTS.md` and `CLAUDE.md` from the repository root through the workflow,
|
|
12
42
|
plus relevant CI documentation and callers. Apply the closest instruction only when rules
|
|
13
43
|
conflict. Identify trusted and untrusted inputs and every credential boundary.
|
|
14
44
|
2. Give each job the least permissions it needs. Keep untrusted pull-request content out of shell
|
|
15
45
|
interpolation, privileged tokens, and write-capable steps.
|
|
16
|
-
3.
|
|
17
|
-
caches, and concurrency behavior explicit.
|
|
46
|
+
3. Apply the portable pinning, runner, trigger, and timeout baseline plus any stricter consumer
|
|
47
|
+
policy. Keep checkout refs, artifact boundaries, caches, and concurrency behavior explicit.
|
|
18
48
|
4. Validate changed YAML with the local workflow checker and run the affected workflow tests or
|
|
19
49
|
scripts. Update local CI documentation when behavior or operator expectations change.
|
|
20
50
|
5. Review the final diff for privilege escalation, accidental secret exposure, unsafe quoting,
|
package/skills/manifest.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{
|
|
5
5
|
"name": "agent-workflow",
|
|
6
6
|
"plugin": "vouchington-workflow",
|
|
7
|
-
"pluginVersion": "0.
|
|
7
|
+
"pluginVersion": "0.5.1",
|
|
8
8
|
"path": "agent-workflow/SKILL.md"
|
|
9
9
|
},
|
|
10
10
|
{
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
{
|
|
18
18
|
"name": "blackboard",
|
|
19
19
|
"plugin": "vouchington-workflow",
|
|
20
|
-
"pluginVersion": "0.
|
|
20
|
+
"pluginVersion": "0.5.1",
|
|
21
21
|
"path": "blackboard/SKILL.md"
|
|
22
22
|
},
|
|
23
23
|
{
|
|
@@ -29,26 +29,26 @@
|
|
|
29
29
|
{
|
|
30
30
|
"name": "git-commit-checklist",
|
|
31
31
|
"plugin": "vouchington-workflow",
|
|
32
|
-
"pluginVersion": "0.
|
|
32
|
+
"pluginVersion": "0.5.1",
|
|
33
33
|
"path": "git-commit-checklist/SKILL.md"
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
"name": "github-actions-authoring",
|
|
37
37
|
"plugin": "vouchington-workflow",
|
|
38
|
-
"pluginVersion": "0.
|
|
38
|
+
"pluginVersion": "0.5.1",
|
|
39
39
|
"path": "github-actions-authoring/SKILL.md",
|
|
40
40
|
"prerequisites": ["github-actions-checklist"]
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"name": "github-actions-checklist",
|
|
44
44
|
"plugin": "vouchington-workflow",
|
|
45
|
-
"pluginVersion": "0.
|
|
45
|
+
"pluginVersion": "0.5.1",
|
|
46
46
|
"path": "github-actions-checklist/SKILL.md"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"name": "github-issue",
|
|
50
50
|
"plugin": "vouchington-workflow",
|
|
51
|
-
"pluginVersion": "0.
|
|
51
|
+
"pluginVersion": "0.5.1",
|
|
52
52
|
"path": "github-issue/SKILL.md"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
@@ -58,22 +58,28 @@
|
|
|
58
58
|
"path": "nextjs-vitest-test-authoring/SKILL.md",
|
|
59
59
|
"prerequisites": ["vitest-test-authoring"]
|
|
60
60
|
},
|
|
61
|
+
{
|
|
62
|
+
"name": "npm-publishing",
|
|
63
|
+
"plugin": "vouchington-workflow",
|
|
64
|
+
"pluginVersion": "0.5.1",
|
|
65
|
+
"path": "npm-publishing/SKILL.md"
|
|
66
|
+
},
|
|
61
67
|
{
|
|
62
68
|
"name": "organize-github-issues",
|
|
63
69
|
"plugin": "vouchington-workflow",
|
|
64
|
-
"pluginVersion": "0.
|
|
70
|
+
"pluginVersion": "0.5.1",
|
|
65
71
|
"path": "organize-github-issues/SKILL.md"
|
|
66
72
|
},
|
|
67
73
|
{
|
|
68
74
|
"name": "package-json-checklist",
|
|
69
75
|
"plugin": "vouchington-workflow",
|
|
70
|
-
"pluginVersion": "0.
|
|
76
|
+
"pluginVersion": "0.5.1",
|
|
71
77
|
"path": "package-json-checklist/SKILL.md"
|
|
72
78
|
},
|
|
73
79
|
{
|
|
74
80
|
"name": "planning",
|
|
75
81
|
"plugin": "vouchington-workflow",
|
|
76
|
-
"pluginVersion": "0.
|
|
82
|
+
"pluginVersion": "0.5.1",
|
|
77
83
|
"path": "planning/SKILL.md"
|
|
78
84
|
},
|
|
79
85
|
{
|
|
@@ -97,43 +103,43 @@
|
|
|
97
103
|
{
|
|
98
104
|
"name": "pr-description",
|
|
99
105
|
"plugin": "vouchington-workflow",
|
|
100
|
-
"pluginVersion": "0.
|
|
106
|
+
"pluginVersion": "0.5.1",
|
|
101
107
|
"path": "pr-description/SKILL.md"
|
|
102
108
|
},
|
|
103
109
|
{
|
|
104
110
|
"name": "retrospective",
|
|
105
111
|
"plugin": "vouchington-workflow",
|
|
106
|
-
"pluginVersion": "0.
|
|
112
|
+
"pluginVersion": "0.5.1",
|
|
107
113
|
"path": "retrospective/SKILL.md"
|
|
108
114
|
},
|
|
109
115
|
{
|
|
110
116
|
"name": "retrospective-distill",
|
|
111
117
|
"plugin": "vouchington-workflow",
|
|
112
|
-
"pluginVersion": "0.
|
|
118
|
+
"pluginVersion": "0.5.1",
|
|
113
119
|
"path": "retrospective-distill/SKILL.md"
|
|
114
120
|
},
|
|
115
121
|
{
|
|
116
122
|
"name": "review-ci-logs",
|
|
117
123
|
"plugin": "vouchington-workflow",
|
|
118
|
-
"pluginVersion": "0.
|
|
124
|
+
"pluginVersion": "0.5.1",
|
|
119
125
|
"path": "review-ci-logs/SKILL.md"
|
|
120
126
|
},
|
|
121
127
|
{
|
|
122
128
|
"name": "review-github-issue-taxonomy",
|
|
123
129
|
"plugin": "vouchington-workflow",
|
|
124
|
-
"pluginVersion": "0.
|
|
130
|
+
"pluginVersion": "0.5.1",
|
|
125
131
|
"path": "review-github-issue-taxonomy/SKILL.md"
|
|
126
132
|
},
|
|
127
133
|
{
|
|
128
134
|
"name": "revisit-followups",
|
|
129
135
|
"plugin": "vouchington-workflow",
|
|
130
|
-
"pluginVersion": "0.
|
|
136
|
+
"pluginVersion": "0.5.1",
|
|
131
137
|
"path": "revisit-followups/SKILL.md"
|
|
132
138
|
},
|
|
133
139
|
{
|
|
134
140
|
"name": "static-analysis-checklist",
|
|
135
141
|
"plugin": "vouchington-workflow",
|
|
136
|
-
"pluginVersion": "0.
|
|
142
|
+
"pluginVersion": "0.5.1",
|
|
137
143
|
"path": "static-analysis-checklist/SKILL.md"
|
|
138
144
|
},
|
|
139
145
|
{
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: npm-publishing
|
|
3
|
+
description: Bootstrap an npm package and give a human the exact commands to publish it publicly and configure GitHub trusted publishing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# npm publishing bootstrap
|
|
7
|
+
|
|
8
|
+
Prepare the local package, but leave public registry and trusted-publisher mutations to the human.
|
|
9
|
+
Read every applicable `AGENTS.md` and `CLAUDE.md` from the repository root through the package.
|
|
10
|
+
Repository-local policy and the consumer wrapper own the package path and name, npm scope, GitHub
|
|
11
|
+
repository, release workflow, build commands, and whether a laptop may publish.
|
|
12
|
+
|
|
13
|
+
## Prepare the package
|
|
14
|
+
|
|
15
|
+
1. Resolve the absolute repository root, package directory relative to that root, exact npm package
|
|
16
|
+
name, `owner/repository`, and release workflow filename. The workflow value is the case-sensitive
|
|
17
|
+
filename under `.github/workflows`, not a path. Do not leave placeholders in the final commands.
|
|
18
|
+
2. Confirm npm 11.15 or newer, account-level two-factor authentication, and write access to the npm
|
|
19
|
+
package or scope. Inspect the workflow on the repository's default branch: it must grant
|
|
20
|
+
`id-token: write`, use a supported runner, install a trusted-publishing-capable npm version, and
|
|
21
|
+
publish this package.
|
|
22
|
+
3. When the package does not exist in the registry, create the smallest useful stub module in its
|
|
23
|
+
intended directory. Follow neighboring package conventions for metadata, source, exports, types,
|
|
24
|
+
license, README, build output, and workspace registration. Do not replace an existing module with
|
|
25
|
+
a stub or publish a version already present in the registry.
|
|
26
|
+
4. Build the package as required, then inspect the publication lifecycle and exact payload with
|
|
27
|
+
`npm publish <package-directory> --access public --dry-run`. Stop if it includes secrets,
|
|
28
|
+
environment files, source maps, unrelated workspace files, or missing runtime/type entrypoints.
|
|
29
|
+
This dry run must include `prepublishOnly`; a pack-only check is insufficient when that lifecycle
|
|
30
|
+
script can change the payload.
|
|
31
|
+
5. If the package already exists, have the human run `npm trust list <package-name>` before any
|
|
32
|
+
mutation. Omit the initial publish command. If a trust relationship already exists, report it and
|
|
33
|
+
omit the trust-creation command rather than revoking or replacing it.
|
|
34
|
+
|
|
35
|
+
## Hand off the mutations
|
|
36
|
+
|
|
37
|
+
Do not run a real `npm publish` or a mutating `npm trust` subcommand. Explain that the first command
|
|
38
|
+
creates an externally visible, effectively irreversible package version and the second grants the
|
|
39
|
+
named workflow publish authority. Include the publish command only when bootstrapping a package that
|
|
40
|
+
does not exist; an existing package proceeds directly to trust setup when its trust list is empty.
|
|
41
|
+
Tell the human to append a current one-time password after each final `--otp=` without sharing or
|
|
42
|
+
recording it. Warn that the requested `--otp=` form can expose the OTP in shell history and process
|
|
43
|
+
arguments, and tell the human to follow their local secret-handling policy. Give the applicable
|
|
44
|
+
commands with fully resolved values and in this order:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
cd /absolute/repository/root
|
|
48
|
+
npm publish ./relative/package-directory --access public --otp=
|
|
49
|
+
npm trust github @scope/package \
|
|
50
|
+
--repo owner/repository \
|
|
51
|
+
--file release.yml \
|
|
52
|
+
--allow-publish \
|
|
53
|
+
--yes \
|
|
54
|
+
--otp=
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The `cd` target must be the directory from which the relative publish path resolves. If local policy
|
|
58
|
+
prohibits publishing from the current machine, say so and identify the approved environment while
|
|
59
|
+
preserving the same ordered commands. Ask the human to confirm the package payload, package name,
|
|
60
|
+
repository, workflow filename, and publish permission immediately before running them.
|
|
61
|
+
|
|
62
|
+
Afterward, have the human verify any newly published package version and run
|
|
63
|
+
`npm trust list @scope/package` again. Do not retry authorization or registry failures blindly, and do
|
|
64
|
+
not fall back to a long-lived npm token without explicit direction.
|