reslop 0.2.6 → 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 +27 -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 +61 -66
  10. package/lib/{files.js → common/files.js} +51 -52
  11. package/lib/common/find.js +61 -0
  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 +117 -51
  18. package/lib/dashboard/npm.js +133 -32
  19. package/lib/dashboard/tree.js +27 -30
  20. package/lib/{session → dashboard}/watch.js +41 -31
  21. package/lib/dashboard/workspace.js +151 -0
  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 -95
  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 +240 -71
  45. package/lib/{editor.js → input/editor.js} +7 -8
  46. package/lib/{keys.js → input/keys.js} +36 -39
  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/dashboard/blocks.js +490 -0
  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 +22 -8
  58. package/lib/render/footer.js +383 -0
  59. package/lib/render/frame.js +127 -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 +29 -13
  64. package/lib/render/npm.js +322 -196
  65. package/lib/render/packages.js +89 -0
  66. package/lib/render/primitives.js +109 -16
  67. package/lib/render/render.js +7 -11
  68. package/lib/render/repos.js +214 -0
  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} +19 -61
  72. package/lib/render/tiles.js +203 -47
  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 +36 -44
  98. package/lib/session/change-actions.js +34 -100
  99. package/lib/session/commit.js +122 -56
  100. package/lib/session/compose.js +197 -146
  101. package/lib/session/dashboard.js +183 -37
  102. package/lib/session/dispatch.js +120 -22
  103. package/lib/session/files-pane.js +60 -24
  104. package/lib/session/find.js +81 -0
  105. package/lib/session/import.js +82 -0
  106. package/lib/session/items.js +8 -17
  107. package/lib/session/lifecycle.js +96 -66
  108. package/lib/session/load.js +2 -4
  109. package/lib/session/navigation.js +8 -3
  110. package/lib/session/npm/history.js +249 -0
  111. package/lib/session/npm/npm.js +815 -0
  112. package/lib/session/npm/packages.js +150 -0
  113. package/lib/session/ops.js +125 -34
  114. package/lib/session/pointer.js +216 -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} +166 -59
  120. package/lib/session/tasks.js +321 -66
  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 +72 -59
  126. package/lib/session/workspace.js +416 -0
  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 -505
  142. package/lib/detect.js +0 -34
  143. package/lib/diff/edit.js +0 -33
  144. package/lib/git-worktree.js +0 -437
  145. package/lib/git.js +0 -79
  146. package/lib/npm-commands.js +0 -522
  147. package/lib/render/chrome.js +0 -628
  148. package/lib/render/dash-blocks.js +0 -245
  149. package/lib/render/present.js +0 -19
  150. package/lib/render/report.js +0 -43
  151. package/lib/review.js +0 -744
  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) {
@@ -200,19 +224,74 @@ class CommitController {
200
224
  editor.cursor = lineEnd < 0 ? editor.text.length : lineEnd;
201
225
  }
202
226
 
203
- onCommit() {
204
- if (this.ui.nav.pane !== 'commits') return void this.show();
205
- if (!this.canCommit()) return;
227
+ onInsert() {
228
+ const entry = this.selected();
229
+ if (!entry || entry.pending || !entry.sha) {
230
+ if (this.canCommit()) this.start('commit');
231
+ return;
232
+ }
233
+ if (!this.canWrite()) return;
234
+ this.ui.status = '';
235
+ this.ui.mode = 'confirmCommit';
236
+ }
237
+
238
+ chooseCommit(kind) {
239
+ this.ui.mode = 'review';
240
+ if (kind === 'update') return void this.onUpdate();
241
+ if (kind === 'amend') {
242
+ this.onAmend();
243
+ return;
244
+ }
245
+ if (kind === 'fixup') {
246
+ this.onFixup();
247
+ return;
248
+ }
206
249
  this.start('commit');
207
250
  }
208
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
+
279
+ cancelCommitChoice() {
280
+ this.ui.mode = 'review';
281
+ }
282
+
283
+ onCommit() {
284
+ if (this.ui.nav.pane === 'commits') return;
285
+ this.show();
286
+ }
287
+
209
288
  onShowDiff() {
210
289
  const ui = this.ui;
211
290
  if (ui.mode === 'compose') return;
212
291
  const entry = this.selected();
213
292
  if (!entry) return;
214
293
  const viewingCommit = Boolean(ui.rev || ui.revShort);
215
- if (entry.pending && !viewingCommit) return void this.onCommit();
294
+ if (entry.pending && !viewingCommit) return void this.onInsert();
216
295
  const sha = entry.pending ? '' : entry.sha || '';
217
296
  ui.rev = sha;
218
297
  ui.revShort = sha ? entry.shortSha || '' : '';
@@ -260,9 +339,12 @@ class CommitController {
260
339
  );
261
340
  }
262
341
 
263
- runAsync(kind, done, run) {
342
+ submit(kind, done, run, settle = null) {
264
343
  this.ui.composer.closeCompose();
265
- const after = () => this.refreshAfterWrite({ doneStatus: done });
344
+ const after = () => {
345
+ if (settle) settle();
346
+ this.refreshAfterWrite({ doneStatus: done });
347
+ };
266
348
  this.ui.ops.runBusy(kind, done, run, after);
267
349
  }
268
350
 
@@ -274,20 +356,8 @@ class CommitController {
274
356
  return;
275
357
  }
276
358
  const done = COMMIT_STATUS.reword;
277
- const picked = pickRepoWrite(ui.repo, 'reword', ui.uiOpen);
278
- if (picked.async) {
279
- const run = (top) => picked.write(top, entry.sha, message);
280
- return void this.runAsync('rewording', done, run);
281
- }
282
- try {
283
- ui.repo.reword(ui.top, entry.sha, message);
284
- } catch (error) {
285
- ui.status = error.message;
286
- return;
287
- }
288
- ui.composer.closeCompose();
289
- this.refreshAfterWrite();
290
- if (!ui.status) ui.status = done;
359
+ const run = (top) => ui.repo.reword(top, entry.sha, message);
360
+ this.submit('rewording', done, run);
291
361
  }
292
362
 
293
363
  finishGitCommit() {
@@ -303,28 +373,22 @@ class CommitController {
303
373
  ui.status = 'empty commit message';
304
374
  return;
305
375
  }
306
- 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) {
307
383
  ui.composer.closeCompose();
308
384
  ui.status = 'nothing to commit';
309
385
  return;
310
386
  }
311
387
  if (kind === 'reword') return void this.finishReword(message);
312
388
  const done = COMMIT_STATUS[kind] ?? 'committed';
313
- const picked = pickRepoWrite(ui.repo, 'commit', ui.uiOpen);
314
- if (picked.async) {
315
- const run = (top) => picked.write(top, kind, message);
316
- return void this.runAsync('committing', done, run);
317
- }
318
- try {
319
- ui.repo.commit(ui.top, kind, message);
320
- } catch (error) {
321
- ui.status = error.message;
322
- return;
323
- }
324
- ui.composer.closeCompose();
325
- ui.collection.clearDismissed();
326
- this.refreshAfterWrite();
327
- 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);
328
392
  }
329
393
 
330
394
  onDropCommit() {
@@ -364,6 +428,8 @@ class CommitController {
364
428
  this.commitView = this.brief ? 'full' : 'brief';
365
429
  this.ui.nav.listScroll = 0;
366
430
  this.ui.status = this.commitView;
431
+ const root = this.ui.top || this.ui.cwd;
432
+ saveUiPrefs(root, { commitView: this.commitView });
367
433
  }
368
434
  }
369
435