@silverbulletmd/silverbullet 2.9.0 → 2.10.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/README.md +36 -23
- package/client/plugos/hooks/syscall.ts +24 -10
- package/client/plugos/syscalls/asset.ts +61 -23
- package/client/plugos/syscalls/clientStore.ts +32 -6
- package/client/plugos/syscalls/client_code_widget.ts +9 -4
- package/client/plugos/syscalls/code_widget.ts +26 -11
- package/client/plugos/syscalls/config.ts +146 -30
- package/client/plugos/syscalls/datastore.ts +146 -40
- package/client/plugos/syscalls/editor.ts +1432 -711
- package/client/plugos/syscalls/event.ts +46 -13
- package/client/plugos/syscalls/fetch.ts +123 -82
- package/client/plugos/syscalls/index.ts +242 -116
- package/client/plugos/syscalls/jsonschema.ts +107 -8
- package/client/plugos/syscalls/language.ts +38 -12
- package/client/plugos/syscalls/markdown.ts +166 -50
- package/client/plugos/syscalls/mq.ts +93 -20
- package/client/plugos/syscalls/schema_introspection.ts +33 -0
- package/client/plugos/syscalls/service_registry.ts +74 -20
- package/client/plugos/syscalls/shell.ts +51 -20
- package/client/plugos/syscalls/space.ts +169 -113
- package/client/plugos/syscalls/sync.ts +50 -19
- package/client/plugos/syscalls/system.ts +236 -139
- package/client/plugos/system.ts +21 -5
- package/client/space_lua/api_documentation.ts +107 -0
- package/client/space_lua/ast.ts +13 -0
- package/client/space_lua/eval.ts +12 -4
- package/client/space_lua/parse.ts +243 -108
- package/client/space_lua/pretty_print.ts +128 -54
- package/client/space_lua/query_collection.ts +4 -4
- package/client/space_lua/render_widget.ts +156 -0
- package/client/space_lua/runtime.ts +83 -22
- package/client/space_lua/stdlib/crypto.ts +8 -3
- package/client/space_lua/stdlib/encoding.ts +27 -9
- package/client/space_lua/stdlib/js.ts +137 -22
- package/client/space_lua/stdlib/load.ts +24 -15
- package/client/space_lua/stdlib/math.ts +323 -118
- package/client/space_lua/stdlib/net.ts +57 -9
- package/client/space_lua/stdlib/os.ts +111 -44
- package/client/space_lua/stdlib/space_lua.ts +344 -20
- package/client/space_lua/stdlib/string.ts +282 -104
- package/client/space_lua/stdlib/string_pack.ts +58 -19
- package/client/space_lua/stdlib/table.ts +195 -40
- package/client/space_lua/stdlib.ts +335 -93
- package/client/space_lua/syscalls.ts +270 -0
- package/dist/plug-compile.js +1 -1
- package/package.json +3 -3
- package/plug-api/lib/ref.ts +96 -0
- package/plug-api/lib/shortcut.ts +2 -1
- package/plug-api/syscalls/config.ts +5 -3
- package/plug-api/syscalls/editor.ts +16 -0
- package/plug-api/syscalls/index.ts +17 -1
- package/plug-api/syscalls/jsonschema.ts +9 -0
- package/plug-api/syscalls/lua.ts +7 -0
- package/plug-api/syscalls/shell.ts +0 -1
- package/plug-api/syscalls/system.ts +7 -0
- package/plug-api/system_mock.ts +2 -2
- package/plug-api/types/index.ts +52 -1
- package/plug-api/types/manifest.ts +22 -4
- package/plug-api/ui/cx.ts +1 -3
- package/plug-api/ui/index.ts +3 -0
- package/plug-api/ui/panel_styles.ts +4 -3
- package/plug-api/ui/slugify.ts +44 -0
- package/client/plugos/syscalls/lua.ts +0 -81
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type MarkdownExpandOptions,
|
|
11
11
|
} from "../../markdown_renderer/inline.ts";
|
|
12
12
|
import type { Client } from "../../client.ts";
|
|
13
|
+
import { bakeSectionsInText } from "../../baked_sections/bake.ts";
|
|
13
14
|
import {
|
|
14
15
|
type MarkdownRenderOptions,
|
|
15
16
|
renderMarkdownToHtml,
|
|
@@ -22,62 +23,177 @@ import * as TagConstants from "../../../plugs/index/constants.ts";
|
|
|
22
23
|
|
|
23
24
|
export function markdownSyscalls(client: Client): SysCallMapping {
|
|
24
25
|
return {
|
|
25
|
-
"markdown.parseMarkdown":
|
|
26
|
-
|
|
26
|
+
"markdown.parseMarkdown": {
|
|
27
|
+
callback: (_ctx, text: string): ParseTree => {
|
|
28
|
+
return parse(markdownLanguageWithUserExtensions(client), text);
|
|
29
|
+
},
|
|
30
|
+
description: "Parses Markdown text into a syntax tree.",
|
|
31
|
+
parameters: [
|
|
32
|
+
{ name: "text", type: "string", description: "Markdown source." },
|
|
33
|
+
],
|
|
34
|
+
returns: [{ type: "table", description: "Parsed Markdown tree." }],
|
|
35
|
+
examples: [{ code: 'local tree = markdown.parseMarkdown("# Title")' }],
|
|
27
36
|
},
|
|
28
|
-
"markdown.renderParseTree":
|
|
29
|
-
|
|
37
|
+
"markdown.renderParseTree": {
|
|
38
|
+
callback: (_ctx, tree: ParseTree): string => {
|
|
39
|
+
return renderToText(tree);
|
|
40
|
+
},
|
|
41
|
+
description: "Renders a Markdown syntax tree back to source text.",
|
|
42
|
+
parameters: [
|
|
43
|
+
{ name: "tree", type: "table", description: "Markdown syntax tree." },
|
|
44
|
+
],
|
|
45
|
+
returns: [{ type: "string", description: "Rendered Markdown." }],
|
|
46
|
+
examples: [
|
|
47
|
+
{
|
|
48
|
+
code: 'local tree = markdown.parseMarkdown("# Title")\nprint(markdown.renderParseTree(tree))',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
30
51
|
},
|
|
31
|
-
"markdown.expandMarkdown":
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
treeOrText
|
|
39
|
-
|
|
52
|
+
"markdown.expandMarkdown": {
|
|
53
|
+
callback: async (
|
|
54
|
+
_ctx,
|
|
55
|
+
treeOrText: ParseTree | string,
|
|
56
|
+
options?: MarkdownExpandOptions,
|
|
57
|
+
): Promise<ParseTree | string> => {
|
|
58
|
+
const outputString = typeof treeOrText === "string";
|
|
59
|
+
if (typeof treeOrText === "string") {
|
|
60
|
+
treeOrText = parse(
|
|
61
|
+
markdownLanguageWithUserExtensions(client),
|
|
62
|
+
treeOrText,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const result = await expandMarkdownWithClient(
|
|
66
|
+
client,
|
|
40
67
|
treeOrText,
|
|
68
|
+
options,
|
|
41
69
|
);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
70
|
+
if (outputString) {
|
|
71
|
+
return renderToText(result);
|
|
72
|
+
} else {
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
description:
|
|
77
|
+
"Expands Markdown transclusions, Lua directives, and task references.",
|
|
78
|
+
signatures: [
|
|
79
|
+
"markdown.expandMarkdown(text, options?)",
|
|
80
|
+
"markdown.expandMarkdown(tree, options?)",
|
|
81
|
+
],
|
|
82
|
+
parameters: [
|
|
83
|
+
{ name: "textOrTree", description: "Markdown text or parsed tree." },
|
|
84
|
+
{
|
|
85
|
+
name: "options",
|
|
86
|
+
type: "table",
|
|
87
|
+
description:
|
|
88
|
+
"Expansion switches: expandTransclusions, expandLuaDirectives, and rewriteTasks; all default to true.",
|
|
89
|
+
optional: true,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
returns: [
|
|
93
|
+
{ description: "Expanded text or tree, matching the input form." },
|
|
94
|
+
],
|
|
95
|
+
examples: [
|
|
96
|
+
{
|
|
97
|
+
code: 'local expanded = markdown.expandMarkdown("This is some Lua: ${1 + 2}")',
|
|
98
|
+
},
|
|
99
|
+
],
|
|
53
100
|
},
|
|
54
|
-
"markdown.markdownToHtml":
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
options.resolveTagHref
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
101
|
+
"markdown.markdownToHtml": {
|
|
102
|
+
callback: async (
|
|
103
|
+
_ctx,
|
|
104
|
+
text: string,
|
|
105
|
+
options: MarkdownRenderOptions = {},
|
|
106
|
+
) => {
|
|
107
|
+
let mdTree = parse(markdownLanguageWithUserExtensions(client), text);
|
|
108
|
+
if (options.expand) {
|
|
109
|
+
mdTree = await expandMarkdownWithClient(client, mdTree);
|
|
110
|
+
}
|
|
111
|
+
if (!options.resolveTagHref) {
|
|
112
|
+
options.resolveTagHref = (tagName: string) => {
|
|
113
|
+
return (
|
|
114
|
+
client.config.get<string | null>(
|
|
115
|
+
["tags", tagName, "tagPage"],
|
|
116
|
+
null,
|
|
117
|
+
) ?? TagConstants.tagPrefix + tagName
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return renderMarkdownToHtml(mdTree, options);
|
|
122
|
+
},
|
|
123
|
+
description: "Renders Markdown text to HTML.",
|
|
124
|
+
parameters: [
|
|
125
|
+
{ name: "text", type: "string", description: "Markdown source." },
|
|
126
|
+
{
|
|
127
|
+
name: "options",
|
|
128
|
+
type: "table",
|
|
129
|
+
description: "HTML rendering options.",
|
|
130
|
+
optional: true,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
returns: [{ type: "string", description: "Rendered HTML." }],
|
|
134
|
+
examples: [{ code: 'local html = markdown.markdownToHtml("# Title")' }],
|
|
72
135
|
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
136
|
+
// Re-bake every baked section (`<!--#lua EXPR -->` … `<!--/lua-->`) in
|
|
137
|
+
// `text` and return the updated markdown. Pure transform (no editor) — the
|
|
138
|
+
// text-level counterpart of the "Baked Sections: Update" command. `pageName`
|
|
139
|
+
// sets the `currentPage` context for the evaluated expressions.
|
|
140
|
+
"markdown.bakeSections": {
|
|
141
|
+
callback: (_ctx, text: string, pageName?: string): Promise<string> => {
|
|
142
|
+
return bakeSectionsInText(client, text, pageName);
|
|
143
|
+
},
|
|
144
|
+
description:
|
|
145
|
+
"Re-evaluates all baked Lua sections in Markdown text; sections that error or only render as HTML are left unchanged.",
|
|
146
|
+
parameters: [
|
|
147
|
+
{
|
|
148
|
+
name: "text",
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "Markdown containing baked sections.",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "pageName",
|
|
154
|
+
type: "string",
|
|
155
|
+
description: "Page used as currentPage during evaluation.",
|
|
156
|
+
optional: true,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
returns: [
|
|
160
|
+
{
|
|
161
|
+
type: "string",
|
|
162
|
+
description: "Markdown with updated baked section bodies.",
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
examples: [
|
|
166
|
+
{
|
|
167
|
+
code: 'local text = "Total: <!--#lua 1 + 2 -->\\nold\\n<!--/lua-->"\nprint(markdown.bakeSections(text))',
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
"markdown.objectsToTable": {
|
|
172
|
+
callback: (
|
|
173
|
+
_ctx,
|
|
174
|
+
data: any[],
|
|
175
|
+
options: {
|
|
176
|
+
renderCell?: (val: any, key: string) => Promise<any> | any;
|
|
177
|
+
} = {},
|
|
178
|
+
) => {
|
|
179
|
+
return jsonToMDTable(data, options.renderCell || refCellTransformer);
|
|
180
|
+
},
|
|
181
|
+
description: "Formats a list of objects as a Markdown table.",
|
|
182
|
+
parameters: [
|
|
183
|
+
{ name: "data", type: "table", description: "Rows to render." },
|
|
184
|
+
{
|
|
185
|
+
name: "options",
|
|
186
|
+
type: "table",
|
|
187
|
+
description: "Optional renderCell callback.",
|
|
188
|
+
optional: true,
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
returns: [{ type: "string", description: "Markdown table." }],
|
|
192
|
+
examples: [
|
|
193
|
+
{
|
|
194
|
+
code: 'local tableText = markdown.objectsToTable({{name = "Pete", age = 20}})',
|
|
195
|
+
},
|
|
196
|
+
],
|
|
81
197
|
},
|
|
82
198
|
};
|
|
83
199
|
}
|
|
@@ -11,34 +11,107 @@ export function mqSyscalls(mq: DataStoreMQ): SysCallMapping {
|
|
|
11
11
|
/**
|
|
12
12
|
* Define a Lua event listener
|
|
13
13
|
*/
|
|
14
|
-
"mq.subscribe":
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
"mq.subscribe": {
|
|
15
|
+
callback: (_ctx, def: MQListenerSpec) => {
|
|
16
|
+
def.autoAck = def.autoAck !== false;
|
|
17
|
+
// console.log("Registering Lua event listener: ", def.name);
|
|
18
|
+
client.config.insert(["mqSubscriptions", def.queue], def);
|
|
19
|
+
},
|
|
20
|
+
description: "Subscribes a Space Lua callback to a message queue.",
|
|
21
|
+
parameters: [
|
|
22
|
+
{
|
|
23
|
+
name: "spec",
|
|
24
|
+
type: "table",
|
|
25
|
+
description:
|
|
26
|
+
"Subscription with queue, optional batchSize and pollInterval, autoAck (default true), and a run(messages) callback; each message has queue, id, and body fields.",
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
examples: [
|
|
30
|
+
{
|
|
31
|
+
code: 'mq.subscribe { queue = "tasks", batchSize = 1, run = function(messages) print(messages[1].body) end }',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
18
34
|
},
|
|
19
|
-
"mq.send":
|
|
20
|
-
|
|
35
|
+
"mq.send": {
|
|
36
|
+
callback: (_ctx, queue: string, body: any) => {
|
|
37
|
+
return mq.send(queue, body);
|
|
38
|
+
},
|
|
39
|
+
description: "Sends a message to a queue.",
|
|
40
|
+
parameters: [
|
|
41
|
+
{ name: "queue", type: "string", description: "Queue name." },
|
|
42
|
+
{ name: "body", description: "Message body." },
|
|
43
|
+
],
|
|
44
|
+
examples: [{ code: 'mq.send("tasks", "my task")' }],
|
|
21
45
|
},
|
|
22
|
-
"mq.batchSend":
|
|
23
|
-
|
|
46
|
+
"mq.batchSend": {
|
|
47
|
+
callback: (_ctx, queue: string, bodies: any[]) => {
|
|
48
|
+
return mq.batchSend(queue, bodies);
|
|
49
|
+
},
|
|
50
|
+
description: "Sends multiple messages to a queue in one operation.",
|
|
51
|
+
parameters: [
|
|
52
|
+
{ name: "queue", type: "string", description: "Queue name." },
|
|
53
|
+
{ name: "bodies", type: "table", description: "Message bodies." },
|
|
54
|
+
],
|
|
24
55
|
},
|
|
25
|
-
"mq.ack":
|
|
26
|
-
|
|
56
|
+
"mq.ack": {
|
|
57
|
+
callback: (_ctx, queue: string, id: string) => {
|
|
58
|
+
return mq.ack(queue, id);
|
|
59
|
+
},
|
|
60
|
+
description: "Acknowledges one queue message as processed.",
|
|
61
|
+
parameters: [
|
|
62
|
+
{ name: "queue", type: "string", description: "Queue name." },
|
|
63
|
+
{ name: "id", type: "string", description: "Message ID." },
|
|
64
|
+
],
|
|
27
65
|
},
|
|
28
|
-
"mq.batchAck":
|
|
29
|
-
|
|
66
|
+
"mq.batchAck": {
|
|
67
|
+
callback: (_ctx, queue: string, ids: string[]) => {
|
|
68
|
+
return mq.batchAck(queue, ids);
|
|
69
|
+
},
|
|
70
|
+
description: "Acknowledges multiple queue messages as processed.",
|
|
71
|
+
parameters: [
|
|
72
|
+
{ name: "queue", type: "string", description: "Queue name." },
|
|
73
|
+
{ name: "ids", type: "table", description: "Message IDs." },
|
|
74
|
+
],
|
|
30
75
|
},
|
|
31
|
-
"mq.flushQueue":
|
|
32
|
-
|
|
76
|
+
"mq.flushQueue": {
|
|
77
|
+
callback: (_ctx, queue: string) => {
|
|
78
|
+
return mq.flushQueue(queue);
|
|
79
|
+
},
|
|
80
|
+
description: "Removes all messages from a queue.",
|
|
81
|
+
parameters: [
|
|
82
|
+
{ name: "queue", type: "string", description: "Queue name." },
|
|
83
|
+
],
|
|
33
84
|
},
|
|
34
|
-
"mq.flushAllQueues":
|
|
35
|
-
|
|
85
|
+
"mq.flushAllQueues": {
|
|
86
|
+
callback: () => {
|
|
87
|
+
return mq.flushAllQueues();
|
|
88
|
+
},
|
|
89
|
+
description: "Removes all messages from every queue.",
|
|
36
90
|
},
|
|
37
|
-
"mq.getQueueStats":
|
|
38
|
-
|
|
91
|
+
"mq.getQueueStats": {
|
|
92
|
+
callback: (_ctx, queue: string) => {
|
|
93
|
+
return mq.getQueueStats(queue);
|
|
94
|
+
},
|
|
95
|
+
description:
|
|
96
|
+
"Gets queued, processing, and dead-letter counts for a queue.",
|
|
97
|
+
parameters: [
|
|
98
|
+
{
|
|
99
|
+
name: "queue",
|
|
100
|
+
type: "string",
|
|
101
|
+
description: "Queue name.",
|
|
102
|
+
optional: true,
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
returns: [{ type: "table", description: "Queue statistics." }],
|
|
39
106
|
},
|
|
40
|
-
"mq.awaitEmptyQueue":
|
|
41
|
-
|
|
107
|
+
"mq.awaitEmptyQueue": {
|
|
108
|
+
callback: (_ctx, queue: string) => {
|
|
109
|
+
return mq.awaitEmptyQueue(queue);
|
|
110
|
+
},
|
|
111
|
+
description: "Waits until a queue has no pending or processing messages.",
|
|
112
|
+
parameters: [
|
|
113
|
+
{ name: "queue", type: "string", description: "Queue name." },
|
|
114
|
+
],
|
|
42
115
|
},
|
|
43
116
|
};
|
|
44
117
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure schema-introspection helpers over the `["tags"]` config table.
|
|
3
|
+
*
|
|
4
|
+
* Returns raw JSON Schema objects; presentation-layer flattening (into typed
|
|
5
|
+
* property rows) happens in the `sb describe` CLI (describe.rs).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns a map of tag name → raw JSON Schema for every tag that defines a schema.
|
|
10
|
+
* Tags without a schema are omitted.
|
|
11
|
+
*/
|
|
12
|
+
export function describeSchemas(
|
|
13
|
+
tags: Record<string, any>,
|
|
14
|
+
): Record<string, unknown> {
|
|
15
|
+
const result: Record<string, unknown> = {};
|
|
16
|
+
for (const [name, def] of Object.entries(tags)) {
|
|
17
|
+
if (def?.schema != null) {
|
|
18
|
+
result[name] = def.schema;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Returns the raw JSON Schema for a single tag, or null if the tag is
|
|
26
|
+
* undefined or has no schema.
|
|
27
|
+
*/
|
|
28
|
+
export function tagSchema(
|
|
29
|
+
tags: Record<string, any>,
|
|
30
|
+
tagName: string,
|
|
31
|
+
): unknown | null {
|
|
32
|
+
return tags[tagName]?.schema ?? null;
|
|
33
|
+
}
|
|
@@ -12,29 +12,83 @@ export function serviceRegistrySyscalls(
|
|
|
12
12
|
/**
|
|
13
13
|
* Define a Lua event listener
|
|
14
14
|
*/
|
|
15
|
-
"service.define":
|
|
16
|
-
|
|
15
|
+
"service.define": {
|
|
16
|
+
callback: (_ctx, def: ServiceSpec) => {
|
|
17
|
+
return serviceRegistry.define(def);
|
|
18
|
+
},
|
|
19
|
+
description: "Defines a service that can be discovered by selector.",
|
|
20
|
+
parameters: [
|
|
21
|
+
{
|
|
22
|
+
name: "spec",
|
|
23
|
+
type: "table",
|
|
24
|
+
description: "Selector, match rule, and run callback.",
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
examples: [
|
|
28
|
+
{
|
|
29
|
+
code: 'service.define { selector = "greeter", match = {}, run = function(name) return "Hello " .. name end }',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
17
32
|
},
|
|
18
|
-
"service.discover":
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
"service.discover": {
|
|
34
|
+
callback: (
|
|
35
|
+
_ctx,
|
|
36
|
+
selector: string,
|
|
37
|
+
data: any,
|
|
38
|
+
): Promise<ServiceMatch[]> => {
|
|
39
|
+
return serviceRegistry.discover(selector, data);
|
|
40
|
+
},
|
|
41
|
+
description: "Discovers matching services sorted by descending priority.",
|
|
42
|
+
parameters: [
|
|
43
|
+
{
|
|
44
|
+
name: "selector",
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "Service selector.",
|
|
47
|
+
},
|
|
48
|
+
{ name: "data", description: "Value passed to match callbacks." },
|
|
49
|
+
],
|
|
50
|
+
returns: [
|
|
51
|
+
{ type: "table", description: "Matching service descriptors." },
|
|
52
|
+
],
|
|
24
53
|
},
|
|
25
|
-
"service.invoke":
|
|
26
|
-
_ctx,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
54
|
+
"service.invoke": {
|
|
55
|
+
callback: (_ctx, service: ServiceMatch, data: any): Promise<any> => {
|
|
56
|
+
return serviceRegistry.invoke(service, data);
|
|
57
|
+
},
|
|
58
|
+
description: "Invokes a previously discovered service match.",
|
|
59
|
+
parameters: [
|
|
60
|
+
{
|
|
61
|
+
name: "match",
|
|
62
|
+
type: "table",
|
|
63
|
+
description: "Service match returned by service.discover.",
|
|
64
|
+
},
|
|
65
|
+
{ name: "data", description: "Value passed to the service." },
|
|
66
|
+
],
|
|
67
|
+
returns: [{ description: "Service result." }],
|
|
31
68
|
},
|
|
32
|
-
"service.invokeBestMatch":
|
|
33
|
-
_ctx,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
69
|
+
"service.invokeBestMatch": {
|
|
70
|
+
callback: (_ctx, selector: string, data: any): Promise<any> => {
|
|
71
|
+
return serviceRegistry.invokeBestMatch(selector, data);
|
|
72
|
+
},
|
|
73
|
+
description:
|
|
74
|
+
"Discovers and invokes the highest-priority matching service.",
|
|
75
|
+
parameters: [
|
|
76
|
+
{
|
|
77
|
+
name: "selector",
|
|
78
|
+
type: "string",
|
|
79
|
+
description: "Service selector.",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "data",
|
|
83
|
+
description: "Value used for matching and invocation.",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
returns: [{ description: "Best matching service result." }],
|
|
87
|
+
examples: [
|
|
88
|
+
{
|
|
89
|
+
code: 'local greeting = service.invokeBestMatch("greeter", "Pete")',
|
|
90
|
+
},
|
|
91
|
+
],
|
|
38
92
|
},
|
|
39
93
|
};
|
|
40
94
|
}
|
|
@@ -4,28 +4,59 @@ import { fsEndpoint } from "../../spaces/constants.ts";
|
|
|
4
4
|
|
|
5
5
|
export function shellSyscalls(client: Client): SysCallMapping {
|
|
6
6
|
return {
|
|
7
|
-
"shell.run":
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
"shell.run": {
|
|
8
|
+
callback: async (
|
|
9
|
+
_ctx,
|
|
10
|
+
cmd: string,
|
|
11
|
+
args: string[],
|
|
12
|
+
stdin?: string,
|
|
13
|
+
): Promise<{ stdout: string; stderr: string; code: number }> => {
|
|
14
|
+
if (!client.httpSpacePrimitives) {
|
|
15
|
+
throw new Error("Not supported in fully local mode");
|
|
16
|
+
}
|
|
17
|
+
const resp = client.httpSpacePrimitives.authenticatedFetch(
|
|
18
|
+
buildShellUrl(client),
|
|
19
|
+
{
|
|
20
|
+
method: "POST",
|
|
21
|
+
body: JSON.stringify({
|
|
22
|
+
cmd,
|
|
23
|
+
args,
|
|
24
|
+
stdin,
|
|
25
|
+
}),
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
const { code, stderr, stdout } = await (await resp).json();
|
|
29
|
+
return { code, stderr, stdout };
|
|
30
|
+
},
|
|
31
|
+
description: "Runs a shell command on the server and returns its output.",
|
|
32
|
+
parameters: [
|
|
33
|
+
{ name: "command", type: "string", description: "Executable name." },
|
|
18
34
|
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
args,
|
|
23
|
-
stdin,
|
|
24
|
-
}),
|
|
35
|
+
name: "arguments",
|
|
36
|
+
type: "table",
|
|
37
|
+
description: "Command arguments.",
|
|
25
38
|
},
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
{
|
|
40
|
+
name: "stdin",
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Text supplied on standard input.",
|
|
43
|
+
optional: true,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
returns: [
|
|
47
|
+
{
|
|
48
|
+
type: "table",
|
|
49
|
+
description: "stdout, stderr, and numeric exit code.",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
examples: [
|
|
53
|
+
{
|
|
54
|
+
code: 'local result = shell.run("ls", {"-l"})\nprint(result.stdout)',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
code: 'local result = shell.run("cat", {}, "hello")\nprint(result.stdout)',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
29
60
|
},
|
|
30
61
|
};
|
|
31
62
|
}
|