@rrlab/cli 0.0.1-git-87d22db.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/README.md +110 -0
- package/bin +54 -0
- package/dist/cli.usage.kdl +71 -0
- package/dist/config.d.mts +11 -0
- package/dist/config.mjs +6 -0
- package/dist/plugin.d.mts +52 -0
- package/dist/plugin.mjs +65 -0
- package/dist/run.mjs +1137 -0
- package/dist/types-C3V27_kd.d.mts +173 -0
- package/package.json +74 -0
- package/src/lib/config.ts +5 -0
- package/src/lib/plugin.ts +31 -0
- package/src/plugin/define-plugin.ts +5 -0
- package/src/plugin/registry.ts +47 -0
- package/src/plugin/tool-service.ts +77 -0
- package/src/plugin/types.ts +139 -0
- package/src/program/commands/check.ts +63 -0
- package/src/program/commands/clean.ts +53 -0
- package/src/program/commands/completion.ts +26 -0
- package/src/program/commands/config.ts +15 -0
- package/src/program/commands/doctor.ts +85 -0
- package/src/program/commands/format.ts +35 -0
- package/src/program/commands/jscheck.ts +44 -0
- package/src/program/commands/lint.ts +37 -0
- package/src/program/commands/pack.ts +27 -0
- package/src/program/commands/plugins.ts +359 -0
- package/src/program/commands/tscheck.ts +112 -0
- package/src/program/composed-jsc.ts +35 -0
- package/src/program/index.ts +50 -0
- package/src/program/missing-plugin.ts +18 -0
- package/src/program/ui.ts +59 -0
- package/src/run.ts +11 -0
- package/src/services/config-ast.ts +202 -0
- package/src/services/config.ts +54 -0
- package/src/services/ctx.ts +72 -0
- package/src/services/json-edit.ts +147 -0
- package/src/services/logger.ts +5 -0
- package/src/services/plugins-registry.ts +21 -0
- package/src/services/prompts.ts +26 -0
- package/src/services/workspace-target.ts +27 -0
- package/src/types/config.ts +13 -0
- package/src/types/tool.ts +57 -0
- package/tsconfig.json +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# 🦊 run-run
|
|
2
|
+
|
|
3
|
+
CLI toolbox to fullstack common scripts in [Variable Land](https://variable.land)
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js >= 20.0.0
|
|
8
|
+
|
|
9
|
+
## Toolbox
|
|
10
|
+
|
|
11
|
+
- [biome](https://biomejs.dev)
|
|
12
|
+
- [tsc](https://www.typescriptlang.org)
|
|
13
|
+
- [rimraf](https://www.npmjs.com/package/rimraf)
|
|
14
|
+
- [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html)
|
|
15
|
+
- [oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
|
16
|
+
- [tsdown](https://tsdown.dev)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
pnpm add -D @rrlab/cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
It adds the `rr` command to your project.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Run the help command:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
pnpm rr help
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> If you have `node_modules/.bin` on your `PATH` (e.g. via `mise` or `direnv` — see [Shell completion](#shell-completion)), you can drop the `pnpm` prefix and invoke `rr` directly.
|
|
35
|
+
|
|
36
|
+
See [`CLI.md`](./CLI.md) for the full reference (auto-generated per release).
|
|
37
|
+
|
|
38
|
+
## Shell completion
|
|
39
|
+
|
|
40
|
+
`rr` ships a `completion` subcommand that prints a shell-specific script.
|
|
41
|
+
Pick the option that matches your setup.
|
|
42
|
+
|
|
43
|
+
### Option A — with `mise` or `direnv` (recommended)
|
|
44
|
+
|
|
45
|
+
If your tooling puts `node_modules/.bin` on `PATH` per-project, `rr` resolves at shell startup and completion picks up new commands automatically on each new shell. Examples:
|
|
46
|
+
|
|
47
|
+
```toml
|
|
48
|
+
# mise.toml
|
|
49
|
+
[env]
|
|
50
|
+
_.path = ["{{config_root}}/node_modules/.bin"]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
# .envrc (direnv)
|
|
55
|
+
PATH_add node_modules/.bin
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Then add a guarded eval to your shell rc — the guard makes it a no-op when you open a shell outside any project:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
# zsh — ~/.zshrc
|
|
62
|
+
command -v rr >/dev/null 2>&1 && eval "$(rr completion zsh)"
|
|
63
|
+
|
|
64
|
+
# bash — ~/.bashrc
|
|
65
|
+
command -v rr >/dev/null 2>&1 && eval "$(rr completion bash)"
|
|
66
|
+
|
|
67
|
+
# fish — ~/.config/fish/config.fish
|
|
68
|
+
command -v rr >/dev/null 2>&1; and rr completion fish | source
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Option B — without a per-project PATH manager
|
|
72
|
+
|
|
73
|
+
Cache the completion script once, then source the cached file from your shell rc. Run the generation step from inside a project that has `@rrlab/cli` installed:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
mkdir -p ~/.cache
|
|
77
|
+
pnpm exec rr completion zsh > ~/.cache/rr-completion.zsh
|
|
78
|
+
pnpm exec rr completion bash > ~/.cache/rr-completion.bash
|
|
79
|
+
pnpm exec rr completion fish > ~/.cache/rr-completion.fish
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
# zsh — ~/.zshrc
|
|
84
|
+
[ -f ~/.cache/rr-completion.zsh ] && source ~/.cache/rr-completion.zsh
|
|
85
|
+
|
|
86
|
+
# bash — ~/.bashrc
|
|
87
|
+
[ -f ~/.cache/rr-completion.bash ] && source ~/.cache/rr-completion.bash
|
|
88
|
+
|
|
89
|
+
# fish — ~/.config/fish/config.fish
|
|
90
|
+
test -f ~/.cache/rr-completion.fish; and source ~/.cache/rr-completion.fish
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Regenerate the cache after upgrading `@rrlab/cli` to pick up new commands.
|
|
94
|
+
|
|
95
|
+
### Prerequisite
|
|
96
|
+
|
|
97
|
+
The [`usage`](https://usage.jdx.dev) CLI must be on your `PATH` (it powers completion at runtime). Install via one of:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
mise use -g usage
|
|
101
|
+
brew install usage
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Troubleshooting
|
|
105
|
+
|
|
106
|
+
To enable debug mode, set the `DEBUG` environment variable to `run-run:*` before running *any* command.
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
DEBUG=run-run:* pnpm rr <command>
|
|
110
|
+
```
|
package/bin
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
SOURCE="${BASH_SOURCE[0]}"
|
|
5
|
+
while [ -L "$SOURCE" ]; do
|
|
6
|
+
TARGET="$(readlink "$SOURCE")"
|
|
7
|
+
case "$TARGET" in
|
|
8
|
+
/*) SOURCE="$TARGET" ;;
|
|
9
|
+
*) SOURCE="$(dirname "$SOURCE")/$TARGET" ;;
|
|
10
|
+
esac
|
|
11
|
+
done
|
|
12
|
+
DIR="$(cd "$(dirname "$SOURCE")" && pwd)"
|
|
13
|
+
|
|
14
|
+
if [ "$1" = "completion" ]; then
|
|
15
|
+
case "$2" in
|
|
16
|
+
bash | zsh | fish)
|
|
17
|
+
kdl="$DIR/dist/cli.usage.kdl"
|
|
18
|
+
if [ ! -f "$kdl" ]; then
|
|
19
|
+
echo "rr completion: missing $kdl. Reinstall @rrlab/cli or run \`pnpm build\`." >&2
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
if ! command -v usage >/dev/null 2>&1; then
|
|
23
|
+
echo "rr completion: 'usage' CLI not found in PATH." >&2
|
|
24
|
+
echo "Install via: mise use -g usage | brew install usage" >&2
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
exec usage generate completion "$2" rr --file "$kdl"
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
# Unknown shell or `--help`: fall through to Node so Commander prints help/errors.
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# `--usage` emits a KDL spec for downstream parsers (e.g. `usage generate
|
|
34
|
+
# completion`). Force NO_COLOR so command summaries don't leak ANSI escapes
|
|
35
|
+
# into the spec — colors are presentation, KDL is data. Also set
|
|
36
|
+
# RR_USAGE_MODE so per-environment annotations (e.g. the active plugin
|
|
37
|
+
# next to each command) are stripped from the spec — the KDL must be
|
|
38
|
+
# stable across machines.
|
|
39
|
+
for arg in "$@"; do
|
|
40
|
+
if [ "$arg" = "--usage" ]; then
|
|
41
|
+
export NO_COLOR=1
|
|
42
|
+
export RR_USAGE_MODE=1
|
|
43
|
+
break
|
|
44
|
+
fi
|
|
45
|
+
done
|
|
46
|
+
|
|
47
|
+
# In the source repo (tsdown.config.ts present, NOT shipped in the npm tarball),
|
|
48
|
+
# always run from src/ so live edits show up. In a published install, use the
|
|
49
|
+
# bundled dist/run.mjs.
|
|
50
|
+
if [ -f "$DIR/tsdown.config.ts" ]; then
|
|
51
|
+
exec node "$DIR/src/run.ts" "$@"
|
|
52
|
+
else
|
|
53
|
+
exec node "$DIR/dist/run.mjs" "$@"
|
|
54
|
+
fi
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// @generated by @usage-spec/commander from Commander.js metadata
|
|
2
|
+
name rr
|
|
3
|
+
bin rr
|
|
4
|
+
version "0.0.1-git-87d22db.0"
|
|
5
|
+
usage "<command...> [options...]"
|
|
6
|
+
flag --usage help="print KDL spec for this CLI (https://kdl.dev)"
|
|
7
|
+
cmd completion help="print shell completion script (usage)" {
|
|
8
|
+
long_help "Prints a shell completion script for rr. Add to your shell rc file:\n\n bash: eval \"$(rr completion bash)\"\n zsh: eval \"$(rr completion zsh)\"\n fish: rr completion fish | source"
|
|
9
|
+
arg <shell> help="target shell" {
|
|
10
|
+
choices bash zsh fish
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
cmd pack help="pack a ts library" {
|
|
14
|
+
long_help "Compiles TypeScript code into JavaScript and generates type declaration files, packaging the library for distribution."
|
|
15
|
+
cmd doctor help="check if the underlying tool is working correctly"
|
|
16
|
+
}
|
|
17
|
+
cmd jsc help="check format and lint" {
|
|
18
|
+
alias jscheck
|
|
19
|
+
long_help "Checks the code for formatting and linting issues, ensuring it adheres to the defined style and quality standards."
|
|
20
|
+
flag --fix help="try to fix issues automatically"
|
|
21
|
+
flag --fix-staged help="try to fix staged files only"
|
|
22
|
+
cmd doctor help="check if the underlying tool is working correctly"
|
|
23
|
+
}
|
|
24
|
+
cmd tsc help="check typescript errors" {
|
|
25
|
+
alias tscheck
|
|
26
|
+
long_help "Checks the TypeScript code for type errors, ensuring that the code adheres to the defined type constraints and helps catch potential issues before runtime."
|
|
27
|
+
cmd doctor help="check if the underlying tool is working correctly"
|
|
28
|
+
}
|
|
29
|
+
cmd lint help="check & fix lint errors" {
|
|
30
|
+
long_help "Checks the code for linting issues and optionally fixes them, ensuring it adheres to the defined quality standards."
|
|
31
|
+
flag "-c --check" help="check if the code is valid" default=#true
|
|
32
|
+
flag --fix help="try to fix all the code"
|
|
33
|
+
cmd doctor help="check if the underlying tool is working correctly"
|
|
34
|
+
}
|
|
35
|
+
cmd format help="check & fix format errors" {
|
|
36
|
+
long_help "Checks the code for formatting issues and optionally fixes them, ensuring it adheres to the defined style standards."
|
|
37
|
+
flag --fix help="format all the code"
|
|
38
|
+
cmd doctor help="check if the underlying tool is working correctly"
|
|
39
|
+
}
|
|
40
|
+
cmd check help="run static checks (run-run)" {
|
|
41
|
+
long_help "Runs `rr jsc` and `rr tsc` concurrently in-process. Aggregates their exit codes — non-zero when either subcommand fails."
|
|
42
|
+
}
|
|
43
|
+
cmd doctor help="run all plugin doctors" {
|
|
44
|
+
long_help "Runs the `doctor()` of every configured plugin capability. Each plugin reports ok / not working. The exit code is non-zero if any reports not working."
|
|
45
|
+
}
|
|
46
|
+
cmd plugins subcommand_required=#true help="manage @rrlab plugins" {
|
|
47
|
+
cmd list help="list plugins configured in run-run.config.{ts,mts}"
|
|
48
|
+
cmd add help="install and configure an @rrlab plugin" {
|
|
49
|
+
flag --force help="re-run install even if the plugin is already configured"
|
|
50
|
+
flag --yes help="skip prompts and use defaults (non-interactive)"
|
|
51
|
+
flag --dry-run help="show what would happen, without applying changes"
|
|
52
|
+
arg <name> help="plugin alias" {
|
|
53
|
+
choices ts eslint biome oxc tsdown
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
cmd remove help="uninstall an @rrlab plugin and undo its config files + deps" {
|
|
57
|
+
flag --yes help="skip the confirmation prompt"
|
|
58
|
+
flag --dry-run help="print the plan without applying changes"
|
|
59
|
+
arg <name> help="plugin alias to remove" {
|
|
60
|
+
choices ts eslint biome oxc tsdown
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
cmd clean help="delete dirty files (rimraf)" {
|
|
65
|
+
long_help "Deletes generated files and folders such as 'dist', 'node_modules', and lock files to ensure a clean state."
|
|
66
|
+
flag --only-dist help="delete 'dist' folders only"
|
|
67
|
+
flag --dry-run help="outputs the paths that would be deleted"
|
|
68
|
+
}
|
|
69
|
+
cmd config help="display the current config" {
|
|
70
|
+
long_help "Displays the current configuration settings, including their source file path if available."
|
|
71
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { u as Plugin } from "./types-C3V27_kd.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/types/config.d.ts
|
|
4
|
+
type UserConfig = {
|
|
5
|
+
plugins?: Plugin[];
|
|
6
|
+
};
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/lib/config.d.ts
|
|
9
|
+
declare function defineConfig(config: UserConfig): UserConfig;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { defineConfig };
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { C as Linter, D as TypeChecker, E as TypeCheckOptions, S as LintOptions, T as StaticCheckerOptions, _ as Doctor, a as InstallFlags, b as FormatOptions, c as PLUGIN_KINDS, d as PluginCapabilities, f as PluginContext, g as UninstallResult, h as UninstallFlags, i as InstallContext, l as Packer, m as UninstallContext, n as ClackPromptsSelectOption, o as InstallResult, p as PluginKind, r as FileOp, s as JsonEdit, t as ClackPrompts, u as Plugin, v as DoctorOutput, w as StaticChecker, x as Formatter, y as DoctorResult } from "./types-C3V27_kd.mjs";
|
|
2
|
+
import { ShellService } from "@vlandoss/clibuddy";
|
|
3
|
+
|
|
4
|
+
//#region src/plugin/define-plugin.d.ts
|
|
5
|
+
declare function definePlugin<T = void>(factory: (options: T) => Plugin): (options: T) => Plugin;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region ../../node_modules/.pnpm/tinyexec@1.1.2/node_modules/tinyexec/dist/main.d.mts
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/main.d.ts
|
|
10
|
+
interface Output {
|
|
11
|
+
stderr: string;
|
|
12
|
+
stdout: string;
|
|
13
|
+
exitCode: number | undefined;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/plugin/tool-service.d.ts
|
|
17
|
+
type ToolServiceOptions = {
|
|
18
|
+
pkg: string;
|
|
19
|
+
bin?: string;
|
|
20
|
+
ui: string;
|
|
21
|
+
shellService: ShellService;
|
|
22
|
+
/**
|
|
23
|
+
* Module URL the resolver walks up from when looking for `pkg` in
|
|
24
|
+
* `node_modules`. Plugins MUST pass their own `import.meta.url` so the
|
|
25
|
+
* binary is resolved from the plugin's own dependency graph (peer-installed
|
|
26
|
+
* by the host project), not the kernel's. Kernel-internal services pass
|
|
27
|
+
* `import.meta.url` of their own module file.
|
|
28
|
+
*/
|
|
29
|
+
from: string;
|
|
30
|
+
};
|
|
31
|
+
type ExecOptions = {
|
|
32
|
+
cwd?: string;
|
|
33
|
+
verbose?: boolean;
|
|
34
|
+
};
|
|
35
|
+
declare class ToolService {
|
|
36
|
+
#private;
|
|
37
|
+
get bin(): string;
|
|
38
|
+
get ui(): string;
|
|
39
|
+
get pkg(): string;
|
|
40
|
+
constructor({
|
|
41
|
+
pkg,
|
|
42
|
+
bin,
|
|
43
|
+
ui,
|
|
44
|
+
shellService,
|
|
45
|
+
from
|
|
46
|
+
}: ToolServiceOptions);
|
|
47
|
+
getBinDir(): Promise<string>;
|
|
48
|
+
exec(args?: string[], options?: ExecOptions): Promise<Output>;
|
|
49
|
+
doctor(): Promise<DoctorResult>;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { type ClackPrompts, type ClackPromptsSelectOption, type Doctor, type DoctorOutput, type DoctorResult, type FileOp, type FormatOptions, type Formatter, type InstallContext, type InstallFlags, type InstallResult, type JsonEdit, type LintOptions, type Linter, PLUGIN_KINDS, type Packer, type Plugin, type PluginCapabilities, type PluginContext, type PluginKind, type StaticChecker, type StaticCheckerOptions, ToolService, type ToolServiceOptions, type TypeCheckOptions, type TypeChecker, type UninstallContext, type UninstallFlags, type UninstallResult, definePlugin };
|
package/dist/plugin.mjs
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { resolvePackageBin } from "@vlandoss/clibuddy";
|
|
2
|
+
//#region src/plugin/define-plugin.ts
|
|
3
|
+
function definePlugin(factory) {
|
|
4
|
+
return factory;
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/plugin/tool-service.ts
|
|
8
|
+
var ToolService = class {
|
|
9
|
+
#shellService;
|
|
10
|
+
#pkg;
|
|
11
|
+
#bin;
|
|
12
|
+
#ui;
|
|
13
|
+
#from;
|
|
14
|
+
get bin() {
|
|
15
|
+
return this.#bin;
|
|
16
|
+
}
|
|
17
|
+
get ui() {
|
|
18
|
+
return this.#ui;
|
|
19
|
+
}
|
|
20
|
+
get pkg() {
|
|
21
|
+
return this.#pkg;
|
|
22
|
+
}
|
|
23
|
+
constructor({ pkg, bin, ui, shellService, from }) {
|
|
24
|
+
this.#pkg = pkg;
|
|
25
|
+
this.#bin = bin ?? pkg;
|
|
26
|
+
this.#ui = ui;
|
|
27
|
+
this.#shellService = shellService;
|
|
28
|
+
this.#from = from;
|
|
29
|
+
}
|
|
30
|
+
async getBinDir() {
|
|
31
|
+
return resolvePackageBin(this.#pkg, {
|
|
32
|
+
from: this.#from,
|
|
33
|
+
binName: this.#bin
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async exec(args = [], options = {}) {
|
|
37
|
+
const { cwd, verbose } = options;
|
|
38
|
+
return (cwd ? this.#shellService.at(cwd) : this.#shellService).run(await this.getBinDir(), args, {
|
|
39
|
+
display: this.#bin,
|
|
40
|
+
verbose
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async doctor() {
|
|
44
|
+
const output = await this.#shellService.runCaptured(await this.getBinDir(), ["--help"], { throwOnError: false });
|
|
45
|
+
return {
|
|
46
|
+
ok: output.exitCode === 0,
|
|
47
|
+
output: {
|
|
48
|
+
stdout: output.stdout,
|
|
49
|
+
stderr: output.stderr,
|
|
50
|
+
exitCode: output.exitCode
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/plugin/types.ts
|
|
57
|
+
const PLUGIN_KINDS = [
|
|
58
|
+
"lint",
|
|
59
|
+
"format",
|
|
60
|
+
"jsc",
|
|
61
|
+
"tsc",
|
|
62
|
+
"pack"
|
|
63
|
+
];
|
|
64
|
+
//#endregion
|
|
65
|
+
export { PLUGIN_KINDS, ToolService, definePlugin };
|