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.
Files changed (81) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +19 -4
  3. package/bin/reslop.js +4 -2
  4. package/lib/ansi.js +120 -4
  5. package/lib/api.js +2 -1
  6. package/lib/cli.js +21 -9
  7. package/lib/clipboard.js +6 -3
  8. package/lib/deps-diff.js +61 -115
  9. package/lib/deps.js +57 -54
  10. package/lib/detect.js +4 -2
  11. package/lib/diff/align.js +2 -1
  12. package/lib/diff/diff.js +6 -3
  13. package/lib/diff/display.js +2 -1
  14. package/lib/diff/inline.js +2 -1
  15. package/lib/diff/patch.js +2 -1
  16. package/lib/diff/unit.js +4 -2
  17. package/lib/editor.js +22 -4
  18. package/lib/files.js +38 -12
  19. package/lib/git-branches.js +150 -165
  20. package/lib/git-deps.js +20 -60
  21. package/lib/git-worktree.js +508 -0
  22. package/lib/git.js +23 -580
  23. package/lib/github.js +2 -1
  24. package/lib/gitlab.js +2 -1
  25. package/lib/highlight/bash.js +2 -1
  26. package/lib/highlight/css.js +2 -1
  27. package/lib/highlight/csv.js +2 -1
  28. package/lib/highlight/dot.js +2 -1
  29. package/lib/highlight/html.js +2 -1
  30. package/lib/highlight/json.js +2 -1
  31. package/lib/highlight/log.js +2 -1
  32. package/lib/highlight/txt.js +2 -1
  33. package/lib/highlight.js +2 -1
  34. package/lib/keys.js +12 -6
  35. package/lib/manifest.js +4 -2
  36. package/lib/npm-commands.js +592 -0
  37. package/lib/remote.js +20 -13
  38. package/lib/render/branches.js +25 -41
  39. package/lib/render/chrome.js +163 -128
  40. package/lib/render/commits.js +727 -65
  41. package/lib/render/diff.js +130 -47
  42. package/lib/render/files.js +4 -12
  43. package/lib/render/frame.js +41 -13
  44. package/lib/render/notes.js +4 -11
  45. package/lib/render/npm.js +216 -0
  46. package/lib/render/present.js +2 -1
  47. package/lib/render/primitives.js +34 -50
  48. package/lib/render/render.js +2 -1
  49. package/lib/render/unit.js +14 -11
  50. package/lib/report-model.js +129 -0
  51. package/lib/report-parse.js +89 -0
  52. package/lib/report-render.js +104 -0
  53. package/lib/report-run.js +166 -0
  54. package/lib/report-test.js +507 -0
  55. package/lib/report-tools.js +337 -0
  56. package/lib/review-merge.js +2 -1
  57. package/lib/review.js +6 -2
  58. package/lib/session/actions.js +77 -44
  59. package/lib/session/branches.js +13 -49
  60. package/lib/session/change-actions.js +2 -1
  61. package/lib/session/commit.js +113 -53
  62. package/lib/session/compose.js +83 -14
  63. package/lib/session/dispatch.js +42 -22
  64. package/lib/session/files-pane.js +16 -21
  65. package/lib/session/items.js +6 -3
  66. package/lib/session/lifecycle.js +12 -5
  67. package/lib/session/load.js +4 -2
  68. package/lib/session/navigation.js +2 -0
  69. package/lib/session/npm.js +388 -0
  70. package/lib/session/ops.js +15 -1
  71. package/lib/session/pointer.js +30 -3
  72. package/lib/session/review.js +2 -1
  73. package/lib/session/terminal.js +4 -2
  74. package/lib/session/update.js +2 -1
  75. package/lib/session/view.js +41 -4
  76. package/lib/session.js +44 -22
  77. package/lib/source.js +6 -3
  78. package/lib/update.js +5 -9
  79. package/lib/utilities.js +4 -2
  80. package/lib/wrap.js +3 -1
  81. package/package.json +6 -6
@@ -3,7 +3,9 @@
3
3
  const path = require('node:path');
4
4
 
5
5
  const files = require('../files.js');
6
- const { fileEntries, REPO_TODOS_LABEL } = files;
6
+ const commit = require('./commit.js');
7
+ const { listedCommits } = commit;
8
+ const { fileEntries, fileTotals, REPO_TODOS_LABEL } = files;
7
9
  const review = require('../review.js');
8
10
  const { noteCounts } = review;
9
11
  const diff = require('../diff/diff.js');
@@ -142,8 +144,32 @@ const unitBodyLines = (api) => {
142
144
  return unitLines(unitFileText(api), group);
143
145
  };
144
146
 
147
+ const pendingLines = (items, rev, revShort) => {
148
+ if (rev || revShort) return null;
149
+ for (const item of items) {
150
+ if (item.origin === 'commit' || item.origin === 'pr') return null;
151
+ }
152
+ return fileTotals(fileEntries(items));
153
+ };
154
+
155
+ const commitRows = (api) => {
156
+ const rows = listedCommits(api.commits.commits);
157
+ const lines = pendingLines(api.collection.items, api.ui.rev, api.ui.revShort);
158
+ if (!lines || !rows[0]) return rows;
159
+ rows[0] = {
160
+ ...rows[0],
161
+ added: lines.added,
162
+ removed: lines.removed,
163
+ stagedAdded: lines.stagedAdded,
164
+ unstagedAdded: lines.unstagedAdded,
165
+ stagedRemoved: lines.stagedRemoved,
166
+ unstagedRemoved: lines.unstagedRemoved,
167
+ };
168
+ return rows;
169
+ };
170
+
145
171
  const view = (api) => {
146
- const { composer, nav, ui, gitBranches, commits, updater } = api;
172
+ const { composer, nav, ui, gitBranches, commits, npm, updater } = api;
147
173
  const templates = composer.shownTemplates();
148
174
  const change = ui.change;
149
175
  const sourceKind = (change && change.source) || '';
@@ -169,9 +195,20 @@ const view = (api) => {
169
195
  branch: ui.branch,
170
196
  branches: gitBranches.branches,
171
197
  branchCursor: nav.branchCursor,
172
- commits: commits.commits,
198
+ commits: commitRows(api),
173
199
  commitCursor: nav.commitCursor,
200
+ commitView: commits.commitView,
201
+ npmCommands: npm.commands,
202
+ npmCursor: nav.npmCursor,
203
+ npmView: npm.viewing,
204
+ npmOutput: npm.output,
205
+ npmFollow: npm.followEnd,
206
+ npmScroll: npm.logScroll,
207
+ npmEditName: npm.editName,
208
+ npmRunning: npm.running,
209
+ npmLogs: nav.pane === 'npm' ? npm.logLabel : '',
174
210
  repoName: repoNameOf(api),
211
+ rev: ui.rev || '',
175
212
  revShort: ui.revShort || '',
176
213
  sourceLabel: ui.sourceLabel || '',
177
214
  sourceKind,
@@ -186,7 +223,7 @@ const view = (api) => {
186
223
  templateIndex: composer.clampedTemplateIndex(templates),
187
224
  updateFrom: updater.from,
188
225
  updateTo: updater.to,
189
- dropName: gitBranches.dropName || commits.dropName,
226
+ dropName: gitBranches.dropName || commits.dropName || npm.dropName,
190
227
  };
191
228
  };
192
229
 
package/lib/session.js CHANGED
@@ -9,30 +9,50 @@ const { renderFrame } = render;
9
9
  const { decodeChunk } = keys;
10
10
  const { AUTOSAVE_MS, hasNotes } = review;
11
11
  const capabilities = require('./capabilities.js');
12
+ const actions = require('./session/actions.js');
13
+ const { LIST_PANES } = actions;
12
14
  const { sessionCapabilities } = capabilities;
13
- const { createTerminal, LEAVE_TERM } = require('./session/terminal.js');
14
- const { createLoadCoordinator } = require('./session/load.js');
15
+ const terminal = require('./session/terminal.js');
16
+ const { createTerminal, LEAVE_TERM } = terminal;
17
+ const load = require('./session/load.js');
18
+ const { createLoadCoordinator } = load;
15
19
  const items = require('./session/items.js');
16
20
  const { createItemCollection } = items;
17
- const { createNavigation } = require('./session/navigation.js');
18
- const { createReviewController } = require('./session/review.js');
19
- const { createUpdateCoordinator } = require('./session/update.js');
20
- const { createProgress } = require('./session/progress.js');
21
- const { createComposer } = require('./session/compose.js');
22
- const { createOpsRunner } = require('./session/ops.js');
23
- const { createChangeActions } = require('./session/change-actions.js');
24
- const { createCommitController } = require('./session/commit.js');
25
- const { createBranchController } = require('./session/branches.js');
21
+ const navigation = require('./session/navigation.js');
22
+ const { createNavigation } = navigation;
23
+ const sessionReview = require('./session/review.js');
24
+ const { createReviewController } = sessionReview;
25
+ const update = require('./session/update.js');
26
+ const { createUpdateCoordinator } = update;
27
+ const progress = require('./session/progress.js');
28
+ const { createProgress } = progress;
29
+ const compose = require('./session/compose.js');
30
+ const { createComposer } = compose;
31
+ const ops = require('./session/ops.js');
32
+ const { createOpsRunner } = ops;
33
+ const changeActions = require('./session/change-actions.js');
34
+ const { createChangeActions } = changeActions;
35
+ const commit = require('./session/commit.js');
36
+ const { createCommitController } = commit;
37
+ const branches = require('./session/branches.js');
38
+ const { createBranchController } = branches;
39
+ const npm = require('./session/npm.js');
40
+ const { createNpmController } = npm;
26
41
  const accessors = require('./session/accessors.js');
27
42
  const { bindAccessors, bindGetters, bindAlias } = accessors;
28
- const { createView } = require('./session/view.js');
29
- const { createFilesPane } = require('./session/files-pane.js');
30
- const { createLifecycle } = require('./session/lifecycle.js');
31
- const { createPointer } = require('./session/pointer.js');
32
- const { createDispatcher, createInput } = require('./session/dispatch.js');
43
+ const view = require('./session/view.js');
44
+ const { createView } = view;
45
+ const filesPane = require('./session/files-pane.js');
46
+ const { createFilesPane } = filesPane;
47
+ const lifecycle = require('./session/lifecycle.js');
48
+ const { createLifecycle } = lifecycle;
49
+ const pointer = require('./session/pointer.js');
50
+ const { createPointer } = pointer;
51
+ const dispatch = require('./session/dispatch.js');
52
+ const { createDispatcher, createInput } = dispatch;
33
53
 
34
54
  const CURSOR_BLINK_MS = 500;
35
- const PROGRESS_MS = 80;
55
+ const PROGRESS_MS = 160;
36
56
 
37
57
  const NAV_FIELDS = [
38
58
  'pane',
@@ -40,6 +60,7 @@ const NAV_FIELDS = [
40
60
  'fileCursor',
41
61
  'branchCursor',
42
62
  'commitCursor',
63
+ 'npmCursor',
43
64
  'scroll',
44
65
  'listScroll',
45
66
  'reviewPath',
@@ -127,6 +148,7 @@ const assignControllers = (session) => {
127
148
  session.changeActions = createChangeActions(session);
128
149
  session.commits = createCommitController(session);
129
150
  session.gitBranches = createBranchController(session);
151
+ session.npm = createNpmController(session);
130
152
  };
131
153
 
132
154
  const bindSessionAccessors = (session) => {
@@ -185,6 +207,7 @@ const bindViewer = (session) => {
185
207
  review: session.review,
186
208
  gitBranches: session.gitBranches,
187
209
  commits: session.commits,
210
+ npm: session.npm,
188
211
  updater: session.updater,
189
212
  ui: session,
190
213
  });
@@ -242,6 +265,7 @@ class Session {
242
265
  if (this.ops) this.ops.reset();
243
266
  if (this.gitBranches) this.gitBranches.reset();
244
267
  if (this.commits) this.commits.reset();
268
+ if (this.npm) this.npm.reset();
245
269
  this.top = this.cwd;
246
270
  this.branch = '';
247
271
  this.status = '';
@@ -309,13 +333,10 @@ class Session {
309
333
  height: size.height,
310
334
  color: this.color,
311
335
  });
312
- if (
313
- this.pane === 'files' ||
314
- this.pane === 'branches' ||
315
- this.pane === 'commits'
316
- ) {
336
+ if (LIST_PANES.includes(this.pane)) {
317
337
  this.nav.listScroll = frame.listScroll;
318
338
  }
339
+ if (this.nav.todoOpen) this.nav.scroll = frame.scroll;
319
340
  const composing = this.mode === 'compose';
320
341
  const cursor = composing && this.blinkOn ? frame.cursor : null;
321
342
  this.term.paint(frame, size, cursor);
@@ -402,6 +423,7 @@ class Session {
402
423
  if (!result) return;
403
424
  if (result.kind === 'commit') this.commits.finishGitCommit();
404
425
  if (result.kind === 'branch') this.gitBranches.finishCreateBranch();
426
+ if (result.kind === 'npm') this.npm.finishEdit();
405
427
  }
406
428
 
407
429
  selectTemplate(index) {
package/lib/source.js CHANGED
@@ -1,8 +1,11 @@
1
1
  'use strict';
2
2
 
3
- const { parseGithubPrUrl } = require('./github.js');
4
- const { parseGitlabMrUrl } = require('./gitlab.js');
5
- const { capabilitiesFor, attachCapabilities } = require('./capabilities.js');
3
+ const github = require('./github.js');
4
+ const { parseGithubPrUrl } = github;
5
+ const gitlab = require('./gitlab.js');
6
+ const { parseGitlabMrUrl } = gitlab;
7
+ const capabilities = require('./capabilities.js');
8
+ const { capabilitiesFor, attachCapabilities } = capabilities;
6
9
 
7
10
  const selectChangeSource = (paths) => {
8
11
  if (!paths.length) return { kind: 'local', paths };
package/lib/update.js CHANGED
@@ -4,15 +4,11 @@ const fs = require('node:fs');
4
4
  const os = require('node:os');
5
5
  const path = require('node:path');
6
6
 
7
- const { jsonParse, isHashObject } = require('metautil');
8
- const {
9
- parseVersion,
10
- cmpVersion,
11
- npmBin,
12
- npmOpts,
13
- runProc,
14
- oneLine,
15
- } = require('./utilities.js');
7
+ const metautil = require('metautil');
8
+ const { jsonParse, isHashObject } = metautil;
9
+ const utilities = require('./utilities.js');
10
+ const { parseVersion, cmpVersion, npmBin } = utilities;
11
+ const { npmOpts, runProc, oneLine } = utilities;
16
12
 
17
13
  const PKG = require('../package.json');
18
14
 
package/lib/utilities.js CHANGED
@@ -1,7 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const { spawn, spawnSync } = require('node:child_process');
4
- const { split } = require('metautil');
3
+ const childProcess = require('node:child_process');
4
+ const { spawn, spawnSync } = childProcess;
5
+ const metautil = require('metautil');
6
+ const { split } = metautil;
5
7
 
6
8
  const IS_WIN = process.platform === 'win32';
7
9
  const DEFAULT_ENCODING = 'utf8';
package/lib/wrap.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const { graphemes, graphemeWidth, visibleWidth } = require('./ansi.js');
3
+ const ansi = require('./ansi.js');
4
+ const { graphemes, graphemeWidth, visibleWidth } = ansi;
4
5
 
5
6
  const wrapPlain = (text, width) => {
6
7
  if (width <= 0) return [''];
@@ -28,6 +29,7 @@ const wrapPlain = (text, width) => {
28
29
  if (col + w > width && col > 0) {
29
30
  if (lastBreak >= start) {
30
31
  flush(lastBreak + 1);
32
+ i = start;
31
33
  continue;
32
34
  }
33
35
  flush(i);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reslop",
3
- "version": "0.2.1",
3
+ "version": "0.2.4",
4
4
  "description": "Interactive code review and repair planning for AI-assisted changes",
5
5
  "keywords": [
6
6
  "code-review",
@@ -46,14 +46,14 @@
46
46
  "CHANGELOG.md"
47
47
  ],
48
48
  "engines": {
49
- "node": ">=18"
49
+ "node": ">=18.15.0"
50
50
  },
51
51
  "scripts": {
52
+ "test": "reslop t -- npm run -s lint && reslop t -- node --test",
53
+ "lint": "reslop t -- eslint . && reslop t -- prettier -c \"**/*.js\" \"**/*.json\" \"**/*.md\"",
54
+ "fix": "reslop t -- eslint . --fix && reslop t -- prettier --write \"**/*.js\" \"**/*.json\" \"**/*.md\"",
52
55
  "enable": "node scripts/enable.js",
53
- "disable": "node scripts/disable.js",
54
- "lint": "eslint . && prettier -c \"**/*.js\" \"**/*.json\" \"**/*.md\"",
55
- "fix": "eslint . --fix && prettier --write \"**/*.js\" \"**/*.json\" \"**/*.md\"",
56
- "test": "npm run -s lint && node --test"
56
+ "disable": "node scripts/disable.js"
57
57
  },
58
58
  "devDependencies": {
59
59
  "eslint": "^9.39.4",