@davmash/bygone 0.5.2 → 0.7.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 +10 -2
- package/README.md +64 -22
- package/bin/bygone.js +72 -38
- package/cli/commandSpec.js +178 -0
- package/cli/completions.js +321 -0
- package/cli/present.js +166 -0
- package/cli/tour.js +189 -0
- package/cli/tourFile.js +26 -0
- package/completions/_bygone +131 -0
- package/completions/bygone +83 -0
- package/completions/bygone.fish +34 -0
- package/docs/change-explanation-plan.md +358 -0
- package/docs/change-tour-format.md +62 -0
- package/docs/generating-change-tours.md +75 -0
- package/docs/releasing.md +342 -0
- package/docs/walkthrough.md +103 -0
- package/examples/bygone-history.bygone.yaml +80 -0
- package/media/editor.worker.js +26 -14250
- package/media/icon.png +0 -0
- package/media/webview.css +1 -9818
- package/media/webview.js +358 -132939
- package/out/changeTour.js +1901 -0
- package/out/standalone-main.js +14698 -8507
- package/out/standalone-preload.js +5 -4
- package/package.json +10 -3
- package/schemas/change-tour-source.schema.json +287 -0
- package/standalone/index.html +23 -6
- package/web/index.html +266 -0
- package/web/presenter.css +725 -0
- package/web/web-host.js +149 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
## 0.7.0
|
|
6
|
+
|
|
7
|
+
- Expanded directory comparison into an N-panel workspace with asynchronous diff computation, drill-down, and complete file navigation
|
|
8
|
+
- Added merge-base branch review with rename pairing, binary and image comparison, and consistent navigation across Git workflows
|
|
9
|
+
- Improved semantic highlighting, structural replacement matching, line-click selection, connector rendering, and multi-panel interaction consistency
|
|
10
|
+
- Added generated shell completions, desktop CLI installation, local rebuild/install automation, linting, and renderer bundle budgets
|
|
11
|
+
- Added authored, code-connected change tours, bounded LLM context, coverage reporting, stacked and deconstructed explanations, the PR Tour Guide skill, and independent narrative and file navigation
|
|
12
|
+
- Added refreshable sessions, pane-local find, persistent line wrapping, resizable sidebars, and horizontal multi-panel scrolling
|
|
13
|
+
- Adopted the crisp-hybrid Bygone icon and strengthened release packaging across npm, VS Code, desktop, and Homebrew artifacts
|
|
14
|
+
- Added a [guided 0.7 release tour](./tours/v0.7.bygone.yaml) covering the complete range from `v0.6.3`
|
|
7
15
|
|
|
8
16
|
## 0.2.0
|
|
9
17
|
|
package/README.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
author: David Mashburn
|
|
3
|
+
created_at: 2026-06-01T20:35:08Z
|
|
4
|
+
modified_at: 2026-07-31T20:56:06Z
|
|
5
|
+
generated_by: Codex
|
|
6
|
+
generated_for: David Mashburn
|
|
7
|
+
reviewed_by:
|
|
8
|
+
approved_by:
|
|
9
|
+
repo: https://github.com/davidmashburn/bygone
|
|
10
|
+
branch: main
|
|
11
|
+
repo_branch_url: https://github.com/davidmashburn/bygone/tree/main
|
|
12
|
+
repo_head_commit_url: https://github.com/davidmashburn/bygone/commit/183156146f54cc35b9304d6b2131e066b88e97dc
|
|
13
|
+
---
|
|
14
|
+
|
|
1
15
|
# Bygone
|
|
2
16
|
|
|
3
17
|
Bygone is a VS Code extension and standalone desktop app for visual diff and file history.
|
|
@@ -10,19 +24,12 @@ Bygone is a VS Code extension and standalone desktop app for visual diff and fil
|
|
|
10
24
|
- Dynamic adjacent multi-panel diff view
|
|
11
25
|
- Flowing connectors, block contours, and inline change highlighting
|
|
12
26
|
- Git file history viewer with commit-by-commit navigation
|
|
27
|
+
- Local branch-review workspace using merge-base-to-tip semantics and changed-file progress
|
|
28
|
+
- Binary-aware comparisons with side-by-side image previews and byte-equality reporting
|
|
13
29
|
|
|
14
30
|
## Status
|
|
15
31
|
|
|
16
|
-
This project is usable as a
|
|
17
|
-
|
|
18
|
-
## Migration Note
|
|
19
|
-
|
|
20
|
-
This project was renamed from `Melden` to `Bygone`.
|
|
21
|
-
|
|
22
|
-
- VS Code extension id changed from `davidmashburn.melden` to `davidmashburn.bygone`
|
|
23
|
-
- CLI changed from `melden` to `bygone`
|
|
24
|
-
- Git difftool names changed from `melden` / `melden-vscode` to `bygone` / `bygone-vscode`
|
|
25
|
-
- Existing users should reinstall the extension and re-run the difftool setup scripts
|
|
32
|
+
This project is usable as a VS Code extension and standalone desktop app. The two-way diff and git history flows are the most complete. The multi-panel view is diff-focused, not a merge tool.
|
|
26
33
|
|
|
27
34
|
## Install For Development
|
|
28
35
|
|
|
@@ -58,23 +65,59 @@ npm install -g .
|
|
|
58
65
|
bygone
|
|
59
66
|
bygone path/to/file-or-directory
|
|
60
67
|
bygone --diff path/to/left path/to/right
|
|
68
|
+
bygone --diff
|
|
61
69
|
bygone --diff path/to/file1 path/to/file2 path/to/file3 [...]
|
|
62
|
-
bygone --
|
|
63
|
-
bygone
|
|
64
|
-
bygone
|
|
65
|
-
bygone --
|
|
70
|
+
bygone --history path/to/path
|
|
71
|
+
bygone review
|
|
72
|
+
bygone review feature/my-branch --base origin/main
|
|
73
|
+
bygone present feature/my-branch --base origin/main
|
|
74
|
+
bygone completion zsh
|
|
66
75
|
bygone --help
|
|
67
76
|
```
|
|
68
77
|
|
|
69
|
-
CLI
|
|
78
|
+
For a one-command local sync that builds the repo, installs the global CLI, packages the desktop app, and auto-installs the VSIX and desktop app for your current platform:
|
|
70
79
|
|
|
71
|
-
|
|
80
|
+
```bash
|
|
81
|
+
npm run dev:sync
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
CLI defaults:
|
|
85
|
+
- In a Git repo, `bygone` opens directory history for the current directory.
|
|
86
|
+
- Outside a Git repo, `bygone` opens a blank editable diff.
|
|
72
87
|
- `bygone <file>` opens file history.
|
|
73
88
|
- `bygone <directory>` opens Git directory history for that directory.
|
|
89
|
+
- `bygone --history <path>` opens file or directory history.
|
|
90
|
+
- `bygone review [<head>] [--base <base>]` reviews the committed branch tip against its merge base. The base is detected from `origin/HEAD`, `main`, or `master` when omitted.
|
|
91
|
+
- `bygone present [<head>] [--base <base>]` opens the same committed range as an app-hosted change tour, grouped into a deterministic suggested reading order.
|
|
74
92
|
- `bygone <left> <right>` auto-selects file diff or directory compare.
|
|
75
|
-
- `bygone --diff <file1> <file2> <file3> ...` opens multi-panel diff.
|
|
93
|
+
- `bygone --diff <file1> <file2> <file3> ...` opens multi-panel diff or multi-directory compare.
|
|
94
|
+
|
|
95
|
+
On macOS, desktop-backed CLI commands and change tours route into the running
|
|
96
|
+
Bygone app instead of opening another app instance and Dock item. Starting a
|
|
97
|
+
new comparison brings the central app window forward and replaces its current
|
|
98
|
+
session after any unsaved-change confirmation. Tours reuse a dedicated window
|
|
99
|
+
owned by that same app process.
|
|
100
|
+
|
|
101
|
+
Shell completion is generated from the same command specification as `bygone --help`, including contextual file arguments and local Git refs for branch review. `npm run dev:sync`, the desktop app's command-line installer, and the Homebrew packages install completions automatically. To install one manually, choose the command for your shell:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
mkdir -p ~/.zfunc ~/.local/share/bash-completion/completions ~/.config/fish/completions
|
|
105
|
+
bygone completion zsh > ~/.zfunc/_bygone # add ~/.zfunc to fpath before compinit
|
|
106
|
+
bygone completion bash > ~/.local/share/bash-completion/completions/bygone
|
|
107
|
+
bygone completion fish > ~/.config/fish/completions/bygone.fish
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If the native desktop app is installed, the npm/source launcher prefers it and forwards the shell working directory. Set `BYGONE_FORCE_BUNDLED=1` to force the npm-bundled Electron runtime instead. The launcher removes `ELECTRON_RUN_AS_NODE` before starting Electron so editor-integrated terminals cannot accidentally force the app into Node mode.
|
|
111
|
+
|
|
112
|
+
Branch review compares the selected head directly with `merge-base(base, head)`, so merge commits are represented correctly in the aggregate diff. Commit metadata retains every parent of merge commits for future temporal review. Dirty index and working-tree changes are reported but never silently included. Detected renames keep distinct old and new paths for correct drill-down and navigation without adding persistent cross-tree connectors.
|
|
113
|
+
|
|
114
|
+
Two-file and directory drill-down comparisons detect binary content before decoding it as text. Images render side by side when they are small enough to preview inline; all binary comparisons report whether the underlying bytes are identical.
|
|
115
|
+
|
|
116
|
+
Change tours can layer an authored, code-connected narrative over the complete generated change set. Pass a `.bygone.yaml` file with `--tour`; named source anchors compile to exact commit and line references, while an independent Files rail keeps every changed file available without adding filler scenes to the narrative. Try the self-referencing example with `bygone present --tour examples/bygone-history.bygone.yaml`, then see the [change tour format](./docs/change-tour-format.md).
|
|
117
|
+
|
|
118
|
+
Agents can validate anchors and structure with `bygone tour validate <file.bygone.yaml> --json`, compile a portable manifest with `bygone tour compile`, and retrieve the authoring contract with `bygone tour schema`. See [Generating change tours with an LLM](./docs/generating-change-tours.md), or give a compatible agent the repository's vendor-neutral [`pr-tour-guide` skill](./skills/pr-tour-guide/SKILL.md).
|
|
76
119
|
|
|
77
|
-
|
|
120
|
+
`bygone tour context [<head>] --base <base>` produces a provider-neutral change dossier with bounded patches, changed ranges, file roles, symbol hints, commits, renames, and explicit binary omissions for an LLM to consume.
|
|
78
121
|
|
|
79
122
|
The desktop app also includes `Help -> Install Command Line Tools...` for non-npm installs. Homebrew cask installs can provide the `bygone` command automatically.
|
|
80
123
|
|
|
@@ -114,7 +157,7 @@ npm run package:npm
|
|
|
114
157
|
npm pack --dry-run ./dist/npm-package
|
|
115
158
|
```
|
|
116
159
|
|
|
117
|
-
The root `package.json` is the VS Code extension manifest and intentionally keeps the unscoped extension name `bygone`. The npm distribution is staged separately as `@
|
|
160
|
+
The root `package.json` is the VS Code extension manifest and intentionally keeps the unscoped extension name `bygone`. The npm distribution is staged separately as `@davmash/bygone` so the global launcher can avoid the already-taken `bygone` package name while preserving the VS Code extension id `davidmashburn.bygone`.
|
|
118
161
|
|
|
119
162
|
Homebrew packaging templates live in `packaging/homebrew/`. They are staged for local validation only until release artifact URLs and checksums exist.
|
|
120
163
|
|
|
@@ -132,7 +175,7 @@ Publishing is intentionally explicit:
|
|
|
132
175
|
npm run release:publish
|
|
133
176
|
```
|
|
134
177
|
|
|
135
|
-
`release:publish` publishes the npm package,
|
|
178
|
+
`release:publish` publishes the npm package, creates a GitHub release for desktop artifacts, and updates a Homebrew tap. Set `BYGONE_HOMEBREW_TAP` to a local tap checkout before publishing Homebrew formulas. Until Marketplace trusted-publisher policies are publicly configurable, upload the packaged VSIX from the Visual Studio Marketplace publisher page.
|
|
136
179
|
|
|
137
180
|
Run the release checks:
|
|
138
181
|
|
|
@@ -195,7 +238,7 @@ The wrapper scripts are:
|
|
|
195
238
|
|
|
196
239
|
- `Bygone: Compare Files`
|
|
197
240
|
- `Bygone: Compare Directories`
|
|
198
|
-
- `Bygone: Compare
|
|
241
|
+
- `Bygone: Compare Multiple Directories`
|
|
199
242
|
- `Bygone: Compare Multiple Files`
|
|
200
243
|
- `Bygone: Compare with Selected`
|
|
201
244
|
- `Bygone: Compare Test Files`
|
|
@@ -207,7 +250,6 @@ The wrapper scripts are:
|
|
|
207
250
|
- Bygone is intentionally diff-focused; merge tooling is not exposed as a product feature.
|
|
208
251
|
- Directory compare supports modified-file detection and file drill-down; deep tree ergonomics are still early.
|
|
209
252
|
- The git history viewer currently steps through single-parent commit history for one file at a time.
|
|
210
|
-
- Marketplace publishing metadata is not finalized yet.
|
|
211
253
|
|
|
212
254
|
## Release Work
|
|
213
255
|
|
package/bin/bygone.js
CHANGED
|
@@ -4,57 +4,80 @@ const { spawn } = require('child_process');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const packageJson = require('../package.json');
|
|
7
|
+
const { generateCompletion, SUPPORTED_SHELLS } = require('../cli/completions.js');
|
|
8
|
+
const { renderCliHelp, tokenMatches } = require('../cli/commandSpec.js');
|
|
9
|
+
const { startPresentation } = require('../cli/present.js');
|
|
10
|
+
const { runTourCommand } = require('../cli/tour.js');
|
|
7
11
|
|
|
8
12
|
const args = process.argv.slice(2);
|
|
9
13
|
const cliCwd = process.cwd();
|
|
14
|
+
const packageRoot = path.join(__dirname, '..');
|
|
10
15
|
|
|
11
|
-
if (args.
|
|
12
|
-
process.stdout.write(
|
|
13
|
-
|
|
14
|
-
Usage:
|
|
15
|
-
bygone
|
|
16
|
-
bygone <file-or-directory>
|
|
17
|
-
bygone <left> <right>
|
|
18
|
-
bygone --diff <left> <right>
|
|
19
|
-
bygone --diff <file1> <file2> <file3> [...]
|
|
20
|
-
bygone --diff3 <left> <middle> <right>
|
|
21
|
-
bygone --dir <left-dir> <right-dir>
|
|
22
|
-
bygone --dir3 <left-dir> <middle-dir> <right-dir>
|
|
23
|
-
bygone --history <file>
|
|
24
|
-
bygone --dir-history <directory>
|
|
25
|
-
bygone --test
|
|
26
|
-
|
|
27
|
-
Notes:
|
|
28
|
-
- No args opens Git directory history for the current directory.
|
|
29
|
-
- One positional path opens file history or Git directory history.
|
|
30
|
-
- Two positional paths auto-select file diff or directory compare.
|
|
31
|
-
- \`--diff\` accepts 2 or more files; 3+ opens multi-panel diff.
|
|
32
|
-
- In the standalone app, drop 1 file for history, 2 files/directories for compare, 3+ files for multi-panel diff, or 3 directories for directory compare.
|
|
33
|
-
`);
|
|
16
|
+
if (args.some((arg) => tokenMatches('help', arg))) {
|
|
17
|
+
process.stdout.write(renderCliHelp(packageJson.version));
|
|
34
18
|
process.exit(0);
|
|
35
19
|
}
|
|
36
20
|
|
|
37
|
-
if (args.
|
|
21
|
+
if (args.some((arg) => tokenMatches('version', arg))) {
|
|
38
22
|
process.stdout.write(`${packageJson.version}\n`);
|
|
39
23
|
process.exit(0);
|
|
40
24
|
}
|
|
41
25
|
|
|
42
|
-
|
|
26
|
+
if (tokenMatches('completion', args[0])) {
|
|
27
|
+
const shell = args[1];
|
|
28
|
+
if (!SUPPORTED_SHELLS.includes(shell)) {
|
|
29
|
+
process.stderr.write(`Usage: bygone completion <${SUPPORTED_SHELLS.join('|')}>\n`);
|
|
30
|
+
process.exit(2);
|
|
31
|
+
}
|
|
32
|
+
process.stdout.write(generateCompletion(shell));
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (tokenMatches('tourCommand', args[0])) {
|
|
37
|
+
try {
|
|
38
|
+
runTourCommand(args.slice(1), cliCwd, packageRoot);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
41
|
+
process.stderr.write(args.includes('--json')
|
|
42
|
+
? `${JSON.stringify({ ok: false, error: { message } }, null, 2)}\n`
|
|
43
|
+
: `Could not process change tour: ${message}\n`);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
46
|
+
} else if (tokenMatches('present', args[0])) {
|
|
47
|
+
const installedApp = findInstalledApp();
|
|
48
|
+
if (installedApp && process.env.BYGONE_FORCE_BUNDLED !== '1') {
|
|
49
|
+
launchDesktopApp({ waitForExit: false });
|
|
50
|
+
} else {
|
|
51
|
+
startPresentation(args.slice(1), cliCwd, packageRoot).catch((error) => {
|
|
52
|
+
process.stderr.write(`Could not start change tour: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
launchDesktopApp();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function launchDesktopApp({ waitForExit = true } = {}) {
|
|
43
61
|
const electronBinary = process.platform === 'win32'
|
|
44
62
|
? '.\\node_modules\\.bin\\electron.cmd'
|
|
45
63
|
: './node_modules/.bin/electron';
|
|
46
64
|
const appEntry = './out/standalone-main.js';
|
|
47
65
|
const forwardedArgs = ['--cwd', cliCwd, ...args];
|
|
48
66
|
const installedApp = findInstalledApp();
|
|
49
|
-
const preferBundledApp = fs.existsSync(path.join(packageRoot, '.git'));
|
|
50
67
|
|
|
51
68
|
const child = installedApp && process.env.BYGONE_FORCE_BUNDLED !== '1'
|
|
52
|
-
|
|
53
|
-
? spawnInstalledApp(installedApp, forwardedArgs)
|
|
69
|
+
? spawnInstalledApp(installedApp, forwardedArgs, { waitForExit })
|
|
54
70
|
: spawn(electronBinary, [appEntry, ...forwardedArgs], {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
71
|
+
cwd: packageRoot,
|
|
72
|
+
detached: !waitForExit,
|
|
73
|
+
stdio: waitForExit ? 'inherit' : 'ignore',
|
|
74
|
+
env: electronEnvironment()
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (!waitForExit) {
|
|
78
|
+
child.unref();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
58
81
|
|
|
59
82
|
child.on('exit', (code, signal) => {
|
|
60
83
|
if (signal) {
|
|
@@ -64,6 +87,7 @@ child.on('exit', (code, signal) => {
|
|
|
64
87
|
|
|
65
88
|
process.exit(code ?? 0);
|
|
66
89
|
});
|
|
90
|
+
}
|
|
67
91
|
|
|
68
92
|
function findInstalledApp() {
|
|
69
93
|
if (process.platform === 'darwin') {
|
|
@@ -99,14 +123,24 @@ function findInstalledApp() {
|
|
|
99
123
|
return candidates.find((candidate) => fs.existsSync(candidate));
|
|
100
124
|
}
|
|
101
125
|
|
|
102
|
-
function spawnInstalledApp(installedApp, launchArgs) {
|
|
126
|
+
function spawnInstalledApp(installedApp, launchArgs, { waitForExit = true } = {}) {
|
|
127
|
+
const spawnOptions = {
|
|
128
|
+
detached: !waitForExit,
|
|
129
|
+
stdio: waitForExit ? 'inherit' : 'ignore',
|
|
130
|
+
env: electronEnvironment()
|
|
131
|
+
};
|
|
132
|
+
|
|
103
133
|
if (process.platform === 'darwin') {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
134
|
+
const executableName = path.basename(installedApp, '.app');
|
|
135
|
+
const executablePath = path.join(installedApp, 'Contents', 'MacOS', executableName);
|
|
136
|
+
return spawn(executablePath, launchArgs, spawnOptions);
|
|
107
137
|
}
|
|
108
138
|
|
|
109
|
-
return spawn(installedApp, launchArgs,
|
|
110
|
-
|
|
111
|
-
|
|
139
|
+
return spawn(installedApp, launchArgs, spawnOptions);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function electronEnvironment() {
|
|
143
|
+
const environment = { ...process.env };
|
|
144
|
+
delete environment.ELECTRON_RUN_AS_NODE;
|
|
145
|
+
return environment;
|
|
112
146
|
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const CLI_SPEC = Object.freeze({
|
|
2
|
+
name: 'bygone',
|
|
3
|
+
summary: 'Visual diff and file history',
|
|
4
|
+
usages: [
|
|
5
|
+
'bygone',
|
|
6
|
+
'bygone <file-or-directory>',
|
|
7
|
+
'bygone <left> <right>',
|
|
8
|
+
'bygone --diff <left> <right>',
|
|
9
|
+
'bygone --diff',
|
|
10
|
+
'bygone --diff <file1> <file2> <file3> [...]',
|
|
11
|
+
'bygone --history <path>',
|
|
12
|
+
'bygone --git-diff <ref1> <ref2> [<ref3>...]',
|
|
13
|
+
'bygone review [<head>] [--base <base>]',
|
|
14
|
+
'bygone present [<head>] [--base <base>] [--tour <file.bygone.yaml>]',
|
|
15
|
+
'bygone tour validate <file.bygone.yaml> [--json]',
|
|
16
|
+
'bygone tour compile <file.bygone.yaml> [--output <tour.json>]',
|
|
17
|
+
'bygone tour context [<head>] [--base <base>] [--output <context.json>]',
|
|
18
|
+
'bygone tour coverage <file.bygone.yaml> [--json] [--minimum-coverage <0-100>]',
|
|
19
|
+
'bygone tour schema',
|
|
20
|
+
'bygone --branch-diff [-b BRANCH] [-m MAIN]',
|
|
21
|
+
'bygone completion <zsh|bash|fish>',
|
|
22
|
+
'bygone --test'
|
|
23
|
+
],
|
|
24
|
+
entries: [
|
|
25
|
+
{
|
|
26
|
+
id: 'review',
|
|
27
|
+
kind: 'command',
|
|
28
|
+
tokens: ['review'],
|
|
29
|
+
description: 'Review a committed branch against its merge base',
|
|
30
|
+
argument: 'git-ref'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'completion',
|
|
34
|
+
kind: 'command',
|
|
35
|
+
tokens: ['completion'],
|
|
36
|
+
description: 'Print shell completion source',
|
|
37
|
+
argument: 'shell'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'present',
|
|
41
|
+
kind: 'command',
|
|
42
|
+
tokens: ['present'],
|
|
43
|
+
description: 'Open an app-hosted tour of a committed branch range',
|
|
44
|
+
argument: 'git-ref'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'tourCommand',
|
|
48
|
+
kind: 'command',
|
|
49
|
+
tokens: ['tour'],
|
|
50
|
+
description: 'Validate, compile, or inspect authored change tours',
|
|
51
|
+
argument: 'tour-action'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'diff',
|
|
55
|
+
kind: 'mode',
|
|
56
|
+
tokens: ['--diff'],
|
|
57
|
+
description: 'Compare files, or open a blank editable diff',
|
|
58
|
+
argument: 'files'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'history',
|
|
62
|
+
kind: 'mode',
|
|
63
|
+
tokens: ['--history'],
|
|
64
|
+
description: 'Open Git history for a file or directory',
|
|
65
|
+
argument: 'path'
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 'gitDiff',
|
|
69
|
+
kind: 'mode',
|
|
70
|
+
tokens: ['--git-diff'],
|
|
71
|
+
description: 'Compare two or more Git sources',
|
|
72
|
+
argument: 'git-refs'
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'branchDiff',
|
|
76
|
+
kind: 'mode',
|
|
77
|
+
tokens: ['--branch-diff'],
|
|
78
|
+
description: 'Legacy alias for branch review',
|
|
79
|
+
argument: 'git-ref'
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: 'test',
|
|
83
|
+
kind: 'mode',
|
|
84
|
+
tokens: ['--test'],
|
|
85
|
+
description: 'Open the built-in test comparison',
|
|
86
|
+
argument: 'none'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'includeStaged',
|
|
90
|
+
kind: 'option',
|
|
91
|
+
tokens: ['--include-staged', '--staged'],
|
|
92
|
+
description: 'Include staged state in Git history',
|
|
93
|
+
argument: 'none'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: 'base',
|
|
97
|
+
kind: 'option',
|
|
98
|
+
tokens: ['--base', '-m', '--main'],
|
|
99
|
+
description: 'Set the branch-review base ref',
|
|
100
|
+
argument: 'git-ref'
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: 'tour',
|
|
104
|
+
kind: 'option',
|
|
105
|
+
tokens: ['--tour'],
|
|
106
|
+
description: 'Use an authored change-tour YAML file',
|
|
107
|
+
argument: 'path'
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'branch',
|
|
111
|
+
kind: 'option',
|
|
112
|
+
tokens: ['-b', '--branch'],
|
|
113
|
+
description: 'Set the branch-review head ref',
|
|
114
|
+
argument: 'git-ref'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: 'help',
|
|
118
|
+
kind: 'global',
|
|
119
|
+
tokens: ['-h', '--help'],
|
|
120
|
+
description: 'Show command help',
|
|
121
|
+
argument: 'none'
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'version',
|
|
125
|
+
kind: 'global',
|
|
126
|
+
tokens: ['-v', '--version'],
|
|
127
|
+
description: 'Show the installed version',
|
|
128
|
+
argument: 'none'
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
notes: [
|
|
132
|
+
'No args opens Git directory history inside a Git repo, or a blank editable diff outside one.',
|
|
133
|
+
'`--diff` with no paths opens a blank editable diff.',
|
|
134
|
+
'One positional path opens file history or Git directory history.',
|
|
135
|
+
'`--history` accepts either files or directories.',
|
|
136
|
+
'Two positional paths auto-select file diff or directory compare.',
|
|
137
|
+
'Three or more positional paths auto-select multi-panel file diff or multi-directory compare.',
|
|
138
|
+
'`--git-diff` accepts branches, tags, SHAs, HEAD~1, stash@{0}, INDEX, and WORKTREE.',
|
|
139
|
+
'`review` compares merge-base(BASE,HEAD) with HEAD and detects the default base when omitted.',
|
|
140
|
+
'`present` turns the same range into an app-hosted, ordered change tour.',
|
|
141
|
+
'`tour validate` resolves every authored anchor; add `--json` for agent-readable output.',
|
|
142
|
+
'`tour compile` writes a portable manifest to stdout or `--output`; `tour schema` prints its source schema.',
|
|
143
|
+
'`tour context` emits compact, structured Git evidence for an LLM without invoking a model.',
|
|
144
|
+
'`tour coverage` reports referenced changed hunks and author-declared explanation depth.',
|
|
145
|
+
'`--branch-diff` is retained as an alias for `review`.',
|
|
146
|
+
'`completion` prints a completion script for Zsh, Bash, or Fish.',
|
|
147
|
+
'In the standalone app, drop 1 file for history, 2 files/directories for compare, or 3+ matching paths for multi-panel compare.'
|
|
148
|
+
]
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
function getCliEntry(id) {
|
|
152
|
+
return CLI_SPEC.entries.find((entry) => entry.id === id);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function tokensFor(id) {
|
|
156
|
+
return getCliEntry(id)?.tokens ?? [];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function tokenMatches(id, token) {
|
|
160
|
+
return tokensFor(id).includes(token);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function renderCliHelp(version) {
|
|
164
|
+
const usage = CLI_SPEC.usages.map((line) => ` ${line}`).join('\n');
|
|
165
|
+
const entries = CLI_SPEC.entries.map((entry) => (
|
|
166
|
+
` ${entry.tokens.join(', ')}\n ${entry.description}`
|
|
167
|
+
)).join('\n');
|
|
168
|
+
const notes = CLI_SPEC.notes.map((line) => ` - ${line}`).join('\n');
|
|
169
|
+
return `Bygone ${version}\n\nUsage:\n${usage}\n\nCommands and options:\n${entries}\n\nNotes:\n${notes}\n`;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = {
|
|
173
|
+
CLI_SPEC,
|
|
174
|
+
getCliEntry,
|
|
175
|
+
renderCliHelp,
|
|
176
|
+
tokenMatches,
|
|
177
|
+
tokensFor
|
|
178
|
+
};
|