reslop 0.2.7 → 0.3.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.
Files changed (158) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/README.md +16 -14
  3. package/bin/reslop.js +8 -5
  4. package/lib/agents/agents.js +504 -0
  5. package/lib/agents/allow.js +71 -0
  6. package/lib/agents/allow.json +16 -0
  7. package/lib/agents/models.js +460 -0
  8. package/lib/api.js +15 -12
  9. package/lib/cli.js +43 -68
  10. package/lib/{files.js → common/files.js} +48 -55
  11. package/lib/{find.js → common/find.js} +1 -1
  12. package/lib/common/format.js +101 -0
  13. package/lib/{utilities.js → common/process.js} +7 -95
  14. package/lib/common/tasks.json +27 -0
  15. package/lib/common/utilities.js +112 -0
  16. package/lib/dashboard/git.js +9 -16
  17. package/lib/dashboard/model.js +90 -49
  18. package/lib/dashboard/npm.js +17 -13
  19. package/lib/dashboard/tree.js +27 -30
  20. package/lib/{session → dashboard}/watch.js +36 -31
  21. package/lib/{workspace.js → dashboard/workspace.js} +23 -38
  22. package/lib/{deps.js → deps/deps.js} +31 -45
  23. package/lib/{deps-diff.js → deps/diff.js} +35 -25
  24. package/lib/{manifest.js → deps/manifest.js} +47 -30
  25. package/lib/diff/align.js +1 -2
  26. package/lib/diff/diff.js +2 -2
  27. package/lib/diff/display.js +29 -5
  28. package/lib/diff/inline.js +10 -14
  29. package/lib/diff/items.js +6 -4
  30. package/lib/diff/patch.js +39 -3
  31. package/lib/diff/unit.js +45 -16
  32. package/lib/{git-branches.js → git/branches.js} +53 -48
  33. package/lib/{git-deps.js → git/deps.js} +123 -96
  34. package/lib/git/git.js +71 -0
  35. package/lib/git/worktree.js +475 -0
  36. package/lib/highlight/bash.js +1 -2
  37. package/lib/highlight/csv.js +1 -2
  38. package/lib/highlight/dot.js +1 -2
  39. package/lib/{highlight.js → highlight/highlight.js} +42 -11
  40. package/lib/highlight/html.js +20 -18
  41. package/lib/highlight/json.js +1 -2
  42. package/lib/highlight/log.js +1 -2
  43. package/lib/highlight/txt.js +1 -2
  44. package/lib/{session → input}/actions.js +111 -48
  45. package/lib/{editor.js → input/editor.js} +7 -8
  46. package/lib/{keys.js → input/keys.js} +15 -43
  47. package/lib/input/line-edit.js +77 -0
  48. package/lib/input/menu-pick.js +70 -0
  49. package/lib/render/agents.js +640 -0
  50. package/lib/render/branches.js +4 -5
  51. package/lib/render/commits.js +54 -64
  52. package/lib/render/{dash-activity.js → dashboard/activity.js} +25 -40
  53. package/lib/render/{dash-blocks.js → dashboard/blocks.js} +131 -137
  54. package/lib/render/{dashboard.js → dashboard/dashboard.js} +25 -22
  55. package/lib/render/diff.js +166 -45
  56. package/lib/render/field.js +131 -0
  57. package/lib/render/files.js +9 -14
  58. package/lib/render/footer.js +383 -0
  59. package/lib/render/frame.js +123 -25
  60. package/lib/render/header.js +176 -0
  61. package/lib/render/log.js +319 -0
  62. package/lib/render/menu.js +60 -0
  63. package/lib/render/notes.js +16 -11
  64. package/lib/render/npm.js +322 -196
  65. package/lib/render/packages.js +9 -13
  66. package/lib/render/primitives.js +101 -15
  67. package/lib/render/render.js +7 -11
  68. package/lib/render/repos.js +13 -25
  69. package/lib/render/status.js +370 -0
  70. package/lib/render/status.json +85 -0
  71. package/lib/render/{dash-table.js → table.js} +13 -60
  72. package/lib/render/tiles.js +109 -48
  73. package/lib/render/unit.js +32 -13
  74. package/lib/{report-model.js → report/model.js} +4 -6
  75. package/lib/{report-parse.js → report/parse.js} +9 -14
  76. package/lib/{report-render.js → report/render.js} +46 -14
  77. package/lib/{report-run.js → report/run.js} +42 -30
  78. package/lib/{report-test.js → report/test.js} +56 -55
  79. package/lib/{report-tools.js → report/tools.js} +24 -33
  80. package/lib/review/agent-instructions.md +9 -0
  81. package/lib/review/format.js +426 -0
  82. package/lib/{review-merge.js → review/merge.js} +9 -8
  83. package/lib/review/review.js +190 -0
  84. package/lib/review/store.js +281 -0
  85. package/lib/review/templates.js +83 -0
  86. package/lib/runs/commands.js +14 -0
  87. package/lib/runs/logs.js +299 -0
  88. package/lib/runs/output.js +174 -0
  89. package/lib/runs/process.js +113 -0
  90. package/lib/{runs.js → runs/runs.js} +84 -36
  91. package/lib/runs/scripts.js +150 -0
  92. package/lib/session/agents/agents.js +958 -0
  93. package/lib/session/agents/job.js +320 -0
  94. package/lib/session/agents/jobs.js +355 -0
  95. package/lib/session/agents/options.js +153 -0
  96. package/lib/session/agents/plans.js +83 -0
  97. package/lib/session/branches.js +33 -39
  98. package/lib/session/change-actions.js +34 -100
  99. package/lib/session/commit.js +91 -52
  100. package/lib/session/compose.js +181 -145
  101. package/lib/session/dashboard.js +23 -22
  102. package/lib/session/dispatch.js +85 -21
  103. package/lib/session/files-pane.js +47 -26
  104. package/lib/session/find.js +16 -29
  105. package/lib/session/import.js +82 -0
  106. package/lib/session/items.js +8 -17
  107. package/lib/session/lifecycle.js +75 -72
  108. package/lib/session/load.js +2 -4
  109. package/lib/session/navigation.js +6 -3
  110. package/lib/session/npm/history.js +249 -0
  111. package/lib/session/npm/npm.js +815 -0
  112. package/lib/session/{packages.js → npm/packages.js} +21 -14
  113. package/lib/session/ops.js +125 -34
  114. package/lib/session/pointer.js +202 -10
  115. package/lib/session/prefs.js +112 -0
  116. package/lib/session/reads.js +109 -0
  117. package/lib/session/review.js +28 -10
  118. package/lib/session/run-panel.js +40 -0
  119. package/lib/{session.js → session/session.js} +156 -63
  120. package/lib/session/tasks.js +320 -65
  121. package/lib/session/templates.js +1 -1
  122. package/lib/session/terminal.js +94 -12
  123. package/lib/session/unit.js +35 -30
  124. package/lib/session/update.js +194 -6
  125. package/lib/session/view.js +65 -65
  126. package/lib/session/workspace.js +39 -78
  127. package/lib/{capabilities.js → source/capabilities.js} +3 -12
  128. package/lib/{github.js → source/github.js} +102 -32
  129. package/lib/{gitlab.js → source/gitlab.js} +87 -10
  130. package/lib/{remote.js → source/remote.js} +144 -40
  131. package/lib/source/review-threads.graphql +20 -0
  132. package/lib/source/source.js +74 -0
  133. package/lib/term/ansi.js +396 -0
  134. package/lib/{clipboard.js → term/clipboard.js} +3 -6
  135. package/lib/{select.js → term/select.js} +2 -2
  136. package/lib/term/themes/dark.json +122 -0
  137. package/lib/term/themes/light.json +122 -0
  138. package/lib/term/wide.txt +21 -0
  139. package/lib/{wrap.js → term/wrap.js} +4 -4
  140. package/package.json +2 -2
  141. package/lib/ansi.js +0 -545
  142. package/lib/detect.js +0 -34
  143. package/lib/diff/edit.js +0 -33
  144. package/lib/git-worktree.js +0 -455
  145. package/lib/git.js +0 -79
  146. package/lib/npm-commands.js +0 -522
  147. package/lib/render/chrome.js +0 -806
  148. package/lib/render/present.js +0 -19
  149. package/lib/render/report.js +0 -43
  150. package/lib/render/search.js +0 -25
  151. package/lib/review.js +0 -745
  152. package/lib/session/accessors.js +0 -26
  153. package/lib/session/edit-click.js +0 -57
  154. package/lib/session/npm.js +0 -452
  155. package/lib/session/progress.js +0 -41
  156. package/lib/source.js +0 -36
  157. package/lib/update.js +0 -192
  158. /package/lib/{git-reword-todo.js → git/reword-todo.js} +0 -0
@@ -1,11 +1,8 @@
1
1
  'use strict';
2
2
 
3
- const files = require('../files.js');
4
- const { isReadOnlyOrigin } = files;
5
- const actions = require('./actions.js');
6
- const { isFixupCommit } = actions;
7
- const ops = require('./ops.js');
8
- const { pickRepoWrite } = ops;
3
+ const { isReadOnlyOrigin } = require('../common/files.js');
4
+ const { saveUiPrefs } = require('./prefs.js');
5
+ const { isFixupCommit } = require('../input/actions.js');
9
6
  const commits = require('../render/commits.js');
10
7
  const { commitLine, commitText, splitMessage } = commits;
11
8
 
@@ -49,7 +46,7 @@ const fixupMessage = (entry) => {
49
46
  return `fixup! ${subject}`;
50
47
  };
51
48
 
52
- const hasStagedChanges = (ui) => {
49
+ const hasStagedChanges = async (ui) => {
53
50
  const repo = ui.repo;
54
51
  if (repo.hasStaged) return repo.hasStaged(ui.top);
55
52
  return ui.items.some((item) => item.origin === 'staged');
@@ -63,6 +60,7 @@ class CommitController {
63
60
 
64
61
  reset() {
65
62
  this.commits = [];
63
+ this.staged = false;
66
64
  this.dropName = '';
67
65
  this.dropSha = '';
68
66
  this.commitView = 'brief';
@@ -89,10 +87,11 @@ class CommitController {
89
87
  return listedCommits(this.commits)[this.ui.nav.commitCursor] ?? null;
90
88
  }
91
89
 
92
- loadCommits() {
90
+ async loadCommits() {
93
91
  const ui = this.ui;
94
92
  try {
95
- this.commits = ui.repo.listCommits(ui.top);
93
+ const reads = [ui.repo.listCommits(ui.top), hasStagedChanges(ui)];
94
+ [this.commits, this.staged] = await Promise.all(reads);
96
95
  return true;
97
96
  } catch (error) {
98
97
  ui.status = error.message;
@@ -100,21 +99,28 @@ class CommitController {
100
99
  }
101
100
  }
102
101
 
103
- refresh() {
104
- if (!this.ui.repo.listCommits || !this.loadCommits()) return;
102
+ async refresh() {
103
+ if (!this.ui.repo.listCommits) return;
104
+ const loaded = await this.loadCommits();
105
+ if (!loaded) return;
105
106
  const last = listedCommits(this.commits).length - 1;
106
107
  const nav = this.ui.nav;
107
108
  if (nav.commitCursor > last) nav.commitCursor = Math.max(0, last);
108
109
  }
109
110
 
111
+ reload() {
112
+ const ui = this.ui;
113
+ return ui.ops.track(this.refresh().then(() => ui.paint()));
114
+ }
115
+
110
116
  refreshAfterWrite(extra = {}) {
111
- this.refresh();
117
+ this.ui.ops.hold(this.refresh());
112
118
  this.ui.refreshFromRepo({ keepEmpty: true, ...extra });
113
119
  }
114
120
 
115
121
  indexForView() {
116
122
  const ui = this.ui;
117
- if (hasStagedChanges(ui)) return 0;
123
+ if (this.staged) return 0;
118
124
  const list = listedCommits(this.commits);
119
125
  const want = `${ui.rev ?? ''}`;
120
126
  const short = `${ui.revShort ?? ''}`;
@@ -137,7 +143,13 @@ class CommitController {
137
143
  ui.status = 'read only';
138
144
  return;
139
145
  }
140
- if (!this.loadCommits()) return;
146
+ ui.ops.hold(this.open());
147
+ }
148
+
149
+ async open() {
150
+ const ui = this.ui;
151
+ const loaded = await this.loadCommits();
152
+ if (!loaded) return;
141
153
  const nav = ui.nav;
142
154
  nav.commitCursor = this.indexForView();
143
155
  nav.pane = 'commits';
@@ -156,36 +168,48 @@ class CommitController {
156
168
  this.ui.status = '';
157
169
  }
158
170
 
159
- messageFor(kind) {
171
+ async stagedFor(kind) {
172
+ if (isInPlaceCommit(kind)) return true;
173
+ return hasStagedChanges(this.ui);
174
+ }
175
+
176
+ async messageFor(kind) {
160
177
  const ui = this.ui;
161
178
  if (kind === 'fixup') return fixupMessage(this.selected());
162
179
  if (kind === 'amend') {
163
180
  const headAt = this.commits.findIndex((entry) => entry.head);
164
181
  const at = headAt < 0 ? 0 : headAt;
165
182
  ui.nav.commitCursor = this.commits.length ? at + 1 : 0;
166
- if (ui.repo.lastMessage) return ui.repo.lastMessage(ui.top) ?? '';
167
- return '';
183
+ if (!ui.repo.lastMessage) return '';
184
+ const last = await ui.repo.lastMessage(ui.top);
185
+ return last ?? '';
168
186
  }
169
187
  if (kind === 'reword') {
170
188
  const entry = this.selected();
171
189
  if (!entry || !entry.sha) return null;
172
190
  if (!ui.repo.commitMessage) return commitText(entry);
173
- return ui.repo.commitMessage(ui.top, entry.sha) ?? '';
191
+ const message = await ui.repo.commitMessage(ui.top, entry.sha);
192
+ return message ?? '';
174
193
  }
175
194
  ui.nav.commitCursor = 0;
176
195
  return '';
177
196
  }
178
197
 
179
198
  start(kind) {
199
+ this.ui.ops.hold(this.compose(kind));
200
+ }
201
+
202
+ async compose(kind) {
180
203
  const ui = this.ui;
181
204
  const composer = ui.composer;
182
- if (!isInPlaceCommit(kind) && !hasStagedChanges(ui)) {
205
+ const staged = await this.stagedFor(kind);
206
+ if (!staged) {
183
207
  ui.mode = 'review';
184
208
  composer.commitKind = null;
185
209
  ui.status = 'nothing to commit';
186
210
  return;
187
211
  }
188
- let text = this.messageFor(kind);
212
+ let text = await this.messageFor(kind);
189
213
  if (text === null) return;
190
214
  composer.commitBody = '';
191
215
  if (isInPlaceCommit(kind) && this.brief) {
@@ -213,6 +237,7 @@ class CommitController {
213
237
 
214
238
  chooseCommit(kind) {
215
239
  this.ui.mode = 'review';
240
+ if (kind === 'update') return void this.onUpdate();
216
241
  if (kind === 'amend') {
217
242
  this.onAmend();
218
243
  return;
@@ -224,6 +249,33 @@ class CommitController {
224
249
  this.start('commit');
225
250
  }
226
251
 
252
+ onUpdate() {
253
+ if (!this.canWrite()) return;
254
+ const entry = this.selected();
255
+ if (!entry || !entry.sha) return;
256
+ this.ui.ops.hold(this.update(entry));
257
+ }
258
+
259
+ async update(entry) {
260
+ const staged = await hasStagedChanges(this.ui);
261
+ if (!staged) {
262
+ this.ui.status = 'nothing to commit';
263
+ return;
264
+ }
265
+ if (!this.ui.repo.updateCommit) {
266
+ this.ui.status = 'read only';
267
+ return;
268
+ }
269
+ const after = (extra) => this.refreshAfterWrite(extra);
270
+ this.ui.ops.runWrite(
271
+ 'updateCommit',
272
+ [entry.sha],
273
+ 'updating',
274
+ 'updated',
275
+ after,
276
+ );
277
+ }
278
+
227
279
  cancelCommitChoice() {
228
280
  this.ui.mode = 'review';
229
281
  }
@@ -287,9 +339,12 @@ class CommitController {
287
339
  );
288
340
  }
289
341
 
290
- runAsync(kind, done, run) {
342
+ submit(kind, done, run, settle = null) {
291
343
  this.ui.composer.closeCompose();
292
- const after = () => this.refreshAfterWrite({ doneStatus: done });
344
+ const after = () => {
345
+ if (settle) settle();
346
+ this.refreshAfterWrite({ doneStatus: done });
347
+ };
293
348
  this.ui.ops.runBusy(kind, done, run, after);
294
349
  }
295
350
 
@@ -301,20 +356,8 @@ class CommitController {
301
356
  return;
302
357
  }
303
358
  const done = COMMIT_STATUS.reword;
304
- const picked = pickRepoWrite(ui.repo, 'reword', ui.uiOpen);
305
- if (picked.async) {
306
- const run = (top) => picked.write(top, entry.sha, message);
307
- return void this.runAsync('rewording', done, run);
308
- }
309
- try {
310
- ui.repo.reword(ui.top, entry.sha, message);
311
- } catch (error) {
312
- ui.status = error.message;
313
- return;
314
- }
315
- ui.composer.closeCompose();
316
- this.refreshAfterWrite();
317
- if (!ui.status) ui.status = done;
359
+ const run = (top) => ui.repo.reword(top, entry.sha, message);
360
+ this.submit('rewording', done, run);
318
361
  }
319
362
 
320
363
  finishGitCommit() {
@@ -330,28 +373,22 @@ class CommitController {
330
373
  ui.status = 'empty commit message';
331
374
  return;
332
375
  }
333
- if (!isInPlaceCommit(kind) && !hasStagedChanges(ui)) {
376
+ ui.ops.hold(this.send(kind, message));
377
+ }
378
+
379
+ async send(kind, message) {
380
+ const ui = this.ui;
381
+ const staged = await this.stagedFor(kind);
382
+ if (!staged) {
334
383
  ui.composer.closeCompose();
335
384
  ui.status = 'nothing to commit';
336
385
  return;
337
386
  }
338
387
  if (kind === 'reword') return void this.finishReword(message);
339
388
  const done = COMMIT_STATUS[kind] ?? 'committed';
340
- const picked = pickRepoWrite(ui.repo, 'commit', ui.uiOpen);
341
- if (picked.async) {
342
- const run = (top) => picked.write(top, kind, message);
343
- return void this.runAsync('committing', done, run);
344
- }
345
- try {
346
- ui.repo.commit(ui.top, kind, message);
347
- } catch (error) {
348
- ui.status = error.message;
349
- return;
350
- }
351
- ui.composer.closeCompose();
352
- ui.collection.clearDismissed();
353
- this.refreshAfterWrite();
354
- if (!ui.done && !ui.pendingExtras) ui.status = done;
389
+ const run = (top) => ui.repo.commit(top, kind, message);
390
+ const settle = () => ui.collection.clearDismissed();
391
+ this.submit('committing', done, run, settle);
355
392
  }
356
393
 
357
394
  onDropCommit() {
@@ -391,6 +428,8 @@ class CommitController {
391
428
  this.commitView = this.brief ? 'full' : 'brief';
392
429
  this.ui.nav.listScroll = 0;
393
430
  this.ui.status = this.commitView;
431
+ const root = this.ui.top || this.ui.cwd;
432
+ saveUiPrefs(root, { commitView: this.commitView });
394
433
  }
395
434
  }
396
435