Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f10ff0f
fix: remove dotenv-cli dependency and related config
stephansama Jan 7, 2026
8998467
feat(multipublish): add new package for publishing to multiple providers
stephansama Jan 8, 2026
30e4950
feat: implement npm publishing strategies
stephansama Jan 8, 2026
97ded53
feat(multipublish): initial release of the multipublish cli tool
stephansama Jan 8, 2026
718e3b1
feat: add dry run publishing mode
stephansama Jan 8, 2026
0eccd20
chore(multipublish): narrow lint script scope to src directory
stephansama Jan 8, 2026
4fb6348
fix: update jsr config file path and npmrc handling in publish logic
stephansama Jan 8, 2026
f2af774
refactor: use getargs instead of parseargs and update changeset type …
stephansama Jan 8, 2026
6b1ac0e
fix: update package.json dependencies and fix util.ts error handling
stephansama Jan 8, 2026
9f58585
build: move zod to dependencies
stephansama Jan 8, 2026
f2ea1be
feat: add include/exclude options for jsr and --no-git-checks flag
stephansama Jan 8, 2026
918dba2
feat(multipublish): add option to allow slow types for jsr publish
stephansama Jan 8, 2026
06c9938
feat: add dependency catalog support and cli config option
stephansama Jan 9, 2026
445c042
build(multipublish): clean package.json after jsr publish with experi…
stephansama Jan 9, 2026
d030c4d
docs: add detailed usage and configuration guide
stephansama Jan 9, 2026
ee65ad7
feat: add jsr configuration options and update publish logic
stephansama Jan 9, 2026
e680b7e
fix(multipublish): correctly handle dry run argument and package vers…
stephansama Jan 9, 2026
591203b
feat: add bun support and automate changeset status generation
stephansama Jan 10, 2026
2897efd
test: add unit tests for core multipublish modules
stephansama Jan 14, 2026
b5118bf
refactor: normalize import paths in test files
stephansama Jan 14, 2026
81a90cf
test: add comprehensive tests for multipublish package publishing
stephansama Jan 15, 2026
1f30a1c
refactor(multipublish): reorder imports in catalog tests
stephansama Jan 15, 2026
82d0ecf
feat: introduce `commitJsrVersionUpdate` option for JSR publishing
stephansama Jan 15, 2026
4fe48a5
test(multipublish/util): add tests for directory, file, and stdin uti…
stephansama Jan 15, 2026
d398211
test(multipublish): add unit tests for run function
stephansama Jan 15, 2026
1cc5dbd
chore: integrate multipublish for multi-platform package releases
stephansama Jan 15, 2026
fff59de
feat(jsr): allow string import/require in export maps
stephansama Jan 15, 2026
3a61577
build(multipublish): configure multipublish cli for use
stephansama Jan 15, 2026
37623f0
refactor: remove commitJsrVersionUpdate option
stephansama Jan 15, 2026
57b983e
docs: enhance jsr and changeset documentation in multipublish readme
stephansama Jan 15, 2026
cadd823
refactor: improve workflow step name clarity
stephansama Jan 15, 2026
0991446
chore: switch npm registry to github packages
stephansama Jan 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changeset/stupid-cycles-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@stephansama/multipublish": major
---

Initial release of `@stephansama/multipublish`, a CLI tool for publishing packages to multiple registries.

Features:

- **npm Publishing Strategies**: Supports two strategies for publishing to npm registries:
- `.npmrc` strategy: Temporarily creates or updates a root-level `.npmrc` file with registry and auth token details.
- `package.json` strategy: Directly sets the `publishConfig.registry` field in the package's `package.json`.
- **JSR Support**: Automatically updates the `version` field in `jsr.json` before publishing.
- **Configuration**: fully configurable via a schema using zod.
1 change: 1 addition & 0 deletions .config/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"kaomojis",
"macchiato",
"manypkg",
"multipublish",
"nodemon",
"nvim",
"nvmrc",
Expand Down
19 changes: 19 additions & 0 deletions .config/.multipublishrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "../node_modules/@stephansama/multipublish/config/schema.json",
"platforms": [
[
"jsr",
{
"experimentalUpdateCatalogs": true,
"experimentalGenerateJSR": true
}
],
[
"npm",
{
"registry": "npm.pkg.github.com",
"tokenEnvironmentKey": "GITHUB_TOKEN"
}
]
Comment on lines +11 to +17
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's find the multipublish source code and understand how tokenEnvironmentKey is used
find . -type f -name "*.json" -o -name "*.ts" -o -name "*.js" | grep -E "(multipublish|publish)" | head -20

Repository: stephansama/packages

Length of output: 766


🏁 Script executed:

# Check the workflow file to see what tokens are set
fd -t f -e "yml" -e "yaml" | xargs grep -l "NODE_AUTH_TOKEN\|GITHUB_TOKEN" 2>/dev/null | head -10

Repository: stephansama/packages

Length of output: 46


🏁 Script executed:

# Search for how tokenEnvironmentKey is consumed in the codebase
rg -n "tokenEnvironmentKey" --type-list --type ts --type js

Repository: stephansama/packages

Length of output: 453


🏁 Script executed:

# Search for tokenEnvironmentKey usage
rg -n "tokenEnvironmentKey" --type ts --type js

Repository: stephansama/packages

Length of output: 427


🏁 Script executed:

# Find workflow files
fd -t f \( -name "*.yml" -o -name "*.yaml" \) | head -20

Repository: stephansama/packages

Length of output: 294


🏁 Script executed:

# Check the config file to understand the structure
cat .config/.multipublishrc.json

Repository: stephansama/packages

Length of output: 384


🏁 Script executed:

# Find workflow files with correct syntax
find . -name "*.yml" -o -name "*.yaml" | grep -i workflow

Repository: stephansama/packages

Length of output: 95


🏁 Script executed:

# Also look in .github/workflows
fd -type f -path "*/.github/workflows/*"

Repository: stephansama/packages

Length of output: 234


🏁 Script executed:

# Check the publish.ts to understand token usage better
sed -n '105,115p' core/multipublish/src/publish.ts

Repository: stephansama/packages

Length of output: 387


🏁 Script executed:

# Check the release workflow to see what tokens are configured
cat .github/workflows/release.yml

Repository: stephansama/packages

Length of output: 2499


🏁 Script executed:

# Check git history for the config file to see if there's context about GITHUB_TOKEN choice
git log --oneline -20 .config/.multipublishrc.json

Repository: stephansama/packages

Length of output: 127


🏁 Script executed:

# Search for comments about GITHUB_TOKEN or npm token usage in the codebase
rg -n "GITHUB_TOKEN|npm.*token|token.*npm" -i core/multipublish/src/ --context 3

Repository: stephansama/packages

Length of output: 1884


🏁 Script executed:

# Check if there's documentation about multipublish token configuration
find . -name "*.md" -o -name "README*" | xargs grep -l "multipublish\|tokenEnvironmentKey" 2>/dev/null

Repository: stephansama/packages

Length of output: 141


🏁 Script executed:

# Check multipublish README for token documentation
cat core/multipublish/README.md

Repository: stephansama/packages

Length of output: 4920


🏁 Script executed:

# Also check the main README
grep -A 10 -B 5 "multipublish\|tokenEnvironmentKey\|GITHUB_TOKEN\|NODE_AUTH_TOKEN" README.md

Repository: stephansama/packages

Length of output: 4851


Change tokenEnvironmentKey to match the public npm registry authentication.

The config uses GITHUB_TOKEN for registry.npmjs.org, but per the multipublish documentation, GITHUB_TOKEN is intended only for the GitHub NPM Registry (npm.pkg.github.com). The public npm registry requires NODE_AUTH_TOKEN, which is the schema default and matches the workflow setup.

🐛 Suggested fix
 		[
 			"npm",
 			{
 				"registry": "https://registry.npmjs.org/",
-				"tokenEnvironmentKey": "GITHUB_TOKEN"
+				"tokenEnvironmentKey": "NODE_AUTH_TOKEN"
 			}
 		]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[
"npm",
{
"registry": "https://registry.npmjs.org/",
"tokenEnvironmentKey": "GITHUB_TOKEN"
}
]
[
"npm",
{
"registry": "https://registry.npmjs.org/",
"tokenEnvironmentKey": "NODE_AUTH_TOKEN"
}
]
🤖 Prompt for AI Agents
In @.config/.multipublishrc.json around lines 11 - 17, Update the multipublish
config to use the public npm registry auth variable: change the
tokenEnvironmentKey value from "GITHUB_TOKEN" to "NODE_AUTH_TOKEN" so the
registry entry that points to "https://registry.npmjs.org/" uses the correct
authentication variable expected by multipublish and your CI workflow.

]
}
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ env:
TURBO_TEAM: ${{vars.TURBO_TEAM}}
permissions:
contents: write
packages: write
id-token: write
issues: write
pull-requests: write
Expand Down Expand Up @@ -67,8 +68,13 @@ jobs:
- if: github.ref_name == 'main'
name: 🦋 Create Changeset Release Pull Request
uses: changesets/action@v1
id: changesets
with:
commit: "chore: Update version for release"
title: "chore: Update version for release"
publish: pnpm run publish
createGithubReleases: true
- name: publish to other registries
if: steps.changesets.outputs.published == 'true'
run: |
echo "${{ steps.changesets.outputs.publishedPackages }}" | multipublish
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
.env**
.next
.react-router
.publish
.svelte-kit
.turbo
.wrangler
core/ai-commit-msg/config
core/auto-readme/config
core/example/scripts/examples.json
core/multipublish/config
dist
dist-js
examples/catppuccin-xsl/vanilla/public/**/*
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ All packages are packaged underneath the `@stephansama` scope (for example: `@st
| [create-stephansama-example](core/example/README.md) | ![npm version image](https://img.shields.io/npm/v/create-stephansama-example?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/create-stephansama-example?labelColor=211F1F) | Download an example from the @stephansama/packages examples |
| [find-makefile-targets](core/find-makefile-targets/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ffind-makefile-targets?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/find-makefile-targets?labelColor=211F1F) | Find makefile targets used to pipe into fzf |
| [github-env](core/github-env/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fgithub-env?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/github-env?labelColor=211F1F) | Additional environment variable types for GitHub CI |
| [multipublish](core/multipublish/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fmultipublish?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/multipublish?labelColor=211F1F) | Publish packages to multiple providers easily |
| [prettier-plugin-handlebars](core/prettier-plugin-handlebars/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fprettier-plugin-handlebars?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/prettier-plugin-handlebars?labelColor=211F1F) | Prettier plugin that automatically assigns the default parser for various handlebars files |
| [remark-asciinema](core/remark-asciinema/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fremark-asciinema?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/remark-asciinema?labelColor=211F1F) | A remark plugin that transforms Asciinema links into embedded players or screenshots. |
| [svelte-social-share-links](core/svelte-social-share-links/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fsvelte-social-share-links?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/svelte-social-share-links?labelColor=211F1F) | Svelte/Web component to share the current url with various social media providers |
Expand Down
173 changes: 173 additions & 0 deletions core/multipublish/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# @stephansama/multipublish

[![Source code](https://img.shields.io/badge/Source-666666?style=flat&logo=github&label=Github&labelColor=211F1F)](https://github.com/stephansama/packages/tree/main/core/multipublish)
[![Documentation](https://img.shields.io/badge/Documentation-211F1F?style=flat&logo=Wikibooks&labelColor=211F1F)](https://packages.stephansama.info/api/@stephansama/multipublish)
[![NPM Version](https://img.shields.io/npm/v/%40stephansama%2Fmultipublish?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F)](https://www.npmjs.com/package/@stephansama/multipublish)
[![npm downloads](https://img.shields.io/npm/dw/@stephansama/multipublish?labelColor=211F1F)](https://www.npmjs.com/package/@stephansama/multipublish)

Publish packages to multiple providers easily

##### Table of contents
Comment thread
coderabbitai[bot] marked this conversation as resolved.

<details><summary>Open Table of contents</summary>

- [Installation](#installation)
- [Usage](#usage)
- [Configuration](#configuration)
- [GitHub NPM Registry](#github-npm-registry)
- [JSR Configuration](#jsr-configuration)
- [Changesets](#changesets)
- [JSR](#jsr)
- [Published packages](#published-packages)

</details>

## Installation

```sh
pnpm install @stephansama/multipublish
```

## Usage
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add usage documentation for the CLI tool.

The Usage section is currently empty. Please document the basic commands, configuration options, and examples for users to understand how to use this multipublish CLI tool.

Would you like me to help draft initial usage documentation based on the CLI implementation?

🤖 Prompt for AI Agents
In @core/multipublish/README.md at line 25, The README's "Usage" section is
empty; add a concise usage guide that describes the CLI entrypoint and primary
commands, e.g., list commands like "multipublish init", "multipublish publish",
"multipublish status" (or the actual command names implemented in the CLI), list
common flags/options (e.g., --config, --dry-run, --verbose, --target), document
configuration file format and relevant environment variables, and include 2–3
short examples showing typical invocation sequences (init -> configure ->
publish and a dry-run example). Keep the section organized with subheadings
"Commands", "Options", "Configuration", and "Examples" and ensure each command
references the actual function/command names implemented in the codebase so
users can map docs to the CLI implementation.


### Configuration

You can configure `multipublish` by creating a configuration file (or object) in the root of your project. The following file formats are supported:

- `package.json`
- `.multipublishrc.cjs`
- `.multipublishrc.js`
- `.multipublishrc.json`
- `.multipublishrc.mjs`
- `.multipublishrc.ts`
- `.multipublishrc.yaml`
- `.multipublishrc.yml`
- `.multipublishrc`
- `.config/.multipublishrc.json`
- `.config/.multipublishrc.yaml`
- `.config/.multipublishrc.yml`
- `.config/.multipublishrc`
- `.config/multipublishrc.cjs`
- `.config/multipublishrc.js`
- `.config/multipublishrc.json`
- `.config/multipublishrc.mjs`
- `.config/multipublishrc.ts`
- `.config/multipublishrc.yaml`
- `.config/multipublishrc.yml`
- `.config/multipublishrc`
- `multipublish.config.cjs`
- `multipublish.config.js`
- `multipublish.config.mjs`
- `multipublish.config.ts`

```json
{
"$schema": "./node_modules/@stephansama/multipublish/config/schema.json",
"platforms": [
["jsr", { "experimentalGenerateJSR": true, "defaultExclude": ["!dist"] }],
[
"npm",
{
"registry": "https://npm.pkg.github.com",
"tokenEnvironmentKey": "GITHUB_TOKEN"
}
]
]
}
```

### GitHub NPM Registry

If publishing to the GitHub NPM registry, you must add `packages` to permissions when using a GitHub token. And allow `write` and `read` permissions for workflows (located in repo settings > actions > general).

```yaml
permissions:
packages: write
```

### JSR Configuration

When publishing to JSR, you must either have a valid `jsr.json` or `deno.json`, or allow `experimentalGenerateJSR` using the config option.

### Changesets

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider more concise wording.

The phrase "In order to use" can be simplified to "To use" for brevity.

✏️ Proposed change
-In order to use this with changesets, please update your version script with a preversion script that calls the `multipublish` CLI.
+To use this with changesets, update your version script with a preversion script that calls the `multipublish` CLI.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 LanguageTool

[style] ~91-~91: Consider a more concise word here.
Context: ...ing the config option. ### Changesets In order to use this with changesets, please update...

(IN_ORDER_TO_PREMIUM)

🤖 Prompt for AI Agents
In @core/multipublish/README.md at line 91, Replace the phrase "In order to use"
with the more concise "To use" in the README text where the usage instruction
appears; locate the sentence containing "In order to use" and edit it to start
with "To use" while preserving the rest of the sentence and formatting.

If you are using jsr this with changesets, please update your version script with a preversion script that calls the `multipublish` CLI in order to update your existing jsr configurations.

#### JSR

```json
{
"scripts": {
"preversion": "multipublish --useChangesetStatus --versionJsr",
"version": "changeset version"
}
}
```

#### Published packages

you can run multipublish after a changeset publish like so

```yaml
- if: github.ref_name == 'main'
name: 🦋 Create Changeset Release
uses: changesets/action@v1
id: changesets
with:
commit: "chore: Update version for release"
title: "chore: Update version for release"
publish: pnpm run publish
createGithubReleases: true
- name: publish to other registries
if: steps.changesets.outputs.published == 'true'
run: |
echo "${{ steps.changesets.outputs.publishedPackages }}" | multipublish
```

<!-- ZOD path="./src/schema.ts" start -->

# Zod Schema

## Config

_Object containing the following properties:_

| Property | Type | Default |
| :------------------- | :---------------------- | :----------- |
| **`platforms`** (\*) | [Platforms](#platforms) | |
| `tmpDirectory` | `string` | `'.release'` |
| `useChangesets` | `boolean` | `true` |

_(\*) Required._

## JsrPlatformOptions

_Object containing the following properties:_

| Property | Type | Default |
| :--------------------------- | :-------------- | :------ |
| `allowSlowTypes` | `boolean` | `true` |
| `defaultExclude` | `Array<string>` | |
| `defaultInclude` | `Array<string>` | |
| `experimentalGenerateJSR` | `boolean` | `false` |
| `experimentalUpdateCatalogs` | `boolean` | `false` |

_All properties are optional._

## NpmPlatformOptions

_Object containing the following properties:_

| Property | Type | Default |
| :-------------------- | :--------------------------- | :------------------------------ |
| `registry` | `string` | `'https://registry.npmjs.org/'` |
| `strategy` | `'.npmrc' \| 'package.json'` | `'.npmrc'` |
| `tokenEnvironmentKey` | `string` | `'NODE_AUTH_TOKEN'` |

_All properties are optional._

## Platforms

*Array of `'jsr' | 'npm'` *or\* _Tuple:_<ol><li>`'jsr'`</li><li>[JsrPlatformOptions](#jsrplatformoptions)</li></ol> _or_ _Tuple:_<ol><li>`'npm'`</li><li>[NpmPlatformOptions](#npmplatformoptions)</li></ol> items.\*
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix malformed emphasis markers in generated content.

The line contains spaces inside emphasis markers (*or\* and items.\*) causing rendering issues. If this is auto-generated, the generator needs adjustment.

📝 Proposed fix
-*Array of `'jsr' | 'npm'` *or\* _Tuple:_<ol><li>`'jsr'`</li><li>[JsrPlatformOptions](#jsrplatformoptions)</li></ol> _or_ _Tuple:_<ol><li>`'npm'`</li><li>[NpmPlatformOptions](#npmplatformoptions)</li></ol> items.\*
+*Array of `'jsr' | 'npm'` or Tuple:*<ol><li>`'jsr'`</li><li>[JsrPlatformOptions](#jsrplatformoptions)</li></ol> *or Tuple:*<ol><li>`'npm'`</li><li>[NpmPlatformOptions](#npmplatformoptions)</li></ol> *items.*
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
*Array of `'jsr' | 'npm'` *or\* _Tuple:_<ol><li>`'jsr'`</li><li>[JsrPlatformOptions](#jsrplatformoptions)</li></ol> _or_ _Tuple:_<ol><li>`'npm'`</li><li>[NpmPlatformOptions](#npmplatformoptions)</li></ol> items.\*
*Array of `'jsr' | 'npm'` or Tuple:*<ol><li>`'jsr'`</li><li>[JsrPlatformOptions](#jsrplatformoptions)</li></ol> *or Tuple:*<ol><li>`'npm'`</li><li>[NpmPlatformOptions](#npmplatformoptions)</li></ol> *items.*
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

147-147: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)

🤖 Prompt for AI Agents
In @core/multipublish/README.md at line 147, The README line "Array of 'jsr' |
'npm' *or\* _Tuple:... items.\*" contains malformed emphasis markers and stray
backslashes; fix it by removing the backslashes and extra spaces around
asterisks or by correctly placing asterisks immediately around the words to be
emphasized (e.g., change "*or\*" to "*or*" or simply "or", and remove the
trailing ".*" so "items." is plain text), ensuring the generated markdown uses
valid emphasis syntax for the Array / Tuple description.


<!-- ZOD end -->
32 changes: 32 additions & 0 deletions core/multipublish/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as fsp from "node:fs/promises";
import * as path from "path";
import { build as tsdown } from "tsdown";
import * as z from "zod";

const outDir = path.resolve("./dist");
const schemaDir = path.resolve("./config");

await build({ attw: false, entry: ["./src/index.ts"] });

await build({ dts: true, entry: ["./src/schema.ts"], outDir: schemaDir });

const { configSchema } = await import("./config/schema.js");

const jsonSchema = z.toJSONSchema(configSchema);

const jsonString = JSON.stringify(jsonSchema);

await fsp.writeFile(path.join(schemaDir, "schema.json"), jsonString);

/** @param {import('tsdown').Options} opts */
function build(opts) {
return tsdown({
attw: { excludeEntrypoints: ["schema.json"] },
exports: true,
format: ["esm", "cjs"],
outDir,
skipNodeModulesBundle: true,
target: "esnext",
...opts,
});
}
5 changes: 5 additions & 0 deletions core/multipublish/cli.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node

"use strict";

import("./dist/index.js").then((mod) => mod.run());
Comment on lines +1 to +5
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding error handling for import/run failures.

If the build hasn't been run or run() throws, users will see an uncaught promise rejection without helpful context. Consider catching and reporting errors gracefully:

♻️ Suggested improvement
 #!/usr/bin/env node
 
 "use strict";
 
-import("./dist/index.js").then((mod) => mod.run());
+import("./dist/index.js")
+	.then((mod) => mod.run())
+	.catch((err) => {
+		console.error("multipublish failed:", err.message);
+		process.exitCode = 1;
+	});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#!/usr/bin/env node
"use strict";
import("./dist/index.js").then((mod) => mod.run());
#!/usr/bin/env node
"use strict";
import("./dist/index.js")
.then((mod) => mod.run())
.catch((err) => {
console.error("multipublish failed:", err.message);
process.exitCode = 1;
});
🤖 Prompt for AI Agents
In `@core/multipublish/cli.mjs` around lines 1 - 5, The bootstrap script currently
imports "./dist/index.js" and calls mod.run() without handling failures, so add
a rejection handler to the dynamic import and the run invocation: wrap
import("./dist/index.js") promise chain with .catch to log a clear error
(including the error object) and exit non‑zero, and also ensure any
thrown/rejected value from mod.run() is caught and reported (either by
awaiting/then/catch on mod.run() or handling its returned promise), referencing
the import("./dist/index.js") call and mod.run() invocation.

68 changes: 68 additions & 0 deletions core/multipublish/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"name": "@stephansama/multipublish",
"version": "0.0.0",
"description": "Publish packages to multiple providers easily",
"keywords": [
"multipublish"
],
"homepage": "https://packages.stephansama.info/api/@stephansama/multipublish",
"repository": {
"type": "git",
"url": "git+https://github.com/stephansama/packages.git",
"directory": "core/multipublish"
},
"license": "MIT",
"author": {
"name": "Stephan Randle",
"email": "stephanrandle.dev@gmail.com",
"url": "https://stephansama.info"
},
"type": "module",
"exports": {
".": {
"import": "./config/schema.js",
"require": "./config/schema.cjs"
},
"./package.json": "./package.json"
},
"main": "./config/schema.cjs",
"module": "./config/schema.js",
"types": "./config/schema.d.cts",
Comment thread
stephansama marked this conversation as resolved.
Comment thread
stephansama marked this conversation as resolved.
"bin": "./cli.mjs",
"files": [
"./dist",
"./config",
"./cli.mjs"
Comment on lines +33 to +35
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider removing the ./ prefix from files array entries.

While the ./ prefix is valid, it's more idiomatic to omit it in the files array. Standard practice uses relative paths without the prefix.

♻️ Proposed refactor
 	"files": [
-		"./dist",
-		"./config",
-		"./cli.mjs"
+		"dist",
+		"config",
+		"cli.mjs"
 	],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"./dist",
"./config",
"./cli.mjs"
"dist",
"config",
"cli.mjs"
🤖 Prompt for AI Agents
In @core/multipublish/package.json around lines 33 - 35, The files array entries
in package.json currently use a leading "./" (e.g., "./dist", "./config",
"./cli.mjs"); update those entries to the idiomatic form without the "./" prefix
(dist, config, cli.mjs) by editing the files array in
core/multipublish/package.json so each entry is the relative path without the
leading dot-slash.

],
Comment on lines +32 to +36
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Examine build configuration and package.json exports
cd core/multipublish || exit 1

echo "=== package.json exports and files ==="
jq '.exports, .files, .bin' package.json

echo ""
echo "=== build.mjs contents ==="
if [ -f build.mjs ]; then
  cat build.mjs
else
  echo "build.mjs not found"
fi

echo ""
echo "=== Directory listing ==="
ls -la

Repository: stephansama/packages

Length of output: 1723


Remove ./dist from the files array or add corresponding exports.

The dist directory is built by build.mjs (compiling src/index.ts), but the exports configuration doesn't reference it. Either remove ./dist from files if it's not intended to be published, or add exports that point to the built files in dist.

🤖 Prompt for AI Agents
In @core/multipublish/package.json around lines 32 - 36, The package.json
"files" array currently includes "./dist" but package.exports doesn’t expose
built artifacts; either remove "./dist" from the "files" array if you don’t
intend to publish built output, or add proper entries in "exports" that point to
the compiled outputs in "./dist" (e.g., map the package entrypoints used by
build.mjs / src/index.ts to their corresponding files in dist and ensure
"main"/"module"/"types" or "exports" entries reference those dist paths) so
published packages include and resolve the built files.

"scripts": {
"build": "node build.mjs",
"dev": "node --watch build.mjs",
"lint": "eslint ./src/ --pass-on-no-patterns --no-error-on-unmatched-pattern"
},
"dependencies": {
"@manypkg/find-root": "catalog:",
"@manypkg/get-packages": "catalog:",
"cosmiconfig": "catalog:cli",
"dedent": "^1.7.1",
"fast-glob": "^3.3.3",
"obug": "catalog:cli",
"package-manager-detector": "^1.6.0",
"yaml": "^2.8.2",
"yargs": "catalog:cli",
"zod": "catalog:schema"
},
"devDependencies": {
"@types/yargs": "catalog:",
"es-toolkit": "catalog:",
"jsr": "catalog:",
"tsdown": "catalog:"
},
"peerDependencies": {
"jsr": ">=0.10"
},
Comment thread
stephansama marked this conversation as resolved.
"packageManager": "pnpm@10.11.0",
"publishConfig": {
"access": "public",
"provenance": true
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
Loading
Loading