mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 17:47:27 +00:00
* ♻️ refactor(cli): extract shared @lobechat/local-file-shell package Extract common file and shell operations from Desktop and CLI into a shared package to eliminate ~1500 lines of duplicated code. CLI now uses @lobechat/file-loaders for rich format support (PDF, DOCX, etc.). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * update * update commands * update version * update deps * refactor version issue * ✨ feat(local-file-shell): add cwd support, move/rename ops, improve logging - Add missing `cwd` parameter to `runCommand` (align with Desktop) - Add `moveLocalFiles` with batch support and detailed error handling - Add `renameLocalFile` with path validation and traversal prevention - Add error logging in shell runner's error/completion handlers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * support update model and provider in cli * fix desktop build * fix * 🐛 fix: pin fast-xml-parser to 5.4.2 in bun overrides Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { cleanupAllProcesses, getCommandOutput, killCommand, runCommand } from './shell';
|
|
|
|
vi.mock('../utils/logger', () => ({
|
|
log: {
|
|
debug: vi.fn(),
|
|
error: vi.fn(),
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
describe('shell tools (integration wrapper)', () => {
|
|
afterEach(() => {
|
|
cleanupAllProcesses();
|
|
});
|
|
|
|
it('should delegate runCommand to shared package', async () => {
|
|
const result = await runCommand({ command: 'echo hello' });
|
|
|
|
expect(result.success).toBe(true);
|
|
expect(result.stdout).toContain('hello');
|
|
});
|
|
|
|
it('should delegate background commands and getCommandOutput', async () => {
|
|
const bgResult = await runCommand({
|
|
command: 'echo background && sleep 0.1',
|
|
run_in_background: true,
|
|
});
|
|
|
|
expect(bgResult.success).toBe(true);
|
|
expect(bgResult.shell_id).toBeDefined();
|
|
|
|
await new Promise((r) => setTimeout(r, 200));
|
|
|
|
const output = await getCommandOutput({ shell_id: bgResult.shell_id! });
|
|
expect(output.success).toBe(true);
|
|
expect(output.stdout).toContain('background');
|
|
});
|
|
|
|
it('should delegate killCommand', async () => {
|
|
const bgResult = await runCommand({
|
|
command: 'sleep 60',
|
|
run_in_background: true,
|
|
});
|
|
|
|
const result = await killCommand({ shell_id: bgResult.shell_id! });
|
|
expect(result.success).toBe(true);
|
|
});
|
|
|
|
it('should return error for unknown shell_id', async () => {
|
|
const result = await getCommandOutput({ shell_id: 'unknown-id' });
|
|
expect(result.success).toBe(false);
|
|
expect(result.error).toContain('not found');
|
|
});
|
|
|
|
it('should cleanup all processes', async () => {
|
|
await runCommand({ command: 'sleep 60', run_in_background: true });
|
|
await runCommand({ command: 'sleep 60', run_in_background: true });
|
|
|
|
cleanupAllProcesses();
|
|
// No assertion needed — verifies no throw
|
|
});
|
|
});
|