reslop 0.1.9 → 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 +12 -1
- package/README.md +2 -1
- package/bin/reslop.js +2 -2
- package/lib/ansi.js +4 -2
- package/lib/api.js +2 -2
- package/lib/capabilities.js +7 -14
- package/lib/cli.js +28 -47
- package/lib/clipboard.js +1 -1
- package/lib/{deps/changes.js → deps-diff.js} +309 -19
- package/lib/deps.js +498 -29
- package/lib/detect.js +1 -7
- package/lib/diff/align.js +7 -10
- package/lib/diff/diff.js +53 -0
- package/lib/diff/display.js +5 -4
- package/lib/diff/inline.js +26 -21
- package/lib/diff/items.js +6 -4
- package/lib/diff/patch.js +1 -3
- package/lib/diff/unit.js +392 -0
- package/lib/files.js +5 -8
- package/lib/{git/branches.js → git-branches.js} +6 -5
- package/lib/{git/dependencies.js → git-deps.js} +111 -38
- package/lib/git.js +589 -68
- package/lib/github.js +28 -197
- package/lib/gitlab.js +24 -195
- package/lib/highlight/bash.js +1 -3
- package/lib/highlight/css.js +1 -3
- package/lib/highlight/js.js +11 -14
- package/lib/highlight.js +6 -9
- package/lib/keys.js +14 -8
- package/lib/manifest.js +330 -0
- package/lib/remote.js +374 -0
- package/lib/render/branches.js +14 -68
- package/lib/render/chrome.js +24 -9
- package/lib/render/commits.js +6 -59
- package/lib/render/diff.js +16 -16
- package/lib/render/files.js +6 -34
- package/lib/render/frame.js +23 -12
- package/lib/render/notes.js +4 -3
- package/lib/render/primitives.js +45 -0
- package/lib/{render.js → render/render.js} +5 -5
- package/lib/render/unit.js +41 -0
- package/lib/review.js +750 -14
- package/lib/select.js +5 -10
- package/lib/session/accessors.js +9 -1
- package/lib/session/actions.js +32 -16
- package/lib/session/branches.js +116 -128
- package/lib/session/change-actions.js +202 -123
- package/lib/session/commit.js +105 -112
- package/lib/session/compose.js +158 -13
- package/lib/session/dispatch.js +104 -60
- package/lib/session/files-pane.js +142 -148
- package/lib/session/items.js +22 -30
- package/lib/session/lifecycle.js +44 -44
- package/lib/session/load.js +19 -33
- package/lib/session/navigation.js +12 -1
- package/lib/session/ops.js +28 -41
- package/lib/session/pointer.js +54 -57
- package/lib/session/review.js +23 -37
- package/lib/session/terminal.js +6 -12
- package/lib/session/todos.js +8 -12
- package/lib/session/unit.js +208 -0
- package/lib/session/update.js +33 -46
- package/lib/session/view.js +78 -9
- package/lib/session/watch.js +11 -19
- package/lib/session.js +21 -246
- package/lib/source.js +3 -3
- package/lib/update.js +40 -75
- package/lib/{git/proc.js → utilities.js} +75 -11
- package/lib/wrap.js +1 -3
- package/package.json +1 -1
- package/lib/deps/items.js +0 -134
- package/lib/deps/manifest.js +0 -152
- package/lib/deps/merge.js +0 -120
- package/lib/deps/proposals.js +0 -164
- package/lib/deps/reports.js +0 -180
- package/lib/deps/rows.js +0 -176
- package/lib/deps/scan.js +0 -138
- package/lib/deps/usage.js +0 -68
- package/lib/deps/versions.js +0 -119
- package/lib/diff.js +0 -33
- package/lib/git/changes.js +0 -164
- package/lib/git/read.js +0 -253
- package/lib/git/run.js +0 -100
- package/lib/npm/commands.js +0 -100
- package/lib/remote/changes.js +0 -37
- package/lib/remote/headers.js +0 -36
- package/lib/remote/http.js +0 -122
- package/lib/remote/notes.js +0 -94
- package/lib/review/format.js +0 -434
- package/lib/review/storage.js +0 -150
- package/lib/review/store.js +0 -178
- package/lib/review/templates.js +0 -49
- package/lib/session/origins.js +0 -7
- package/lib/sys.js +0 -84
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased][unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.2.0][] - 2026-09-22
|
|
6
|
+
|
|
7
|
+
- Add a full-size file editor
|
|
8
|
+
- Optimize codebase and reorganize code structure
|
|
9
|
+
- Add pull and push on the commits list screen
|
|
10
|
+
- Fix disk watcher startup on macOS
|
|
11
|
+
- Fix Windows temp-path comparison and same-size file reload polling
|
|
12
|
+
|
|
13
|
+
## [0.1.9][] - 2026-09-19
|
|
14
|
+
|
|
5
15
|
- Remove `r` reload hotkey and hint; auto-reload covers disk changes
|
|
6
16
|
- Improve branch list TUI/TUX
|
|
7
17
|
- Right-align the time column in the branch list
|
|
@@ -95,7 +105,8 @@
|
|
|
95
105
|
- Feedback and todos that produce a repair plan for an agent
|
|
96
106
|
- Intra-line highlighting in unified, mixed, and side-by-side layouts
|
|
97
107
|
|
|
98
|
-
[unreleased]: https://github.com/tshemsedinov/reslop/compare/v0.
|
|
108
|
+
[unreleased]: https://github.com/tshemsedinov/reslop/compare/v0.2.0...HEAD
|
|
109
|
+
[0.2.0]: https://github.com/tshemsedinov/reslop/compare/v0.1.9...v0.2.0
|
|
99
110
|
[0.1.9]: https://github.com/tshemsedinov/reslop/compare/v0.1.8...v0.1.9
|
|
100
111
|
[0.1.8]: https://github.com/tshemsedinov/reslop/compare/v0.1.7...v0.1.8
|
|
101
112
|
[0.1.7]: https://github.com/tshemsedinov/reslop/compare/v0.1.6...v0.1.7
|
package/README.md
CHANGED
|
@@ -20,10 +20,11 @@ Review → Plan → Repair → Verify
|
|
|
20
20
|
|
|
21
21
|
- Leave feedback, issues/todos, and in-place code proposals as a repair plan
|
|
22
22
|
- Review uncommitted git diffs, a given commit, a GitHub PR, or a GitLab MR
|
|
23
|
+
- File-scope review mode: not just diffs, with editor mode
|
|
23
24
|
- Stage, unstage, or revert each contiguous block of diff lines
|
|
24
25
|
- Auto-reload local diffs when files change, keeping the current screen
|
|
25
26
|
- Import GitHub PR and GitLab MR review comments into the local plan for AI
|
|
26
|
-
- Commits list: commit, amend, fixup, and
|
|
27
|
+
- Commits list: commit, amend, fixup, drop, pull, and push
|
|
27
28
|
- Branches: checkout, create, rebase, drop, pull, and push
|
|
28
29
|
- Review each npm dependency once across `package.json` and the lockfile
|
|
29
30
|
- Propose unused removals, npm audit fixes, and outdated updates as diffs
|
package/bin/reslop.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const { run,
|
|
4
|
+
const { run, errorMessage } = require('../lib/cli.js');
|
|
5
5
|
const { LEAVE_TERM } = require('../lib/session.js');
|
|
6
6
|
|
|
7
7
|
const fail = (reason) => {
|
|
@@ -10,7 +10,7 @@ const fail = (reason) => {
|
|
|
10
10
|
} catch {
|
|
11
11
|
// ignore
|
|
12
12
|
}
|
|
13
|
-
process.stderr.write(
|
|
13
|
+
process.stderr.write(`reslop: ${errorMessage(reason)}\n`);
|
|
14
14
|
process.exit(1);
|
|
15
15
|
};
|
|
16
16
|
|
package/lib/ansi.js
CHANGED
|
@@ -158,8 +158,10 @@ const paint = (text, fgRgb, bgRgb, color, bold) => {
|
|
|
158
158
|
const stripAnsi = (text) => text.replace(ANSI_RE, '');
|
|
159
159
|
|
|
160
160
|
const graphemes = (text) => {
|
|
161
|
-
const parts =
|
|
162
|
-
|
|
161
|
+
const parts = new Array(text.length);
|
|
162
|
+
let n = 0;
|
|
163
|
+
for (const { segment } of SEGMENTER.segment(text)) parts[n++] = segment;
|
|
164
|
+
parts.length = n;
|
|
163
165
|
return parts;
|
|
164
166
|
};
|
|
165
167
|
|
package/lib/api.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const ansi = require('./ansi.js');
|
|
4
|
-
const diff = require('./diff.js');
|
|
4
|
+
const diff = require('./diff/diff.js');
|
|
5
5
|
const git = require('./git.js');
|
|
6
6
|
const keys = require('./keys.js');
|
|
7
|
-
const render = require('./render.js');
|
|
7
|
+
const render = require('./render/render.js');
|
|
8
8
|
const highlight = require('./highlight.js');
|
|
9
9
|
const detect = require('./detect.js');
|
|
10
10
|
const github = require('./github.js');
|
package/lib/capabilities.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const fs = require('node:fs');
|
|
4
|
-
|
|
5
3
|
const READ_METHODS = [
|
|
6
4
|
'load',
|
|
7
5
|
'loadAsync',
|
|
8
6
|
'loadExtras',
|
|
9
7
|
'toplevel',
|
|
10
8
|
'resolveRev',
|
|
9
|
+
'listFiles',
|
|
10
|
+
'fileText',
|
|
11
11
|
];
|
|
12
12
|
|
|
13
13
|
const CHANGE_METHODS = [
|
|
@@ -17,6 +17,7 @@ const CHANGE_METHODS = [
|
|
|
17
17
|
'revert',
|
|
18
18
|
'revertFile',
|
|
19
19
|
'edit',
|
|
20
|
+
'writeFile',
|
|
20
21
|
];
|
|
21
22
|
|
|
22
23
|
const BRANCH_METHODS = [
|
|
@@ -46,9 +47,9 @@ const BRANCH_METHODS = [
|
|
|
46
47
|
const SOURCE_CAPS = {
|
|
47
48
|
local: { read: true, changes: true, branches: true, review: true },
|
|
48
49
|
commit: { read: true, changes: false, branches: false, review: true },
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
pr: { read: true, changes: false, branches: false, review: true },
|
|
51
|
+
mr: { read: true, changes: false, branches: false, review: true },
|
|
52
|
+
readonly: { read: true, changes: false, branches: false, review: true },
|
|
52
53
|
};
|
|
53
54
|
|
|
54
55
|
const withReadOnly = (caps, readOnly) => {
|
|
@@ -86,16 +87,9 @@ const sessionCapabilities = (options) => {
|
|
|
86
87
|
}
|
|
87
88
|
const repoCaps = options.repo && options.repo.capabilities;
|
|
88
89
|
if (repoCaps) return withReadOnly(repoCaps, readOnly);
|
|
89
|
-
return capabilitiesFor(readOnly ? '
|
|
90
|
+
return capabilitiesFor(readOnly ? 'readonly' : 'local');
|
|
90
91
|
};
|
|
91
92
|
|
|
92
|
-
const createReviewStorage = (io = {}) => ({
|
|
93
|
-
readdirSync: io.readdirSync ?? fs.readdirSync,
|
|
94
|
-
readFileSync: io.readFileSync ?? fs.readFileSync,
|
|
95
|
-
writeFileSync: io.writeFileSync ?? fs.writeFileSync,
|
|
96
|
-
mkdirSync: io.mkdirSync ?? fs.mkdirSync,
|
|
97
|
-
});
|
|
98
|
-
|
|
99
93
|
module.exports = {
|
|
100
94
|
READ_METHODS,
|
|
101
95
|
CHANGE_METHODS,
|
|
@@ -105,5 +99,4 @@ module.exports = {
|
|
|
105
99
|
withReadOnly,
|
|
106
100
|
attachCapabilities,
|
|
107
101
|
sessionCapabilities,
|
|
108
|
-
createReviewStorage,
|
|
109
102
|
};
|
package/lib/cli.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const fs = require('node:fs');
|
|
4
3
|
const path = require('node:path');
|
|
5
4
|
|
|
5
|
+
const { exists } = require('metautil');
|
|
6
|
+
|
|
6
7
|
const { createGitRepo } = require('./git.js');
|
|
7
8
|
const { githubToken, loadPullRequest } = require('./github.js');
|
|
8
9
|
const { gitlabToken, loadMergeRequest } = require('./gitlab.js');
|
|
@@ -17,13 +18,13 @@ const RANGE_REV = /[~^]/;
|
|
|
17
18
|
const USAGE = 'Usage: reslop [-n] [-r] [path | commit | pr-url | mr-url]';
|
|
18
19
|
|
|
19
20
|
const REMOTE_CHANGE = {
|
|
20
|
-
|
|
21
|
+
pr: {
|
|
21
22
|
load: 'loadPullRequest',
|
|
22
23
|
fallback: loadPullRequest,
|
|
23
24
|
token: githubToken,
|
|
24
25
|
target: (selected) => selected.pr,
|
|
25
26
|
},
|
|
26
|
-
|
|
27
|
+
mr: {
|
|
27
28
|
load: 'loadMergeRequest',
|
|
28
29
|
fallback: loadMergeRequest,
|
|
29
30
|
token: gitlabToken,
|
|
@@ -38,16 +39,8 @@ const errorMessage = (reason) => {
|
|
|
38
39
|
return `${reason}`;
|
|
39
40
|
};
|
|
40
41
|
|
|
41
|
-
const failLine = (reason) => `reslop: ${errorMessage(reason)}\n`;
|
|
42
|
-
|
|
43
42
|
const fail = (stderr, reason) => {
|
|
44
|
-
stderr.write(
|
|
45
|
-
return 1;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const failUsage = (stderr, reason) => {
|
|
49
|
-
fail(stderr, reason);
|
|
50
|
-
stderr.write(`${USAGE}\n`);
|
|
43
|
+
stderr.write(`reslop: ${errorMessage(reason)}\n`);
|
|
51
44
|
return 1;
|
|
52
45
|
};
|
|
53
46
|
|
|
@@ -79,19 +72,10 @@ const looksLikeRev = (spec) => {
|
|
|
79
72
|
return RANGE_REV.test(spec);
|
|
80
73
|
};
|
|
81
74
|
|
|
82
|
-
const
|
|
83
|
-
try {
|
|
84
|
-
statSync(path.resolve(cwd, rel));
|
|
85
|
-
return true;
|
|
86
|
-
} catch {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const resolveScope = (cwd, paths, repo, statSync = fs.statSync) => {
|
|
75
|
+
const resolveScope = async (cwd, paths, repo) => {
|
|
92
76
|
if (!paths.length) return { rev: null, paths };
|
|
93
77
|
const first = paths[0];
|
|
94
|
-
if (
|
|
78
|
+
if (await exists(path.resolve(cwd, first))) {
|
|
95
79
|
return { rev: null, paths };
|
|
96
80
|
}
|
|
97
81
|
const resolved = repo.resolveRev(cwd, first);
|
|
@@ -107,14 +91,11 @@ const resolveScope = (cwd, paths, repo, statSync = fs.statSync) => {
|
|
|
107
91
|
return { rev: null, paths };
|
|
108
92
|
};
|
|
109
93
|
|
|
110
|
-
const isColorEnabled = (stdout, env) => stdout.isTTY === true && !env.NO_COLOR;
|
|
111
|
-
|
|
112
94
|
const sessionOptions = (proc, deps, args, env, extra) => ({
|
|
113
95
|
cwd: deps.cwd ?? proc.cwd(),
|
|
114
96
|
stdin: proc.stdin,
|
|
115
97
|
stdout: proc.stdout,
|
|
116
|
-
color:
|
|
117
|
-
getSize: deps.getSize,
|
|
98
|
+
color: proc.stdout.isTTY === true && !env.NO_COLOR,
|
|
118
99
|
startPane: 'files',
|
|
119
100
|
newReview: args.newReview,
|
|
120
101
|
readOnly: args.readOnly,
|
|
@@ -122,22 +103,21 @@ const sessionOptions = (proc, deps, args, env, extra) => ({
|
|
|
122
103
|
...extra,
|
|
123
104
|
});
|
|
124
105
|
|
|
125
|
-
const openLocalSession = (proc, deps, args, selected, env) => {
|
|
106
|
+
const openLocalSession = async (proc, deps, args, selected, env) => {
|
|
126
107
|
const cwd = deps.cwd ?? proc.cwd();
|
|
127
108
|
const rawRepo = deps.repo ?? createGitRepo();
|
|
128
|
-
const
|
|
129
|
-
const scope = resolveScope(cwd, selected.paths, rawRepo, statSync);
|
|
109
|
+
const scope = await resolveScope(cwd, selected.paths, rawRepo);
|
|
130
110
|
const kind = scope.rev ? 'commit' : 'local';
|
|
131
111
|
const capabilities = capabilitiesFor(kind, { readOnly: args.readOnly });
|
|
132
112
|
const repo = attachCapabilities(rawRepo, capabilities);
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
);
|
|
113
|
+
const extra = {
|
|
114
|
+
repo,
|
|
115
|
+
paths: scope.paths,
|
|
116
|
+
rev: scope.rev,
|
|
117
|
+
capabilities,
|
|
118
|
+
};
|
|
119
|
+
const options = sessionOptions(proc, deps, args, env, extra);
|
|
120
|
+
const session = new Session(options);
|
|
141
121
|
session.ensureRepo();
|
|
142
122
|
return session;
|
|
143
123
|
};
|
|
@@ -168,13 +148,12 @@ const openRemoteSession = (proc, deps, args, selected, env) => {
|
|
|
168
148
|
const capabilities = capabilitiesFor(selected.kind, {
|
|
169
149
|
readOnly: args.readOnly,
|
|
170
150
|
});
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
);
|
|
151
|
+
const repo = remoteRepo(deps, selected, env, cwd);
|
|
152
|
+
const extra = { repo, paths: selected.paths, capabilities };
|
|
153
|
+
const options = sessionOptions(proc, deps, args, env, extra);
|
|
154
|
+
const session = new Session(options);
|
|
155
|
+
session.ensureRepo();
|
|
156
|
+
return session;
|
|
178
157
|
};
|
|
179
158
|
|
|
180
159
|
const loadSession = async (proc, deps, args) => {
|
|
@@ -200,7 +179,9 @@ const run = async (proc, deps = {}) => {
|
|
|
200
179
|
try {
|
|
201
180
|
args = parseArgv(proc.argv.slice(2));
|
|
202
181
|
} catch (error) {
|
|
203
|
-
|
|
182
|
+
fail(stderr, error);
|
|
183
|
+
stderr.write(`${USAGE}\n`);
|
|
184
|
+
return 1;
|
|
204
185
|
}
|
|
205
186
|
let session;
|
|
206
187
|
try {
|
|
@@ -224,7 +205,7 @@ const run = async (proc, deps = {}) => {
|
|
|
224
205
|
};
|
|
225
206
|
|
|
226
207
|
module.exports = {
|
|
227
|
-
|
|
208
|
+
errorMessage,
|
|
228
209
|
parseArgv,
|
|
229
210
|
resolveScope,
|
|
230
211
|
run,
|
package/lib/clipboard.js
CHANGED