proofscan 0.10.53 → 0.10.55

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 (53) hide show
  1. package/dist/shell/filter-mappers.d.ts +23 -0
  2. package/dist/shell/filter-mappers.d.ts.map +1 -0
  3. package/dist/shell/filter-mappers.js +36 -0
  4. package/dist/shell/filter-mappers.js.map +1 -0
  5. package/dist/shell/find-command.d.ts +54 -0
  6. package/dist/shell/find-command.d.ts.map +1 -0
  7. package/dist/shell/find-command.js +330 -0
  8. package/dist/shell/find-command.js.map +1 -0
  9. package/dist/shell/pager/index.d.ts +9 -0
  10. package/dist/shell/pager/index.d.ts.map +1 -0
  11. package/dist/shell/pager/index.js +8 -0
  12. package/dist/shell/pager/index.js.map +1 -0
  13. package/dist/shell/pager/less-pager.d.ts +31 -0
  14. package/dist/shell/pager/less-pager.d.ts.map +1 -0
  15. package/dist/shell/pager/less-pager.js +196 -0
  16. package/dist/shell/pager/less-pager.js.map +1 -0
  17. package/dist/shell/pager/more-pager.d.ts +31 -0
  18. package/dist/shell/pager/more-pager.d.ts.map +1 -0
  19. package/dist/shell/pager/more-pager.js +108 -0
  20. package/dist/shell/pager/more-pager.js.map +1 -0
  21. package/dist/shell/pager/renderer.d.ts +17 -0
  22. package/dist/shell/pager/renderer.d.ts.map +1 -0
  23. package/dist/shell/pager/renderer.js +125 -0
  24. package/dist/shell/pager/renderer.js.map +1 -0
  25. package/dist/shell/pager/types.d.ts +19 -0
  26. package/dist/shell/pager/types.d.ts.map +1 -0
  27. package/dist/shell/pager/types.js +7 -0
  28. package/dist/shell/pager/types.js.map +1 -0
  29. package/dist/shell/pager/utils.d.ts +28 -0
  30. package/dist/shell/pager/utils.d.ts.map +1 -0
  31. package/dist/shell/pager/utils.js +53 -0
  32. package/dist/shell/pager/utils.js.map +1 -0
  33. package/dist/shell/pipeline-types.d.ts +51 -0
  34. package/dist/shell/pipeline-types.d.ts.map +1 -0
  35. package/dist/shell/pipeline-types.js +8 -0
  36. package/dist/shell/pipeline-types.js.map +1 -0
  37. package/dist/shell/repl.d.ts +36 -0
  38. package/dist/shell/repl.d.ts.map +1 -1
  39. package/dist/shell/repl.js +408 -5
  40. package/dist/shell/repl.js.map +1 -1
  41. package/dist/shell/router-commands.d.ts +7 -0
  42. package/dist/shell/router-commands.d.ts.map +1 -1
  43. package/dist/shell/router-commands.js +121 -0
  44. package/dist/shell/router-commands.js.map +1 -1
  45. package/dist/shell/types.d.ts +14 -0
  46. package/dist/shell/types.d.ts.map +1 -1
  47. package/dist/shell/types.js +16 -1
  48. package/dist/shell/types.js.map +1 -1
  49. package/dist/shell/where-command.d.ts +31 -0
  50. package/dist/shell/where-command.d.ts.map +1 -0
  51. package/dist/shell/where-command.js +96 -0
  52. package/dist/shell/where-command.js.map +1 -0
  53. package/package.json +1 -1
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Less Pager for psh Shell
3
+ *
4
+ * Delegates to external pager for reliable TTY handling.
5
+ * Pager selection priority:
6
+ * 1. $PAGER environment variable (user preference)
7
+ * 2. 'less' command
8
+ * 3. Built-in pager (fallback)
9
+ *
10
+ * Note: When using external pager, standard pager key bindings apply.
11
+ * The built-in fallback provides vim-style navigation (j/k/space/b/g/G/q).
12
+ */
13
+ import { renderRowsToLines } from './renderer.js';
14
+ import { commandExists, parsePagerCommand, runPager, FOOTER_RESERVE_LINES } from './utils.js';
15
+ export class LessPager {
16
+ options;
17
+ constructor(options) {
18
+ this.options = options ?? {};
19
+ }
20
+ async run(input) {
21
+ // TTY check - non-TTY outputs all lines without paging
22
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
23
+ const lines = renderRowsToLines(input, { useColor: false });
24
+ lines.forEach(line => console.log(line));
25
+ return;
26
+ }
27
+ const lines = renderRowsToLines(input, { useColor: true });
28
+ // If content fits in one page, just print and return
29
+ const terminalHeight = this.options.height ?? (process.stdout.rows || 24);
30
+ const pageSize = Math.max(1, terminalHeight - FOOTER_RESERVE_LINES);
31
+ if (lines.length <= pageSize) {
32
+ lines.forEach(line => console.log(line));
33
+ return;
34
+ }
35
+ // Try external pager (PAGER env -> less -> built-in)
36
+ const pagerResult = await this.tryExternalPager(lines);
37
+ if (!pagerResult) {
38
+ // All external pagers failed, use built-in
39
+ await this.runBuiltIn(lines, pageSize);
40
+ }
41
+ }
42
+ /**
43
+ * Try external pager in priority order
44
+ * Returns true if successful, false if all failed
45
+ */
46
+ async tryExternalPager(lines) {
47
+ const content = lines.join('\n') + '\n';
48
+ // 1. Try $PAGER environment variable (supports arguments like "less -R")
49
+ const pagerEnv = process.env.PAGER;
50
+ if (pagerEnv) {
51
+ const { cmd, args } = parsePagerCommand(pagerEnv);
52
+ if (commandExists(cmd)) {
53
+ try {
54
+ await runPager(cmd, args, content);
55
+ return true;
56
+ }
57
+ catch {
58
+ // $PAGER failed, continue to next option
59
+ }
60
+ }
61
+ }
62
+ // 2. Try 'less' with recommended options
63
+ // -F: quit if content fits one screen
64
+ // -R: interpret ANSI color codes
65
+ // -S: don't wrap long lines (preserves table layout)
66
+ // -X: don't clear screen on exit
67
+ if (commandExists('less')) {
68
+ try {
69
+ await runPager('less', ['-FRSX'], content);
70
+ return true;
71
+ }
72
+ catch {
73
+ // less failed, continue
74
+ }
75
+ }
76
+ // All external pagers failed
77
+ return false;
78
+ }
79
+ /**
80
+ * Built-in pager fallback
81
+ * Provides vim-style navigation when no external pager is available
82
+ */
83
+ async runBuiltIn(lines, pageSize) {
84
+ // Enable raw mode for key input
85
+ process.stdin.setRawMode(true);
86
+ process.stdin.resume();
87
+ // Hide cursor while in pager mode
88
+ process.stdout.write('\x1B[?25l');
89
+ try {
90
+ await this.runLoop(lines, pageSize);
91
+ }
92
+ finally {
93
+ // Show cursor again
94
+ process.stdout.write('\x1B[?25h');
95
+ // Restore raw mode
96
+ process.stdin.setRawMode(false);
97
+ }
98
+ }
99
+ async runLoop(lines, pageSize) {
100
+ let offset = 0;
101
+ return new Promise((resolve) => {
102
+ const render = () => {
103
+ // Clear screen and move cursor to top
104
+ process.stdout.write('\x1B[2J\x1B[H');
105
+ // Show visible lines
106
+ const visible = lines.slice(offset, offset + pageSize);
107
+ visible.forEach(line => console.log(line));
108
+ // Footer with position info
109
+ const start = offset + 1;
110
+ const end = Math.min(offset + pageSize, lines.length);
111
+ const position = `${start}-${end}/${lines.length}`;
112
+ process.stdout.write(`\x1b[2m-- psh pager -- ${position} | j/k scroll | space page | q quit\x1b[0m`);
113
+ };
114
+ const cleanup = () => {
115
+ process.stdin.removeListener('data', onKey);
116
+ // Show cursor and clear screen before returning to shell
117
+ process.stdout.write('\x1B[?25h\x1B[2J\x1B[H');
118
+ };
119
+ const maxOffset = Math.max(0, lines.length - pageSize);
120
+ const onKey = (key) => {
121
+ const ch = key.toString();
122
+ // Handle escape sequences (arrow keys, page up/down)
123
+ if (ch.startsWith('\x1B[')) {
124
+ switch (ch) {
125
+ case '\x1B[B': // Down arrow
126
+ if (offset < maxOffset) {
127
+ offset++;
128
+ }
129
+ render(); // Always re-render to clear any stray characters
130
+ break;
131
+ case '\x1B[A': // Up arrow
132
+ if (offset > 0) {
133
+ offset--;
134
+ }
135
+ render();
136
+ break;
137
+ case '\x1B[6~': // Page Down
138
+ offset = Math.min(offset + pageSize, maxOffset);
139
+ render();
140
+ break;
141
+ case '\x1B[5~': // Page Up
142
+ offset = Math.max(0, offset - pageSize);
143
+ render();
144
+ break;
145
+ default:
146
+ // Unknown escape sequence - re-render to clear
147
+ render();
148
+ }
149
+ return;
150
+ }
151
+ // Single character commands - always re-render to prevent stray chars
152
+ switch (ch) {
153
+ case 'q':
154
+ case '\x03': // Ctrl+C
155
+ cleanup();
156
+ resolve();
157
+ return; // Don't render after cleanup
158
+ case 'j': // Down
159
+ if (offset < maxOffset) {
160
+ offset++;
161
+ }
162
+ break;
163
+ case 'k': // Up
164
+ if (offset > 0) {
165
+ offset--;
166
+ }
167
+ break;
168
+ case ' ': // Page down
169
+ case 'f': // Forward (like less)
170
+ offset = Math.min(offset + pageSize, maxOffset);
171
+ break;
172
+ case 'b': // Page up / backward
173
+ offset = Math.max(0, offset - pageSize);
174
+ break;
175
+ case 'g': // First line
176
+ offset = 0;
177
+ break;
178
+ case 'G': // Last line
179
+ offset = maxOffset;
180
+ break;
181
+ case 'd': // Half page down (like vim)
182
+ offset = Math.min(offset + Math.floor(pageSize / 2), maxOffset);
183
+ break;
184
+ case 'u': // Half page up (like vim)
185
+ offset = Math.max(0, offset - Math.floor(pageSize / 2));
186
+ break;
187
+ }
188
+ // Re-render after any key to clear potential stray characters
189
+ render();
190
+ };
191
+ process.stdin.on('data', onKey);
192
+ render();
193
+ });
194
+ }
195
+ }
196
+ //# sourceMappingURL=less-pager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"less-pager.js","sourceRoot":"","sources":["../../../src/shell/pager/less-pager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE9F,MAAM,OAAO,SAAS;IACZ,OAAO,CAAe;IAE9B,YAAY,OAAsB;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAoB;QAC5B,uDAAuD;QACvD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5D,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3D,qDAAqD;QACrD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,oBAAoB,CAAC,CAAC;QAEpE,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC7B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,qDAAqD;QACrD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,2CAA2C;YAC3C,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,gBAAgB,CAAC,KAAe;QAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAExC,yEAAyE;QACzE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACnC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;oBACnC,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC;oBACP,yCAAyC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;QAED,yCAAyC;QACzC,sCAAsC;QACtC,iCAAiC;QACjC,qDAAqD;QACrD,iCAAiC;QACjC,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;YAC1B,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,UAAU,CAAC,KAAe,EAAE,QAAgB;QACxD,gCAAgC;QAChC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAEvB,kCAAkC;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAElC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC;gBAAS,CAAC;YACT,oBAAoB;YACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAElC,mBAAmB;YACnB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,KAAe,EAAE,QAAgB;QACrD,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,GAAG,EAAE;gBAClB,sCAAsC;gBACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;gBAEtC,qBAAqB;gBACrB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;gBACvD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;gBAE3C,4BAA4B;gBAC5B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC;gBACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBACtD,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,QAAQ,4CAA4C,CAAC,CAAC;YACvG,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,GAAG,EAAE;gBACnB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAC5C,yDAAyD;gBACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACjD,CAAC,CAAC;YAEF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;YAEvD,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,EAAE;gBAC5B,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;gBAE1B,qDAAqD;gBACrD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3B,QAAQ,EAAE,EAAE,CAAC;wBACX,KAAK,QAAQ,EAAE,aAAa;4BAC1B,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;gCACvB,MAAM,EAAE,CAAC;4BACX,CAAC;4BACD,MAAM,EAAE,CAAC,CAAC,iDAAiD;4BAC3D,MAAM;wBACR,KAAK,QAAQ,EAAE,WAAW;4BACxB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;gCACf,MAAM,EAAE,CAAC;4BACX,CAAC;4BACD,MAAM,EAAE,CAAC;4BACT,MAAM;wBACR,KAAK,SAAS,EAAE,YAAY;4BAC1B,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,QAAQ,EAAE,SAAS,CAAC,CAAC;4BAChD,MAAM,EAAE,CAAC;4BACT,MAAM;wBACR,KAAK,SAAS,EAAE,UAAU;4BACxB,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;4BACxC,MAAM,EAAE,CAAC;4BACT,MAAM;wBACR;4BACE,+CAA+C;4BAC/C,MAAM,EAAE,CAAC;oBACb,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,sEAAsE;gBACtE,QAAQ,EAAE,EAAE,CAAC;oBACX,KAAK,GAAG,CAAC;oBACT,KAAK,MAAM,EAAE,SAAS;wBACpB,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,CAAC;wBACV,OAAO,CAAC,6BAA6B;oBACvC,KAAK,GAAG,EAAE,OAAO;wBACf,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;4BACvB,MAAM,EAAE,CAAC;wBACX,CAAC;wBACD,MAAM;oBACR,KAAK,GAAG,EAAE,KAAK;wBACb,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;4BACf,MAAM,EAAE,CAAC;wBACX,CAAC;wBACD,MAAM;oBACR,KAAK,GAAG,CAAC,CAAC,YAAY;oBACtB,KAAK,GAAG,EAAE,sBAAsB;wBAC9B,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,QAAQ,EAAE,SAAS,CAAC,CAAC;wBAChD,MAAM;oBACR,KAAK,GAAG,EAAE,qBAAqB;wBAC7B,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;wBACxC,MAAM;oBACR,KAAK,GAAG,EAAE,aAAa;wBACrB,MAAM,GAAG,CAAC,CAAC;wBACX,MAAM;oBACR,KAAK,GAAG,EAAE,YAAY;wBACpB,MAAM,GAAG,SAAS,CAAC;wBACnB,MAAM;oBACR,KAAK,GAAG,EAAE,4BAA4B;wBACpC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;wBAChE,MAAM;oBACR,KAAK,GAAG,EAAE,0BAA0B;wBAClC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;wBACxD,MAAM;gBACV,CAAC;gBACD,8DAA8D;gBAC9D,MAAM,EAAE,CAAC;YACX,CAAC,CAAC;YAEF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAChC,MAAM,EAAE,CAAC;QACX,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * More Pager for psh Shell
3
+ *
4
+ * "Page-forward" mode pager that auto-exits at end of content.
5
+ * Uses 'less -E' for implementation (more feature-complete than system 'more').
6
+ *
7
+ * Pager selection priority:
8
+ * 1. 'less' with -E option (quit at EOF, like more)
9
+ * 2. Built-in pager (fallback)
10
+ *
11
+ * Note: When using external pager, standard pager key bindings apply.
12
+ */
13
+ import type { Pager, PagerOptions } from './types.js';
14
+ import type { PipelineValue } from '../pipeline-types.js';
15
+ export declare class MorePager implements Pager {
16
+ private options;
17
+ constructor(options?: PagerOptions);
18
+ run(input: PipelineValue): Promise<void>;
19
+ /**
20
+ * Try external pager
21
+ * Returns true if successful, false if failed
22
+ */
23
+ private tryExternalPager;
24
+ /**
25
+ * Built-in pager fallback
26
+ * Simple page-forward mode (no backward navigation)
27
+ */
28
+ private runBuiltIn;
29
+ private prompt;
30
+ }
31
+ //# sourceMappingURL=more-pager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"more-pager.d.ts","sourceRoot":"","sources":["../../../src/shell/pager/more-pager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,qBAAa,SAAU,YAAW,KAAK;IACrC,OAAO,CAAC,OAAO,CAAe;gBAElB,OAAO,CAAC,EAAE,YAAY;IAI5B,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B9C;;;OAGG;YACW,gBAAgB;IAoB9B;;;OAGG;YACW,UAAU;IAgBxB,OAAO,CAAC,MAAM;CA6Bf"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * More Pager for psh Shell
3
+ *
4
+ * "Page-forward" mode pager that auto-exits at end of content.
5
+ * Uses 'less -E' for implementation (more feature-complete than system 'more').
6
+ *
7
+ * Pager selection priority:
8
+ * 1. 'less' with -E option (quit at EOF, like more)
9
+ * 2. Built-in pager (fallback)
10
+ *
11
+ * Note: When using external pager, standard pager key bindings apply.
12
+ */
13
+ import { renderRowsToLines } from './renderer.js';
14
+ import { commandExists, runPager, FOOTER_RESERVE_LINES } from './utils.js';
15
+ export class MorePager {
16
+ options;
17
+ constructor(options) {
18
+ this.options = options ?? {};
19
+ }
20
+ async run(input) {
21
+ // TTY check - non-TTY outputs all lines without paging
22
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
23
+ const lines = renderRowsToLines(input, { useColor: false });
24
+ lines.forEach(line => console.log(line));
25
+ return;
26
+ }
27
+ const lines = renderRowsToLines(input, { useColor: true });
28
+ // If content fits in one page, just print and return
29
+ const terminalHeight = this.options.height ?? (process.stdout.rows || 24);
30
+ const pageSize = Math.max(1, terminalHeight - FOOTER_RESERVE_LINES);
31
+ if (lines.length <= pageSize) {
32
+ lines.forEach(line => console.log(line));
33
+ return;
34
+ }
35
+ // Try external pager (less -E -> built-in)
36
+ const pagerResult = await this.tryExternalPager(lines);
37
+ if (!pagerResult) {
38
+ // External pager failed, use built-in
39
+ await this.runBuiltIn(lines, pageSize);
40
+ }
41
+ }
42
+ /**
43
+ * Try external pager
44
+ * Returns true if successful, false if failed
45
+ */
46
+ async tryExternalPager(lines) {
47
+ const content = lines.join('\n') + '\n';
48
+ // Use 'less' with more-like options
49
+ // -E: quit at end of file (like more)
50
+ // -R: interpret ANSI color codes
51
+ // -S: don't wrap long lines (preserves table layout)
52
+ // -X: don't clear screen on exit
53
+ if (commandExists('less')) {
54
+ try {
55
+ await runPager('less', ['-ERSX'], content);
56
+ return true;
57
+ }
58
+ catch {
59
+ // less failed, continue to built-in
60
+ }
61
+ }
62
+ return false;
63
+ }
64
+ /**
65
+ * Built-in pager fallback
66
+ * Simple page-forward mode (no backward navigation)
67
+ */
68
+ async runBuiltIn(lines, pageSize) {
69
+ // Page through content
70
+ for (let i = 0; i < lines.length; i += pageSize) {
71
+ const page = lines.slice(i, i + pageSize);
72
+ page.forEach(line => console.log(line));
73
+ // Show prompt if there's more content
74
+ if (i + pageSize < lines.length) {
75
+ const shouldContinue = await this.prompt(i + pageSize, lines.length);
76
+ if (!shouldContinue) {
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ prompt(current, total) {
83
+ return new Promise((resolve) => {
84
+ // Show prompt
85
+ process.stdout.write(`\x1b[2m-- more (${current}/${total}) -- Enter/Space: next | q: quit\x1b[0m`);
86
+ // Enable raw mode for single key input
87
+ process.stdin.setRawMode(true);
88
+ process.stdin.resume();
89
+ const onKey = (key) => {
90
+ // Restore raw mode but do NOT pause stdin
91
+ // The shell's readline interface manages stdin and pausing would disrupt it
92
+ process.stdin.setRawMode(false);
93
+ process.stdin.removeListener('data', onKey);
94
+ // Clear the prompt line
95
+ process.stdout.write('\r\x1b[K');
96
+ const ch = key.toString();
97
+ if (ch === 'q' || ch === '\x03') { // q or Ctrl+C
98
+ resolve(false);
99
+ }
100
+ else {
101
+ resolve(true);
102
+ }
103
+ };
104
+ process.stdin.once('data', onKey);
105
+ });
106
+ }
107
+ }
108
+ //# sourceMappingURL=more-pager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"more-pager.js","sourceRoot":"","sources":["../../../src/shell/pager/more-pager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Pager Renderer
3
+ *
4
+ * Converts PipelineValue rows to string lines for pager display.
5
+ * Extracts and reuses table rendering logic from repl.ts.
6
+ */
7
+ import type { PipelineValue } from '../pipeline-types.js';
8
+ /** Render options */
9
+ export interface RenderOptions {
10
+ /** Use ANSI colors (default: auto-detect from TTY) */
11
+ useColor?: boolean;
12
+ }
13
+ /**
14
+ * Convert pipeline value to array of lines for pager display
15
+ */
16
+ export declare function renderRowsToLines(input: PipelineValue, options?: RenderOptions): string[];
17
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/shell/pager/renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAG9E,qBAAqB;AACrB,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,EAAE,CAoBV"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Pager Renderer
3
+ *
4
+ * Converts PipelineValue rows to string lines for pager display.
5
+ * Extracts and reuses table rendering logic from repl.ts.
6
+ */
7
+ import { shortenSessionId } from '../prompt.js';
8
+ /**
9
+ * Convert pipeline value to array of lines for pager display
10
+ */
11
+ export function renderRowsToLines(input, options) {
12
+ if (input.kind === 'text') {
13
+ return input.text.split('\n');
14
+ }
15
+ if (input.rows.length === 0) {
16
+ return ['No results'];
17
+ }
18
+ const useColor = options?.useColor ?? process.stdout.isTTY ?? false;
19
+ if (input.rowType === 'rpc') {
20
+ return renderRpcLines(input.rows, useColor);
21
+ }
22
+ else if (input.rowType === 'session') {
23
+ return renderSessionLines(input.rows, useColor);
24
+ }
25
+ else if (input.rowType === 'connector') {
26
+ return ['Connector rows not supported in pager'];
27
+ }
28
+ return ['Unknown row type'];
29
+ }
30
+ /**
31
+ * Render RPC rows to lines
32
+ */
33
+ function renderRpcLines(rows, useColor) {
34
+ const lines = [];
35
+ const dimText = (text) => useColor ? `\x1b[2m${text}\x1b[0m` : text;
36
+ const statusColor = (status) => {
37
+ if (!useColor)
38
+ return status;
39
+ switch (status) {
40
+ case 'OK': return '\x1b[32mOK\x1b[0m';
41
+ case 'ERR': return '\x1b[31mERR\x1b[0m';
42
+ default: return '\x1b[33mpending\x1b[0m';
43
+ }
44
+ };
45
+ // Check if rows have connector_id (find results have it, ls does not)
46
+ const hasConnector = rows.some(r => r.connector_id);
47
+ if (hasConnector) {
48
+ // Extended format for find results: Connector, Session, Method, Status, Latency, Time
49
+ lines.push(dimText('Connector'.padEnd(10)) + ' ' +
50
+ dimText('Session'.padEnd(10)) + ' ' +
51
+ dimText('Method'.padEnd(16)) + ' ' +
52
+ dimText('Status'.padEnd(useColor ? 16 : 8)) + ' ' +
53
+ dimText('Latency'.padEnd(8)) + ' ' +
54
+ dimText('Time'));
55
+ lines.push(dimText('-'.repeat(90)));
56
+ rows.forEach((row) => {
57
+ const connector = (row.connector_id ?? '').slice(0, 10).padEnd(10);
58
+ const sessionShort = shortenSessionId(row.session_id);
59
+ const method = row.method.slice(0, 16).padEnd(16);
60
+ const status = statusColor(row.status).padEnd(useColor ? 16 : 8);
61
+ const latency = (row.latency_ms !== null ? `${row.latency_ms}ms` : '-').padEnd(8);
62
+ // MM-DD HH:MM:SS format
63
+ const time = row.request_ts ? row.request_ts.slice(5, 19).replace('T', ' ') : '-';
64
+ lines.push(`${connector} ${sessionShort} ${method} ${status} ${latency} ${time}`);
65
+ });
66
+ }
67
+ else {
68
+ // Simple format for ls results (within a session)
69
+ lines.push(dimText('#'.padEnd(4)) + ' ' +
70
+ dimText('Method'.padEnd(20)) + ' ' +
71
+ dimText('Status'.padEnd(useColor ? 16 : 8)) + ' ' +
72
+ dimText('Latency'));
73
+ lines.push(dimText('-'.repeat(55)));
74
+ rows.forEach((row, idx) => {
75
+ const num = String(idx + 1).padEnd(4);
76
+ const method = row.method.slice(0, 20).padEnd(20);
77
+ const status = statusColor(row.status).padEnd(useColor ? 16 : 8);
78
+ const latency = row.latency_ms !== null ? `${row.latency_ms}ms` : '-';
79
+ lines.push(`${num} ${method} ${status} ${latency}`);
80
+ });
81
+ }
82
+ return lines;
83
+ }
84
+ /**
85
+ * Render Session rows to lines
86
+ */
87
+ function renderSessionLines(rows, useColor) {
88
+ const lines = [];
89
+ const dimText = (text) => useColor ? `\x1b[2m${text}\x1b[0m` : text;
90
+ // Check if rows span multiple connectors (find at root level)
91
+ const connectorIds = new Set(rows.map(r => r.connector_id));
92
+ const multiConnector = connectorIds.size > 1;
93
+ if (multiConnector) {
94
+ // Extended format with connector column
95
+ lines.push(dimText('Connector'.padEnd(12)) + ' ' +
96
+ dimText('Session'.padEnd(10)) + ' ' +
97
+ dimText('RPCs'.padEnd(6)) + ' ' +
98
+ dimText('Started'));
99
+ lines.push(dimText('-'.repeat(55)));
100
+ rows.forEach((row) => {
101
+ const connector = (row.connector_id ?? '').slice(0, 12).padEnd(12);
102
+ const sessionShort = shortenSessionId(row.session_id);
103
+ const rpcs = String(row.rpc_count).padEnd(6);
104
+ const started = row.started_at ? row.started_at.slice(0, 19).replace('T', ' ') : '-';
105
+ lines.push(`${connector} ${sessionShort} ${rpcs} ${started}`);
106
+ });
107
+ }
108
+ else {
109
+ // Simple format (within a connector)
110
+ lines.push(dimText('Session'.padEnd(10)) + ' ' +
111
+ dimText('RPCs'.padEnd(6)) + ' ' +
112
+ dimText('Events'.padEnd(8)) + ' ' +
113
+ dimText('Started'));
114
+ lines.push(dimText('-'.repeat(50)));
115
+ rows.forEach((row) => {
116
+ const sessionShort = shortenSessionId(row.session_id);
117
+ const rpcs = String(row.rpc_count).padEnd(6);
118
+ const events = String(row.event_count).padEnd(8);
119
+ const started = row.started_at ? row.started_at.slice(0, 19).replace('T', ' ') : '-';
120
+ lines.push(`${sessionShort} ${rpcs} ${events} ${started}`);
121
+ });
122
+ }
123
+ return lines;
124
+ }
125
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../../src/shell/pager/renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Pager Types for psh Shell
3
+ *
4
+ * Defines interfaces for pager implementations (less, more).
5
+ */
6
+ import type { PipelineValue } from '../pipeline-types.js';
7
+ /** Pager common interface */
8
+ export interface Pager {
9
+ /** Run pager with pipeline input */
10
+ run(input: PipelineValue): Promise<void>;
11
+ }
12
+ /** Pager options */
13
+ export interface PagerOptions {
14
+ /** Terminal width (default: process.stdout.columns) */
15
+ width?: number;
16
+ /** Terminal height (default: process.stdout.rows) */
17
+ height?: number;
18
+ }
19
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shell/pager/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,6BAA6B;AAC7B,MAAM,WAAW,KAAK;IACpB,oCAAoC;IACpC,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,oBAAoB;AACpB,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Pager Types for psh Shell
3
+ *
4
+ * Defines interfaces for pager implementations (less, more).
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/shell/pager/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Pager Utilities for psh Shell
3
+ *
4
+ * Common functionality shared between pager implementations.
5
+ */
6
+ /** Number of lines reserved for pager footer/prompt */
7
+ export declare const FOOTER_RESERVE_LINES = 2;
8
+ /**
9
+ * Check if a command exists on the system
10
+ * Cross-platform: uses 'where' on Windows, 'which' on Unix
11
+ */
12
+ export declare function commandExists(cmd: string): boolean;
13
+ /**
14
+ * Parse a pager command string that may include arguments
15
+ * e.g., "less -R" -> { cmd: "less", args: ["-R"] }
16
+ */
17
+ export declare function parsePagerCommand(pagerString: string): {
18
+ cmd: string;
19
+ args: string[];
20
+ };
21
+ /**
22
+ * Run a pager command with content
23
+ * @param cmd - Command to run
24
+ * @param args - Command arguments
25
+ * @param content - Content to pipe to pager
26
+ */
27
+ export declare function runPager(cmd: string, args: string[], content: string): Promise<void>;
28
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/shell/pager/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAMtF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBpF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Pager Utilities for psh Shell
3
+ *
4
+ * Common functionality shared between pager implementations.
5
+ */
6
+ import { spawn, spawnSync } from 'child_process';
7
+ /** Number of lines reserved for pager footer/prompt */
8
+ export const FOOTER_RESERVE_LINES = 2;
9
+ /**
10
+ * Check if a command exists on the system
11
+ * Cross-platform: uses 'where' on Windows, 'which' on Unix
12
+ */
13
+ export function commandExists(cmd) {
14
+ const command = process.platform === 'win32' ? 'where' : 'which';
15
+ const result = spawnSync(command, [cmd], { stdio: 'ignore' });
16
+ return result.status === 0;
17
+ }
18
+ /**
19
+ * Parse a pager command string that may include arguments
20
+ * e.g., "less -R" -> { cmd: "less", args: ["-R"] }
21
+ */
22
+ export function parsePagerCommand(pagerString) {
23
+ const parts = pagerString.trim().split(/\s+/);
24
+ return {
25
+ cmd: parts[0],
26
+ args: parts.slice(1),
27
+ };
28
+ }
29
+ /**
30
+ * Run a pager command with content
31
+ * @param cmd - Command to run
32
+ * @param args - Command arguments
33
+ * @param content - Content to pipe to pager
34
+ */
35
+ export function runPager(cmd, args, content) {
36
+ return new Promise((resolve, reject) => {
37
+ const pager = spawn(cmd, args, {
38
+ stdio: ['pipe', 'inherit', 'inherit'],
39
+ });
40
+ pager.on('error', reject);
41
+ pager.on('close', (code) => {
42
+ if (code === 0 || code === null) {
43
+ resolve();
44
+ }
45
+ else {
46
+ reject(new Error(`Pager exited with code ${code}`));
47
+ }
48
+ });
49
+ pager.stdin?.write(content);
50
+ pager.stdin?.end();
51
+ });
52
+ }
53
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/shell/pager/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEjD,uDAAuD;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACb,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;KACrB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAc,EAAE,OAAe;IACnE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;YAC7B,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC;SACtC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChC,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC"}