@kaynooo/cli-kit 0.14.0 → 0.15.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 CHANGED
@@ -6,7 +6,7 @@ What every @kaynooo CLI shares, so each one parses, helps and fails the same way
6
6
  bun add @kaynooo/cli-kit
7
7
  ```
8
8
 
9
- It ships its TypeScript source and runs on Bun only (>= 1.4.3). The agent-tools CLIs take it as a `workspace:*` dev dependency and bundle it at build; a CLI elsewhere takes it from npmjs as a dependency (`bun add --exact @kaynooo/cli-kit`).
9
+ It ships its TypeScript source and runs on Bun only (>= 1.4.3). The @kaynooo/cli-* packages take it as a `workspace:*` dev dependency and bundle it at build; a CLI elsewhere takes it from npmjs as a dependency (`bun add --exact @kaynooo/cli-kit`).
10
10
 
11
11
  ```ts
12
12
  import { parse, runCli } from '@kaynooo/cli-kit'
@@ -47,11 +47,11 @@ On a terminal, help has bold `Usage:`, `Commands:` and `Options:` headers, comma
47
47
  - `isStdinPiped()` is true when stdin is a pipe or a file, false on a terminal or `/dev/null`, so a command can read what is piped in without waiting on a terminal.
48
48
  - `runCommand(argv, { cwd, env, stdin, timeoutMs, signal, maxBytes, onChunk, onStart })` runs a command and returns `{ code, text, output, chunks, timedOut, truncated }`, the output of both streams (in arrival order, tagged by stream in `chunks`); it throws when the command cannot start. With `timeoutMs`, `signal`, `onChunk` or `onStart` the child leads its own process group, ended whole (SIGTERM, SIGKILL after 2 s) when the timeout passes, the signal aborts or `onChunk` throws, the pipes still read to the end: `timedOut` is then true, for the caller to exit 2. `maxBytes` caps what `chunks`, `output` and `text` keep (`truncated`), `onChunk` sees every chunk, and `onStart` hands over `{ kill }` for the whole group, to pass to `holdSignals().forward`. `exitCodeOf(code, signal)` is the exit code a shell reports.
49
49
  - `holdSignals(cleanup?)` takes SIGINT, SIGTERM and SIGHUP over until `release()`: a signal goes to the child given to `forward(child)`, so the CLI exits with the child's code; without one, `cleanup(signal)` runs and the signal is raised again, ending the process as it would have; without either, it is only kept in `signal`, for the caller to wind down (`base` holds them while its worktree exists).
50
- - `privateLogDirectory(name)` returns a folder for log files only this user reads (`$XDG_RUNTIME_DIR` or `~/.cache/agent-tools`, mode 0700, verified with `lstat` when it exists, else a fresh temp folder), `createLog(path)` opens a 0600 file that must not exist (returning its descriptor), and `sweepLogs(dir, maxAgeMs?)` removes what is older than a day, subfolders included.
50
+ - `privateLogDirectory(name)` returns a folder for log files only this user reads (`$XDG_RUNTIME_DIR` or `~/.cache/kaynooo-cli`, mode 0700, verified with `lstat` when it exists, else a fresh temp folder), `createLog(path)` opens a 0600 file that must not exist (returning its descriptor), and `sweepLogs(dir, maxAgeMs?)` removes what is older than a day, subfolders included.
51
51
  - `openUrl(target, env?)` opens a URL, or a file path made absolute, with the command `BROWSER` names or the platform's opener (`xdg-open`, `open`, `start`), without waiting; it returns `false` when that command cannot start.
52
52
  - Every command's `parse`, and `runCli` before the command name (`ft --plain runs`), takes `--color auto|always|never` and `--plain` (`--color never`), unless the command has its own option of that name. `always` sets `FORCE_COLOR=1` and `never` sets `NO_COLOR=1`, each dropping the other, so the kit's colours, marks and redrawn lines follow, and so do the processes the command starts; `always` colours a pipe but never redraws in one. `applyOutput(color, plain, env?)` is what they run.
53
53
  - `--help` lists the commands under `Commands:`, then a heading per `group` a command names (`{ summary, group: 'Admin', run }`), then the level's `Options:` and the `Examples:` the CLI or a group's `examples` give (`['ft ci', ['ft ci HEAD~1', 'the commit before']]`, a note shown dimmed after `#`); a command's own examples go to `parse(args, usage, options, { examples })`, shown under its options.
54
- - `replaces` on the CLI or in `parse`'s settings (`'sed -n N,Mp, grep -n chains'`) adds an `Instead of:` line under the usage. With `KIT_HELP=json` in the environment, `--help` prints `{synopsis, summary, replaces?, examples}` instead, the usage's first line split at its first `: `, which is how `agent-tools list` reads every bin.
54
+ - `replaces` on the CLI or in `parse`'s settings (`'sed -n N,Mp, grep -n chains'`) adds an `Instead of:` line under the usage. With `KIT_HELP=json` in the environment, `--help` prints `{synopsis, summary, replaces?, examples}` instead, the usage's first line split at its first `: `, which is how `cli list` reads every bin.
55
55
  - `runHint(command, effect?)` words the hint of a refusal that a command resolves, ``run `ft take 12 --take-stale` to take it over``, so every CLI writes it alike: `fail(message, 1, runHint('ft take 12 --take-stale', 'take it over'))`. `printHint(hint)` prints the `hint:` line under a refusal a command prints itself (one issue of several refused).
56
56
  - `limitOptions(fallback)` is the `--limit <n>` and `--full` flags of a listing, `limitOf(values, fallback)` the row count they ask for (Infinity with `--full`; with `json: true` in the values, Infinity unless `--limit` is given, so JSON is never cut on its own), and `capped(rows, limit)` the first rows plus the footer `N more, rerun with --full` when some are left out.
57
57
  - `jsonOption(holds?)` is the `--json` flag, worded `print JSON` or `print JSON: <holds>` alike in every CLI, and `printJson(value)` prints the value indented on stdout, bare, with no envelope. Under `--json` runMain and runCli print a thrown error as `{"error", "hint"?, "cause"?}` on stderr instead of the `error:` line, its exit code unchanged; `printJsonError(message, hint?, cause?)` prints one for a command reporting a failure itself.
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@kaynooo/cli-kit",
3
3
  "type": "module",
4
- "version": "0.14.0",
4
+ "version": "0.15.0",
5
5
  "description": "What every @kaynooo CLI shares: argument parsing with --help, a command dispatcher with typo hints and shell completion, and output formatting.",
6
6
  "author": "Kaynooo <contact@kaynooo.fr>",
7
7
  "license": "MIT",
8
- "homepage": "https://git.kaynooo.fr/kaynooo/agent-tools/src/branch/main/packages/kit#readme",
8
+ "homepage": "https://git.kaynooo.fr/kaynooo/cli/src/branch/main/packages/kit#readme",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://git.kaynooo.fr/kaynooo/agent-tools.git",
11
+ "url": "git+https://git.kaynooo.fr/kaynooo/cli.git",
12
12
  "directory": "packages/kit"
13
13
  },
14
- "bugs": "https://git.kaynooo.fr/kaynooo/agent-tools/issues",
14
+ "bugs": "https://git.kaynooo.fr/kaynooo/cli/issues",
15
15
  "keywords": [
16
16
  "args",
17
17
  "bun",
package/src/args.ts CHANGED
@@ -69,7 +69,7 @@ export function replacesRows(replaces: string | undefined, colors = paint(proces
69
69
  return replaces === undefined ? [] : ['', `${colors.bold('Instead of:')} ${replaces}`]
70
70
  }
71
71
 
72
- // What a bin's --help prints under KIT_HELP=json, for `agent-tools list` to read without parsing the text.
72
+ // What a bin's --help prints under KIT_HELP=json, for `cli list` to read without parsing the text.
73
73
  export interface Description {
74
74
  synopsis: string
75
75
  summary: string
@@ -132,7 +132,7 @@ export interface ParseSettings<Names extends readonly string[] = string[]> {
132
132
  positionals?: Names
133
133
  // Command lines shown under `Examples:` in the help, each with an optional dimmed note: `['ft ci HEAD~1', 'wait for the commit before the last']`.
134
134
  examples?: Example[]
135
- // What the command is reached for instead of, shown as `Instead of:` in the help and listed by `agent-tools list`: 'sed -n N,Mp, grep -n chains and whole-file reads'.
135
+ // What the command is reached for instead of, shown as `Instead of:` in the help and listed by `cli list`: 'sed -n N,Mp, grep -n chains and whole-file reads'.
136
136
  replaces?: string
137
137
  }
138
138
 
package/src/logs.ts CHANGED
@@ -6,6 +6,9 @@ import process from 'node:process'
6
6
 
7
7
  const DAY_MS = 24 * 60 * 60 * 1000
8
8
 
9
+ // The folder the @kaynooo/cli-* bins keep their logs and state in, under the runtime, cache or state directory.
10
+ export const CLI_FOLDER = 'kaynooo-cli'
11
+
9
12
  // Whether the folder is a real directory (not a link) that only this user can use.
10
13
  function isPrivateDirectory(path: string): boolean {
11
14
  try {
@@ -18,10 +21,10 @@ function isPrivateDirectory(path: string): boolean {
18
21
  }
19
22
  }
20
23
 
21
- // A folder for log files that only this user can read: `<name>` under $XDG_RUNTIME_DIR, else ~/.cache/agent-tools. When one already exists it must be a private directory of this user, otherwise a fresh private folder in the temp directory is used instead of trusting it.
24
+ // A folder for log files that only this user can read: `<name>` under $XDG_RUNTIME_DIR, else ~/.cache/kaynooo-cli. When one already exists it must be a private directory of this user, otherwise a fresh private folder in the temp directory is used instead of trusting it.
22
25
  export async function privateLogDirectory(name: string, env: Record<string, string | undefined> = process.env): Promise<string> {
23
26
  const runtime = env.XDG_RUNTIME_DIR
24
- const base = runtime === undefined || runtime === '' ? join(homedir(), '.cache', 'agent-tools') : join(runtime, 'agent-tools')
27
+ const base = runtime === undefined || runtime === '' ? join(homedir(), '.cache', CLI_FOLDER) : join(runtime, CLI_FOLDER)
25
28
  const path = join(base, name)
26
29
 
27
30
  try {