@fnndsc/salsa 3.5.1 → 3.6.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 (73) hide show
  1. package/README.md +3 -3
  2. package/dist/connect/index.d.ts +11 -0
  3. package/dist/connect/index.js +11 -0
  4. package/dist/connect/index.js.map +1 -1
  5. package/dist/dag/feedJoins.js +4 -1
  6. package/dist/dag/feedJoins.js.map +1 -1
  7. package/dist/feeds/index.d.ts +15 -2
  8. package/dist/feeds/index.js.map +1 -1
  9. package/dist/files/index.d.ts +7 -0
  10. package/dist/files/index.js +12 -11
  11. package/dist/files/index.js.map +1 -1
  12. package/dist/files/regular_content.js +11 -3
  13. package/dist/files/regular_content.js.map +1 -1
  14. package/dist/groups/index.d.ts +59 -0
  15. package/dist/groups/index.js +89 -0
  16. package/dist/groups/index.js.map +1 -1
  17. package/dist/groups/membershipRevision.d.ts +19 -0
  18. package/dist/groups/membershipRevision.js +29 -0
  19. package/dist/groups/membershipRevision.js.map +1 -0
  20. package/dist/index.d.ts +3 -1
  21. package/dist/index.js +5 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/jobs/jobOps.js +45 -2
  24. package/dist/jobs/jobOps.js.map +1 -1
  25. package/dist/pipelines/index.d.ts +28 -5
  26. package/dist/pipelines/index.js +110 -48
  27. package/dist/pipelines/index.js.map +1 -1
  28. package/dist/pipelines/invocation.d.ts +80 -0
  29. package/dist/pipelines/invocation.js +290 -0
  30. package/dist/pipelines/invocation.js.map +1 -0
  31. package/dist/pipelines/manifest.d.ts +102 -0
  32. package/dist/pipelines/manifest.js +204 -0
  33. package/dist/pipelines/manifest.js.map +1 -0
  34. package/dist/plugins/index.d.ts +29 -0
  35. package/dist/plugins/index.js +51 -10
  36. package/dist/plugins/index.js.map +1 -1
  37. package/dist/plugins/internal/plugin_executeNewFeed.d.ts +0 -14
  38. package/dist/plugins/internal/plugin_executeNewFeed.js +3 -3
  39. package/dist/plugins/internal/plugin_executeNewFeed.js.map +1 -1
  40. package/dist/plugins/plugin_register.js +5 -5
  41. package/dist/plugins/plugin_register.js.map +1 -1
  42. package/dist/plugins/store_import.js +1 -1
  43. package/dist/plugins/store_import.js.map +1 -1
  44. package/dist/retrieve/watch.d.ts +114 -0
  45. package/dist/retrieve/watch.js +360 -0
  46. package/dist/retrieve/watch.js.map +1 -0
  47. package/dist/store/index.d.ts +17 -4
  48. package/dist/store/index.js +9 -4
  49. package/dist/store/index.js.map +1 -1
  50. package/dist/users/index.d.ts +36 -0
  51. package/dist/users/index.js +50 -0
  52. package/dist/users/index.js.map +1 -0
  53. package/dist/vfs/dispatcher.d.ts +11 -0
  54. package/dist/vfs/dispatcher.js +37 -6
  55. package/dist/vfs/dispatcher.js.map +1 -1
  56. package/dist/vfs/index.d.ts +1 -0
  57. package/dist/vfs/index.js +3 -0
  58. package/dist/vfs/index.js.map +1 -1
  59. package/dist/vfs/provider.d.ts +13 -0
  60. package/dist/vfs/providers/etc.d.ts +2 -0
  61. package/dist/vfs/providers/etc.js +41 -2
  62. package/dist/vfs/providers/etc.js.map +1 -1
  63. package/dist/vfs/providers/native.js +41 -7
  64. package/dist/vfs/providers/native.js.map +1 -1
  65. package/dist/vfs/providers/pacs.d.ts +13 -1
  66. package/dist/vfs/providers/pacs.js +86 -107
  67. package/dist/vfs/providers/pacs.js.map +1 -1
  68. package/dist/vfs/providers/pacsHelpers.js +9 -5
  69. package/dist/vfs/providers/pacsHelpers.js.map +1 -1
  70. package/dist/vfs/providers/proc.d.ts +34 -1
  71. package/dist/vfs/providers/proc.js +301 -62
  72. package/dist/vfs/providers/proc.js.map +1 -1
  73. package/package.json +11 -8
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/vfs/dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/vfs/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -6,4 +6,5 @@ export * from "./provider.js";
6
6
  export * from "./dispatcher.js";
7
7
  export * from "./providers/native.js";
8
8
  export * from "./providers/pacs.js";
9
+ export { queryId_extractFromFolder } from "./providers/pacsHelpers.js";
9
10
  export * from "./providers/etc.js";
package/dist/vfs/index.js CHANGED
@@ -18,9 +18,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
18
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.queryId_extractFromFolder = void 0;
21
22
  __exportStar(require("./provider.js"), exports);
22
23
  __exportStar(require("./dispatcher.js"), exports);
23
24
  __exportStar(require("./providers/native.js"), exports);
24
25
  __exportStar(require("./providers/pacs.js"), exports);
26
+ var pacsHelpers_js_1 = require("./providers/pacsHelpers.js");
27
+ Object.defineProperty(exports, "queryId_extractFromFolder", { enumerable: true, get: function () { return pacsHelpers_js_1.queryId_extractFromFolder; } });
25
28
  __exportStar(require("./providers/etc.js"), exports);
26
29
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vfs/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;AAEH,gDAA8B;AAC9B,kDAAgC;AAChC,wDAAsC;AACtC,sDAAoC;AACpC,qDAAmC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vfs/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;AAEH,gDAA8B;AAC9B,kDAAgC;AAChC,wDAAsC;AACtC,sDAAoC;AACpC,6DAAuE;AAA9D,2HAAA,yBAAyB,OAAA;AAClC,qDAAmC"}
@@ -27,6 +27,8 @@ export interface VFSItem {
27
27
  version?: string;
28
28
  /** Title or description (for feeds, queries). */
29
29
  title?: string;
30
+ /** Backing resource ID, when the virtual entry represents one. */
31
+ id?: number;
30
32
  /** Execution status (for job type items). */
31
33
  status?: string;
32
34
  }
@@ -77,4 +79,15 @@ export interface VFSProvider {
77
79
  * @returns A Promise resolving to a Result containing the file contents as a Buffer.
78
80
  */
79
81
  readBinary?(path: string): Promise<Result<Buffer>>;
82
+ /**
83
+ * Resolves the target of a provider-defined lazy link when an operation
84
+ * actually follows it.
85
+ *
86
+ * Listings must not use this hook: providers may expose an unresolved link
87
+ * as structural metadata without paying for its target until navigation.
88
+ *
89
+ * @param path - Absolute virtual path naming the link.
90
+ * @returns The target path, or an error when the provider cannot resolve it.
91
+ */
92
+ linkTarget_resolve?(path: string): Promise<Result<string>>;
80
93
  }
@@ -16,6 +16,7 @@ import { VFSProvider, VFSItem, CpOptions } from '../provider.js';
16
16
  */
17
17
  export declare class EtcVfsProvider implements VFSProvider {
18
18
  prefix: string;
19
+ private groupProjectionCache;
19
20
  /**
20
21
  * Lists contents of /etc — the four virtual config files.
21
22
  *
@@ -38,6 +39,7 @@ export declare class EtcVfsProvider implements VFSProvider {
38
39
  */
39
40
  read(path: string): Promise<Result<string>>;
40
41
  private computeYaml_render;
42
+ /** Renders CUBE groups and their usernames in POSIX `/etc/group` form. */
41
43
  private group_render;
42
44
  private passwd_render;
43
45
  private cube_render;
@@ -14,13 +14,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.EtcVfsProvider = void 0;
15
15
  const cumin_1 = require("@fnndsc/cumin");
16
16
  const cumin_2 = require("@fnndsc/cumin");
17
+ const membershipRevision_js_1 = require("../../groups/membershipRevision.js");
17
18
  /** Virtual files exposed under /etc. */
18
19
  const ETC_FILES = ['compute.yaml', 'group', 'passwd', 'cube'];
20
+ /** Maximum group membership lists hydrated concurrently for `/etc/group`. */
21
+ const GROUP_MEMBERSHIP_CONCURRENCY = 4;
22
+ /** How long external CUBE membership changes may remain cached. */
23
+ const GROUP_PROJECTION_TTL_MS = 5 * 60 * 1000;
19
24
  /**
20
25
  * VFS provider for /etc — maps ChRIS API resources to Unix-style config files.
21
26
  */
22
27
  class EtcVfsProvider {
23
28
  prefix = '/etc';
29
+ groupProjectionCache;
24
30
  /**
25
31
  * Lists contents of /etc — the four virtual config files.
26
32
  *
@@ -86,12 +92,45 @@ class EtcVfsProvider {
86
92
  }
87
93
  return (0, cumin_1.Ok)(lines.join('\n') + '\n');
88
94
  }
95
+ /** Renders CUBE groups and their usernames in POSIX `/etc/group` form. */
89
96
  async group_render() {
97
+ const cubeURL = await cumin_2.chrisContext.ChRISURL_get();
98
+ const cubeUser = await cumin_2.chrisContext.ChRISuser_get();
99
+ const connectionKey = `${cubeURL ?? ''}\u0000${cubeUser ?? ''}`;
100
+ const membershipRevision = (0, membershipRevision_js_1.groupMembershipRevision_get)();
101
+ const now = Date.now();
102
+ if (this.groupProjectionCache?.connectionKey === connectionKey
103
+ && this.groupProjectionCache.membershipRevision === membershipRevision
104
+ && this.groupProjectionCache.expiresAt > now) {
105
+ return (0, cumin_1.Ok)(this.groupProjectionCache.content);
106
+ }
90
107
  const result = await (0, cumin_2.groups_getAll)();
91
108
  if (!result.ok)
92
109
  return (0, cumin_1.Err)();
93
- const lines = result.value.map((g) => `${g.name}:x:${g.id}:`);
94
- return (0, cumin_1.Ok)(lines.join('\n') + '\n');
110
+ const lines = [];
111
+ for (let index = 0; index < result.value.length; index += GROUP_MEMBERSHIP_CONCURRENCY) {
112
+ const groupBatch = result.value.slice(index, index + GROUP_MEMBERSHIP_CONCURRENCY);
113
+ const batchResults = await Promise.all(groupBatch.map(async (group) => ({
114
+ group,
115
+ members: await (0, cumin_2.groupMembers_getAll)(group.id),
116
+ })));
117
+ for (const { group, members } of batchResults) {
118
+ if (!members.ok)
119
+ return (0, cumin_1.Err)();
120
+ const usernames = members.value
121
+ .map((member) => member.username)
122
+ .join(',');
123
+ lines.push(`${group.name}:x:${group.id}:${usernames}`);
124
+ }
125
+ }
126
+ const content = lines.join('\n') + '\n';
127
+ this.groupProjectionCache = {
128
+ connectionKey,
129
+ content,
130
+ expiresAt: Date.now() + GROUP_PROJECTION_TTL_MS,
131
+ membershipRevision,
132
+ };
133
+ return (0, cumin_1.Ok)(content);
95
134
  }
96
135
  async passwd_render() {
97
136
  const result = await (0, cumin_2.currentUser_get)();
@@ -1 +1 @@
1
- {"version":3,"file":"etc.js","sourceRoot":"","sources":["../../../src/vfs/providers/etc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"etc.js","sourceRoot":"","sources":["../../../src/vfs/providers/etc.ts"],"names":[],"mappings":"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"}
@@ -38,6 +38,24 @@ class NativeVfsProvider {
38
38
  (0, index_js_1.files_listAll)(fetchOpts, "links", resolvedPath),
39
39
  ]);
40
40
  const [dirsResult, filesResult, linksResult] = results;
41
+ // files_listAll returns null both for a failed folder resolution and for
42
+ // an existing folder whose collection is simply empty. When every
43
+ // sub-listing comes back empty-or-failed the two cases are
44
+ // indistinguishable here, so probe the parent listing: a missing folder
45
+ // must surface as an error, not render as an empty directory.
46
+ const noneSucceeded = results.every((settled) => settled.status === "rejected" || !settled.value?.tableData);
47
+ if (noneSucceeded && resolvedPath !== "/") {
48
+ const dirExists = await path_checkIsDir(resolvedPath);
49
+ if (!dirExists.ok) {
50
+ // The probe itself failed: report the verification failure rather
51
+ // than claiming the folder is absent.
52
+ return (0, cumin_1.Err)();
53
+ }
54
+ if (!dirExists.value) {
55
+ cumin_1.errorStack.stack_push("error", `Cannot list ${resolvedPath}: No such file or directory`);
56
+ return (0, cumin_1.Err)();
57
+ }
58
+ }
41
59
  const items = [];
42
60
  const mapToItem = (raw, type) => {
43
61
  let name = raw.fname || raw.path || "";
@@ -89,13 +107,19 @@ class NativeVfsProvider {
89
107
  async cp(src, dest, options) {
90
108
  try {
91
109
  const srcIsDir = await path_checkIsDir(src);
92
- if (srcIsDir && !options.recursive) {
110
+ if (!srcIsDir.ok) {
111
+ return false;
112
+ }
113
+ if (srcIsDir.value && !options.recursive) {
93
114
  cumin_1.errorStack.stack_push("error", `Source is a directory. Re-run with --recursive to copy: ${src}`);
94
115
  return false;
95
116
  }
96
117
  const destIsDir = await path_checkIsDir(dest);
118
+ if (!destIsDir.ok) {
119
+ return false;
120
+ }
97
121
  const destLooksDir = dest.endsWith("/");
98
- const finalDest = (destIsDir || destLooksDir)
122
+ const finalDest = (destIsDir.value || destLooksDir)
99
123
  ? path_1.default.posix.join(dest, path_1.default.posix.basename(src))
100
124
  : dest;
101
125
  if (options.recursive) {
@@ -116,8 +140,13 @@ exports.NativeVfsProvider = NativeVfsProvider;
116
140
  /**
117
141
  * Determines whether a given ChRIS path refers to a directory.
118
142
  *
143
+ * Distinguishes "verified absent" from "could not verify": a listing failure
144
+ * while probing must not masquerade as a missing directory, since callers use
145
+ * this probe to decide between not-found errors and real operations.
146
+ *
119
147
  * @param targetPath - The absolute ChRIS path to check.
120
- * @returns Promise<boolean> indicating directory existence.
148
+ * @returns Ok(true/false) when the parent listing answered, Err when the
149
+ * probe itself failed (an error has been pushed to the stack).
121
150
  */
122
151
  async function path_checkIsDir(targetPath) {
123
152
  const parent = path_1.default.posix.dirname(targetPath);
@@ -125,9 +154,11 @@ async function path_checkIsDir(targetPath) {
125
154
  try {
126
155
  const results = await (0, index_js_1.files_listAll)({ limit: 1000, offset: 0 }, "dirs", parent);
127
156
  if (!results || !results.tableData) {
128
- return false;
157
+ // files_listAll returns null for both an empty parent and a failed
158
+ // context: an empty parent simply has no dirs, so absent is the answer.
159
+ return (0, cumin_1.Ok)(false);
129
160
  }
130
- return results.tableData.some((entry) => {
161
+ const found = results.tableData.some((entry) => {
131
162
  const candidate = typeof entry.path === "string" && entry.path.length > 0
132
163
  ? entry.path
133
164
  : typeof entry.fname === "string"
@@ -135,9 +166,12 @@ async function path_checkIsDir(targetPath) {
135
166
  : "";
136
167
  return candidate === targetPath || path_1.default.posix.basename(candidate) === name;
137
168
  });
169
+ return (0, cumin_1.Ok)(found);
138
170
  }
139
- catch {
140
- return false;
171
+ catch (error) {
172
+ const msg = error instanceof Error ? error.message : String(error);
173
+ cumin_1.errorStack.stack_push("error", `Cannot verify directory ${targetPath}: ${msg}`);
174
+ return (0, cumin_1.Err)();
141
175
  }
142
176
  }
143
177
  //# sourceMappingURL=native.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/vfs/providers/native.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/vfs/providers/native.ts"],"names":[],"mappings":"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"}
@@ -17,8 +17,20 @@ type SortOptions = {
17
17
  export declare class PacsVfsProvider implements VFSProvider {
18
18
  /** Prefix matches /net/pacs and subdirectories. */
19
19
  prefix: string;
20
- /** Cache for decoded PACS query results to avoid redundant API hits. */
20
+ /**
21
+ * Cache for decoded PACS query results to avoid redundant API hits.
22
+ *
23
+ * Contract (see docs/code-audit-2026-08.adoc, cache inventory): only a
24
+ * settled result — one carrying a structured `json` payload — is cached,
25
+ * since a query's payload is written once and never mutates afterwards; a
26
+ * payload-less decode (query still running, or empty) is re-fetched on the
27
+ * next access. The cache is size-bounded so a long-lived daemon does not
28
+ * grow it monotonically; eviction is oldest-inserted-first, which for
29
+ * monotonically increasing query ids approximates least-recently-created.
30
+ */
21
31
  private _queryCache;
32
+ /** Upper bound on cached decoded query results. */
33
+ private static readonly QUERY_CACHE_MAX;
22
34
  /**
23
35
  * Fetches the decoded query result, leveraging a cache to prevent redundant API calls.
24
36
  *
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.PacsVfsProvider = void 0;
14
14
  const cumin_1 = require("@fnndsc/cumin");
15
+ const watch_js_1 = require("../../retrieve/watch.js");
15
16
  const sort_js_1 = require("../sort.js");
16
17
  const pacsHelpers_js_1 = require("./pacsHelpers.js");
17
18
  const index_js_1 = require("../../pacs/index.js");
@@ -19,28 +20,6 @@ const index_js_2 = require("../../files/index.js");
19
20
  const path_1 = __importDefault(require("path"));
20
21
  const chalk_1 = __importDefault(require("chalk"));
21
22
  const pacs_content_js_1 = require("./pacs_content.js");
22
- /**
23
- * Resolves the folder path on ChRIS storage for a retrieved series.
24
- *
25
- * @param seriesInstanceUID - The Series Instance UID to resolve.
26
- * @returns Promise resolving to the folder path string or null on failure.
27
- */
28
- async function series_getFolderPath(seriesInstanceUID) {
29
- const client = await cumin_1.chrisConnection.client_get();
30
- if (!client) {
31
- return null;
32
- }
33
- const seriesList = await client.getPACSSeriesList({
34
- SeriesInstanceUID: seriesInstanceUID,
35
- limit: 1,
36
- });
37
- const seriesItems = seriesList.getItems();
38
- if (!seriesItems || seriesItems.length === 0) {
39
- return null;
40
- }
41
- const series = seriesItems[0];
42
- return series?.data?.folder_path || null;
43
- }
44
23
  function pacsRoot_list() {
45
24
  return (0, cumin_1.Ok)([{ name: "queries", type: "vfs", size: 0, owner: "root", date: new Date().toISOString() }]);
46
25
  }
@@ -126,16 +105,17 @@ function seriesToRetrieve_build(decoded, studyUID, seriesUID, src) {
126
105
  }
127
106
  const seriesArray = (0, pacsHelpers_js_1.series_extractFromStudy)(studyObj);
128
107
  const seriesToRetrieve = [];
108
+ const expected_of = (obj) => Number((0, pacsHelpers_js_1.tag_extractValue)(obj?.NumberOfSeriesRelatedInstances ?? 0)) || 0;
129
109
  if (seriesUID) {
130
110
  const seriesObj = (0, pacsHelpers_js_1.series_findByUID)(seriesArray, seriesUID);
131
111
  const desc = seriesObj ? (0, pacsHelpers_js_1.tag_extractValue)(seriesObj.SeriesDescription || "Series") : "Series";
132
- seriesToRetrieve.push({ uid: seriesUID, description: desc });
112
+ seriesToRetrieve.push({ uid: seriesUID, description: desc, expectedFiles: expected_of(seriesObj) });
133
113
  }
134
114
  else {
135
115
  for (const s of seriesArray) {
136
116
  const sUID = (0, pacsHelpers_js_1.tag_extractValue)(s.SeriesInstanceUID || s.uid);
137
117
  if (sUID) {
138
- seriesToRetrieve.push({ uid: sUID, description: (0, pacsHelpers_js_1.tag_extractValue)(s.SeriesDescription || "Series") });
118
+ seriesToRetrieve.push({ uid: sUID, description: (0, pacsHelpers_js_1.tag_extractValue)(s.SeriesDescription || "Series"), expectedFiles: expected_of(s) });
139
119
  }
140
120
  }
141
121
  }
@@ -156,98 +136,69 @@ async function pacsServer_resolve() {
156
136
  cumin_1.errorStack.stack_push("error", "cp: No PACS server available or configured in context.");
157
137
  return (0, cumin_1.Err)();
158
138
  }
159
- async function retrieve_pollUntilComplete(syntheticQueryId, seriesUID, maxAttempts) {
160
- let attempts = 0;
161
- while (attempts < maxAttempts) {
162
- attempts++;
163
- await new Promise((resolve) => setTimeout(resolve, 5000));
164
- const statusResult = await (0, index_js_1.pacsRetrieve_statusForQuery)(syntheticQueryId);
165
- if (!statusResult.ok || !statusResult.value) {
166
- console.log(chalk_1.default.yellow(` [Attempt ${attempts}/${maxAttempts}] Failed to fetch status report, retrying...`));
167
- continue;
168
- }
169
- const statusReport = statusResult.value;
170
- let totalExpected = 0;
171
- let totalActual = 0;
172
- let anyPulling = false;
173
- let allPulled = true;
174
- let anyError = false;
175
- if (statusReport.studies) {
176
- for (const s of statusReport.studies) {
177
- if (s.series) {
178
- for (const ser of s.series) {
179
- if (String(ser.seriesInstanceUID) === String(seriesUID)) {
180
- totalExpected = Number(ser.expectedFiles) || 0;
181
- totalActual = Number(ser.actualFiles) || 0;
182
- if (ser.status === "pulling")
183
- anyPulling = true;
184
- if (ser.status !== "pulled")
185
- allPulled = false;
186
- if (ser.status === "error")
187
- anyError = true;
188
- }
189
- }
139
+ async function series_retrieveAndCopy(seriesItem, studyUID, pacsserver, dest, idx, total) {
140
+ (0, cumin_1.runtimeOutput_data)(`${chalk_1.default.cyan(`\n[PACS Retrieve ${idx + 1}/${total}] Processing series: ${seriesItem.description} (${seriesItem.uid})...`)}\n`);
141
+ const client = await cumin_1.chrisConnection.client_get();
142
+ if (!client) {
143
+ (0, cumin_1.runtimeOutput_err)(`${chalk_1.default.red(" ✗ Not connected to ChRIS.")}\n`);
144
+ return false;
145
+ }
146
+ // One retrieve engine for cp and pull alike: bounded, retried firing plus
147
+ // the LONK watch, replacing this provider's former 5-second polling loop.
148
+ const task = (0, watch_js_1.retrieveTask_make)({
149
+ label: seriesItem.description,
150
+ seriesUID: seriesItem.uid,
151
+ studyUID,
152
+ pacsName: pacsserver,
153
+ // The decode's instance count enables the idempotency skip: a series
154
+ // already fully registered in CUBE is copied without refiring.
155
+ expectedFiles: seriesItem.expectedFiles,
156
+ });
157
+ const alreadyThere = await (0, watch_js_1.retrieveTasks_skipComplete)([task]);
158
+ if (alreadyThere === 0) {
159
+ const events = {
160
+ task: (t, status) => {
161
+ if (status === 'running' && t.actualFiles > 0) {
162
+ (0, cumin_1.runtimeOutput_data)(`${chalk_1.default.gray(` ${t.actualFiles} file(s) received...`)}\n`);
190
163
  }
191
- }
192
- }
193
- const overallStatus = statusReport.retrieveStatus || "pending";
194
- console.log(chalk_1.default.gray(` [Attempt ${attempts}/${maxAttempts}] CUBE Status: ${overallStatus} | Files: ${totalActual}/${totalExpected}`));
195
- if (allPulled && totalExpected > 0 && totalActual === totalExpected) {
196
- console.log(chalk_1.default.green(` ✓ Pull complete: ${totalActual}/${totalExpected} files retrieved.`));
197
- return true;
198
- }
199
- if (overallStatus === "succeeded" || overallStatus === "completed") {
200
- console.log(chalk_1.default.green(` ✓ Pull complete (Status: ${overallStatus}).`));
201
- return true;
164
+ else if (status === 'error') {
165
+ (0, cumin_1.runtimeOutput_err)(`${chalk_1.default.red(" ✗ PACS retrieve reported an error.")}\n`);
166
+ }
167
+ else if (status === 'stalled' || status === 'timeout') {
168
+ (0, cumin_1.runtimeOutput_err)(`${chalk_1.default.red(` ✗ PACS retrieve ${status}.`)}\n`);
169
+ }
170
+ },
171
+ };
172
+ (0, cumin_1.runtimeOutput_data)(`${chalk_1.default.gray(" -> Firing PACS retrieve and watching progress...")}\n`);
173
+ const firingErrors = await (0, watch_js_1.retrieve_fireAndWatch)([task], pacsserver, client, events);
174
+ if (firingErrors > 0) {
175
+ (0, cumin_1.runtimeOutput_err)(`${chalk_1.default.red(` ✗ Retrieve could not be fired for series ${seriesItem.uid}.`)}\n`);
176
+ return false;
202
177
  }
203
- if (anyError || overallStatus === "error" || overallStatus === "failed") {
204
- console.error(chalk_1.default.red(" ✗ PACS retrieve reported error status."));
178
+ if (task.status !== 'pulled') {
205
179
  return false;
206
180
  }
207
181
  }
208
- console.error(chalk_1.default.red(" ✗ PACS retrieve timed out."));
209
- return false;
210
- }
211
- async function series_retrieveAndCopy(seriesItem, studyUID, pacsserver, dest, idx, total) {
212
- console.log(chalk_1.default.cyan(`\n[PACS Retrieve ${idx + 1}/${total}] Processing series: ${seriesItem.description} (${seriesItem.uid})...`));
213
- const queryPayload = {
214
- title: `Synthetic cp Query ${seriesItem.uid}`,
215
- query: JSON.stringify({ SeriesInstanceUID: seriesItem.uid, StudyInstanceUID: studyUID }),
216
- execute: false,
217
- };
218
- console.log(chalk_1.default.gray(" -> Registering synthetic query on CUBE..."));
219
- const queryResult = await (0, index_js_1.pacsQueries_create)(pacsserver, queryPayload);
220
- if (!queryResult.ok) {
221
- console.error(chalk_1.default.red(` ✗ Failed to create synthetic query for series ${seriesItem.uid}`));
222
- return false;
223
- }
224
- const syntheticQueryId = queryResult.value.id;
225
- console.log(chalk_1.default.gray(` -> Triggering PACS retrieve (Query ID: ${syntheticQueryId})...`));
226
- const retrieveResult = await (0, index_js_1.pacsRetrieve_create)(syntheticQueryId);
227
- if (!retrieveResult.ok) {
228
- console.error(chalk_1.default.red(` ✗ Failed to create PACS retrieve for query ${syntheticQueryId}`));
229
- return false;
182
+ (0, cumin_1.runtimeOutput_data)(`${chalk_1.default.gray(" -> Finding folder path on ChRIS storage...")}\n`);
183
+ let folderPath = task.cubePathDir;
184
+ if (folderPath === null) {
185
+ const stateResult = await (0, cumin_1.seriesStorage_resolve)(seriesItem.uid, { attempts: 4, delayMs: 2_000 });
186
+ folderPath = stateResult.ok ? stateResult.value.folderPath : null;
230
187
  }
231
- console.log(chalk_1.default.gray(" -> Pulling series data sequentially, polling progress..."));
232
- const finished = await retrieve_pollUntilComplete(syntheticQueryId, seriesItem.uid, 60);
233
- if (!finished)
234
- return false;
235
- console.log(chalk_1.default.gray(" -> Finding folder path on ChRIS storage..."));
236
- const folderPath = await series_getFolderPath(seriesItem.uid);
237
188
  if (!folderPath) {
238
- console.error(chalk_1.default.red(` ✗ No registered folder path found for series UID ${seriesItem.uid}`));
189
+ (0, cumin_1.runtimeOutput_err)(`${chalk_1.default.red(` ✗ No registered folder path found for series UID ${seriesItem.uid}`)}\n`);
239
190
  return false;
240
191
  }
241
192
  const absoluteFolderPath = folderPath.startsWith("/") ? folderPath : "/" + folderPath;
242
193
  const cleanDesc = seriesItem.description.replace(/[\s/]/g, "_");
243
194
  const targetSeriesFolder = path_1.default.posix.join(dest, `Series_${seriesItem.uid}_${cleanDesc}`);
244
- console.log(chalk_1.default.gray(` -> Copying series files to '${targetSeriesFolder}'...`));
195
+ (0, cumin_1.runtimeOutput_data)(`${chalk_1.default.gray(` -> Copying series files to '${targetSeriesFolder}'...`)}\n`);
245
196
  const copySuccess = await (0, index_js_2.files_copyRecursively)(absoluteFolderPath, targetSeriesFolder);
246
197
  if (!copySuccess) {
247
- console.error(chalk_1.default.red(` ✗ Recursive copy failed from '${absoluteFolderPath}' to '${targetSeriesFolder}'`));
198
+ (0, cumin_1.runtimeOutput_err)(`${chalk_1.default.red(` ✗ Recursive copy failed from '${absoluteFolderPath}' to '${targetSeriesFolder}'`)}\n`);
248
199
  return false;
249
200
  }
250
- console.log(chalk_1.default.green(` ✓ Series '${seriesItem.description}' copied successfully.`));
201
+ (0, cumin_1.runtimeOutput_data)(`${chalk_1.default.green(` ✓ Series '${seriesItem.description}' copied successfully.`)}\n`);
251
202
  return true;
252
203
  }
253
204
  /**
@@ -256,8 +207,20 @@ async function series_retrieveAndCopy(seriesItem, studyUID, pacsserver, dest, id
256
207
  class PacsVfsProvider {
257
208
  /** Prefix matches /net/pacs and subdirectories. */
258
209
  prefix = "/net/pacs";
259
- /** Cache for decoded PACS query results to avoid redundant API hits. */
210
+ /**
211
+ * Cache for decoded PACS query results to avoid redundant API hits.
212
+ *
213
+ * Contract (see docs/code-audit-2026-08.adoc, cache inventory): only a
214
+ * settled result — one carrying a structured `json` payload — is cached,
215
+ * since a query's payload is written once and never mutates afterwards; a
216
+ * payload-less decode (query still running, or empty) is re-fetched on the
217
+ * next access. The cache is size-bounded so a long-lived daemon does not
218
+ * grow it monotonically; eviction is oldest-inserted-first, which for
219
+ * monotonically increasing query ids approximates least-recently-created.
220
+ */
260
221
  _queryCache = new Map();
222
+ /** Upper bound on cached decoded query results. */
223
+ static QUERY_CACHE_MAX = 100;
261
224
  /**
262
225
  * Fetches the decoded query result, leveraging a cache to prevent redundant API calls.
263
226
  *
@@ -273,7 +236,17 @@ class PacsVfsProvider {
273
236
  if (!decodedResult.ok || !decodedResult.value) {
274
237
  return null;
275
238
  }
276
- this._queryCache.set(queryId, decodedResult.value);
239
+ // Cache settled results only: a decode without a structured payload may
240
+ // be a still-running query whose payload arrives later, and caching it
241
+ // would pin the empty view for the life of the process.
242
+ if (decodedResult.value.json !== undefined && decodedResult.value.json !== null) {
243
+ if (this._queryCache.size >= PacsVfsProvider.QUERY_CACHE_MAX) {
244
+ const oldest = this._queryCache.keys().next().value;
245
+ if (oldest !== undefined)
246
+ this._queryCache.delete(oldest);
247
+ }
248
+ this._queryCache.set(queryId, decodedResult.value);
249
+ }
277
250
  return decodedResult.value;
278
251
  }
279
252
  /**
@@ -309,16 +282,22 @@ class PacsVfsProvider {
309
282
  return studies_list(studies, options);
310
283
  const studyUID = parts[4].replace(/^Study_/, "").split("_")[0];
311
284
  const studyObj = (0, pacsHelpers_js_1.study_findByUID)(studies, studyUID);
312
- if (!studyObj)
313
- return (0, cumin_1.Ok)([]);
285
+ // A missing UID is "no such directory", never an empty one: rendering
286
+ // not-found as an empty listing hides typos and stale paths entirely.
287
+ if (!studyObj) {
288
+ cumin_1.errorStack.stack_push("error", `'${effectivePath}': No such study in query ${queryId}. Use 'ls' on the query directory to see available studies.`);
289
+ return (0, cumin_1.Err)();
290
+ }
314
291
  const seriesArr = (0, pacsHelpers_js_1.series_extractFromStudy)(studyObj);
315
292
  if (parts.length === 5)
316
293
  return series_list(seriesArr, options);
317
294
  if (parts.length === 6) {
318
295
  const seriesUID = parts[5].replace(/^Series_/, "").split("_")[0];
319
296
  const seriesObj = (0, pacsHelpers_js_1.series_findByUID)(seriesArr, seriesUID);
320
- if (!seriesObj)
321
- return (0, cumin_1.Ok)([]);
297
+ if (!seriesObj) {
298
+ cumin_1.errorStack.stack_push("error", `'${effectivePath}': No such series in study ${studyUID}.`);
299
+ return (0, cumin_1.Err)();
300
+ }
322
301
  return seriesFiles_list(seriesObj);
323
302
  }
324
303
  return (0, cumin_1.Ok)([]);
@@ -355,7 +334,7 @@ class PacsVfsProvider {
355
334
  if (!serverResult.ok)
356
335
  return false;
357
336
  const pacsserver = serverResult.value;
358
- console.log(chalk_1.default.cyan(`[PACS Retrieve] Initiating sequential gather of ${seriesToRetrieve.length} series...`));
337
+ (0, cumin_1.runtimeOutput_data)(`${chalk_1.default.cyan(`[PACS Retrieve] Initiating sequential gather of ${seriesToRetrieve.length} series...`)}\n`);
359
338
  let overallSuccess = true;
360
339
  for (let i = 0; i < seriesToRetrieve.length; i++) {
361
340
  const ok = await series_retrieveAndCopy(seriesToRetrieve[i], studyUID, pacsserver, dest, i, seriesToRetrieve.length);