Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions v3/@claude-flow/cli/__tests__/autopilot.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';

vi.mock('node:crypto', () => ({
randomUUID: vi.fn(() => 'session-test-id'),
}));

vi.mock('node:fs', () => ({
existsSync: vi.fn(() => false),
mkdirSync: vi.fn(),
writeFileSync: vi.fn(),
readFileSync: vi.fn(),
readdirSync: vi.fn(() => []),
renameSync: vi.fn(),
}));

vi.mock('../src/output.js', () => ({
output: {
writeln: vi.fn(),
printJson: vi.fn(),
success: (str: string) => str,
bold: (str: string) => str,
dim: (str: string) => str,
},
}));

import { output } from '../src/output.js';
import { autopilotCommand } from '../src/commands/autopilot.js';

describe('autopilot command', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('runs status in ESM mode without require errors', async () => {
const statusCommand = autopilotCommand.subcommands?.find(command => command.name === 'status');

const result = await statusCommand?.action?.({
args: [],
flags: {},
cwd: process.cwd(),
interactive: false,
config: {},
});

expect(result).toEqual({ success: true });
expect(output.writeln).toHaveBeenCalledWith('Autopilot: ✗ DISABLED');
expect(output.writeln).toHaveBeenCalledWith('Session: session-...');
});
});
17 changes: 5 additions & 12 deletions v3/@claude-flow/cli/src/autopilot-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
* Security: Addresses prototype pollution, NaN bypass, input validation
*/

import * as crypto from 'node:crypto';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';

// ── Constants ─────────────────────────────────────────────────

export const STATE_DIR = '.claude-flow/data';
Expand Down Expand Up @@ -113,7 +118,6 @@ export function validateTaskSources(sources: unknown): string[] {
// ── State Management ──────────────────────────────────────────

export function getDefaultState(): AutopilotState {
const crypto = require('crypto') as typeof import('crypto');
return {
sessionId: crypto.randomUUID(),
enabled: false,
Expand All @@ -128,8 +132,6 @@ export function getDefaultState(): AutopilotState {
}

export function loadState(): AutopilotState {
const fs = require('fs') as typeof import('fs');
const path = require('path') as typeof import('path');
const filePath = path.resolve(STATE_FILE);
const defaults = getDefaultState();
try {
Expand All @@ -154,8 +156,6 @@ export function loadState(): AutopilotState {
}

export function saveState(state: AutopilotState): void {
const fs = require('fs') as typeof import('fs');
const path = require('path') as typeof import('path');
const dir = path.resolve(STATE_DIR);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
// Cap history before saving
Expand All @@ -168,8 +168,6 @@ export function saveState(state: AutopilotState): void {
}

export function appendLog(entry: AutopilotLogEntry): void {
const fs = require('fs') as typeof import('fs');
const path = require('path') as typeof import('path');
const filePath = path.resolve(LOG_FILE);
const dir = path.resolve(STATE_DIR);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
Expand All @@ -190,8 +188,6 @@ export function appendLog(entry: AutopilotLogEntry): void {
}

export function loadLog(): AutopilotLogEntry[] {
const fs = require('fs') as typeof import('fs');
const path = require('path') as typeof import('path');
const filePath = path.resolve(LOG_FILE);
try {
if (fs.existsSync(filePath)) {
Expand All @@ -207,9 +203,6 @@ export function loadLog(): AutopilotLogEntry[] {
// ── Task Discovery ────────────────────────────────────────────

export function discoverTasks(sources: string[]): TaskInfo[] {
const fs = require('fs') as typeof import('fs');
const path = require('path') as typeof import('path');
const os = require('os') as typeof import('os');
const tasks: TaskInfo[] = [];

// Only process valid sources
Expand Down
4 changes: 2 additions & 2 deletions v3/@claude-flow/cli/src/commands/autopilot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* ADR-072: Autopilot Integration
*/

import * as fs from 'node:fs';
import * as path from 'node:path';
import type { Command, CommandContext, CommandResult } from '../types.js';
import { output } from '../output.js';
import {
Expand Down Expand Up @@ -212,8 +214,6 @@ const logCommand: Command = {
],
action: async (ctx: CommandContext): Promise<CommandResult> => {
if (ctx.flags?.clear) {
const fs = require('fs') as typeof import('fs');
const path = require('path') as typeof import('path');
try { fs.writeFileSync(path.resolve(LOG_FILE), '[]'); } catch { /* ignore */ }
output.writeln('Autopilot log cleared');
return { success: true };
Expand Down