@zhin.js/plugin-code-runner 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -9
- package/commands/run/[language]/index.js +12 -11
- package/commands/run/[language]/index.ts +13 -11
- package/lib/run-code.d.ts +3 -1
- package/lib/run-code.d.ts.map +1 -1
- package/lib/run-code.js +5 -4
- package/lib/run-code.js.map +1 -1
- package/package.json +6 -6
- package/src/run-code.ts +6 -4
package/README.md
CHANGED
|
@@ -5,24 +5,30 @@ Zhin.js plugin for code-runner functionality.
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm
|
|
8
|
+
pnpm exec zhin install @zhin.js/plugin-code-runner
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Run the installation command from your application directory. It installs the package and mounts the `code-runner` instance in `package.json#zhin.plugins`. The corresponding `zhin.config.yml` node is:
|
|
14
14
|
|
|
15
15
|
```yaml
|
|
16
16
|
plugins:
|
|
17
|
-
|
|
17
|
+
code-runner: {}
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
## Configuration
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
zhin install @zhin.js/plugin-code-runner
|
|
24
|
-
```
|
|
22
|
+
This plugin currently has no configuration fields. Its [`schema.json`](./schema.json) accepts an empty object; do not place package names in a `plugins` array.
|
|
25
23
|
|
|
26
|
-
##
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
- `run javascript console.log("hello")`: execute with the default 30-second timeout.
|
|
27
|
+
- `run python --timeout 5 print(1)` / `run python -t 5 print(1)`: choose 1–30 seconds.
|
|
28
|
+
- `run --help`: show supported languages, code constraints and timeout defaults.
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
The Endpoint determines any command prefix, and an explicit `commandNamespace` adds a plugin
|
|
31
|
+
namespace. `commands/run/[language]/index.ts` binds the language, while code and timeout are
|
|
32
|
+
centrally declared in the same definition. Code keeps quotes and newlines; its limit is
|
|
33
|
+
10,000 characters. Use `--` before code containing option-like words. Unsupported languages,
|
|
34
|
+
missing code and invalid timeout values are rejected before the remote request.
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { defineCommand } from 'zhin.js/command';
|
|
3
|
-
import { formatResult, runCode } from "../../../lib/run-code.js";
|
|
3
|
+
import { formatResult, MAX_CODE_LENGTH, runCode, supportedLanguages } from "../../../lib/run-code.js";
|
|
4
4
|
export default defineCommand({
|
|
5
|
-
description: '
|
|
6
|
-
params: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
description: '在远程沙箱中运行代码片段',
|
|
6
|
+
params: {
|
|
7
|
+
language: {
|
|
8
|
+
type: 'string', description: `执行语言:${supportedLanguages.join(', ')}(不区分大小写)`,
|
|
9
|
+
validate: (value) => typeof value === 'string' && supportedLanguages.includes(value.toLowerCase().trim()),
|
|
10
|
+
},
|
|
11
|
+
code: { type: 'text', min: 1, max: MAX_CODE_LENGTH, description: '要运行的代码' },
|
|
12
|
+
},
|
|
13
|
+
options: { timeout: { type: 'integer', alias: 't', default: 30, min: 1, max: 30, description: '请求超时(秒)' } },
|
|
14
|
+
async execute({ params, options }) {
|
|
15
|
+
return formatResult(await runCode(params.language, params.code, options.timeout));
|
|
15
16
|
},
|
|
16
17
|
});
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { defineCommand } from 'zhin.js/command';
|
|
2
|
-
import { formatResult, runCode } from '../../../src/run-code.js';
|
|
1
|
+
import { defineCommand, type CommandParameterValue } from 'zhin.js/command';
|
|
2
|
+
import { formatResult, MAX_CODE_LENGTH, runCode, supportedLanguages } from '../../../src/run-code.js';
|
|
3
3
|
|
|
4
4
|
export default defineCommand({
|
|
5
|
-
description: '
|
|
6
|
-
params: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
description: '在远程沙箱中运行代码片段',
|
|
6
|
+
params: {
|
|
7
|
+
language: {
|
|
8
|
+
type: 'string', description: `执行语言:${supportedLanguages.join(', ')}(不区分大小写)`,
|
|
9
|
+
validate: (value: CommandParameterValue) => typeof value === 'string' && supportedLanguages.includes(value.toLowerCase().trim()),
|
|
10
|
+
},
|
|
11
|
+
code: { type: 'text', min: 1, max: MAX_CODE_LENGTH, description: '要运行的代码' },
|
|
12
|
+
},
|
|
13
|
+
options: { timeout: { type: 'integer', alias: 't', default: 30, min: 1, max: 30, description: '请求超时(秒)' } },
|
|
14
|
+
async execute({ params, options }) {
|
|
15
|
+
return formatResult(await runCode(params.language, params.code, options.timeout));
|
|
14
16
|
},
|
|
15
17
|
});
|
package/lib/run-code.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
export declare const MAX_CODE_LENGTH = 10000;
|
|
2
|
+
export declare const supportedLanguages: readonly string[];
|
|
1
3
|
interface RunResult {
|
|
2
4
|
stdout: string;
|
|
3
5
|
stderr: string;
|
|
4
6
|
error: string;
|
|
5
7
|
}
|
|
6
|
-
export declare function runCode(language: string, code: string): Promise<RunResult>;
|
|
8
|
+
export declare function runCode(language: string, code: string, timeoutSeconds?: number): Promise<RunResult>;
|
|
7
9
|
export declare function formatResult(result: RunResult): string;
|
|
8
10
|
export {};
|
|
9
11
|
//# sourceMappingURL=run-code.d.ts.map
|
package/lib/run-code.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../src/run-code.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../src/run-code.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,QAAQ,CAAC;AAerC,eAAO,MAAM,kBAAkB,mBAAkD,CAAC;AAIlF,UAAU,SAAS;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,SAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAmDrG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAMtD"}
|
package/lib/run-code.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const MAX_CODE_LENGTH = 10000;
|
|
1
|
+
export const MAX_CODE_LENGTH = 10000;
|
|
2
2
|
const SUPPORTED_LANGUAGES = {
|
|
3
3
|
python: 'main.py',
|
|
4
4
|
javascript: 'main.js',
|
|
@@ -11,8 +11,9 @@ const SUPPORTED_LANGUAGES = {
|
|
|
11
11
|
ruby: 'main.rb',
|
|
12
12
|
php: 'main.php',
|
|
13
13
|
};
|
|
14
|
+
export const supportedLanguages = Object.freeze(Object.keys(SUPPORTED_LANGUAGES));
|
|
14
15
|
const GLOT_API_BASE = 'https://glot.io/api/run';
|
|
15
|
-
export async function runCode(language, code) {
|
|
16
|
+
export async function runCode(language, code, timeoutSeconds = 30) {
|
|
16
17
|
const lang = language.toLowerCase().trim();
|
|
17
18
|
if (!SUPPORTED_LANGUAGES[lang]) {
|
|
18
19
|
return {
|
|
@@ -37,7 +38,7 @@ export async function runCode(language, code) {
|
|
|
37
38
|
body: JSON.stringify({
|
|
38
39
|
files: [{ name: fileName, content: code }],
|
|
39
40
|
}),
|
|
40
|
-
signal: AbortSignal.timeout(
|
|
41
|
+
signal: AbortSignal.timeout(timeoutSeconds * 1000),
|
|
41
42
|
});
|
|
42
43
|
if (!response.ok) {
|
|
43
44
|
return {
|
|
@@ -55,7 +56,7 @@ export async function runCode(language, code) {
|
|
|
55
56
|
}
|
|
56
57
|
catch (e) {
|
|
57
58
|
const err = e;
|
|
58
|
-
const msg = err.name === 'TimeoutError' ?
|
|
59
|
+
const msg = err.name === 'TimeoutError' ? `请求超时(${timeoutSeconds}s)` : err.message || '未知错误';
|
|
59
60
|
return { stdout: '', stderr: '', error: msg };
|
|
60
61
|
}
|
|
61
62
|
}
|
package/lib/run-code.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-code.js","sourceRoot":"","sources":["../src/run-code.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"run-code.js","sourceRoot":"","sources":["../src/run-code.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/plugin-code-runner",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Sandboxed code execution plugin for Zhin.js (Plugin Runtime)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"typescript": "^6.0.3",
|
|
43
43
|
"vitest": "^4.1.10",
|
|
44
44
|
"zod": "^4.4.3",
|
|
45
|
-
"zhin.js": "1.1.
|
|
45
|
+
"zhin.js": "1.1.8"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"zod": "^4.0.0",
|
|
49
|
-
"@zhin.js/command": "^1.1.
|
|
50
|
-
"zhin.js": "^1.1.
|
|
49
|
+
"@zhin.js/command": "^1.1.6",
|
|
50
|
+
"zhin.js": "^1.1.8"
|
|
51
51
|
},
|
|
52
52
|
"peerDependenciesMeta": {
|
|
53
53
|
"@zhin.js/command": {
|
|
@@ -92,8 +92,8 @@
|
|
|
92
92
|
"plugins": []
|
|
93
93
|
},
|
|
94
94
|
"dependencies": {
|
|
95
|
-
"@zhin.js/tool": "1.1.
|
|
96
|
-
"@zhin.js/skill": "1.1.
|
|
95
|
+
"@zhin.js/tool": "1.1.5",
|
|
96
|
+
"@zhin.js/skill": "1.1.5"
|
|
97
97
|
},
|
|
98
98
|
"scripts": {
|
|
99
99
|
"build": "tsc",
|
package/src/run-code.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const MAX_CODE_LENGTH = 10000;
|
|
1
|
+
export const MAX_CODE_LENGTH = 10000;
|
|
2
2
|
|
|
3
3
|
const SUPPORTED_LANGUAGES: Record<string, string> = {
|
|
4
4
|
python: 'main.py',
|
|
@@ -13,6 +13,8 @@ const SUPPORTED_LANGUAGES: Record<string, string> = {
|
|
|
13
13
|
php: 'main.php',
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
export const supportedLanguages = Object.freeze(Object.keys(SUPPORTED_LANGUAGES));
|
|
17
|
+
|
|
16
18
|
const GLOT_API_BASE = 'https://glot.io/api/run';
|
|
17
19
|
|
|
18
20
|
interface RunResult {
|
|
@@ -21,7 +23,7 @@ interface RunResult {
|
|
|
21
23
|
error: string;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
export async function runCode(language: string, code: string): Promise<RunResult> {
|
|
26
|
+
export async function runCode(language: string, code: string, timeoutSeconds = 30): Promise<RunResult> {
|
|
25
27
|
const lang = language.toLowerCase().trim();
|
|
26
28
|
|
|
27
29
|
if (!SUPPORTED_LANGUAGES[lang]) {
|
|
@@ -50,7 +52,7 @@ export async function runCode(language: string, code: string): Promise<RunResult
|
|
|
50
52
|
body: JSON.stringify({
|
|
51
53
|
files: [{ name: fileName, content: code }],
|
|
52
54
|
}),
|
|
53
|
-
signal: AbortSignal.timeout(
|
|
55
|
+
signal: AbortSignal.timeout(timeoutSeconds * 1000),
|
|
54
56
|
});
|
|
55
57
|
|
|
56
58
|
if (!response.ok) {
|
|
@@ -69,7 +71,7 @@ export async function runCode(language: string, code: string): Promise<RunResult
|
|
|
69
71
|
};
|
|
70
72
|
} catch (e: unknown) {
|
|
71
73
|
const err = e as Error;
|
|
72
|
-
const msg = err.name === 'TimeoutError' ?
|
|
74
|
+
const msg = err.name === 'TimeoutError' ? `请求超时(${timeoutSeconds}s)` : err.message || '未知错误';
|
|
73
75
|
return { stdout: '', stderr: '', error: msg };
|
|
74
76
|
}
|
|
75
77
|
}
|