@ondeinference / cli / commits / 02e2fff

Add NPM packaging and release workflow for CLI

keypair34 committed Apr 23, 2026 at 06:28 UTC 02e2fffcb0e3f45788aba5a27ce0cd52a01b5c90
13 files changed +651
.github/workflows/release-npm.yml new
+221
@@ -0,0 +1,221 @@
1 +name: NPM Release
2 +
3 +on:
4 + push:
5 + tags:
6 + - "v*.*.*"
7 + workflow_dispatch:
8 + inputs:
9 + tag:
10 + description: "Release tag (e.g. v0.2.0)"
11 + required: true
12 +
13 +permissions:
14 + id-token: write
15 + contents: read
16 +
17 +env:
18 + CARGO_TERM_COLOR: always
19 + ONDE_APP_ID: ${{ secrets.ONDE_APP_ID }}
20 + ONDE_APP_SECRET: ${{ secrets.ONDE_APP_SECRET }}
21 + GRESIQ_API_KEY: ${{ secrets.GRESIQ_API_KEY }}
22 + GRESIQ_API_SECRET: ${{ secrets.GRESIQ_API_SECRET }}
23 + HF_TOKEN: ${{ secrets.HF_TOKEN }}
24 +
25 +jobs:
26 + publish-npm-binaries:
27 + name: Publish NPM platform packages
28 + runs-on: ${{ matrix.build.OS }}
29 + strategy:
30 + fail-fast: false
31 + matrix:
32 + build:
33 + - {
34 + NAME: linux-x64-glibc,
35 + OS: ubuntu-latest,
36 + TARGET: x86_64-unknown-linux-gnu,
37 + }
38 + - {
39 + NAME: linux-arm64-glibc,
40 + OS: ubuntu-24.04-arm,
41 + TARGET: aarch64-unknown-linux-gnu,
42 + }
43 + - {
44 + NAME: win32-x64-msvc,
45 + OS: windows-2022,
46 + TARGET: x86_64-pc-windows-msvc,
47 + }
48 + - {
49 + NAME: win32-arm64-msvc,
50 + OS: windows-2022,
51 + TARGET: aarch64-pc-windows-msvc,
52 + }
53 + - {
54 + NAME: darwin-x64,
55 + OS: macos-15-intel,
56 + TARGET: x86_64-apple-darwin,
57 + }
58 + - {
59 + NAME: darwin-arm64,
60 + OS: macos-latest,
61 + TARGET: aarch64-apple-darwin,
62 + }
63 +
64 + steps:
65 + - name: Checkout
66 + uses: actions/checkout@v6
67 + with:
68 + ref: ${{ github.event.inputs.tag || github.ref }}
69 +
70 + - name: Set the release version
71 + shell: bash
72 + run: |
73 + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
74 + release_version="${GITHUB_REF_NAME#v}"
75 + else
76 + release_version="${{ github.event.inputs.tag }}"
77 + release_version="${release_version#v}"
78 + fi
79 + echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
80 +
81 + - name: Read Rust toolchain
82 + shell: bash
83 + run: |
84 + rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
85 + if [ -z "$rust_toolchain" ]; then
86 + echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
87 + exit 1
88 + fi
89 + echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
90 +
91 + - name: Install Rust toolchain
92 + uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
93 + with:
94 + toolchain: ${{ env.RUST_TOOLCHAIN }}
95 +
96 + - name: Install Rust target
97 + shell: bash
98 + run: |
99 + rustup target add ${{ matrix.build.TARGET }} --toolchain ${{ env.RUST_TOOLCHAIN }}
100 + rustup target list --installed
101 +
102 + - name: Setup Rust cache
103 + uses: Swatinem/rust-cache@v2
104 + with:
105 + key: npm-${{ matrix.build.TARGET }}
106 +
107 + - name: Build binary
108 + shell: bash
109 + run: cargo build --locked --release --target ${{ matrix.build.TARGET }}
110 +
111 + - name: Install Node
112 + uses: actions/setup-node@v6
113 + with:
114 + node-version-file: .nvmrc
115 + registry-url: "https://registry.npmjs.org"
116 +
117 + - name: Publish platform package to NPM
118 + shell: bash
119 + run: |
120 + cd npm
121 +
122 + # Binary name from Cargo.toml
123 + cargo_bin="onde"
124 +
125 + # Prefix used for optional dependency package names
126 + node_pkg_prefix="cli"
127 +
128 + # Derive OS and architecture from the build matrix name
129 + # Matrix name format: <os>-<arch>[-<extra>]
130 + node_os=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f1)
131 + export node_os
132 + node_arch=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f2)
133 + export node_arch
134 +
135 + # Set the version
136 + export node_version="${{ env.RELEASE_VERSION }}"
137 +
138 + # Build the platform package name; normalise win32 → windows
139 + if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
140 + export node_pkg="${node_pkg_prefix}-windows-${node_arch}"
141 + else
142 + export node_pkg="${node_pkg_prefix}-${node_os}-${node_arch}"
143 + fi
144 +
145 + # Create the package directory
146 + mkdir -p "${node_pkg}/bin"
147 +
148 + # Generate package.json + README for this platform slice
149 + node ./scripts/render-platform-package.cjs \
150 + "${node_pkg}" \
151 + "${node_version}" \
152 + "${node_os}" \
153 + "${node_arch}"
154 +
155 + # Windows binaries carry a .exe extension
156 + if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
157 + cargo_bin="${cargo_bin}.exe"
158 + fi
159 +
160 + cp "../target/${{ matrix.build.TARGET }}/release/${cargo_bin}" "${node_pkg}/bin"
161 +
162 + cd "${node_pkg}"
163 +
164 + npm_package_name="@ondeinference/${node_pkg}"
165 + if npm view "${npm_package_name}@${node_version}" version >/dev/null 2>&1; then
166 + echo "${npm_package_name}@${node_version} already exists on npm, skipping publish"
167 + exit 0
168 + fi
169 +
170 + npm publish --access public --provenance
171 +
172 + publish-npm-base:
173 + name: Publish base NPM package (@ondeinference/cli)
174 + needs: publish-npm-binaries
175 + runs-on: ubuntu-latest
176 +
177 + steps:
178 + - name: Checkout
179 + uses: actions/checkout@v6
180 + with:
181 + ref: ${{ github.event.inputs.tag || github.ref }}
182 +
183 + - name: Set the release version
184 + shell: bash
185 + run: |
186 + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
187 + release_version="${GITHUB_REF_NAME#v}"
188 + else
189 + release_version="${{ github.event.inputs.tag }}"
190 + release_version="${release_version#v}"
191 + fi
192 + echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
193 +
194 + - name: Install Node
195 + uses: actions/setup-node@v6
196 + with:
197 + node-version-file: .nvmrc
198 + registry-url: "https://registry.npmjs.org"
199 +
200 + - name: Publish base package to NPM
201 + shell: bash
202 + run: |
203 + cd npm/onde-cli
204 +
205 + # Rewrite package.json with the correct release version and
206 + # matching optionalDependency versions
207 + node ../scripts/render-main-package.cjs \
208 + "./package.json" \
209 + "${{ env.RELEASE_VERSION }}"
210 +
211 + npm_package_name="@ondeinference/cli"
212 + npm_package_version="${{ env.RELEASE_VERSION }}"
213 +
214 + if npm view "${npm_package_name}@${npm_package_version}" version >/dev/null 2>&1; then
215 + echo "${npm_package_name}@${npm_package_version} already exists on npm, skipping publish"
216 + exit 0
217 + fi
218 +
219 + npm install
220 + npm run build
221 + npm publish --access public --provenance
.nvmrc new
+1
@@ -0,0 +1 @@
1 +20
npm/README.md.tmpl new
+27
@@ -0,0 +1,27 @@
1 +<p align="center">
2 + <img src="https://avatars.githubusercontent.com/u/218425892?s=200&v=4" alt="Onde Inference" width="96">
3 +</p>
4 +
5 +<h1 align="center">Onde CLI</h1>
6 +
7 +## `${node_pkg}`
8 +
9 +This is a platform-specific binary for [`@ondeinference/cli`](https://www.npmjs.com/package/@ondeinference/cli). You don't need to install it directly.
10 +
11 +Install the main package instead:
12 +
13 +```sh
14 +npm install -g @ondeinference/cli
15 +```
16 +
17 +npm pulls in the right binary for your OS and architecture.
18 +
19 +## Links
20 +
21 +- [Source code](https://github.com/ondeinference/onde-cli)
22 +- [Issues](https://github.com/ondeinference/onde-cli/issues)
23 +- [Website](https://ondeinference.com)
24 +
25 +## License
26 +
27 +[MIT OR Apache-2.0](https://github.com/ondeinference/onde-cli/blob/main/LICENSE)
npm/onde-cli/.gitignore new
+2
@@ -0,0 +1,2 @@
1 +lib/
2 +node_modules/
npm/onde-cli/README.md new
+79
@@ -0,0 +1,79 @@
1 +<p align="center">
2 + <img src="https://raw.githubusercontent.com/ondeinference/onde/main/assets/onde-inference-logo.svg" alt="Onde Inference" width="80">
3 +</p>
4 +
5 +<h1 align="center">@ondeinference/cli</h1>
6 +
7 +<p align="center">
8 + Manage your Onde Inference account from the terminal.
9 +</p>
10 +
11 +<p align="center">
12 + <a href="https://www.npmjs.com/package/@ondeinference/cli"><img src="https://img.shields.io/npm/v/@ondeinference/cli?style=flat-square&labelColor=17211D&color=235843" alt="npm"></a>
13 + <a href="https://crates.io/crates/onde-cli"><img src="https://img.shields.io/crates/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="crates.io"></a>
14 + <a href="https://pypi.org/project/onde-cli/"><img src="https://img.shields.io/pypi/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="PyPI"></a>
15 + <a href="https://ondeinference.com"><img src="https://img.shields.io/badge/ondeinference.com-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
16 +</p>
17 +
18 +---
19 +
20 +## Install
21 +
22 +```sh
23 +npm install -g @ondeinference/cli
24 +```
25 +
26 +The right binary for your platform gets pulled in automatically. Works on macOS (Apple Silicon and Intel), Linux (x64 and arm64), and Windows (x64 and arm64).
27 +
28 +### Other ways to install
29 +
30 +| Method | Command |
31 +|---|---|
32 +| **Homebrew** | `brew install ondeinference/homebrew-tap/onde` |
33 +| **pip** | `pip install onde-cli` |
34 +| **uv** | `uv tool install onde-cli` |
35 +| **Cargo** | `cargo install onde-cli` |
36 +
37 +---
38 +
39 +## Usage
40 +
41 +```sh
42 +onde
43 +```
44 +
45 +Opens a TUI. Sign up or sign in from there, no browser needed.
46 +
47 +| Key | What it does |
48 +|---|---|
49 +| `Tab` | Move between fields |
50 +| `Enter` | Submit / sign out |
51 +| `Ctrl+L` | Sign in screen |
52 +| `Ctrl+N` | New account screen |
53 +| `Ctrl+C` | Quit |
54 +
55 +---
56 +
57 +## What's Onde?
58 +
59 +[Onde Inference](https://ondeinference.com) runs LLMs on the user's device. No server round-trips, no data leaving the hardware. It ships as a native SDK for each platform:
60 +
61 +<p align="center">
62 + <a href="https://github.com/ondeinference/onde-swift">Swift</a>&ensp;·&ensp;<a href="https://pub.dev/packages/onde_inference">Flutter</a>&ensp;·&ensp;<a href="https://www.npmjs.com/package/@ondeinference/react-native">React Native</a>&ensp;·&ensp;<a href="https://crates.io/crates/onde">Rust</a>
63 +</p>
64 +
65 +This CLI handles the account side of things. The SDKs handle inference.
66 +
67 +---
68 +
69 +## Debug
70 +
71 +Logs go to `~/.cache/onde/debug.log`.
72 +
73 +## License
74 +
75 +Dual-licensed under [MIT](https://github.com/ondeinference/onde-cli/blob/main/LICENSE-MIT) and [Apache 2.0](https://github.com/ondeinference/onde-cli/blob/main/LICENSE-APACHE).
76 +
77 +<p align="center">
78 + <sub>© 2026 <a href="https://ondeinference.com">Onde Inference</a> · <a href="https://apps.apple.com/se/developer/splitfire-ab/id1831430993">Splitfire AB</a></sub>
79 +</p>
\ No newline at end of file
npm/onde-cli/package-lock.json new
+77
@@ -0,0 +1,77 @@
1 +{
2 + "name": "@ondeinference/cli",
3 + "version": "0.2.0",
4 + "lockfileVersion": 3,
5 + "requires": true,
6 + "packages": {
7 + "": {
8 + "name": "@ondeinference/cli",
9 + "version": "0.2.0",
10 + "license": "MIT OR Apache-2.0",
11 + "bin": {
12 + "onde": "lib/index.js"
13 + },
14 + "devDependencies": {
15 + "@types/node": "^18.15.11",
16 + "typescript": "^5.0.0"
17 + },
18 + "optionalDependencies": {
19 + "@ondeinference/cli-darwin-arm64": "0.2.0",
20 + "@ondeinference/cli-darwin-x64": "0.2.0",
21 + "@ondeinference/cli-linux-arm64": "0.2.0",
22 + "@ondeinference/cli-linux-x64": "0.2.0",
23 + "@ondeinference/cli-windows-arm64": "0.2.0",
24 + "@ondeinference/cli-windows-x64": "0.2.0"
25 + }
26 + },
27 + "node_modules/@ondeinference/cli-darwin-arm64": {
28 + "optional": true
29 + },
30 + "node_modules/@ondeinference/cli-darwin-x64": {
31 + "optional": true
32 + },
33 + "node_modules/@ondeinference/cli-linux-arm64": {
34 + "optional": true
35 + },
36 + "node_modules/@ondeinference/cli-linux-x64": {
37 + "optional": true
38 + },
39 + "node_modules/@ondeinference/cli-windows-arm64": {
40 + "optional": true
41 + },
42 + "node_modules/@ondeinference/cli-windows-x64": {
43 + "optional": true
44 + },
45 + "node_modules/@types/node": {
46 + "version": "18.19.130",
47 + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
48 + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
49 + "dev": true,
50 + "license": "MIT",
51 + "dependencies": {
52 + "undici-types": "~5.26.4"
53 + }
54 + },
55 + "node_modules/typescript": {
56 + "version": "5.9.3",
57 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
58 + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
59 + "dev": true,
60 + "license": "Apache-2.0",
61 + "bin": {
62 + "tsc": "bin/tsc",
63 + "tsserver": "bin/tsserver"
64 + },
65 + "engines": {
66 + "node": ">=14.17"
67 + }
68 + },
69 + "node_modules/undici-types": {
70 + "version": "5.26.5",
71 + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
72 + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
73 + "dev": true,
74 + "license": "MIT"
75 + }
76 + }
77 +}
npm/onde-cli/package.json new
+45
@@ -0,0 +1,45 @@
1 +{
2 + "name": "@ondeinference/cli",
3 + "version": "0.2.0",
4 + "keywords": [
5 + "onde",
6 + "cli",
7 + "onde-cli",
8 + "inference",
9 + "llm",
10 + "ai",
11 + "on-device",
12 + "developer",
13 + "tools"
14 + ],
15 + "bin": {
16 + "onde": "lib/index.js"
17 + },
18 + "files": [
19 + "lib",
20 + "README.md"
21 + ],
22 + "description": "A CLI for managing your Onde Inference account and models.",
23 + "license": "MIT OR Apache-2.0",
24 + "repository": {
25 + "type": "git",
26 + "url": "git+https://github.com/ondeinference/onde-cli.git"
27 + },
28 + "scripts": {
29 + "typecheck": "tsc --noEmit",
30 + "build": "tsc",
31 + "dev": "npm run build && node lib/index.js"
32 + },
33 + "devDependencies": {
34 + "@types/node": "^18.15.11",
35 + "typescript": "^5.0.0"
36 + },
37 + "optionalDependencies": {
38 + "@ondeinference/cli-darwin-arm64": "0.2.0",
39 + "@ondeinference/cli-darwin-x64": "0.2.0",
40 + "@ondeinference/cli-linux-arm64": "0.2.0",
41 + "@ondeinference/cli-linux-x64": "0.2.0",
42 + "@ondeinference/cli-windows-arm64": "0.2.0",
43 + "@ondeinference/cli-windows-x64": "0.2.0"
44 + }
45 +}
npm/onde-cli/src/index.ts new
+41
@@ -0,0 +1,41 @@
1 +#!/usr/bin/env node
2 +
3 +import { spawnSync } from "child_process";
4 +
5 +/**
6 + * Returns the executable path which is located inside node_modules
7 + * The naming convention is cli-OS-ARCH
8 + * If the platform is win32 or cygwin, executable will include a .exe extension.
9 + * @see https://nodejs.org/api/os.html#osarch
10 + * @see https://nodejs.org/api/os.html#osplatform
11 + * @example "x/xx/node_modules/cli-darwin-arm64"
12 + */
13 +function getExePath() {
14 + const arch = process.arch;
15 + let os = process.platform as string;
16 + let extension = "";
17 + if (["win32", "cygwin"].includes(process.platform)) {
18 + os = "windows";
19 + extension = ".exe";
20 + }
21 +
22 + try {
23 + // Since the binary will be located inside node_modules, we can simply call require.resolve
24 + return require.resolve(`@ondeinference/cli-${os}-${arch}/bin/onde${extension}`);
25 + } catch (e) {
26 + throw new Error(
27 + `Couldn't find application binary inside node_modules for ${os}-${arch}`
28 + );
29 + }
30 +}
31 +
32 +/**
33 + * Runs the application with args using nodejs spawn
34 + */
35 +function run() {
36 + const args = process.argv.slice(2);
37 + const processResult = spawnSync(getExePath(), args, { stdio: "inherit" });
38 + process.exit(processResult.status ?? 0);
39 +}
40 +
41 +run();
npm/onde-cli/tsconfig.json new
+12
@@ -0,0 +1,12 @@
1 +{
2 + "compilerOptions": {
3 + "target": "es2016",
4 + "module": "commonjs",
5 + "esModuleInterop": true,
6 + "baseUrl": "./",
7 + "outDir": "lib",
8 + "forceConsistentCasingInFileNames": true,
9 + "strict": true,
10 + "skipLibCheck": true
11 + }
12 +}
npm/package-main.json.tmpl new
+42
@@ -0,0 +1,42 @@
1 +{
2 + "name": "@ondeinference/cli",
3 + "version": "${release_version}",
4 + "keywords": [
5 + "onde",
6 + "cli",
7 + "onde-cli",
8 + "inference",
9 + "llm",
10 + "ai",
11 + "on-device",
12 + "developer",
13 + "tools"
14 + ],
15 + "bin": {
16 + "onde": "lib/index.js"
17 + },
18 + "files": ["lib", "README.md"],
19 + "description": "A CLI for managing your Onde Inference account and models.",
20 + "license": "MIT OR Apache-2.0",
21 + "repository": {
22 + "type": "git",
23 + "url": "git+https://github.com/ondeinference/onde-cli.git"
24 + },
25 + "scripts": {
26 + "typecheck": "tsc --noEmit",
27 + "build": "tsc",
28 + "dev": "npm run build && node lib/index.js"
29 + },
30 + "devDependencies": {
31 + "@types/node": "^18.15.11",
32 + "typescript": "^5.0.0"
33 + },
34 + "optionalDependencies": {
35 + "@ondeinference/cli-darwin-arm64": "${release_version}",
36 + "@ondeinference/cli-darwin-x64": "${release_version}",
37 + "@ondeinference/cli-linux-arm64": "${release_version}",
38 + "@ondeinference/cli-linux-x64": "${release_version}",
39 + "@ondeinference/cli-windows-arm64": "${release_version}",
40 + "@ondeinference/cli-windows-x64": "${release_version}"
41 + }
42 +}
npm/package.json.tmpl new
+14
@@ -0,0 +1,14 @@
1 +{
2 + "name": "@ondeinference/${node_pkg}",
3 + "version": "${node_version}",
4 + "description": "Platform binary for the Onde CLI.",
5 + "license": "MIT OR Apache-2.0",
6 + "repository": {
7 + "type": "git",
8 + "url": "git+https://github.com/ondeinference/onde-cli.git"
9 + },
10 + "keywords": ["${node_pkg}","cli","binary","node","nodejs","npm","package","onde","inference","llm"],
11 + "os": ["${node_os}"],
12 + "cpu": ["${node_arch}"],
13 + "files": ["bin"]
14 +}
npm/scripts/render-main-package.cjs new
+34
@@ -0,0 +1,34 @@
1 +#!/usr/bin/env node
2 +
3 +const fs = require("fs");
4 +const path = require("path");
5 +
6 +const [outputPath, version] = process.argv.slice(2);
7 +
8 +if (!outputPath || !version) {
9 + throw new Error("Usage: render-main-package.cjs <output-path> <version>");
10 +}
11 +
12 +const npmRoot = path.resolve(__dirname, "..");
13 +
14 +const vars = {
15 + release_version: version,
16 +};
17 +
18 +/**
19 + * Replace every `${key}` in the template with the corresponding value from vars.
20 + */
21 +function interpolate(template, variables) {
22 + return template.replace(/\$\{(\w+)\}/g, (match, key) => {
23 + if (key in variables) return variables[key];
24 + return match;
25 + });
26 +}
27 +
28 +// Read and interpolate package-main.json.tmpl
29 +const template = fs.readFileSync(
30 + path.join(npmRoot, "package-main.json.tmpl"),
31 + "utf-8",
32 +);
33 +
34 +fs.writeFileSync(path.resolve(outputPath), interpolate(template, vars));
npm/scripts/render-platform-package.cjs new
+56
@@ -0,0 +1,56 @@
1 +#!/usr/bin/env node
2 +
3 +const fs = require("fs");
4 +const path = require("path");
5 +
6 +const [packageName, version, operatingSystem, architecture] =
7 + process.argv.slice(2);
8 +
9 +if (!packageName || !version || !operatingSystem || !architecture) {
10 + throw new Error(
11 + "Usage: render-platform-package.cjs <package-name> <version> <os> <arch>",
12 + );
13 +}
14 +
15 +const npmRoot = path.resolve(__dirname, "..");
16 +const packageDirectory = path.resolve(npmRoot, packageName);
17 +
18 +fs.mkdirSync(packageDirectory, { recursive: true });
19 +
20 +// Variable map for template interpolation
21 +const vars = {
22 + node_pkg: packageName,
23 + node_version: version,
24 + node_os: operatingSystem,
25 + node_arch: architecture,
26 +};
27 +
28 +/**
29 + * Replace every `${key}` in the template with the corresponding value from vars.
30 + */
31 +function interpolate(template, variables) {
32 + return template.replace(/\$\{(\w+)\}/g, (match, key) => {
33 + if (key in variables) return variables[key];
34 + return match;
35 + });
36 +}
37 +
38 +// Read and interpolate package.json.tmpl
39 +const packageTemplate = fs.readFileSync(
40 + path.join(npmRoot, "package.json.tmpl"),
41 + "utf-8",
42 +);
43 +fs.writeFileSync(
44 + path.join(packageDirectory, "package.json"),
45 + interpolate(packageTemplate, vars),
46 +);
47 +
48 +// Read and interpolate README.md.tmpl
49 +const readmeTemplate = fs.readFileSync(
50 + path.join(npmRoot, "README.md.tmpl"),
51 + "utf-8",
52 +);
53 +fs.writeFileSync(
54 + path.join(packageDirectory, "README.md"),
55 + interpolate(readmeTemplate, vars),
56 +);