Skip to content

Commit 1ff7796

Browse files
Merge pull request #219 from robocode-dev/ch-002-reconcile-typescript-npm-publishing
docs(CH-002): reconcile corpus with shipped TypeScript npm publishing
2 parents b7fb320 + 1c6a2a4 commit 1ff7796

5 files changed

Lines changed: 49 additions & 15 deletions

File tree

docs/capabilities/CAP-013-typescript-bot-api-npm-publish/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ provenance: inferred
99

1010
# CAP-013 — TypeScript Bot API npm publishing
1111

12-
(No purpose statement was recorded in the source spec.)
12+
Publish the TypeScript Bot API package (`@robocode.dev/tank-royale-bot-api`) to the npm registry through Gradle, so every official Bot API is installable through its platform's native channel (Java via Maven Central, Python via PyPI, TypeScript via npm).
1313

14-
Extracted from `openspec/specs/typescript-bot-api-npm-publish/spec.md` at CH-001; the source spec's requirement prose is preserved as comments in [criteria.md](criteria.md).
14+
Implemented: the `npmPack` and `npmPublish` Gradle tasks live in `bot-api/typescript/build.gradle.kts`, the `/release` skill drives `npmPublish`, and the package is live on npm. Criteria stay `draft` until their tests are wired (P-001/M-002).
15+
16+
Extracted from `openspec/specs/typescript-bot-api-npm-publish/spec.md` at CH-001 and reconciled to the shipped implementation at CH-002; the source spec's original requirement prose is preserved as comments in [criteria.md](criteria.md).

docs/capabilities/CAP-013-typescript-bot-api-npm-publish/criteria.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,27 @@ Feature: typescript-bot-api-npm-publish — TypeScript Bot API npm publishing
1717
# the Python bot API's PyPI publishing tasks.
1818
# The following tasks SHALL be available:
1919
# - `npmPack` — runs `npm pack` to produce a local `.tgz` tarball for verification and local use
20-
# - `npmPublishDryRun` — validates the package with `npm publish --dry-run` without uploading
21-
# - `npmPublish` — publishes to the npm registry; requires `NPM_TOKEN` environment variable
20+
# - `npmPublish` — publishes to the npm registry; requires the `npmjs-api-key` Gradle property
2221
23-
@TNP-001
22+
# TNP-001 retired (CH-002): the `npmPublishDryRun` task it verified was never built and
23+
# is not needed — `npmPack` already produces the `.tgz` and shows what would be published
24+
# without uploading. No replacement minted.
25+
@TNP-001 @retired
2426
Scenario: npmPublishDryRun succeeds without credentials
2527
When `./gradlew :bot-api:typescript:npmPublishDryRun` is run
2628
Then the task succeeds and prints the files that would be published
2729
And no package is uploaded to the registry
2830
29-
@TNP-002
31+
# TNP-002 retired (CH-002): the shipped task uses the `npmjs-api-key` Gradle property, not
32+
# an `NPM_TOKEN` environment variable. Reminted as TNP-005.
33+
@TNP-002 @retired
3034
Scenario: npmPublish requires NPM_TOKEN
3135
When `./gradlew :bot-api:typescript:npmPublish` is run without `NPM_TOKEN` set
3236
Then the build fails with a clear error message indicating the token is missing
3337
34-
@TNP-003
38+
# TNP-003 retired (CH-002): credential carrier changed from `NPM_TOKEN` to the
39+
# `npmjs-api-key` Gradle property. Reminted as TNP-006.
40+
@TNP-003 @retired
3541
Scenario: npmPublish succeeds with valid token
3642
When `./gradlew :bot-api:typescript:npmPublish` is run with a valid `NPM_TOKEN`
3743
Then the package is uploaded to `https://registry.npmjs.org`
@@ -41,4 +47,15 @@ Feature: typescript-bot-api-npm-publish — TypeScript Bot API npm publishing
4147
Scenario: npmrc is not committed to source control
4248
When the `npmPublish` task writes a temporary `.npmrc` file
4349
Then `.npmrc` is listed in `.gitignore` and cannot be accidentally committed
50+
51+
@TNP-005
52+
Scenario: npmPublish requires the npmjs-api-key Gradle property
53+
When `./gradlew :bot-api:typescript:npmPublish` is run without `npmjs-api-key` set
54+
Then the build fails with a clear error message: "npmjs-api-key is not set in gradle.properties"
55+
56+
@TNP-006
57+
Scenario: npmPublish succeeds with a valid npmjs-api-key
58+
When `./gradlew :bot-api:typescript:npmPublish` is run with a valid `npmjs-api-key` Gradle property
59+
Then the package is published to `https://registry.npmjs.org` with public access
60+
And the temporary `.npmrc` credential file is deleted after the task completes
4461
```

docs/capabilities/CAP-013-typescript-bot-api-npm-publish/design.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,25 @@ provenance: inferred
99

1010
# CAP-013 design
1111

12-
Carried over from the in-flight OpenSpec change `add-typescript-bot-api-npm-publish` at CH-001 (tracked as [P-002](../../plans/P-002-typescript-bot-api-npm.md), door M-004).
12+
Originated as the in-flight OpenSpec change `add-typescript-bot-api-npm-publish`, carried into the corpus at CH-001 (tracked as [P-002](../../plans/P-002-typescript-bot-api-npm.md), door M-004) and reconciled to the shipped implementation at CH-002.
1313

14-
The TypeScript Bot API package (`@robocode.dev/tank-royale-bot-api`) builds but cannot be published to the npm registry through Gradle, while Java (Maven Central) and Python (PyPI) both publish via Gradle tasks. The intended shape:
14+
The TypeScript Bot API package (`@robocode.dev/tank-royale-bot-api`) builds but originally could not be published to the npm registry through Gradle, while Java (Maven Central) and Python (PyPI) both publish via Gradle tasks. As shipped in `bot-api/typescript/build.gradle.kts`:
1515

16-
- `npmPack` task in `bot-api/typescript/build.gradle.kts` (also needed by sample-bot startup work)
17-
- `npmPublishDryRun` task — `npm publish --dry-run` validates the package without uploading
18-
- `npmPublish` task — publishes to npm; requires the `NPM_TOKEN` environment variable
16+
- `npmPack` task — runs `npm pack` to produce a local `.tgz` tarball for verification and local use. This also covers pre-publish inspection: it shows exactly what would be published without uploading, so a separate `npm publish --dry-run` task was deemed redundant and not built.
17+
- `npmPublish` task — publishes to npm with `--access public`; requires the `npmjs-api-key` Gradle property (looked up from the user or project `gradle.properties`), consistent with the Sonatype/PyPI credential pattern and the `/release` skill. It writes a temporary `.npmrc` with the token and deletes it afterwards.
1918

20-
Impact beyond the build script: `.gitignore` must exclude `.npmrc` (a temporary credential file is written and deleted during publish).
19+
Impact beyond the build script: `.gitignore` excludes `/bot-api/typescript/.npmrc` (the temporary credential file written and deleted during publish).
20+
21+
## Credential setup
22+
23+
`npmPublish` reads the npm token from the `npmjs-api-key` Gradle property. Keep it out of the repo by putting it in your **user** Gradle properties file, never the project one:
24+
25+
- Unix/macOS: `~/.gradle/gradle.properties`
26+
- Windows: `%USERPROFILE%\.gradle\gradle.properties`
27+
28+
```properties
29+
# npm token (Automation type) from https://www.npmjs.com/settings/<user>/tokens
30+
npmjs-api-key=npm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
31+
```
32+
33+
The token must have publish rights to the `@robocode.dev` scope. If it is missing, `npmPublish` fails with `npmjs-api-key is not set in gradle.properties` (criterion TNP-005). This mirrors the other publish credentials, which live in the same file: `ossrhUsername` / `ossrhPassword` (Maven Central), `nuget-api-key` (NuGet), `pypiToken` (PyPI) — see the `/release` skill for the full set.

docs/decisions/log.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Decisions that are cheap and local to reverse, one row each — newest first. Th
1212

1313
| Date | Decision | Why | Change/PR |
1414
|---|---|---|---|
15+
| 2026-07-19 | Drop the never-built `npmPublishDryRun` task from CAP-013 (retire TNP-001) instead of building it | `npmPack` already produces the `.tgz` and shows what would be published without uploading, so a dry-run task is redundant | CH-002 |
16+
| 2026-07-19 | TypeScript npm publishing authenticates via the `npmjs-api-key` Gradle property, not an `NPM_TOKEN` env var (retire TNP-002/003, remint TNP-005/006) | Reconciles the corpus to the shipped code and matches the Sonatype/PyPI credential pattern and the `/release` skill | CH-002 |
1517
| 2026-07-19 | Extracted criteria are born `status: draft`; a capability's criteria go `active` when its tests carry purpose tags | Draft criteria are exempt from the AC↔test wall, which turns the four-language tagging backlog (P-001/M-002) into per-capability increments instead of one blocking big bang | CH-001 |
1618
| 2026-07-19 | Pre-Cliewen ADRs keep ids ADR-0001…ADR-0041 and become `verified` with `accepted-by: … (date, pre-Cliewen MADR acceptance)` | The MADR acceptance already happened and is preserved as fact, not re-judged; renumbering 41 cross-referenced records would break links for no gain | CH-001 |
1719
| 2026-07-19 | `INDEX.md` files and `docs/decisions/template.md` deleted; README `clue:index` blocks are the only indexes | Two indexes drift; the validate-checked index block is the enforced one | CH-001 |

docs/plans/P-002-typescript-bot-api-npm.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
id: P-002
33
type: plan
4-
status: active
4+
status: completed
55
links: [G-001]
66
title: TypeScript Bot API reaches npm
77
provenance: inferred
@@ -15,4 +15,4 @@ Carried over from the pending OpenSpec change `add-typescript-bot-api-npm-publis
1515

1616
| ID | Milestone | Exit criterion | Status | Evidence |
1717
|---|---|---|---|---|
18-
| M-004 | npm publishing via Gradle | `npmPack`, `npmPublishDryRun`, `npmPublish` Gradle tasks exist and a dry-run publish of the package succeeds from a clean checkout; CAP-014 flips to `active` with its ACs tested | todo | |
18+
| M-004 | npm publishing via Gradle | `npmPack` and `npmPublish` Gradle tasks exist in `bot-api/typescript/build.gradle.kts` and the package publishes to npm via the `/release` skill | done | Commits `b1654f620` / `287ff01ac` / `51c30e21b`; `@robocode.dev/tank-royale-bot-api@1.0.2` live on npm; CAP-013 |

0 commit comments

Comments
 (0)