reslop 0.2.1 → 0.2.4
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 +27 -1
- package/README.md +19 -4
- package/bin/reslop.js +4 -2
- package/lib/ansi.js +120 -4
- package/lib/api.js +2 -1
- package/lib/cli.js +21 -9
- package/lib/clipboard.js +6 -3
- package/lib/deps-diff.js +61 -115
- package/lib/deps.js +57 -54
- package/lib/detect.js +4 -2
- package/lib/diff/align.js +2 -1
- package/lib/diff/diff.js +6 -3
- package/lib/diff/display.js +2 -1
- package/lib/diff/inline.js +2 -1
- package/lib/diff/patch.js +2 -1
- package/lib/diff/unit.js +4 -2
- package/lib/editor.js +22 -4
- package/lib/files.js +38 -12
- package/lib/git-branches.js +150 -165
- package/lib/git-deps.js +20 -60
- package/lib/git-worktree.js +508 -0
- package/lib/git.js +23 -580
- package/lib/github.js +2 -1
- package/lib/gitlab.js +2 -1
- package/lib/highlight/bash.js +2 -1
- package/lib/highlight/css.js +2 -1
- package/lib/highlight/csv.js +2 -1
- package/lib/highlight/dot.js +2 -1
- package/lib/highlight/html.js +2 -1
- package/lib/highlight/json.js +2 -1
- package/lib/highlight/log.js +2 -1
- package/lib/highlight/txt.js +2 -1
- package/lib/highlight.js +2 -1
- package/lib/keys.js +12 -6
- package/lib/manifest.js +4 -2
- package/lib/npm-commands.js +592 -0
- package/lib/remote.js +20 -13
- package/lib/render/branches.js +25 -41
- package/lib/render/chrome.js +163 -128
- package/lib/render/commits.js +727 -65
- package/lib/render/diff.js +130 -47
- package/lib/render/files.js +4 -12
- package/lib/render/frame.js +41 -13
- package/lib/render/notes.js +4 -11
- package/lib/render/npm.js +216 -0
- package/lib/render/present.js +2 -1
- package/lib/render/primitives.js +34 -50
- package/lib/render/render.js +2 -1
- package/lib/render/unit.js +14 -11
- package/lib/report-model.js +129 -0
- package/lib/report-parse.js +89 -0
- package/lib/report-render.js +104 -0
- package/lib/report-run.js +166 -0
- package/lib/report-test.js +507 -0
- package/lib/report-tools.js +337 -0
- package/lib/review-merge.js +2 -1
- package/lib/review.js +6 -2
- package/lib/session/actions.js +77 -44
- package/lib/session/branches.js +13 -49
- package/lib/session/change-actions.js +2 -1
- package/lib/session/commit.js +113 -53
- package/lib/session/compose.js +83 -14
- package/lib/session/dispatch.js +42 -22
- package/lib/session/files-pane.js +16 -21
- package/lib/session/items.js +6 -3
- package/lib/session/lifecycle.js +12 -5
- package/lib/session/load.js +4 -2
- package/lib/session/navigation.js +2 -0
- package/lib/session/npm.js +388 -0
- package/lib/session/ops.js +15 -1
- package/lib/session/pointer.js +30 -3
- package/lib/session/review.js +2 -1
- package/lib/session/terminal.js +4 -2
- package/lib/session/update.js +2 -1
- package/lib/session/view.js +41 -4
- package/lib/session.js +44 -22
- package/lib/source.js +6 -3
- package/lib/update.js +5 -9
- package/lib/utilities.js +4 -2
- package/lib/wrap.js +3 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased][unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.2.4][] - 2026-09-28
|
|
6
|
+
|
|
7
|
+
- Add AI instructions to run `npm t` or `reslop t -- node --test`
|
|
8
|
+
- Cleanup old logs (older than 5 days)
|
|
9
|
+
- Rename TODO list to Project Backlog and Issues
|
|
10
|
+
- Word wrap in view and horizontal scrolling in edit mode
|
|
11
|
+
- Return to uncommitted changes when viewing history in read-only mode
|
|
12
|
+
- Improve TUI/TUX for commits and npm commands
|
|
13
|
+
- Remove circular dependencies between Git modules
|
|
14
|
+
- Unify list rendering and keyboard navigation
|
|
15
|
+
- Simplify dependency transformations and remove redundant wrappers
|
|
16
|
+
|
|
17
|
+
## [0.2.3][] - 2026-09-27
|
|
18
|
+
|
|
19
|
+
- Add brief and full commit lists, toggled with `v`
|
|
20
|
+
- Select a commit from the list to view its diff
|
|
21
|
+
- Edit a multi-line commit message
|
|
22
|
+
- Propose unused removals only for libraries that export code
|
|
23
|
+
- Improve TUI/TUX, multiple small fixes
|
|
24
|
+
- Implement npm command runner with termination and re-run
|
|
25
|
+
- Filter tests output to reduce AI costs: `npm t` and other scripts
|
|
26
|
+
- Save script logs under `.log/`
|
|
27
|
+
- Group similar problems in test and other output
|
|
28
|
+
|
|
5
29
|
## [0.2.1][] - 2026-09-23
|
|
6
30
|
|
|
7
31
|
- Type a new commit message at the top of the list
|
|
@@ -117,7 +141,9 @@
|
|
|
117
141
|
- Feedback and todos that produce a repair plan for an agent
|
|
118
142
|
- Intra-line highlighting in unified, mixed, and side-by-side layouts
|
|
119
143
|
|
|
120
|
-
[unreleased]: https://github.com/tshemsedinov/reslop/compare/v0.2.
|
|
144
|
+
[unreleased]: https://github.com/tshemsedinov/reslop/compare/v0.2.4...HEAD
|
|
145
|
+
[0.2.4]: https://github.com/tshemsedinov/reslop/compare/v0.2.3...v0.2.4
|
|
146
|
+
[0.2.3]: https://github.com/tshemsedinov/reslop/compare/v0.2.1...v0.2.3
|
|
121
147
|
[0.2.1]: https://github.com/tshemsedinov/reslop/compare/v0.2.0...v0.2.1
|
|
122
148
|
[0.2.0]: https://github.com/tshemsedinov/reslop/compare/v0.1.9...v0.2.0
|
|
123
149
|
[0.1.9]: https://github.com/tshemsedinov/reslop/compare/v0.1.8...v0.1.9
|
package/README.md
CHANGED
|
@@ -11,21 +11,24 @@
|
|
|
11
11
|
|
|
12
12
|
> Turn generated changes into owned changes
|
|
13
13
|
|
|
14
|
-
Open a change, leave findings and
|
|
14
|
+
Open a change, leave findings and a backlog, and prepare a repair plan
|
|
15
15
|
for the agent.
|
|
16
16
|
|
|
17
17
|
```text
|
|
18
18
|
Review → Plan → Repair → Verify
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
- Leave feedback,
|
|
21
|
+
- Leave feedback, a project backlog, 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
23
|
- File-scope review mode: not just diffs, with editor mode
|
|
24
24
|
- Stage, unstage, or revert each contiguous block of diff lines
|
|
25
25
|
- Auto-reload local diffs when files change, keeping the current screen
|
|
26
26
|
- Import GitHub PR and GitLab MR review comments into the local plan for AI
|
|
27
|
-
- Commits list: commit, amend, fixup, reword, drop, pull, and push
|
|
27
|
+
- Commits list: brief and full, view a commit's diff, commit, amend, fixup, reword, drop, pull, and push
|
|
28
28
|
- Branches: checkout, create, rebase, drop, pull, and push
|
|
29
|
+
- npm scripts and bins: run, edit, and reorder; double-click to run; clean logs older than 5 days
|
|
30
|
+
- Long lines wrap in the diff view; the editor scrolls horizontally
|
|
31
|
+
- Reduced test and lint output for agents: failures and a short summary, not passing noise
|
|
29
32
|
- Review each npm dependency once across `package.json` and the lockfile
|
|
30
33
|
- Propose unused removals, npm audit fixes, and outdated updates as diffs
|
|
31
34
|
- Code highlighting and intra-line diffs: unified, mixed, and side-by-side
|
|
@@ -39,6 +42,7 @@ npm i -g reslop
|
|
|
39
42
|
```
|
|
40
43
|
|
|
41
44
|
Works on Linux, macOS, and Windows. On Windows use Windows Terminal.
|
|
45
|
+
Requires Node.js `>=18.15.0`.
|
|
42
46
|
|
|
43
47
|
## Usage
|
|
44
48
|
|
|
@@ -49,6 +53,18 @@ Works on Linux, macOS, and Windows. On Windows use Windows Terminal.
|
|
|
49
53
|
- `reslop -n` start a new review even if the latest is still editing
|
|
50
54
|
- `reslop -r` read-only mode
|
|
51
55
|
- `reslop -light` light color theme (default dark)
|
|
56
|
+
- `reslop t -- <program> [args]` run one program and print a reduced report
|
|
57
|
+
|
|
58
|
+
Prefix each program in an npm script with `reslop t --`. Keep `&&` between those wraps, so each program is captured on its own and a failing step does not start the next one:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
"lint": "reslop t -- eslint . && reslop t -- prettier -c \"**/*.js\"",
|
|
62
|
+
"test": "reslop t -- npm run -s lint && reslop t -- node --test"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The report is Markdown: failures, diagnostics, and a short summary. Passing results are omitted and similar problems are grouped. The same text is saved under `.log/`. Set `RESLOP_OUTPUT=raw` to pass the command through unchanged. The review screen runs scripts in raw mode and applies its own filter once.
|
|
66
|
+
|
|
67
|
+
Run the full check with `npm t`. Run one or more test files with `reslop t -- node --test <files>`. New reviews include those two commands in the agent instructions.
|
|
52
68
|
|
|
53
69
|
Reviews go in `.review/YYYY-MM-DD-NN.md` with frontmatter `status`:
|
|
54
70
|
|
|
@@ -65,7 +81,6 @@ Reviews go in `.review/YYYY-MM-DD-NN.md` with frontmatter `status`:
|
|
|
65
81
|
- Send anonymized code blocks for expert review
|
|
66
82
|
- Send questions and the repair plan to experts for approval
|
|
67
83
|
- Ask experts
|
|
68
|
-
- Verify the codebase
|
|
69
84
|
- Apply refactoring skills
|
|
70
85
|
- Call agents, harnesses, and IDEs to execute prepared plans
|
|
71
86
|
- Squash, cherry-pick, and interactive rebase
|
package/bin/reslop.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
4
|
+
const cli = require('../lib/cli.js');
|
|
5
|
+
const { run, errorMessage } = cli;
|
|
6
|
+
const session = require('../lib/session.js');
|
|
7
|
+
const { LEAVE_TERM } = session;
|
|
6
8
|
|
|
7
9
|
const fail = (reason) => {
|
|
8
10
|
try {
|
package/lib/ansi.js
CHANGED
|
@@ -60,7 +60,6 @@ const DARK_UI = {
|
|
|
60
60
|
headerDirFg: [0x6e, 0x6e, 0x6e],
|
|
61
61
|
headerSlashFg: [0x8a, 0x8a, 0x8a],
|
|
62
62
|
headerFileFg: [0x4e, 0x4e, 0x4e],
|
|
63
|
-
headerMetaFg: [0x5a, 0x5a, 0x5a],
|
|
64
63
|
chromeFg: [0xd0, 0xd0, 0xe0],
|
|
65
64
|
chromeBg: [0x18, 0x18, 0x24],
|
|
66
65
|
noteBg: [0x24, 0x24, 0x36],
|
|
@@ -153,7 +152,6 @@ const LIGHT_UI = {
|
|
|
153
152
|
headerDirFg: [0x57, 0x60, 0x6a],
|
|
154
153
|
headerSlashFg: [0x8c, 0x95, 0x9f],
|
|
155
154
|
headerFileFg: [0x1f, 0x23, 0x28],
|
|
156
|
-
headerMetaFg: [0x42, 0x4a, 0x53],
|
|
157
155
|
chromeFg: [0x24, 0x29, 0x2f],
|
|
158
156
|
chromeBg: [0xf0, 0xf2, 0xf5],
|
|
159
157
|
noteBg: [0xe8, 0xf0, 0xfe],
|
|
@@ -280,9 +278,14 @@ const codeFg = (style) => {
|
|
|
280
278
|
return CODE_FG.plain;
|
|
281
279
|
};
|
|
282
280
|
|
|
283
|
-
const
|
|
281
|
+
const channels = (rgb) => {
|
|
282
|
+
if (typeof rgb === 'number') return `${rgb};${rgb};${rgb}`;
|
|
283
|
+
return `${rgb[0]};${rgb[1]};${rgb[2]}`;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const fg = (rgb) => `${ESC}[38;2;${channels(rgb)}m`;
|
|
284
287
|
|
|
285
|
-
const bg = (rgb) => `${ESC}[48;2;${rgb
|
|
288
|
+
const bg = (rgb) => `${ESC}[48;2;${channels(rgb)}m`;
|
|
286
289
|
|
|
287
290
|
const seq = (fgRgb, bgRgb) => `${fg(fgRgb)}${bg(bgRgb)}`;
|
|
288
291
|
|
|
@@ -352,6 +355,117 @@ const truncateVisible = (text, width) => {
|
|
|
352
355
|
return out;
|
|
353
356
|
};
|
|
354
357
|
|
|
358
|
+
const csiLength = (text, index) => {
|
|
359
|
+
if (text[index] !== ESC || text[index + 1] !== '[') return 0;
|
|
360
|
+
let at = index + 2;
|
|
361
|
+
while (at < text.length) {
|
|
362
|
+
const code = text.charCodeAt(at);
|
|
363
|
+
at += 1;
|
|
364
|
+
if (code >= 64 && code <= 126) return at - index;
|
|
365
|
+
}
|
|
366
|
+
return 0;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const firstGrapheme = (text) => {
|
|
370
|
+
const next = SEGMENTER.segment(text)[Symbol.iterator]().next();
|
|
371
|
+
if (next.done || !next.value) return '';
|
|
372
|
+
return next.value.segment;
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const clipAnsi = (text, width) => {
|
|
376
|
+
const raw = `${text ?? ''}`;
|
|
377
|
+
if (width <= 0) return '';
|
|
378
|
+
if (visibleWidth(raw) <= width) return raw;
|
|
379
|
+
let used = 0;
|
|
380
|
+
let out = '';
|
|
381
|
+
let index = 0;
|
|
382
|
+
while (index < raw.length && used < width) {
|
|
383
|
+
const csi = csiLength(raw, index);
|
|
384
|
+
if (csi) {
|
|
385
|
+
out += raw.slice(index, index + csi);
|
|
386
|
+
index += csi;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
const ch = firstGrapheme(raw.slice(index));
|
|
390
|
+
if (!ch) break;
|
|
391
|
+
const w = graphemeWidth(ch, used);
|
|
392
|
+
if (used + w > width) break;
|
|
393
|
+
out += ch;
|
|
394
|
+
used += w;
|
|
395
|
+
index += ch.length;
|
|
396
|
+
}
|
|
397
|
+
if (stripAnsi(out) !== stripAnsi(raw)) out += RESET;
|
|
398
|
+
return out;
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const sgrParams = (seq) => {
|
|
402
|
+
const inner = seq.slice(2, -1);
|
|
403
|
+
if (!inner) return [0];
|
|
404
|
+
return inner.split(';').map((part) => (part === '' ? 0 : Number(part)));
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
const colorSpan = (params, index) => {
|
|
408
|
+
const mode = params[index + 1];
|
|
409
|
+
if (mode === 5) return 2;
|
|
410
|
+
if (mode === 2) return 4;
|
|
411
|
+
return 0;
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
const keepFgParams = (params) => {
|
|
415
|
+
const kept = [];
|
|
416
|
+
for (let i = 0; i < params.length; i++) {
|
|
417
|
+
const code = params[i];
|
|
418
|
+
if (code === 38 || code === 48) {
|
|
419
|
+
const extra = colorSpan(params, i);
|
|
420
|
+
if (code === 38 && extra) {
|
|
421
|
+
kept.push(code, ...params.slice(i + 1, i + 1 + extra));
|
|
422
|
+
}
|
|
423
|
+
i += extra;
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
if (code >= 40 && code <= 49) continue;
|
|
427
|
+
if (code >= 100 && code <= 107) continue;
|
|
428
|
+
if (code === 7 || code === 27) continue;
|
|
429
|
+
kept.push(code);
|
|
430
|
+
}
|
|
431
|
+
return kept;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const foregroundOn = (text, bgRgb) => {
|
|
435
|
+
const raw = `${text ?? ''}`;
|
|
436
|
+
const ground = bg(bgRgb);
|
|
437
|
+
let out = '';
|
|
438
|
+
let index = 0;
|
|
439
|
+
while (index < raw.length) {
|
|
440
|
+
if (raw[index] !== ESC) {
|
|
441
|
+
const next = raw.indexOf(ESC, index);
|
|
442
|
+
const end = next < 0 ? raw.length : next;
|
|
443
|
+
out += raw.slice(index, end);
|
|
444
|
+
index = end;
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
const csi = csiLength(raw, index);
|
|
448
|
+
if (!csi) {
|
|
449
|
+
out += raw[index];
|
|
450
|
+
index += 1;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
const seq = raw.slice(index, index + csi);
|
|
454
|
+
index += csi;
|
|
455
|
+
if (!seq.endsWith('m')) {
|
|
456
|
+
out += seq;
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
const kept = keepFgParams(sgrParams(seq));
|
|
460
|
+
const reset = kept.includes(0);
|
|
461
|
+
const rest = kept.filter((code) => code !== 0);
|
|
462
|
+
if (reset) out += `${ESC}[0m`;
|
|
463
|
+
out += ground;
|
|
464
|
+
if (rest.length) out += `${ESC}[${rest.join(';')}m`;
|
|
465
|
+
}
|
|
466
|
+
return out;
|
|
467
|
+
};
|
|
468
|
+
|
|
355
469
|
module.exports = {
|
|
356
470
|
ESC,
|
|
357
471
|
RESET,
|
|
@@ -373,4 +487,6 @@ module.exports = {
|
|
|
373
487
|
graphemeWidth,
|
|
374
488
|
visibleWidth,
|
|
375
489
|
truncateVisible,
|
|
490
|
+
clipAnsi,
|
|
491
|
+
foregroundOn,
|
|
376
492
|
};
|
package/lib/api.js
CHANGED
|
@@ -10,7 +10,8 @@ const detect = require('./detect.js');
|
|
|
10
10
|
const github = require('./github.js');
|
|
11
11
|
const gitlab = require('./gitlab.js');
|
|
12
12
|
const source = require('./source.js');
|
|
13
|
-
const
|
|
13
|
+
const session = require('./session.js');
|
|
14
|
+
const { Session } = session;
|
|
14
15
|
const cli = require('./cli.js');
|
|
15
16
|
|
|
16
17
|
module.exports = {
|
package/lib/cli.js
CHANGED
|
@@ -2,15 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const {
|
|
10
|
-
const
|
|
11
|
-
const {
|
|
12
|
-
const
|
|
13
|
-
const {
|
|
5
|
+
const metautil = require('metautil');
|
|
6
|
+
const { exists } = metautil;
|
|
7
|
+
|
|
8
|
+
const git = require('./git.js');
|
|
9
|
+
const { createGitRepo } = git;
|
|
10
|
+
const github = require('./github.js');
|
|
11
|
+
const { githubToken, loadPullRequest } = github;
|
|
12
|
+
const gitlab = require('./gitlab.js');
|
|
13
|
+
const { gitlabToken, loadMergeRequest } = gitlab;
|
|
14
|
+
const source = require('./source.js');
|
|
15
|
+
const { selectChangeSource, createLoadedSource } = source;
|
|
16
|
+
const session = require('./session.js');
|
|
17
|
+
const { Session } = session;
|
|
18
|
+
const capabilities = require('./capabilities.js');
|
|
19
|
+
const { capabilitiesFor, attachCapabilities } = capabilities;
|
|
20
|
+
const ansi = require('./ansi.js');
|
|
21
|
+
const { setTheme } = ansi;
|
|
22
|
+
const reportRun = require('./report-run.js');
|
|
23
|
+
const { runCapture } = reportRun;
|
|
14
24
|
|
|
15
25
|
const HEX_REV = /^[0-9a-f]{4,40}$/i;
|
|
16
26
|
const HEAD_REV = /^HEAD([~^].*)?$/i;
|
|
@@ -180,6 +190,8 @@ const runUi = async (session, proc) => {
|
|
|
180
190
|
};
|
|
181
191
|
|
|
182
192
|
const run = async (proc, deps = {}) => {
|
|
193
|
+
const argv = proc.argv.slice(2);
|
|
194
|
+
if (argv[0] === 't') return runCapture(proc, deps);
|
|
183
195
|
const stdout = proc.stdout;
|
|
184
196
|
const stderr = proc.stderr;
|
|
185
197
|
let args;
|
package/lib/clipboard.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const childProcess = require('node:child_process');
|
|
4
|
+
const { spawnSync } = childProcess;
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
const {
|
|
6
|
+
const ansi = require('./ansi.js');
|
|
7
|
+
const { ESC } = ansi;
|
|
8
|
+
const utilities = require('./utilities.js');
|
|
9
|
+
const { clipTools, spawnBase } = utilities;
|
|
7
10
|
|
|
8
11
|
const CLIP_TIMEOUT_MS = 1000;
|
|
9
12
|
|
package/lib/deps-diff.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const { isCtxType } =
|
|
3
|
+
const metautil = require('metautil');
|
|
4
|
+
const { jsonParse } = metautil;
|
|
5
|
+
const files = require('./files.js');
|
|
6
|
+
const { itemPath } = files;
|
|
7
|
+
const patch = require('./diff/patch.js');
|
|
8
|
+
const { countSides, formatHunkHeader, formatPatch } = patch;
|
|
9
|
+
const diff = require('./diff/diff.js');
|
|
10
|
+
const { isCtxType } = diff;
|
|
11
11
|
const manifest = require('./manifest.js');
|
|
12
12
|
const { MANIFEST, LOCKFILE, SECTION_KEYS, depFileMeta, relOf } = manifest;
|
|
13
13
|
const { listFilePath, readSections, emptySectionMaps } = manifest;
|
|
@@ -37,14 +37,8 @@ const diffMaps = (oldMap, newMap, section) => {
|
|
|
37
37
|
return changes;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
const diffSections = (oldMaps, newMaps) =>
|
|
41
|
-
|
|
42
|
-
for (const key of SECTION_KEYS) {
|
|
43
|
-
const found = diffMaps(oldMaps[key], newMaps[key], key);
|
|
44
|
-
for (const change of found) changes.push(change);
|
|
45
|
-
}
|
|
46
|
-
return changes;
|
|
47
|
-
};
|
|
40
|
+
const diffSections = (oldMaps, newMaps) =>
|
|
41
|
+
SECTION_KEYS.flatMap((key) => diffMaps(oldMaps[key], newMaps[key], key));
|
|
48
42
|
|
|
49
43
|
const fieldText = (value) => {
|
|
50
44
|
if (value === undefined) return '';
|
|
@@ -263,15 +257,8 @@ const compareChangeOrder = (left, right) => {
|
|
|
263
257
|
|
|
264
258
|
const orderedChanges = (changes) => [...changes].sort(compareChangeOrder);
|
|
265
259
|
|
|
266
|
-
const kindItems = (items, kind) =>
|
|
267
|
-
|
|
268
|
-
for (const item of items) {
|
|
269
|
-
const rel = itemPath(item);
|
|
270
|
-
const meta = depFileMeta(rel);
|
|
271
|
-
if (meta && meta.kind === kind) matched.push(item);
|
|
272
|
-
}
|
|
273
|
-
return matched;
|
|
274
|
-
};
|
|
260
|
+
const kindItems = (items, kind) =>
|
|
261
|
+
items.filter((item) => depFileMeta(itemPath(item))?.kind === kind);
|
|
275
262
|
|
|
276
263
|
const readGroupSnapshot = (group, readSides) => {
|
|
277
264
|
const origin = group.origin;
|
|
@@ -457,26 +444,10 @@ const entryText = (change, side) => {
|
|
|
457
444
|
return `"${change.name}": "${version}"`;
|
|
458
445
|
};
|
|
459
446
|
|
|
460
|
-
const ctxLine = (text) => {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
const warnLine = (text) => {
|
|
466
|
-
const type = 'warn';
|
|
467
|
-
return { type, text };
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
const noteLine = (text) => {
|
|
471
|
-
const type = 'note';
|
|
472
|
-
return { type, text };
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
const noteSepLine = () => {
|
|
476
|
-
const type = 'noteSep';
|
|
477
|
-
const text = '';
|
|
478
|
-
return { type, text };
|
|
479
|
-
};
|
|
447
|
+
const ctxLine = (text) => ({ type: 'ctx', text });
|
|
448
|
+
const warnLine = (text) => ({ type: 'warn', text });
|
|
449
|
+
const noteLine = (text) => ({ type: 'note', text });
|
|
450
|
+
const noteSepLine = () => ({ type: 'noteSep', text: '' });
|
|
480
451
|
|
|
481
452
|
const changeLine = (type, change, side) => {
|
|
482
453
|
const text = entryText(change, side);
|
|
@@ -522,12 +493,7 @@ const auditNoteTexts = (audit) => {
|
|
|
522
493
|
}
|
|
523
494
|
const severity = audit.severity;
|
|
524
495
|
if (!notes.length) return [`npm audit ${severity}`];
|
|
525
|
-
|
|
526
|
-
const texts = new Array(length);
|
|
527
|
-
for (let i = 0; i < length; i++) {
|
|
528
|
-
texts[i] = `npm audit ${severity} ${notes[i]}`;
|
|
529
|
-
}
|
|
530
|
-
return texts;
|
|
496
|
+
return notes.map((note) => `npm audit ${severity} ${note}`);
|
|
531
497
|
};
|
|
532
498
|
|
|
533
499
|
const pushAuditNotes = (rows, audit) => {
|
|
@@ -562,13 +528,12 @@ const buildRows = (change, oldCount, newCount) => {
|
|
|
562
528
|
return rows;
|
|
563
529
|
};
|
|
564
530
|
|
|
565
|
-
const toHunkLine = (row, blockId) => {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
};
|
|
531
|
+
const toHunkLine = (row, blockId) => ({
|
|
532
|
+
type: row.type,
|
|
533
|
+
text: row.text,
|
|
534
|
+
noNl: false,
|
|
535
|
+
blockId: isCtxType(row.type) ? null : blockId,
|
|
536
|
+
});
|
|
572
537
|
|
|
573
538
|
const makeHunk = (rows, blockId) => {
|
|
574
539
|
const lines = rows.map((row) => toHunkLine(row, blockId));
|
|
@@ -600,21 +565,13 @@ const filesForChange = (change, files) => {
|
|
|
600
565
|
if (meta.kind === 'manifest') manifest.push(rel);
|
|
601
566
|
else lockfile.push(rel);
|
|
602
567
|
}
|
|
603
|
-
if (change.section === '
|
|
604
|
-
|
|
605
|
-
return files;
|
|
606
|
-
}
|
|
607
|
-
if (change.section === 'resolved') {
|
|
608
|
-
if (lockfile.length) return lockfile;
|
|
609
|
-
return files;
|
|
610
|
-
}
|
|
611
|
-
if (change.propose) {
|
|
612
|
-
if (manifest.length) return manifest;
|
|
613
|
-
return files;
|
|
568
|
+
if (change.section === 'resolved') return lockfile.length ? lockfile : files;
|
|
569
|
+
if (change.section === 'field' || change.propose) {
|
|
570
|
+
return manifest.length ? manifest : files;
|
|
614
571
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
572
|
+
return manifest.length || lockfile.length
|
|
573
|
+
? [...manifest, ...lockfile]
|
|
574
|
+
: files;
|
|
618
575
|
};
|
|
619
576
|
|
|
620
577
|
const pickPrimary = (items) => {
|
|
@@ -630,36 +587,28 @@ const makeDepItem = (origin, fileItems, hidden, change, extra, blockId) => {
|
|
|
630
587
|
const allFiles = uniquePaths(fileItems);
|
|
631
588
|
const files = change ? filesForChange(change, allFiles) : allFiles;
|
|
632
589
|
const primary = pickPrimary(fileItems);
|
|
633
|
-
const
|
|
634
|
-
const
|
|
635
|
-
const
|
|
636
|
-
const isDeleted = fileItems.every((item) => item.file && item.file.isDeleted);
|
|
637
|
-
let oldCount = 0;
|
|
638
|
-
let newCount = 0;
|
|
639
|
-
if (!change) {
|
|
640
|
-
oldCount = extra.oldCount ?? 0;
|
|
641
|
-
newCount = extra.newCount ?? 0;
|
|
642
|
-
}
|
|
643
|
-
const rows = buildRows(change, oldCount, newCount);
|
|
590
|
+
const rel = listFilePath(itemPath(primary));
|
|
591
|
+
const counts = change ? {} : extra;
|
|
592
|
+
const rows = buildRows(change, counts.oldCount ?? 0, counts.newCount ?? 0);
|
|
644
593
|
const hunk = makeHunk(rows, blockId);
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
594
|
+
return {
|
|
595
|
+
origin,
|
|
596
|
+
file: {
|
|
597
|
+
oldPath: rel,
|
|
598
|
+
newPath: rel,
|
|
599
|
+
isNew: fileItems.some((item) => item.file?.isNew),
|
|
600
|
+
isDeleted: fileItems.every((item) => item.file?.isDeleted),
|
|
601
|
+
isBinary: false,
|
|
602
|
+
preamble: [],
|
|
603
|
+
hunks: [hunk],
|
|
604
|
+
},
|
|
605
|
+
hunk,
|
|
606
|
+
blockId,
|
|
607
|
+
patchAdd: '',
|
|
608
|
+
patchRevert: '',
|
|
609
|
+
dep: { files, items: hidden, change },
|
|
610
|
+
reload: !!change?.propose,
|
|
656
611
|
};
|
|
657
|
-
const patchAdd = '';
|
|
658
|
-
const patchRevert = '';
|
|
659
|
-
const items = hidden;
|
|
660
|
-
const dep = { files, items, change };
|
|
661
|
-
const reload = !!(change && change.propose);
|
|
662
|
-
return { origin, file, hunk, blockId, patchAdd, patchRevert, dep, reload };
|
|
663
612
|
};
|
|
664
613
|
|
|
665
614
|
const makeDepItems = (origin, fileItems, hidden, summary) => {
|
|
@@ -670,16 +619,14 @@ const makeDepItems = (origin, fileItems, hidden, summary) => {
|
|
|
670
619
|
if (oldCount === newCount) return [];
|
|
671
620
|
return [makeDepItem(origin, fileItems, hidden, null, summary, 0)];
|
|
672
621
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
items[i] = makeDepItem(origin, fileItems, hidden, ordered[i], summary, i);
|
|
677
|
-
}
|
|
678
|
-
return items;
|
|
622
|
+
return ordered.map((change, index) =>
|
|
623
|
+
makeDepItem(origin, fileItems, hidden, change, summary, index),
|
|
624
|
+
);
|
|
679
625
|
};
|
|
680
626
|
|
|
681
|
-
const stubFileItem = (rel, origin) => {
|
|
682
|
-
|
|
627
|
+
const stubFileItem = (rel, origin) => ({
|
|
628
|
+
origin,
|
|
629
|
+
file: {
|
|
683
630
|
oldPath: rel,
|
|
684
631
|
newPath: rel,
|
|
685
632
|
isNew: false,
|
|
@@ -687,13 +634,12 @@ const stubFileItem = (rel, origin) => {
|
|
|
687
634
|
isBinary: false,
|
|
688
635
|
preamble: [],
|
|
689
636
|
hunks: [],
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
};
|
|
637
|
+
},
|
|
638
|
+
hunk: null,
|
|
639
|
+
blockId: 0,
|
|
640
|
+
patchAdd: '',
|
|
641
|
+
patchRevert: '',
|
|
642
|
+
});
|
|
697
643
|
|
|
698
644
|
module.exports = {
|
|
699
645
|
DEP_CAPTION,
|