@fnndsc/brasa 0.1.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 (226) hide show
  1. package/dist/builtins/debug.d.ts +8 -0
  2. package/dist/builtins/debug.js +39 -0
  3. package/dist/builtins/debug.js.map +1 -0
  4. package/dist/builtins/executable.d.ts +22 -0
  5. package/dist/builtins/executable.js +115 -0
  6. package/dist/builtins/executable.js.map +1 -0
  7. package/dist/builtins/fs/cat.d.ts +16 -0
  8. package/dist/builtins/fs/cat.js +266 -0
  9. package/dist/builtins/fs/cat.js.map +1 -0
  10. package/dist/builtins/fs/cd.d.ts +42 -0
  11. package/dist/builtins/fs/cd.js +193 -0
  12. package/dist/builtins/fs/cd.js.map +1 -0
  13. package/dist/builtins/fs/cp.d.ts +10 -0
  14. package/dist/builtins/fs/cp.js +86 -0
  15. package/dist/builtins/fs/cp.js.map +1 -0
  16. package/dist/builtins/fs/download.d.ts +6 -0
  17. package/dist/builtins/fs/download.js +45 -0
  18. package/dist/builtins/fs/download.js.map +1 -0
  19. package/dist/builtins/fs/du.d.ts +58 -0
  20. package/dist/builtins/fs/du.js +210 -0
  21. package/dist/builtins/fs/du.js.map +1 -0
  22. package/dist/builtins/fs/edit.d.ts +7 -0
  23. package/dist/builtins/fs/edit.js +104 -0
  24. package/dist/builtins/fs/edit.js.map +1 -0
  25. package/dist/builtins/fs/ls.d.ts +8 -0
  26. package/dist/builtins/fs/ls.js +68 -0
  27. package/dist/builtins/fs/ls.js.map +1 -0
  28. package/dist/builtins/fs/mkdir.d.ts +9 -0
  29. package/dist/builtins/fs/mkdir.js +52 -0
  30. package/dist/builtins/fs/mkdir.js.map +1 -0
  31. package/dist/builtins/fs/mv.d.ts +10 -0
  32. package/dist/builtins/fs/mv.js +88 -0
  33. package/dist/builtins/fs/mv.js.map +1 -0
  34. package/dist/builtins/fs/pull.args.d.ts +22 -0
  35. package/dist/builtins/fs/pull.args.js +30 -0
  36. package/dist/builtins/fs/pull.args.js.map +1 -0
  37. package/dist/builtins/fs/pull.d.ts +26 -0
  38. package/dist/builtins/fs/pull.js +445 -0
  39. package/dist/builtins/fs/pull.js.map +1 -0
  40. package/dist/builtins/fs/pwd.d.ts +10 -0
  41. package/dist/builtins/fs/pwd.js +73 -0
  42. package/dist/builtins/fs/pwd.js.map +1 -0
  43. package/dist/builtins/fs/rm.d.ts +37 -0
  44. package/dist/builtins/fs/rm.js +197 -0
  45. package/dist/builtins/fs/rm.js.map +1 -0
  46. package/dist/builtins/fs/touch.d.ts +9 -0
  47. package/dist/builtins/fs/touch.js +76 -0
  48. package/dist/builtins/fs/touch.js.map +1 -0
  49. package/dist/builtins/fs/tree.d.ts +15 -0
  50. package/dist/builtins/fs/tree.js +84 -0
  51. package/dist/builtins/fs/tree.js.map +1 -0
  52. package/dist/builtins/fs/upload.d.ts +6 -0
  53. package/dist/builtins/fs/upload.js +48 -0
  54. package/dist/builtins/fs/upload.js.map +1 -0
  55. package/dist/builtins/help.d.ts +74 -0
  56. package/dist/builtins/help.js +1217 -0
  57. package/dist/builtins/help.js.map +1 -0
  58. package/dist/builtins/index.d.ts +45 -0
  59. package/dist/builtins/index.js +45 -0
  60. package/dist/builtins/index.js.map +1 -0
  61. package/dist/builtins/net/connect.d.ts +7 -0
  62. package/dist/builtins/net/connect.js +42 -0
  63. package/dist/builtins/net/connect.js.map +1 -0
  64. package/dist/builtins/net/cubepath.d.ts +18 -0
  65. package/dist/builtins/net/cubepath.js +102 -0
  66. package/dist/builtins/net/cubepath.js.map +1 -0
  67. package/dist/builtins/net/logout.d.ts +6 -0
  68. package/dist/builtins/net/logout.js +24 -0
  69. package/dist/builtins/net/logout.js.map +1 -0
  70. package/dist/builtins/net/pacs.d.ts +24 -0
  71. package/dist/builtins/net/pacs.js +121 -0
  72. package/dist/builtins/net/pacs.js.map +1 -0
  73. package/dist/builtins/net/pacsUtils.d.ts +85 -0
  74. package/dist/builtins/net/pacsUtils.js +184 -0
  75. package/dist/builtins/net/pacsUtils.js.map +1 -0
  76. package/dist/builtins/net/query.d.ts +60 -0
  77. package/dist/builtins/net/query.js +324 -0
  78. package/dist/builtins/net/query.js.map +1 -0
  79. package/dist/builtins/parametersofplugin.d.ts +13 -0
  80. package/dist/builtins/parametersofplugin.js +43 -0
  81. package/dist/builtins/parametersofplugin.js.map +1 -0
  82. package/dist/builtins/pluginExecute.d.ts +27 -0
  83. package/dist/builtins/pluginExecute.js +165 -0
  84. package/dist/builtins/pluginExecute.js.map +1 -0
  85. package/dist/builtins/proc.d.ts +6 -0
  86. package/dist/builtins/proc.helpers.d.ts +68 -0
  87. package/dist/builtins/proc.helpers.js +102 -0
  88. package/dist/builtins/proc.helpers.js.map +1 -0
  89. package/dist/builtins/proc.js +289 -0
  90. package/dist/builtins/proc.js.map +1 -0
  91. package/dist/builtins/res/compute.d.ts +6 -0
  92. package/dist/builtins/res/compute.js +55 -0
  93. package/dist/builtins/res/compute.js.map +1 -0
  94. package/dist/builtins/res/feed.d.ts +6 -0
  95. package/dist/builtins/res/feed.js +244 -0
  96. package/dist/builtins/res/feed.js.map +1 -0
  97. package/dist/builtins/res/feed.notes.d.ts +28 -0
  98. package/dist/builtins/res/feed.notes.js +24 -0
  99. package/dist/builtins/res/feed.notes.js.map +1 -0
  100. package/dist/builtins/res/files.d.ts +18 -0
  101. package/dist/builtins/res/files.js +85 -0
  102. package/dist/builtins/res/files.js.map +1 -0
  103. package/dist/builtins/res/group.d.ts +6 -0
  104. package/dist/builtins/res/group.js +54 -0
  105. package/dist/builtins/res/group.js.map +1 -0
  106. package/dist/builtins/res/pipeline.args.d.ts +22 -0
  107. package/dist/builtins/res/pipeline.args.js +28 -0
  108. package/dist/builtins/res/pipeline.args.js.map +1 -0
  109. package/dist/builtins/res/pipeline.d.ts +20 -0
  110. package/dist/builtins/res/pipeline.js +252 -0
  111. package/dist/builtins/res/pipeline.js.map +1 -0
  112. package/dist/builtins/res/plugin.d.ts +13 -0
  113. package/dist/builtins/res/plugin.js +140 -0
  114. package/dist/builtins/res/plugin.js.map +1 -0
  115. package/dist/builtins/res/plugininstance.d.ts +6 -0
  116. package/dist/builtins/res/plugininstance.js +53 -0
  117. package/dist/builtins/res/plugininstance.js.map +1 -0
  118. package/dist/builtins/res/pluginmeta.d.ts +6 -0
  119. package/dist/builtins/res/pluginmeta.js +53 -0
  120. package/dist/builtins/res/pluginmeta.js.map +1 -0
  121. package/dist/builtins/res/tag.d.ts +6 -0
  122. package/dist/builtins/res/tag.js +53 -0
  123. package/dist/builtins/res/tag.js.map +1 -0
  124. package/dist/builtins/res/workflow.d.ts +6 -0
  125. package/dist/builtins/res/workflow.js +53 -0
  126. package/dist/builtins/res/workflow.js.map +1 -0
  127. package/dist/builtins/store.d.ts +6 -0
  128. package/dist/builtins/store.js +107 -0
  129. package/dist/builtins/store.js.map +1 -0
  130. package/dist/builtins/sys/context.d.ts +6 -0
  131. package/dist/builtins/sys/context.js +50 -0
  132. package/dist/builtins/sys/context.js.map +1 -0
  133. package/dist/builtins/sys/physicalmode.d.ts +8 -0
  134. package/dist/builtins/sys/physicalmode.js +34 -0
  135. package/dist/builtins/sys/physicalmode.js.map +1 -0
  136. package/dist/builtins/sys/timing.d.ts +8 -0
  137. package/dist/builtins/sys/timing.js +34 -0
  138. package/dist/builtins/sys/timing.js.map +1 -0
  139. package/dist/builtins/sys/version.d.ts +15 -0
  140. package/dist/builtins/sys/version.js +23 -0
  141. package/dist/builtins/sys/version.js.map +1 -0
  142. package/dist/builtins/sys/whoami.d.ts +17 -0
  143. package/dist/builtins/sys/whoami.js +44 -0
  144. package/dist/builtins/sys/whoami.js.map +1 -0
  145. package/dist/builtins/utils.d.ts +55 -0
  146. package/dist/builtins/utils.js +145 -0
  147. package/dist/builtins/utils.js.map +1 -0
  148. package/dist/builtins/wildcard.d.ts +26 -0
  149. package/dist/builtins/wildcard.js +120 -0
  150. package/dist/builtins/wildcard.js.map +1 -0
  151. package/dist/command-keys.d.ts +8 -0
  152. package/dist/command-keys.js +32 -0
  153. package/dist/command-keys.js.map +1 -0
  154. package/dist/config/storeConfig.d.ts +57 -0
  155. package/dist/config/storeConfig.js +78 -0
  156. package/dist/config/storeConfig.js.map +1 -0
  157. package/dist/core/chiliDelegate.d.ts +21 -0
  158. package/dist/core/chiliDelegate.js +32 -0
  159. package/dist/core/chiliDelegate.js.map +1 -0
  160. package/dist/core/connect.d.ts +38 -0
  161. package/dist/core/connect.js +46 -0
  162. package/dist/core/connect.js.map +1 -0
  163. package/dist/core/dispatch.d.ts +95 -0
  164. package/dist/core/dispatch.js +618 -0
  165. package/dist/core/dispatch.js.map +1 -0
  166. package/dist/core/engine.d.ts +91 -0
  167. package/dist/core/engine.js +222 -0
  168. package/dist/core/engine.js.map +1 -0
  169. package/dist/core/preprocess.d.ts +46 -0
  170. package/dist/core/preprocess.js +146 -0
  171. package/dist/core/preprocess.js.map +1 -0
  172. package/dist/core/progress.d.ts +50 -0
  173. package/dist/core/progress.js +21 -0
  174. package/dist/core/progress.js.map +1 -0
  175. package/dist/core/promptContext.d.ts +49 -0
  176. package/dist/core/promptContext.js +39 -0
  177. package/dist/core/promptContext.js.map +1 -0
  178. package/dist/core/question.d.ts +27 -0
  179. package/dist/core/question.js +33 -0
  180. package/dist/core/question.js.map +1 -0
  181. package/dist/core/sink.d.ts +207 -0
  182. package/dist/core/sink.js +329 -0
  183. package/dist/core/sink.js.map +1 -0
  184. package/dist/core/surface.d.ts +172 -0
  185. package/dist/core/surface.js +105 -0
  186. package/dist/core/surface.js.map +1 -0
  187. package/dist/core/version.d.ts +20 -0
  188. package/dist/core/version.js +82 -0
  189. package/dist/core/version.js.map +1 -0
  190. package/dist/index.d.ts +31 -0
  191. package/dist/index.js +32 -0
  192. package/dist/index.js.map +1 -0
  193. package/dist/lib/completer/index.d.ts +15 -0
  194. package/dist/lib/completer/index.js +212 -0
  195. package/dist/lib/completer/index.js.map +1 -0
  196. package/dist/lib/completer/pathComplete.helpers.d.ts +22 -0
  197. package/dist/lib/completer/pathComplete.helpers.js +49 -0
  198. package/dist/lib/completer/pathComplete.helpers.js.map +1 -0
  199. package/dist/lib/parser.d.ts +13 -0
  200. package/dist/lib/parser.js +52 -0
  201. package/dist/lib/parser.js.map +1 -0
  202. package/dist/lib/pipe.d.ts +11 -0
  203. package/dist/lib/pipe.js +90 -0
  204. package/dist/lib/pipe.js.map +1 -0
  205. package/dist/lib/prefetch.d.ts +25 -0
  206. package/dist/lib/prefetch.js +64 -0
  207. package/dist/lib/prefetch.js.map +1 -0
  208. package/dist/lib/semicolonParser.d.ts +22 -0
  209. package/dist/lib/semicolonParser.js +53 -0
  210. package/dist/lib/semicolonParser.js.map +1 -0
  211. package/dist/lib/spinner.d.ts +23 -0
  212. package/dist/lib/spinner.js +71 -0
  213. package/dist/lib/spinner.js.map +1 -0
  214. package/dist/lib/vfs/providers/static.d.ts +65 -0
  215. package/dist/lib/vfs/providers/static.js +164 -0
  216. package/dist/lib/vfs/providers/static.js.map +1 -0
  217. package/dist/lib/vfs/providers/static_content.d.ts +27 -0
  218. package/dist/lib/vfs/providers/static_content.js +180 -0
  219. package/dist/lib/vfs/providers/static_content.js.map +1 -0
  220. package/dist/lib/vfs/vfs.d.ts +59 -0
  221. package/dist/lib/vfs/vfs.js +202 -0
  222. package/dist/lib/vfs/vfs.js.map +1 -0
  223. package/dist/session/index.d.ts +76 -0
  224. package/dist/session/index.js +120 -0
  225. package/dist/session/index.js.map +1 -0
  226. package/package.json +58 -0
@@ -0,0 +1,445 @@
1
+ /**
2
+ * @file Builtin pull command.
3
+ *
4
+ * Blocking PACS series retrieve with parallel execution and per-series structured progress.
5
+ * Accepts one or more `/net/pacs/queries/...` VFS paths (query, study, or series level)
6
+ * and materialises the matching DICOM series into ChRIS storage.
7
+ *
8
+ * Progress is driven by LONK WebSocket push notifications (api/v1/pacs/ws/).
9
+ * Use `--retry N` to automatically re-fire retrieves for series that received no LONK activity.
10
+ *
11
+ * @module
12
+ */
13
+ import chalk from 'chalk';
14
+ import WebSocket from 'ws';
15
+ import { pacsQueries_create, pacsRetrieve_create, } from '@fnndsc/cumin';
16
+ import { session } from '../../session/index.js';
17
+ import { args_checkHasHelpFlag, help_show } from '../help.js';
18
+ import { pacsQuery_createAndWait, queryExpr_parse } from '../net/query.js';
19
+ import { spinner } from '../../lib/spinner.js';
20
+ import { path_resolve } from '../utils.js';
21
+ import { pacs_seriesCollect, pacsServer_resolve, series_cubePathGet, } from '../net/pacsUtils.js';
22
+ import { builtin_cubepath } from '../net/cubepath.js';
23
+ import { pullArgs_parse } from './pull.args.js';
24
+ import { sink_get } from '../../core/sink.js';
25
+ const STALL_TIMEOUT_MS = 30_000;
26
+ const NO_ACTIVITY_TIMEOUT_MS = 15_000;
27
+ const SERIES_TIMEOUT_MS = 5 * 60 * 1_000;
28
+ const CHECKER_INTERVAL_MS = 2_000;
29
+ function progressStatus_fromSeries(status, lonkConfirmed) {
30
+ if (status === 'pulled')
31
+ return lonkConfirmed ? 'done' : 'unconfirmed';
32
+ if (status === 'pending' || status === 'pulling')
33
+ return 'running';
34
+ return status;
35
+ }
36
+ function pullProgress_emit(task, status, phase = 'watching') {
37
+ const current = task.actualFiles;
38
+ const total = task.expectedFiles > 0 ? Math.max(task.expectedFiles, current, 1) : Math.max(current, 1);
39
+ sink_get().progress_write({
40
+ operation: 'pull',
41
+ kind: 'retrieve',
42
+ phase,
43
+ itemId: task.seriesUID,
44
+ label: task.label,
45
+ current,
46
+ total,
47
+ percent: total > 0 ? Math.min(100, (current / total) * 100) : undefined,
48
+ unit: 'files',
49
+ status: status ?? progressStatus_fromSeries(task.status, task.lonkConfirmed),
50
+ });
51
+ }
52
+ function pullProgress_complete(allTasks, failed) {
53
+ const done = allTasks.filter((t) => t.status === 'pulled').length;
54
+ sink_get().progress_write({
55
+ operation: 'pull',
56
+ kind: 'retrieve',
57
+ phase: failed ? 'failed' : 'complete',
58
+ label: failed ? 'Pull incomplete' : 'Pull complete',
59
+ current: done,
60
+ total: allTasks.length,
61
+ percent: allTasks.length > 0 ? (done / allTasks.length) * 100 : 100,
62
+ unit: 'series',
63
+ status: failed ? 'error' : 'done',
64
+ });
65
+ }
66
+ /**
67
+ * Walks a VFS path and returns SeriesPullTask array, delegating collection to pacsUtils.
68
+ *
69
+ * @param pathStr - Absolute VFS path to a query, study, or series directory.
70
+ * @param fallbackPacsName - PACS identifier used when RetrieveAETitle is absent.
71
+ * @returns Array of SeriesPullTask ready for firing.
72
+ */
73
+ async function path_seriesCollect(pathStr, fallbackPacsName) {
74
+ const infos = await pacs_seriesCollect(pathStr, fallbackPacsName, 'pull');
75
+ return infos.map((info) => ({
76
+ label: info.label,
77
+ seriesUID: info.seriesUID,
78
+ studyUID: info.studyUID,
79
+ pacsName: info.pacsName,
80
+ expectedFiles: info.expectedFiles,
81
+ syntheticQueryId: null,
82
+ retrieveId: null,
83
+ status: 'pending',
84
+ actualFiles: 0,
85
+ lastProgressFiles: 0,
86
+ lastProgressTime: Date.now(),
87
+ startTime: 0,
88
+ lonkConfirmed: false,
89
+ cubePathDir: null,
90
+ }));
91
+ }
92
+ /**
93
+ * Creates a synthetic PACSQuery + PACSRetrieve for a single series.
94
+ *
95
+ * @param task - The pull task to fire (mutated in place: syntheticQueryId, retrieveId, startTime).
96
+ * @param pacsserver - Resolved PACS server ID string.
97
+ */
98
+ async function task_fire(task, pacsserver) {
99
+ const queryData = {
100
+ // CUBE rejects duplicate query titles per user, which used to make a
101
+ // re-pull of the same series fail; a timestamp keeps titles unique.
102
+ title: `pull_${task.seriesUID}_${Date.now().toString(36)}`,
103
+ query: JSON.stringify({
104
+ SeriesInstanceUID: task.seriesUID,
105
+ StudyInstanceUID: task.studyUID,
106
+ }),
107
+ execute: false,
108
+ };
109
+ const queryResult = await pacsQueries_create(pacsserver, queryData);
110
+ if (!queryResult.ok) {
111
+ task.status = 'error';
112
+ return;
113
+ }
114
+ const syntheticQueryId = queryResult.value.id;
115
+ const retrieveResult = await pacsRetrieve_create(syntheticQueryId);
116
+ if (!retrieveResult.ok) {
117
+ task.status = 'error';
118
+ return;
119
+ }
120
+ task.syntheticQueryId = syntheticQueryId;
121
+ task.retrieveId = retrieveResult.value.id;
122
+ task.startTime = Date.now();
123
+ }
124
+ /**
125
+ * Constructs a LONK WebSocket URL from a download token response.
126
+ *
127
+ * @param tokenUrl - The download token resource URL.
128
+ * @param token - The actual download token string.
129
+ * @returns WebSocket URL for the LONK endpoint.
130
+ */
131
+ function lonkWsUrl_build(tokenUrl, token) {
132
+ return tokenUrl
133
+ .replace(/^http(s?):\/\//, (_m, s) => `ws${s}://`)
134
+ .replace(/v1\/downloadtokens\/\d+\//, `v1/pacs/ws/?token=${token}`);
135
+ }
136
+ /**
137
+ * Opens a LONK WebSocket, fires retrieves for the given tasks, and blocks until all
138
+ * tasks reach a terminal state. Mutates each task's status, actualFiles, and lonkConfirmed.
139
+ *
140
+ * @param tasks - Tasks to subscribe, fire, and watch.
141
+ * @param pacsserver - Resolved PACS server identifier.
142
+ * @param client - Authenticated ChRIS API client.
143
+ * @returns Number of tasks that failed to fire their retrieve.
144
+ */
145
+ async function tasks_pullWatch(tasks, pacsserver, client) {
146
+ const tokenClient = client;
147
+ const downloadToken = await tokenClient.createDownloadToken();
148
+ const tokenStr = String(downloadToken.data.token ?? '');
149
+ const wsUrl = lonkWsUrl_build(downloadToken.url, tokenStr);
150
+ const ws = new WebSocket(wsUrl);
151
+ await new Promise((openResolve, openReject) => {
152
+ ws.once('open', openResolve);
153
+ ws.once('error', (err) => openReject(err));
154
+ });
155
+ for (const t of tasks) {
156
+ ws.send(JSON.stringify({
157
+ SeriesInstanceUID: t.seriesUID,
158
+ pacs_name: t.pacsName,
159
+ action: 'subscribe',
160
+ }));
161
+ }
162
+ await Promise.all(tasks.map((t) => task_fire(t, pacsserver)));
163
+ const fired = tasks.filter((t) => t.status !== 'error');
164
+ const firingErrors = tasks.length - fired.length;
165
+ if (fired.length === 0) {
166
+ for (const t of tasks) {
167
+ if (t.status === 'error')
168
+ pullProgress_emit(t, 'error');
169
+ }
170
+ ws.close();
171
+ return firingErrors;
172
+ }
173
+ for (const t of tasks) {
174
+ pullProgress_emit(t, t.status === 'error' ? 'error' : 'running');
175
+ }
176
+ const taskByUID = new Map(tasks.map((t) => [t.seriesUID, t]));
177
+ await new Promise((resolve) => {
178
+ let resolved = false;
179
+ const done = () => {
180
+ if (resolved)
181
+ return;
182
+ resolved = true;
183
+ clearInterval(checker);
184
+ try {
185
+ ws.close();
186
+ }
187
+ catch { /* ignore */ }
188
+ resolve();
189
+ };
190
+ const checker = setInterval(() => {
191
+ const now = Date.now();
192
+ let allTerminal = true;
193
+ for (const t of fired) {
194
+ if (t.status === 'pulled' || t.status === 'error' || t.status === 'stalled' || t.status === 'timeout') {
195
+ continue;
196
+ }
197
+ allTerminal = false;
198
+ if (t.startTime > 0 && now - t.startTime > SERIES_TIMEOUT_MS) {
199
+ t.status = 'timeout';
200
+ pullProgress_emit(t, 'timeout');
201
+ continue;
202
+ }
203
+ if (t.actualFiles > 0 && now - t.lastProgressTime > STALL_TIMEOUT_MS) {
204
+ t.status = 'stalled';
205
+ pullProgress_emit(t, 'stalled');
206
+ continue;
207
+ }
208
+ if (t.startTime > 0 && t.actualFiles === 0 && now - t.startTime > NO_ACTIVITY_TIMEOUT_MS) {
209
+ t.status = 'pulled';
210
+ t.lonkConfirmed = false;
211
+ pullProgress_emit(t, 'unconfirmed');
212
+ continue;
213
+ }
214
+ }
215
+ if (allTerminal)
216
+ done();
217
+ }, CHECKER_INTERVAL_MS);
218
+ ws.on('message', (data) => {
219
+ try {
220
+ const outer = JSON.parse(data.toString());
221
+ const seriesUID = outer.SeriesInstanceUID;
222
+ const message = outer.message;
223
+ if (!seriesUID || !message)
224
+ return;
225
+ const t = taskByUID.get(seriesUID);
226
+ if (!t)
227
+ return;
228
+ if ('ndicom' in message && typeof message.ndicom === 'number') {
229
+ const n = message.ndicom;
230
+ t.actualFiles = n;
231
+ t.lastProgressFiles = n;
232
+ t.lastProgressTime = Date.now();
233
+ if (t.status === 'pending')
234
+ t.status = 'pulling';
235
+ pullProgress_emit(t, 'running');
236
+ }
237
+ else if ('done' in message && message.done === true) {
238
+ t.status = 'pulled';
239
+ t.lonkConfirmed = true;
240
+ if (t.actualFiles < t.expectedFiles)
241
+ t.actualFiles = t.expectedFiles;
242
+ pullProgress_emit(t, 'done');
243
+ }
244
+ else if ('error' in message && typeof message.error === 'string') {
245
+ t.status = 'error';
246
+ pullProgress_emit(t, 'error');
247
+ }
248
+ }
249
+ catch {
250
+ // Malformed message — ignore
251
+ }
252
+ });
253
+ ws.on('error', () => {
254
+ for (const t of fired) {
255
+ if (t.status === 'pending' || t.status === 'pulling') {
256
+ t.status = 'error';
257
+ pullProgress_emit(t, 'error');
258
+ }
259
+ }
260
+ done();
261
+ });
262
+ ws.on('close', () => { done(); });
263
+ });
264
+ return firingErrors;
265
+ }
266
+ /**
267
+ * Resolves raw path/query arguments to concrete `/net/pacs` VFS paths,
268
+ * running PACS queries for query expressions.
269
+ *
270
+ * @param paths - Raw path or query-expression operands.
271
+ * @param pacsserver - The resolved PACS server identifier.
272
+ * @returns The resolved VFS paths.
273
+ */
274
+ async function paths_resolveToVfs(paths, pacsserver) {
275
+ const resolvedPaths = [];
276
+ for (const rawPath of paths) {
277
+ const p = rawPath.startsWith('/') ? rawPath : await path_resolve(rawPath);
278
+ if (p.startsWith('/net/pacs')) {
279
+ resolvedPaths.push(p);
280
+ }
281
+ else if (queryExpr_parse(rawPath)) {
282
+ // Query with the RAW expression: path resolution prefixes the CWD,
283
+ // which would corrupt the first DICOM key (e.g. '/AccessionNumber').
284
+ spinner.start(`Querying PACS for ${rawPath}...`, true);
285
+ const qResult = await pacsQuery_createAndWait(rawPath, `pull_${rawPath}`, pacsserver, (msg) => spinner.updateMessage(msg));
286
+ spinner.stop();
287
+ if (qResult) {
288
+ console.log(chalk.gray(` → ${qResult.vfsPath}`));
289
+ resolvedPaths.push(qResult.vfsPath);
290
+ }
291
+ else {
292
+ console.error(chalk.red(`pull: Query failed for: ${rawPath}`));
293
+ }
294
+ }
295
+ else {
296
+ console.error(chalk.red(`pull: Not a PACS VFS path or valid query expression: ${rawPath}`));
297
+ }
298
+ }
299
+ return resolvedPaths;
300
+ }
301
+ /**
302
+ * Re-fires retrieves for series that pulled without LONK confirmation, up to
303
+ * `retryMax` additional attempts, then permanently fails any still unconfirmed.
304
+ *
305
+ * @param allTasks - All pull tasks.
306
+ * @param retryMax - Maximum retry attempts.
307
+ * @param pacsserver - The PACS server identifier.
308
+ * @param client - The connected ChRIS client.
309
+ * @returns The number of additional retrieve-firing errors incurred.
310
+ */
311
+ async function pullRetryLoop(allTasks, retryMax, pacsserver, client) {
312
+ let extraFiringErrors = 0;
313
+ let retryCandidates = allTasks.filter((t) => t.status === 'pulled' && !t.lonkConfirmed);
314
+ const pacsClient = client;
315
+ for (let attempt = 1; attempt <= retryMax && retryCandidates.length > 0; attempt++) {
316
+ await Promise.all(retryCandidates.map(async (t) => {
317
+ const result = await series_cubePathGet(t.seriesUID, pacsClient, 1, 0);
318
+ if (result) {
319
+ t.lonkConfirmed = true;
320
+ t.cubePathDir = result.folderPath;
321
+ }
322
+ }));
323
+ retryCandidates = retryCandidates.filter((t) => !t.lonkConfirmed);
324
+ if (retryCandidates.length === 0)
325
+ break;
326
+ console.log(chalk.yellow(`\nRetry ${attempt}/${retryMax} for ${retryCandidates.length} unconfirmed series...`));
327
+ for (const t of retryCandidates) {
328
+ t.status = 'pending';
329
+ t.actualFiles = 0;
330
+ t.lastProgressFiles = 0;
331
+ t.lastProgressTime = Date.now();
332
+ t.startTime = 0;
333
+ t.lonkConfirmed = false;
334
+ t.syntheticQueryId = null;
335
+ t.retrieveId = null;
336
+ pullProgress_emit(t, 'running', 'retrying');
337
+ }
338
+ extraFiringErrors += await tasks_pullWatch(retryCandidates, pacsserver, client);
339
+ retryCandidates = retryCandidates.filter((t) => t.status === 'pulled' && !t.lonkConfirmed);
340
+ }
341
+ for (const t of retryCandidates) {
342
+ t.status = 'error';
343
+ pullProgress_emit(t, 'error');
344
+ }
345
+ return extraFiringErrors;
346
+ }
347
+ /**
348
+ * Prints the pull summary and sets a non-zero exit code on any failure.
349
+ *
350
+ * @param allTasks - All pull tasks.
351
+ * @param totalFiringErrors - Count of retrieve-firing errors across all attempts.
352
+ */
353
+ function pullSummary_print(allTasks, totalFiringErrors) {
354
+ const pulled = allTasks.filter((t) => t.status === 'pulled').length;
355
+ const totalCount = allTasks.length;
356
+ const failures = allTasks.filter((t) => t.status !== 'pulled');
357
+ if (failures.length === 0) {
358
+ console.log(chalk.green(`\n✓ ${pulled}/${totalCount} series pulled successfully.`));
359
+ }
360
+ else {
361
+ console.log(chalk.yellow(`\n⚠ ${pulled}/${totalCount} series complete.`));
362
+ for (const f of failures) {
363
+ console.log(chalk.red(` ✗ ${f.label} [${f.status.toUpperCase()}]`));
364
+ }
365
+ process.exitCode = 1;
366
+ }
367
+ if (totalFiringErrors > 0) {
368
+ console.log(chalk.red(` ${totalFiringErrors} retrieve(s) failed to start.`));
369
+ process.exitCode = 1;
370
+ }
371
+ pullProgress_complete(allTasks, failures.length > 0 || totalFiringErrors > 0);
372
+ }
373
+ /**
374
+ * Pulls one or more `/net/pacs/queries/...` VFS paths into ChRIS storage.
375
+ *
376
+ * Blocking by default: emits per-series structured progress via LONK WebSocket,
377
+ * exits non-zero on partial failure.
378
+ * With `--nowait`: fires retrieves and prints `<seriesUID> <retrieveId>` per line, then returns.
379
+ * With `--retry N`: re-fires retrieves for [NO LONK] series up to N additional times.
380
+ *
381
+ * @param args - Command arguments (VFS paths, optional flags).
382
+ * @example
383
+ * pull /net/pacs/queries/42_AccessionNumber:12345678
384
+ * pull --retry 3 /net/pacs/queries/42_AccessionNumber:12345678/Study_1.2.3_US-Hips
385
+ */
386
+ export async function builtin_pull(args) {
387
+ if (args_checkHasHelpFlag(args, 'pull')) {
388
+ help_show('pull');
389
+ return;
390
+ }
391
+ const { nowait, retryMax, paths } = pullArgs_parse(args);
392
+ if (paths.length === 0) {
393
+ console.error(chalk.red('pull: No paths specified. Usage: pull [--nowait] [--retry N] <vfs-path> [...]'));
394
+ process.exitCode = 1;
395
+ return;
396
+ }
397
+ const pacsIdentifier = await pacsServer_resolve();
398
+ if (!pacsIdentifier) {
399
+ console.error(chalk.red('pull: No PACS server available. Set one with: pacs connect <id>'));
400
+ process.exitCode = 1;
401
+ return;
402
+ }
403
+ const pacsserver = pacsIdentifier;
404
+ const resolvedPaths = await paths_resolveToVfs(paths, pacsserver);
405
+ const allTasks = [];
406
+ for (const p of resolvedPaths) {
407
+ const tasks = await path_seriesCollect(p, pacsIdentifier);
408
+ if (tasks.length === 0) {
409
+ console.error(chalk.yellow(`pull: No series found under: ${p}`));
410
+ }
411
+ allTasks.push(...tasks);
412
+ }
413
+ if (allTasks.length === 0) {
414
+ console.error(chalk.red('pull: No series to retrieve.'));
415
+ process.exitCode = 1;
416
+ return;
417
+ }
418
+ const client = await session.connection.client_get();
419
+ if (!client) {
420
+ console.error(chalk.red('pull: Not connected to ChRIS.'));
421
+ process.exitCode = 1;
422
+ return;
423
+ }
424
+ // --nowait: fire retrieves and exit without watching
425
+ if (nowait) {
426
+ for (const t of allTasks) {
427
+ await task_fire(t, pacsserver);
428
+ if (t.retrieveId !== null) {
429
+ console.log(`${t.seriesUID} ${t.retrieveId}`);
430
+ }
431
+ else {
432
+ console.log(`${t.seriesUID} ERROR`);
433
+ process.exitCode = 1;
434
+ }
435
+ }
436
+ return;
437
+ }
438
+ let totalFiringErrors = await tasks_pullWatch(allTasks, pacsserver, client);
439
+ totalFiringErrors += await pullRetryLoop(allTasks, retryMax, pacsserver, client);
440
+ pullSummary_print(allTasks, totalFiringErrors);
441
+ // Report CUBE paths via cubepath; --retry handles pacsseries DB lag post-pull
442
+ await builtin_cubepath([...resolvedPaths, '--retry']);
443
+ console.log(chalk.gray('Detached — use `pacsretrieve report <queryId>` to verify.'));
444
+ }
445
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../src/builtins/fs/pull.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { CommandEnvelope } from '@fnndsc/cumin';
2
+ /**
3
+ * Reports the current working directory in the ChRIS filesystem context.
4
+ *
5
+ * @param args - Command arguments (--title flag supported).
6
+ * @returns An envelope whose rendered text is the directory (with feed and
7
+ * plugin segments replaced by titles under --title) and whose model
8
+ * carries the raw path.
9
+ */
10
+ export declare function builtin_pwd(args?: string[]): Promise<CommandEnvelope>;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @file Builtin pwd command.
3
+ * Reports the current working directory as a command envelope.
4
+ */
5
+ import { session } from '../../session/index.js';
6
+ import { envelope_ok } from '@fnndsc/cumin';
7
+ import { feeds_list, pluginInstances_list } from '@fnndsc/salsa';
8
+ /**
9
+ * Reports the current working directory in the ChRIS filesystem context.
10
+ *
11
+ * @param args - Command arguments (--title flag supported).
12
+ * @returns An envelope whose rendered text is the directory (with feed and
13
+ * plugin segments replaced by titles under --title) and whose model
14
+ * carries the raw path.
15
+ */
16
+ export async function builtin_pwd(args = []) {
17
+ const showTitles = args.includes('--title');
18
+ const cwd = await session.getCWD();
19
+ const shown = showTitles ? await path_withTitles(cwd) : cwd;
20
+ return envelope_ok(`${shown}\n`, { kind: 'fs.cwd', data: { path: cwd, shown } });
21
+ }
22
+ /**
23
+ * Replaces feed_XXXX and pl-<name>_XXXX patterns in a path with their titles.
24
+ *
25
+ * @param path - The path to process.
26
+ * @returns The path with titles replacing directory names.
27
+ */
28
+ async function path_withTitles(path) {
29
+ const parts = path.split('/');
30
+ const replacedParts = await Promise.all(parts.map(async (part) => {
31
+ // Pattern 1: feed_XXXX
32
+ const feedMatch = part.match(/^feed_(\d+)$/);
33
+ if (feedMatch) {
34
+ const feedId = parseInt(feedMatch[1], 10);
35
+ try {
36
+ const feedData = await feeds_list({ id: feedId, limit: 1 });
37
+ if (feedData && feedData.tableData && feedData.tableData.length > 0) {
38
+ const feed = feedData.tableData[0];
39
+ if (feed && typeof feed.name === 'string') {
40
+ return feed.name;
41
+ }
42
+ }
43
+ }
44
+ catch (e) {
45
+ // Silently ignore errors
46
+ }
47
+ return part;
48
+ }
49
+ // Pattern 2: pl-<name>_XXXX
50
+ const pluginMatch = part.match(/^(pl-.+)_(\d+)$/);
51
+ if (pluginMatch) {
52
+ const pluginInstanceId = parseInt(pluginMatch[2], 10);
53
+ try {
54
+ const instanceData = await pluginInstances_list({ id: pluginInstanceId, limit: 1 });
55
+ if (instanceData && instanceData.tableData && instanceData.tableData.length > 0) {
56
+ const instance = instanceData.tableData[0];
57
+ if (instance) {
58
+ const pluginName = typeof instance.plugin_name === 'string' ? instance.plugin_name : '';
59
+ const pluginVersion = typeof instance.plugin_version === 'string' ? instance.plugin_version : '';
60
+ return pluginVersion ? `${pluginName} v${pluginVersion}` : pluginName;
61
+ }
62
+ }
63
+ }
64
+ catch (e) {
65
+ // Silently ignore errors
66
+ }
67
+ return part;
68
+ }
69
+ return part; // Return unchanged if no match
70
+ }));
71
+ return replacedParts.join('/');
72
+ }
73
+ //# sourceMappingURL=pwd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pwd.js","sourceRoot":"","sources":["../../../src/builtins/fs/pwd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { CommandEnvelope } from '@fnndsc/cumin';
2
+ /**
3
+ * Parsed `rm` arguments: flags plus the resolved list of path operands.
4
+ */
5
+ export interface RmArgs {
6
+ recursive: boolean;
7
+ force: boolean;
8
+ interactive: boolean;
9
+ paths: string[];
10
+ }
11
+ /**
12
+ * Parses `rm` arguments, supporting combined short flags (`-rf`, `-rfi`) and the
13
+ * `--` end-of-options separator.
14
+ *
15
+ * @param args - Raw command arguments.
16
+ * @returns The parsed flags and path operands.
17
+ */
18
+ export declare function rmArgs_parse(args: string[]): RmArgs;
19
+ /**
20
+ * Formats the multi-target removal summary line.
21
+ *
22
+ * @param successCount - Number of items removed successfully.
23
+ * @param failCount - Number of items that failed to remove.
24
+ * @returns The summary string, or null if there is nothing to summarise.
25
+ */
26
+ export declare function rmSummary_format(successCount: number, failCount: number): string | null;
27
+ /**
28
+ * Removes one or more files or directories.
29
+ *
30
+ * In interactive mode (-i) output is streamed live through the sink so each
31
+ * confirmation prompt appears in sequence with its result; the envelope then
32
+ * carries only the model. Otherwise output is buffered into the envelope.
33
+ *
34
+ * @param args - Command line arguments (flags and paths).
35
+ * @returns An envelope whose model lists per-target outcomes.
36
+ */
37
+ export declare function builtin_rm(args: string[]): Promise<CommandEnvelope>;