skimpyclaw 0.3.14 → 0.4.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 +47 -37
- package/dist/__tests__/adapter-types.test.d.ts +4 -0
- package/dist/__tests__/adapter-types.test.js +63 -0
- package/dist/__tests__/anthropic-adapter.test.d.ts +4 -0
- package/dist/__tests__/anthropic-adapter.test.js +264 -0
- package/dist/__tests__/api.test.js +0 -1
- package/dist/__tests__/cli.integration.test.js +2 -4
- package/dist/__tests__/cli.test.js +0 -1
- package/dist/__tests__/code-agents-notifications.test.js +137 -0
- package/dist/__tests__/code-agents-parser.test.js +19 -1
- package/dist/__tests__/code-agents-preflight.test.js +3 -28
- package/dist/__tests__/code-agents-utils.test.js +34 -9
- package/dist/__tests__/code-agents-worktrees.test.js +116 -0
- package/dist/__tests__/codex-adapter.test.js +184 -0
- package/dist/__tests__/codex-auth.test.js +66 -0
- package/dist/__tests__/codex-provider-gating.test.js +35 -0
- package/dist/__tests__/codex-unified-loop.test.js +111 -0
- package/dist/__tests__/config-security.test.js +127 -0
- package/dist/__tests__/config.test.js +23 -0
- package/dist/__tests__/context-manager.test.js +243 -164
- package/dist/__tests__/cron-run.test.js +250 -0
- package/dist/__tests__/cron.test.js +12 -38
- package/dist/__tests__/digests.test.js +67 -0
- package/dist/__tests__/discord-attachments.test.js +211 -0
- package/dist/__tests__/discord-docs.test.d.ts +1 -0
- package/dist/__tests__/discord-docs.test.js +27 -0
- package/dist/__tests__/discord-thread-agents.test.d.ts +1 -0
- package/dist/__tests__/discord-thread-agents.test.js +115 -0
- package/dist/__tests__/discord-thread-context.test.d.ts +1 -0
- package/dist/__tests__/discord-thread-context.test.js +42 -0
- package/dist/__tests__/doctor.formatters.test.js +4 -4
- package/dist/__tests__/doctor.index.test.js +1 -1
- package/dist/__tests__/doctor.runner.test.js +3 -15
- package/dist/__tests__/env-sanitizer.test.d.ts +1 -0
- package/dist/__tests__/env-sanitizer.test.js +45 -0
- package/dist/__tests__/exec-approval.test.js +61 -0
- package/dist/__tests__/fetch-tool.test.d.ts +1 -0
- package/dist/__tests__/fetch-tool.test.js +85 -0
- package/dist/__tests__/gateway-status-auth.test.d.ts +1 -0
- package/dist/__tests__/gateway-status-auth.test.js +72 -0
- package/dist/__tests__/heartbeat.test.js +3 -3
- package/dist/__tests__/interactive-sessions.test.d.ts +1 -0
- package/dist/__tests__/interactive-sessions.test.js +96 -0
- package/dist/__tests__/langfuse.test.js +6 -18
- package/dist/__tests__/model-selection.test.js +3 -4
- package/dist/__tests__/providers-init.test.js +2 -8
- package/dist/__tests__/providers-routing.test.js +1 -1
- package/dist/__tests__/providers-utils.test.js +13 -3
- package/dist/__tests__/sessions.test.js +14 -10
- package/dist/__tests__/setup.test.js +12 -29
- package/dist/__tests__/skills.test.js +10 -7
- package/dist/__tests__/stream-formatter.test.d.ts +1 -0
- package/dist/__tests__/stream-formatter.test.js +114 -0
- package/dist/__tests__/token-efficiency.test.js +131 -15
- package/dist/__tests__/tool-loop.test.d.ts +4 -0
- package/dist/__tests__/tool-loop.test.js +505 -0
- package/dist/__tests__/tools.test.js +101 -276
- package/dist/__tests__/utils.test.d.ts +1 -0
- package/dist/__tests__/utils.test.js +14 -0
- package/dist/__tests__/voice.test.js +21 -0
- package/dist/agent.js +35 -4
- package/dist/api.js +113 -37
- package/dist/channels/discord/attachments.d.ts +50 -0
- package/dist/channels/discord/attachments.js +137 -0
- package/dist/channels/discord/delegation.d.ts +5 -0
- package/dist/channels/discord/delegation.js +136 -0
- package/dist/channels/discord/handlers.js +694 -7
- package/dist/channels/discord/index.d.ts +16 -1
- package/dist/channels/discord/index.js +64 -1
- package/dist/channels/discord/thread-agents.d.ts +54 -0
- package/dist/channels/discord/thread-agents.js +323 -0
- package/dist/channels/discord/threads.d.ts +58 -0
- package/dist/channels/discord/threads.js +192 -0
- package/dist/channels/discord/types.js +4 -2
- package/dist/channels/discord/utils.d.ts +16 -0
- package/dist/channels/discord/utils.js +86 -6
- package/dist/channels/telegram/index.d.ts +1 -1
- package/dist/channels/telegram/types.js +1 -1
- package/dist/channels/telegram/utils.js +9 -3
- package/dist/channels.d.ts +1 -1
- package/dist/cli.js +20 -400
- package/dist/code-agents/executor.d.ts +1 -1
- package/dist/code-agents/executor.js +101 -45
- package/dist/code-agents/index.d.ts +2 -7
- package/dist/code-agents/index.js +111 -80
- package/dist/code-agents/interactive-resume.d.ts +6 -0
- package/dist/code-agents/interactive-resume.js +98 -0
- package/dist/code-agents/interactive-sessions.d.ts +20 -0
- package/dist/code-agents/interactive-sessions.js +132 -0
- package/dist/code-agents/parser.js +5 -1
- package/dist/code-agents/registry.d.ts +7 -1
- package/dist/code-agents/registry.js +11 -23
- package/dist/code-agents/stream-formatter.d.ts +8 -0
- package/dist/code-agents/stream-formatter.js +92 -0
- package/dist/code-agents/types.d.ts +16 -24
- package/dist/code-agents/utils.d.ts +35 -11
- package/dist/code-agents/utils.js +349 -95
- package/dist/code-agents/worktrees.d.ts +37 -0
- package/dist/code-agents/worktrees.js +116 -0
- package/dist/config.d.ts +2 -4
- package/dist/config.js +123 -23
- package/dist/cron.d.ts +1 -6
- package/dist/cron.js +175 -82
- package/dist/dashboard/assets/index-B345aOO-.js +65 -0
- package/dist/dashboard/assets/index-ZWK4dalJ.css +1 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/digests.d.ts +1 -0
- package/dist/digests.js +132 -42
- package/dist/doctor/checks.d.ts +0 -3
- package/dist/doctor/checks.js +1 -108
- package/dist/doctor/runner.js +1 -4
- package/dist/env-sanitizer.d.ts +2 -0
- package/dist/env-sanitizer.js +61 -0
- package/dist/exec-approval.d.ts +11 -1
- package/dist/exec-approval.js +17 -4
- package/dist/gateway.d.ts +3 -1
- package/dist/gateway.js +17 -7
- package/dist/heartbeat.js +1 -6
- package/dist/langfuse.js +3 -29
- package/dist/model-selection.js +3 -1
- package/dist/providers/adapter.d.ts +118 -0
- package/dist/providers/adapter.js +6 -0
- package/dist/providers/adapters/anthropic-adapter.d.ts +22 -0
- package/dist/providers/adapters/anthropic-adapter.js +204 -0
- package/dist/providers/adapters/codex-adapter.d.ts +26 -0
- package/dist/providers/adapters/codex-adapter.js +203 -0
- package/dist/providers/anthropic.d.ts +1 -0
- package/dist/providers/anthropic.js +10 -272
- package/dist/providers/codex.d.ts +21 -0
- package/dist/providers/codex.js +149 -330
- package/dist/providers/content.d.ts +1 -1
- package/dist/providers/content.js +2 -2
- package/dist/providers/context-manager.d.ts +18 -6
- package/dist/providers/context-manager.js +199 -223
- package/dist/providers/index.d.ts +9 -1
- package/dist/providers/index.js +73 -64
- package/dist/providers/loop-utils.d.ts +20 -0
- package/dist/providers/loop-utils.js +30 -0
- package/dist/providers/tool-loop.d.ts +12 -0
- package/dist/providers/tool-loop.js +251 -0
- package/dist/providers/utils.d.ts +19 -3
- package/dist/providers/utils.js +100 -29
- package/dist/secure-store.d.ts +8 -0
- package/dist/secure-store.js +80 -0
- package/dist/service.js +3 -28
- package/dist/sessions.d.ts +3 -0
- package/dist/sessions.js +147 -18
- package/dist/setup-templates.js +13 -25
- package/dist/setup.d.ts +10 -6
- package/dist/setup.js +84 -292
- package/dist/skills.js +3 -11
- package/dist/tools/agent-delegation.d.ts +19 -0
- package/dist/tools/agent-delegation.js +49 -0
- package/dist/tools/bash-tool.js +89 -34
- package/dist/tools/definitions.d.ts +199 -302
- package/dist/tools/definitions.js +70 -123
- package/dist/tools/execute-context.d.ts +13 -4
- package/dist/tools/fetch-tool.js +109 -13
- package/dist/tools/file-tools.js +7 -1
- package/dist/tools.d.ts +7 -7
- package/dist/tools.js +133 -151
- package/dist/types.d.ts +37 -30
- package/dist/utils.js +4 -6
- package/dist/voice.d.ts +1 -1
- package/dist/voice.js +17 -4
- package/package.json +33 -23
- package/templates/TOOLS.md +0 -27
- package/dist/__tests__/audit.test.js +0 -122
- package/dist/__tests__/code-agents-orchestrator.test.js +0 -216
- package/dist/__tests__/code-agents-sandbox.test.js +0 -163
- package/dist/__tests__/orchestrator.test.js +0 -425
- package/dist/__tests__/sandbox-bridge.test.js +0 -116
- package/dist/__tests__/sandbox-manager.test.js +0 -144
- package/dist/__tests__/sandbox-mount-security.test.js +0 -139
- package/dist/__tests__/sandbox-runtime.test.js +0 -176
- package/dist/__tests__/subagent.test.js +0 -240
- package/dist/__tests__/telegram.test.js +0 -42
- package/dist/code-agents/orchestrator.d.ts +0 -29
- package/dist/code-agents/orchestrator.js +0 -694
- package/dist/code-agents/worktree.d.ts +0 -40
- package/dist/code-agents/worktree.js +0 -215
- package/dist/dashboard/assets/index-BoTHPby4.js +0 -65
- package/dist/dashboard/assets/index-D4mufvBg.css +0 -1
- package/dist/dashboard.d.ts +0 -8
- package/dist/dashboard.js +0 -4071
- package/dist/discord.d.ts +0 -8
- package/dist/discord.js +0 -792
- package/dist/mcp-context-a8c.d.ts +0 -13
- package/dist/mcp-context-a8c.js +0 -34
- package/dist/orchestrator.d.ts +0 -15
- package/dist/orchestrator.js +0 -676
- package/dist/providers/openai.d.ts +0 -10
- package/dist/providers/openai.js +0 -355
- package/dist/sandbox/bridge.d.ts +0 -5
- package/dist/sandbox/bridge.js +0 -63
- package/dist/sandbox/index.d.ts +0 -5
- package/dist/sandbox/index.js +0 -4
- package/dist/sandbox/manager.d.ts +0 -7
- package/dist/sandbox/manager.js +0 -100
- package/dist/sandbox/mount-security.d.ts +0 -12
- package/dist/sandbox/mount-security.js +0 -122
- package/dist/sandbox/runtime.d.ts +0 -39
- package/dist/sandbox/runtime.js +0 -192
- package/dist/sandbox-utils.d.ts +0 -6
- package/dist/sandbox-utils.js +0 -36
- package/dist/subagent.d.ts +0 -19
- package/dist/subagent.js +0 -407
- package/dist/telegram.d.ts +0 -2
- package/dist/telegram.js +0 -11
- package/dist/tools/browser-tool.d.ts +0 -3
- package/dist/tools/browser-tool.js +0 -266
- package/sandbox/Dockerfile +0 -40
- /package/dist/__tests__/{audit.test.d.ts → code-agents-notifications.test.d.ts} +0 -0
- /package/dist/__tests__/{code-agents-orchestrator.test.d.ts → code-agents-worktrees.test.d.ts} +0 -0
- /package/dist/__tests__/{code-agents-sandbox.test.d.ts → codex-adapter.test.d.ts} +0 -0
- /package/dist/__tests__/{orchestrator.test.d.ts → codex-auth.test.d.ts} +0 -0
- /package/dist/__tests__/{sandbox-bridge.test.d.ts → codex-provider-gating.test.d.ts} +0 -0
- /package/dist/__tests__/{sandbox-manager.test.d.ts → codex-unified-loop.test.d.ts} +0 -0
- /package/dist/__tests__/{sandbox-mount-security.test.d.ts → config-security.test.d.ts} +0 -0
- /package/dist/__tests__/{sandbox-runtime.test.d.ts → cron-run.test.d.ts} +0 -0
- /package/dist/__tests__/{subagent.test.d.ts → digests.test.d.ts} +0 -0
- /package/dist/__tests__/{telegram.test.d.ts → discord-attachments.test.d.ts} +0 -0
package/dist/skills.js
CHANGED
|
@@ -64,17 +64,10 @@ export function checkEligibility(skill, toolConfig) {
|
|
|
64
64
|
if (!toolConfig?.enabled) {
|
|
65
65
|
return { eligible: false, reason: `Tools not enabled (needs: ${reqs.tools.join(', ')})` };
|
|
66
66
|
}
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
const t = tool.toLowerCase();
|
|
70
|
-
if (t === 'browser') {
|
|
71
|
-
if (!toolConfig.browser?.enabled)
|
|
72
|
-
missing.push(tool);
|
|
73
|
-
}
|
|
74
|
-
// built-in tools are available whenever tools.enabled is true
|
|
75
|
-
}
|
|
67
|
+
const supportedTools = new Set(['read', 'write', 'glob', 'bash', 'fetch', 'code_with_agent', 'check_code_agent', 'delegate_to_agent']);
|
|
68
|
+
const missing = reqs.tools.filter(tool => !supportedTools.has(tool.toLowerCase()));
|
|
76
69
|
if (missing.length > 0) {
|
|
77
|
-
return { eligible: false, reason: `
|
|
70
|
+
return { eligible: false, reason: `Unsupported tools requested: ${missing.join(', ')}` };
|
|
78
71
|
}
|
|
79
72
|
}
|
|
80
73
|
return { eligible: true };
|
|
@@ -156,7 +149,6 @@ export function loadSkills(skillConfig, toolConfig) {
|
|
|
156
149
|
entries: skillConfig?.entries,
|
|
157
150
|
enabled: skillConfig?.enabled,
|
|
158
151
|
toolEnabled: toolConfig?.enabled,
|
|
159
|
-
browserEnabled: toolConfig?.browser?.enabled,
|
|
160
152
|
});
|
|
161
153
|
const cached = skillsCache.get(cacheKey);
|
|
162
154
|
if (cached)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Config } from '../types.js';
|
|
2
|
+
import type { ExecuteToolContext } from './execute-context.js';
|
|
3
|
+
export interface DelegateToAgentInput {
|
|
4
|
+
alias?: string;
|
|
5
|
+
task?: string;
|
|
6
|
+
mode?: string;
|
|
7
|
+
wait?: boolean;
|
|
8
|
+
allowSelf?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface NormalizedDelegateToAgentInput {
|
|
11
|
+
alias: string;
|
|
12
|
+
task: string;
|
|
13
|
+
mode: 'new_thread';
|
|
14
|
+
wait: boolean;
|
|
15
|
+
allowSelf: boolean;
|
|
16
|
+
}
|
|
17
|
+
export type DelegateToAgentHandler = (input: NormalizedDelegateToAgentInput, config: Config, context?: ExecuteToolContext) => Promise<string>;
|
|
18
|
+
export declare function registerDelegateToAgentHandler(nextHandler: DelegateToAgentHandler | null): void;
|
|
19
|
+
export declare function executeDelegateToAgent(input: DelegateToAgentInput, config: Config, context?: ExecuteToolContext): Promise<string>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const MAX_DELEGATION_DEPTH = 2;
|
|
2
|
+
const ALIAS_RE = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
3
|
+
let handler = null;
|
|
4
|
+
function normalizeAlias(value) {
|
|
5
|
+
const normalized = typeof value === 'string'
|
|
6
|
+
? value.trim().replace(/^@/, '').toLowerCase()
|
|
7
|
+
: '';
|
|
8
|
+
return ALIAS_RE.test(normalized) ? normalized : null;
|
|
9
|
+
}
|
|
10
|
+
export function registerDelegateToAgentHandler(nextHandler) {
|
|
11
|
+
handler = nextHandler;
|
|
12
|
+
}
|
|
13
|
+
export async function executeDelegateToAgent(input, config, context) {
|
|
14
|
+
const alias = normalizeAlias(input.alias);
|
|
15
|
+
if (!alias) {
|
|
16
|
+
return 'Error: alias must start with a letter and use only letters, numbers, underscore, or dash.';
|
|
17
|
+
}
|
|
18
|
+
const task = typeof input.task === 'string' ? input.task.trim() : '';
|
|
19
|
+
if (!task) {
|
|
20
|
+
return 'Error: task is required.';
|
|
21
|
+
}
|
|
22
|
+
const mode = input.mode?.trim() || 'new_thread';
|
|
23
|
+
if (mode !== 'new_thread') {
|
|
24
|
+
return 'Error: delegate_to_agent currently supports mode "new_thread" only.';
|
|
25
|
+
}
|
|
26
|
+
if (context?.channel !== 'discord') {
|
|
27
|
+
return 'Error: delegate_to_agent is currently Discord-only.';
|
|
28
|
+
}
|
|
29
|
+
if (context?.isDm) {
|
|
30
|
+
return 'Error: delegate_to_agent requires a Discord server channel. Direct messages do not support task threads.';
|
|
31
|
+
}
|
|
32
|
+
const depth = context?.delegationDepth ?? 0;
|
|
33
|
+
if (depth >= MAX_DELEGATION_DEPTH) {
|
|
34
|
+
return `Error: maximum agent delegation depth reached (${MAX_DELEGATION_DEPTH}).`;
|
|
35
|
+
}
|
|
36
|
+
if (!input.allowSelf && context?.threadAgentAlias === alias) {
|
|
37
|
+
return `Error: @${alias} cannot delegate to itself. Choose another agent profile.`;
|
|
38
|
+
}
|
|
39
|
+
if (!handler) {
|
|
40
|
+
return 'Error: Discord agent delegation is not available.';
|
|
41
|
+
}
|
|
42
|
+
return handler({
|
|
43
|
+
alias,
|
|
44
|
+
task,
|
|
45
|
+
mode,
|
|
46
|
+
wait: input.wait === true,
|
|
47
|
+
allowSelf: input.allowSelf === true,
|
|
48
|
+
}, config, context);
|
|
49
|
+
}
|
package/dist/tools/bash-tool.js
CHANGED
|
@@ -1,33 +1,51 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
2
|
import { isBashCommandSafe } from '../security.js';
|
|
3
3
|
import { classifyCommandRisk, requiresApproval, createApprovalRequest, waitForApproval, } from '../exec-approval.js';
|
|
4
4
|
import { isPathAllowed } from './path-utils.js';
|
|
5
5
|
import { validateBashPaths } from './bash-path-validation.js';
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
delete env[key];
|
|
6
|
+
import { sanitizeExecEnv } from '../env-sanitizer.js';
|
|
7
|
+
const SHELL_CONTROL_PATTERN = /[|&;<>()`$\n]/;
|
|
8
|
+
function tokenizeCommand(command) {
|
|
9
|
+
const tokens = [];
|
|
10
|
+
let current = '';
|
|
11
|
+
let quote = null;
|
|
12
|
+
for (let i = 0; i < command.length; i++) {
|
|
13
|
+
const ch = command[i];
|
|
14
|
+
if (ch === '\\' && quote !== "'") {
|
|
15
|
+
const next = command[i + 1];
|
|
16
|
+
if (next) {
|
|
17
|
+
current += next;
|
|
18
|
+
i++;
|
|
19
|
+
}
|
|
20
|
+
continue;
|
|
22
21
|
}
|
|
22
|
+
if (quote) {
|
|
23
|
+
if (ch === quote) {
|
|
24
|
+
quote = null;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
current += ch;
|
|
28
|
+
}
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (ch === '"' || ch === "'") {
|
|
32
|
+
quote = ch;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (/\s/.test(ch)) {
|
|
36
|
+
if (current) {
|
|
37
|
+
tokens.push(current);
|
|
38
|
+
current = '';
|
|
39
|
+
}
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
current += ch;
|
|
23
43
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
return env;
|
|
44
|
+
if (quote)
|
|
45
|
+
return null;
|
|
46
|
+
if (current)
|
|
47
|
+
tokens.push(current);
|
|
48
|
+
return tokens;
|
|
31
49
|
}
|
|
32
50
|
export async function executeBash(command, cwd, config, context) {
|
|
33
51
|
// Hard block: existing safety filter (always enforced)
|
|
@@ -79,21 +97,58 @@ export async function executeBash(command, cwd, config, context) {
|
|
|
79
97
|
// Approved — fall through to execution below
|
|
80
98
|
}
|
|
81
99
|
}
|
|
100
|
+
if (SHELL_CONTROL_PATTERN.test(command)) {
|
|
101
|
+
return 'Error: Shell control operators are blocked in safe mode. Run a single executable with explicit arguments (no pipes, redirects, chaining, or subshell expansion).';
|
|
102
|
+
}
|
|
103
|
+
const argv = tokenizeCommand(command);
|
|
104
|
+
if (!argv || argv.length === 0) {
|
|
105
|
+
return 'Error: Invalid command syntax.';
|
|
106
|
+
}
|
|
82
107
|
const timeout = config.bashTimeout || 30_000;
|
|
108
|
+
const [executable, ...args] = argv;
|
|
83
109
|
return new Promise((res) => {
|
|
84
|
-
|
|
110
|
+
const child = spawn(executable, args, {
|
|
85
111
|
cwd: cwd || undefined,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
112
|
+
env: sanitizeExecEnv(),
|
|
113
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
114
|
+
shell: false,
|
|
115
|
+
});
|
|
116
|
+
let stdout = '';
|
|
117
|
+
let stderr = '';
|
|
118
|
+
let timedOut = false;
|
|
119
|
+
const timer = setTimeout(() => {
|
|
120
|
+
timedOut = true;
|
|
121
|
+
child.kill('SIGTERM');
|
|
122
|
+
setTimeout(() => child.kill('SIGKILL'), 1000);
|
|
123
|
+
}, timeout);
|
|
124
|
+
child.stdout.on('data', (chunk) => {
|
|
125
|
+
stdout += chunk.toString();
|
|
126
|
+
if (stdout.length > 60_000)
|
|
127
|
+
stdout = stdout.slice(-60_000);
|
|
128
|
+
});
|
|
129
|
+
child.stderr.on('data', (chunk) => {
|
|
130
|
+
stderr += chunk.toString();
|
|
131
|
+
if (stderr.length > 60_000)
|
|
132
|
+
stderr = stderr.slice(-60_000);
|
|
133
|
+
});
|
|
134
|
+
child.on('error', (error) => {
|
|
135
|
+
clearTimeout(timer);
|
|
136
|
+
res(`Error: ${error.message}`);
|
|
137
|
+
});
|
|
138
|
+
child.on('close', (code, signal) => {
|
|
139
|
+
clearTimeout(timer);
|
|
140
|
+
if (timedOut) {
|
|
141
|
+
const output = [stdout, stderr].filter(Boolean).join('\n');
|
|
142
|
+
res((output ? `${output}\n` : '') + `Exit code: timeout after ${timeout}ms`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const output = [stdout, stderr].filter(Boolean).join('\n').slice(0, 50_000);
|
|
146
|
+
if (code && code !== 0) {
|
|
147
|
+
const reason = signal ? `signal ${signal}` : `Exit code: ${code}`;
|
|
148
|
+
res((output ? `${output}\n` : '') + reason);
|
|
93
149
|
return;
|
|
94
150
|
}
|
|
95
|
-
|
|
96
|
-
res(output.slice(0, 50_000) || '(no output)');
|
|
151
|
+
res(output || '(no output)');
|
|
97
152
|
});
|
|
98
153
|
});
|
|
99
154
|
}
|