@lewishowles/cli-style 0.1.0 → 0.2.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 - 2026-06-27
4
+
5
+ ### Added
6
+
7
+ - Added standalone binary packaging with `bun run package:binary`.
8
+ - Added release tarballs containing `bin/cli-style` and Bash/Python adapters.
9
+ - Added tagged GitHub release workflow for npm trusted publishing and binary assets.
10
+ - Added `cli-style adapter-path bash|python` for adapter discovery.
11
+
12
+ ### Changed
13
+
14
+ - Configured package publishing for public npm.
15
+ - Documented binary install flow for non-JS projects.
package/README.md CHANGED
@@ -4,8 +4,8 @@ Shared terminal output styles for tools, diagnostics, and package CLIs.
4
4
 
5
5
  ## Requirements
6
6
 
7
- - Bun
8
- - Node.js 20 or newer
7
+ - Bun and Node.js 20 or newer for JavaScript projects and local binary builds
8
+ - The standalone binary for Bash or Python projects that should not install Bun
9
9
 
10
10
  ## Install
11
11
 
@@ -15,11 +15,10 @@ JavaScript projects can install the package directly:
15
15
  bun add @lewishowles/cli-style
16
16
  ```
17
17
 
18
- Bash and Python projects still need the package available somewhere, because their adapters call the `cli-style` binary. If the project already has Node or Bun tooling, add it as a dev dependency. Otherwise, link or vendor this package in a stable tools directory and point the adapters at that copy:
18
+ Bash and Python projects call the `cli-style` binary through thin adapters. If the project already has Node or Bun tooling, add this package as a dev dependency and use the package binary. Otherwise, install or vendor the standalone binary and put it on `PATH`:
19
19
 
20
20
  ```bash
21
- export CLI_STYLE_BIN="/path/to/cli-style/bin/cli-style.js"
22
- export PYTHONPATH="/path/to/cli-style/adapters/python:$PYTHONPATH"
21
+ export PATH="/path/to/cli-style/bin:$PATH"
23
22
  ```
24
23
 
25
24
  ## JavaScript
@@ -68,10 +67,26 @@ JSON
68
67
 
69
68
  `render` supports `--profile`, `--plain`, `--no-colour`, `--no-color`, `--no-unicode`, and `--width`. It rejects `--json`; JSON profile behaviour is for library calls and machine-readable commands.
70
69
 
70
+ Build a local standalone binary when a repo should not need Bun at runtime:
71
+
72
+ ```bash
73
+ bun run build:binary
74
+ bun run smoke:binary
75
+ ```
76
+
77
+ Create a binary install tarball:
78
+
79
+ ```bash
80
+ bun run package:binary
81
+ tar -tzf dist/release/cli-style-*.tar.gz
82
+ ```
83
+
84
+ The package contains `bin/cli-style` and `adapters/`. Install it into a repo-local tools directory, then call that repo-local `bin/cli-style` from scripts.
85
+
71
86
  ## Bash
72
87
 
73
88
  ```bash
74
- source /path/to/node_modules/@lewishowles/cli-style/adapters/bash/cli-style.sh
89
+ source "$(cli-style adapter-path bash)"
75
90
 
76
91
  cli_style_render status --profile diagnostic <<'JSON'
77
92
  {
@@ -95,7 +110,11 @@ JSON
95
110
 
96
111
  ## Python
97
112
 
98
- Add `/path/to/node_modules/@lewishowles/cli-style/adapters/python` to `PYTHONPATH`, then import the helper:
113
+ Add the adapter directory to `PYTHONPATH`, then import the helper:
114
+
115
+ ```bash
116
+ export PYTHONPATH="$(cli-style adapter-path python):$PYTHONPATH"
117
+ ```
99
118
 
100
119
  ```python
101
120
  from cli_style import render
package/bin/cli-style.js CHANGED
@@ -1,20 +1,17 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
3
  import { Buffer } from "node:buffer";
4
-
5
4
  import { createCliStyle, renderGallery, renderHelp } from "../src/index.js";
5
+ import { parseAdapterPathRequest, renderAdapterPath } from "../src/cli/adapter-path-command.js";
6
+ import { parseRenderRequest, renderJsonInput } from "../src/cli/render-command.js";
7
+
6
8
  import {
7
9
  parseGalleryRequest,
8
10
  selectInteractiveGalleryRequest,
9
11
  } from "../src/cli/gallery-command.js";
10
- import {
11
- parseRenderRequest,
12
- renderJsonInput,
13
- } from "../src/cli/render-command.js";
14
12
 
15
13
  // Command-line arguments passed to the package binary.
16
14
  const args = process.argv.slice(2);
17
-
18
15
  // First positional command requested by the caller.
19
16
  const command = args[0];
20
17
 
@@ -38,6 +35,15 @@ function print(value) {
38
35
 
39
36
  if (command === undefined || command === "--help" || command === "-h") {
40
37
  print(renderHelp());
38
+ } else if (command === "adapter-path") {
39
+ try {
40
+ const request = parseAdapterPathRequest(args.slice(1));
41
+
42
+ print(renderAdapterPath(request));
43
+ } catch (error) {
44
+ console.error(error.message);
45
+ process.exitCode = 1;
46
+ }
41
47
  } else if (command === "gallery") {
42
48
  try {
43
49
  const request = parseGalleryRequest(args.slice(1));
package/package.json CHANGED
@@ -1,20 +1,22 @@
1
1
  {
2
2
  "name": "@lewishowles/cli-style",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Shared terminal output styles for Lewis Howles tools, diagnostics, and package CLIs.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/lewishowles/cli-style.git"
8
+ "url": "git+https://github.com/lewishowles/cli-style.git"
9
9
  },
10
10
  "bin": {
11
- "cli-style": "./bin/cli-style.js"
11
+ "cli-style": "bin/cli-style.js"
12
12
  },
13
13
  "files": [
14
14
  "adapters",
15
15
  "bin",
16
16
  "examples",
17
+ "scripts",
17
18
  "src",
19
+ "CHANGELOG.md",
18
20
  "README.md"
19
21
  ],
20
22
  "type": "module",
@@ -23,11 +25,14 @@
23
25
  ".": "./src/index.js"
24
26
  },
25
27
  "publishConfig": {
26
- "registry": "https://npm.pkg.github.com/"
28
+ "access": "public"
27
29
  },
28
30
  "scripts": {
31
+ "build:binary": "scripts/build-binary.sh",
29
32
  "check": "vp check --fix",
30
33
  "cli-style:gallery": "bun ./bin/cli-style.js gallery",
34
+ "package:binary": "scripts/package-binary.sh",
35
+ "smoke:binary": "./dist/bin/cli-style render status --plain < tests/fixtures/render/status-success.json",
31
36
  "test:unit": "bun test"
32
37
  },
33
38
  "devDependencies": {
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ # Builds the standalone cli-style binary and copies wrapper adapters beside it.
3
+ #
4
+ # Release layout:
5
+ # dist/bin/cli-style
6
+ # dist/adapters/bash/cli-style.sh
7
+ # dist/adapters/python/cli_style.py
8
+
9
+ set -euo pipefail
10
+
11
+ mkdir -p dist/bin dist/adapters/bash dist/adapters/python
12
+
13
+ build_args=(--compile ./bin/cli-style.js --outfile ./dist/bin/cli-style)
14
+
15
+ if [ "${BUN_COMPILE_TARGET:-}" != "" ]; then
16
+ build_args+=(--target "$BUN_COMPILE_TARGET")
17
+ fi
18
+
19
+ bun build "${build_args[@]}"
20
+
21
+ cp adapters/bash/cli-style.sh dist/adapters/bash/cli-style.sh
22
+ cp adapters/python/cli_style.py dist/adapters/python/cli_style.py
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+ # Packages the standalone binary layout into a platform tarball.
3
+ #
4
+ # Archive layout:
5
+ # bin/cli-style
6
+ # adapters/bash/cli-style.sh
7
+ # adapters/python/cli_style.py
8
+
9
+ set -euo pipefail
10
+
11
+ platform="${CLI_STYLE_PLATFORM:-$(uname -s | tr '[:upper:]' '[:lower:]')}"
12
+ architecture="${CLI_STYLE_ARCH:-$(uname -m)}"
13
+
14
+ case "$platform" in
15
+ darwin) platform="darwin" ;;
16
+ linux) platform="linux" ;;
17
+ *) printf 'Unsupported platform: %s\n' "$platform" >&2; exit 1 ;;
18
+ esac
19
+
20
+ case "$architecture" in
21
+ arm64|aarch64) architecture="arm64" ;;
22
+ x64|x86_64|amd64) architecture="x64" ;;
23
+ *) printf 'Unsupported architecture: %s\n' "$architecture" >&2; exit 1 ;;
24
+ esac
25
+
26
+ case "$platform-$architecture" in
27
+ darwin-arm64) compile_target="bun-darwin-arm64" ;;
28
+ darwin-x64) compile_target="bun-darwin-x64" ;;
29
+ linux-arm64) compile_target="bun-linux-arm64" ;;
30
+ linux-x64) compile_target="bun-linux-x64" ;;
31
+ *) printf 'Unsupported binary target: %s-%s\n' "$platform" "$architecture" >&2; exit 1 ;;
32
+ esac
33
+
34
+ BUN_COMPILE_TARGET="$compile_target" scripts/build-binary.sh
35
+
36
+ mkdir -p dist/release
37
+
38
+ archive="dist/release/cli-style-${platform}-${architecture}.tar.gz"
39
+
40
+ tar -C dist -czf "$archive" bin adapters
41
+
42
+ printf '%s\n' "$archive"
@@ -0,0 +1,78 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ // Adapter paths returned for shell and Python wrapper setup.
6
+ const adapterPaths = {
7
+ bash: {
8
+ releasePath: "adapters/bash/cli-style.sh",
9
+ sourceUrl: new URL("../../adapters/bash/cli-style.sh", import.meta.url),
10
+ },
11
+ python: {
12
+ releasePath: "adapters/python",
13
+ sourceUrl: new URL("../../adapters/python", import.meta.url),
14
+ },
15
+ };
16
+
17
+ // Adapter names accepted by the adapter-path command.
18
+ export const adapterNames = Object.keys(adapterPaths);
19
+
20
+ /**
21
+ * Parse adapter-path command arguments.
22
+ *
23
+ * @param {string[]} args
24
+ * Arguments after the adapter-path command.
25
+ * @returns {object}
26
+ * Adapter path request.
27
+ */
28
+ export function parseAdapterPathRequest(args = []) {
29
+ const request = {
30
+ adapter: args[0],
31
+ };
32
+
33
+ validateRequest(request, args);
34
+
35
+ return request;
36
+ }
37
+
38
+ /**
39
+ * Render the filesystem path for an adapter.
40
+ *
41
+ * @param {object} request
42
+ * Parsed adapter path request.
43
+ * @returns {string}
44
+ * Adapter file or directory path.
45
+ */
46
+ export function renderAdapterPath(request) {
47
+ const adapterPath = adapterPaths[request.adapter];
48
+ const sourcePath = fileURLToPath(adapterPath.sourceUrl);
49
+
50
+ if (existsSync(sourcePath)) {
51
+ return sourcePath;
52
+ }
53
+
54
+ return join(dirname(process.execPath), "..", adapterPath.releasePath);
55
+ }
56
+
57
+ /**
58
+ * Validate adapter-path request values.
59
+ *
60
+ * @param {object} request
61
+ * Parsed adapter path request.
62
+ * @param {string[]} args
63
+ * Raw command arguments.
64
+ * @returns {void}
65
+ */
66
+ function validateRequest(request, args) {
67
+ if (request.adapter === undefined) {
68
+ throw new Error("Missing adapter");
69
+ }
70
+
71
+ if (!Object.hasOwn(adapterPaths, request.adapter)) {
72
+ throw new Error(`Unknown adapter: ${request.adapter}`);
73
+ }
74
+
75
+ if (args.length > 1) {
76
+ throw new Error(`Unexpected adapter-path argument: ${args[1]}`);
77
+ }
78
+ }
package/src/cli/help.js CHANGED
@@ -4,10 +4,12 @@ const helpLines = [
4
4
  "",
5
5
  "Usage:",
6
6
  " cli-style --help",
7
+ " cli-style adapter-path bash|python",
7
8
  " cli-style gallery [variant] [options]",
8
9
  " cli-style render <renderer> [options] < input.json",
9
10
  "",
10
11
  "Commands:",
12
+ " adapter-path Print a Bash or Python adapter path.",
11
13
  " gallery Print the read-only style gallery.",
12
14
  " render Render caller-provided JSON from stdin.",
13
15
  "",
package/src/index.js CHANGED
@@ -5,6 +5,11 @@ export { resolveTerminalCapabilities } from "./capability/terminal.js";
5
5
  export { isProfile } from "./profiles/profiles.js";
6
6
 
7
7
  export { renderHelp } from "./cli/help.js";
8
+ export {
9
+ adapterNames,
10
+ parseAdapterPathRequest,
11
+ renderAdapterPath,
12
+ } from "./cli/adapter-path-command.js";
8
13
  export {
9
14
  parseRenderRequest,
10
15
  rendererNames,