@fnndsc/chell 4.2.8

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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +325 -0
  3. package/dist/builtins/debug.d.ts +6 -0
  4. package/dist/builtins/debug.js +47 -0
  5. package/dist/builtins/debug.js.map +1 -0
  6. package/dist/builtins/executable.d.ts +22 -0
  7. package/dist/builtins/executable.js +115 -0
  8. package/dist/builtins/executable.js.map +1 -0
  9. package/dist/builtins/fs/cat.d.ts +16 -0
  10. package/dist/builtins/fs/cat.js +249 -0
  11. package/dist/builtins/fs/cat.js.map +1 -0
  12. package/dist/builtins/fs/cd.d.ts +41 -0
  13. package/dist/builtins/fs/cd.js +178 -0
  14. package/dist/builtins/fs/cd.js.map +1 -0
  15. package/dist/builtins/fs/cp.d.ts +7 -0
  16. package/dist/builtins/fs/cp.js +73 -0
  17. package/dist/builtins/fs/cp.js.map +1 -0
  18. package/dist/builtins/fs/download.d.ts +6 -0
  19. package/dist/builtins/fs/download.js +41 -0
  20. package/dist/builtins/fs/download.js.map +1 -0
  21. package/dist/builtins/fs/du.d.ts +58 -0
  22. package/dist/builtins/fs/du.js +210 -0
  23. package/dist/builtins/fs/du.js.map +1 -0
  24. package/dist/builtins/fs/edit.d.ts +7 -0
  25. package/dist/builtins/fs/edit.js +86 -0
  26. package/dist/builtins/fs/edit.js.map +1 -0
  27. package/dist/builtins/fs/ls.d.ts +8 -0
  28. package/dist/builtins/fs/ls.js +68 -0
  29. package/dist/builtins/fs/ls.js.map +1 -0
  30. package/dist/builtins/fs/mkdir.d.ts +6 -0
  31. package/dist/builtins/fs/mkdir.js +38 -0
  32. package/dist/builtins/fs/mkdir.js.map +1 -0
  33. package/dist/builtins/fs/mv.d.ts +7 -0
  34. package/dist/builtins/fs/mv.js +75 -0
  35. package/dist/builtins/fs/mv.js.map +1 -0
  36. package/dist/builtins/fs/pull.args.d.ts +22 -0
  37. package/dist/builtins/fs/pull.args.js +30 -0
  38. package/dist/builtins/fs/pull.args.js.map +1 -0
  39. package/dist/builtins/fs/pull.d.ts +26 -0
  40. package/dist/builtins/fs/pull.js +413 -0
  41. package/dist/builtins/fs/pull.js.map +1 -0
  42. package/dist/builtins/fs/pwd.d.ts +7 -0
  43. package/dist/builtins/fs/pwd.js +75 -0
  44. package/dist/builtins/fs/pwd.js.map +1 -0
  45. package/dist/builtins/fs/rm.d.ts +31 -0
  46. package/dist/builtins/fs/rm.js +148 -0
  47. package/dist/builtins/fs/rm.js.map +1 -0
  48. package/dist/builtins/fs/touch.d.ts +6 -0
  49. package/dist/builtins/fs/touch.js +64 -0
  50. package/dist/builtins/fs/touch.js.map +1 -0
  51. package/dist/builtins/fs/tree.d.ts +15 -0
  52. package/dist/builtins/fs/tree.js +84 -0
  53. package/dist/builtins/fs/tree.js.map +1 -0
  54. package/dist/builtins/fs/upload.d.ts +6 -0
  55. package/dist/builtins/fs/upload.js +45 -0
  56. package/dist/builtins/fs/upload.js.map +1 -0
  57. package/dist/builtins/help.d.ts +74 -0
  58. package/dist/builtins/help.js +1217 -0
  59. package/dist/builtins/help.js.map +1 -0
  60. package/dist/builtins/index.d.ts +45 -0
  61. package/dist/builtins/index.js +45 -0
  62. package/dist/builtins/index.js.map +1 -0
  63. package/dist/builtins/net/connect.d.ts +7 -0
  64. package/dist/builtins/net/connect.js +42 -0
  65. package/dist/builtins/net/connect.js.map +1 -0
  66. package/dist/builtins/net/cubepath.d.ts +18 -0
  67. package/dist/builtins/net/cubepath.js +102 -0
  68. package/dist/builtins/net/cubepath.js.map +1 -0
  69. package/dist/builtins/net/logout.d.ts +6 -0
  70. package/dist/builtins/net/logout.js +24 -0
  71. package/dist/builtins/net/logout.js.map +1 -0
  72. package/dist/builtins/net/pacs.d.ts +24 -0
  73. package/dist/builtins/net/pacs.js +121 -0
  74. package/dist/builtins/net/pacs.js.map +1 -0
  75. package/dist/builtins/net/pacsUtils.d.ts +85 -0
  76. package/dist/builtins/net/pacsUtils.js +184 -0
  77. package/dist/builtins/net/pacsUtils.js.map +1 -0
  78. package/dist/builtins/net/query.d.ts +60 -0
  79. package/dist/builtins/net/query.js +304 -0
  80. package/dist/builtins/net/query.js.map +1 -0
  81. package/dist/builtins/parametersofplugin.d.ts +13 -0
  82. package/dist/builtins/parametersofplugin.js +43 -0
  83. package/dist/builtins/parametersofplugin.js.map +1 -0
  84. package/dist/builtins/pluginExecute.d.ts +27 -0
  85. package/dist/builtins/pluginExecute.js +165 -0
  86. package/dist/builtins/pluginExecute.js.map +1 -0
  87. package/dist/builtins/proc.d.ts +6 -0
  88. package/dist/builtins/proc.helpers.d.ts +68 -0
  89. package/dist/builtins/proc.helpers.js +102 -0
  90. package/dist/builtins/proc.helpers.js.map +1 -0
  91. package/dist/builtins/proc.js +289 -0
  92. package/dist/builtins/proc.js.map +1 -0
  93. package/dist/builtins/res/compute.d.ts +6 -0
  94. package/dist/builtins/res/compute.js +55 -0
  95. package/dist/builtins/res/compute.js.map +1 -0
  96. package/dist/builtins/res/feed.d.ts +6 -0
  97. package/dist/builtins/res/feed.js +244 -0
  98. package/dist/builtins/res/feed.js.map +1 -0
  99. package/dist/builtins/res/feed.notes.d.ts +28 -0
  100. package/dist/builtins/res/feed.notes.js +24 -0
  101. package/dist/builtins/res/feed.notes.js.map +1 -0
  102. package/dist/builtins/res/files.d.ts +18 -0
  103. package/dist/builtins/res/files.js +85 -0
  104. package/dist/builtins/res/files.js.map +1 -0
  105. package/dist/builtins/res/group.d.ts +6 -0
  106. package/dist/builtins/res/group.js +54 -0
  107. package/dist/builtins/res/group.js.map +1 -0
  108. package/dist/builtins/res/pipeline.args.d.ts +22 -0
  109. package/dist/builtins/res/pipeline.args.js +28 -0
  110. package/dist/builtins/res/pipeline.args.js.map +1 -0
  111. package/dist/builtins/res/pipeline.d.ts +20 -0
  112. package/dist/builtins/res/pipeline.js +252 -0
  113. package/dist/builtins/res/pipeline.js.map +1 -0
  114. package/dist/builtins/res/plugin.d.ts +13 -0
  115. package/dist/builtins/res/plugin.js +140 -0
  116. package/dist/builtins/res/plugin.js.map +1 -0
  117. package/dist/builtins/res/plugininstance.d.ts +6 -0
  118. package/dist/builtins/res/plugininstance.js +53 -0
  119. package/dist/builtins/res/plugininstance.js.map +1 -0
  120. package/dist/builtins/res/pluginmeta.d.ts +6 -0
  121. package/dist/builtins/res/pluginmeta.js +53 -0
  122. package/dist/builtins/res/pluginmeta.js.map +1 -0
  123. package/dist/builtins/res/tag.d.ts +6 -0
  124. package/dist/builtins/res/tag.js +53 -0
  125. package/dist/builtins/res/tag.js.map +1 -0
  126. package/dist/builtins/res/workflow.d.ts +6 -0
  127. package/dist/builtins/res/workflow.js +53 -0
  128. package/dist/builtins/res/workflow.js.map +1 -0
  129. package/dist/builtins/store.d.ts +6 -0
  130. package/dist/builtins/store.js +108 -0
  131. package/dist/builtins/store.js.map +1 -0
  132. package/dist/builtins/sys/context.d.ts +6 -0
  133. package/dist/builtins/sys/context.js +50 -0
  134. package/dist/builtins/sys/context.js.map +1 -0
  135. package/dist/builtins/sys/physicalmode.d.ts +6 -0
  136. package/dist/builtins/sys/physicalmode.js +41 -0
  137. package/dist/builtins/sys/physicalmode.js.map +1 -0
  138. package/dist/builtins/sys/prompt.d.ts +13 -0
  139. package/dist/builtins/sys/prompt.helpers.d.ts +31 -0
  140. package/dist/builtins/sys/prompt.helpers.js +36 -0
  141. package/dist/builtins/sys/prompt.helpers.js.map +1 -0
  142. package/dist/builtins/sys/prompt.js +182 -0
  143. package/dist/builtins/sys/prompt.js.map +1 -0
  144. package/dist/builtins/sys/timing.d.ts +6 -0
  145. package/dist/builtins/sys/timing.js +41 -0
  146. package/dist/builtins/sys/timing.js.map +1 -0
  147. package/dist/builtins/sys/whoami.d.ts +12 -0
  148. package/dist/builtins/sys/whoami.js +37 -0
  149. package/dist/builtins/sys/whoami.js.map +1 -0
  150. package/dist/builtins/utils.d.ts +55 -0
  151. package/dist/builtins/utils.js +145 -0
  152. package/dist/builtins/utils.js.map +1 -0
  153. package/dist/builtins/wildcard.d.ts +26 -0
  154. package/dist/builtins/wildcard.js +120 -0
  155. package/dist/builtins/wildcard.js.map +1 -0
  156. package/dist/chell.d.ts +16 -0
  157. package/dist/chell.js +1193 -0
  158. package/dist/chell.js.map +1 -0
  159. package/dist/command-keys.d.ts +8 -0
  160. package/dist/command-keys.js +32 -0
  161. package/dist/command-keys.js.map +1 -0
  162. package/dist/config/settings.d.ts +39 -0
  163. package/dist/config/settings.js +93 -0
  164. package/dist/config/settings.js.map +1 -0
  165. package/dist/core/bootFlags.d.ts +32 -0
  166. package/dist/core/bootFlags.js +25 -0
  167. package/dist/core/bootFlags.js.map +1 -0
  168. package/dist/core/cli.d.ts +58 -0
  169. package/dist/core/cli.js +251 -0
  170. package/dist/core/cli.js.map +1 -0
  171. package/dist/core/prompt/index.d.ts +80 -0
  172. package/dist/core/prompt/index.js +29 -0
  173. package/dist/core/prompt/index.js.map +1 -0
  174. package/dist/core/prompt/theme_default.d.ts +19 -0
  175. package/dist/core/prompt/theme_default.js +47 -0
  176. package/dist/core/prompt/theme_default.js.map +1 -0
  177. package/dist/core/prompt/theme_p10k.d.ts +22 -0
  178. package/dist/core/prompt/theme_p10k.js +164 -0
  179. package/dist/core/prompt/theme_p10k.js.map +1 -0
  180. package/dist/core/prompt/utils.d.ts +23 -0
  181. package/dist/core/prompt/utils.js +40 -0
  182. package/dist/core/prompt/utils.js.map +1 -0
  183. package/dist/core/question.d.ts +34 -0
  184. package/dist/core/question.js +76 -0
  185. package/dist/core/question.js.map +1 -0
  186. package/dist/core/repl.d.ts +31 -0
  187. package/dist/core/repl.js +146 -0
  188. package/dist/core/repl.js.map +1 -0
  189. package/dist/index.d.ts +7 -0
  190. package/dist/index.js +34 -0
  191. package/dist/index.js.map +1 -0
  192. package/dist/lib/bootsequence.d.ts +62 -0
  193. package/dist/lib/bootsequence.js +222 -0
  194. package/dist/lib/bootsequence.js.map +1 -0
  195. package/dist/lib/completer/index.d.ts +15 -0
  196. package/dist/lib/completer/index.js +212 -0
  197. package/dist/lib/completer/index.js.map +1 -0
  198. package/dist/lib/completer/pathComplete.helpers.d.ts +22 -0
  199. package/dist/lib/completer/pathComplete.helpers.js +49 -0
  200. package/dist/lib/completer/pathComplete.helpers.js.map +1 -0
  201. package/dist/lib/logo.d.ts +47 -0
  202. package/dist/lib/logo.js +313 -0
  203. package/dist/lib/logo.js.map +1 -0
  204. package/dist/lib/parser.d.ts +13 -0
  205. package/dist/lib/parser.js +52 -0
  206. package/dist/lib/parser.js.map +1 -0
  207. package/dist/lib/pipe.d.ts +11 -0
  208. package/dist/lib/pipe.js +90 -0
  209. package/dist/lib/pipe.js.map +1 -0
  210. package/dist/lib/prefetch.d.ts +25 -0
  211. package/dist/lib/prefetch.js +64 -0
  212. package/dist/lib/prefetch.js.map +1 -0
  213. package/dist/lib/semicolonParser.d.ts +22 -0
  214. package/dist/lib/semicolonParser.js +53 -0
  215. package/dist/lib/semicolonParser.js.map +1 -0
  216. package/dist/lib/spinner.d.ts +23 -0
  217. package/dist/lib/spinner.js +68 -0
  218. package/dist/lib/spinner.js.map +1 -0
  219. package/dist/lib/vfs/providers/static.d.ts +65 -0
  220. package/dist/lib/vfs/providers/static.js +164 -0
  221. package/dist/lib/vfs/providers/static.js.map +1 -0
  222. package/dist/lib/vfs/providers/static_content.d.ts +27 -0
  223. package/dist/lib/vfs/providers/static_content.js +180 -0
  224. package/dist/lib/vfs/providers/static_content.js.map +1 -0
  225. package/dist/lib/vfs/vfs.d.ts +59 -0
  226. package/dist/lib/vfs/vfs.js +198 -0
  227. package/dist/lib/vfs/vfs.js.map +1 -0
  228. package/dist/session/index.d.ts +76 -0
  229. package/dist/session/index.js +120 -0
  230. package/dist/session/index.js.map +1 -0
  231. package/package.json +65 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * @file Builtin cat command.
3
+ * Displays file contents.
4
+ */
5
+ import chalk from 'chalk';
6
+ import { path_resolve, error_stripDebugPrefix } from '../utils.js';
7
+ import { files_cat as chefs_cat_cmd, files_catBinary as chefs_catBinary_cmd } from '@fnndsc/chili/commands/fs/cat.js';
8
+ import { cat_render } from '@fnndsc/chili/views/fs.js';
9
+ import { errorStack } from '@fnndsc/cumin';
10
+ import * as path from 'path';
11
+ /** File extensions that receive syntax highlighting. */
12
+ const HIGHLIGHT_EXTENSIONS = new Set(['.json', '.yaml', '.yml']);
13
+ /**
14
+ * Applies chalk-based syntax highlighting to JSON content.
15
+ * Returns the original string if the content is not valid JSON.
16
+ *
17
+ * @param content - Raw JSON string.
18
+ * @returns Highlighted string, or original on parse failure.
19
+ */
20
+ function json_highlight(content) {
21
+ try {
22
+ JSON.parse(content);
23
+ }
24
+ catch {
25
+ return content;
26
+ }
27
+ return content.replace(/("(?:\\u[0-9a-fA-F]{4}|\\[^u]|[^\\"])*"(\s*:)?|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, (match) => {
28
+ if (match.endsWith(':'))
29
+ return chalk.cyan(match); // key
30
+ if (match.startsWith('"'))
31
+ return chalk.green(match); // string value
32
+ if (match === 'true' || match === 'false')
33
+ return chalk.yellow(match);
34
+ if (match === 'null')
35
+ return chalk.gray(match);
36
+ return chalk.magenta(match); // number
37
+ });
38
+ }
39
+ /**
40
+ * Applies chalk-based syntax highlighting to YAML content line by line.
41
+ *
42
+ * @param content - Raw YAML string.
43
+ * @returns Highlighted string.
44
+ */
45
+ function yaml_highlight(content) {
46
+ return content.split('\n').map((line) => {
47
+ if (/^\s*#/.test(line))
48
+ return chalk.gray(line);
49
+ const kv = line.match(/^(\s*)([\w./-]+)(\s*:\s*)(.*)/);
50
+ if (kv) {
51
+ const [, indent, key, sep, value] = kv;
52
+ const coloredValue = value_yamlColor(value);
53
+ return `${indent}${chalk.cyan(key)}${chalk.gray(sep)}${coloredValue}`;
54
+ }
55
+ const listItem = line.match(/^(\s*-\s+)(.*)/);
56
+ if (listItem) {
57
+ return `${chalk.gray(listItem[1])}${chalk.green(listItem[2])}`;
58
+ }
59
+ return line;
60
+ }).join('\n');
61
+ }
62
+ /**
63
+ * Colors a scalar YAML value based on its type.
64
+ *
65
+ * @param value - The raw value string from a YAML key: value line.
66
+ * @returns Chalk-colored value string.
67
+ */
68
+ function value_yamlColor(value) {
69
+ if (!value)
70
+ return value;
71
+ if (value === 'true' || value === 'false')
72
+ return chalk.yellow(value);
73
+ if (value === 'null' || value === '~')
74
+ return chalk.gray(value);
75
+ if (/^-?\d+(\.\d+)?$/.test(value))
76
+ return chalk.magenta(value);
77
+ if (/^["']/.test(value))
78
+ return chalk.green(value);
79
+ return chalk.white(value);
80
+ }
81
+ /**
82
+ * Applies syntax highlighting to text content based on file extension.
83
+ * Returns the original string unchanged when stdout is not a TTY (piping).
84
+ *
85
+ * @param content - File content string.
86
+ * @param filePath - Full path used to determine the file type.
87
+ * @returns Highlighted or original content.
88
+ */
89
+ function content_highlight(content, filePath) {
90
+ if (!process.stdout.isTTY)
91
+ return content;
92
+ const ext = path.extname(filePath).toLowerCase();
93
+ if (ext === '.json')
94
+ return json_highlight(content);
95
+ if (ext === '.yaml' || ext === '.yml')
96
+ return yaml_highlight(content);
97
+ return content;
98
+ }
99
+ /**
100
+ * List of file extensions that are considered binary.
101
+ */
102
+ const BINARY_EXTENSIONS = new Set([
103
+ '.dcm', // DICOM medical images
104
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.webp', // Images
105
+ '.pdf', // Documents
106
+ '.zip', '.tar', '.gz', '.bz2', '.xz', '.7z', '.rar', // Archives
107
+ '.exe', '.dll', '.so', '.dylib', '.bin', // Executables/Libraries
108
+ '.mp3', '.mp4', '.avi', '.mov', '.wav', '.flac', // Media
109
+ ]);
110
+ /**
111
+ * Checks if a file path has a binary extension.
112
+ *
113
+ * @param filePath - The file path to check.
114
+ * @returns True if the file has a binary extension.
115
+ */
116
+ function extension_isBinary(filePath) {
117
+ const ext = path.extname(filePath).toLowerCase();
118
+ return BINARY_EXTENSIONS.has(ext);
119
+ }
120
+ /**
121
+ * Writes a buffer to stdout with proper backpressure handling.
122
+ *
123
+ * Splits large buffers into 64KB chunks and waits for drain events when the
124
+ * output buffer is full. This prevents data loss when piping large binary files
125
+ * to external commands. Waits for all data to be flushed before resolving.
126
+ *
127
+ * @param buffer - The buffer to write to stdout.
128
+ * @returns A Promise that resolves when all data has been written and flushed.
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const dicomData: Buffer = await fetchDicomFile();
133
+ * await buffer_writeToStdout(dicomData);
134
+ * ```
135
+ */
136
+ async function buffer_writeToStdout(buffer) {
137
+ return new Promise((resolve, reject) => {
138
+ if (buffer.length === 0) {
139
+ resolve();
140
+ return;
141
+ }
142
+ let offset = 0;
143
+ const chunkSize = 64 * 1024; // 64KB chunks
144
+ /**
145
+ * Recursively writes the next chunk of data to stdout.
146
+ * Handles backpressure by waiting for drain events when buffer is full.
147
+ */
148
+ const chunk_writeNext = () => {
149
+ try {
150
+ while (offset < buffer.length) {
151
+ const end = Math.min(offset + chunkSize, buffer.length);
152
+ const chunk = buffer.subarray(offset, end);
153
+ offset = end;
154
+ const canContinue = process.stdout.write(chunk);
155
+ if (!canContinue) {
156
+ // Buffer is full, wait for drain event
157
+ process.stdout.once('drain', chunk_writeNext);
158
+ return;
159
+ }
160
+ }
161
+ // All chunks written - ensure stdout is flushed before resolving
162
+ // Writing an empty string forces a flush check. If write() returns false,
163
+ // the buffer is full and we must wait for drain. This prevents truncation
164
+ // when piping to external processes, as Node.js won't exit until we resolve.
165
+ if (process.stdout.write('')) {
166
+ // Buffer has space, all data is flushed
167
+ resolve();
168
+ }
169
+ else {
170
+ // Buffer is full, wait for final drain before resolving
171
+ process.stdout.once('drain', () => resolve());
172
+ }
173
+ }
174
+ catch (err) {
175
+ reject(err);
176
+ }
177
+ };
178
+ chunk_writeNext();
179
+ });
180
+ }
181
+ /**
182
+ * Displays the content of one or more files.
183
+ *
184
+ * Supports multiple files and concatenates their output. Binary mode is applied
185
+ * consistently to all files if any file is detected as binary or --binary is specified.
186
+ *
187
+ * @param args - Command line arguments (file paths and optional --binary flag).
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * await builtin_cat(['file1.txt', 'file2.txt']);
192
+ * await builtin_cat(['--binary', 'image.dcm']);
193
+ * await builtin_cat(['*.json']); // After wildcard expansion
194
+ * ```
195
+ */
196
+ export async function builtin_cat(args) {
197
+ let binaryMode = false;
198
+ const filePaths = [];
199
+ for (const arg of args) {
200
+ if (arg === '--binary') {
201
+ binaryMode = true;
202
+ }
203
+ else {
204
+ filePaths.push(arg);
205
+ }
206
+ }
207
+ if (filePaths.length === 0) {
208
+ console.error(chalk.red('Usage: cat [--binary] <file> [file...]'));
209
+ return;
210
+ }
211
+ for (let i = 0; i < filePaths.length; i++) {
212
+ const pathArg = filePaths[i];
213
+ const target = await path_resolve(pathArg);
214
+ // Auto-detect binary files
215
+ const isBinaryFile = extension_isBinary(target);
216
+ // Inform user about auto-detection only if in interactive mode (stdout is TTY)
217
+ // Don't show warning when piping, as it would corrupt the binary output
218
+ // Only show on first file to avoid spam
219
+ if (i === 0 && isBinaryFile && !binaryMode && process.stdout.isTTY) {
220
+ console.error(chalk.cyan(`Info: ${pathArg} detected as binary file (${path.extname(target)}), using binary mode.`));
221
+ console.error(chalk.cyan('Tip: Use "cat --binary <file>" to explicitly request binary mode.'));
222
+ console.error('');
223
+ }
224
+ // Use binary mode if requested OR if file is detected as binary
225
+ if (binaryMode || isBinaryFile) {
226
+ const result = await chefs_catBinary_cmd(target);
227
+ if (!result.ok) {
228
+ const error = errorStack.stack_pop();
229
+ console.error(chalk.red(`cat: ${pathArg}: ${error ? error_stripDebugPrefix(error.message) : 'Unknown error'}`));
230
+ process.exitCode = 1;
231
+ continue;
232
+ }
233
+ // Output raw buffer to stdout with backpressure handling
234
+ await buffer_writeToStdout(result.value);
235
+ }
236
+ else {
237
+ const result = await chefs_cat_cmd(target);
238
+ if (!result.ok) {
239
+ const error = errorStack.stack_pop();
240
+ console.error(chalk.red(`cat: ${pathArg}: ${error ? error_stripDebugPrefix(error.message) : 'Unknown error'}`));
241
+ process.exitCode = 1;
242
+ continue;
243
+ }
244
+ const highlighted = content_highlight(result.value, target);
245
+ console.log(cat_render(highlighted, pathArg));
246
+ }
247
+ }
248
+ }
249
+ //# sourceMappingURL=cat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cat.js","sourceRoot":"","sources":["../../../src/builtins/fs/cat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Interface representing a FileBrowserFolder from ChRIS API.
3
+ */
4
+ interface FileBrowserFolder {
5
+ path?: string;
6
+ data?: {
7
+ path?: string;
8
+ };
9
+ }
10
+ /**
11
+ * Normalizes a logical path for VFS comparison by stripping a single trailing
12
+ * slash (except for the root path).
13
+ *
14
+ * @param logicalPath - The resolved logical path.
15
+ * @returns The normalized path.
16
+ */
17
+ export declare function vfsPath_normalize(logicalPath: string): string;
18
+ /**
19
+ * Reports whether a path is a structural VFS container (always valid).
20
+ *
21
+ * @param cleanPath - The normalized path.
22
+ * @returns True if the path is a known structural VFS container.
23
+ */
24
+ export declare function vfsPath_isStructural(cleanPath: string): boolean;
25
+ /**
26
+ * Verifies if a given FileBrowserFolder object exactly matches the validation path.
27
+ *
28
+ * @param folder - The FileBrowserFolder object to verify.
29
+ * @param validationPath - The path to match against.
30
+ * @returns True if the folder path exactly matches validationPath, false otherwise.
31
+ */
32
+ export declare function folder_verifyPathMatch(folder: FileBrowserFolder | null | undefined, validationPath: string): boolean;
33
+ /**
34
+ * Changes the current working directory in the ChRIS filesystem context.
35
+ * Validates the existence of the target path before setting it.
36
+ *
37
+ * @param args - An array containing the target path as the first element.
38
+ * @returns A Promise that resolves when the operation is complete.
39
+ */
40
+ export declare function builtin_cd(args: string[]): Promise<void>;
41
+ export {};
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @file Builtin cd command.
3
+ * Changes the current working directory.
4
+ */
5
+ import chalk from 'chalk';
6
+ import { session } from '../../session/index.js';
7
+ import { path_resolve, path_resolveLinks, error_stripDebugPrefix } from '../utils.js';
8
+ /**
9
+ * Structural VFS container paths that exist by definition and need no API
10
+ * validation when `cd`-ing into them.
11
+ */
12
+ const STRUCTURAL_VFS_PATHS = ['/', '/net', '/net/pacs', '/net/pacs/queries', '/proc', '/proc/jobs'];
13
+ /**
14
+ * Normalizes a logical path for VFS comparison by stripping a single trailing
15
+ * slash (except for the root path).
16
+ *
17
+ * @param logicalPath - The resolved logical path.
18
+ * @returns The normalized path.
19
+ */
20
+ export function vfsPath_normalize(logicalPath) {
21
+ return logicalPath.endsWith('/') && logicalPath.length > 1 ? logicalPath.slice(0, -1) : logicalPath;
22
+ }
23
+ /**
24
+ * Reports whether a path is a structural VFS container (always valid).
25
+ *
26
+ * @param cleanPath - The normalized path.
27
+ * @returns True if the path is a known structural VFS container.
28
+ */
29
+ export function vfsPath_isStructural(cleanPath) {
30
+ return STRUCTURAL_VFS_PATHS.includes(cleanPath);
31
+ }
32
+ /**
33
+ * Verifies if a given FileBrowserFolder object exactly matches the validation path.
34
+ *
35
+ * @param folder - The FileBrowserFolder object to verify.
36
+ * @param validationPath - The path to match against.
37
+ * @returns True if the folder path exactly matches validationPath, false otherwise.
38
+ */
39
+ export function folder_verifyPathMatch(folder, validationPath) {
40
+ if (!folder) {
41
+ return false;
42
+ }
43
+ const folderPath = folder.data?.path || folder.path || '';
44
+ // Normalize both by removing all leading and trailing slashes to be robust against API inconsistencies
45
+ const cleanFolder = folderPath.replace(/^\/+|\/+$/g, '');
46
+ const cleanValidation = validationPath.replace(/^\/+|\/+$/g, '');
47
+ return cleanFolder === cleanValidation;
48
+ }
49
+ /**
50
+ * Handles `cd` into a virtual (VFS) path: structural containers are accepted
51
+ * directly, deeper VFS paths are validated and their listing cached.
52
+ *
53
+ * @param cleanPath - The normalized virtual path.
54
+ * @param pathArg - The original user-supplied path (for error messages).
55
+ */
56
+ async function cdVirtual_handle(cleanPath, pathArg) {
57
+ if (vfsPath_isStructural(cleanPath)) {
58
+ await session.setCWD(cleanPath);
59
+ return;
60
+ }
61
+ // For deeper VFS paths (e.g. /net/pacs/queries/<id>), validate and cache the
62
+ // result so a subsequent `ls` doesn't need to re-fetch.
63
+ const { vfsDispatcher } = await import('@fnndsc/salsa');
64
+ const listResult = await vfsDispatcher.list(cleanPath);
65
+ if (!listResult.ok) {
66
+ const { errorStack } = await import('@fnndsc/cumin');
67
+ const lastError = errorStack.stack_pop();
68
+ const detail = lastError ? error_stripDebugPrefix(lastError.message) : 'No such file or directory';
69
+ console.error(chalk.red(`cd: ${pathArg}: ${detail}`));
70
+ return;
71
+ }
72
+ const { listCache_get } = await import('@fnndsc/cumin');
73
+ listCache_get().cache_set(cleanPath, listResult.value);
74
+ await session.setCWD(cleanPath);
75
+ }
76
+ /**
77
+ * Handles `cd` into a real (API-backed) ChRIS folder: resolves the validation
78
+ * path, then confirms the folder exists with an exact path match before setting
79
+ * the working directory.
80
+ *
81
+ * @param logicalPath - The resolved logical path.
82
+ * @param pathArg - The original user-supplied path (for error messages).
83
+ */
84
+ async function cdReal_handle(logicalPath, pathArg) {
85
+ const client = await session.connection.client_get();
86
+ if (!client) {
87
+ console.error(chalk.red('Not connected to ChRIS.'));
88
+ return;
89
+ }
90
+ let validationPath;
91
+ if (session.physicalMode_get()) {
92
+ validationPath = await path_resolveLinks(logicalPath);
93
+ }
94
+ else {
95
+ const { logical_toPhysical } = await import('@fnndsc/chili/utils');
96
+ const physicalResult = await logical_toPhysical(logicalPath);
97
+ if (!physicalResult.ok) {
98
+ console.error(chalk.red(`cd: ${pathArg}: No such file or directory`));
99
+ if (session.connection.config?.debug) {
100
+ console.error(chalk.gray(` Logical path: ${logicalPath}`));
101
+ }
102
+ return;
103
+ }
104
+ validationPath = physicalResult.value;
105
+ }
106
+ if (session.connection.config?.debug) {
107
+ console.log(chalk.gray(`cd: ${pathArg} → logical: ${logicalPath} → validation: ${validationPath}`));
108
+ }
109
+ const cwdPath = session.physicalMode_get() ? validationPath : logicalPath;
110
+ const currentCwd = await session.getCWD();
111
+ if (currentCwd === cwdPath) {
112
+ if (session.connection.config?.debug) {
113
+ console.log(chalk.gray(` Already in target directory, skipping validation`));
114
+ }
115
+ return;
116
+ }
117
+ try {
118
+ const folder = (await client.getFileBrowserFolderByPath(validationPath));
119
+ if (folder_verifyPathMatch(folder, validationPath)) {
120
+ await session.setCWD(cwdPath);
121
+ }
122
+ else {
123
+ console.error(chalk.red(`cd: ${pathArg}: No such file or directory`));
124
+ if (session.connection.config?.debug) {
125
+ if (!folder) {
126
+ console.error(chalk.gray(` API returned null for path: ${validationPath}`));
127
+ }
128
+ else {
129
+ const folderPath = folder.data?.path || folder.path;
130
+ console.error(chalk.gray(` API returned mismatched folder path: ${folderPath} (expected: ${validationPath})`));
131
+ }
132
+ }
133
+ }
134
+ }
135
+ catch (apiError) {
136
+ console.error(chalk.red(`cd: ${pathArg}: No such file or directory`));
137
+ if (session.connection.config?.debug) {
138
+ const msg = apiError instanceof Error ? apiError.message : String(apiError);
139
+ console.error(chalk.gray(` API error: ${msg}`));
140
+ }
141
+ }
142
+ }
143
+ /**
144
+ * Changes the current working directory in the ChRIS filesystem context.
145
+ * Validates the existence of the target path before setting it.
146
+ *
147
+ * @param args - An array containing the target path as the first element.
148
+ * @returns A Promise that resolves when the operation is complete.
149
+ */
150
+ export async function builtin_cd(args) {
151
+ const pathArg = args.length > 0 ? args.join(' ') : undefined;
152
+ // 'cd' with no args goes to home
153
+ if (!pathArg) {
154
+ return builtin_cd(['~']);
155
+ }
156
+ try {
157
+ const logicalPath = await path_resolve(pathArg);
158
+ const { vfsDispatcher } = await import('@fnndsc/salsa');
159
+ const cleanPath = vfsPath_normalize(logicalPath);
160
+ // Treat the path as virtual if it is, or is a parent of, any registered
161
+ // provider prefix (e.g. /proc is parent of /proc/feeds).
162
+ const isParentOfVfs = vfsDispatcher.providers_get().some((p) => p.prefix.startsWith(cleanPath + '/'));
163
+ const isVirtual = cleanPath === '/' ||
164
+ cleanPath === '/net' ||
165
+ isParentOfVfs ||
166
+ vfsDispatcher.provider_get(cleanPath).prefix !== '';
167
+ if (isVirtual) {
168
+ await cdVirtual_handle(cleanPath, pathArg);
169
+ return;
170
+ }
171
+ await cdReal_handle(logicalPath, pathArg);
172
+ }
173
+ catch (error) {
174
+ const msg = error instanceof Error ? error.message : String(error);
175
+ console.error(chalk.red(`Failed to cd: ${msg}`));
176
+ }
177
+ }
178
+ //# sourceMappingURL=cd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cd.js","sourceRoot":"","sources":["../../../src/builtins/fs/cd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copies a file or directory.
3
+ * Supports multiple sources when destination is a directory.
4
+ *
5
+ * @param args - [flags, src1, src2, ..., dest]
6
+ */
7
+ export declare function builtin_cp(args: string[]): Promise<void>;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @file Builtin cp command.
3
+ * Copies files or directories.
4
+ */
5
+ import chalk from 'chalk';
6
+ import path from 'path';
7
+ import { commandArgs_process, path_resolve } from '../utils.js';
8
+ import { files_cp as chefs_cp_cmd } from '@fnndsc/chili/commands/fs/cp.js';
9
+ import { cp_render } from '@fnndsc/chili/views/fs.js';
10
+ import { listCache_get } from '@fnndsc/cumin';
11
+ /**
12
+ * Copies a file or directory.
13
+ * Supports multiple sources when destination is a directory.
14
+ *
15
+ * @param args - [flags, src1, src2, ..., dest]
16
+ */
17
+ export async function builtin_cp(args) {
18
+ const parsed = commandArgs_process(args);
19
+ const pathArgs = parsed._;
20
+ if (pathArgs.length < 2) {
21
+ console.log(chalk.red('Usage: cp [-r] <source...> <dest>'));
22
+ return;
23
+ }
24
+ const recursive = !!parsed['r'] || !!parsed['recursive'];
25
+ // Last arg is destination, all others are sources
26
+ const dest = pathArgs[pathArgs.length - 1];
27
+ const sources = pathArgs.slice(0, -1);
28
+ const destPath = await path_resolve(dest);
29
+ const listCache = listCache_get();
30
+ let successCount = 0;
31
+ let failCount = 0;
32
+ for (const src of sources) {
33
+ try {
34
+ const srcPath = await path_resolve(src);
35
+ // For multiple sources, show which file we're copying
36
+ if (sources.length > 1) {
37
+ console.log(chalk.gray(`Copying ${srcPath}...`));
38
+ }
39
+ else {
40
+ console.log(`Copying ${srcPath} to ${destPath}...`);
41
+ }
42
+ const success = await chefs_cp_cmd(srcPath, destPath, { recursive });
43
+ if (sources.length === 1) {
44
+ console.log(cp_render(srcPath, destPath, success));
45
+ }
46
+ if (success) {
47
+ successCount++;
48
+ }
49
+ else {
50
+ failCount++;
51
+ }
52
+ }
53
+ catch (e) {
54
+ const msg = e instanceof Error ? e.message : String(e);
55
+ console.error(chalk.red(`cp: ${src}: ${msg}`));
56
+ failCount++;
57
+ }
58
+ }
59
+ // Invalidate destination directory (always, since files copied into it)
60
+ listCache.cache_invalidate(destPath);
61
+ const destParent = path.posix.dirname(destPath);
62
+ listCache.cache_invalidate(destParent);
63
+ // Summary for multiple files
64
+ if (sources.length > 1) {
65
+ if (failCount === 0) {
66
+ console.log(chalk.green(`✓ Copied ${successCount} file(s) to ${destPath}`));
67
+ }
68
+ else {
69
+ console.log(chalk.yellow(`⚠ Copied ${successCount} file(s), ${failCount} failed`));
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=cp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cp.js","sourceRoot":"","sources":["../../../src/builtins/fs/cp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Downloads a remote ChRIS file or directory to the local filesystem.
3
+ *
4
+ * @param args - [remotePath, localPath] plus optional -f/--force to overwrite.
5
+ */
6
+ export declare function builtin_download(args: string[]): Promise<void>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @file Builtin download command.
3
+ * Downloads files from ChRIS to the local filesystem with progress.
4
+ */
5
+ import chalk from 'chalk';
6
+ import path from 'path';
7
+ import { path_resolve } from '../utils.js';
8
+ import { files_downloadWithProgress as chefs_download_cmd, bytes_format } from '@fnndsc/chili/commands/fs/download.js';
9
+ /**
10
+ * Downloads a remote ChRIS file or directory to the local filesystem.
11
+ *
12
+ * @param args - [remotePath, localPath] plus optional -f/--force to overwrite.
13
+ */
14
+ export async function builtin_download(args) {
15
+ const force = args.includes('-f') || args.includes('--force');
16
+ const cleanArgs = args.filter(arg => arg !== '-f' && arg !== '--force');
17
+ if (cleanArgs.length < 2) {
18
+ console.log(chalk.red('Usage: download <remote_path> <local_path> [-f|--force]'));
19
+ return;
20
+ }
21
+ const remotePathArg = cleanArgs[0];
22
+ const localPathArg = cleanArgs[1];
23
+ const targetRemote = await path_resolve(remotePathArg);
24
+ const targetLocal = path.resolve(localPathArg);
25
+ try {
26
+ const summary = await chefs_download_cmd(targetRemote, targetLocal, { force });
27
+ console.log('');
28
+ if (summary.failedCount === 0) {
29
+ console.log(chalk.green(`✓ Successfully downloaded ${summary.transferredCount} file(s)`));
30
+ }
31
+ else {
32
+ console.log(chalk.yellow(`⚠ Downloaded ${summary.transferredCount} file(s), ${summary.failedCount} failed`));
33
+ }
34
+ console.log(chalk.gray(` Total: ${bytes_format(summary.transferSize)} in ${summary.duration.toFixed(1)}s (${bytes_format(summary.speed)}/s)`));
35
+ }
36
+ catch (e) {
37
+ const msg = e instanceof Error ? e.message : String(e);
38
+ console.error(chalk.red(`Download error: ${msg}`));
39
+ }
40
+ }
41
+ //# sourceMappingURL=download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/builtins/fs/download.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,0BAA0B,IAAI,kBAAkB,EAEhD,YAAY,EACb,MAAM,uCAAuC,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAc;IACnD,MAAM,KAAK,GAAY,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACvE,MAAM,SAAS,GAAa,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,CAAC,CAAC;IAElF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC,CAAC;QAClF,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAW,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAW,SAAS,CAAC,CAAC,CAAC,CAAC;IAE1C,MAAM,YAAY,GAAW,MAAM,YAAY,CAAC,aAAa,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAW,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,OAAO,GAAoB,MAAM,kBAAkB,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,IAAI,OAAO,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,6BAA6B,OAAO,CAAC,gBAAgB,UAAU,CAAC,CAAC,CAAC;QAC5F,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,OAAO,CAAC,gBAAgB,aAAa,OAAO,CAAC,WAAW,SAAS,CAAC,CAAC,CAAC;QAC/G,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAClJ,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,MAAM,GAAG,GAAW,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC"}