@fnndsc/chili 3.2.5

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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/dist/chefs/chefs.d.ts +15 -0
  4. package/dist/chefs/chefs.js +195 -0
  5. package/dist/commands/compute/fields.d.ts +6 -0
  6. package/dist/commands/compute/fields.js +13 -0
  7. package/dist/commands/compute/list.d.ts +19 -0
  8. package/dist/commands/compute/list.js +20 -0
  9. package/dist/commands/connect/login.d.ts +16 -0
  10. package/dist/commands/connect/login.js +18 -0
  11. package/dist/commands/connect/logout.d.ts +6 -0
  12. package/dist/commands/connect/logout.js +16 -0
  13. package/dist/commands/feed/comments.d.ts +41 -0
  14. package/dist/commands/feed/comments.js +45 -0
  15. package/dist/commands/feed/create.d.ts +13 -0
  16. package/dist/commands/feed/create.js +40 -0
  17. package/dist/commands/feed/note.d.ts +21 -0
  18. package/dist/commands/feed/note.js +24 -0
  19. package/dist/commands/feeds/delete.d.ts +14 -0
  20. package/dist/commands/feeds/delete.js +34 -0
  21. package/dist/commands/feeds/fields.d.ts +6 -0
  22. package/dist/commands/feeds/fields.js +17 -0
  23. package/dist/commands/feeds/list.d.ts +17 -0
  24. package/dist/commands/feeds/list.js +38 -0
  25. package/dist/commands/feeds/share.d.ts +17 -0
  26. package/dist/commands/feeds/share.js +19 -0
  27. package/dist/commands/file/view.d.ts +8 -0
  28. package/dist/commands/file/view.js +25 -0
  29. package/dist/commands/files/delete.d.ts +16 -0
  30. package/dist/commands/files/delete.js +36 -0
  31. package/dist/commands/files/fields.d.ts +7 -0
  32. package/dist/commands/files/fields.js +18 -0
  33. package/dist/commands/files/list.d.ts +11 -0
  34. package/dist/commands/files/list.js +23 -0
  35. package/dist/commands/fs/cat.d.ts +15 -0
  36. package/dist/commands/fs/cat.js +26 -0
  37. package/dist/commands/fs/cp.d.ts +17 -0
  38. package/dist/commands/fs/cp.js +26 -0
  39. package/dist/commands/fs/create.d.ts +15 -0
  40. package/dist/commands/fs/create.js +83 -0
  41. package/dist/commands/fs/download.d.ts +25 -0
  42. package/dist/commands/fs/download.js +235 -0
  43. package/dist/commands/fs/edit.d.ts +16 -0
  44. package/dist/commands/fs/edit.js +25 -0
  45. package/dist/commands/fs/ls.d.ts +18 -0
  46. package/dist/commands/fs/ls.js +142 -0
  47. package/dist/commands/fs/mkdir.d.ts +8 -0
  48. package/dist/commands/fs/mkdir.js +21 -0
  49. package/dist/commands/fs/mv.d.ts +13 -0
  50. package/dist/commands/fs/mv.js +73 -0
  51. package/dist/commands/fs/rm.d.ts +24 -0
  52. package/dist/commands/fs/rm.js +108 -0
  53. package/dist/commands/fs/touch.d.ts +16 -0
  54. package/dist/commands/fs/touch.js +62 -0
  55. package/dist/commands/fs/upload.d.ts +55 -0
  56. package/dist/commands/fs/upload.js +221 -0
  57. package/dist/commands/groups/fields.d.ts +6 -0
  58. package/dist/commands/groups/fields.js +13 -0
  59. package/dist/commands/groups/list.d.ts +16 -0
  60. package/dist/commands/groups/list.js +26 -0
  61. package/dist/commands/man/doc.d.ts +16 -0
  62. package/dist/commands/man/doc.js +32 -0
  63. package/dist/commands/man/topics.d.ts +6 -0
  64. package/dist/commands/man/topics.js +27 -0
  65. package/dist/commands/pipeline/fields.d.ts +6 -0
  66. package/dist/commands/pipeline/fields.js +13 -0
  67. package/dist/commands/pipeline/run.d.ts +18 -0
  68. package/dist/commands/pipeline/run.js +33 -0
  69. package/dist/commands/plugin/readme.d.ts +14 -0
  70. package/dist/commands/plugin/readme.js +49 -0
  71. package/dist/commands/plugin/run.d.ts +10 -0
  72. package/dist/commands/plugin/run.js +29 -0
  73. package/dist/commands/plugin/search.d.ts +7 -0
  74. package/dist/commands/plugin/search.js +18 -0
  75. package/dist/commands/plugininstances/fields.d.ts +6 -0
  76. package/dist/commands/plugininstances/fields.js +13 -0
  77. package/dist/commands/plugininstances/list.d.ts +16 -0
  78. package/dist/commands/plugininstances/list.js +26 -0
  79. package/dist/commands/pluginmetas/fields.d.ts +6 -0
  80. package/dist/commands/pluginmetas/fields.js +13 -0
  81. package/dist/commands/pluginmetas/list.d.ts +16 -0
  82. package/dist/commands/pluginmetas/list.js +26 -0
  83. package/dist/commands/plugins/add.d.ts +34 -0
  84. package/dist/commands/plugins/add.js +374 -0
  85. package/dist/commands/plugins/delete.d.ts +14 -0
  86. package/dist/commands/plugins/delete.js +34 -0
  87. package/dist/commands/plugins/fields.d.ts +6 -0
  88. package/dist/commands/plugins/fields.js +17 -0
  89. package/dist/commands/plugins/list.d.ts +17 -0
  90. package/dist/commands/plugins/list.js +40 -0
  91. package/dist/commands/plugins/overview.d.ts +6 -0
  92. package/dist/commands/plugins/overview.js +17 -0
  93. package/dist/commands/store/list.d.ts +23 -0
  94. package/dist/commands/store/list.js +48 -0
  95. package/dist/commands/tags/fields.d.ts +6 -0
  96. package/dist/commands/tags/fields.js +13 -0
  97. package/dist/commands/tags/list.d.ts +16 -0
  98. package/dist/commands/tags/list.js +26 -0
  99. package/dist/commands/workflows/fields.d.ts +6 -0
  100. package/dist/commands/workflows/fields.js +13 -0
  101. package/dist/commands/workflows/list.d.ts +16 -0
  102. package/dist/commands/workflows/list.js +26 -0
  103. package/dist/config/colorConfig.d.ts +56 -0
  104. package/dist/config/colorConfig.js +161 -0
  105. package/dist/connect/connectHandler.d.ts +15 -0
  106. package/dist/connect/connectHandler.js +48 -0
  107. package/dist/context/contextCommand.d.ts +13 -0
  108. package/dist/context/contextCommand.js +193 -0
  109. package/dist/controllers/baseController.d.ts +43 -0
  110. package/dist/controllers/baseController.js +67 -0
  111. package/dist/controllers/feedController.d.ts +35 -0
  112. package/dist/controllers/feedController.js +53 -0
  113. package/dist/controllers/fileController.d.ts +56 -0
  114. package/dist/controllers/fileController.js +93 -0
  115. package/dist/controllers/pluginContextController.d.ts +24 -0
  116. package/dist/controllers/pluginContextController.js +49 -0
  117. package/dist/controllers/pluginController.d.ts +70 -0
  118. package/dist/controllers/pluginController.js +98 -0
  119. package/dist/controllers/pluginMetaController.d.ts +41 -0
  120. package/dist/controllers/pluginMetaController.js +52 -0
  121. package/dist/feeds/feedHandler.d.ts +64 -0
  122. package/dist/feeds/feedHandler.js +203 -0
  123. package/dist/filesystem/fileGroupHandler.d.ts +92 -0
  124. package/dist/filesystem/fileGroupHandler.js +318 -0
  125. package/dist/filesystem/filesystemHandler.d.ts +12 -0
  126. package/dist/filesystem/filesystemHandler.js +135 -0
  127. package/dist/filesystem/inodeCommand.d.ts +12 -0
  128. package/dist/filesystem/inodeCommand.js +37 -0
  129. package/dist/handlers/baseGroupHandler.d.ts +103 -0
  130. package/dist/handlers/baseGroupHandler.js +342 -0
  131. package/dist/index.d.ts +7 -0
  132. package/dist/index.js +239 -0
  133. package/dist/lfs/lfs.d.ts +25 -0
  134. package/dist/lfs/lfs.js +74 -0
  135. package/dist/man/man.d.ts +15 -0
  136. package/dist/man/man.js +31 -0
  137. package/dist/man/renderer.d.ts +26 -0
  138. package/dist/man/renderer.js +187 -0
  139. package/dist/models/feed.d.ts +18 -0
  140. package/dist/models/feed.js +8 -0
  141. package/dist/models/listing.d.ts +33 -0
  142. package/dist/models/listing.js +9 -0
  143. package/dist/models/plugin.d.ts +27 -0
  144. package/dist/models/plugin.js +1 -0
  145. package/dist/models/resource.d.ts +39 -0
  146. package/dist/models/resource.js +9 -0
  147. package/dist/pacs/pacsQueryHandler.d.ts +55 -0
  148. package/dist/pacs/pacsQueryHandler.js +196 -0
  149. package/dist/pacs/pacsQueryPayload.d.ts +19 -0
  150. package/dist/pacs/pacsQueryPayload.js +44 -0
  151. package/dist/pacs/pacsResultRender.d.ts +20 -0
  152. package/dist/pacs/pacsResultRender.js +141 -0
  153. package/dist/pacs/pacsRetrieveHandler.d.ts +87 -0
  154. package/dist/pacs/pacsRetrieveHandler.js +272 -0
  155. package/dist/pacs/pacsServerHandler.d.ts +15 -0
  156. package/dist/pacs/pacsServerHandler.js +32 -0
  157. package/dist/path/pathCommand.d.ts +64 -0
  158. package/dist/path/pathCommand.js +805 -0
  159. package/dist/path/pathMapper.d.ts +189 -0
  160. package/dist/path/pathMapper.js +382 -0
  161. package/dist/plugins/pluginGroupHandler.d.ts +42 -0
  162. package/dist/plugins/pluginGroupHandler.js +90 -0
  163. package/dist/plugins/pluginHandler.d.ts +87 -0
  164. package/dist/plugins/pluginHandler.js +303 -0
  165. package/dist/plugins/pluginMetaHandler.d.ts +21 -0
  166. package/dist/plugins/pluginMetaHandler.js +27 -0
  167. package/dist/screen/screen.d.ts +214 -0
  168. package/dist/screen/screen.js +478 -0
  169. package/dist/utils/admin_prompt.d.ts +42 -0
  170. package/dist/utils/admin_prompt.js +105 -0
  171. package/dist/utils/cli.d.ts +67 -0
  172. package/dist/utils/cli.js +112 -0
  173. package/dist/utils/docker.d.ts +74 -0
  174. package/dist/utils/docker.js +155 -0
  175. package/dist/utils/input_format.d.ts +77 -0
  176. package/dist/utils/input_format.js +135 -0
  177. package/dist/utils/sort.d.ts +29 -0
  178. package/dist/utils/sort.js +63 -0
  179. package/dist/utils/ui.d.ts +7 -0
  180. package/dist/utils/ui.js +26 -0
  181. package/dist/utils.d.ts +15 -0
  182. package/dist/utils.js +14 -0
  183. package/dist/views/compute.d.ts +17 -0
  184. package/dist/views/compute.js +40 -0
  185. package/dist/views/connect.d.ts +13 -0
  186. package/dist/views/connect.js +35 -0
  187. package/dist/views/feed.d.ts +44 -0
  188. package/dist/views/feed.js +110 -0
  189. package/dist/views/file.d.ts +25 -0
  190. package/dist/views/file.js +71 -0
  191. package/dist/views/fs.d.ts +51 -0
  192. package/dist/views/fs.js +105 -0
  193. package/dist/views/ls.d.ts +37 -0
  194. package/dist/views/ls.js +190 -0
  195. package/dist/views/plugin.d.ts +28 -0
  196. package/dist/views/plugin.js +71 -0
  197. package/dist/views/pluginParameters.d.ts +17 -0
  198. package/dist/views/pluginParameters.js +79 -0
  199. package/docs/00_intro.adoc +25 -0
  200. package/docs/01_setup.adoc +63 -0
  201. package/docs/02_context.adoc +128 -0
  202. package/docs/03_searchable.adoc +134 -0
  203. package/docs/10_everyday_examples.adoc +9 -0
  204. package/docs/11_upload_data.adoc +146 -0
  205. package/docs/12_create_a_feed.adoc +9 -0
  206. package/docs/13_run_a_plugin.adoc +271 -0
  207. package/docs/20_plugins.adoc +16 -0
  208. package/docs/21_pluginReadme.adoc +123 -0
  209. package/docs/30_filesystem.adoc +93 -0
  210. package/docs/31_fileops.adoc +51 -0
  211. package/docs/32_file_content.adoc +471 -0
  212. package/docs/_architecture.adoc +48 -0
  213. package/docs/_deepContext.adoc +84 -0
  214. package/docs/_roadmap.adoc +42 -0
  215. package/docs/_searchable.adoc +187 -0
  216. package/docs/_state.adoc +68 -0
  217. package/docs/pacs.adoc +101 -0
  218. package/docs/pathMapper.md +246 -0
  219. package/package.json +92 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Renders the result of a mkdir operation.
3
+ * @param path - The path created.
4
+ * @param success - Whether the operation succeeded.
5
+ */
6
+ export declare function mkdir_render(path: string, success: boolean): string;
7
+ /**
8
+ * Renders the result of a touch operation.
9
+ * @param path - The path created.
10
+ * @param success - Whether the operation succeeded.
11
+ */
12
+ export declare function touch_render(path: string, success: boolean): string;
13
+ /**
14
+ * Renders the result of an upload operation.
15
+ * @param local - Local path.
16
+ * @param remote - Remote path.
17
+ * @param success - Whether the operation succeeded.
18
+ */
19
+ export declare function upload_render(local: string, remote: string, success: boolean): string;
20
+ /**
21
+ * Renders the content of a file or an error message.
22
+ * @param content - The file content or null if not found/error.
23
+ * @param path - The file path (for error message).
24
+ */
25
+ export declare function cat_render(content: string | null, path: string): string;
26
+ /**
27
+ * Renders the result of a copy operation.
28
+ * @param src - Source path.
29
+ * @param dest - Destination path.
30
+ * @param success - Whether the operation succeeded.
31
+ */
32
+ export declare function cp_render(src: string, dest: string, success: boolean): string;
33
+ /**
34
+ * Renders the result of a move operation.
35
+ * @param src - Source path.
36
+ * @param dest - Destination path.
37
+ * @param success - Whether the operation succeeded.
38
+ */
39
+ export declare function mv_render(src: string, dest: string, success: boolean): string;
40
+ /**
41
+ * Renders the outcome of an rm operation for terminal display.
42
+ *
43
+ * @param result - The rm result.
44
+ * @returns Formatted status string.
45
+ */
46
+ export declare function rm_render(result: {
47
+ success: boolean;
48
+ path: string;
49
+ type: 'file' | 'dir' | 'link' | null;
50
+ error?: string;
51
+ }): string;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @file File System View components.
3
+ *
4
+ * Provides standard output formatting for file system operations
5
+ * (mkdir, touch, cat, upload).
6
+ *
7
+ * @module
8
+ */
9
+ import chalk from 'chalk';
10
+ /**
11
+ * Renders the result of a mkdir operation.
12
+ * @param path - The path created.
13
+ * @param success - Whether the operation succeeded.
14
+ */
15
+ export function mkdir_render(path, success) {
16
+ if (success) {
17
+ return chalk.green(`Created directory: ${path}`);
18
+ }
19
+ else {
20
+ return chalk.red(`Failed to create directory: ${path}`);
21
+ }
22
+ }
23
+ /**
24
+ * Renders the result of a touch operation.
25
+ * @param path - The path created.
26
+ * @param success - Whether the operation succeeded.
27
+ */
28
+ export function touch_render(path, success) {
29
+ if (success) {
30
+ return chalk.green(`Created file: ${path}`);
31
+ }
32
+ else {
33
+ return chalk.red(`Failed to create file: ${path}`);
34
+ }
35
+ }
36
+ /**
37
+ * Renders the result of an upload operation.
38
+ * @param local - Local path.
39
+ * @param remote - Remote path.
40
+ * @param success - Whether the operation succeeded.
41
+ */
42
+ export function upload_render(local, remote, success) {
43
+ if (success) {
44
+ return chalk.green(`Successfully uploaded ${local}`);
45
+ }
46
+ else {
47
+ return chalk.red(`Failed to upload ${local}`);
48
+ }
49
+ }
50
+ /**
51
+ * Renders the content of a file or an error message.
52
+ * @param content - The file content or null if not found/error.
53
+ * @param path - The file path (for error message).
54
+ */
55
+ export function cat_render(content, path) {
56
+ if (content !== null) {
57
+ return content;
58
+ }
59
+ else {
60
+ return chalk.red(`File not found or empty: ${path}`);
61
+ }
62
+ }
63
+ /**
64
+ * Renders the result of a copy operation.
65
+ * @param src - Source path.
66
+ * @param dest - Destination path.
67
+ * @param success - Whether the operation succeeded.
68
+ */
69
+ export function cp_render(src, dest, success) {
70
+ if (success) {
71
+ return chalk.green(`Copied ${src} to ${dest}`);
72
+ }
73
+ else {
74
+ return chalk.red(`Failed to copy ${src} to ${dest}`);
75
+ }
76
+ }
77
+ /**
78
+ * Renders the result of a move operation.
79
+ * @param src - Source path.
80
+ * @param dest - Destination path.
81
+ * @param success - Whether the operation succeeded.
82
+ */
83
+ export function mv_render(src, dest, success) {
84
+ if (success) {
85
+ return chalk.green(`Moved ${src} to ${dest}`);
86
+ }
87
+ else {
88
+ return chalk.red(`Failed to move ${src} to ${dest}`);
89
+ }
90
+ }
91
+ /**
92
+ * Renders the outcome of an rm operation for terminal display.
93
+ *
94
+ * @param result - The rm result.
95
+ * @returns Formatted status string.
96
+ */
97
+ export function rm_render(result) {
98
+ if (result.success) {
99
+ const typeStr = result.type || 'item';
100
+ return chalk.green(`Removed ${typeStr}: ${result.path}`);
101
+ }
102
+ else {
103
+ return chalk.red(result.error || `Failed to remove: ${result.path}`);
104
+ }
105
+ }
@@ -0,0 +1,37 @@
1
+ import { ListingItem } from '../models/listing.js';
2
+ /**
3
+ * Options for the view renderers.
4
+ */
5
+ export interface ViewOptions {
6
+ human?: boolean;
7
+ oneColumn?: boolean;
8
+ sort?: 'name' | 'size' | 'date' | 'owner';
9
+ reverse?: boolean;
10
+ }
11
+ /**
12
+ * Formats bytes into human-readable string.
13
+ */
14
+ export declare function size_format(bytes: number): string;
15
+ /**
16
+ * DEPRECATED: Sorts an array of listing items based on specified criteria.
17
+ * @deprecated Sorting should be done at the command layer, not in views.
18
+ * @param items - Array of items to sort.
19
+ * @param sortBy - Field to sort by (default: 'name').
20
+ * @param reverse - Whether to reverse the sort order.
21
+ * @returns Sorted array of items.
22
+ */
23
+ export declare function items_sort(items: ListingItem[], sortBy?: 'name' | 'size' | 'date' | 'owner', reverse?: boolean): ListingItem[];
24
+ /**
25
+ * Renders the items in a multi-column grid format (standard `ls`).
26
+ * Note: Items should already be sorted at the command layer.
27
+ */
28
+ export declare function grid_render(items: ListingItem[], options?: ViewOptions): string;
29
+ /**
30
+ * Renders the items in a long list format (`ls -l`).
31
+ * Note: Items should already be sorted at the command layer.
32
+ */
33
+ export declare function long_render(items: ListingItem[], options?: ViewOptions): string;
34
+ /**
35
+ * Renders the items as a JSON string.
36
+ */
37
+ export declare function json_render(items: ListingItem[]): string;
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @file View layer for the `ls` command.
3
+ *
4
+ * Provides different rendering strategies for file listing data:
5
+ * - Grid: Multi-column standard view.
6
+ * - Long: Detailed list with metadata (-l).
7
+ * - JSON: Raw structured data.
8
+ *
9
+ * @module
10
+ */
11
+ import chalk from 'chalk';
12
+ import { fileSystemItem_colorize } from '../config/colorConfig.js';
13
+ /**
14
+ * Formats bytes into human-readable string.
15
+ */
16
+ export function size_format(bytes) {
17
+ if (bytes === 0)
18
+ return '0 B';
19
+ const k = 1024;
20
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
21
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
22
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
23
+ }
24
+ /**
25
+ * Formats a resource item name based on its type (color coding).
26
+ * Uses color configuration from cumin.
27
+ */
28
+ function name_format(item) {
29
+ const base = fileSystemItem_colorize(item.name, item.type);
30
+ // Append / to navigable container types so they're visually distinct from files
31
+ if (item.type === 'dir' || item.type === 'job') {
32
+ return base + chalk.cyan.bold('/');
33
+ }
34
+ return base;
35
+ }
36
+ /**
37
+ * Calculates the visible length of a string, stripping ANSI codes.
38
+ */
39
+ function string_lengthVisible(str) {
40
+ return str.replace(/\u001b\[[0-9;]*m/g, "").length;
41
+ }
42
+ /**
43
+ * DEPRECATED: Sorts an array of listing items based on specified criteria.
44
+ * @deprecated Sorting should be done at the command layer, not in views.
45
+ * @param items - Array of items to sort.
46
+ * @param sortBy - Field to sort by (default: 'name').
47
+ * @param reverse - Whether to reverse the sort order.
48
+ * @returns Sorted array of items.
49
+ */
50
+ export function items_sort(items, sortBy = 'name', reverse = false) {
51
+ const sorted = [...items].sort((a, b) => {
52
+ let comparison = 0;
53
+ switch (sortBy) {
54
+ case 'name':
55
+ comparison = a.name.localeCompare(b.name);
56
+ break;
57
+ case 'size':
58
+ comparison = a.size - b.size;
59
+ break;
60
+ case 'date':
61
+ comparison = a.date.localeCompare(b.date);
62
+ break;
63
+ case 'owner':
64
+ comparison = a.owner.localeCompare(b.owner);
65
+ break;
66
+ }
67
+ return reverse ? -comparison : comparison;
68
+ });
69
+ return sorted;
70
+ }
71
+ /**
72
+ * Renders the items in a multi-column grid format (standard `ls`).
73
+ * Note: Items should already be sorted at the command layer.
74
+ */
75
+ export function grid_render(items, options = {}) {
76
+ if (items.length === 0)
77
+ return '';
78
+ // Legacy sorting support (deprecated - sort at command layer instead)
79
+ let displayItems = items;
80
+ if (options.sort) {
81
+ const sortBy = options.sort;
82
+ const reverse = options.reverse || false;
83
+ displayItems = items_sort(items, sortBy, reverse);
84
+ }
85
+ const formattedItems = displayItems.map((item) => {
86
+ let str = name_format(item);
87
+ if (item.version)
88
+ str += chalk.dim(` (${item.version})`);
89
+ return str;
90
+ });
91
+ if (options.oneColumn) {
92
+ return formattedItems.join('\n');
93
+ }
94
+ const termWidth = process.stdout.columns || 80;
95
+ const padding = 2;
96
+ const maxLen = Math.max(...formattedItems.map(string_lengthVisible));
97
+ // Cap colWidth at termWidth so padding never causes a terminal line wrap.
98
+ const colWidth = Math.min(maxLen + padding, termWidth);
99
+ const cols = Math.max(1, Math.floor(termWidth / colWidth));
100
+ let output = "";
101
+ for (let i = 0; i < formattedItems.length; i++) {
102
+ const item = formattedItems[i];
103
+ const visibleLen = string_lengthVisible(item);
104
+ const padLen = Math.max(0, colWidth - visibleLen);
105
+ output += item + " ".repeat(padLen);
106
+ if ((i + 1) % cols === 0) {
107
+ output += "\n";
108
+ }
109
+ }
110
+ return output.trimEnd();
111
+ }
112
+ /**
113
+ * Renders the items in a long list format (`ls -l`).
114
+ * Note: Items should already be sorted at the command layer.
115
+ */
116
+ export function long_render(items, options = {}) {
117
+ if (items.length === 0)
118
+ return '';
119
+ // Legacy sorting support (deprecated - sort at command layer instead)
120
+ let displayItems = items;
121
+ if (options.sort) {
122
+ const sortBy = options.sort;
123
+ const reverse = options.reverse || false;
124
+ displayItems = items_sort(items, sortBy, reverse);
125
+ }
126
+ // Calculate max name width for alignment
127
+ const maxNameWidth = Math.max(...displayItems.map((item) => {
128
+ const nameStr = name_format(item);
129
+ const visibleLen = string_lengthVisible(nameStr);
130
+ return item.version ? visibleLen + item.version.length + 3 : visibleLen;
131
+ }));
132
+ return displayItems.map((item) => {
133
+ // Type
134
+ let typeChar = '-';
135
+ if (item.type === 'dir')
136
+ typeChar = 'd';
137
+ else if (item.type === 'link')
138
+ typeChar = 'l';
139
+ else if (item.type === 'plugin')
140
+ typeChar = 'p';
141
+ else if (item.type === 'pipeline')
142
+ typeChar = 'P';
143
+ else if (item.type === 'vfs')
144
+ typeChar = 'v';
145
+ else if (item.type === 'job')
146
+ typeChar = 'j';
147
+ // Owner
148
+ const owner = item.owner.padEnd(10);
149
+ // Size — for job entries replace with colour-coded status
150
+ let sizeStr;
151
+ if (item.type === 'job' && item.status) {
152
+ const s = item.status;
153
+ const statusColoured = s === 'finishedSuccessfully' ? chalk.green(s) :
154
+ s === 'finishedWithError' ? chalk.red(s) :
155
+ s === 'cancelled' ? chalk.gray(s) :
156
+ s === 'started' || s === 'running' ? chalk.yellow(s) :
157
+ chalk.gray(s);
158
+ sizeStr = statusColoured.padEnd(30);
159
+ }
160
+ else {
161
+ sizeStr = (options.human ? size_format(item.size) : item.size.toString()).padEnd(8);
162
+ }
163
+ // Date
164
+ // Assuming date is ISO, just take the first 19 chars "YYYY-MM-DD HH:mm:ss"
165
+ const dateStr = item.date.replace('T', ' ').slice(0, 19);
166
+ // Name
167
+ let nameStr = name_format(item);
168
+ if (item.version)
169
+ nameStr += ` (${item.version})`;
170
+ // Pad name to max width for alignment
171
+ const nameVisibleLen = string_lengthVisible(nameStr);
172
+ const namePadding = ' '.repeat(Math.max(0, maxNameWidth - nameVisibleLen));
173
+ let line = `${typeChar} ${owner} ${sizeStr} ${dateStr} ${nameStr}${namePadding}`;
174
+ // Title (for feeds, plugin instances)
175
+ if (item.title) {
176
+ line += ` ${chalk.greenBright(item.title)}`;
177
+ }
178
+ // Link Target
179
+ if (item.type === 'link' && item.target) {
180
+ line += ` -> ${item.target}`;
181
+ }
182
+ return line;
183
+ }).join('\n');
184
+ }
185
+ /**
186
+ * Renders the items as a JSON string.
187
+ */
188
+ export function json_render(items) {
189
+ return JSON.stringify(items, null, 2);
190
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @file View layer for Plugin commands.
3
+ *
4
+ * Provides output formatting for plugin listing, execution, and details.
5
+ *
6
+ * @module
7
+ */
8
+ import { Plugin, PluginInstance } from '../models/plugin.js';
9
+ /**
10
+ * Options for rendering output.
11
+ */
12
+ export interface OutputOptions {
13
+ table?: boolean;
14
+ csv?: boolean;
15
+ }
16
+ /**
17
+ * Renders the result of a plugin execution.
18
+ * @param instance - The created plugin instance.
19
+ * @returns Formatted string.
20
+ */
21
+ export declare function pluginRun_render(instance: PluginInstance): string;
22
+ /**
23
+ * Renders a list of plugins.
24
+ * @param plugins - Array of Plugin objects.
25
+ * @param selectedFields - The fields to display, in order.
26
+ * @param options - Output options (e.g., table, csv).
27
+ */
28
+ export declare function pluginList_render(plugins: Plugin[], selectedFields: string[], options?: OutputOptions): string;
@@ -0,0 +1,71 @@
1
+ import chalk from 'chalk';
2
+ import { screen } from '../screen/screen.js';
3
+ /**
4
+ * Renders the result of a plugin execution.
5
+ * @param instance - The created plugin instance.
6
+ * @returns Formatted string.
7
+ */
8
+ export function pluginRun_render(instance) {
9
+ return chalk.green(`Plugin started successfully.\nInstance ID: ${chalk.bold(instance.id)}\nStatus: ${instance.status}`);
10
+ }
11
+ /**
12
+ * Renders a list of plugins.
13
+ * @param plugins - Array of Plugin objects.
14
+ * @param selectedFields - The fields to display, in order.
15
+ * @param options - Output options (e.g., table, csv).
16
+ */
17
+ export function pluginList_render(plugins, selectedFields, options = {}) {
18
+ if (plugins.length === 0)
19
+ return chalk.gray("No plugins found.");
20
+ // Define default fields if none are specified or if the fields are empty
21
+ const effectiveFields = selectedFields.length > 0 ? selectedFields : ['name', 'version', 'title'];
22
+ const rows = plugins.map(p => {
23
+ return effectiveFields.map(field => {
24
+ const fieldKey = field;
25
+ const rawValue = p[fieldKey];
26
+ let value = rawValue !== undefined && rawValue !== null ? String(rawValue) : '';
27
+ // Apply basic styling for key fields only in non-CSV/non-Table output
28
+ if (!options.csv && !options.table) {
29
+ if (field === 'id')
30
+ return chalk.bold(value);
31
+ if (field === 'name')
32
+ return chalk.cyan(value);
33
+ }
34
+ return value;
35
+ });
36
+ });
37
+ const headerForDisplay = effectiveFields.map(field => field.toUpperCase());
38
+ if (options.csv) {
39
+ // CSV format
40
+ const csvHeader = headerForDisplay.map(h => `"${h}"`).join(',');
41
+ const csvRows = rows.map(row => row.map(cell => `"${String(cell).split('"').join('""')}"`).join(',')).join('\n');
42
+ return [csvHeader, csvRows].join('\n');
43
+ }
44
+ else if (options.table) {
45
+ // Prepare data for screen.table_output
46
+ const tableDataForScreen = plugins.map(plugin => {
47
+ const row = {};
48
+ effectiveFields.forEach(field => {
49
+ const fieldKey = field;
50
+ const val = plugin[fieldKey];
51
+ row[field] = val !== undefined && val !== null ? val : '';
52
+ });
53
+ return row;
54
+ });
55
+ // Pass original effectiveFields as head for correct data mapping, headerForDisplay for title
56
+ return screen.table_output(tableDataForScreen, {
57
+ head: effectiveFields,
58
+ title: { title: "Plugins", justification: "center" },
59
+ typeColors: {
60
+ string: "green",
61
+ number: "yellow",
62
+ boolean: "cyan",
63
+ object: "magenta"
64
+ }
65
+ });
66
+ }
67
+ else {
68
+ // Default list format (tab-separated)
69
+ return rows.map(row => row.join('\t')).join('\n');
70
+ }
71
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @file Renderer for plugin parameter tables in man/help output.
3
+ *
4
+ * @module
5
+ */
6
+ import { FilteredResourceData } from '@fnndsc/cumin';
7
+ /**
8
+ * Renders plugin parameters in a "man page" style format.
9
+ *
10
+ * Format:
11
+ * [long parameter] [short parameter -- only if different] <value> (default: <default value>)
12
+ * Type: <type>
13
+ * [help description]
14
+ *
15
+ * @param data - The filtered resource data containing plugin parameters.
16
+ */
17
+ export declare function pluginParameters_renderMan(data: FilteredResourceData): void;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @file Renderer for plugin parameter tables in man/help output.
3
+ *
4
+ * @module
5
+ */
6
+ import chalk from 'chalk';
7
+ /**
8
+ * Renders plugin parameters in a "man page" style format.
9
+ *
10
+ * Format:
11
+ * [long parameter] [short parameter -- only if different] <value> (default: <default value>)
12
+ * Type: <type>
13
+ * [help description]
14
+ *
15
+ * @param data - The filtered resource data containing plugin parameters.
16
+ */
17
+ export function pluginParameters_renderMan(data) {
18
+ if (!data.tableData || data.tableData.length === 0) {
19
+ console.log("No parameters found.");
20
+ return;
21
+ }
22
+ data.tableData.forEach((param) => {
23
+ // 1. Construct the first line: Flags and Value
24
+ let line1Parts = [];
25
+ // Long flag: Display only if name length > 1
26
+ if (param.name && param.name.length > 1) {
27
+ line1Parts.push(chalk.bold(`--${param.name}`));
28
+ }
29
+ // Short flag: Display only if it exists and is a single character (excluding dashes)
30
+ // Note: 'param.flag' usually comes with dashes (e.g. '-v').
31
+ if (param.flag) {
32
+ const cleanFlag = param.flag.replace(/^-+/, '');
33
+ if (cleanFlag.length === 1) {
34
+ // Avoid duplicating if it somehow matches the long flag visual (unlikely given logic)
35
+ // The prompt says "only if different to long parameter".
36
+ // Since long parameter is always --name (length > 1) and this is -f (length 1),
37
+ // they are visually different.
38
+ line1Parts.push(chalk.bold(param.flag));
39
+ }
40
+ }
41
+ // Value placeholder
42
+ if (param.action === 'store_true' || param.action === 'store_false') {
43
+ // Boolean flags usually don't take a value in the signature invocation
44
+ }
45
+ else {
46
+ // Generic value placeholder based on type
47
+ const valueType = param.type ? `<${param.type}>` : '<value>';
48
+ line1Parts.push(chalk.cyan(valueType));
49
+ }
50
+ // Default value
51
+ if (param.default !== undefined && param.default !== null && param.default !== "") {
52
+ line1Parts.push(chalk.gray(`(default: ${param.default})`));
53
+ }
54
+ if (line1Parts.length > 0) {
55
+ console.log(line1Parts.join(' '));
56
+ }
57
+ else {
58
+ // Fallback if both are suppressed (e.g. name 'v', no flag)?
59
+ // In strict adherence, we show nothing on line 1, which is weird.
60
+ // But assuming a valid plugin definition, one of them should appear.
61
+ // If name is 'v', it implies it should probably have a flag '-v'.
62
+ // If not, we might want to show '--v' anyway despite the rule, or '-v'.
63
+ // For safety, if line1 is empty but we have a name, show it as long flag to avoid invisible params.
64
+ if (param.name) {
65
+ console.log(chalk.bold(`--${param.name}`) + ' ' + chalk.gray('(implicit)'));
66
+ }
67
+ }
68
+ // 2. Type line
69
+ if (param.type) {
70
+ console.log(`Type: ${chalk.yellow(param.type)}`);
71
+ }
72
+ // 3. Help description
73
+ if (param.help) {
74
+ console.log(chalk.white(param.help));
75
+ }
76
+ // Separator (newline)
77
+ console.log('');
78
+ });
79
+ }
@@ -0,0 +1,25 @@
1
+ = intro
2
+
3
+ == welcome
4
+
5
+ Welome to the inline `chili` documentation system! This set of documents provides help text for each `chili` command. Additionally several important concepts like _searchable_ and _context_ are discussed.
6
+
7
+ == how to use
8
+
9
+ To use this documentation system, simply read it!
10
+
11
+ == Architectural Goals
12
+
13
+ The `chili` and `cumin` projects are designed with a clear separation of concerns, with the goal of creating a reusable library of business logic for interacting with ChRIS.
14
+
15
+ === The `chili` and `cumin` relationship
16
+
17
+ *`cumin`* is a "backend" or "runtime" library that is specific to a nodejs environment. It is responsible for all direct interaction with the ChRIS API, as well as managing state, credentials, and access to the local filesystem. It provides a high-level, object-oriented interface over the ChRIS API.
18
+
19
+ *`chili`* is the "frontend" or business logic library. It is designed to be environment-agnostic. It contains the core logic and workflow for interacting with ChRIS resources, but it does not perform any direct API or filesystem access. Instead, it is designed to be paired with a backend like `cumin`.
20
+
21
+ This separation allows the `chili` library to be potentially used in other environments, for instance as the logic layer for a future ChRIS web UI, by simply swapping `cumin` with a browser-compatible backend.
22
+
23
+ === The Naming Convention
24
+
25
+ The codebase follows a strict `<object>_<method>` naming convention (e.g., `userNames_get`). This Reverse Polish Notation (RPN) style is designed for high discoverability and grouping of related functions. It is also machine-parsable, which aids in automated tooling and analysis. Further details can be found in the `TYPESCRIPT-STYLE-GUIDE.md` document.
@@ -0,0 +1,63 @@
1
+ = Setup Guide
2
+
3
+ This guide outlines the steps required to build and install `chili` from source.
4
+
5
+ == Prerequisites: The Kitchen Sink
6
+
7
+ To cook `chili` without needing `sudo` or running into permission errors (EACCES), we strictly recommend using **NVM (Node Version Manager)**.
8
+
9
+ ### Why NVM?
10
+ The build process (`make meal`) uses `npm link` to symlink the packages globally. On a standard Linux system, the global npm directory is `/usr/lib/node_modules`, which requires root access. `nvm` installs Node.js in your home directory (e.g., `~/.nvm`), allowing you to install and link global packages without `sudo`.
11
+
12
+ === 1. Install NVM
13
+
14
+ If you don't have it yet, install NVM:
15
+
16
+ [source,bash]
17
+ ----
18
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
19
+ ----
20
+
21
+ Restart your terminal, then install and use the latest Node LTS:
22
+
23
+ [source,bash]
24
+ ----
25
+ nvm install --lts
26
+ nvm use --lts
27
+ ----
28
+
29
+ == Developer Setup
30
+
31
+ Once NVM is set up, you can use the "Cooking" makefile to handle everything.
32
+
33
+ === 1. Clone the Repository
34
+
35
+ Clone the `chili` repository (and its siblings `cumin` and `salsa` if they are separate, though the Makefile handles cloning them if missing).
36
+
37
+ [source,bash]
38
+ ----
39
+ git clone <repo_url>
40
+ cd chili
41
+ ----
42
+
43
+ === 2. The Full Meal
44
+
45
+ Run the all-in-one command to clone dependencies, install packages, build, test, and link everything globally.
46
+
47
+ [source,bash]
48
+ ----
49
+ make meal
50
+ ----
51
+
52
+ If your NVM environment is correct, this will complete successfully, and you will have the `chili` command available in your terminal immediately.
53
+
54
+ == Verification
55
+
56
+ To verify the installation, try running the help command:
57
+
58
+ [source,bash]
59
+ ----
60
+ chili --help
61
+ ----
62
+
63
+ You should see the ChILI logo and a list of available commands.