@amirdaraee/namewise 0.3.0
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.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +82 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +61 -0
- package/.github/workflows/auto-release.yml +78 -0
- package/.github/workflows/ci.yml +78 -0
- package/.github/workflows/publish.yml +43 -0
- package/.github/workflows/test.yml +37 -0
- package/CHANGELOG.md +128 -0
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/cli/commands.d.ts +3 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +19 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/rename.d.ts +2 -0
- package/dist/cli/rename.d.ts.map +1 -0
- package/dist/cli/rename.js +136 -0
- package/dist/cli/rename.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/excel-parser.d.ts +6 -0
- package/dist/parsers/excel-parser.d.ts.map +1 -0
- package/dist/parsers/excel-parser.js +42 -0
- package/dist/parsers/excel-parser.js.map +1 -0
- package/dist/parsers/factory.d.ts +7 -0
- package/dist/parsers/factory.d.ts.map +1 -0
- package/dist/parsers/factory.js +29 -0
- package/dist/parsers/factory.js.map +1 -0
- package/dist/parsers/pdf-parser.d.ts +7 -0
- package/dist/parsers/pdf-parser.d.ts.map +1 -0
- package/dist/parsers/pdf-parser.js +67 -0
- package/dist/parsers/pdf-parser.js.map +1 -0
- package/dist/parsers/text-parser.d.ts +6 -0
- package/dist/parsers/text-parser.d.ts.map +1 -0
- package/dist/parsers/text-parser.js +39 -0
- package/dist/parsers/text-parser.js.map +1 -0
- package/dist/parsers/word-parser.d.ts +6 -0
- package/dist/parsers/word-parser.d.ts.map +1 -0
- package/dist/parsers/word-parser.js +44 -0
- package/dist/parsers/word-parser.js.map +1 -0
- package/dist/services/ai-factory.d.ts +5 -0
- package/dist/services/ai-factory.d.ts.map +1 -0
- package/dist/services/ai-factory.js +15 -0
- package/dist/services/ai-factory.js.map +1 -0
- package/dist/services/claude-service.d.ts +9 -0
- package/dist/services/claude-service.d.ts.map +1 -0
- package/dist/services/claude-service.js +113 -0
- package/dist/services/claude-service.js.map +1 -0
- package/dist/services/file-renamer.d.ts +12 -0
- package/dist/services/file-renamer.d.ts.map +1 -0
- package/dist/services/file-renamer.js +99 -0
- package/dist/services/file-renamer.js.map +1 -0
- package/dist/services/openai-service.d.ts +9 -0
- package/dist/services/openai-service.d.ts.map +1 -0
- package/dist/services/openai-service.js +112 -0
- package/dist/services/openai-service.js.map +1 -0
- package/dist/types/index.d.ts +61 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/file-templates.d.ts +18 -0
- package/dist/utils/file-templates.d.ts.map +1 -0
- package/dist/utils/file-templates.js +232 -0
- package/dist/utils/file-templates.js.map +1 -0
- package/dist/utils/naming-conventions.d.ts +4 -0
- package/dist/utils/naming-conventions.d.ts.map +1 -0
- package/dist/utils/naming-conventions.js +55 -0
- package/dist/utils/naming-conventions.js.map +1 -0
- package/package.json +75 -0
- package/src/cli/commands.ts +20 -0
- package/src/cli/rename.ts +157 -0
- package/src/index.ts +17 -0
- package/src/parsers/excel-parser.ts +49 -0
- package/src/parsers/factory.ts +34 -0
- package/src/parsers/pdf-parser.ts +78 -0
- package/src/parsers/text-parser.ts +43 -0
- package/src/parsers/word-parser.ts +50 -0
- package/src/services/ai-factory.ts +16 -0
- package/src/services/claude-service.ts +114 -0
- package/src/services/file-renamer.ts +123 -0
- package/src/services/openai-service.ts +113 -0
- package/src/types/index.ts +71 -0
- package/src/types/pdf-extraction.d.ts +7 -0
- package/src/utils/file-templates.ts +275 -0
- package/src/utils/naming-conventions.ts +67 -0
- package/tests/data/empty-file.txt +0 -0
- package/tests/data/sample-markdown.md +9 -0
- package/tests/data/sample-pdf.pdf +0 -0
- package/tests/data/sample-text.txt +25 -0
- package/tests/integration/end-to-end.test.ts +209 -0
- package/tests/integration/workflow.test.ts +336 -0
- package/tests/mocks/mock-ai-service.ts +58 -0
- package/tests/unit/cli/commands.test.ts +163 -0
- package/tests/unit/parsers/factory.test.ts +100 -0
- package/tests/unit/parsers/pdf-parser.test.ts +63 -0
- package/tests/unit/parsers/text-parser.test.ts +85 -0
- package/tests/unit/services/ai-factory.test.ts +37 -0
- package/tests/unit/services/claude-service.test.ts +188 -0
- package/tests/unit/services/file-renamer.test.ts +299 -0
- package/tests/unit/services/openai-service.test.ts +196 -0
- package/tests/unit/utils/file-templates.test.ts +199 -0
- package/tests/unit/utils/naming-conventions.test.ts +88 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +30 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-parser.js","sourceRoot":"","sources":["../../src/parsers/pdf-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,OAAO,SAAS;IACpB,QAAQ,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,CAAC;YACH,qDAAqD;YACrD,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC;YAEtC,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAE3C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAExC,oCAAoC;YACpC,MAAM,QAAQ,GAAqB,EAAE,CAAC;YAEtC,sEAAsE;YACtE,MAAM,OAAO,GAAG,IAAW,CAAC;YAE5B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACtB,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;oBACzC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;oBAC3C,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;oBAC7C,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;oBAE7C,2BAA2B;oBAC3B,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;wBACnC,QAAQ,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBACzE,CAAC;oBACD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;wBAC9B,QAAQ,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACxE,CAAC;gBACH,CAAC;gBAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACrB,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC;gBACpC,CAAC;YACH,CAAC;YAED,wCAAwC;YACxC,IAAI,OAAO,EAAE,CAAC;gBACZ,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YACnF,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAC3G,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,OAAe;QAC/B,IAAI,CAAC;YACH,sEAAsE;YACtE,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB;gBACxD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB;gBACrE,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;gBACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;gBACvD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;gBAEvD,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAC1D,CAAC;YACD,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/text-parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAElF,qBAAa,UAAW,YAAW,cAAc;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAK7B,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAgCpD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export class TextParser {
|
|
4
|
+
supports(filePath) {
|
|
5
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
6
|
+
return ext === '.txt' || ext === '.md' || ext === '.rtf';
|
|
7
|
+
}
|
|
8
|
+
async parse(filePath) {
|
|
9
|
+
try {
|
|
10
|
+
const content = fs.readFileSync(filePath, 'utf-8').trim();
|
|
11
|
+
const metadata = {};
|
|
12
|
+
// Extract basic metadata from content
|
|
13
|
+
const lines = content.split('\n').filter(line => line.trim());
|
|
14
|
+
if (lines.length > 0) {
|
|
15
|
+
// For markdown files, look for title in first heading
|
|
16
|
+
if (path.extname(filePath).toLowerCase() === '.md') {
|
|
17
|
+
const firstLine = lines[0];
|
|
18
|
+
if (firstLine.startsWith('# ')) {
|
|
19
|
+
metadata.title = firstLine.substring(2).trim();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// For other text files, use first non-empty line as potential title
|
|
24
|
+
const firstNonEmptyLine = lines[0];
|
|
25
|
+
if (firstNonEmptyLine.length < 100 && !firstNonEmptyLine.endsWith('.')) {
|
|
26
|
+
metadata.title = firstNonEmptyLine.trim();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Word count
|
|
30
|
+
metadata.wordCount = content.split(/\s+/).filter(word => word.length > 0).length;
|
|
31
|
+
}
|
|
32
|
+
return { content, metadata };
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw new Error(`Failed to parse text file: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=text-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-parser.js","sourceRoot":"","sources":["../../src/parsers/text-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,OAAO,UAAU;IACrB,QAAQ,CAAC,QAAgB;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QACjD,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1D,MAAM,QAAQ,GAAqB,EAAE,CAAC;YAEtC,sCAAsC;YACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAE9D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,sDAAsD;gBACtD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;oBACnD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC3B,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC/B,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBACjD,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,oEAAoE;oBACpE,MAAM,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBACnC,IAAI,iBAAiB,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBACvE,QAAQ,CAAC,KAAK,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC;oBAC5C,CAAC;gBACH,CAAC;gBAED,aAAa;gBACb,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YACnF,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"word-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/word-parser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAElF,qBAAa,UAAW,YAAW,cAAc;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAK7B,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAsCpD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import mammoth from 'mammoth';
|
|
4
|
+
export class WordParser {
|
|
5
|
+
supports(filePath) {
|
|
6
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
7
|
+
return ext === '.docx' || ext === '.doc';
|
|
8
|
+
}
|
|
9
|
+
async parse(filePath) {
|
|
10
|
+
try {
|
|
11
|
+
const buffer = fs.readFileSync(filePath);
|
|
12
|
+
// Extract text content
|
|
13
|
+
const textResult = await mammoth.extractRawText({ buffer });
|
|
14
|
+
const content = textResult.value.trim();
|
|
15
|
+
// Extract metadata
|
|
16
|
+
const metadata = {};
|
|
17
|
+
// Estimate word count
|
|
18
|
+
if (content) {
|
|
19
|
+
metadata.wordCount = content.split(/\s+/).filter(word => word.length > 0).length;
|
|
20
|
+
}
|
|
21
|
+
// Try to extract document properties for .docx files
|
|
22
|
+
if (path.extname(filePath).toLowerCase() === '.docx') {
|
|
23
|
+
try {
|
|
24
|
+
// For DOCX files, we could parse document.xml for metadata
|
|
25
|
+
// For now, we'll use basic analysis of the content
|
|
26
|
+
const lines = content.split('\n');
|
|
27
|
+
const firstNonEmptyLine = lines.find(line => line.trim().length > 0);
|
|
28
|
+
// If the first line looks like a title (short and not a sentence)
|
|
29
|
+
if (firstNonEmptyLine && firstNonEmptyLine.length < 100 && !firstNonEmptyLine.endsWith('.')) {
|
|
30
|
+
metadata.title = firstNonEmptyLine.trim();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Ignore metadata extraction errors
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { content, metadata };
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw new Error(`Failed to parse Word document: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=word-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"word-parser.js","sourceRoot":"","sources":["../../src/parsers/word-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,MAAM,OAAO,UAAU;IACrB,QAAQ,CAAC,QAAgB;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QACjD,OAAO,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,MAAM,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEzC,uBAAuB;YACvB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAExC,mBAAmB;YACnB,MAAM,QAAQ,GAAqB,EAAE,CAAC;YAEtC,sBAAsB;YACtB,IAAI,OAAO,EAAE,CAAC;gBACZ,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YACnF,CAAC;YAED,qDAAqD;YACrD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;gBACrD,IAAI,CAAC;oBACH,2DAA2D;oBAC3D,mDAAmD;oBACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAClC,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBAErE,kEAAkE;oBAClE,IAAI,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC5F,QAAQ,CAAC,KAAK,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC;oBAC5C,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,oCAAoC;gBACtC,CAAC;YACH,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAChH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-factory.d.ts","sourceRoot":"","sources":["../../src/services/ai-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI/C,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU;CAUzE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ClaudeService } from './claude-service.js';
|
|
2
|
+
import { OpenAIService } from './openai-service.js';
|
|
3
|
+
export class AIServiceFactory {
|
|
4
|
+
static create(provider, apiKey) {
|
|
5
|
+
switch (provider) {
|
|
6
|
+
case 'claude':
|
|
7
|
+
return new ClaudeService(apiKey);
|
|
8
|
+
case 'openai':
|
|
9
|
+
return new OpenAIService(apiKey);
|
|
10
|
+
default:
|
|
11
|
+
throw new Error(`Unsupported AI provider: ${provider}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=ai-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-factory.js","sourceRoot":"","sources":["../../src/services/ai-factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAC,MAAM,CAAC,QAA6B,EAAE,MAAc;QACzD,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;YACnC,KAAK,QAAQ;gBACX,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;YACnC;gBACE,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AIProvider, FileInfo } from '../types/index.js';
|
|
2
|
+
export declare class ClaudeService implements AIProvider {
|
|
3
|
+
name: string;
|
|
4
|
+
private client;
|
|
5
|
+
constructor(apiKey: string);
|
|
6
|
+
generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo): Promise<string>;
|
|
7
|
+
private sanitizeFileName;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=claude-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-service.d.ts","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIzD,qBAAa,aAAc,YAAW,UAAU;IAC9C,IAAI,SAAY;IAChB,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,MAAM;IAMpB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,GAAE,MAAqB,EAAE,QAAQ,GAAE,MAAkB,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IA2E1K,OAAO,CAAC,gBAAgB;CAuBzB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import { applyNamingConvention, getNamingInstructions } from '../utils/naming-conventions.js';
|
|
3
|
+
import { getTemplateInstructions } from '../utils/file-templates.js';
|
|
4
|
+
export class ClaudeService {
|
|
5
|
+
name = 'Claude';
|
|
6
|
+
client;
|
|
7
|
+
constructor(apiKey) {
|
|
8
|
+
this.client = new Anthropic({
|
|
9
|
+
apiKey: apiKey
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo) {
|
|
13
|
+
const convention = namingConvention;
|
|
14
|
+
const fileCategory = category;
|
|
15
|
+
const namingInstructions = getNamingInstructions(convention);
|
|
16
|
+
const templateInstructions = getTemplateInstructions(fileCategory);
|
|
17
|
+
// Build comprehensive context from all metadata
|
|
18
|
+
let metadataContext = '';
|
|
19
|
+
if (fileInfo) {
|
|
20
|
+
metadataContext += `File Information:
|
|
21
|
+
- Original filename: ${originalName}
|
|
22
|
+
- File size: ${Math.round(fileInfo.size / 1024)}KB
|
|
23
|
+
- Created: ${fileInfo.createdAt.toLocaleDateString()}
|
|
24
|
+
- Modified: ${fileInfo.modifiedAt.toLocaleDateString()}
|
|
25
|
+
- Parent folder: ${fileInfo.parentFolder}
|
|
26
|
+
- Folder path: ${fileInfo.folderPath.join(' > ')}`;
|
|
27
|
+
if (fileInfo.documentMetadata) {
|
|
28
|
+
const meta = fileInfo.documentMetadata;
|
|
29
|
+
metadataContext += `
|
|
30
|
+
Document Properties:`;
|
|
31
|
+
if (meta.title)
|
|
32
|
+
metadataContext += `\n- Title: ${meta.title}`;
|
|
33
|
+
if (meta.author)
|
|
34
|
+
metadataContext += `\n- Author: ${meta.author}`;
|
|
35
|
+
if (meta.creator)
|
|
36
|
+
metadataContext += `\n- Creator: ${meta.creator}`;
|
|
37
|
+
if (meta.subject)
|
|
38
|
+
metadataContext += `\n- Subject: ${meta.subject}`;
|
|
39
|
+
if (meta.keywords?.length)
|
|
40
|
+
metadataContext += `\n- Keywords: ${meta.keywords.join(', ')}`;
|
|
41
|
+
if (meta.creationDate)
|
|
42
|
+
metadataContext += `\n- Created: ${meta.creationDate.toLocaleDateString()}`;
|
|
43
|
+
if (meta.modificationDate)
|
|
44
|
+
metadataContext += `\n- Modified: ${meta.modificationDate.toLocaleDateString()}`;
|
|
45
|
+
if (meta.pages)
|
|
46
|
+
metadataContext += `\n- Pages: ${meta.pages}`;
|
|
47
|
+
if (meta.wordCount)
|
|
48
|
+
metadataContext += `\n- Word count: ${meta.wordCount}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const prompt = `Based on the following document information, generate a descriptive filename that captures the main topic/purpose of the document. The filename should be:
|
|
52
|
+
- Descriptive and meaningful
|
|
53
|
+
- Professional and clean
|
|
54
|
+
- Between 3-8 words
|
|
55
|
+
- ${namingInstructions}
|
|
56
|
+
- ${templateInstructions}
|
|
57
|
+
- Do not include file extension
|
|
58
|
+
- Do not include personal names, dates, or template variables - just the core content description
|
|
59
|
+
- Only use letters, numbers, and appropriate separators for the naming convention
|
|
60
|
+
- Use all available context (metadata, folder context, document properties) to create the most accurate filename
|
|
61
|
+
|
|
62
|
+
${metadataContext}
|
|
63
|
+
|
|
64
|
+
Document content (first 2000 characters):
|
|
65
|
+
${content.substring(0, 2000)}
|
|
66
|
+
|
|
67
|
+
Respond with only the core filename (without personal info or dates) using the specified naming convention, no explanation.`;
|
|
68
|
+
try {
|
|
69
|
+
const response = await this.client.messages.create({
|
|
70
|
+
model: 'claude-3-haiku-20240307',
|
|
71
|
+
max_tokens: 100,
|
|
72
|
+
messages: [
|
|
73
|
+
{
|
|
74
|
+
role: 'user',
|
|
75
|
+
content: prompt
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
});
|
|
79
|
+
const suggestedName = response.content[0].type === 'text'
|
|
80
|
+
? response.content[0].text.trim()
|
|
81
|
+
: 'untitled-document';
|
|
82
|
+
// Apply naming convention and clean the suggested name
|
|
83
|
+
return this.sanitizeFileName(suggestedName, convention);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('Claude API error:', error);
|
|
87
|
+
throw new Error(`Failed to generate filename with Claude: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
sanitizeFileName(name, convention) {
|
|
91
|
+
// Remove any potential file extensions from the suggestion
|
|
92
|
+
const nameWithoutExt = name.replace(/\.[^/.]+$/, '');
|
|
93
|
+
// Apply the naming convention
|
|
94
|
+
let cleaned = applyNamingConvention(nameWithoutExt, convention);
|
|
95
|
+
// Ensure it's not empty and not too long
|
|
96
|
+
if (!cleaned) {
|
|
97
|
+
cleaned = applyNamingConvention('untitled document', convention);
|
|
98
|
+
}
|
|
99
|
+
else if (cleaned.length > 100) {
|
|
100
|
+
// Truncate while preserving naming convention structure
|
|
101
|
+
cleaned = cleaned.substring(0, 100);
|
|
102
|
+
// Clean up any broken separators at the end
|
|
103
|
+
if (convention === 'kebab-case') {
|
|
104
|
+
cleaned = cleaned.replace(/-[^-]*$/, '');
|
|
105
|
+
}
|
|
106
|
+
else if (convention === 'snake_case') {
|
|
107
|
+
cleaned = cleaned.replace(/_[^_]*$/, '');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return cleaned;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=claude-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-service.js","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FileInfo, Config, RenameResult, AIProvider } from '../types/index.js';
|
|
2
|
+
import { DocumentParserFactory } from '../parsers/factory.js';
|
|
3
|
+
export declare class FileRenamer {
|
|
4
|
+
private parserFactory;
|
|
5
|
+
private aiService;
|
|
6
|
+
private config;
|
|
7
|
+
constructor(parserFactory: DocumentParserFactory, aiService: AIProvider, config: Config);
|
|
8
|
+
renameFiles(files: FileInfo[]): Promise<RenameResult[]>;
|
|
9
|
+
private renameFile;
|
|
10
|
+
private checkForConflicts;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=file-renamer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-renamer.d.ts","sourceRoot":"","sources":["../../src/services/file-renamer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,qBAAa,WAAW;IAEpB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;gBAFN,aAAa,EAAE,qBAAqB,EACpC,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,MAAM;IAGlB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;YA4B/C,UAAU;YAqEV,iBAAiB;CAYhC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { categorizeFile, applyTemplate } from '../utils/file-templates.js';
|
|
4
|
+
export class FileRenamer {
|
|
5
|
+
parserFactory;
|
|
6
|
+
aiService;
|
|
7
|
+
config;
|
|
8
|
+
constructor(parserFactory, aiService, config) {
|
|
9
|
+
this.parserFactory = parserFactory;
|
|
10
|
+
this.aiService = aiService;
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
async renameFiles(files) {
|
|
14
|
+
const results = [];
|
|
15
|
+
for (let i = 0; i < files.length; i++) {
|
|
16
|
+
const file = files[i];
|
|
17
|
+
// Use \r to overwrite the same line, show progress counter
|
|
18
|
+
process.stdout.write(`\rProcessing: ${file.name}... (${i + 1}/${files.length})`);
|
|
19
|
+
try {
|
|
20
|
+
const result = await this.renameFile(file);
|
|
21
|
+
results.push(result);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
results.push({
|
|
25
|
+
originalPath: file.path,
|
|
26
|
+
newPath: file.path,
|
|
27
|
+
suggestedName: file.name,
|
|
28
|
+
success: false,
|
|
29
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Clear the processing line and move to next line
|
|
34
|
+
process.stdout.write('\r' + ' '.repeat(80) + '\r');
|
|
35
|
+
return results;
|
|
36
|
+
}
|
|
37
|
+
async renameFile(file) {
|
|
38
|
+
// Check file size
|
|
39
|
+
if (file.size > this.config.maxFileSize) {
|
|
40
|
+
throw new Error(`File size (${Math.round(file.size / 1024 / 1024)}MB) exceeds maximum allowed size (${Math.round(this.config.maxFileSize / 1024 / 1024)}MB)`);
|
|
41
|
+
}
|
|
42
|
+
// Get appropriate parser
|
|
43
|
+
const parser = this.parserFactory.getParser(file.path);
|
|
44
|
+
if (!parser) {
|
|
45
|
+
throw new Error(`No parser available for file type: ${file.extension}`);
|
|
46
|
+
}
|
|
47
|
+
// Extract content and metadata
|
|
48
|
+
const parseResult = await parser.parse(file.path);
|
|
49
|
+
const content = parseResult.content;
|
|
50
|
+
if (!content || content.trim().length === 0) {
|
|
51
|
+
throw new Error('No content could be extracted from the file');
|
|
52
|
+
}
|
|
53
|
+
// Update file info with extracted document metadata
|
|
54
|
+
file.documentMetadata = parseResult.metadata;
|
|
55
|
+
// Determine file category (use configured category or auto-categorize)
|
|
56
|
+
const fileCategory = this.config.templateOptions.category === 'auto'
|
|
57
|
+
? categorizeFile(file.path, content, file)
|
|
58
|
+
: this.config.templateOptions.category;
|
|
59
|
+
// Generate core filename using AI with all available metadata
|
|
60
|
+
const coreFileName = await this.aiService.generateFileName(content, file.name, this.config.namingConvention, fileCategory, file // Pass the entire file info with all metadata
|
|
61
|
+
);
|
|
62
|
+
if (!coreFileName || coreFileName.trim().length === 0) {
|
|
63
|
+
throw new Error('AI service failed to generate a filename');
|
|
64
|
+
}
|
|
65
|
+
// Apply template to include personal info, dates, etc.
|
|
66
|
+
const templatedName = applyTemplate(coreFileName, fileCategory, this.config.templateOptions, this.config.namingConvention);
|
|
67
|
+
// Create new filename with original extension
|
|
68
|
+
const newFileName = `${templatedName}${file.extension}`;
|
|
69
|
+
const newPath = path.join(path.dirname(file.path), newFileName);
|
|
70
|
+
// Check if new filename would conflict with existing file
|
|
71
|
+
if (newPath !== file.path) {
|
|
72
|
+
await this.checkForConflicts(newPath);
|
|
73
|
+
}
|
|
74
|
+
// Perform the rename (or simulate if dry run)
|
|
75
|
+
if (!this.config.dryRun && newPath !== file.path) {
|
|
76
|
+
await fs.rename(file.path, newPath);
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
originalPath: file.path,
|
|
80
|
+
newPath,
|
|
81
|
+
suggestedName: newFileName,
|
|
82
|
+
success: true
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async checkForConflicts(newPath) {
|
|
86
|
+
try {
|
|
87
|
+
await fs.access(newPath);
|
|
88
|
+
// If we reach here, the file exists
|
|
89
|
+
throw new Error(`Target filename already exists: ${path.basename(newPath)}`);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
// If the error is ENOENT (file doesn't exist), that's what we want
|
|
93
|
+
if (error.code !== 'ENOENT') {
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=file-renamer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-renamer.js","sourceRoot":"","sources":["../../src/services/file-renamer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AIProvider, FileInfo } from '../types/index.js';
|
|
2
|
+
export declare class OpenAIService implements AIProvider {
|
|
3
|
+
name: string;
|
|
4
|
+
private client;
|
|
5
|
+
constructor(apiKey: string);
|
|
6
|
+
generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo): Promise<string>;
|
|
7
|
+
private sanitizeFileName;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=openai-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-service.d.ts","sourceRoot":"","sources":["../../src/services/openai-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIzD,qBAAa,aAAc,YAAW,UAAU;IAC9C,IAAI,SAAY;IAChB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAMpB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,GAAE,MAAqB,EAAE,QAAQ,GAAE,MAAkB,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IA0E1K,OAAO,CAAC,gBAAgB;CAuBzB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { applyNamingConvention, getNamingInstructions } from '../utils/naming-conventions.js';
|
|
3
|
+
import { getTemplateInstructions } from '../utils/file-templates.js';
|
|
4
|
+
export class OpenAIService {
|
|
5
|
+
name = 'OpenAI';
|
|
6
|
+
client;
|
|
7
|
+
constructor(apiKey) {
|
|
8
|
+
this.client = new OpenAI({
|
|
9
|
+
apiKey: apiKey
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo) {
|
|
13
|
+
const convention = namingConvention;
|
|
14
|
+
const fileCategory = category;
|
|
15
|
+
const namingInstructions = getNamingInstructions(convention);
|
|
16
|
+
const templateInstructions = getTemplateInstructions(fileCategory);
|
|
17
|
+
// Build comprehensive context from all metadata
|
|
18
|
+
let metadataContext = '';
|
|
19
|
+
if (fileInfo) {
|
|
20
|
+
metadataContext += `File Information:
|
|
21
|
+
- Original filename: ${originalName}
|
|
22
|
+
- File size: ${Math.round(fileInfo.size / 1024)}KB
|
|
23
|
+
- Created: ${fileInfo.createdAt.toLocaleDateString()}
|
|
24
|
+
- Modified: ${fileInfo.modifiedAt.toLocaleDateString()}
|
|
25
|
+
- Parent folder: ${fileInfo.parentFolder}
|
|
26
|
+
- Folder path: ${fileInfo.folderPath.join(' > ')}`;
|
|
27
|
+
if (fileInfo.documentMetadata) {
|
|
28
|
+
const meta = fileInfo.documentMetadata;
|
|
29
|
+
metadataContext += `
|
|
30
|
+
Document Properties:`;
|
|
31
|
+
if (meta.title)
|
|
32
|
+
metadataContext += `\n- Title: ${meta.title}`;
|
|
33
|
+
if (meta.author)
|
|
34
|
+
metadataContext += `\n- Author: ${meta.author}`;
|
|
35
|
+
if (meta.creator)
|
|
36
|
+
metadataContext += `\n- Creator: ${meta.creator}`;
|
|
37
|
+
if (meta.subject)
|
|
38
|
+
metadataContext += `\n- Subject: ${meta.subject}`;
|
|
39
|
+
if (meta.keywords?.length)
|
|
40
|
+
metadataContext += `\n- Keywords: ${meta.keywords.join(', ')}`;
|
|
41
|
+
if (meta.creationDate)
|
|
42
|
+
metadataContext += `\n- Created: ${meta.creationDate.toLocaleDateString()}`;
|
|
43
|
+
if (meta.modificationDate)
|
|
44
|
+
metadataContext += `\n- Modified: ${meta.modificationDate.toLocaleDateString()}`;
|
|
45
|
+
if (meta.pages)
|
|
46
|
+
metadataContext += `\n- Pages: ${meta.pages}`;
|
|
47
|
+
if (meta.wordCount)
|
|
48
|
+
metadataContext += `\n- Word count: ${meta.wordCount}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const prompt = `Based on the following document information, generate a descriptive filename that captures the main topic/purpose of the document. The filename should be:
|
|
52
|
+
- Descriptive and meaningful
|
|
53
|
+
- Professional and clean
|
|
54
|
+
- Between 3-8 words
|
|
55
|
+
- ${namingInstructions}
|
|
56
|
+
- ${templateInstructions}
|
|
57
|
+
- Do not include file extension
|
|
58
|
+
- Do not include personal names, dates, or template variables - just the core content description
|
|
59
|
+
- Only use letters, numbers, and appropriate separators for the naming convention
|
|
60
|
+
- Use all available context (metadata, folder context, document properties) to create the most accurate filename
|
|
61
|
+
|
|
62
|
+
${metadataContext}
|
|
63
|
+
|
|
64
|
+
Document content (first 2000 characters):
|
|
65
|
+
${content.substring(0, 2000)}
|
|
66
|
+
|
|
67
|
+
Respond with only the core filename (without personal info or dates) using the specified naming convention, no explanation.`;
|
|
68
|
+
try {
|
|
69
|
+
const response = await this.client.chat.completions.create({
|
|
70
|
+
model: 'gpt-3.5-turbo',
|
|
71
|
+
messages: [
|
|
72
|
+
{
|
|
73
|
+
role: 'user',
|
|
74
|
+
content: prompt
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
max_tokens: 100,
|
|
78
|
+
temperature: 0.3
|
|
79
|
+
});
|
|
80
|
+
const suggestedName = response.choices[0]?.message?.content?.trim() || 'untitled-document';
|
|
81
|
+
// Clean and validate the suggested name
|
|
82
|
+
return this.sanitizeFileName(suggestedName, convention);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error('OpenAI API error:', error);
|
|
86
|
+
throw new Error(`Failed to generate filename with OpenAI: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
sanitizeFileName(name, convention) {
|
|
90
|
+
// Remove any potential file extensions from the suggestion
|
|
91
|
+
const nameWithoutExt = name.replace(/\.[^/.]+$/, '');
|
|
92
|
+
// Apply the naming convention
|
|
93
|
+
let cleaned = applyNamingConvention(nameWithoutExt, convention);
|
|
94
|
+
// Ensure it's not empty and not too long
|
|
95
|
+
if (!cleaned) {
|
|
96
|
+
cleaned = applyNamingConvention('untitled document', convention);
|
|
97
|
+
}
|
|
98
|
+
else if (cleaned.length > 100) {
|
|
99
|
+
// Truncate while preserving naming convention structure
|
|
100
|
+
cleaned = cleaned.substring(0, 100);
|
|
101
|
+
// Clean up any broken separators at the end
|
|
102
|
+
if (convention === 'kebab-case') {
|
|
103
|
+
cleaned = cleaned.replace(/-[^-]*$/, '');
|
|
104
|
+
}
|
|
105
|
+
else if (convention === 'snake_case') {
|
|
106
|
+
cleaned = cleaned.replace(/_[^_]*$/, '');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return cleaned;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=openai-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-service.js","sourceRoot":"","sources":["../../src/services/openai-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface DocumentMetadata {
|
|
2
|
+
title?: string;
|
|
3
|
+
author?: string;
|
|
4
|
+
creator?: string;
|
|
5
|
+
subject?: string;
|
|
6
|
+
keywords?: string[];
|
|
7
|
+
creationDate?: Date;
|
|
8
|
+
modificationDate?: Date;
|
|
9
|
+
pages?: number;
|
|
10
|
+
wordCount?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface FileInfo {
|
|
13
|
+
path: string;
|
|
14
|
+
name: string;
|
|
15
|
+
extension: string;
|
|
16
|
+
size: number;
|
|
17
|
+
content?: string;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
modifiedAt: Date;
|
|
20
|
+
accessedAt: Date;
|
|
21
|
+
parentFolder: string;
|
|
22
|
+
folderPath: string[];
|
|
23
|
+
documentMetadata?: DocumentMetadata;
|
|
24
|
+
}
|
|
25
|
+
export interface RenameResult {
|
|
26
|
+
originalPath: string;
|
|
27
|
+
newPath: string;
|
|
28
|
+
suggestedName: string;
|
|
29
|
+
success: boolean;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface AIProvider {
|
|
33
|
+
name: string;
|
|
34
|
+
generateFileName: (content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo) => Promise<string>;
|
|
35
|
+
}
|
|
36
|
+
export type NamingConvention = 'kebab-case' | 'snake_case' | 'camelCase' | 'PascalCase' | 'lowercase' | 'UPPERCASE';
|
|
37
|
+
export type FileCategory = 'document' | 'movie' | 'music' | 'series' | 'photo' | 'book' | 'general' | 'auto';
|
|
38
|
+
export type DateFormat = 'YYYY-MM-DD' | 'YYYY' | 'YYYYMMDD' | 'none';
|
|
39
|
+
export interface TemplateOptions {
|
|
40
|
+
category: FileCategory;
|
|
41
|
+
personalName?: string;
|
|
42
|
+
dateFormat: DateFormat;
|
|
43
|
+
}
|
|
44
|
+
export interface Config {
|
|
45
|
+
aiProvider: 'claude' | 'openai';
|
|
46
|
+
apiKey: string;
|
|
47
|
+
maxFileSize: number;
|
|
48
|
+
supportedExtensions: string[];
|
|
49
|
+
dryRun: boolean;
|
|
50
|
+
namingConvention: NamingConvention;
|
|
51
|
+
templateOptions: TemplateOptions;
|
|
52
|
+
}
|
|
53
|
+
export interface ParseResult {
|
|
54
|
+
content: string;
|
|
55
|
+
metadata?: DocumentMetadata;
|
|
56
|
+
}
|
|
57
|
+
export interface DocumentParser {
|
|
58
|
+
supports: (filePath: string) => boolean;
|
|
59
|
+
parse: (filePath: string) => Promise<ParseResult>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;IAEjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IAErB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACjJ;AAED,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;AACpH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAC7G,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,eAAe,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|