From f6f3b7adbbe8ae9e18e5575fce7204f13989cbcc Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Tue, 22 Sep 2026 04:51:07 -0400 Subject: [PATCH] fix(api-docs/ts): derive package names from the manifest, restore the 7 dropped packages The TypeScript template carried two stale literals about resq-software/npm. Both were found by running the template's own extraction logic against a fresh clone of that repo, the same way the .NET read_version() bug was proven. 1. The top-level index rebuilt each entry as `@resq-sw/`. That scope was renamed to `@resq-systems/*` in npm#167 (July 2026), so the template renders install names that no longer resolve on the registry. It now reads `.name` out of the package manifest it already opens for `.version`, which is the point: a name derived from the source of truth survives the next rename without a template edit. 2. `PUBLIC_PACKAGES` listed 9 packages; the monorepo publishes 16. The missing 7 are constants, email-templates, map, math, nav, telemetry and types. This one bites hard because "Sync generated MDX" clears the target directory before copying: a run from the stale list would have dropped 6 already-published package doc trees from sdks/typescript/api/ and never added nav. The list now matches every packages/*/ that has a src/, which is exactly the set the generation step accepts. Verified against a clone of resq-software/npm at 39ea053: the patched index step emits all 16 packages under the correct scope with the versions their manifests carry. actionlint is clean on all five templates. The other three siblings were audited the same way and are NOT changed: - rust: already correct on the hybrid workspace. field_in() requires a double-quoted value, so `version.workspace = true` does not match and the `or ws_version` fallback supplies the inherited version. Run against resq-software/crates, all 8 crates matched their release-plz tags, including the 4 inheriting ones (v0.1.24). - python: resq-software/pypi configures python-semantic-release with version_toml = ["pyproject.toml:project.version"], so PSR writes a literal into [project] version on every release. resq-dsa v1.3.4 and resq-mcp v1.3.3 both read correctly. - cpp: resq-software/vcpkg carries a literal "version" in packages/resq-common/vcpkg.json, matching both the CMake project VERSION and the resq-common@v0.1.0 tag. Reads correctly. --- .../api-docs.typescript.yml | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/automation/source-repo-templates/api-docs.typescript.yml b/automation/source-repo-templates/api-docs.typescript.yml index 7731efda..b1d27325 100644 --- a/automation/source-repo-templates/api-docs.typescript.yml +++ b/automation/source-repo-templates/api-docs.typescript.yml @@ -7,7 +7,7 @@ # Copy this file to resq-software/npm at: # .github/workflows/api-docs.yml # -# Renders TypeDoc API reference for every public @resq-sw/* package +# Renders TypeDoc API reference for every public @resq-systems/* package # in the bun monorepo and opens a single PR in resq-software/docs # with generated MDX under sdks/typescript/api//. @@ -54,13 +54,20 @@ jobs: # this list when the monorepo gains new public packages. PUBLIC_PACKAGES: >- analytics + constants decorators dsa + email-templates helpers http logger + map + math + nav rate-limiting security + telemetry + types ui steps: @@ -445,16 +452,24 @@ jobs: repo = os.environ.get("GH_REPO", "") out = pathlib.Path(os.environ["OUTPUT_DIR"]) - def read_version(pkg: str) -> str: + def read_manifest(pkg: str) -> tuple[str, str]: + # Read BOTH the published name and the version out of the + # manifest. The name is deliberately not rebuilt from a + # scope literal: the org already renamed this scope once + # (@resq-sw/* -> @resq-systems/*) and the hardcoded copy + # outlived the rename here for two months, publishing + # install names that no longer resolve. Reading .name + # means the next rename needs no template change. + # Directory name is the fallback so a missing or + # unparseable manifest still yields a readable entry. pkg_json = pathlib.Path("packages") / pkg / "package.json" if not pkg_json.exists(): - return "unknown" + return pkg, "unknown" try: - return json.loads( - pkg_json.read_text(encoding="utf-8") - ).get("version", "unknown") + data = json.loads(pkg_json.read_text(encoding="utf-8")) except json.JSONDecodeError: - return "unknown" + return pkg, "unknown" + return data.get("name", pkg), data.get("version", "unknown") print("# ResQ TypeScript SDK") print() @@ -469,8 +484,8 @@ jobs: for pkg_dir in sorted(out.iterdir()): if not pkg_dir.is_dir(): continue - version = read_version(pkg_dir.name) - print(f"- `@resq-sw/{pkg_dir.name}` — `v{version}`") + name, version = read_manifest(pkg_dir.name) + print(f"- `{name}` — `v{version}`") PY - name: Build pages index @@ -621,7 +636,7 @@ jobs: (run: ${{ github.run_id }}). Regenerated files under `sdks/typescript/api/`. One - sub-directory per `@resq-sw/*` package. Review the diff + sub-directory per `@resq-systems/*` package. Review the diff for unintended exports and merge to publish. branch: auto/typescript-api-${{ env.DOCS_REF_SLUG }} base: main