filex-cli 0.1.0 → 0.1.2

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.
Files changed (43) hide show
  1. package/README.md +33 -25
  2. package/dist/filex.cjs +91 -0
  3. package/package.json +10 -6
  4. package/dist/bin/filex.d.ts +0 -3
  5. package/dist/bin/filex.d.ts.map +0 -1
  6. package/dist/bin/filex.js +0 -5
  7. package/dist/bin/filex.js.map +0 -1
  8. package/dist/src/actions/convertImages.d.ts +0 -16
  9. package/dist/src/actions/convertImages.d.ts.map +0 -1
  10. package/dist/src/actions/convertImages.js +0 -101
  11. package/dist/src/actions/convertImages.js.map +0 -1
  12. package/dist/src/actions/mergePdfs.d.ts +0 -12
  13. package/dist/src/actions/mergePdfs.d.ts.map +0 -1
  14. package/dist/src/actions/mergePdfs.js +0 -132
  15. package/dist/src/actions/mergePdfs.js.map +0 -1
  16. package/dist/src/actions/resizeImages.d.ts +0 -11
  17. package/dist/src/actions/resizeImages.d.ts.map +0 -1
  18. package/dist/src/actions/resizeImages.js +0 -71
  19. package/dist/src/actions/resizeImages.js.map +0 -1
  20. package/dist/src/ai/explain.d.ts +0 -15
  21. package/dist/src/ai/explain.d.ts.map +0 -1
  22. package/dist/src/ai/explain.js +0 -75
  23. package/dist/src/ai/explain.js.map +0 -1
  24. package/dist/src/ai/parseIntent.d.ts +0 -18
  25. package/dist/src/ai/parseIntent.d.ts.map +0 -1
  26. package/dist/src/ai/parseIntent.js +0 -145
  27. package/dist/src/ai/parseIntent.js.map +0 -1
  28. package/dist/src/cli.d.ts +0 -2
  29. package/dist/src/cli.d.ts.map +0 -1
  30. package/dist/src/cli.js +0 -149
  31. package/dist/src/cli.js.map +0 -1
  32. package/dist/src/confirm.d.ts +0 -17
  33. package/dist/src/confirm.d.ts.map +0 -1
  34. package/dist/src/confirm.js +0 -69
  35. package/dist/src/confirm.js.map +0 -1
  36. package/dist/src/scan.d.ts +0 -27
  37. package/dist/src/scan.d.ts.map +0 -1
  38. package/dist/src/scan.js +0 -79
  39. package/dist/src/scan.js.map +0 -1
  40. package/dist/src/schema.d.ts +0 -224
  41. package/dist/src/schema.d.ts.map +0 -1
  42. package/dist/src/schema.js +0 -52
  43. package/dist/src/schema.js.map +0 -1
package/package.json CHANGED
@@ -1,20 +1,21 @@
1
1
  {
2
2
  "name": "filex-cli",
3
- "version": "0.1.0",
4
- "description": "A Terminal CLI agent to modify and talk with your files",
3
+ "version": "0.1.2",
4
+ "description": "A CLI agent to modify and interact with your files",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
7
7
  "bin": {
8
- "filex": "./dist/bin/filex.js"
8
+ "filex": "dist/filex.cjs"
9
9
  },
10
10
  "files": [
11
- "dist",
11
+ "dist/filex.cjs",
12
12
  "README.md"
13
13
  ],
14
14
  "scripts": {
15
- "build": "tsc",
15
+ "build": "esbuild bin/filex.ts --bundle --platform=node --format=cjs --minify --outfile=dist/filex.cjs --external:sharp --define:__VERSION__=\\\"$(node -p \"require('./package.json').version\")\\\"",
16
16
  "dev": "tsx bin/filex.ts",
17
- "start": "node dist/bin/filex.js"
17
+ "start": "node dist/filex.cjs",
18
+ "prepare": "husky"
18
19
  },
19
20
  "keywords": [
20
21
  "cli",
@@ -40,6 +41,9 @@
40
41
  },
41
42
  "devDependencies": {
42
43
  "@types/node": "^22.10.5",
44
+ "@vercel/node": "^4.0.0",
45
+ "esbuild": "^0.27.2",
46
+ "husky": "^9.1.7",
43
47
  "tsx": "^4.19.2",
44
48
  "typescript": "^5.7.3"
45
49
  }
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- import 'dotenv/config';
3
- //# sourceMappingURL=filex.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"filex.d.ts","sourceRoot":"","sources":["../../bin/filex.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC"}
package/dist/bin/filex.js DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- import 'dotenv/config';
3
- import { runCli } from '../src/cli.js';
4
- runCli();
5
- //# sourceMappingURL=filex.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"filex.js","sourceRoot":"","sources":["../../bin/filex.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,MAAM,EAAE,CAAC"}
@@ -1,16 +0,0 @@
1
- export declare const INPUT_FORMATS: readonly ["png", "jpg", "jpeg", "webp", "gif", "tiff", "avif"];
2
- export declare const OUTPUT_FORMATS: readonly ["webp", "png", "jpg"];
3
- export type InputFormat = typeof INPUT_FORMATS[number];
4
- export type OutputFormat = typeof OUTPUT_FORMATS[number];
5
- export interface ConvertImagesOptions {
6
- from?: InputFormat | InputFormat[];
7
- to?: OutputFormat;
8
- quality?: number;
9
- maxWidth?: number;
10
- }
11
- /**
12
- * Convert images in a directory from one format to another.
13
- * Originals are preserved. Output files are written alongside originals.
14
- */
15
- export declare function convertImages(dirPath: string, options?: ConvertImagesOptions): Promise<void>;
16
- //# sourceMappingURL=convertImages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertImages.d.ts","sourceRoot":"","sources":["../../../src/actions/convertImages.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,aAAa,gEAAiE,CAAC;AAC5F,eAAO,MAAM,cAAc,iCAAkC,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AACvD,MAAM,MAAM,YAAY,GAAG,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACjC,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC;IACnC,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,oBAAyB,GACnC,OAAO,CAAC,IAAI,CAAC,CA0Gf"}
@@ -1,101 +0,0 @@
1
- import * as path from 'node:path';
2
- import sharp from 'sharp';
3
- import ora from 'ora';
4
- import chalk from 'chalk';
5
- import { scanDirectory } from '../scan.js';
6
- import { confirmAction } from '../confirm.js';
7
- // Supported formats
8
- export const INPUT_FORMATS = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'tiff', 'avif'];
9
- export const OUTPUT_FORMATS = ['webp', 'png', 'jpg'];
10
- /**
11
- * Convert images in a directory from one format to another.
12
- * Originals are preserved. Output files are written alongside originals.
13
- */
14
- export async function convertImages(dirPath, options = {}) {
15
- const { from, to = 'webp', quality = 80, maxWidth } = options;
16
- // Determine which extensions to scan for
17
- const inputExtensions = from
18
- ? (Array.isArray(from) ? from : [from])
19
- : [...INPUT_FORMATS];
20
- // Filter out the target format from input (no point converting webp to webp)
21
- const filteredExtensions = inputExtensions.filter(ext => {
22
- // jpg and jpeg are the same
23
- if (to === 'jpg' && (ext === 'jpg' || ext === 'jpeg'))
24
- return false;
25
- return ext !== to;
26
- });
27
- if (filteredExtensions.length === 0) {
28
- console.log(chalk.yellow('No valid source formats to convert.'));
29
- return;
30
- }
31
- // Scan for images with specified extensions
32
- const scanResult = await scanDirectory(dirPath, filteredExtensions);
33
- if (scanResult.count === 0) {
34
- const extList = filteredExtensions.map(e => e.toUpperCase()).join(', ');
35
- console.log(chalk.yellow(`No ${extList} images found in directory.`));
36
- return;
37
- }
38
- // Build action descriptions
39
- const fromLabel = from
40
- ? (Array.isArray(from) ? from.join(', ') : from).toUpperCase()
41
- : 'all supported formats';
42
- const actions = [
43
- `Convert ${fromLabel} → ${to.toUpperCase()}`,
44
- ];
45
- if (maxWidth) {
46
- actions.push(`Resize to max width ${maxWidth}px`);
47
- }
48
- actions.push(`Quality: ${quality}%`);
49
- // Confirm with user
50
- const confirmed = await confirmAction({
51
- fileCount: scanResult.count,
52
- fileType: `${fromLabel} images`,
53
- actions,
54
- preserveOriginals: true,
55
- });
56
- if (!confirmed) {
57
- return;
58
- }
59
- // Process images
60
- const spinner = ora('Converting images...').start();
61
- let successCount = 0;
62
- let errorCount = 0;
63
- for (const filePath of scanResult.files) {
64
- try {
65
- const dir = path.dirname(filePath);
66
- const basename = path.basename(filePath, path.extname(filePath));
67
- const outputExt = to === 'jpg' ? 'jpg' : to;
68
- const outputPath = path.join(dir, `${basename}.${outputExt}`);
69
- let pipeline = sharp(filePath);
70
- if (maxWidth) {
71
- pipeline = pipeline.resize({ width: maxWidth, withoutEnlargement: true });
72
- }
73
- // Convert to target format
74
- switch (to) {
75
- case 'webp':
76
- await pipeline.webp({ quality }).toFile(outputPath);
77
- break;
78
- case 'png':
79
- await pipeline.png({ quality }).toFile(outputPath);
80
- break;
81
- case 'jpg':
82
- await pipeline.jpeg({ quality }).toFile(outputPath);
83
- break;
84
- }
85
- successCount++;
86
- spinner.text = `Converting images... (${successCount}/${scanResult.count})`;
87
- }
88
- catch (error) {
89
- errorCount++;
90
- spinner.warn(`Failed to convert: ${path.basename(filePath)}`);
91
- spinner.start();
92
- }
93
- }
94
- spinner.stop();
95
- console.log();
96
- console.log(chalk.green(`✓ Converted ${successCount} images to ${to.toUpperCase()}`));
97
- if (errorCount > 0) {
98
- console.log(chalk.red(`✗ Failed to convert ${errorCount} images`));
99
- }
100
- }
101
- //# sourceMappingURL=convertImages.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertImages.js","sourceRoot":"","sources":["../../../src/actions/convertImages.ts"],"names":[],"mappings":"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"}
@@ -1,12 +0,0 @@
1
- export declare const SORT_ORDERS: readonly ["name", "name-desc", "date", "date-desc", "random"];
2
- export type SortOrder = typeof SORT_ORDERS[number];
3
- export interface MergePdfsOptions {
4
- outputFile?: string;
5
- order?: SortOrder;
6
- }
7
- /**
8
- * Merge all PDFs in a directory into a single output file.
9
- * Originals are preserved.
10
- */
11
- export declare function mergePdfs(dirPath: string, options?: MergePdfsOptions): Promise<void>;
12
- //# sourceMappingURL=mergePdfs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mergePdfs.d.ts","sourceRoot":"","sources":["../../../src/actions/mergePdfs.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,WAAW,+DAAgE,CAAC;AACzF,MAAM,MAAM,SAAS,GAAG,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;CACrB;AAwED;;;GAGG;AACH,wBAAsB,SAAS,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,gBAAqB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAyEf"}
@@ -1,132 +0,0 @@
1
- import * as fs from 'node:fs/promises';
2
- import * as path from 'node:path';
3
- import { PDFDocument } from 'pdf-lib';
4
- import ora from 'ora';
5
- import chalk from 'chalk';
6
- import { scanForPdfs } from '../scan.js';
7
- import { confirmAction } from '../confirm.js';
8
- export const SORT_ORDERS = ['name', 'name-desc', 'date', 'date-desc', 'random'];
9
- /**
10
- * Get file modification time.
11
- */
12
- async function getFileMtime(filePath) {
13
- const stat = await fs.stat(filePath);
14
- return stat.mtimeMs;
15
- }
16
- /**
17
- * Sort files according to the specified order.
18
- */
19
- async function sortFiles(files, order) {
20
- const sorted = [...files];
21
- switch (order) {
22
- case 'name':
23
- // Already sorted alphabetically by scan.ts
24
- return sorted;
25
- case 'name-desc':
26
- return sorted.reverse();
27
- case 'date': {
28
- const withTimes = await Promise.all(sorted.map(async (f) => ({ path: f, mtime: await getFileMtime(f) })));
29
- withTimes.sort((a, b) => a.mtime - b.mtime);
30
- return withTimes.map((f) => f.path);
31
- }
32
- case 'date-desc': {
33
- const withTimes = await Promise.all(sorted.map(async (f) => ({ path: f, mtime: await getFileMtime(f) })));
34
- withTimes.sort((a, b) => b.mtime - a.mtime);
35
- return withTimes.map((f) => f.path);
36
- }
37
- case 'random':
38
- for (let i = sorted.length - 1; i > 0; i--) {
39
- const j = Math.floor(Math.random() * (i + 1));
40
- [sorted[i], sorted[j]] = [sorted[j], sorted[i]];
41
- }
42
- return sorted;
43
- default:
44
- return sorted;
45
- }
46
- }
47
- /**
48
- * Get human-readable order description.
49
- */
50
- function getOrderDescription(order) {
51
- switch (order) {
52
- case 'name':
53
- return 'alphabetical (A→Z)';
54
- case 'name-desc':
55
- return 'reverse alphabetical (Z→A)';
56
- case 'date':
57
- return 'oldest first';
58
- case 'date-desc':
59
- return 'newest first';
60
- case 'random':
61
- return 'random';
62
- default:
63
- return 'alphabetical';
64
- }
65
- }
66
- /**
67
- * Merge all PDFs in a directory into a single output file.
68
- * Originals are preserved.
69
- */
70
- export async function mergePdfs(dirPath, options = {}) {
71
- const { outputFile = 'merged.pdf', order = 'name' } = options;
72
- // Scan for PDFs
73
- const scanResult = await scanForPdfs(dirPath);
74
- if (scanResult.count === 0) {
75
- console.log(chalk.yellow('No PDF files found in directory.'));
76
- return;
77
- }
78
- if (scanResult.count === 1) {
79
- console.log(chalk.yellow('Only one PDF found. Nothing to merge.'));
80
- return;
81
- }
82
- // Sort files according to order
83
- const sortedFiles = await sortFiles(scanResult.files, order);
84
- const outputPath = path.join(scanResult.directory, outputFile);
85
- const orderDesc = getOrderDescription(order);
86
- // Build action descriptions
87
- const actions = [
88
- `Merge ${scanResult.count} PDFs (${orderDesc})`,
89
- `Output: ${outputFile}`,
90
- ];
91
- // Confirm with user
92
- const confirmed = await confirmAction({
93
- fileCount: scanResult.count,
94
- fileType: 'PDF files',
95
- actions,
96
- preserveOriginals: true,
97
- });
98
- if (!confirmed) {
99
- return;
100
- }
101
- // Merge PDFs
102
- const spinner = ora('Merging PDFs...').start();
103
- try {
104
- const mergedPdf = await PDFDocument.create();
105
- for (let i = 0; i < sortedFiles.length; i++) {
106
- const filePath = sortedFiles[i];
107
- spinner.text = `Merging PDFs... (${i + 1}/${scanResult.count})`;
108
- try {
109
- const pdfBytes = await fs.readFile(filePath);
110
- const pdf = await PDFDocument.load(pdfBytes);
111
- const pages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
112
- for (const page of pages) {
113
- mergedPdf.addPage(page);
114
- }
115
- }
116
- catch (error) {
117
- spinner.warn(`Failed to read: ${path.basename(filePath)}`);
118
- spinner.start();
119
- }
120
- }
121
- const outputBytes = await mergedPdf.save();
122
- await fs.writeFile(outputPath, outputBytes);
123
- spinner.stop();
124
- console.log();
125
- console.log(chalk.green(`✓ Created ${outputFile} with ${mergedPdf.getPageCount()} pages`));
126
- }
127
- catch (error) {
128
- spinner.stop();
129
- console.log(chalk.red(`✗ Failed to merge PDFs: ${error.message}`));
130
- }
131
- }
132
- //# sourceMappingURL=mergePdfs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mergePdfs.js","sourceRoot":"","sources":["../../../src/actions/mergePdfs.ts"],"names":[],"mappings":"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"}
@@ -1,11 +0,0 @@
1
- export interface ResizeImagesOptions {
2
- maxWidth: number;
3
- quality?: number;
4
- }
5
- /**
6
- * Resize images in a directory to a maximum width.
7
- * Aspect ratio is preserved. Originals are preserved.
8
- * Output files are written with _resized suffix.
9
- */
10
- export declare function resizeImages(dirPath: string, options: ResizeImagesOptions): Promise<void>;
11
- //# sourceMappingURL=resizeImages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resizeImages.d.ts","sourceRoot":"","sources":["../../../src/actions/resizeImages.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAsEf"}
@@ -1,71 +0,0 @@
1
- import * as path from 'node:path';
2
- import sharp from 'sharp';
3
- import ora from 'ora';
4
- import chalk from 'chalk';
5
- import { scanForImages } from '../scan.js';
6
- import { confirmAction } from '../confirm.js';
7
- /**
8
- * Resize images in a directory to a maximum width.
9
- * Aspect ratio is preserved. Originals are preserved.
10
- * Output files are written with _resized suffix.
11
- */
12
- export async function resizeImages(dirPath, options) {
13
- const { maxWidth, quality = 80 } = options;
14
- // Scan for images
15
- const scanResult = await scanForImages(dirPath);
16
- if (scanResult.count === 0) {
17
- console.log(chalk.yellow('No images found in directory.'));
18
- return;
19
- }
20
- // Build action descriptions
21
- const actions = [
22
- `Resize to max width ${maxWidth}px`,
23
- 'Preserve aspect ratio',
24
- ];
25
- // Confirm with user
26
- const confirmed = await confirmAction({
27
- fileCount: scanResult.count,
28
- fileType: 'images',
29
- actions,
30
- preserveOriginals: true,
31
- });
32
- if (!confirmed) {
33
- return;
34
- }
35
- // Process images
36
- const spinner = ora('Resizing images...').start();
37
- let successCount = 0;
38
- let errorCount = 0;
39
- for (const filePath of scanResult.files) {
40
- try {
41
- const dir = path.dirname(filePath);
42
- const ext = path.extname(filePath);
43
- const basename = path.basename(filePath, ext);
44
- const outputPath = path.join(dir, `${basename}_resized${ext}`);
45
- const metadata = await sharp(filePath).metadata();
46
- // Skip if already smaller than maxWidth
47
- if (metadata.width && metadata.width <= maxWidth) {
48
- spinner.text = `Skipping ${path.basename(filePath)} (already ${metadata.width}px wide)`;
49
- successCount++;
50
- continue;
51
- }
52
- await sharp(filePath)
53
- .resize({ width: maxWidth, withoutEnlargement: true })
54
- .toFile(outputPath);
55
- successCount++;
56
- spinner.text = `Resizing images... (${successCount}/${scanResult.count})`;
57
- }
58
- catch (error) {
59
- errorCount++;
60
- spinner.warn(`Failed to resize: ${path.basename(filePath)}`);
61
- spinner.start();
62
- }
63
- }
64
- spinner.stop();
65
- console.log();
66
- console.log(chalk.green(`✓ Resized ${successCount} images successfully`));
67
- if (errorCount > 0) {
68
- console.log(chalk.red(`✗ Failed to resize ${errorCount} images`));
69
- }
70
- }
71
- //# sourceMappingURL=resizeImages.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resizeImages.js","sourceRoot":"","sources":["../../../src/actions/resizeImages.ts"],"names":[],"mappings":"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"}
@@ -1,15 +0,0 @@
1
- import type { Action } from '../schema.js';
2
- /**
3
- * Get action name for display.
4
- */
5
- export declare function getActionName(action: Action): string;
6
- /**
7
- * Generate a human-friendly explanation from an Action.
8
- * This is a pure function - no API calls needed.
9
- */
10
- export declare function explainAction(action: Action): string[];
11
- /**
12
- * Format explanation as a styled string for console output.
13
- */
14
- export declare function formatExplanation(action: Action): string;
15
- //# sourceMappingURL=explain.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/ai/explain.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAkDtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKxD"}
@@ -1,75 +0,0 @@
1
- import chalk from 'chalk';
2
- /**
3
- * Get action name for display.
4
- */
5
- export function getActionName(action) {
6
- switch (action.action) {
7
- case 'convert_images':
8
- return 'Image Conversion';
9
- case 'resize_images':
10
- return 'Image Resize';
11
- case 'merge_pdfs':
12
- return 'PDF Merge';
13
- default:
14
- return 'Unknown';
15
- }
16
- }
17
- /**
18
- * Generate a human-friendly explanation from an Action.
19
- * This is a pure function - no API calls needed.
20
- */
21
- export function explainAction(action) {
22
- switch (action.action) {
23
- case 'convert_images': {
24
- const lines = [];
25
- const from = action.options?.from;
26
- const to = action.options?.to ?? action.options?.format ?? 'webp';
27
- if (from) {
28
- lines.push(`Convert: ${from.toUpperCase()} → ${to.toUpperCase()}`);
29
- }
30
- else {
31
- lines.push(`Convert to: ${to.toUpperCase()}`);
32
- }
33
- if (action.options?.maxWidth) {
34
- lines.push(`Max width: ${action.options.maxWidth}px`);
35
- }
36
- if (action.options?.quality) {
37
- lines.push(`Quality: ${action.options.quality}%`);
38
- }
39
- return lines;
40
- }
41
- case 'resize_images': {
42
- return [
43
- `Max width: ${action.options.maxWidth}px`,
44
- 'Aspect ratio preserved',
45
- ];
46
- }
47
- case 'merge_pdfs': {
48
- const outputFile = action.options?.outputFile ?? 'merged.pdf';
49
- const order = action.options?.order ?? 'name';
50
- const orderLabels = {
51
- 'name': 'Alphabetical (A→Z)',
52
- 'name-desc': 'Reverse (Z→A)',
53
- 'date': 'Oldest first',
54
- 'date-desc': 'Newest first',
55
- 'random': 'Random',
56
- };
57
- return [
58
- `Order: ${orderLabels[order] ?? 'Alphabetical'}`,
59
- `Output: ${outputFile}`,
60
- ];
61
- }
62
- default:
63
- return ['Unknown action'];
64
- }
65
- }
66
- /**
67
- * Format explanation as a styled string for console output.
68
- */
69
- export function formatExplanation(action) {
70
- const name = getActionName(action);
71
- const lines = explainAction(action);
72
- const formatted = lines.map(line => ` ${chalk.gray('›')} ${chalk.white(line)}`).join('\n');
73
- return `${chalk.cyan.bold(`▸ ${name}`)}\n${formatted}`;
74
- }
75
- //# sourceMappingURL=explain.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"explain.js","sourceRoot":"","sources":["../../../src/ai/explain.ts"],"names":[],"mappings":"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"}
@@ -1,18 +0,0 @@
1
- import { type Action } from '../schema.js';
2
- export type ParseIntentResult = {
3
- success: true;
4
- action: Action;
5
- } | {
6
- success: false;
7
- error: string;
8
- };
9
- /**
10
- * Parse natural language input into a structured Action using Gemini AI.
11
- * Returns a validated Action or an error message.
12
- */
13
- export declare function parseIntent(input: string): Promise<ParseIntentResult>;
14
- /**
15
- * Display a helpful message when AI parsing fails.
16
- */
17
- export declare function showAiFailureMessage(error: string): void;
18
- //# sourceMappingURL=parseIntent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"parseIntent.d.ts","sourceRoot":"","sources":["../../../src/ai/parseIntent.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AA+B5D,MAAM,MAAM,iBAAiB,GACvB;IACE,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,GACC;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwG3E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAiBxD"}