@amirdaraee/namewise 0.4.0 → 0.5.1
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/workflows/build.yml +6 -0
- package/.github/workflows/publish.yml +59 -11
- package/.github/workflows/test.yml +1 -0
- package/CHANGELOG.md +102 -0
- package/RELEASE.md +15 -3
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +14 -7
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/rename.js +1 -1
- package/dist/cli/rename.js.map +1 -1
- package/dist/parsers/factory.d.ts +2 -1
- package/dist/parsers/factory.d.ts.map +1 -1
- package/dist/parsers/factory.js +9 -6
- package/dist/parsers/factory.js.map +1 -1
- package/dist/parsers/pdf-parser.d.ts +1 -0
- package/dist/parsers/pdf-parser.d.ts.map +1 -1
- package/dist/parsers/pdf-parser.js +20 -1
- package/dist/parsers/pdf-parser.js.map +1 -1
- package/dist/services/claude-service.d.ts.map +1 -1
- package/dist/services/claude-service.js +59 -65
- package/dist/services/claude-service.js.map +1 -1
- package/dist/services/lmstudio-service.d.ts.map +1 -1
- package/dist/services/lmstudio-service.js +16 -19
- package/dist/services/lmstudio-service.js.map +1 -1
- package/dist/services/ollama-service.d.ts +1 -0
- package/dist/services/ollama-service.d.ts.map +1 -1
- package/dist/services/ollama-service.js +61 -32
- package/dist/services/ollama-service.js.map +1 -1
- package/dist/services/openai-service.d.ts.map +1 -1
- package/dist/services/openai-service.js +59 -66
- package/dist/services/openai-service.js.map +1 -1
- package/dist/utils/ai-prompts.d.ts +20 -0
- package/dist/utils/ai-prompts.d.ts.map +1 -0
- package/dist/utils/ai-prompts.js +71 -0
- package/dist/utils/ai-prompts.js.map +1 -0
- package/dist/utils/pdf-to-image.d.ts +11 -0
- package/dist/utils/pdf-to-image.d.ts.map +1 -0
- package/dist/utils/pdf-to-image.js +91 -0
- package/dist/utils/pdf-to-image.js.map +1 -0
- package/eng.traineddata +0 -0
- package/package.json +5 -2
- package/src/cli/commands.ts +14 -7
- package/src/cli/rename.ts +1 -1
- package/src/parsers/factory.ts +11 -7
- package/src/parsers/pdf-parser.ts +22 -1
- package/src/services/claude-service.ts +63 -58
- package/src/services/lmstudio-service.ts +20 -20
- package/src/services/ollama-service.ts +75 -31
- package/src/services/openai-service.ts +63 -59
- package/src/utils/ai-prompts.ts +76 -0
- package/src/utils/pdf-to-image.ts +124 -0
- package/tests/integration/ai-prompting.test.ts +386 -0
- package/tests/integration/end-to-end.test.ts +9 -9
- package/tests/integration/person-name-extraction.test.ts +440 -0
- package/tests/unit/cli/commands.test.ts +9 -3
- package/tests/unit/services/lmstudio-service.test.ts +4 -4
- package/tests/unit/services/ollama-service.test.ts +4 -4
- package/tests/unit/utils/ai-prompts.test.ts +213 -0
- package/tests/unit/utils/pdf-to-image.test.ts +127 -0
|
@@ -7,9 +7,15 @@ on:
|
|
|
7
7
|
workflow_call: # Allows this workflow to be called by other workflows
|
|
8
8
|
|
|
9
9
|
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Run Tests Before Build
|
|
12
|
+
uses: ./.github/workflows/test.yml
|
|
13
|
+
|
|
10
14
|
build:
|
|
11
15
|
name: Build Project
|
|
12
16
|
runs-on: ubuntu-latest
|
|
17
|
+
needs: [test]
|
|
18
|
+
if: ${{ needs.test.result == 'success' }}
|
|
13
19
|
|
|
14
20
|
steps:
|
|
15
21
|
- name: Checkout code
|
|
@@ -2,13 +2,25 @@ name: Publish Pipeline
|
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_dispatch: # Allows manual triggering
|
|
5
|
+
inputs:
|
|
6
|
+
use_artifact:
|
|
7
|
+
description: 'Use build artifact (provide artifact name or "latest")'
|
|
8
|
+
required: false
|
|
9
|
+
default: ''
|
|
5
10
|
release:
|
|
6
11
|
types: [published]
|
|
7
12
|
|
|
8
13
|
jobs:
|
|
14
|
+
build:
|
|
15
|
+
name: Build for Publishing
|
|
16
|
+
uses: ./.github/workflows/build.yml
|
|
17
|
+
if: ${{ github.event.inputs.use_artifact == '' }}
|
|
18
|
+
|
|
9
19
|
publish:
|
|
10
20
|
name: Publish Package
|
|
11
21
|
runs-on: ubuntu-latest
|
|
22
|
+
needs: [build]
|
|
23
|
+
if: ${{ always() && (needs.build.result == 'success' || github.event.inputs.use_artifact != '') }}
|
|
12
24
|
environment: production # Requires environment approval for production
|
|
13
25
|
|
|
14
26
|
steps:
|
|
@@ -22,14 +34,30 @@ jobs:
|
|
|
22
34
|
registry-url: 'https://registry.npmjs.org'
|
|
23
35
|
cache: 'npm'
|
|
24
36
|
|
|
25
|
-
- name:
|
|
26
|
-
|
|
37
|
+
- name: Download build artifacts (from current run)
|
|
38
|
+
if: ${{ github.event.inputs.use_artifact == '' }}
|
|
39
|
+
uses: actions/download-artifact@v4
|
|
40
|
+
with:
|
|
41
|
+
name: build-artifacts-${{ github.sha }}
|
|
42
|
+
path: ./
|
|
43
|
+
|
|
44
|
+
- name: Download build artifacts (from specific run)
|
|
45
|
+
if: ${{ github.event.inputs.use_artifact != '' && github.event.inputs.use_artifact != 'latest' }}
|
|
46
|
+
uses: actions/download-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: ${{ github.event.inputs.use_artifact }}
|
|
49
|
+
path: ./
|
|
27
50
|
|
|
28
|
-
- name:
|
|
29
|
-
|
|
51
|
+
- name: Download latest build artifacts
|
|
52
|
+
if: ${{ github.event.inputs.use_artifact == 'latest' }}
|
|
53
|
+
run: |
|
|
54
|
+
echo "Downloading latest build artifacts..."
|
|
55
|
+
gh run download --name "build-artifacts-*" --limit 1
|
|
56
|
+
env:
|
|
57
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
30
58
|
|
|
31
|
-
- name:
|
|
32
|
-
run: npm
|
|
59
|
+
- name: Install dependencies (only for package.json)
|
|
60
|
+
run: npm ci --production
|
|
33
61
|
|
|
34
62
|
- name: Publish to NPM
|
|
35
63
|
run: npm publish
|
|
@@ -42,7 +70,8 @@ jobs:
|
|
|
42
70
|
publish-github:
|
|
43
71
|
name: Publish to GitHub Packages
|
|
44
72
|
runs-on: ubuntu-latest
|
|
45
|
-
needs: publish
|
|
73
|
+
needs: [build, publish]
|
|
74
|
+
if: ${{ always() && needs.publish.result == 'success' }}
|
|
46
75
|
permissions:
|
|
47
76
|
contents: read
|
|
48
77
|
packages: write
|
|
@@ -58,11 +87,30 @@ jobs:
|
|
|
58
87
|
registry-url: 'https://npm.pkg.github.com'
|
|
59
88
|
cache: 'npm'
|
|
60
89
|
|
|
61
|
-
- name:
|
|
62
|
-
|
|
90
|
+
- name: Download build artifacts (reuse from publish job)
|
|
91
|
+
if: ${{ github.event.inputs.use_artifact == '' }}
|
|
92
|
+
uses: actions/download-artifact@v4
|
|
93
|
+
with:
|
|
94
|
+
name: build-artifacts-${{ github.sha }}
|
|
95
|
+
path: ./
|
|
96
|
+
|
|
97
|
+
- name: Download build artifacts (from specific run)
|
|
98
|
+
if: ${{ github.event.inputs.use_artifact != '' && github.event.inputs.use_artifact != 'latest' }}
|
|
99
|
+
uses: actions/download-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: ${{ github.event.inputs.use_artifact }}
|
|
102
|
+
path: ./
|
|
103
|
+
|
|
104
|
+
- name: Download latest build artifacts
|
|
105
|
+
if: ${{ github.event.inputs.use_artifact == 'latest' }}
|
|
106
|
+
run: |
|
|
107
|
+
echo "Downloading latest build artifacts..."
|
|
108
|
+
gh run download --name "build-artifacts-*" --limit 1
|
|
109
|
+
env:
|
|
110
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
63
111
|
|
|
64
|
-
- name:
|
|
65
|
-
run: npm
|
|
112
|
+
- name: Install dependencies (only for package.json)
|
|
113
|
+
run: npm ci --production
|
|
66
114
|
|
|
67
115
|
- name: Configure package for GitHub Packages
|
|
68
116
|
run: |
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,108 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.0] - 2025-11-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **📄 Scanned PDF Support**: Full support for image-only (scanned) PDFs with vision AI
|
|
14
|
+
- Automatic detection of scanned PDFs (documents with minimal or no text)
|
|
15
|
+
- Converts first page to image and sends to AI for content analysis
|
|
16
|
+
- Intelligent image optimization to stay under Claude's 5MB limit
|
|
17
|
+
- Progressive JPEG compression with multiple quality levels (0.85 → 0.3)
|
|
18
|
+
- Automatic dimension scaling if needed (100% → 70% → 50%)
|
|
19
|
+
- Smart size calculation to ensure API compatibility
|
|
20
|
+
|
|
21
|
+
### Enhanced
|
|
22
|
+
- **🔄 PDF Processing**: Replaced PDF.js with pdf-to-png-converter for better Node.js compatibility
|
|
23
|
+
- Resolves canvas rendering issues in Node.js environment
|
|
24
|
+
- More reliable PDF-to-image conversion
|
|
25
|
+
- Better error handling and debugging
|
|
26
|
+
- **🤖 AI Model**: Updated to Claude Sonnet 4.5 (claude-sonnet-4-5-20250929)
|
|
27
|
+
- Latest Claude model with enhanced vision capabilities
|
|
28
|
+
- Improved accuracy for document analysis
|
|
29
|
+
- Better understanding of complex document layouts
|
|
30
|
+
|
|
31
|
+
### Technical
|
|
32
|
+
- Replaced `pdfjs-dist` with `pdf-to-png-converter` package
|
|
33
|
+
- Enhanced PDFToImageConverter with size optimization algorithms
|
|
34
|
+
- Added comprehensive test suite for PDF-to-image conversion (12 new tests)
|
|
35
|
+
- Improved error logging with detailed stack traces
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- **🐛 Critical**: Fixed "Image or Canvas expected" errors when processing scanned PDFs
|
|
39
|
+
- **🐛 Critical**: Fixed "image exceeds 5 MB maximum" errors with large scanned documents
|
|
40
|
+
- **🐛 Model**: Fixed deprecated model warnings by updating to latest Claude API
|
|
41
|
+
|
|
42
|
+
### Examples
|
|
43
|
+
```bash
|
|
44
|
+
# Process directory with scanned PDFs
|
|
45
|
+
namewise rename ./documents --dry-run
|
|
46
|
+
|
|
47
|
+
# Scanned PDFs are automatically detected and processed:
|
|
48
|
+
# Input: Iran-criminal-record-2.pdf (scanned, no text)
|
|
49
|
+
# Output: iran-criminal-record-certificate.pdf
|
|
50
|
+
#
|
|
51
|
+
# Input: Luxembourg-identity-2025.pdf (scanned, 14.7MB image)
|
|
52
|
+
# Output: luxembourg-identity-card-2025.pdf (optimized to <5MB)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## [0.4.1] - 2025-09-15
|
|
56
|
+
|
|
57
|
+
### Enhanced
|
|
58
|
+
- **🔧 Reliability Improvements**: Enhanced stability and consistency across all AI providers
|
|
59
|
+
- **📋 Documentation**: Improved examples and usage documentation
|
|
60
|
+
|
|
61
|
+
## [0.4.0] - 2025-09-15
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
- **🤖 Local LLM Provider Support**: Full integration with local AI services
|
|
65
|
+
- **Ollama**: Local LLM support with customizable models (llama3.1, codellama, etc.)
|
|
66
|
+
- **LMStudio**: Local model hosting with OpenAI-compatible API
|
|
67
|
+
- Support for custom base URLs and model selection
|
|
68
|
+
- Availability checking and model listing for local providers
|
|
69
|
+
|
|
70
|
+
### Enhanced
|
|
71
|
+
- **🎯 Intelligent Person Name Detection**: Major AI prompting improvements
|
|
72
|
+
- AI now extracts person names from document content and places them at filename beginning
|
|
73
|
+
- Smart folder name filtering to ignore irrelevant names like "no", "temp", "downloads"
|
|
74
|
+
- Enhanced prompts that focus on document content rather than metadata
|
|
75
|
+
- Support for detecting visa applications, contracts, medical records, certificates
|
|
76
|
+
|
|
77
|
+
### Architecture
|
|
78
|
+
- **📋 Centralized Prompt System**: Single source of truth for all AI prompts
|
|
79
|
+
- Model-agnostic prompting that works across Claude, OpenAI, LMStudio, and Ollama
|
|
80
|
+
- Consolidated prompt building in `/src/utils/ai-prompts.ts`
|
|
81
|
+
- Consistent behavior across all AI providers
|
|
82
|
+
- Easier maintenance and updates
|
|
83
|
+
|
|
84
|
+
### Examples
|
|
85
|
+
```bash
|
|
86
|
+
# Use local Ollama service
|
|
87
|
+
namewise rename ./documents --provider ollama --dry-run
|
|
88
|
+
|
|
89
|
+
# Use LMStudio with custom model
|
|
90
|
+
namewise rename ./files --provider lmstudio --base-url http://localhost:1234 --model codellama
|
|
91
|
+
|
|
92
|
+
# Enhanced person name detection (Sarah example)
|
|
93
|
+
# Input: visitor-visa-application-for-family-in-canada.pdf (in folder "no")
|
|
94
|
+
# Output: sarah-visitor-visa-application-for-family-members-in-canada.pdf
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Technical
|
|
98
|
+
- Enhanced CLI with new provider options and base URL configuration
|
|
99
|
+
- Added availability checking and model discovery for local providers
|
|
100
|
+
|
|
101
|
+
## [0.3.1] - 2025-09-05
|
|
102
|
+
|
|
103
|
+
### Security
|
|
104
|
+
- **🔒 Vulnerability Fix**: Replaced vulnerable `xlsx` package with secure `exceljs`
|
|
105
|
+
- Enhanced Excel file parsing with improved security and reliability
|
|
106
|
+
|
|
107
|
+
### Infrastructure
|
|
108
|
+
- **⚙️ CI/CD Improvements**: Enhanced GitHub Actions workflows
|
|
109
|
+
- Updated Node.js versions in CI pipelines
|
|
110
|
+
- Improved test workflow reliability and build process
|
|
111
|
+
|
|
10
112
|
## [0.3.0] - 2025-09-05
|
|
11
113
|
|
|
12
114
|
### Added
|
package/RELEASE.md
CHANGED
|
@@ -73,18 +73,23 @@ This triggers the `publish.yml` workflow.
|
|
|
73
73
|
Your project has three separate, independently runnable workflows:
|
|
74
74
|
|
|
75
75
|
### 1. Test Pipeline (`test.yml`)
|
|
76
|
-
- **Triggers**: Push to main/develop, PRs, manual dispatch
|
|
76
|
+
- **Triggers**: Push to main/develop, PRs, manual dispatch, called by other workflows
|
|
77
77
|
- **Purpose**: Run tests and linting across Node.js versions
|
|
78
78
|
- **Manual run**: Go to Actions → Test Pipeline → "Run workflow"
|
|
79
79
|
|
|
80
80
|
### 2. Build Pipeline (`build.yml`)
|
|
81
81
|
- **Triggers**: Push to main, manual dispatch, or called by other workflows
|
|
82
|
-
- **Purpose**:
|
|
82
|
+
- **Purpose**: Run tests first, then build the project and create artifacts
|
|
83
|
+
- **Dependencies**: Calls Test Pipeline automatically
|
|
83
84
|
- **Manual run**: Go to Actions → Build Pipeline → "Run workflow"
|
|
84
85
|
|
|
85
86
|
### 3. Publish Pipeline (`publish.yml`)
|
|
86
87
|
- **Triggers**: GitHub releases, manual dispatch
|
|
87
|
-
- **Purpose**: Publish to NPM and GitHub Packages
|
|
88
|
+
- **Purpose**: Publish to NPM and GitHub Packages using build artifacts
|
|
89
|
+
- **Features**:
|
|
90
|
+
- Uses artifacts from build pipeline (no rebuilding)
|
|
91
|
+
- Can use existing artifacts from previous builds
|
|
92
|
+
- Option to specify which artifact to use
|
|
88
93
|
- **Manual run**: Go to Actions → Publish Pipeline → "Run workflow"
|
|
89
94
|
|
|
90
95
|
### 4. Auto Release (`auto-release.yml`)
|
|
@@ -127,6 +132,13 @@ Follow [Semantic Versioning](https://semver.org/):
|
|
|
127
132
|
- Bump the version: `npm version patch`
|
|
128
133
|
- Push: `git push origin main`
|
|
129
134
|
|
|
135
|
+
### Using Existing Build Artifacts
|
|
136
|
+
|
|
137
|
+
You can publish using previously built artifacts:
|
|
138
|
+
|
|
139
|
+
1. **Use latest build**: Go to Actions → Publish Pipeline → Run workflow → Use artifact: `latest`
|
|
140
|
+
2. **Use specific build**: Find the artifact name from a previous build run → Run workflow → Use artifact: `build-artifacts-abc123def`
|
|
141
|
+
|
|
130
142
|
### Manual Publishing
|
|
131
143
|
If workflows fail, you can publish manually:
|
|
132
144
|
```bash
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4DpD"}
|
package/dist/cli/commands.js
CHANGED
|
@@ -3,7 +3,7 @@ export function setupCommands(program) {
|
|
|
3
3
|
program
|
|
4
4
|
.command('rename')
|
|
5
5
|
.description('🚀 Rename files in a directory based on their content using AI analysis')
|
|
6
|
-
.argument('
|
|
6
|
+
.argument('[directory]', 'Directory containing files to rename (default: current directory)', '.')
|
|
7
7
|
.option('-p, --provider <provider>', 'AI provider (claude|openai|ollama|lmstudio)', 'claude')
|
|
8
8
|
.option('-k, --api-key <key>', 'API key for cloud providers (or set CLAUDE_API_KEY/OPENAI_API_KEY)')
|
|
9
9
|
.option('-c, --case <convention>', 'Naming convention (kebab-case|snake_case|camelCase|PascalCase|lowercase|UPPERCASE)', 'kebab-case')
|
|
@@ -19,14 +19,16 @@ export function setupCommands(program) {
|
|
|
19
19
|
🔍 How it works:
|
|
20
20
|
1. Scans directory for supported files (PDF, DOCX, XLSX, TXT, MD, RTF)
|
|
21
21
|
2. Extracts content and metadata from each file
|
|
22
|
-
3.
|
|
23
|
-
4.
|
|
24
|
-
5.
|
|
22
|
+
3. For scanned PDFs with no text, converts to image for AI vision analysis
|
|
23
|
+
4. Uses AI to analyze content and generate descriptive names
|
|
24
|
+
5. Applies your chosen template and naming convention
|
|
25
|
+
6. Renames files (or shows preview with --dry-run)
|
|
25
26
|
|
|
26
27
|
💡 Pro Tips:
|
|
27
28
|
• Always use --dry-run first to preview changes
|
|
28
29
|
• Use 'auto' template for smart file type detection
|
|
29
30
|
• Personal templates work great for documents and photos
|
|
31
|
+
• Scanned PDFs are automatically handled via AI vision (Claude/OpenAI/Ollama)
|
|
30
32
|
• Set API keys as environment variables for cloud providers
|
|
31
33
|
• Local LLMs (Ollama/LMStudio) require running servers first
|
|
32
34
|
|
|
@@ -35,7 +37,11 @@ export function setupCommands(program) {
|
|
|
35
37
|
• LMStudio: Enable local server mode (default: http://localhost:1234)
|
|
36
38
|
|
|
37
39
|
📝 Examples:
|
|
38
|
-
#
|
|
40
|
+
# Current directory (no directory argument needed)
|
|
41
|
+
namewise rename --dry-run
|
|
42
|
+
namewise rename --provider claude --template document --name "alice"
|
|
43
|
+
|
|
44
|
+
# Specific directory
|
|
39
45
|
namewise rename ./documents --dry-run
|
|
40
46
|
|
|
41
47
|
# Cloud providers (require API keys)
|
|
@@ -43,9 +49,10 @@ export function setupCommands(program) {
|
|
|
43
49
|
namewise rename ./media --provider openai --template auto
|
|
44
50
|
|
|
45
51
|
# Local LLMs (no API key needed)
|
|
46
|
-
namewise rename
|
|
52
|
+
namewise rename --provider ollama --model llama3.1 --dry-run
|
|
53
|
+
namewise rename ./documents --provider ollama --model llama3.1
|
|
47
54
|
namewise rename ./contracts --provider lmstudio --base-url http://localhost:1234
|
|
48
|
-
|
|
55
|
+
|
|
49
56
|
# Custom Ollama setup
|
|
50
57
|
namewise rename ./files --provider ollama --base-url http://192.168.1.100:11434 --model codellama
|
|
51
58
|
`)
|
package/dist/cli/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yEAAyE,CAAC;SACtF,QAAQ,CAAC,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yEAAyE,CAAC;SACtF,QAAQ,CAAC,aAAa,EAAE,mEAAmE,EAAE,GAAG,CAAC;SACjG,MAAM,CAAC,2BAA2B,EAAE,6CAA6C,EAAE,QAAQ,CAAC;SAC5F,MAAM,CAAC,qBAAqB,EAAE,oEAAoE,CAAC;SACnG,MAAM,CAAC,yBAAyB,EAAE,oFAAoF,EAAE,YAAY,CAAC;SACrI,MAAM,CAAC,2BAA2B,EAAE,8EAA8E,EAAE,SAAS,CAAC;SAC9H,MAAM,CAAC,2BAA2B,EAAE,sEAAsE,CAAC;SAC3G,MAAM,CAAC,qBAAqB,EAAE,wDAAwD,EAAE,MAAM,CAAC;SAC/F,MAAM,CAAC,WAAW,EAAE,sEAAsE,EAAE,KAAK,CAAC;SAClG,MAAM,CAAC,mBAAmB,EAAE,oCAAoC,EAAE,IAAI,CAAC;SACvE,MAAM,CAAC,kBAAkB,EAAE,2GAA2G,CAAC;SACvI,MAAM,CAAC,gBAAgB,EAAE,qFAAqF,CAAC;SAC/G,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCzB,CAAC;SACG,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE;QACnC,MAAM,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/cli/rename.js
CHANGED
|
@@ -54,7 +54,7 @@ export async function renameFiles(directory, options) {
|
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
// Initialize services
|
|
57
|
-
const parserFactory = new DocumentParserFactory();
|
|
57
|
+
const parserFactory = new DocumentParserFactory(config);
|
|
58
58
|
const aiService = AIServiceFactory.create(config.aiProvider, apiKey, config.localLLMConfig);
|
|
59
59
|
const fileRenamer = new FileRenamer(parserFactory, aiService, config);
|
|
60
60
|
// Get files to process
|
package/dist/cli/rename.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../src/cli/rename.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB,EAAE,OAAY;IAC/D,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,qBAAqB,CAAC,CAAC;QACrD,CAAC;QAED,uCAAuC;QACvC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC5B,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEvE,IAAI,cAAc,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9B,oCAAoC;YACpC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;gBAChE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YACtC,CAAC;iBAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;gBACvE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;oBACtC;wBACE,IAAI,EAAE,UAAU;wBAChB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,cAAc,OAAO,CAAC,QAAQ,WAAW;wBAClD,IAAI,EAAE,GAAG;qBACV;iBACF,CAAC,CAAC;gBACH,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,gBAAgB;QAChB,MAAM,MAAM,GAAW;YACrB,UAAU,EAAE,OAAO,CAAC,QAAQ;YAC5B,MAAM;YACN,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,sBAAsB;YAC5E,mBAAmB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;YACvE,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,gBAAgB,EAAE,OAAO,CAAC,IAAI;YAC9B,eAAe,EAAE;gBACf,QAAQ,EAAE,OAAO,CAAC,QAAwB;gBAC1C,YAAY,EAAE,OAAO,CAAC,IAAI;gBAC1B,UAAU,EAAE,OAAO,CAAC,IAAkB;aACvC;YACD,mCAAmC;YACnC,cAAc,EAAE;gBACd,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB;SACF,CAAC;QAEF,sBAAsB;QACtB,MAAM,aAAa,GAAG,IAAI,qBAAqB,
|
|
1
|
+
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../src/cli/rename.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { DocumentParser } from '../types/index.js';
|
|
1
|
+
import { DocumentParser, Config } from '../types/index.js';
|
|
2
2
|
export declare class DocumentParserFactory {
|
|
3
3
|
private parsers;
|
|
4
|
+
constructor(config?: Config);
|
|
4
5
|
getParser(filePath: string): DocumentParser | null;
|
|
5
6
|
getSupportedExtensions(): string[];
|
|
6
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/parsers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/parsers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAM3D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,OAAO,CAAmB;gBAEtB,MAAM,CAAC,EAAE,MAAM;IAS3B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAIlD,sBAAsB,IAAI,MAAM,EAAE;CAenC"}
|
package/dist/parsers/factory.js
CHANGED
|
@@ -3,12 +3,15 @@ import { WordParser } from './word-parser.js';
|
|
|
3
3
|
import { ExcelParser } from './excel-parser.js';
|
|
4
4
|
import { TextParser } from './text-parser.js';
|
|
5
5
|
export class DocumentParserFactory {
|
|
6
|
-
parsers
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
parsers;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.parsers = [
|
|
9
|
+
new PDFParser(),
|
|
10
|
+
new WordParser(),
|
|
11
|
+
new ExcelParser(),
|
|
12
|
+
new TextParser()
|
|
13
|
+
];
|
|
14
|
+
}
|
|
12
15
|
getParser(filePath) {
|
|
13
16
|
return this.parsers.find(parser => parser.supports(filePath)) || null;
|
|
14
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/parsers/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,OAAO,qBAAqB;IACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/parsers/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,OAAO,qBAAqB;IACxB,OAAO,CAAmB;IAElC,YAAY,MAAe;QACzB,IAAI,CAAC,OAAO,GAAG;YACb,IAAI,SAAS,EAAE;YACf,IAAI,UAAU,EAAE;YAChB,IAAI,WAAW,EAAE;YACjB,IAAI,UAAU,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,QAAgB;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC;IACxE,CAAC;IAED,sBAAsB;QACpB,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAErC,uDAAuD;QACvD,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvB,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvB,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEvB,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/pdf-parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"pdf-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/pdf-parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAGlF,qBAAa,SAAU,YAAW,cAAc;;IAK9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI7B,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiEnD,OAAO,CAAC,SAAS;CAmBlB"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { PDFToImageConverter } from '../utils/pdf-to-image.js';
|
|
3
4
|
export class PDFParser {
|
|
5
|
+
constructor() {
|
|
6
|
+
// No constructor parameters needed anymore
|
|
7
|
+
}
|
|
4
8
|
supports(filePath) {
|
|
5
9
|
return path.extname(filePath).toLowerCase() === '.pdf';
|
|
6
10
|
}
|
|
@@ -11,7 +15,22 @@ export class PDFParser {
|
|
|
11
15
|
const extract = pdfExtraction.default;
|
|
12
16
|
const dataBuffer = fs.readFileSync(filePath);
|
|
13
17
|
const data = await extract(dataBuffer, {});
|
|
14
|
-
|
|
18
|
+
let content = data.text?.trim() || '';
|
|
19
|
+
// Check if this is a scanned PDF and convert to image for AI analysis
|
|
20
|
+
if (PDFToImageConverter.isScannedPDF(content)) {
|
|
21
|
+
try {
|
|
22
|
+
console.log('🔍 Detected scanned PDF, converting to image for AI analysis...');
|
|
23
|
+
const imageBase64 = await PDFToImageConverter.convertFirstPageToBase64(dataBuffer);
|
|
24
|
+
// Store the image data as a special marker for the AI service to detect
|
|
25
|
+
content = `[SCANNED_PDF_IMAGE]:${imageBase64}`;
|
|
26
|
+
console.log('✅ PDF converted to image successfully');
|
|
27
|
+
}
|
|
28
|
+
catch (conversionError) {
|
|
29
|
+
console.warn('⚠️ PDF to image conversion failed:', conversionError instanceof Error ? conversionError.message : 'Unknown error');
|
|
30
|
+
console.log('💡 PDF-poppler requires system dependencies. Falling back to empty content.');
|
|
31
|
+
// Continue with empty content - AI services will handle this gracefully
|
|
32
|
+
}
|
|
33
|
+
}
|
|
15
34
|
// Extract PDF metadata if available
|
|
16
35
|
const metadata = {};
|
|
17
36
|
// Cast data to any to access potentially existing metadata properties
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"pdf-parser.js","sourceRoot":"","sources":["../../src/parsers/pdf-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +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;
|
|
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;AAKzD,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;IA+E1K,OAAO,CAAC,gBAAgB;CAuBzB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import { applyNamingConvention
|
|
3
|
-
import {
|
|
2
|
+
import { applyNamingConvention } from '../utils/naming-conventions.js';
|
|
3
|
+
import { buildFileNamePrompt } from '../utils/ai-prompts.js';
|
|
4
4
|
export class ClaudeService {
|
|
5
5
|
name = 'Claude';
|
|
6
6
|
client;
|
|
@@ -12,70 +12,64 @@ export class ClaudeService {
|
|
|
12
12
|
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo) {
|
|
13
13
|
const convention = namingConvention;
|
|
14
14
|
const fileCategory = category;
|
|
15
|
-
|
|
16
|
-
const
|
|
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.`;
|
|
15
|
+
// Check if this is a scanned PDF image
|
|
16
|
+
const isScannedPDF = content.startsWith('[SCANNED_PDF_IMAGE]:');
|
|
68
17
|
try {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
18
|
+
let response;
|
|
19
|
+
if (isScannedPDF) {
|
|
20
|
+
// Extract base64 image data
|
|
21
|
+
const imageBase64 = content.replace('[SCANNED_PDF_IMAGE]:', '');
|
|
22
|
+
const prompt = buildFileNamePrompt({
|
|
23
|
+
content: 'This is a scanned PDF document converted to an image. Please analyze the image and extract the main content to generate an appropriate filename.',
|
|
24
|
+
originalName,
|
|
25
|
+
namingConvention: convention,
|
|
26
|
+
category: fileCategory,
|
|
27
|
+
fileInfo
|
|
28
|
+
});
|
|
29
|
+
response = await this.client.messages.create({
|
|
30
|
+
model: 'claude-sonnet-4-5-20250929', // Use Claude Sonnet 4.5 for vision capabilities
|
|
31
|
+
max_tokens: 100,
|
|
32
|
+
messages: [
|
|
33
|
+
{
|
|
34
|
+
role: 'user',
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: prompt
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'image',
|
|
42
|
+
source: {
|
|
43
|
+
type: 'base64',
|
|
44
|
+
media_type: imageBase64.startsWith('data:image/png') ? 'image/png' : 'image/jpeg',
|
|
45
|
+
data: imageBase64.split(',')[1] // Remove data:image/format;base64, prefix
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Standard text processing
|
|
55
|
+
const prompt = buildFileNamePrompt({
|
|
56
|
+
content,
|
|
57
|
+
originalName,
|
|
58
|
+
namingConvention: convention,
|
|
59
|
+
category: fileCategory,
|
|
60
|
+
fileInfo
|
|
61
|
+
});
|
|
62
|
+
response = await this.client.messages.create({
|
|
63
|
+
model: 'claude-3-haiku-20240307',
|
|
64
|
+
max_tokens: 100,
|
|
65
|
+
messages: [
|
|
66
|
+
{
|
|
67
|
+
role: 'user',
|
|
68
|
+
content: prompt
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
});
|
|
72
|
+
}
|
|
79
73
|
const suggestedName = response.content[0].type === 'text'
|
|
80
74
|
? response.content[0].text.trim()
|
|
81
75
|
: 'untitled-document';
|