@willh/copilotstatusline 0.1.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/LICENSE +21 -0
- package/NOTICE +8 -0
- package/README.md +109 -0
- package/dist/copilotstatusline.js +53877 -0
- package/docs/DEVELOPMENT.md +79 -0
- package/docs/USAGE.md +135 -0
- package/docs/WINDOWS.md +54 -0
- package/package.json +81 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
bun install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The project is written in TypeScript. Bun runs source files and tests; the published bundle targets Node.js 22 or newer.
|
|
10
|
+
|
|
11
|
+
## Verification
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
bun run lint
|
|
15
|
+
bun test
|
|
16
|
+
bun run build
|
|
17
|
+
bun run example
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`bun run lint` runs TypeScript checking before ESLint. The lint configuration is intentionally strict. Fix the implementation instead of suppressing a rule.
|
|
21
|
+
|
|
22
|
+
## Architecture
|
|
23
|
+
|
|
24
|
+
The external Copilot payload is parsed into `NormalizedCopilotStatus` before rendering. This boundary prevents payload aliases and nullable fields from spreading through widget logic.
|
|
25
|
+
|
|
26
|
+
Formatter settings and Copilot CLI settings are separate:
|
|
27
|
+
|
|
28
|
+
- formatter settings control lines, widgets, colors, Powerline, and local command behavior;
|
|
29
|
+
- Copilot settings control whether and how Copilot invokes the formatter.
|
|
30
|
+
|
|
31
|
+
Both settings writers use a temporary file and atomic rename. Copilot settings also receive timestamped backups because the file belongs to another application.
|
|
32
|
+
|
|
33
|
+
## Adding a payload field
|
|
34
|
+
|
|
35
|
+
1. Add the known optional field to `CopilotStatusSchema`.
|
|
36
|
+
2. Normalize it in `normalizeCopilotStatus`.
|
|
37
|
+
3. Add a widget type and catalog entry only if the value is useful independently.
|
|
38
|
+
4. Render absence as `null` instead of a fabricated fallback.
|
|
39
|
+
5. Add payload and rendering tests.
|
|
40
|
+
|
|
41
|
+
Keep the top-level and nested schemas loose so future Copilot fields do not break existing installations.
|
|
42
|
+
|
|
43
|
+
## Adding a widget
|
|
44
|
+
|
|
45
|
+
1. Add its type to `WIDGET_TYPES` in `src/types/Settings.ts`.
|
|
46
|
+
2. Add metadata to `WIDGET_CATALOG` in `src/widgets/catalog.ts`.
|
|
47
|
+
3. Add rendering behavior to `renderWidget`.
|
|
48
|
+
4. Add a focused renderer or widget test.
|
|
49
|
+
|
|
50
|
+
Subprocess widgets must suppress stderr, use a short timeout, work with an absent command, and avoid filesystem mutations. Git and Jujutsu values should go through the existing TTL cache.
|
|
51
|
+
|
|
52
|
+
## Integration testing
|
|
53
|
+
|
|
54
|
+
Use a temporary Copilot home so local user settings are never touched:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
temporary_home="$(mktemp -d)"
|
|
58
|
+
COPILOT_HOME="$temporary_home" bun run src/copilotstatusline.ts --install global
|
|
59
|
+
COPILOT_HOME="$temporary_home" bun run src/copilotstatusline.ts --check
|
|
60
|
+
COPILOT_HOME="$temporary_home" bun run src/copilotstatusline.ts --uninstall
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
For custom formatter settings:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
temporary_config="$(mktemp)"
|
|
67
|
+
rm "$temporary_config"
|
|
68
|
+
COPILOT_HOME="$temporary_home" bun run src/copilotstatusline.ts \
|
|
69
|
+
--config "$temporary_config" --install global
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Build
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
bun run build
|
|
76
|
+
node dist/copilotstatusline.js --version
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The postbuild script replaces the `__PACKAGE_VERSION__` placeholder from `package.json`. The bundle must remain executable as the npm `copilotstatusline` binary.
|
package/docs/USAGE.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Usage
|
|
2
|
+
|
|
3
|
+
## Runtime model
|
|
4
|
+
|
|
5
|
+
GitHub Copilot CLI executes the configured shell command and sends a JSON object on stdin. `copilotstatusline` validates the known fields, normalizes aliases, loads formatter settings, and writes rendered lines to stdout.
|
|
6
|
+
|
|
7
|
+
Unknown payload fields are accepted for forward compatibility. Missing optional fields hide the corresponding widgets. Invalid known field types fail the invocation with a concise stderr message and a nonzero exit code.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Interactive installation:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npx -y copilotstatusline@latest
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Non-interactive installation:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npx -y copilotstatusline@latest --install npm
|
|
21
|
+
bunx -y copilotstatusline@latest --install bunx
|
|
22
|
+
copilotstatusline --install global
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The accepted install modes are `npm`, `bunx`, and `global`. Installation writes only to `$COPILOT_HOME/settings.json`, with `~/.copilot/settings.json` as the fallback. Existing files are backed up as `settings.json.bak.<timestamp>` before replacement.
|
|
26
|
+
|
|
27
|
+
The installer:
|
|
28
|
+
|
|
29
|
+
- preserves unrelated root and footer keys;
|
|
30
|
+
- sets `statusLine.type` to `command`;
|
|
31
|
+
- sets status-line padding to zero;
|
|
32
|
+
- enables `footer.showCustom`;
|
|
33
|
+
- refuses an installed Copilot CLI version older than 1.0.52.
|
|
34
|
+
|
|
35
|
+
If the `copilot` executable cannot be resolved, installation still writes the configuration. This supports configuring an environment before Copilot CLI is added to `PATH`.
|
|
36
|
+
|
|
37
|
+
## Uninstallation safety
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
copilotstatusline --uninstall
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Uninstallation removes `statusLine` only when its command is recognized as belonging to `copilotstatusline`. A different custom status-line command is left untouched.
|
|
44
|
+
|
|
45
|
+
## Formatter settings
|
|
46
|
+
|
|
47
|
+
Default path:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
~/.config/copilotstatusline/settings.json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`XDG_CONFIG_HOME` changes the Unix root. `%APPDATA%` is used on Windows. A custom path can be selected with:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
copilotstatusline --config /absolute/path/settings.json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Combine the flag with installation so Copilot always invokes the same file:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
copilotstatusline --config /absolute/path/settings.json --install global
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The settings schema is versioned independently of Copilot settings:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"version": 1,
|
|
70
|
+
"lines": [
|
|
71
|
+
[
|
|
72
|
+
{
|
|
73
|
+
"id": "model",
|
|
74
|
+
"type": "model",
|
|
75
|
+
"color": "cyan",
|
|
76
|
+
"backgroundColor": "none",
|
|
77
|
+
"bold": false,
|
|
78
|
+
"raw": false,
|
|
79
|
+
"prefix": "",
|
|
80
|
+
"suffix": "",
|
|
81
|
+
"merge": false,
|
|
82
|
+
"hideWhenZero": false
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
],
|
|
86
|
+
"defaultSeparator": " · ",
|
|
87
|
+
"colorLevel": 2,
|
|
88
|
+
"powerline": {
|
|
89
|
+
"enabled": false,
|
|
90
|
+
"separator": ""
|
|
91
|
+
},
|
|
92
|
+
"gitCacheTtlSeconds": 5
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`colorLevel` accepts zero through three. Zero disables ANSI styling. The current renderer uses ANSI 16-color names; values above zero enable them.
|
|
97
|
+
|
|
98
|
+
## Widget configuration
|
|
99
|
+
|
|
100
|
+
Every widget has an `id`, `type`, foreground and background colors, bold and raw-value flags, prefix and suffix text, merge behavior, and an optional zero-hiding flag.
|
|
101
|
+
|
|
102
|
+
Additional widget fields:
|
|
103
|
+
|
|
104
|
+
- `custom-text`: set `value`.
|
|
105
|
+
- `custom-command`: set `command`.
|
|
106
|
+
- `separator`: set `value`.
|
|
107
|
+
- `flex`: no additional value; it consumes remaining terminal width.
|
|
108
|
+
|
|
109
|
+
Custom commands execute through the local shell with a 500 ms timeout. Only the first output line is rendered. Store only trusted commands in the settings file.
|
|
110
|
+
|
|
111
|
+
## Payload fields
|
|
112
|
+
|
|
113
|
+
The normalized widgets currently use:
|
|
114
|
+
|
|
115
|
+
- session: `session_id`, `session_name`, `cwd`, `workspace`, and `version`;
|
|
116
|
+
- model: string or object `model`, `modelName`, `current_model`, `reasoning_effort`, and `effort.level`;
|
|
117
|
+
- context: cumulative input, output, cache read/write, reasoning and total tokens, last-call tokens, current context, displayed limit, and used percentage;
|
|
118
|
+
- cost: API duration, total duration, premium requests, and added/removed lines;
|
|
119
|
+
- permission state: `allow_all`.
|
|
120
|
+
|
|
121
|
+
## Diagnostics
|
|
122
|
+
|
|
123
|
+
Inspect integration status:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
copilotstatusline --check
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Test rendering without changing Copilot settings:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
bun run example
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Warnings about malformed formatter settings go to stderr. Status-line content remains on stdout so Copilot does not receive diagnostics as display content.
|
package/docs/WINDOWS.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Windows
|
|
2
|
+
|
|
3
|
+
## Requirements
|
|
4
|
+
|
|
5
|
+
- GitHub Copilot CLI 1.0.52 or newer
|
|
6
|
+
- Node.js 22 or newer
|
|
7
|
+
- Windows Terminal or another terminal with ANSI support
|
|
8
|
+
|
|
9
|
+
## Paths
|
|
10
|
+
|
|
11
|
+
Copilot user settings:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
%COPILOT_HOME%\settings.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
When `COPILOT_HOME` is not set, the fallback is the `.copilot` directory in the current user's home directory.
|
|
18
|
+
|
|
19
|
+
Formatter settings:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
%APPDATA%\copilotstatusline\settings.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`--config <path>` overrides the formatter settings path. Installing with the same command writes the absolute Windows path into Copilot settings.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
PowerShell:
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
npx -y copilotstatusline@latest --install npm
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
If a global package is installed:
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
copilotstatusline --install global
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Restart Copilot CLI after installation.
|
|
42
|
+
|
|
43
|
+
## Powerline
|
|
44
|
+
|
|
45
|
+
The default Powerline separator requires a font containing U+E0B0. If the glyph is missing, disable Powerline in the TUI or install a compatible terminal font and select it in the terminal profile.
|
|
46
|
+
|
|
47
|
+
## Diagnostics
|
|
48
|
+
|
|
49
|
+
```powershell
|
|
50
|
+
copilotstatusline --check
|
|
51
|
+
Get-Content $env:COPILOT_HOME\settings.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
All helper subprocesses are launched with hidden Windows process windows. Missing Git or Jujutsu executables cause only the related widgets to be omitted.
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@willh/copilotstatusline",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"bugs": {
|
|
5
|
+
"url": "https://github.com/sirmalloc/copilotstatusline/issues"
|
|
6
|
+
},
|
|
7
|
+
"description": "A customizable status line formatter for GitHub Copilot CLI",
|
|
8
|
+
"main": "./dist/copilotstatusline.js",
|
|
9
|
+
"module": "./dist/copilotstatusline.js",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"bin": {
|
|
12
|
+
"copilotstatusline": "./dist/copilotstatusline.js"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/copilotstatusline.js",
|
|
17
|
+
"default": "./dist/copilotstatusline.js"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist/",
|
|
23
|
+
"docs/",
|
|
24
|
+
"NOTICE"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"start": "bun run src/copilotstatusline.ts",
|
|
28
|
+
"build": "rm -rf dist/* && bun build src/copilotstatusline.ts --target=node --outfile=dist/copilotstatusline.js --target-version=22",
|
|
29
|
+
"postbuild": "bun run scripts/replace-version.ts",
|
|
30
|
+
"example": "bun run src/copilotstatusline.ts < scripts/payload.example.json",
|
|
31
|
+
"prepublishOnly": "bun run build",
|
|
32
|
+
"lint": "bun tsc --noEmit && eslint . --config eslint.config.js --max-warnings=0",
|
|
33
|
+
"lint:fix": "bun tsc --noEmit && eslint . --config eslint.config.js --max-warnings=0 --fix",
|
|
34
|
+
"docs": "typedoc",
|
|
35
|
+
"docs:clean": "rm -rf typedoc"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@eslint/js": "^10.0.1",
|
|
39
|
+
"@stylistic/eslint-plugin": "^5.2.3",
|
|
40
|
+
"@types/bun": "latest",
|
|
41
|
+
"@types/react": "^19.1.10",
|
|
42
|
+
"eslint": "^10.0.0",
|
|
43
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
44
|
+
"eslint-plugin-import-newlines": "^2.0.0",
|
|
45
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
46
|
+
"eslint-plugin-react": "^7.37.5",
|
|
47
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
48
|
+
"globals": "^17.3.0",
|
|
49
|
+
"ink": "6.2.0",
|
|
50
|
+
"ink-select-input": "^6.2.0",
|
|
51
|
+
"ink-text-input": "^6.0.0",
|
|
52
|
+
"react": "19.2.7",
|
|
53
|
+
"slice-ansi": "^7.1.2",
|
|
54
|
+
"string-width": "^8.1.0",
|
|
55
|
+
"strip-ansi": "^7.1.0",
|
|
56
|
+
"typedoc": "^0.28.12",
|
|
57
|
+
"typescript": "^6.0.2",
|
|
58
|
+
"typescript-eslint": "^8.39.1",
|
|
59
|
+
"vitest": "^4.0.18",
|
|
60
|
+
"zod": "^4.0.17"
|
|
61
|
+
},
|
|
62
|
+
"keywords": [
|
|
63
|
+
"github-copilot",
|
|
64
|
+
"copilot-cli",
|
|
65
|
+
"cli",
|
|
66
|
+
"status-line",
|
|
67
|
+
"terminal"
|
|
68
|
+
],
|
|
69
|
+
"author": "",
|
|
70
|
+
"license": "MIT",
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "git+https://github.com/sirmalloc/copilotstatusline.git"
|
|
74
|
+
},
|
|
75
|
+
"engines": {
|
|
76
|
+
"node": ">=22.0.0"
|
|
77
|
+
},
|
|
78
|
+
"trustedDependencies": [
|
|
79
|
+
"unrs-resolver"
|
|
80
|
+
]
|
|
81
|
+
}
|