@fnndsc/brasa 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/debug.d.ts +8 -0
- package/dist/builtins/debug.js +39 -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 +266 -0
- package/dist/builtins/fs/cat.js.map +1 -0
- package/dist/builtins/fs/cd.d.ts +42 -0
- package/dist/builtins/fs/cd.js +193 -0
- package/dist/builtins/fs/cd.js.map +1 -0
- package/dist/builtins/fs/cp.d.ts +10 -0
- package/dist/builtins/fs/cp.js +86 -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 +45 -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 +104 -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 +9 -0
- package/dist/builtins/fs/mkdir.js +52 -0
- package/dist/builtins/fs/mkdir.js.map +1 -0
- package/dist/builtins/fs/mv.d.ts +10 -0
- package/dist/builtins/fs/mv.js +88 -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 +445 -0
- package/dist/builtins/fs/pull.js.map +1 -0
- package/dist/builtins/fs/pwd.d.ts +10 -0
- package/dist/builtins/fs/pwd.js +73 -0
- package/dist/builtins/fs/pwd.js.map +1 -0
- package/dist/builtins/fs/rm.d.ts +37 -0
- package/dist/builtins/fs/rm.js +197 -0
- package/dist/builtins/fs/rm.js.map +1 -0
- package/dist/builtins/fs/touch.d.ts +9 -0
- package/dist/builtins/fs/touch.js +76 -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 +48 -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 +324 -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 +107 -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 +8 -0
- package/dist/builtins/sys/physicalmode.js +34 -0
- package/dist/builtins/sys/physicalmode.js.map +1 -0
- package/dist/builtins/sys/timing.d.ts +8 -0
- package/dist/builtins/sys/timing.js +34 -0
- package/dist/builtins/sys/timing.js.map +1 -0
- package/dist/builtins/sys/version.d.ts +15 -0
- package/dist/builtins/sys/version.js +23 -0
- package/dist/builtins/sys/version.js.map +1 -0
- package/dist/builtins/sys/whoami.d.ts +17 -0
- package/dist/builtins/sys/whoami.js +44 -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/command-keys.d.ts +8 -0
- package/dist/command-keys.js +32 -0
- package/dist/command-keys.js.map +1 -0
- package/dist/config/storeConfig.d.ts +57 -0
- package/dist/config/storeConfig.js +78 -0
- package/dist/config/storeConfig.js.map +1 -0
- package/dist/core/chiliDelegate.d.ts +21 -0
- package/dist/core/chiliDelegate.js +32 -0
- package/dist/core/chiliDelegate.js.map +1 -0
- package/dist/core/connect.d.ts +38 -0
- package/dist/core/connect.js +46 -0
- package/dist/core/connect.js.map +1 -0
- package/dist/core/dispatch.d.ts +95 -0
- package/dist/core/dispatch.js +618 -0
- package/dist/core/dispatch.js.map +1 -0
- package/dist/core/engine.d.ts +91 -0
- package/dist/core/engine.js +222 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/preprocess.d.ts +46 -0
- package/dist/core/preprocess.js +146 -0
- package/dist/core/preprocess.js.map +1 -0
- package/dist/core/progress.d.ts +50 -0
- package/dist/core/progress.js +21 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/promptContext.d.ts +49 -0
- package/dist/core/promptContext.js +39 -0
- package/dist/core/promptContext.js.map +1 -0
- package/dist/core/question.d.ts +27 -0
- package/dist/core/question.js +33 -0
- package/dist/core/question.js.map +1 -0
- package/dist/core/sink.d.ts +207 -0
- package/dist/core/sink.js +329 -0
- package/dist/core/sink.js.map +1 -0
- package/dist/core/surface.d.ts +172 -0
- package/dist/core/surface.js +105 -0
- package/dist/core/surface.js.map +1 -0
- package/dist/core/version.d.ts +20 -0
- package/dist/core/version.js +82 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +32 -0
- package/dist/index.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/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 +71 -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 +202 -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 +58 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { CommandEnvelope } from '@fnndsc/cumin';
|
|
2
|
+
/**
|
|
3
|
+
* Result of a completion request: the candidates and the prefix they
|
|
4
|
+
* complete, matching what a readline completer consumes.
|
|
5
|
+
*
|
|
6
|
+
* @property candidates - The matching completion candidates.
|
|
7
|
+
* @property prefix - The input prefix the candidates complete.
|
|
8
|
+
*/
|
|
9
|
+
export interface CompletionResult {
|
|
10
|
+
candidates: string[];
|
|
11
|
+
prefix: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The hostable shell engine.
|
|
15
|
+
*
|
|
16
|
+
* One engine serves one session: it executes command lines against the
|
|
17
|
+
* shared session state and answers completion requests. Hosts own the
|
|
18
|
+
* output destination (via the sink) and the input source (a readline loop,
|
|
19
|
+
* a socket); the engine owns everything between.
|
|
20
|
+
*/
|
|
21
|
+
export interface BrasaEngine {
|
|
22
|
+
/**
|
|
23
|
+
* Executes one input line and returns one envelope per executed command.
|
|
24
|
+
*
|
|
25
|
+
* @param line - The raw input line (may contain `;`, `|`, `>`, `!`).
|
|
26
|
+
* @returns The envelopes of the executed commands, in execution order.
|
|
27
|
+
*/
|
|
28
|
+
line_execute(line: string): Promise<CommandEnvelope[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Computes completion candidates for a partial input line.
|
|
31
|
+
*
|
|
32
|
+
* @param linePrefix - The input line up to the cursor.
|
|
33
|
+
* @returns The matching candidates and the prefix they complete.
|
|
34
|
+
*/
|
|
35
|
+
line_complete(linePrefix: string): Promise<CompletionResult>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Sets the shared stop-on-error flag. Exposed so the boot layer (which owns
|
|
39
|
+
* the `-e` flag and script execution) can drive the flag that the batch
|
|
40
|
+
* loop reads.
|
|
41
|
+
*
|
|
42
|
+
* @param value - `true` to abort a batch on the first error.
|
|
43
|
+
*/
|
|
44
|
+
export declare function stopOnError_set(value: boolean): void;
|
|
45
|
+
/**
|
|
46
|
+
* Executes one input line and returns one envelope per executed command.
|
|
47
|
+
*
|
|
48
|
+
* Line-level constructs are recognized in the shell's historical order:
|
|
49
|
+
* shell escape first (the whole line goes to the host shell), then
|
|
50
|
+
* semicolon batching (each segment recurses through this function), then
|
|
51
|
+
* output redirection, then pipes, then plain dispatch. Output reaches the
|
|
52
|
+
* active sink as each command completes.
|
|
53
|
+
*
|
|
54
|
+
* @param line - The raw input line.
|
|
55
|
+
* @returns The envelopes of the executed commands, in execution order.
|
|
56
|
+
*/
|
|
57
|
+
export declare function line_execute(line: string): Promise<CommandEnvelope[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Computes completion candidates for a partial input line.
|
|
60
|
+
*
|
|
61
|
+
* Promise-shaped facade over the callback-style completer, for hosts that
|
|
62
|
+
* answer completion requests asynchronously (a remote surface's tab press).
|
|
63
|
+
* Completion failures resolve to no candidates; they never reject, matching
|
|
64
|
+
* the completer's own never-crash contract.
|
|
65
|
+
*
|
|
66
|
+
* @param linePrefix - The input line up to the cursor.
|
|
67
|
+
* @returns The matching candidates and the prefix they complete.
|
|
68
|
+
*/
|
|
69
|
+
export declare function line_complete(linePrefix: string): Promise<CompletionResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Handles a command entered by the user.
|
|
72
|
+
*
|
|
73
|
+
* Compatibility shape over {@link line_execute} for callers that do not
|
|
74
|
+
* consume envelopes.
|
|
75
|
+
*
|
|
76
|
+
* @param line - The input line.
|
|
77
|
+
* @returns A Promise that resolves once the command has been processed.
|
|
78
|
+
*/
|
|
79
|
+
export declare function command_handle(line: string): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Creates the engine: initializes session state, registers the VFS
|
|
82
|
+
* providers, and returns the facade a host drives.
|
|
83
|
+
*
|
|
84
|
+
* Establishing a CUBE connection is deliberately not the engine's concern —
|
|
85
|
+
* connection setup involves host-owned interaction (credential prompting,
|
|
86
|
+
* boot reporting) and the engine executes correctly both offline and
|
|
87
|
+
* connected.
|
|
88
|
+
*
|
|
89
|
+
* @returns The engine facade.
|
|
90
|
+
*/
|
|
91
|
+
export declare function engine_create(): Promise<BrasaEngine>;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The chell engine facade: line execution and completion behind one
|
|
3
|
+
* hostable interface.
|
|
4
|
+
*
|
|
5
|
+
* The engine is the seam between the shell's deterministic core (dispatch,
|
|
6
|
+
* session, VFS) and whatever hosts it. The CLI REPL is one host; a session
|
|
7
|
+
* daemon serving remote surfaces is the next. A host creates the engine,
|
|
8
|
+
* installs an output sink, and drives it one line at a time:
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* const engine: BrasaEngine = await engine_create();
|
|
12
|
+
* const envelopes: CommandEnvelope[] = await engine.line_execute('ls; pwd');
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* `line_execute` owns line-level orchestration — shell escape, semicolon
|
|
16
|
+
* batching, redirects, pipes — and yields exactly one envelope per executed
|
|
17
|
+
* command. Output is delivered through the active sink as each command
|
|
18
|
+
* completes, so a terminal host sees output live; the returned envelopes are
|
|
19
|
+
* the records an envelope-aware host (daemon, test) consumes.
|
|
20
|
+
*
|
|
21
|
+
* Single-command execution and the command table live in `./dispatch.js`;
|
|
22
|
+
* this module deliberately keeps its cumin imports type-only.
|
|
23
|
+
*
|
|
24
|
+
* @see docs/calypso.adoc for the governing design.
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
import chalk from 'chalk';
|
|
28
|
+
import { session } from '../session/index.js';
|
|
29
|
+
import { semicolons_parse } from '../lib/semicolonParser.js';
|
|
30
|
+
import { pipes_parse, redirect_parse, command_shellEscape_detect, } from './preprocess.js';
|
|
31
|
+
import { shellCommand_execute, command_executeToEnvelope, command_timingMaybePrint, redirect_execute, pipe_execute, } from './dispatch.js';
|
|
32
|
+
/**
|
|
33
|
+
* Whether a batch (semicolon list, script) should abort on the first error.
|
|
34
|
+
* Read by the batch loop; set by the boot layer for `-e` / script modes.
|
|
35
|
+
*/
|
|
36
|
+
let stopOnError = false;
|
|
37
|
+
/**
|
|
38
|
+
* Sets the shared stop-on-error flag. Exposed so the boot layer (which owns
|
|
39
|
+
* the `-e` flag and script execution) can drive the flag that the batch
|
|
40
|
+
* loop reads.
|
|
41
|
+
*
|
|
42
|
+
* @param value - `true` to abort a batch on the first error.
|
|
43
|
+
*/
|
|
44
|
+
export function stopOnError_set(value) {
|
|
45
|
+
stopOnError = value;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Executes a shell-escaped line (`!command`) on the host system.
|
|
49
|
+
*
|
|
50
|
+
* @param trimmedLine - The trimmed input line including the leading `!`.
|
|
51
|
+
* @param startTime - Timing reference from `performance.now()`.
|
|
52
|
+
* @param timingEnabled - Whether to print elapsed time after execution.
|
|
53
|
+
* @returns One envelope carrying the host command's outcome, or none for a
|
|
54
|
+
* bare `!`.
|
|
55
|
+
*/
|
|
56
|
+
async function shellEscape_execute(trimmedLine, startTime, timingEnabled) {
|
|
57
|
+
const shellCommand = trimmedLine.substring(1).trim();
|
|
58
|
+
if (!shellCommand)
|
|
59
|
+
return [];
|
|
60
|
+
const exitCode = await shellCommand_execute(shellCommand);
|
|
61
|
+
command_timingMaybePrint(startTime, timingEnabled);
|
|
62
|
+
return [{ status: exitCode === 0 ? 'ok' : 'error', rendered: '' }];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Executes a semicolon batch, one segment at a time, collecting each
|
|
66
|
+
* segment's envelopes.
|
|
67
|
+
*
|
|
68
|
+
* A segment that throws yields an error envelope; the batch continues unless
|
|
69
|
+
* stop-on-error is set, in which case the envelopes collected so far are
|
|
70
|
+
* returned immediately (and no total time is printed, matching the shell's
|
|
71
|
+
* historical behavior).
|
|
72
|
+
*
|
|
73
|
+
* @param commands - The batch segments in execution order.
|
|
74
|
+
* @param startTime - Timing reference from `performance.now()`.
|
|
75
|
+
* @param timingEnabled - Whether to print the batch's total elapsed time.
|
|
76
|
+
* @returns The envelopes of all executed segments, in execution order.
|
|
77
|
+
*/
|
|
78
|
+
async function batch_execute(commands, startTime, timingEnabled) {
|
|
79
|
+
const envelopes = [];
|
|
80
|
+
for (const command of commands) {
|
|
81
|
+
try {
|
|
82
|
+
envelopes.push(...await line_execute(command));
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
86
|
+
console.error(chalk.red(`Command error: ${msg}`));
|
|
87
|
+
envelopes.push({ status: 'error', rendered: '' });
|
|
88
|
+
if (stopOnError) {
|
|
89
|
+
return envelopes;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (timingEnabled) {
|
|
94
|
+
const elapsed = performance.now() - startTime;
|
|
95
|
+
console.log(chalk.gray(`[Total: ${elapsed.toFixed(2)}ms]`));
|
|
96
|
+
}
|
|
97
|
+
return envelopes;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Executes one input line and returns one envelope per executed command.
|
|
101
|
+
*
|
|
102
|
+
* Line-level constructs are recognized in the shell's historical order:
|
|
103
|
+
* shell escape first (the whole line goes to the host shell), then
|
|
104
|
+
* semicolon batching (each segment recurses through this function), then
|
|
105
|
+
* output redirection, then pipes, then plain dispatch. Output reaches the
|
|
106
|
+
* active sink as each command completes.
|
|
107
|
+
*
|
|
108
|
+
* @param line - The raw input line.
|
|
109
|
+
* @returns The envelopes of the executed commands, in execution order.
|
|
110
|
+
*/
|
|
111
|
+
export async function line_execute(line) {
|
|
112
|
+
const trimmedLine = line.trim();
|
|
113
|
+
if (!trimmedLine)
|
|
114
|
+
return [];
|
|
115
|
+
// Start timing if enabled
|
|
116
|
+
const timingEnabled = session.timingEnabled_get();
|
|
117
|
+
const startTime = timingEnabled ? performance.now() : 0;
|
|
118
|
+
if (command_shellEscape_detect(trimmedLine)) {
|
|
119
|
+
return shellEscape_execute(trimmedLine, startTime, timingEnabled);
|
|
120
|
+
}
|
|
121
|
+
const batch = semicolons_parse(trimmedLine);
|
|
122
|
+
if (batch.length > 1) {
|
|
123
|
+
return batch_execute(batch, startTime, timingEnabled);
|
|
124
|
+
}
|
|
125
|
+
const redirectInfo = redirect_parse(trimmedLine);
|
|
126
|
+
if (redirectInfo) {
|
|
127
|
+
const envelope = await redirect_execute(redirectInfo);
|
|
128
|
+
if (envelope.status === 'ok') {
|
|
129
|
+
command_timingMaybePrint(startTime, timingEnabled);
|
|
130
|
+
}
|
|
131
|
+
return [envelope];
|
|
132
|
+
}
|
|
133
|
+
const pipeSegments = pipes_parse(trimmedLine);
|
|
134
|
+
if (pipeSegments.length > 1) {
|
|
135
|
+
try {
|
|
136
|
+
const envelope = await pipe_execute(pipeSegments);
|
|
137
|
+
command_timingMaybePrint(startTime, timingEnabled);
|
|
138
|
+
return [envelope];
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
142
|
+
console.error(chalk.red(`Pipe error: ${msg}`));
|
|
143
|
+
return [{ status: 'error', rendered: '' }];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const envelope = await command_executeToEnvelope(trimmedLine, startTime, timingEnabled);
|
|
147
|
+
return envelope ? [envelope] : [];
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Computes completion candidates for a partial input line.
|
|
151
|
+
*
|
|
152
|
+
* Promise-shaped facade over the callback-style completer, for hosts that
|
|
153
|
+
* answer completion requests asynchronously (a remote surface's tab press).
|
|
154
|
+
* Completion failures resolve to no candidates; they never reject, matching
|
|
155
|
+
* the completer's own never-crash contract.
|
|
156
|
+
*
|
|
157
|
+
* @param linePrefix - The input line up to the cursor.
|
|
158
|
+
* @returns The matching candidates and the prefix they complete.
|
|
159
|
+
*/
|
|
160
|
+
export async function line_complete(linePrefix) {
|
|
161
|
+
const { input_complete } = await import('../lib/completer/index.js');
|
|
162
|
+
return new Promise((resolve) => {
|
|
163
|
+
input_complete(linePrefix, (err, result) => {
|
|
164
|
+
if (err || !result) {
|
|
165
|
+
resolve({ candidates: [], prefix: linePrefix });
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
resolve({ candidates: result[0], prefix: result[1] });
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Handles a command entered by the user.
|
|
174
|
+
*
|
|
175
|
+
* Compatibility shape over {@link line_execute} for callers that do not
|
|
176
|
+
* consume envelopes.
|
|
177
|
+
*
|
|
178
|
+
* @param line - The input line.
|
|
179
|
+
* @returns A Promise that resolves once the command has been processed.
|
|
180
|
+
*/
|
|
181
|
+
export async function command_handle(line) {
|
|
182
|
+
await line_execute(line);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Registers the static VFS providers and the logical→physical path resolver
|
|
186
|
+
* hook on the shared salsa vfsDispatcher.
|
|
187
|
+
*/
|
|
188
|
+
async function vfsProviders_register() {
|
|
189
|
+
const { vfsDispatcher } = await import('@fnndsc/salsa');
|
|
190
|
+
const { StaticVfsProvider } = await import('../lib/vfs/providers/static.js');
|
|
191
|
+
vfsDispatcher.provider_register(new StaticVfsProvider('/bin'));
|
|
192
|
+
vfsDispatcher.provider_register(new StaticVfsProvider('/usr'));
|
|
193
|
+
vfsDispatcher.provider_register(new StaticVfsProvider('/usr/bin'));
|
|
194
|
+
vfsDispatcher.pathResolver_register(async (logicalPath) => {
|
|
195
|
+
if (session.physicalMode_get()) {
|
|
196
|
+
return logicalPath;
|
|
197
|
+
}
|
|
198
|
+
const { logical_toPhysical } = await import('@fnndsc/chili/utils');
|
|
199
|
+
const res = await logical_toPhysical(logicalPath);
|
|
200
|
+
if (res.ok) {
|
|
201
|
+
return res.value;
|
|
202
|
+
}
|
|
203
|
+
throw new Error(`Logical-to-physical resolution failed for path: ${logicalPath}`);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Creates the engine: initializes session state, registers the VFS
|
|
208
|
+
* providers, and returns the facade a host drives.
|
|
209
|
+
*
|
|
210
|
+
* Establishing a CUBE connection is deliberately not the engine's concern —
|
|
211
|
+
* connection setup involves host-owned interaction (credential prompting,
|
|
212
|
+
* boot reporting) and the engine executes correctly both offline and
|
|
213
|
+
* connected.
|
|
214
|
+
*
|
|
215
|
+
* @returns The engine facade.
|
|
216
|
+
*/
|
|
217
|
+
export async function engine_create() {
|
|
218
|
+
await session.init();
|
|
219
|
+
await vfsProviders_register();
|
|
220
|
+
return { line_execute, line_complete };
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Result } from '@fnndsc/cumin';
|
|
2
|
+
/**
|
|
3
|
+
* Determines if a command should have its arguments expanded for wildcards.
|
|
4
|
+
*
|
|
5
|
+
* @param command - The command name.
|
|
6
|
+
* @returns True if wildcards should be expanded.
|
|
7
|
+
*/
|
|
8
|
+
export declare function wildcards_expandCheck(command: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Returns true if the input line is a shell escape (starts with `!`).
|
|
11
|
+
*
|
|
12
|
+
* @param line - Trimmed input line.
|
|
13
|
+
*/
|
|
14
|
+
export declare function command_shellEscape_detect(line: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Parses a command line for pipe operators and returns segments.
|
|
17
|
+
* Respects single and double quotes.
|
|
18
|
+
*
|
|
19
|
+
* @param line - The full command line.
|
|
20
|
+
* @returns An array of command segments.
|
|
21
|
+
*/
|
|
22
|
+
export declare function pipes_parse(line: string): string[];
|
|
23
|
+
/** Parsed output-redirection: command plus target file and append/overwrite. */
|
|
24
|
+
export interface RedirectInfo {
|
|
25
|
+
command: string;
|
|
26
|
+
operator: '>' | '>>';
|
|
27
|
+
filePath: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parses a command line for output redirection operators (> or >>).
|
|
31
|
+
* Respects single and double quotes.
|
|
32
|
+
*
|
|
33
|
+
* @param line - The full command line.
|
|
34
|
+
* @returns An object with the command and redirect info, or null if no redirection.
|
|
35
|
+
*/
|
|
36
|
+
export declare function redirect_parse(line: string): RedirectInfo | null;
|
|
37
|
+
/**
|
|
38
|
+
* Resolves the final redirect target path. If the target is an existing directory
|
|
39
|
+
* and the source command is `cat <file>`, resolves to `<dir>/<basename>`.
|
|
40
|
+
* Returns Err (with message on errorStack) when the filename cannot be determined.
|
|
41
|
+
*
|
|
42
|
+
* @param filePath - The redirect target path as written by the user.
|
|
43
|
+
* @param commandLine - The command whose output is being redirected.
|
|
44
|
+
* @returns Ok(resolved path) or Err on failure.
|
|
45
|
+
*/
|
|
46
|
+
export declare function redirectTarget_resolve(filePath: string, commandLine: string): Result<string>;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Command-line preprocessing: pure parsing of pipes, redirects and
|
|
3
|
+
* wildcard/shell-escape detection.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { statSync } from 'fs';
|
|
9
|
+
import { Ok, Err, errorStack } from '@fnndsc/cumin';
|
|
10
|
+
import { args_tokenize } from '../lib/parser.js';
|
|
11
|
+
/** Commands whose arguments benefit from glob/wildcard expansion. */
|
|
12
|
+
const WILDCARD_COMMANDS = ['ls', 'rm', 'cat', 'mv', 'cp', 'du', 'tree'];
|
|
13
|
+
/**
|
|
14
|
+
* Determines if a command should have its arguments expanded for wildcards.
|
|
15
|
+
*
|
|
16
|
+
* @param command - The command name.
|
|
17
|
+
* @returns True if wildcards should be expanded.
|
|
18
|
+
*/
|
|
19
|
+
export function wildcards_expandCheck(command) {
|
|
20
|
+
return WILDCARD_COMMANDS.includes(command);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns true if the input line is a shell escape (starts with `!`).
|
|
24
|
+
*
|
|
25
|
+
* @param line - Trimmed input line.
|
|
26
|
+
*/
|
|
27
|
+
export function command_shellEscape_detect(line) {
|
|
28
|
+
return line.startsWith('!');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parses a command line for pipe operators and returns segments.
|
|
32
|
+
* Respects single and double quotes.
|
|
33
|
+
*
|
|
34
|
+
* @param line - The full command line.
|
|
35
|
+
* @returns An array of command segments.
|
|
36
|
+
*/
|
|
37
|
+
export function pipes_parse(line) {
|
|
38
|
+
const segments = [];
|
|
39
|
+
let currentSegment = '';
|
|
40
|
+
let inSingleQuote = false;
|
|
41
|
+
let inDoubleQuote = false;
|
|
42
|
+
for (let i = 0; i < line.length; i++) {
|
|
43
|
+
const char = line[i];
|
|
44
|
+
if (char === "'" && !inDoubleQuote) {
|
|
45
|
+
inSingleQuote = !inSingleQuote;
|
|
46
|
+
currentSegment += char;
|
|
47
|
+
}
|
|
48
|
+
else if (char === '"' && !inSingleQuote) {
|
|
49
|
+
inDoubleQuote = !inDoubleQuote;
|
|
50
|
+
currentSegment += char;
|
|
51
|
+
}
|
|
52
|
+
else if (char === '|' && !inSingleQuote && !inDoubleQuote) {
|
|
53
|
+
segments.push(currentSegment.trim());
|
|
54
|
+
currentSegment = '';
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
currentSegment += char;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (currentSegment.trim()) {
|
|
61
|
+
segments.push(currentSegment.trim());
|
|
62
|
+
}
|
|
63
|
+
return segments;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Parses a command line for output redirection operators (> or >>).
|
|
67
|
+
* Respects single and double quotes.
|
|
68
|
+
*
|
|
69
|
+
* @param line - The full command line.
|
|
70
|
+
* @returns An object with the command and redirect info, or null if no redirection.
|
|
71
|
+
*/
|
|
72
|
+
export function redirect_parse(line) {
|
|
73
|
+
let inSingleQuote = false;
|
|
74
|
+
let inDoubleQuote = false;
|
|
75
|
+
for (let i = 0; i < line.length; i++) {
|
|
76
|
+
const char = line[i];
|
|
77
|
+
if (char === "'" && !inDoubleQuote) {
|
|
78
|
+
inSingleQuote = !inSingleQuote;
|
|
79
|
+
}
|
|
80
|
+
else if (char === '"' && !inSingleQuote) {
|
|
81
|
+
inDoubleQuote = !inDoubleQuote;
|
|
82
|
+
}
|
|
83
|
+
else if (!inSingleQuote && !inDoubleQuote) {
|
|
84
|
+
// Check for >>
|
|
85
|
+
if (i < line.length - 1 && line[i] === '>' && line[i + 1] === '>') {
|
|
86
|
+
const command = line.substring(0, i).trim();
|
|
87
|
+
const filePath = line.substring(i + 2).trim();
|
|
88
|
+
return { command, operator: '>>', filePath };
|
|
89
|
+
}
|
|
90
|
+
// Check for >
|
|
91
|
+
else if (line[i] === '>') {
|
|
92
|
+
const command = line.substring(0, i).trim();
|
|
93
|
+
const filePath = line.substring(i + 1).trim();
|
|
94
|
+
return { command, operator: '>', filePath };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolves the final redirect target path. If the target is an existing directory
|
|
102
|
+
* and the source command is `cat <file>`, resolves to `<dir>/<basename>`.
|
|
103
|
+
* Returns Err (with message on errorStack) when the filename cannot be determined.
|
|
104
|
+
*
|
|
105
|
+
* @param filePath - The redirect target path as written by the user.
|
|
106
|
+
* @param commandLine - The command whose output is being redirected.
|
|
107
|
+
* @returns Ok(resolved path) or Err on failure.
|
|
108
|
+
*/
|
|
109
|
+
export function redirectTarget_resolve(filePath, commandLine) {
|
|
110
|
+
try {
|
|
111
|
+
const stats = statSync(filePath);
|
|
112
|
+
if (!stats.isDirectory()) {
|
|
113
|
+
return Ok(filePath);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
const nodeErr = err;
|
|
118
|
+
if (nodeErr.code === 'ENOENT') {
|
|
119
|
+
return Ok(filePath);
|
|
120
|
+
}
|
|
121
|
+
errorStack.stack_push('error', `Redirect: filesystem error for '${filePath}': ${String(err)}`);
|
|
122
|
+
return Err();
|
|
123
|
+
}
|
|
124
|
+
const tokens = args_tokenize(commandLine);
|
|
125
|
+
if (tokens.length === 0) {
|
|
126
|
+
errorStack.stack_push('error', `Redirect target '${filePath}' is a directory and no source command was provided.`);
|
|
127
|
+
return Err();
|
|
128
|
+
}
|
|
129
|
+
const [command, ...args] = tokens;
|
|
130
|
+
if (command !== 'cat') {
|
|
131
|
+
errorStack.stack_push('error', `Redirect target '${filePath}' is a directory; cannot infer filename for command '${command}'.`);
|
|
132
|
+
return Err();
|
|
133
|
+
}
|
|
134
|
+
const sourceArgs = args.filter((arg) => arg !== '--binary');
|
|
135
|
+
if (sourceArgs.length === 0) {
|
|
136
|
+
errorStack.stack_push('error', `Redirect target '${filePath}' is a directory; no source file provided to 'cat'.`);
|
|
137
|
+
return Err();
|
|
138
|
+
}
|
|
139
|
+
if (sourceArgs.length > 1) {
|
|
140
|
+
errorStack.stack_push('error', `Redirect target '${filePath}' is a directory; 'cat' with multiple files cannot choose a single output name.`);
|
|
141
|
+
return Err();
|
|
142
|
+
}
|
|
143
|
+
const sourceName = path.basename(sourceArgs[0]);
|
|
144
|
+
return Ok(path.join(filePath, sourceName));
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=preprocess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preprocess.js","sourceRoot":"","sources":["../../src/core/preprocess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Structured progress events emitted by commands and rendered by hosts.
|
|
3
|
+
*
|
|
4
|
+
* Progress is semantic live telemetry. It is not command output, is never
|
|
5
|
+
* captured into envelopes, and is never consumed by pipes or redirects.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
export type ProgressOperation = 'upload' | 'download' | 'pull' | 'workflow';
|
|
10
|
+
export type ProgressKind = 'transfer' | 'retrieve' | 'workflow';
|
|
11
|
+
export type ProgressPhase = 'scanning' | 'transferring' | 'watching' | 'retrying' | 'complete' | 'failed';
|
|
12
|
+
export type ProgressUnit = 'files' | 'bytes' | 'series' | 'jobs' | 'nodes';
|
|
13
|
+
export type ProgressStatus = 'running' | 'done' | 'unconfirmed' | 'stalled' | 'timeout' | 'error' | 'unknown';
|
|
14
|
+
export interface ProgressEvent {
|
|
15
|
+
operation: ProgressOperation;
|
|
16
|
+
kind?: ProgressKind;
|
|
17
|
+
phase: ProgressPhase;
|
|
18
|
+
label?: string;
|
|
19
|
+
itemId?: string;
|
|
20
|
+
current?: number;
|
|
21
|
+
total?: number;
|
|
22
|
+
percent?: number;
|
|
23
|
+
unit?: ProgressUnit;
|
|
24
|
+
status?: ProgressStatus;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Renders progress events for a frontend.
|
|
28
|
+
*
|
|
29
|
+
* The engine emits {@link ProgressEvent}s and knows nothing about how they are
|
|
30
|
+
* shown. Each frontend supplies its own implementation: a terminal draws bars,
|
|
31
|
+
* a daemon forwards the events over its wire, a headless host drops them.
|
|
32
|
+
*/
|
|
33
|
+
export interface ProgressRenderer {
|
|
34
|
+
/**
|
|
35
|
+
* Renders a single progress event.
|
|
36
|
+
*
|
|
37
|
+
* @param event - The progress telemetry to render.
|
|
38
|
+
*/
|
|
39
|
+
write(event: ProgressEvent): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Progress renderer that drops every event.
|
|
43
|
+
*
|
|
44
|
+
* The engine's default when no frontend has supplied a live renderer, so
|
|
45
|
+
* headless hosts incur no terminal coupling.
|
|
46
|
+
*/
|
|
47
|
+
export declare class NullProgressRenderer implements ProgressRenderer {
|
|
48
|
+
/** @inheritdoc */
|
|
49
|
+
write(_event: ProgressEvent): void;
|
|
50
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Structured progress events emitted by commands and rendered by hosts.
|
|
3
|
+
*
|
|
4
|
+
* Progress is semantic live telemetry. It is not command output, is never
|
|
5
|
+
* captured into envelopes, and is never consumed by pipes or redirects.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Progress renderer that drops every event.
|
|
11
|
+
*
|
|
12
|
+
* The engine's default when no frontend has supplied a live renderer, so
|
|
13
|
+
* headless hosts incur no terminal coupling.
|
|
14
|
+
*/
|
|
15
|
+
export class NullProgressRenderer {
|
|
16
|
+
/** @inheritdoc */
|
|
17
|
+
write(_event) {
|
|
18
|
+
// Progress is live telemetry: with no frontend to render it, it is dropped.
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/core/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqCH;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAC/B,kBAAkB;IACX,KAAK,CAAC,MAAqB;QAChC,4EAA4E;IAC9E,CAAC;CACF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The session's prompt context: the engine-known facts a prompt reflects.
|
|
3
|
+
*
|
|
4
|
+
* A prompt shows live session state — user, CUBE, working directory, PACS,
|
|
5
|
+
* physical-mode, warm-up progress — plus the last command's outcome. Only the
|
|
6
|
+
* process holding the session can know these, but how they are *rendered*
|
|
7
|
+
* (theme, segments, terminal width) is a frontend concern. This module builds
|
|
8
|
+
* the engine half; each frontend renders it with its own theme, so the daemon
|
|
9
|
+
* ships context and never a themed string.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The engine-known facts a prompt reflects, independent of any theme.
|
|
15
|
+
*
|
|
16
|
+
* This is the shape carried over the wire to remote frontends. Rendering
|
|
17
|
+
* inputs a frontend owns (terminal width, enabled segments, theme) are not
|
|
18
|
+
* here — each surface supplies its own.
|
|
19
|
+
*/
|
|
20
|
+
export interface SessionPromptContext {
|
|
21
|
+
user: string;
|
|
22
|
+
uri: string;
|
|
23
|
+
cwd: string;
|
|
24
|
+
pacsserver: string | null;
|
|
25
|
+
physicalMode: boolean;
|
|
26
|
+
lastExitCode: number;
|
|
27
|
+
lastCommandDurationMs: number;
|
|
28
|
+
/** Present while /proc topology warm-up is in progress. */
|
|
29
|
+
procWarmup?: {
|
|
30
|
+
loaded: number;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Inputs the caller knows that the session state does not.
|
|
35
|
+
*
|
|
36
|
+
* @property lastExitCode - The previous command's exit code (default 0).
|
|
37
|
+
* @property lastCommandDurationMs - The previous command's duration (default 0).
|
|
38
|
+
*/
|
|
39
|
+
export interface SessionPromptContextOptions {
|
|
40
|
+
lastExitCode?: number;
|
|
41
|
+
lastCommandDurationMs?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Builds the current session's prompt context.
|
|
45
|
+
*
|
|
46
|
+
* @param options - The last-command inputs the session cannot know.
|
|
47
|
+
* @returns The engine-known prompt facts.
|
|
48
|
+
*/
|
|
49
|
+
export declare function sessionPromptContext_build(options?: SessionPromptContextOptions): Promise<SessionPromptContext>;
|