@fastino-ai/pioneer-cli 0.2.10 → 0.2.11

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.
@@ -1,104 +0,0 @@
1
- import { describe, test, expect } from "bun:test";
2
- import type { Tool, ToolParameter, ToolResult } from "../tools/types";
3
-
4
- describe("Tool Types", () => {
5
- describe("ToolParameter", () => {
6
- test("should have valid structure", () => {
7
- const param: ToolParameter = {
8
- name: "filePath",
9
- type: "string",
10
- description: "Path to the file",
11
- required: true,
12
- default: "./default.txt",
13
- };
14
-
15
- expect(param.name).toBe("filePath");
16
- expect(param.type).toBe("string");
17
- expect(param.description).toBeDefined();
18
- expect(param.required).toBe(true);
19
- expect(param.default).toBe("./default.txt");
20
- });
21
-
22
- test("should support all parameter types", () => {
23
- const types: Array<ToolParameter["type"]> = [
24
- "string",
25
- "number",
26
- "boolean",
27
- "array",
28
- "object",
29
- ];
30
-
31
- types.forEach((type) => {
32
- const param: ToolParameter = {
33
- name: "testParam",
34
- type,
35
- description: `Test ${type} parameter`,
36
- required: false,
37
- };
38
-
39
- expect(param.type).toBe(type);
40
- });
41
- });
42
- });
43
-
44
- describe("ToolResult", () => {
45
- test("should support successful result", () => {
46
- const result: ToolResult = {
47
- toolCallId: "call-123",
48
- output: "Operation completed successfully",
49
- success: true,
50
- };
51
-
52
- expect(result.success).toBe(true);
53
- expect(result.output).toBeDefined();
54
- expect(result.toolCallId).toBe("call-123");
55
- expect(result.error).toBeUndefined();
56
- });
57
-
58
- test("should support error result", () => {
59
- const result: ToolResult = {
60
- toolCallId: "call-456",
61
- output: "",
62
- success: false,
63
- error: "File not found",
64
- };
65
-
66
- expect(result.success).toBe(false);
67
- expect(result.error).toBe("File not found");
68
- });
69
- });
70
-
71
- describe("Tool", () => {
72
- test("should have valid structure", async () => {
73
- const tool: Tool = {
74
- name: "test_tool",
75
- description: "A test tool",
76
- parameters: [
77
- {
78
- name: "input",
79
- type: "string",
80
- description: "Input value",
81
- required: true,
82
- },
83
- ],
84
- execute: async (args: Record<string, unknown>) => {
85
- return {
86
- toolCallId: "test-id",
87
- output: `Executed with: ${args.input}`,
88
- success: true,
89
- };
90
- },
91
- };
92
-
93
- expect(tool.name).toBe("test_tool");
94
- expect(tool.description).toBeDefined();
95
- expect(tool.parameters.length).toBe(1);
96
- expect(typeof tool.execute).toBe("function");
97
-
98
- // Test execution
99
- const result = await tool.execute({ input: "test value" });
100
- expect(result.success).toBe(true);
101
- expect(result.output).toContain("test value");
102
- });
103
- });
104
- });
@@ -1,90 +0,0 @@
1
- import { describe, test, expect, beforeEach } from "bun:test";
2
- import { FileResolver } from "../utils/FileResolver";
3
- import * as path from "path";
4
- import * as os from "os";
5
-
6
- describe("FileResolver", () => {
7
- let resolver: FileResolver;
8
-
9
- beforeEach(() => {
10
- resolver = new FileResolver(process.cwd());
11
- });
12
-
13
- describe("Constructor and setup", () => {
14
- test("should initialize with default cwd", () => {
15
- const defaultResolver = new FileResolver();
16
- expect(defaultResolver).toBeDefined();
17
- });
18
-
19
- test("should initialize with custom base path", () => {
20
- const customPath = "/custom/path";
21
- const customResolver = new FileResolver(customPath);
22
- expect(customResolver).toBeDefined();
23
- });
24
-
25
- test("should allow setting base path", () => {
26
- const newPath = "/new/path";
27
- resolver.setBasePath(newPath);
28
- expect(resolver).toBeDefined();
29
- });
30
- });
31
-
32
- describe("Reference parsing", () => {
33
- test("should parse simple file reference", () => {
34
- const message = "Check @package.json for details";
35
- const result = resolver.resolve(message);
36
-
37
- expect(result.originalMessage).toBe(message);
38
- expect(result.references.length).toBeGreaterThanOrEqual(1);
39
- expect(result.references[0].relativePath).toBe("package.json");
40
- });
41
-
42
- test("should parse multiple file references", () => {
43
- const message = "Check @package.json and @tsconfig.json";
44
- const result = resolver.resolve(message);
45
-
46
- expect(result.references.length).toBeGreaterThanOrEqual(2);
47
- });
48
-
49
- test("should handle relative path references", () => {
50
- const message = "Check @./src/config.ts";
51
- const result = resolver.resolve(message);
52
-
53
- expect(result.references.length).toBeGreaterThanOrEqual(1);
54
- expect(result.references[0].relativePath).toBe("./src/config.ts");
55
- });
56
-
57
- test("should deduplicate same reference mentioned multiple times", () => {
58
- const message = "@package.json is important. Check @package.json again.";
59
- const result = resolver.resolve(message);
60
-
61
- expect(result.references.length).toBe(1);
62
- });
63
- });
64
-
65
- describe("getSuggestions", () => {
66
- test("should return suggestions for empty string", () => {
67
- const suggestions = resolver.getSuggestions("");
68
- expect(Array.isArray(suggestions)).toBe(true);
69
- });
70
-
71
- test("should return suggestions for partial filename", () => {
72
- const suggestions = resolver.getSuggestions("pa");
73
- expect(Array.isArray(suggestions)).toBe(true);
74
- // Should include package.json if it exists
75
- const hasPackageJson = suggestions.some(s => s.includes("package.json"));
76
- expect(hasPackageJson).toBe(true);
77
- });
78
-
79
- test("should limit suggestions to specified count", () => {
80
- const limit = 5;
81
- const suggestions = resolver.getSuggestions("", limit);
82
- expect(suggestions.length).toBeLessThanOrEqual(limit);
83
- });
84
-
85
- test("should handle directory paths with trailing slash", () => {
86
- const suggestions = resolver.getSuggestions("src/");
87
- expect(Array.isArray(suggestions)).toBe(true);
88
- });
89
- });
90
- });
package/src/tools/bash.ts DELETED
@@ -1,184 +0,0 @@
1
- /**
2
- * Bash execution tool - Execute shell commands safely
3
- */
4
-
5
- import { spawn } from "child_process";
6
- import type { Tool, ToolResult, ToolParameter } from "./types.js";
7
-
8
- export interface BashOptions {
9
- cwd?: string;
10
- timeout?: number;
11
- env?: Record<string, string>;
12
- maxOutput?: number;
13
- }
14
-
15
- export function createBashTool(options: BashOptions = {}): Tool {
16
- const { cwd = process.cwd(), timeout = 60000, maxOutput = 100000 } = options;
17
-
18
- return {
19
- name: "bash",
20
- description: "Execute a bash command. Use this to run shell commands, install packages, manage files, etc.",
21
- parameters: [
22
- {
23
- name: "command",
24
- type: "string",
25
- description: "The bash command to execute",
26
- required: true,
27
- },
28
- {
29
- name: "workdir",
30
- type: "string",
31
- description: "Working directory for the command (optional, defaults to current directory)",
32
- required: false,
33
- },
34
- ],
35
-
36
- async execute(args: Record<string, unknown>): Promise<ToolResult> {
37
- const command = args.command as string;
38
- const workdir = (args.workdir as string) || cwd;
39
-
40
- if (!command || typeof command !== "string") {
41
- return {
42
- toolCallId: "",
43
- output: "",
44
- success: false,
45
- error: "Command is required and must be a string",
46
- };
47
- }
48
-
49
- return new Promise((resolve) => {
50
- let stdout = "";
51
- let stderr = "";
52
- let timedOut = false;
53
-
54
- const proc = spawn("bash", ["-c", command], {
55
- cwd: workdir,
56
- env: { ...process.env, ...options.env },
57
- stdio: ["pipe", "pipe", "pipe"],
58
- });
59
-
60
- const timer = setTimeout(() => {
61
- timedOut = true;
62
- proc.kill("SIGTERM");
63
- setTimeout(() => proc.kill("SIGKILL"), 5000);
64
- }, timeout);
65
-
66
- proc.stdout.on("data", (data: Buffer) => {
67
- const chunk = data.toString();
68
- if (stdout.length + chunk.length <= maxOutput) {
69
- stdout += chunk;
70
- } else if (stdout.length < maxOutput) {
71
- stdout += chunk.slice(0, maxOutput - stdout.length);
72
- stdout += "\n... (output truncated)";
73
- }
74
- });
75
-
76
- proc.stderr.on("data", (data: Buffer) => {
77
- const chunk = data.toString();
78
- if (stderr.length + chunk.length <= maxOutput) {
79
- stderr += chunk;
80
- } else if (stderr.length < maxOutput) {
81
- stderr += chunk.slice(0, maxOutput - stderr.length);
82
- stderr += "\n... (output truncated)";
83
- }
84
- });
85
-
86
- proc.on("close", (code) => {
87
- clearTimeout(timer);
88
-
89
- let output = "";
90
- if (stdout) output += stdout;
91
- if (stderr) output += (output ? "\n" : "") + stderr;
92
- if (timedOut) output += `\n(Command timed out after ${timeout / 1000}s)`;
93
-
94
- resolve({
95
- toolCallId: "",
96
- output: output || "(no output)",
97
- success: !timedOut && code === 0,
98
- error: timedOut
99
- ? `Command timed out after ${timeout / 1000}s`
100
- : code !== 0
101
- ? `Command exited with code ${code}`
102
- : undefined,
103
- });
104
- });
105
-
106
- proc.on("error", (err) => {
107
- clearTimeout(timer);
108
- resolve({
109
- toolCallId: "",
110
- output: "",
111
- success: false,
112
- error: `Failed to execute command: ${err.message}`,
113
- });
114
- });
115
- });
116
- },
117
- };
118
- }
119
-
120
- // Streaming version for real-time output
121
- export async function* executeBashStream(
122
- command: string,
123
- options: BashOptions = {}
124
- ): AsyncGenerator<{ type: "stdout" | "stderr" | "exit"; data: string | number }> {
125
- const { cwd = process.cwd(), timeout = 60000 } = options;
126
-
127
- const proc = spawn("bash", ["-c", command], {
128
- cwd,
129
- env: { ...process.env, ...options.env },
130
- stdio: ["pipe", "pipe", "pipe"],
131
- });
132
-
133
- let timedOut = false;
134
- const timer = setTimeout(() => {
135
- timedOut = true;
136
- proc.kill("SIGTERM");
137
- setTimeout(() => proc.kill("SIGKILL"), 5000);
138
- }, timeout);
139
-
140
- const stdoutQueue: string[] = [];
141
- const stderrQueue: string[] = [];
142
- let exited = false;
143
- let exitCode: number | null = null;
144
-
145
- proc.stdout.on("data", (data: Buffer) => {
146
- stdoutQueue.push(data.toString());
147
- });
148
-
149
- proc.stderr.on("data", (data: Buffer) => {
150
- stderrQueue.push(data.toString());
151
- });
152
-
153
- const exitPromise = new Promise<number | null>((resolve) => {
154
- proc.on("close", (code) => {
155
- clearTimeout(timer);
156
- exited = true;
157
- exitCode = timedOut ? -1 : code;
158
- resolve(exitCode);
159
- });
160
-
161
- proc.on("error", () => {
162
- clearTimeout(timer);
163
- exited = true;
164
- exitCode = -1;
165
- resolve(-1);
166
- });
167
- });
168
-
169
- // Yield output as it comes
170
- while (!exited || stdoutQueue.length > 0 || stderrQueue.length > 0) {
171
- while (stdoutQueue.length > 0) {
172
- yield { type: "stdout", data: stdoutQueue.shift()! };
173
- }
174
- while (stderrQueue.length > 0) {
175
- yield { type: "stderr", data: stderrQueue.shift()! };
176
- }
177
- if (!exited) {
178
- await new Promise((resolve) => setTimeout(resolve, 10));
179
- }
180
- }
181
-
182
- yield { type: "exit", data: exitCode ?? -1 };
183
- }
184
-