@fnndsc/chell 4.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +325 -0
- package/dist/builtins/debug.d.ts +6 -0
- package/dist/builtins/debug.js +47 -0
- package/dist/builtins/debug.js.map +1 -0
- package/dist/builtins/executable.d.ts +22 -0
- package/dist/builtins/executable.js +115 -0
- package/dist/builtins/executable.js.map +1 -0
- package/dist/builtins/fs/cat.d.ts +16 -0
- package/dist/builtins/fs/cat.js +249 -0
- package/dist/builtins/fs/cat.js.map +1 -0
- package/dist/builtins/fs/cd.d.ts +41 -0
- package/dist/builtins/fs/cd.js +178 -0
- package/dist/builtins/fs/cd.js.map +1 -0
- package/dist/builtins/fs/cp.d.ts +7 -0
- package/dist/builtins/fs/cp.js +73 -0
- package/dist/builtins/fs/cp.js.map +1 -0
- package/dist/builtins/fs/download.d.ts +6 -0
- package/dist/builtins/fs/download.js +41 -0
- package/dist/builtins/fs/download.js.map +1 -0
- package/dist/builtins/fs/du.d.ts +58 -0
- package/dist/builtins/fs/du.js +210 -0
- package/dist/builtins/fs/du.js.map +1 -0
- package/dist/builtins/fs/edit.d.ts +7 -0
- package/dist/builtins/fs/edit.js +86 -0
- package/dist/builtins/fs/edit.js.map +1 -0
- package/dist/builtins/fs/ls.d.ts +8 -0
- package/dist/builtins/fs/ls.js +68 -0
- package/dist/builtins/fs/ls.js.map +1 -0
- package/dist/builtins/fs/mkdir.d.ts +6 -0
- package/dist/builtins/fs/mkdir.js +38 -0
- package/dist/builtins/fs/mkdir.js.map +1 -0
- package/dist/builtins/fs/mv.d.ts +7 -0
- package/dist/builtins/fs/mv.js +75 -0
- package/dist/builtins/fs/mv.js.map +1 -0
- package/dist/builtins/fs/pull.args.d.ts +22 -0
- package/dist/builtins/fs/pull.args.js +30 -0
- package/dist/builtins/fs/pull.args.js.map +1 -0
- package/dist/builtins/fs/pull.d.ts +26 -0
- package/dist/builtins/fs/pull.js +413 -0
- package/dist/builtins/fs/pull.js.map +1 -0
- package/dist/builtins/fs/pwd.d.ts +7 -0
- package/dist/builtins/fs/pwd.js +75 -0
- package/dist/builtins/fs/pwd.js.map +1 -0
- package/dist/builtins/fs/rm.d.ts +31 -0
- package/dist/builtins/fs/rm.js +148 -0
- package/dist/builtins/fs/rm.js.map +1 -0
- package/dist/builtins/fs/touch.d.ts +6 -0
- package/dist/builtins/fs/touch.js +64 -0
- package/dist/builtins/fs/touch.js.map +1 -0
- package/dist/builtins/fs/tree.d.ts +15 -0
- package/dist/builtins/fs/tree.js +84 -0
- package/dist/builtins/fs/tree.js.map +1 -0
- package/dist/builtins/fs/upload.d.ts +6 -0
- package/dist/builtins/fs/upload.js +45 -0
- package/dist/builtins/fs/upload.js.map +1 -0
- package/dist/builtins/help.d.ts +74 -0
- package/dist/builtins/help.js +1217 -0
- package/dist/builtins/help.js.map +1 -0
- package/dist/builtins/index.d.ts +45 -0
- package/dist/builtins/index.js +45 -0
- package/dist/builtins/index.js.map +1 -0
- package/dist/builtins/net/connect.d.ts +7 -0
- package/dist/builtins/net/connect.js +42 -0
- package/dist/builtins/net/connect.js.map +1 -0
- package/dist/builtins/net/cubepath.d.ts +18 -0
- package/dist/builtins/net/cubepath.js +102 -0
- package/dist/builtins/net/cubepath.js.map +1 -0
- package/dist/builtins/net/logout.d.ts +6 -0
- package/dist/builtins/net/logout.js +24 -0
- package/dist/builtins/net/logout.js.map +1 -0
- package/dist/builtins/net/pacs.d.ts +24 -0
- package/dist/builtins/net/pacs.js +121 -0
- package/dist/builtins/net/pacs.js.map +1 -0
- package/dist/builtins/net/pacsUtils.d.ts +85 -0
- package/dist/builtins/net/pacsUtils.js +184 -0
- package/dist/builtins/net/pacsUtils.js.map +1 -0
- package/dist/builtins/net/query.d.ts +60 -0
- package/dist/builtins/net/query.js +304 -0
- package/dist/builtins/net/query.js.map +1 -0
- package/dist/builtins/parametersofplugin.d.ts +13 -0
- package/dist/builtins/parametersofplugin.js +43 -0
- package/dist/builtins/parametersofplugin.js.map +1 -0
- package/dist/builtins/pluginExecute.d.ts +27 -0
- package/dist/builtins/pluginExecute.js +165 -0
- package/dist/builtins/pluginExecute.js.map +1 -0
- package/dist/builtins/proc.d.ts +6 -0
- package/dist/builtins/proc.helpers.d.ts +68 -0
- package/dist/builtins/proc.helpers.js +102 -0
- package/dist/builtins/proc.helpers.js.map +1 -0
- package/dist/builtins/proc.js +289 -0
- package/dist/builtins/proc.js.map +1 -0
- package/dist/builtins/res/compute.d.ts +6 -0
- package/dist/builtins/res/compute.js +55 -0
- package/dist/builtins/res/compute.js.map +1 -0
- package/dist/builtins/res/feed.d.ts +6 -0
- package/dist/builtins/res/feed.js +244 -0
- package/dist/builtins/res/feed.js.map +1 -0
- package/dist/builtins/res/feed.notes.d.ts +28 -0
- package/dist/builtins/res/feed.notes.js +24 -0
- package/dist/builtins/res/feed.notes.js.map +1 -0
- package/dist/builtins/res/files.d.ts +18 -0
- package/dist/builtins/res/files.js +85 -0
- package/dist/builtins/res/files.js.map +1 -0
- package/dist/builtins/res/group.d.ts +6 -0
- package/dist/builtins/res/group.js +54 -0
- package/dist/builtins/res/group.js.map +1 -0
- package/dist/builtins/res/pipeline.args.d.ts +22 -0
- package/dist/builtins/res/pipeline.args.js +28 -0
- package/dist/builtins/res/pipeline.args.js.map +1 -0
- package/dist/builtins/res/pipeline.d.ts +20 -0
- package/dist/builtins/res/pipeline.js +252 -0
- package/dist/builtins/res/pipeline.js.map +1 -0
- package/dist/builtins/res/plugin.d.ts +13 -0
- package/dist/builtins/res/plugin.js +140 -0
- package/dist/builtins/res/plugin.js.map +1 -0
- package/dist/builtins/res/plugininstance.d.ts +6 -0
- package/dist/builtins/res/plugininstance.js +53 -0
- package/dist/builtins/res/plugininstance.js.map +1 -0
- package/dist/builtins/res/pluginmeta.d.ts +6 -0
- package/dist/builtins/res/pluginmeta.js +53 -0
- package/dist/builtins/res/pluginmeta.js.map +1 -0
- package/dist/builtins/res/tag.d.ts +6 -0
- package/dist/builtins/res/tag.js +53 -0
- package/dist/builtins/res/tag.js.map +1 -0
- package/dist/builtins/res/workflow.d.ts +6 -0
- package/dist/builtins/res/workflow.js +53 -0
- package/dist/builtins/res/workflow.js.map +1 -0
- package/dist/builtins/store.d.ts +6 -0
- package/dist/builtins/store.js +108 -0
- package/dist/builtins/store.js.map +1 -0
- package/dist/builtins/sys/context.d.ts +6 -0
- package/dist/builtins/sys/context.js +50 -0
- package/dist/builtins/sys/context.js.map +1 -0
- package/dist/builtins/sys/physicalmode.d.ts +6 -0
- package/dist/builtins/sys/physicalmode.js +41 -0
- package/dist/builtins/sys/physicalmode.js.map +1 -0
- package/dist/builtins/sys/prompt.d.ts +13 -0
- package/dist/builtins/sys/prompt.helpers.d.ts +31 -0
- package/dist/builtins/sys/prompt.helpers.js +36 -0
- package/dist/builtins/sys/prompt.helpers.js.map +1 -0
- package/dist/builtins/sys/prompt.js +182 -0
- package/dist/builtins/sys/prompt.js.map +1 -0
- package/dist/builtins/sys/timing.d.ts +6 -0
- package/dist/builtins/sys/timing.js +41 -0
- package/dist/builtins/sys/timing.js.map +1 -0
- package/dist/builtins/sys/whoami.d.ts +12 -0
- package/dist/builtins/sys/whoami.js +37 -0
- package/dist/builtins/sys/whoami.js.map +1 -0
- package/dist/builtins/utils.d.ts +55 -0
- package/dist/builtins/utils.js +145 -0
- package/dist/builtins/utils.js.map +1 -0
- package/dist/builtins/wildcard.d.ts +26 -0
- package/dist/builtins/wildcard.js +120 -0
- package/dist/builtins/wildcard.js.map +1 -0
- package/dist/chell.d.ts +16 -0
- package/dist/chell.js +1193 -0
- package/dist/chell.js.map +1 -0
- package/dist/command-keys.d.ts +8 -0
- package/dist/command-keys.js +32 -0
- package/dist/command-keys.js.map +1 -0
- package/dist/config/settings.d.ts +39 -0
- package/dist/config/settings.js +93 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/core/bootFlags.d.ts +32 -0
- package/dist/core/bootFlags.js +25 -0
- package/dist/core/bootFlags.js.map +1 -0
- package/dist/core/cli.d.ts +58 -0
- package/dist/core/cli.js +251 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/prompt/index.d.ts +80 -0
- package/dist/core/prompt/index.js +29 -0
- package/dist/core/prompt/index.js.map +1 -0
- package/dist/core/prompt/theme_default.d.ts +19 -0
- package/dist/core/prompt/theme_default.js +47 -0
- package/dist/core/prompt/theme_default.js.map +1 -0
- package/dist/core/prompt/theme_p10k.d.ts +22 -0
- package/dist/core/prompt/theme_p10k.js +164 -0
- package/dist/core/prompt/theme_p10k.js.map +1 -0
- package/dist/core/prompt/utils.d.ts +23 -0
- package/dist/core/prompt/utils.js +40 -0
- package/dist/core/prompt/utils.js.map +1 -0
- package/dist/core/question.d.ts +34 -0
- package/dist/core/question.js +76 -0
- package/dist/core/question.js.map +1 -0
- package/dist/core/repl.d.ts +31 -0
- package/dist/core/repl.js +146 -0
- package/dist/core/repl.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/bootsequence.d.ts +62 -0
- package/dist/lib/bootsequence.js +222 -0
- package/dist/lib/bootsequence.js.map +1 -0
- package/dist/lib/completer/index.d.ts +15 -0
- package/dist/lib/completer/index.js +212 -0
- package/dist/lib/completer/index.js.map +1 -0
- package/dist/lib/completer/pathComplete.helpers.d.ts +22 -0
- package/dist/lib/completer/pathComplete.helpers.js +49 -0
- package/dist/lib/completer/pathComplete.helpers.js.map +1 -0
- package/dist/lib/logo.d.ts +47 -0
- package/dist/lib/logo.js +313 -0
- package/dist/lib/logo.js.map +1 -0
- package/dist/lib/parser.d.ts +13 -0
- package/dist/lib/parser.js +52 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/pipe.d.ts +11 -0
- package/dist/lib/pipe.js +90 -0
- package/dist/lib/pipe.js.map +1 -0
- package/dist/lib/prefetch.d.ts +25 -0
- package/dist/lib/prefetch.js +64 -0
- package/dist/lib/prefetch.js.map +1 -0
- package/dist/lib/semicolonParser.d.ts +22 -0
- package/dist/lib/semicolonParser.js +53 -0
- package/dist/lib/semicolonParser.js.map +1 -0
- package/dist/lib/spinner.d.ts +23 -0
- package/dist/lib/spinner.js +68 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/vfs/providers/static.d.ts +65 -0
- package/dist/lib/vfs/providers/static.js +164 -0
- package/dist/lib/vfs/providers/static.js.map +1 -0
- package/dist/lib/vfs/providers/static_content.d.ts +27 -0
- package/dist/lib/vfs/providers/static_content.js +180 -0
- package/dist/lib/vfs/providers/static_content.js.map +1 -0
- package/dist/lib/vfs/vfs.d.ts +59 -0
- package/dist/lib/vfs/vfs.js +198 -0
- package/dist/lib/vfs/vfs.js.map +1 -0
- package/dist/session/index.d.ts +76 -0
- package/dist/session/index.js +120 -0
- package/dist/session/index.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Plugin Execute Builtin
|
|
3
|
+
*
|
|
4
|
+
* This module implements the builtin for executing plugins "in place"
|
|
5
|
+
* based on current directory context.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Executes a plugin in the current directory context.
|
|
11
|
+
*
|
|
12
|
+
* This function is called when the user types a plugin name that exists in /bin.
|
|
13
|
+
* It handles parameter parsing, interactive prompts, and delegates execution to salsa.
|
|
14
|
+
*
|
|
15
|
+
* @param pluginName - Full plugin name with version (e.g., pl-dcm2niix-v2.1.1).
|
|
16
|
+
* @param args - Array of command line arguments.
|
|
17
|
+
* @returns Promise that resolves when execution completes.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // User types: pl-dcm2niix-v2.1.1 --outputdir results -- feed_title="Brain MRI"
|
|
22
|
+
* await builtin_executePlugin('pl-dcm2niix-v2.1.1', [
|
|
23
|
+
* '--outputdir', 'results', '--', 'feed_title=Brain MRI'
|
|
24
|
+
* ]);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function builtin_executePlugin(pluginName: string, args: string[]): Promise<void>;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Plugin Execute Builtin
|
|
3
|
+
*
|
|
4
|
+
* This module implements the builtin for executing plugins "in place"
|
|
5
|
+
* based on current directory context.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { plugin_executeInPlace } from '@fnndsc/salsa';
|
|
10
|
+
import { dictionary_fromCLI, errorStack, procCache_get } from '@fnndsc/cumin';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import { session } from '../session/index.js';
|
|
13
|
+
import { vfs } from '../lib/vfs/vfs.js';
|
|
14
|
+
/**
|
|
15
|
+
* Parses a plugin name from /bin format (name-vVersion) into ChRIS search format.
|
|
16
|
+
*
|
|
17
|
+
* @param pluginName - Plugin name in format: pl-name-vX.Y.Z
|
|
18
|
+
* @returns Search string in format: name_exact:pl-name,version:X.Y.Z
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* pluginName_toSearchString('pl-dcm2niix-v1.0.2')
|
|
23
|
+
* // Returns: 'name_exact:pl-dcm2niix,version:1.0.2'
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function pluginName_toSearchString(pluginName) {
|
|
27
|
+
// Pattern: (name)-v(version)
|
|
28
|
+
const match = pluginName.match(/^(.+)-v(.+)$/);
|
|
29
|
+
if (match) {
|
|
30
|
+
const name = match[1];
|
|
31
|
+
const version = match[2];
|
|
32
|
+
return `name_exact:${name},version:${version}`;
|
|
33
|
+
}
|
|
34
|
+
// Fallback: if no version suffix, search by name only
|
|
35
|
+
return `name_exact:${pluginName}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Executes a plugin in the current directory context.
|
|
39
|
+
*
|
|
40
|
+
* This function is called when the user types a plugin name that exists in /bin.
|
|
41
|
+
* It handles parameter parsing, interactive prompts, and delegates execution to salsa.
|
|
42
|
+
*
|
|
43
|
+
* @param pluginName - Full plugin name with version (e.g., pl-dcm2niix-v2.1.1).
|
|
44
|
+
* @param args - Array of command line arguments.
|
|
45
|
+
* @returns Promise that resolves when execution completes.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* // User types: pl-dcm2niix-v2.1.1 --outputdir results -- feed_title="Brain MRI"
|
|
50
|
+
* await builtin_executePlugin('pl-dcm2niix-v2.1.1', [
|
|
51
|
+
* '--outputdir', 'results', '--', 'feed_title=Brain MRI'
|
|
52
|
+
* ]);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export async function builtin_executePlugin(pluginName, args) {
|
|
56
|
+
try {
|
|
57
|
+
// 1. Parse arguments - split on '--' delimiter
|
|
58
|
+
const argsString = args.join(' ');
|
|
59
|
+
let pluginArgsStr = argsString;
|
|
60
|
+
let contextArgsStr = '';
|
|
61
|
+
// Check for ' -- ' delimiter (space-dash-dash-space)
|
|
62
|
+
const delimiterIndex = argsString.indexOf(' -- ');
|
|
63
|
+
if (delimiterIndex !== -1) {
|
|
64
|
+
pluginArgsStr = argsString.substring(0, delimiterIndex);
|
|
65
|
+
contextArgsStr = argsString.substring(delimiterIndex + 4); // +4 to skip ' -- '
|
|
66
|
+
}
|
|
67
|
+
// 2. Parse both sets of parameters
|
|
68
|
+
let pluginParams = {};
|
|
69
|
+
let contextParams = {};
|
|
70
|
+
if (pluginArgsStr.trim()) {
|
|
71
|
+
try {
|
|
72
|
+
pluginParams = dictionary_fromCLI(pluginArgsStr);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
76
|
+
console.error(chalk.red(`Error parsing plugin parameters: ${msg}`));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (contextArgsStr.trim()) {
|
|
81
|
+
try {
|
|
82
|
+
contextParams = dictionary_fromCLI(contextArgsStr);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
86
|
+
console.error(chalk.red(`Error parsing context parameters: ${msg}`));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// 3. Set default context params if not provided
|
|
91
|
+
const cwd = await session.getCWD();
|
|
92
|
+
const isInFeed = cwd.includes('/feeds/feed_');
|
|
93
|
+
// If no context params provided and not in a feed, use directory name as feed title
|
|
94
|
+
if (!contextArgsStr && !isInFeed) {
|
|
95
|
+
const defaultTitle = cwd.split('/').pop() || 'Untitled';
|
|
96
|
+
contextParams.feed_title = defaultTitle;
|
|
97
|
+
console.log(chalk.cyan(`Using feed title: "${defaultTitle}" (customize with -- feed_title="Custom Title")`));
|
|
98
|
+
}
|
|
99
|
+
// 4. Get /bin listing for finding pl-dircopy
|
|
100
|
+
const binResult = await vfs.data_get('/bin');
|
|
101
|
+
if (!binResult.ok) {
|
|
102
|
+
console.error(chalk.red('Failed to access /bin directory'));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const binListing = binResult.value.map((item) => item.name);
|
|
106
|
+
// 5. Convert plugin name from /bin format to ChRIS search format
|
|
107
|
+
// Example: pl-dcm2niix-v1.0.2 → name_exact:pl-dcm2niix,version:1.0.2
|
|
108
|
+
const pluginSearchString = pluginName_toSearchString(pluginName);
|
|
109
|
+
// 6. Execute via salsa
|
|
110
|
+
const result = await plugin_executeInPlace(pluginSearchString, pluginParams, contextParams, cwd, binListing);
|
|
111
|
+
if (!result) {
|
|
112
|
+
// Display all errors from the stack for better debugging
|
|
113
|
+
console.error(chalk.red('Plugin execution failed:'));
|
|
114
|
+
let error = errorStack.stack_pop();
|
|
115
|
+
while (error) {
|
|
116
|
+
console.error(chalk.red(` - ${error.message}`));
|
|
117
|
+
error = errorStack.stack_pop();
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// 7. Push to procCache so /proc reflects new jobs immediately
|
|
122
|
+
if (result.feedID !== undefined && result.dircopyInstanceID !== undefined) {
|
|
123
|
+
// New feed: push dircopy root node + plugin node
|
|
124
|
+
const feedTitle = cwd.split('/').pop() || `feed_${result.feedID}`;
|
|
125
|
+
procCache_get().feed_add({
|
|
126
|
+
id: result.feedID, title: feedTitle,
|
|
127
|
+
creationDate: new Date().toISOString(),
|
|
128
|
+
finishedJobs: 0, erroredJobs: 0, startedJobs: 0,
|
|
129
|
+
scheduledJobs: 2, cancelledJobs: 0, createdJobs: 0,
|
|
130
|
+
});
|
|
131
|
+
procCache_get().instance_add({
|
|
132
|
+
id: result.dircopyInstanceID, feedID: result.feedID,
|
|
133
|
+
parentID: null, pluginName: 'pl-dircopy', params: null,
|
|
134
|
+
});
|
|
135
|
+
procCache_get().instance_add({
|
|
136
|
+
id: result.pluginInstanceID, feedID: result.feedID,
|
|
137
|
+
parentID: result.dircopyInstanceID, pluginName: result.pluginName, params: null,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
else if (result.parentID !== null) {
|
|
141
|
+
// Continue feed: push just the new instance
|
|
142
|
+
const feedID = (() => {
|
|
143
|
+
const inst = procCache_get().instance_get(result.parentID);
|
|
144
|
+
return inst ? inst.feedID : null;
|
|
145
|
+
})();
|
|
146
|
+
if (feedID !== null) {
|
|
147
|
+
procCache_get().instance_add({
|
|
148
|
+
id: result.pluginInstanceID, feedID,
|
|
149
|
+
parentID: result.parentID, pluginName: result.pluginName, params: null,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// 8. Render output
|
|
154
|
+
if (result.feedID) {
|
|
155
|
+
console.log(chalk.green(`Feed created: ${result.feedID}`));
|
|
156
|
+
}
|
|
157
|
+
console.log(chalk.green(`Job scheduled: ${pluginName} (ID: ${result.pluginInstanceID})`));
|
|
158
|
+
console.log(chalk.cyan(`Output will be in: ${result.outputPath}`));
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
162
|
+
console.error(chalk.red(`Error executing plugin: ${msg}`));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=pluginExecute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pluginExecute.js","sourceRoot":"","sources":["../../src/builtins/pluginExecute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ProcFeed } from '@fnndsc/cumin';
|
|
2
|
+
/**
|
|
3
|
+
* Flat record representing one feed entry for resource-group-style listing.
|
|
4
|
+
* All ProcFeed counter fields exposed as first-class columns.
|
|
5
|
+
*/
|
|
6
|
+
export interface ProcJobEntry {
|
|
7
|
+
id: number;
|
|
8
|
+
title: string;
|
|
9
|
+
status: string;
|
|
10
|
+
finishedJobs: number;
|
|
11
|
+
erroredJobs: number;
|
|
12
|
+
startedJobs: number;
|
|
13
|
+
scheduledJobs: number;
|
|
14
|
+
cancelledJobs: number;
|
|
15
|
+
createdJobs: number;
|
|
16
|
+
creationDate: string;
|
|
17
|
+
instances: number | string;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
/** All job fields available for `proc jobs` listing. */
|
|
21
|
+
export declare const ALL_JOB_FIELDS: ReadonlyArray<string>;
|
|
22
|
+
/** Default columns shown for `proc jobs` listing. */
|
|
23
|
+
export declare const DEFAULT_JOB_FIELDS: ReadonlyArray<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Derives an aggregate status label for a feed from its job counters.
|
|
26
|
+
*
|
|
27
|
+
* @param feed - The feed whose counters are inspected.
|
|
28
|
+
* @returns A status label (e.g. `running`, `finishedWithError`).
|
|
29
|
+
*/
|
|
30
|
+
export declare function feedStatus_derive(feed: ProcFeed): string;
|
|
31
|
+
/**
|
|
32
|
+
* Colorizes a status label for terminal display.
|
|
33
|
+
*
|
|
34
|
+
* @param status - The status label.
|
|
35
|
+
* @returns The colorized status string.
|
|
36
|
+
*/
|
|
37
|
+
export declare function statusColor(status: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves the selected fields for a listing from a `--fields` argument,
|
|
40
|
+
* falling back to the default set.
|
|
41
|
+
*
|
|
42
|
+
* @param fieldsArg - Comma-separated field names (may be empty).
|
|
43
|
+
* @returns The selected field names.
|
|
44
|
+
*/
|
|
45
|
+
export declare function jobFields_select(fieldsArg: string): string[];
|
|
46
|
+
/**
|
|
47
|
+
* Filters job entries by a case-insensitive title substring.
|
|
48
|
+
*
|
|
49
|
+
* @param entries - The entries to filter.
|
|
50
|
+
* @param search - The search substring (empty returns all).
|
|
51
|
+
* @returns The matching entries.
|
|
52
|
+
*/
|
|
53
|
+
export declare function procEntries_filterBySearch(entries: ProcJobEntry[], search: string): ProcJobEntry[];
|
|
54
|
+
/**
|
|
55
|
+
* Renders job entries as CSV with quoted fields.
|
|
56
|
+
*
|
|
57
|
+
* @param rows - The entries to render.
|
|
58
|
+
* @param fields - The columns to include, in order.
|
|
59
|
+
* @returns The CSV string (header row plus data rows).
|
|
60
|
+
*/
|
|
61
|
+
export declare function procCsv_render(rows: ProcJobEntry[], fields: string[]): string;
|
|
62
|
+
/**
|
|
63
|
+
* Parses a feed identifier of the form `123` or `feed_123`.
|
|
64
|
+
*
|
|
65
|
+
* @param arg - The feed argument.
|
|
66
|
+
* @returns The numeric feed ID, or null if malformed.
|
|
67
|
+
*/
|
|
68
|
+
export declare function feedId_parse(arg: string): number | null;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pure helpers for the `proc` builtin.
|
|
3
|
+
*
|
|
4
|
+
* Status derivation/coloring, field selection, search filtering, CSV rendering,
|
|
5
|
+
* and feed-id parsing — all dependency-free (chalk only) for unit testing.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
/** All job fields available for `proc jobs` listing. */
|
|
11
|
+
export const ALL_JOB_FIELDS = [
|
|
12
|
+
'id', 'title', 'status',
|
|
13
|
+
'finishedJobs', 'erroredJobs', 'startedJobs',
|
|
14
|
+
'scheduledJobs', 'cancelledJobs', 'createdJobs',
|
|
15
|
+
'creationDate', 'instances',
|
|
16
|
+
];
|
|
17
|
+
/** Default columns shown for `proc jobs` listing. */
|
|
18
|
+
export const DEFAULT_JOB_FIELDS = [
|
|
19
|
+
'id', 'title', 'status', 'finishedJobs', 'erroredJobs',
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Derives an aggregate status label for a feed from its job counters.
|
|
23
|
+
*
|
|
24
|
+
* @param feed - The feed whose counters are inspected.
|
|
25
|
+
* @returns A status label (e.g. `running`, `finishedWithError`).
|
|
26
|
+
*/
|
|
27
|
+
export function feedStatus_derive(feed) {
|
|
28
|
+
if (feed.erroredJobs > 0)
|
|
29
|
+
return 'finishedWithError';
|
|
30
|
+
if (feed.startedJobs + feed.scheduledJobs + feed.createdJobs > 0)
|
|
31
|
+
return 'running';
|
|
32
|
+
if (feed.cancelledJobs > 0 && feed.finishedJobs === 0)
|
|
33
|
+
return 'cancelled';
|
|
34
|
+
if (feed.finishedJobs > 0)
|
|
35
|
+
return 'finishedSuccessfully';
|
|
36
|
+
return 'empty';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Colorizes a status label for terminal display.
|
|
40
|
+
*
|
|
41
|
+
* @param status - The status label.
|
|
42
|
+
* @returns The colorized status string.
|
|
43
|
+
*/
|
|
44
|
+
export function statusColor(status) {
|
|
45
|
+
if (status === 'finishedSuccessfully')
|
|
46
|
+
return chalk.green(status);
|
|
47
|
+
if (status === 'finishedWithError')
|
|
48
|
+
return chalk.red(status);
|
|
49
|
+
if (status === 'running')
|
|
50
|
+
return chalk.yellow(status);
|
|
51
|
+
if (status === 'cancelled')
|
|
52
|
+
return chalk.dim(status);
|
|
53
|
+
return chalk.gray(status);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Resolves the selected fields for a listing from a `--fields` argument,
|
|
57
|
+
* falling back to the default set.
|
|
58
|
+
*
|
|
59
|
+
* @param fieldsArg - Comma-separated field names (may be empty).
|
|
60
|
+
* @returns The selected field names.
|
|
61
|
+
*/
|
|
62
|
+
export function jobFields_select(fieldsArg) {
|
|
63
|
+
return fieldsArg
|
|
64
|
+
? fieldsArg.split(',').map((f) => f.trim()).filter(Boolean)
|
|
65
|
+
: [...DEFAULT_JOB_FIELDS];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Filters job entries by a case-insensitive title substring.
|
|
69
|
+
*
|
|
70
|
+
* @param entries - The entries to filter.
|
|
71
|
+
* @param search - The search substring (empty returns all).
|
|
72
|
+
* @returns The matching entries.
|
|
73
|
+
*/
|
|
74
|
+
export function procEntries_filterBySearch(entries, search) {
|
|
75
|
+
if (!search)
|
|
76
|
+
return entries;
|
|
77
|
+
const lower = search.toLowerCase();
|
|
78
|
+
return entries.filter((e) => e.title.toLowerCase().includes(lower));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Renders job entries as CSV with quoted fields.
|
|
82
|
+
*
|
|
83
|
+
* @param rows - The entries to render.
|
|
84
|
+
* @param fields - The columns to include, in order.
|
|
85
|
+
* @returns The CSV string (header row plus data rows).
|
|
86
|
+
*/
|
|
87
|
+
export function procCsv_render(rows, fields) {
|
|
88
|
+
const header = fields.map((f) => `"${f}"`).join(',');
|
|
89
|
+
const body = rows.map((e) => fields.map((f) => `"${String(e[f] ?? '').replace(/"/g, '""')}"`).join(',')).join('\n');
|
|
90
|
+
return [header, body].join('\n');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Parses a feed identifier of the form `123` or `feed_123`.
|
|
94
|
+
*
|
|
95
|
+
* @param arg - The feed argument.
|
|
96
|
+
* @returns The numeric feed ID, or null if malformed.
|
|
97
|
+
*/
|
|
98
|
+
export function feedId_parse(arg) {
|
|
99
|
+
const match = arg.match(/^(?:feed_)?(\d+)$/);
|
|
100
|
+
return match ? parseInt(match[1], 10) : null;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=proc.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proc.helpers.js","sourceRoot":"","sources":["../../src/builtins/proc.helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Builtin proc command.
|
|
3
|
+
* Manages the /proc VFS cache (job monitoring).
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { procCache_refresh, procFeed_ensureLoaded, jobs_find } from '@fnndsc/salsa';
|
|
7
|
+
import { procCache_get } from '@fnndsc/cumin';
|
|
8
|
+
import { spinner } from '../lib/spinner.js';
|
|
9
|
+
import { commandArgs_process } from './utils.js';
|
|
10
|
+
import { list_applySort } from '@fnndsc/chili/utils/sort.js';
|
|
11
|
+
import { screen, table_display } from '@fnndsc/chili/screen/screen.js';
|
|
12
|
+
import { ALL_JOB_FIELDS, feedStatus_derive, statusColor, jobFields_select, procEntries_filterBySearch, procCsv_render, feedId_parse, } from './proc.helpers.js';
|
|
13
|
+
// ── proc jobs ─────────────────────────────────────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* Builds flat job entries from the proc cache.
|
|
16
|
+
*
|
|
17
|
+
* @param cache - The proc cache.
|
|
18
|
+
* @returns One entry per known feed.
|
|
19
|
+
*/
|
|
20
|
+
function procEntries_fromCache(cache) {
|
|
21
|
+
return cache.feedIDs_get().map((feedID) => {
|
|
22
|
+
const feed = cache.feed_get(feedID);
|
|
23
|
+
const topoLoaded = cache.topologyLoaded_has(feedID);
|
|
24
|
+
return {
|
|
25
|
+
id: feed.id,
|
|
26
|
+
title: feed.title,
|
|
27
|
+
status: feedStatus_derive(feed),
|
|
28
|
+
finishedJobs: feed.finishedJobs,
|
|
29
|
+
erroredJobs: feed.erroredJobs,
|
|
30
|
+
startedJobs: feed.startedJobs,
|
|
31
|
+
scheduledJobs: feed.scheduledJobs,
|
|
32
|
+
cancelledJobs: feed.cancelledJobs,
|
|
33
|
+
createdJobs: feed.createdJobs,
|
|
34
|
+
creationDate: feed.creationDate ? feed.creationDate.substring(0, 10) : '',
|
|
35
|
+
instances: topoLoaded ? cache.instancesForFeed_count(feedID) : '-',
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Renders job entries as a bordered table.
|
|
41
|
+
*
|
|
42
|
+
* @param page - The entries to render.
|
|
43
|
+
* @param selectedFields - The columns to show.
|
|
44
|
+
*/
|
|
45
|
+
function procJobs_renderTable(page, selectedFields) {
|
|
46
|
+
const tableData = page.map((e) => {
|
|
47
|
+
const row = {};
|
|
48
|
+
selectedFields.forEach((f) => { row[f] = e[f] ?? ''; });
|
|
49
|
+
return row;
|
|
50
|
+
});
|
|
51
|
+
console.log(screen.table_output(tableData, {
|
|
52
|
+
head: selectedFields,
|
|
53
|
+
title: { title: 'proc jobs', justification: 'center' },
|
|
54
|
+
typeColors: { string: 'green', number: 'yellow', boolean: 'cyan', object: 'magenta' },
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Renders job entries as colorized, tab-separated lines.
|
|
59
|
+
*
|
|
60
|
+
* @param page - The entries to render.
|
|
61
|
+
* @param selectedFields - The columns to show.
|
|
62
|
+
*/
|
|
63
|
+
function procJobs_renderLines(page, selectedFields) {
|
|
64
|
+
for (const e of page) {
|
|
65
|
+
const cols = selectedFields.map((f) => {
|
|
66
|
+
const val = String(e[f] ?? '');
|
|
67
|
+
if (f === 'id')
|
|
68
|
+
return chalk.bold(val);
|
|
69
|
+
if (f === 'title')
|
|
70
|
+
return chalk.cyan(val);
|
|
71
|
+
if (f === 'status')
|
|
72
|
+
return statusColor(val);
|
|
73
|
+
if (f === 'erroredJobs' && e.erroredJobs > 0)
|
|
74
|
+
return chalk.red(val);
|
|
75
|
+
return val;
|
|
76
|
+
});
|
|
77
|
+
console.log(cols.join('\t'));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Handles `proc jobs [inspect|list]`: lists cached feed jobs with optional
|
|
82
|
+
* search, sort, paging, field selection, and CSV/table output.
|
|
83
|
+
*
|
|
84
|
+
* @param args - Arguments following `proc jobs`.
|
|
85
|
+
*/
|
|
86
|
+
async function jobs_subcmd(args) {
|
|
87
|
+
const second = args[0];
|
|
88
|
+
if (second === 'inspect') {
|
|
89
|
+
table_display([...ALL_JOB_FIELDS].map((f) => ({ field: f })), ['field'], { title: { title: 'proc jobs fields', justification: 'center' } });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const listArgs = second === 'list' ? args.slice(1) : args;
|
|
93
|
+
const parsed = commandArgs_process(listArgs);
|
|
94
|
+
let entries = procEntries_fromCache(procCache_get());
|
|
95
|
+
entries = procEntries_filterBySearch(entries, String(parsed['search'] ?? ''));
|
|
96
|
+
if (entries.length === 0) {
|
|
97
|
+
console.log(chalk.gray('No feeds in cache.'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const sortField = String(parsed['sort'] ?? '');
|
|
101
|
+
if (sortField)
|
|
102
|
+
entries = list_applySort(entries, sortField, !!parsed['reverse']);
|
|
103
|
+
const showAll = !!parsed['all'];
|
|
104
|
+
const limit = showAll ? entries.length : Math.max(1, Number(parsed['limit'] ?? 20));
|
|
105
|
+
const page = entries.slice(0, limit);
|
|
106
|
+
const selectedFields = jobFields_select(String(parsed['fields'] ?? ''));
|
|
107
|
+
if (parsed['csv']) {
|
|
108
|
+
console.log(procCsv_render(page, selectedFields));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (parsed['table']) {
|
|
112
|
+
procJobs_renderTable(page, selectedFields);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
procJobs_renderLines(page, selectedFields);
|
|
116
|
+
if (!showAll && entries.length > limit) {
|
|
117
|
+
console.log(chalk.gray(` … ${entries.length - limit} more. Use --all or --limit <n>.`));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// ── proc subcommand handlers ────────────────────────────────────────────────
|
|
121
|
+
/**
|
|
122
|
+
* Handles `proc refresh [feed]`: refreshes the cache for one feed or all.
|
|
123
|
+
*
|
|
124
|
+
* @param args - Full command args (`args[1]` is the optional feed).
|
|
125
|
+
*/
|
|
126
|
+
async function procRefresh_handle(args) {
|
|
127
|
+
const feedArg = args[1];
|
|
128
|
+
let feedID;
|
|
129
|
+
if (feedArg) {
|
|
130
|
+
const parsedId = feedId_parse(feedArg);
|
|
131
|
+
if (parsedId === null) {
|
|
132
|
+
console.error(chalk.red(`proc refresh: invalid feed ID '${feedArg}'`));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
feedID = parsedId;
|
|
136
|
+
}
|
|
137
|
+
const scope = feedID !== undefined ? `feed_${feedID}` : 'all feeds';
|
|
138
|
+
spinner.start(`Refreshing /proc cache (${scope})...`);
|
|
139
|
+
try {
|
|
140
|
+
await procCache_refresh(feedID);
|
|
141
|
+
spinner.stop();
|
|
142
|
+
console.log(chalk.green(`/proc cache refreshed (${scope})`));
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
spinner.stop();
|
|
146
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
147
|
+
console.error(chalk.red(`proc refresh failed: ${msg}`));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Handles `proc find <query>`: locates instances by id/plugin-name and prints
|
|
152
|
+
* their /proc paths.
|
|
153
|
+
*
|
|
154
|
+
* @param args - Full command args (`args[1]` is the query).
|
|
155
|
+
*/
|
|
156
|
+
async function procFind_handle(args) {
|
|
157
|
+
const query = args[1];
|
|
158
|
+
if (!query) {
|
|
159
|
+
console.error(chalk.red('Usage: proc find <instance_id | plugin_name_substring>'));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
spinner.start(`Finding "${query}"...`);
|
|
163
|
+
try {
|
|
164
|
+
const cache = procCache_get();
|
|
165
|
+
const result = await jobs_find(query);
|
|
166
|
+
if (!result.ok) {
|
|
167
|
+
spinner.stop();
|
|
168
|
+
console.error(chalk.red(`Search failed.`));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const matches = result.value;
|
|
172
|
+
if (matches.length === 0) {
|
|
173
|
+
spinner.stop();
|
|
174
|
+
console.error(chalk.yellow(`No instances found matching "${query}".`));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const feedIDs = [...new Set(matches.map((m) => m.feedID))];
|
|
178
|
+
await Promise.all(feedIDs.map((feedID) => procFeed_ensureLoaded(feedID)));
|
|
179
|
+
spinner.stop();
|
|
180
|
+
for (const m of matches) {
|
|
181
|
+
const path = cache.path_build(m.id);
|
|
182
|
+
if (path)
|
|
183
|
+
console.log(path);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
spinner.stop();
|
|
188
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
189
|
+
console.error(chalk.red(`proc find failed: ${msg}`));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Handles `proc feeds <query>`: lists cached feeds whose title matches.
|
|
194
|
+
*
|
|
195
|
+
* @param args - Full command args (`args[1]` is the query).
|
|
196
|
+
*/
|
|
197
|
+
async function procFeeds_handle(args) {
|
|
198
|
+
const query = args[1];
|
|
199
|
+
if (!query) {
|
|
200
|
+
console.error(chalk.red('Usage: proc feeds <title_substring>'));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const cache = procCache_get();
|
|
204
|
+
const matches = cache.feeds_find(query);
|
|
205
|
+
if (matches.length === 0) {
|
|
206
|
+
console.error(chalk.yellow(`No feeds found with title containing "${query}".`));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
for (const feed of matches) {
|
|
210
|
+
const status = feedStatus_derive(feed);
|
|
211
|
+
console.log(`/proc/jobs/feed_${feed.id} ${statusColor(status)} ${chalk.dim(feed.title)}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Handles `proc stat [feed]`: prints a cache summary or a single feed's detail.
|
|
216
|
+
*
|
|
217
|
+
* @param args - Full command args (`args[1]` is the optional feed).
|
|
218
|
+
*/
|
|
219
|
+
async function procStat_handle(args) {
|
|
220
|
+
const cache = procCache_get();
|
|
221
|
+
const feedArg = args[1];
|
|
222
|
+
if (!feedArg) {
|
|
223
|
+
const warmup = cache.warmupProgress_get();
|
|
224
|
+
const warmupLine = warmup.active
|
|
225
|
+
? chalk.yellow(`in progress (${warmup.loaded} instances loaded)`)
|
|
226
|
+
: cache.warmupComplete
|
|
227
|
+
? chalk.green('complete')
|
|
228
|
+
: chalk.dim('not started');
|
|
229
|
+
console.log(chalk.bold('proc cache summary'));
|
|
230
|
+
console.log(` feeds known : ${chalk.cyan(String(cache.feedIDs_get().length))}`);
|
|
231
|
+
console.log(` instances : ${chalk.cyan(String(cache.instances_count()))}`);
|
|
232
|
+
console.log(` topology sweep : ${warmupLine}`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const feedID = feedId_parse(feedArg);
|
|
236
|
+
if (feedID === null) {
|
|
237
|
+
console.error(chalk.red(`proc stat: invalid feed ID '${feedArg}'`));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const feed = cache.feed_get(feedID);
|
|
241
|
+
if (!feed) {
|
|
242
|
+
console.error(chalk.yellow(`proc stat: feed_${feedID} not in cache`));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const topoLoaded = cache.topologyLoaded_has(feedID);
|
|
246
|
+
const instCount = topoLoaded ? cache.instancesForFeed_count(feedID) : -1;
|
|
247
|
+
const status = feedStatus_derive(feed);
|
|
248
|
+
console.log(chalk.bold(`feed_${feedID}`));
|
|
249
|
+
console.log(` title : ${chalk.cyan(feed.title)}`);
|
|
250
|
+
console.log(` status : ${statusColor(status)}`);
|
|
251
|
+
console.log(` finishedJobs : ${feed.finishedJobs}`);
|
|
252
|
+
console.log(` erroredJobs : ${chalk[feed.erroredJobs > 0 ? 'red' : 'white'](String(feed.erroredJobs))}`);
|
|
253
|
+
console.log(` startedJobs : ${feed.startedJobs}`);
|
|
254
|
+
console.log(` scheduledJobs : ${feed.scheduledJobs}`);
|
|
255
|
+
console.log(` cancelledJobs : ${feed.cancelledJobs}`);
|
|
256
|
+
console.log(` createdJobs : ${feed.createdJobs}`);
|
|
257
|
+
console.log(` topology : ${topoLoaded ? chalk.green(`loaded (${instCount} instances)`) : chalk.dim('not loaded')}`);
|
|
258
|
+
}
|
|
259
|
+
// ── Main dispatcher ───────────────────────────────────────────────────────────
|
|
260
|
+
/**
|
|
261
|
+
* Handles proc commands.
|
|
262
|
+
*
|
|
263
|
+
* @param args - command arguments.
|
|
264
|
+
*/
|
|
265
|
+
export async function builtin_proc(args) {
|
|
266
|
+
const subcommand = args[0];
|
|
267
|
+
if (!subcommand || subcommand === 'refresh') {
|
|
268
|
+
await procRefresh_handle(args);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (subcommand === 'jobs') {
|
|
272
|
+
await jobs_subcmd(args.slice(1));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (subcommand === 'find') {
|
|
276
|
+
await procFind_handle(args);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (subcommand === 'feeds') {
|
|
280
|
+
await procFeeds_handle(args);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (subcommand === 'stat') {
|
|
284
|
+
await procStat_handle(args);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
console.error(chalk.red(`proc: unknown subcommand '${subcommand}'. Use proc --help.`));
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=proc.js.map
|