@dexto/tools-process 1.7.2 → 1.8.1

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.
@@ -33,7 +33,7 @@ __export(bash_exec_tool_exports, {
33
33
  module.exports = __toCommonJS(bash_exec_tool_exports);
34
34
  var path = __toESM(require("node:path"), 1);
35
35
  var import_zod = require("zod");
36
- var import_core = require("@dexto/core");
36
+ var import_tools = require("@dexto/core/tools");
37
37
  var import_errors = require("./errors.js");
38
38
  var import_command_pattern_utils = require("./command-pattern-utils.js");
39
39
  const BashExecInputSchema = import_zod.z.object({
@@ -46,7 +46,7 @@ const BashExecInputSchema = import_zod.z.object({
46
46
  cwd: import_zod.z.string().optional().describe("Working directory for command execution (optional)")
47
47
  }).strict();
48
48
  function createBashExecTool(getProcessService) {
49
- return (0, import_core.defineTool)({
49
+ return (0, import_tools.defineTool)({
50
50
  id: "bash_exec",
51
51
  aliases: ["bash"],
52
52
  description: `Execute a shell command in the project root directory.
@@ -100,9 +100,9 @@ Security: Dangerous commands are blocked. Injection attempts are detected. Requi
100
100
  suggestPatterns: (input) => (0, import_command_pattern_utils.generateCommandPatternSuggestions)(input.command)
101
101
  },
102
102
  presentation: {
103
- describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
103
+ describeHeader: (input) => (0, import_tools.createLocalToolCallHeader)({
104
104
  title: "Bash",
105
- argsText: (0, import_core.truncateForHeader)(input.command, 140)
105
+ argsText: (0, import_tools.truncateForHeader)(input.command, 140)
106
106
  }),
107
107
  /**
108
108
  * Generate preview for approval UI - shows the command to be executed
@@ -123,8 +123,10 @@ Security: Dangerous commands are blocked. Injection attempts are detected. Requi
123
123
  }
124
124
  },
125
125
  async execute(input, context) {
126
- const resolvedProcessService = await getProcessService(context);
127
126
  const { command, description, timeout, run_in_background, cwd } = input;
127
+ const resolvedProcessService = await getProcessService(context, {
128
+ background: run_in_background
129
+ });
128
130
  let validatedCwd = cwd;
129
131
  if (cwd) {
130
132
  const baseDir = resolvedProcessService.getConfig().workingDirectory || process.cwd();
@@ -5,8 +5,8 @@
5
5
  * Pattern-based approval support is declared on the tool (ToolManager stays generic).
6
6
  */
7
7
  import { z } from 'zod';
8
- import type { Tool, ToolExecutionContext } from '@dexto/core';
9
- import { ProcessService } from './process-service.js';
8
+ import type { Tool, ToolExecutionContext } from '@dexto/core/tools';
9
+ import type { ExecuteOptions, ProcessConfig, ProcessHandle, ProcessOutput, ProcessResult } from './types.js';
10
10
  declare const BashExecInputSchema: z.ZodObject<{
11
11
  command: z.ZodString;
12
12
  description: z.ZodOptional<z.ZodString>;
@@ -17,7 +17,15 @@ declare const BashExecInputSchema: z.ZodObject<{
17
17
  /**
18
18
  * Create the bash_exec internal tool
19
19
  */
20
- export type ProcessServiceGetter = (context: ToolExecutionContext) => Promise<ProcessService>;
20
+ export interface ProcessCommandService {
21
+ executeCommand(command: string, options?: ExecuteOptions): Promise<ProcessResult | ProcessHandle>;
22
+ getConfig(): Readonly<ProcessConfig>;
23
+ getProcessOutput(processId: string): Promise<ProcessOutput>;
24
+ killProcess(processId: string): Promise<void>;
25
+ }
26
+ export type ProcessServiceGetter = (context: ToolExecutionContext, options?: {
27
+ background?: boolean;
28
+ }) => Promise<ProcessCommandService>;
21
29
  export declare function createBashExecTool(getProcessService: ProcessServiceGetter): Tool<typeof BashExecInputSchema>;
22
30
  export {};
23
31
  //# sourceMappingURL=bash-exec-tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bash-exec-tool.d.ts","sourceRoot":"","sources":["../src/bash-exec-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD,QAAA,MAAM,mBAAmB;;;;;;kBAwBZ,CAAC;AAEd;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAE9F,wBAAgB,kBAAkB,CAC9B,iBAAiB,EAAE,oBAAoB,GACxC,IAAI,CAAC,OAAO,mBAAmB,CAAC,CAmKlC"}
1
+ {"version":3,"file":"bash-exec-tool.d.ts","sourceRoot":"","sources":["../src/bash-exec-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAoB,IAAI,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAMtF,OAAO,KAAK,EACR,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EAChB,MAAM,YAAY,CAAC;AAEpB,QAAA,MAAM,mBAAmB;;;;;;kBAwBZ,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,cAAc,CACV,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACzB,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC,CAAC;IAC1C,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC,CAAC;IACrC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,MAAM,MAAM,oBAAoB,GAAG,CAC/B,OAAO,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,KACjC,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC,wBAAgB,kBAAkB,CAC9B,iBAAiB,EAAE,oBAAoB,GACxC,IAAI,CAAC,OAAO,mBAAmB,CAAC,CAoKlC"}
@@ -1,6 +1,6 @@
1
1
  import * as path from "node:path";
2
2
  import { z } from "zod";
3
- import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
3
+ import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core/tools";
4
4
  import { ProcessError } from "./errors.js";
5
5
  import {
6
6
  generateCommandPatternKey,
@@ -93,8 +93,10 @@ Security: Dangerous commands are blocked. Injection attempts are detected. Requi
93
93
  }
94
94
  },
95
95
  async execute(input, context) {
96
- const resolvedProcessService = await getProcessService(context);
97
96
  const { command, description, timeout, run_in_background, cwd } = input;
97
+ const resolvedProcessService = await getProcessService(context, {
98
+ background: run_in_background
99
+ });
98
100
  let validatedCwd = cwd;
99
101
  if (cwd) {
100
102
  const baseDir = resolvedProcessService.getConfig().workingDirectory || process.cwd();
@@ -22,23 +22,25 @@ __export(bash_output_tool_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(bash_output_tool_exports);
24
24
  var import_zod = require("zod");
25
- var import_core = require("@dexto/core");
25
+ var import_tools = require("@dexto/core/tools");
26
26
  const BashOutputInputSchema = import_zod.z.object({
27
27
  process_id: import_zod.z.string().describe("Process ID from bash_exec (when run_in_background=true)")
28
28
  }).strict();
29
29
  function createBashOutputTool(getProcessService) {
30
- return (0, import_core.defineTool)({
30
+ return (0, import_tools.defineTool)({
31
31
  id: "bash_output",
32
32
  description: "Retrieve output from a background process started with bash_exec. Returns stdout, stderr, status (running/completed/failed), exit code, and duration. Each call returns only new output since last read. The output buffer is cleared after reading. Use this tool to monitor long-running commands.",
33
33
  inputSchema: BashOutputInputSchema,
34
34
  presentation: {
35
- describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
35
+ describeHeader: (input) => (0, import_tools.createLocalToolCallHeader)({
36
36
  title: "Bash Output",
37
- argsText: (0, import_core.truncateForHeader)(input.process_id, 80)
37
+ argsText: (0, import_tools.truncateForHeader)(input.process_id, 80)
38
38
  })
39
39
  },
40
40
  async execute(input, context) {
41
- const resolvedProcessService = await getProcessService(context);
41
+ const resolvedProcessService = await getProcessService(context, {
42
+ background: true
43
+ });
42
44
  const { process_id } = input;
43
45
  const result = await resolvedProcessService.getProcessOutput(process_id);
44
46
  return {
@@ -4,7 +4,7 @@
4
4
  * Internal tool for retrieving output from background processes
5
5
  */
6
6
  import { z } from 'zod';
7
- import type { Tool } from '@dexto/core';
7
+ import type { Tool } from '@dexto/core/tools';
8
8
  import type { ProcessServiceGetter } from './bash-exec-tool.js';
9
9
  declare const BashOutputInputSchema: z.ZodObject<{
10
10
  process_id: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"bash-output-tool.d.ts","sourceRoot":"","sources":["../src/bash-output-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,QAAA,MAAM,qBAAqB;;kBAId,CAAC;AAEd;;GAEG;AACH,wBAAgB,oBAAoB,CAChC,iBAAiB,EAAE,oBAAoB,GACxC,IAAI,CAAC,OAAO,qBAAqB,CAAC,CA+BpC"}
1
+ {"version":3,"file":"bash-output-tool.d.ts","sourceRoot":"","sources":["../src/bash-output-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,QAAA,MAAM,qBAAqB;;kBAId,CAAC;AAEd;;GAEG;AACH,wBAAgB,oBAAoB,CAChC,iBAAiB,EAAE,oBAAoB,GACxC,IAAI,CAAC,OAAO,qBAAqB,CAAC,CAiCpC"}
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
2
+ import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core/tools";
3
3
  const BashOutputInputSchema = z.object({
4
4
  process_id: z.string().describe("Process ID from bash_exec (when run_in_background=true)")
5
5
  }).strict();
@@ -15,7 +15,9 @@ function createBashOutputTool(getProcessService) {
15
15
  })
16
16
  },
17
17
  async execute(input, context) {
18
- const resolvedProcessService = await getProcessService(context);
18
+ const resolvedProcessService = await getProcessService(context, {
19
+ background: true
20
+ });
19
21
  const { process_id } = input;
20
22
  const result = await resolvedProcessService.getProcessOutput(process_id);
21
23
  return {
@@ -4,7 +4,7 @@
4
4
  * Security-focused command validation for process execution
5
5
  */
6
6
  import { ProcessConfig, CommandValidation } from './types.js';
7
- import type { Logger } from '@dexto/core';
7
+ import type { Logger } from '@dexto/core/logger';
8
8
  /**
9
9
  * CommandValidator - Validates commands for security and policy compliance
10
10
  *
@@ -1 +1 @@
1
- {"version":3,"file":"command-validator.d.ts","sourceRoot":"","sources":["../src/command-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAkQ1C;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM;IAQjD;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAgFnD;;OAEG;IACH,OAAO,CAAC,eAAe;IAgCvB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAyCpC;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,gBAAgB,IAAI,MAAM;CAG7B"}
1
+ {"version":3,"file":"command-validator.d.ts","sourceRoot":"","sources":["../src/command-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAkQjD;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM;IAQjD;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAgFnD;;OAEG;IACH,OAAO,CAAC,eAAe;IAgCvB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAyCpC;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,gBAAgB,IAAI,MAAM;CAG7B"}
package/dist/errors.cjs CHANGED
@@ -21,7 +21,7 @@ __export(errors_exports, {
21
21
  ProcessError: () => ProcessError
22
22
  });
23
23
  module.exports = __toCommonJS(errors_exports);
24
- var import_core = require("@dexto/core");
24
+ var import_errors = require("@dexto/core/errors");
25
25
  var import_error_codes = require("./error-codes.js");
26
26
  const PROCESS_SCOPE = "process";
27
27
  class ProcessError {
@@ -31,10 +31,10 @@ class ProcessError {
31
31
  * Invalid command error
32
32
  */
33
33
  static invalidCommand(command, reason) {
34
- return new import_core.DextoRuntimeError(
34
+ return new import_errors.DextoRuntimeError(
35
35
  import_error_codes.ProcessErrorCode.INVALID_COMMAND,
36
36
  PROCESS_SCOPE,
37
- import_core.ErrorType.USER,
37
+ import_errors.ErrorType.USER,
38
38
  `Invalid command: ${command}. ${reason}`,
39
39
  { command, reason }
40
40
  );
@@ -43,10 +43,10 @@ class ProcessError {
43
43
  * Command blocked error
44
44
  */
45
45
  static commandBlocked(command, reason) {
46
- return new import_core.DextoRuntimeError(
46
+ return new import_errors.DextoRuntimeError(
47
47
  import_error_codes.ProcessErrorCode.COMMAND_BLOCKED,
48
48
  PROCESS_SCOPE,
49
- import_core.ErrorType.FORBIDDEN,
49
+ import_errors.ErrorType.FORBIDDEN,
50
50
  `Command is blocked: ${command}. ${reason}`,
51
51
  { command, reason }
52
52
  );
@@ -55,10 +55,10 @@ class ProcessError {
55
55
  * Command too long error
56
56
  */
57
57
  static commandTooLong(length, maxLength) {
58
- return new import_core.DextoRuntimeError(
58
+ return new import_errors.DextoRuntimeError(
59
59
  import_error_codes.ProcessErrorCode.COMMAND_TOO_LONG,
60
60
  PROCESS_SCOPE,
61
- import_core.ErrorType.USER,
61
+ import_errors.ErrorType.USER,
62
62
  `Command too long: ${length} characters. Maximum allowed: ${maxLength}`,
63
63
  { length, maxLength }
64
64
  );
@@ -67,10 +67,10 @@ class ProcessError {
67
67
  * Command injection detected error
68
68
  */
69
69
  static commandInjection(command, pattern) {
70
- return new import_core.DextoRuntimeError(
70
+ return new import_errors.DextoRuntimeError(
71
71
  import_error_codes.ProcessErrorCode.INJECTION_DETECTED,
72
72
  PROCESS_SCOPE,
73
- import_core.ErrorType.FORBIDDEN,
73
+ import_errors.ErrorType.FORBIDDEN,
74
74
  `Potential command injection detected in: ${command}. Pattern: ${pattern}`,
75
75
  { command, pattern }
76
76
  );
@@ -79,10 +79,10 @@ class ProcessError {
79
79
  * Command approval required error
80
80
  */
81
81
  static approvalRequired(command, reason) {
82
- return new import_core.DextoRuntimeError(
82
+ return new import_errors.DextoRuntimeError(
83
83
  import_error_codes.ProcessErrorCode.APPROVAL_REQUIRED,
84
84
  PROCESS_SCOPE,
85
- import_core.ErrorType.FORBIDDEN,
85
+ import_errors.ErrorType.FORBIDDEN,
86
86
  `Command requires approval: ${command}${reason ? `. ${reason}` : ""}`,
87
87
  { command, reason },
88
88
  "Provide an approval function to execute dangerous commands"
@@ -92,10 +92,10 @@ class ProcessError {
92
92
  * Command approval denied error
93
93
  */
94
94
  static approvalDenied(command) {
95
- return new import_core.DextoRuntimeError(
95
+ return new import_errors.DextoRuntimeError(
96
96
  import_error_codes.ProcessErrorCode.APPROVAL_DENIED,
97
97
  PROCESS_SCOPE,
98
- import_core.ErrorType.FORBIDDEN,
98
+ import_errors.ErrorType.FORBIDDEN,
99
99
  `Command approval denied by user: ${command}`,
100
100
  { command }
101
101
  );
@@ -104,10 +104,10 @@ class ProcessError {
104
104
  * Command execution failed error
105
105
  */
106
106
  static executionFailed(command, cause) {
107
- return new import_core.DextoRuntimeError(
107
+ return new import_errors.DextoRuntimeError(
108
108
  import_error_codes.ProcessErrorCode.EXECUTION_FAILED,
109
109
  PROCESS_SCOPE,
110
- import_core.ErrorType.SYSTEM,
110
+ import_errors.ErrorType.SYSTEM,
111
111
  `Command execution failed: ${command}. ${cause}`,
112
112
  { command, cause }
113
113
  );
@@ -116,10 +116,10 @@ class ProcessError {
116
116
  * Command timeout error
117
117
  */
118
118
  static timeout(command, timeout) {
119
- return new import_core.DextoRuntimeError(
119
+ return new import_errors.DextoRuntimeError(
120
120
  import_error_codes.ProcessErrorCode.TIMEOUT,
121
121
  PROCESS_SCOPE,
122
- import_core.ErrorType.TIMEOUT,
122
+ import_errors.ErrorType.TIMEOUT,
123
123
  `Command timed out after ${timeout}ms: ${command}`,
124
124
  { command, timeout },
125
125
  "Increase timeout or optimize the command"
@@ -129,10 +129,10 @@ class ProcessError {
129
129
  * Permission denied error
130
130
  */
131
131
  static permissionDenied(command) {
132
- return new import_core.DextoRuntimeError(
132
+ return new import_errors.DextoRuntimeError(
133
133
  import_error_codes.ProcessErrorCode.PERMISSION_DENIED,
134
134
  PROCESS_SCOPE,
135
- import_core.ErrorType.FORBIDDEN,
135
+ import_errors.ErrorType.FORBIDDEN,
136
136
  `Permission denied: ${command}`,
137
137
  { command }
138
138
  );
@@ -141,10 +141,10 @@ class ProcessError {
141
141
  * Command not found error
142
142
  */
143
143
  static commandNotFound(command) {
144
- return new import_core.DextoRuntimeError(
144
+ return new import_errors.DextoRuntimeError(
145
145
  import_error_codes.ProcessErrorCode.COMMAND_NOT_FOUND,
146
146
  PROCESS_SCOPE,
147
- import_core.ErrorType.NOT_FOUND,
147
+ import_errors.ErrorType.NOT_FOUND,
148
148
  `Command not found: ${command}`,
149
149
  { command },
150
150
  "Ensure the command is installed and available in PATH"
@@ -154,10 +154,10 @@ class ProcessError {
154
154
  * Invalid working directory error
155
155
  */
156
156
  static invalidWorkingDirectory(path, reason) {
157
- return new import_core.DextoRuntimeError(
157
+ return new import_errors.DextoRuntimeError(
158
158
  import_error_codes.ProcessErrorCode.WORKING_DIRECTORY_INVALID,
159
159
  PROCESS_SCOPE,
160
- import_core.ErrorType.USER,
160
+ import_errors.ErrorType.USER,
161
161
  `Invalid working directory: ${path}. ${reason}`,
162
162
  { path, reason }
163
163
  );
@@ -166,10 +166,10 @@ class ProcessError {
166
166
  * Process not found error
167
167
  */
168
168
  static processNotFound(processId) {
169
- return new import_core.DextoRuntimeError(
169
+ return new import_errors.DextoRuntimeError(
170
170
  import_error_codes.ProcessErrorCode.PROCESS_NOT_FOUND,
171
171
  PROCESS_SCOPE,
172
- import_core.ErrorType.NOT_FOUND,
172
+ import_errors.ErrorType.NOT_FOUND,
173
173
  `Process not found: ${processId}`,
174
174
  { processId }
175
175
  );
@@ -178,10 +178,10 @@ class ProcessError {
178
178
  * Too many concurrent processes error
179
179
  */
180
180
  static tooManyProcesses(current, max) {
181
- return new import_core.DextoRuntimeError(
181
+ return new import_errors.DextoRuntimeError(
182
182
  import_error_codes.ProcessErrorCode.TOO_MANY_PROCESSES,
183
183
  PROCESS_SCOPE,
184
- import_core.ErrorType.USER,
184
+ import_errors.ErrorType.USER,
185
185
  `Too many concurrent processes: ${current}. Maximum allowed: ${max}`,
186
186
  { current, max },
187
187
  "Wait for running processes to complete or increase the limit"
@@ -191,10 +191,10 @@ class ProcessError {
191
191
  * Kill process failed error
192
192
  */
193
193
  static killFailed(processId, cause) {
194
- return new import_core.DextoRuntimeError(
194
+ return new import_errors.DextoRuntimeError(
195
195
  import_error_codes.ProcessErrorCode.KILL_FAILED,
196
196
  PROCESS_SCOPE,
197
- import_core.ErrorType.SYSTEM,
197
+ import_errors.ErrorType.SYSTEM,
198
198
  `Failed to kill process ${processId}: ${cause}`,
199
199
  { processId, cause }
200
200
  );
@@ -203,10 +203,10 @@ class ProcessError {
203
203
  * Output buffer full error
204
204
  */
205
205
  static outputBufferFull(processId, size, maxSize) {
206
- return new import_core.DextoRuntimeError(
206
+ return new import_errors.DextoRuntimeError(
207
207
  import_error_codes.ProcessErrorCode.OUTPUT_BUFFER_FULL,
208
208
  PROCESS_SCOPE,
209
- import_core.ErrorType.SYSTEM,
209
+ import_errors.ErrorType.SYSTEM,
210
210
  `Output buffer full for process ${processId}: ${size} bytes. Maximum: ${maxSize}`,
211
211
  { processId, size, maxSize },
212
212
  "Process output exceeded buffer limit"
@@ -216,10 +216,10 @@ class ProcessError {
216
216
  * Invalid configuration error
217
217
  */
218
218
  static invalidConfig(reason) {
219
- return new import_core.DextoRuntimeError(
219
+ return new import_errors.DextoRuntimeError(
220
220
  import_error_codes.ProcessErrorCode.INVALID_CONFIG,
221
221
  PROCESS_SCOPE,
222
- import_core.ErrorType.USER,
222
+ import_errors.ErrorType.USER,
223
223
  `Invalid Process configuration: ${reason}`,
224
224
  { reason }
225
225
  );
@@ -228,10 +228,10 @@ class ProcessError {
228
228
  * Service not initialized error
229
229
  */
230
230
  static notInitialized() {
231
- return new import_core.DextoRuntimeError(
231
+ return new import_errors.DextoRuntimeError(
232
232
  import_error_codes.ProcessErrorCode.SERVICE_NOT_INITIALIZED,
233
233
  PROCESS_SCOPE,
234
- import_core.ErrorType.SYSTEM,
234
+ import_errors.ErrorType.SYSTEM,
235
235
  "ProcessService has not been initialized",
236
236
  {},
237
237
  "Initialize the ProcessService before using it"
package/dist/errors.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Error classes for process execution and management
5
5
  */
6
- import { DextoRuntimeError } from '@dexto/core';
6
+ import { DextoRuntimeError } from '@dexto/core/errors';
7
7
  export interface ProcessErrorContext {
8
8
  command?: string;
9
9
  processId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAa,MAAM,aAAa,CAAC;AAM3D,MAAM,WAAW,mBAAmB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,YAAY;IACrB,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAUzE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAUzE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB;IAU3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAU5E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAW5E;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAUzD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB;IAUzE;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAWnE;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAU3D;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAW1D;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAU/E;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB;IAU5D;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB;IAWxE;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB;IAUtE;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAW5F;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAUvD;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,iBAAiB;CAU7C"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAa,MAAM,oBAAoB,CAAC;AAMlE,MAAM,WAAW,mBAAmB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,YAAY;IACrB,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAUzE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAUzE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB;IAU3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAU5E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAW5E;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAUzD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB;IAUzE;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAWnE;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAU3D;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAW1D;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAU/E;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB;IAU5D;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB;IAWxE;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB;IAUtE;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAW5F;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAUvD;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,iBAAiB;CAU7C"}
package/dist/errors.js CHANGED
@@ -1,4 +1,4 @@
1
- import { DextoRuntimeError, ErrorType } from "@dexto/core";
1
+ import { DextoRuntimeError, ErrorType } from "@dexto/core/errors";
2
2
  const PROCESS_SCOPE = "process";
3
3
  import { ProcessErrorCode } from "./error-codes.js";
4
4
  class ProcessError {
package/dist/index.d.cts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { ToolFactory } from '@dexto/agent-config';
2
2
  import { z } from 'zod';
3
- import { Logger, DextoRuntimeError, ToolExecutionContext, Tool } from '@dexto/core';
3
+ import { Logger } from '@dexto/core/logger';
4
+ import { DextoRuntimeError } from '@dexto/core/errors';
5
+ import { ToolExecutionContext, Tool } from '@dexto/core/tools';
4
6
 
5
7
  /**
6
8
  * Process Tools Factory
@@ -415,7 +417,15 @@ declare const BashExecInputSchema: z.ZodObject<{
415
417
  /**
416
418
  * Create the bash_exec internal tool
417
419
  */
418
- type ProcessServiceGetter = (context: ToolExecutionContext) => Promise<ProcessService>;
420
+ interface ProcessCommandService {
421
+ executeCommand(command: string, options?: ExecuteOptions): Promise<ProcessResult | ProcessHandle>;
422
+ getConfig(): Readonly<ProcessConfig>;
423
+ getProcessOutput(processId: string): Promise<ProcessOutput>;
424
+ killProcess(processId: string): Promise<void>;
425
+ }
426
+ type ProcessServiceGetter = (context: ToolExecutionContext, options?: {
427
+ background?: boolean;
428
+ }) => Promise<ProcessCommandService>;
419
429
  declare function createBashExecTool(getProcessService: ProcessServiceGetter): Tool<typeof BashExecInputSchema>;
420
430
 
421
431
  /**
@@ -22,23 +22,25 @@ __export(kill_process_tool_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(kill_process_tool_exports);
24
24
  var import_zod = require("zod");
25
- var import_core = require("@dexto/core");
25
+ var import_tools = require("@dexto/core/tools");
26
26
  const KillProcessInputSchema = import_zod.z.object({
27
27
  process_id: import_zod.z.string().describe("Process ID of the background process to terminate")
28
28
  }).strict();
29
29
  function createKillProcessTool(getProcessService) {
30
- return (0, import_core.defineTool)({
30
+ return (0, import_tools.defineTool)({
31
31
  id: "kill_process",
32
32
  description: "Terminate a background process started with bash_exec. Sends SIGTERM signal first, then SIGKILL if process doesn't terminate within 5 seconds. Only works on processes started by this agent. Returns success status and whether the process was running. Does not require additional approval (process was already approved when started).",
33
33
  inputSchema: KillProcessInputSchema,
34
34
  presentation: {
35
- describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
35
+ describeHeader: (input) => (0, import_tools.createLocalToolCallHeader)({
36
36
  title: "Kill",
37
- argsText: (0, import_core.truncateForHeader)(input.process_id, 80)
37
+ argsText: (0, import_tools.truncateForHeader)(input.process_id, 80)
38
38
  })
39
39
  },
40
40
  async execute(input, context) {
41
- const resolvedProcessService = await getProcessService(context);
41
+ const resolvedProcessService = await getProcessService(context, {
42
+ background: true
43
+ });
42
44
  const { process_id } = input;
43
45
  await resolvedProcessService.killProcess(process_id);
44
46
  return {
@@ -4,7 +4,7 @@
4
4
  * Internal tool for terminating background processes
5
5
  */
6
6
  import { z } from 'zod';
7
- import type { Tool } from '@dexto/core';
7
+ import type { Tool } from '@dexto/core/tools';
8
8
  import type { ProcessServiceGetter } from './bash-exec-tool.js';
9
9
  declare const KillProcessInputSchema: z.ZodObject<{
10
10
  process_id: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"kill-process-tool.d.ts","sourceRoot":"","sources":["../src/kill-process-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,QAAA,MAAM,sBAAsB;;kBAIf,CAAC;AAEd;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,iBAAiB,EAAE,oBAAoB,GACxC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CA8BrC"}
1
+ {"version":3,"file":"kill-process-tool.d.ts","sourceRoot":"","sources":["../src/kill-process-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,QAAA,MAAM,sBAAsB;;kBAIf,CAAC;AAEd;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,iBAAiB,EAAE,oBAAoB,GACxC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAgCrC"}
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
2
+ import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core/tools";
3
3
  const KillProcessInputSchema = z.object({
4
4
  process_id: z.string().describe("Process ID of the background process to terminate")
5
5
  }).strict();
@@ -15,7 +15,9 @@ function createKillProcessTool(getProcessService) {
15
15
  })
16
16
  },
17
17
  async execute(input, context) {
18
- const resolvedProcessService = await getProcessService(context);
18
+ const resolvedProcessService = await getProcessService(context, {
19
+ background: true
20
+ });
19
21
  const { process_id } = input;
20
22
  await resolvedProcessService.killProcess(process_id);
21
23
  return {
@@ -36,7 +36,7 @@ var crypto = __toESM(require("node:crypto"), 1);
36
36
  var path = __toESM(require("node:path"), 1);
37
37
  var import_command_validator = require("./command-validator.js");
38
38
  var import_errors = require("./errors.js");
39
- var import_core = require("@dexto/core");
39
+ var import_logger = require("@dexto/core/logger");
40
40
  const DEFAULT_TIMEOUT = 12e4;
41
41
  class ProcessService {
42
42
  config;
@@ -54,7 +54,7 @@ class ProcessService {
54
54
  */
55
55
  constructor(config, logger) {
56
56
  this.config = config;
57
- this.logger = logger.createChild(import_core.DextoLogComponent.PROCESS);
57
+ this.logger = logger.createChild(import_logger.DextoLogComponent.PROCESS);
58
58
  this.commandValidator = new import_command_validator.CommandValidator(this.config, this.logger);
59
59
  }
60
60
  /**
@@ -4,7 +4,7 @@
4
4
  * Secure command execution and process management for Dexto internal tools
5
5
  */
6
6
  import { ProcessConfig, ExecuteOptions, ProcessResult, ProcessHandle, ProcessOutput, ProcessInfo } from './types.js';
7
- import type { Logger } from '@dexto/core';
7
+ import type { Logger } from '@dexto/core/logger';
8
8
  /**
9
9
  * ProcessService - Handles command execution and process management
10
10
  *
@@ -1 +1 @@
1
- {"version":3,"file":"process-service.d.ts","sourceRoot":"","sources":["../src/process-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACH,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,EAEd,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAoB1C;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;;;OAMG;gBACS,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM;IAQjD;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;OAEG;YACW,YAAY;IAa1B;;;;OAIG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxC;;OAEG;IACG,cAAc,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,cAAmB,GAC7B,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC;IAqDzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAEjD;;OAEG;YACW,eAAe;IA6B7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8KzB;;OAEG;YACW,mBAAmB;IAoKjC;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA6BjE;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCnD;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAe7C;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC;IAIpC;;OAEG;IACH,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAQnD;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAcjC"}
1
+ {"version":3,"file":"process-service.d.ts","sourceRoot":"","sources":["../src/process-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACH,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,EAEd,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAoBjD;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;;;OAMG;gBACS,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM;IAQjD;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;OAEG;YACW,YAAY;IAa1B;;;;OAIG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxC;;OAEG;IACG,cAAc,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,cAAmB,GAC7B,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC;IAqDzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAEjD;;OAEG;YACW,eAAe;IA6B7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8KzB;;OAEG;YACW,mBAAmB;IAoKjC;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA6BjE;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCnD;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAe7C;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC;IAIpC;;OAEG;IACH,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAQnD;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAcjC"}
@@ -3,7 +3,7 @@ import * as crypto from "node:crypto";
3
3
  import * as path from "node:path";
4
4
  import { CommandValidator } from "./command-validator.js";
5
5
  import { ProcessError } from "./errors.js";
6
- import { DextoLogComponent } from "@dexto/core";
6
+ import { DextoLogComponent } from "@dexto/core/logger";
7
7
  const DEFAULT_TIMEOUT = 12e4;
8
8
  class ProcessService {
9
9
  config;
@@ -26,6 +26,9 @@ var import_bash_exec_tool = require("./bash-exec-tool.js");
26
26
  var import_bash_output_tool = require("./bash-output-tool.js");
27
27
  var import_kill_process_tool = require("./kill-process-tool.js");
28
28
  var import_tool_factory_config = require("./tool-factory-config.js");
29
+ var import_command_validator = require("./command-validator.js");
30
+ var import_errors = require("./errors.js");
31
+ var import_workspace = require("@dexto/core/workspace");
29
32
  const processToolsFactory = {
30
33
  configSchema: import_tool_factory_config.ProcessToolsConfigSchema,
31
34
  metadata: {
@@ -57,7 +60,11 @@ const processToolsFactory = {
57
60
  const hasMethods = typeof candidate.executeCommand === "function" && typeof candidate.killProcess === "function" && typeof candidate.setWorkingDirectory === "function" && typeof candidate.getConfig === "function";
58
61
  return hasMethods ? candidate : null;
59
62
  };
60
- const getProcessService = async (context) => {
63
+ const getProcessService = async (context, options = {}) => {
64
+ const workspaceProcessService = options.background === true ? null : await createWorkspaceProcessService(context, processConfig);
65
+ if (workspaceProcessService !== null) {
66
+ return workspaceProcessService;
67
+ }
61
68
  const injectedService = resolveInjectedService(context);
62
69
  if (injectedService) {
63
70
  applyWorkspace(context, injectedService);
@@ -83,6 +90,81 @@ const processToolsFactory = {
83
90
  ];
84
91
  }
85
92
  };
93
+ async function createWorkspaceProcessService(context, processConfig) {
94
+ const workspaceManager = context.services?.workspaceManager;
95
+ if (workspaceManager === void 0) {
96
+ return null;
97
+ }
98
+ let handle;
99
+ try {
100
+ handle = await workspaceManager.open({ intent: "process" });
101
+ } catch (error) {
102
+ if (isWorkspaceUnavailable(error)) {
103
+ return null;
104
+ }
105
+ throw error;
106
+ }
107
+ if (handle.processes === void 0) {
108
+ return null;
109
+ }
110
+ return new WorkspaceProcessService(processConfig, context, handle);
111
+ }
112
+ function isWorkspaceUnavailable(error) {
113
+ if (typeof error === "object" && error !== null && "issues" in error && Array.isArray(error.issues)) {
114
+ return error.issues.some(
115
+ (issue) => typeof issue === "object" && issue !== null && "code" in issue && (issue.code === import_workspace.WorkspaceErrorCodes.CURRENT_WORKSPACE_REQUIRED || issue.code === import_workspace.WorkspaceErrorCodes.HANDLE_PROVIDER_REQUIRED)
116
+ );
117
+ }
118
+ return false;
119
+ }
120
+ class WorkspaceProcessService {
121
+ constructor(processConfig, context, handle) {
122
+ this.processConfig = processConfig;
123
+ this.context = context;
124
+ this.handle = handle;
125
+ this.commandValidator = new import_command_validator.CommandValidator(processConfig, context.logger);
126
+ }
127
+ commandValidator;
128
+ async executeCommand(command, options = {}) {
129
+ if (options.runInBackground === true) {
130
+ throw import_errors.ProcessError.executionFailed(
131
+ command,
132
+ "Workspace process handles do not support background execution yet"
133
+ );
134
+ }
135
+ const validation = this.commandValidator.validateCommand(command);
136
+ if (!validation.isValid || !validation.normalizedCommand) {
137
+ throw import_errors.ProcessError.invalidCommand(command, validation.error || "Unknown error");
138
+ }
139
+ const startedAt = Date.now();
140
+ const result = await this.handle.processes?.exec({
141
+ command: validation.normalizedCommand,
142
+ ...options.cwd === void 0 ? {} : { cwd: options.cwd },
143
+ ...options.timeout === void 0 ? {} : { timeout: options.timeout }
144
+ });
145
+ if (result === void 0) {
146
+ throw import_errors.ProcessError.executionFailed(command, "Workspace process execution unavailable");
147
+ }
148
+ return {
149
+ duration: Date.now() - startedAt,
150
+ exitCode: result.exitCode ?? 0,
151
+ stderr: result.stderr,
152
+ stdout: result.stdout
153
+ };
154
+ }
155
+ getConfig() {
156
+ return {
157
+ ...this.processConfig,
158
+ workingDirectory: this.handle.context.path
159
+ };
160
+ }
161
+ async getProcessOutput(processId) {
162
+ throw import_errors.ProcessError.processNotFound(processId);
163
+ }
164
+ async killProcess(processId) {
165
+ throw import_errors.ProcessError.processNotFound(processId);
166
+ }
167
+ }
86
168
  // Annotate the CommonJS export names for ESM import in node:
87
169
  0 && (module.exports = {
88
170
  processToolsFactory
@@ -1 +1 @@
1
- {"version":3,"file":"tool-factory.d.ts","sourceRoot":"","sources":["../src/tool-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMvD,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAG7F,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,kBAAkB,CA0E/D,CAAC"}
1
+ {"version":3,"file":"tool-factory.d.ts","sourceRoot":"","sources":["../src/tool-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAO7F,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,kBAAkB,CAmF/D,CAAC"}
@@ -3,6 +3,9 @@ import { createBashExecTool } from "./bash-exec-tool.js";
3
3
  import { createBashOutputTool } from "./bash-output-tool.js";
4
4
  import { createKillProcessTool } from "./kill-process-tool.js";
5
5
  import { ProcessToolsConfigSchema } from "./tool-factory-config.js";
6
+ import { CommandValidator } from "./command-validator.js";
7
+ import { ProcessError } from "./errors.js";
8
+ import { WorkspaceErrorCodes } from "@dexto/core/workspace";
6
9
  const processToolsFactory = {
7
10
  configSchema: ProcessToolsConfigSchema,
8
11
  metadata: {
@@ -34,7 +37,11 @@ const processToolsFactory = {
34
37
  const hasMethods = typeof candidate.executeCommand === "function" && typeof candidate.killProcess === "function" && typeof candidate.setWorkingDirectory === "function" && typeof candidate.getConfig === "function";
35
38
  return hasMethods ? candidate : null;
36
39
  };
37
- const getProcessService = async (context) => {
40
+ const getProcessService = async (context, options = {}) => {
41
+ const workspaceProcessService = options.background === true ? null : await createWorkspaceProcessService(context, processConfig);
42
+ if (workspaceProcessService !== null) {
43
+ return workspaceProcessService;
44
+ }
38
45
  const injectedService = resolveInjectedService(context);
39
46
  if (injectedService) {
40
47
  applyWorkspace(context, injectedService);
@@ -60,6 +67,81 @@ const processToolsFactory = {
60
67
  ];
61
68
  }
62
69
  };
70
+ async function createWorkspaceProcessService(context, processConfig) {
71
+ const workspaceManager = context.services?.workspaceManager;
72
+ if (workspaceManager === void 0) {
73
+ return null;
74
+ }
75
+ let handle;
76
+ try {
77
+ handle = await workspaceManager.open({ intent: "process" });
78
+ } catch (error) {
79
+ if (isWorkspaceUnavailable(error)) {
80
+ return null;
81
+ }
82
+ throw error;
83
+ }
84
+ if (handle.processes === void 0) {
85
+ return null;
86
+ }
87
+ return new WorkspaceProcessService(processConfig, context, handle);
88
+ }
89
+ function isWorkspaceUnavailable(error) {
90
+ if (typeof error === "object" && error !== null && "issues" in error && Array.isArray(error.issues)) {
91
+ return error.issues.some(
92
+ (issue) => typeof issue === "object" && issue !== null && "code" in issue && (issue.code === WorkspaceErrorCodes.CURRENT_WORKSPACE_REQUIRED || issue.code === WorkspaceErrorCodes.HANDLE_PROVIDER_REQUIRED)
93
+ );
94
+ }
95
+ return false;
96
+ }
97
+ class WorkspaceProcessService {
98
+ constructor(processConfig, context, handle) {
99
+ this.processConfig = processConfig;
100
+ this.context = context;
101
+ this.handle = handle;
102
+ this.commandValidator = new CommandValidator(processConfig, context.logger);
103
+ }
104
+ commandValidator;
105
+ async executeCommand(command, options = {}) {
106
+ if (options.runInBackground === true) {
107
+ throw ProcessError.executionFailed(
108
+ command,
109
+ "Workspace process handles do not support background execution yet"
110
+ );
111
+ }
112
+ const validation = this.commandValidator.validateCommand(command);
113
+ if (!validation.isValid || !validation.normalizedCommand) {
114
+ throw ProcessError.invalidCommand(command, validation.error || "Unknown error");
115
+ }
116
+ const startedAt = Date.now();
117
+ const result = await this.handle.processes?.exec({
118
+ command: validation.normalizedCommand,
119
+ ...options.cwd === void 0 ? {} : { cwd: options.cwd },
120
+ ...options.timeout === void 0 ? {} : { timeout: options.timeout }
121
+ });
122
+ if (result === void 0) {
123
+ throw ProcessError.executionFailed(command, "Workspace process execution unavailable");
124
+ }
125
+ return {
126
+ duration: Date.now() - startedAt,
127
+ exitCode: result.exitCode ?? 0,
128
+ stderr: result.stderr,
129
+ stdout: result.stdout
130
+ };
131
+ }
132
+ getConfig() {
133
+ return {
134
+ ...this.processConfig,
135
+ workingDirectory: this.handle.context.path
136
+ };
137
+ }
138
+ async getProcessOutput(processId) {
139
+ throw ProcessError.processNotFound(processId);
140
+ }
141
+ async killProcess(processId) {
142
+ throw ProcessError.processNotFound(processId);
143
+ }
144
+ }
63
145
  export {
64
146
  processToolsFactory
65
147
  };
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var import_workspace = require("@dexto/core/workspace");
3
+ var import_vitest = require("vitest");
4
+ var import_tool_factory = require("./tool-factory.js");
5
+ var import_tool_factory_config = require("./tool-factory-config.js");
6
+ const processConfig = import_tool_factory_config.ProcessToolsConfigSchema.parse({ type: "process-tools" });
7
+ (0, import_vitest.describe)("processToolsFactory", () => {
8
+ (0, import_vitest.it)("executes foreground bash commands through a workspace process handle when available", async () => {
9
+ const exec = import_vitest.vi.fn(async () => ({
10
+ exitCode: 7,
11
+ stderr: "not clean",
12
+ stdout: "changed files"
13
+ }));
14
+ const open = import_vitest.vi.fn(async () => ({
15
+ capabilities: ["files", "processes"],
16
+ context: {
17
+ createdAt: 1,
18
+ id: "workspace-1",
19
+ lastActiveAt: 1,
20
+ path: "/workspace"
21
+ },
22
+ files: {},
23
+ processes: { exec }
24
+ }));
25
+ const bashExec = import_tool_factory.processToolsFactory.create(processConfig).find((tool) => tool.id === "bash_exec");
26
+ if (bashExec === void 0) {
27
+ throw new Error("Expected bash_exec tool to be registered.");
28
+ }
29
+ const result = await bashExec.execute(
30
+ {
31
+ command: "git status",
32
+ cwd: "src",
33
+ run_in_background: false,
34
+ timeout: 5e3
35
+ },
36
+ createToolContext({
37
+ workspaceManager: {
38
+ open
39
+ }
40
+ })
41
+ );
42
+ (0, import_vitest.expect)(open).toHaveBeenCalledWith({ intent: "process" });
43
+ (0, import_vitest.expect)(exec).toHaveBeenCalledWith({
44
+ command: "git status",
45
+ cwd: "/workspace/src",
46
+ timeout: 5e3
47
+ });
48
+ (0, import_vitest.expect)(result).toMatchObject({
49
+ exit_code: 7,
50
+ stderr: "not clean",
51
+ stdout: "changed files"
52
+ });
53
+ });
54
+ (0, import_vitest.it)("keeps the existing process service path when no workspace is active", async () => {
55
+ const processService = new FakeProcessCommandService();
56
+ const bashExec = import_tool_factory.processToolsFactory.create(processConfig).find((tool) => tool.id === "bash_exec");
57
+ if (bashExec === void 0) {
58
+ throw new Error("Expected bash_exec tool to be registered.");
59
+ }
60
+ const result = await bashExec.execute(
61
+ {
62
+ command: "pwd",
63
+ run_in_background: false,
64
+ timeout: 5e3
65
+ },
66
+ createToolContext({
67
+ processService,
68
+ workspaceManager: {
69
+ open: async () => {
70
+ throw import_workspace.WorkspaceError.currentWorkspaceRequired();
71
+ }
72
+ }
73
+ })
74
+ );
75
+ (0, import_vitest.expect)(processService.commands).toEqual([
76
+ {
77
+ command: "pwd",
78
+ options: {
79
+ abortSignal: void 0,
80
+ cwd: void 0,
81
+ description: void 0,
82
+ runInBackground: false,
83
+ timeout: 5e3
84
+ }
85
+ }
86
+ ]);
87
+ (0, import_vitest.expect)(result).toMatchObject({
88
+ exit_code: 0,
89
+ stderr: "",
90
+ stdout: "/local\n"
91
+ });
92
+ });
93
+ });
94
+ function createToolContext(services) {
95
+ return {
96
+ logger: createLogger(),
97
+ services
98
+ };
99
+ }
100
+ function createLogger() {
101
+ return {
102
+ createChild: () => createLogger(),
103
+ debug: () => {
104
+ },
105
+ error: () => {
106
+ },
107
+ info: () => {
108
+ },
109
+ warn: () => {
110
+ }
111
+ };
112
+ }
113
+ class FakeProcessCommandService {
114
+ commands = [];
115
+ async executeCommand(command, options) {
116
+ this.commands.push({ command, options });
117
+ return {
118
+ duration: 10,
119
+ exitCode: 0,
120
+ stderr: "",
121
+ stdout: "/local\n"
122
+ };
123
+ }
124
+ getConfig() {
125
+ return {
126
+ allowedCommands: [],
127
+ blockedCommands: [],
128
+ environment: {},
129
+ maxConcurrentProcesses: 5,
130
+ maxOutputBuffer: 1024,
131
+ maxTimeout: 6e5,
132
+ securityLevel: "moderate",
133
+ workingDirectory: "/local"
134
+ };
135
+ }
136
+ async getProcessOutput(_processId) {
137
+ return {
138
+ status: "completed",
139
+ stderr: "",
140
+ stdout: ""
141
+ };
142
+ }
143
+ async killProcess(_processId) {
144
+ }
145
+ setWorkingDirectory(_workingDirectory) {
146
+ }
147
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tool-factory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-factory.test.d.ts","sourceRoot":"","sources":["../src/tool-factory.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ import { WorkspaceError } from "@dexto/core/workspace";
2
+ import { describe, expect, it, vi } from "vitest";
3
+ import { processToolsFactory } from "./tool-factory.js";
4
+ import { ProcessToolsConfigSchema } from "./tool-factory-config.js";
5
+ const processConfig = ProcessToolsConfigSchema.parse({ type: "process-tools" });
6
+ describe("processToolsFactory", () => {
7
+ it("executes foreground bash commands through a workspace process handle when available", async () => {
8
+ const exec = vi.fn(async () => ({
9
+ exitCode: 7,
10
+ stderr: "not clean",
11
+ stdout: "changed files"
12
+ }));
13
+ const open = vi.fn(async () => ({
14
+ capabilities: ["files", "processes"],
15
+ context: {
16
+ createdAt: 1,
17
+ id: "workspace-1",
18
+ lastActiveAt: 1,
19
+ path: "/workspace"
20
+ },
21
+ files: {},
22
+ processes: { exec }
23
+ }));
24
+ const bashExec = processToolsFactory.create(processConfig).find((tool) => tool.id === "bash_exec");
25
+ if (bashExec === void 0) {
26
+ throw new Error("Expected bash_exec tool to be registered.");
27
+ }
28
+ const result = await bashExec.execute(
29
+ {
30
+ command: "git status",
31
+ cwd: "src",
32
+ run_in_background: false,
33
+ timeout: 5e3
34
+ },
35
+ createToolContext({
36
+ workspaceManager: {
37
+ open
38
+ }
39
+ })
40
+ );
41
+ expect(open).toHaveBeenCalledWith({ intent: "process" });
42
+ expect(exec).toHaveBeenCalledWith({
43
+ command: "git status",
44
+ cwd: "/workspace/src",
45
+ timeout: 5e3
46
+ });
47
+ expect(result).toMatchObject({
48
+ exit_code: 7,
49
+ stderr: "not clean",
50
+ stdout: "changed files"
51
+ });
52
+ });
53
+ it("keeps the existing process service path when no workspace is active", async () => {
54
+ const processService = new FakeProcessCommandService();
55
+ const bashExec = processToolsFactory.create(processConfig).find((tool) => tool.id === "bash_exec");
56
+ if (bashExec === void 0) {
57
+ throw new Error("Expected bash_exec tool to be registered.");
58
+ }
59
+ const result = await bashExec.execute(
60
+ {
61
+ command: "pwd",
62
+ run_in_background: false,
63
+ timeout: 5e3
64
+ },
65
+ createToolContext({
66
+ processService,
67
+ workspaceManager: {
68
+ open: async () => {
69
+ throw WorkspaceError.currentWorkspaceRequired();
70
+ }
71
+ }
72
+ })
73
+ );
74
+ expect(processService.commands).toEqual([
75
+ {
76
+ command: "pwd",
77
+ options: {
78
+ abortSignal: void 0,
79
+ cwd: void 0,
80
+ description: void 0,
81
+ runInBackground: false,
82
+ timeout: 5e3
83
+ }
84
+ }
85
+ ]);
86
+ expect(result).toMatchObject({
87
+ exit_code: 0,
88
+ stderr: "",
89
+ stdout: "/local\n"
90
+ });
91
+ });
92
+ });
93
+ function createToolContext(services) {
94
+ return {
95
+ logger: createLogger(),
96
+ services
97
+ };
98
+ }
99
+ function createLogger() {
100
+ return {
101
+ createChild: () => createLogger(),
102
+ debug: () => {
103
+ },
104
+ error: () => {
105
+ },
106
+ info: () => {
107
+ },
108
+ warn: () => {
109
+ }
110
+ };
111
+ }
112
+ class FakeProcessCommandService {
113
+ commands = [];
114
+ async executeCommand(command, options) {
115
+ this.commands.push({ command, options });
116
+ return {
117
+ duration: 10,
118
+ exitCode: 0,
119
+ stderr: "",
120
+ stdout: "/local\n"
121
+ };
122
+ }
123
+ getConfig() {
124
+ return {
125
+ allowedCommands: [],
126
+ blockedCommands: [],
127
+ environment: {},
128
+ maxConcurrentProcesses: 5,
129
+ maxOutputBuffer: 1024,
130
+ maxTimeout: 6e5,
131
+ securityLevel: "moderate",
132
+ workingDirectory: "/local"
133
+ };
134
+ }
135
+ async getProcessOutput(_processId) {
136
+ return {
137
+ status: "completed",
138
+ stderr: "",
139
+ stdout: ""
140
+ };
141
+ }
142
+ async killProcess(_processId) {
143
+ }
144
+ setWorkingDirectory(_workingDirectory) {
145
+ }
146
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexto/tools-process",
3
- "version": "1.7.2",
3
+ "version": "1.8.1",
4
4
  "description": "Process tools factory for Dexto agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,8 +20,8 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "zod": "^4.3.6",
23
- "@dexto/agent-config": "1.7.2",
24
- "@dexto/core": "1.7.2"
23
+ "@dexto/agent-config": "1.8.1",
24
+ "@dexto/core": "1.8.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "tsup": "^8.0.0",