@amirdaraee/namewise 1.0.1 → 1.1.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +6 -6
  3. package/dist/cli/clean-empty.d.ts.map +1 -1
  4. package/dist/cli/clean-empty.js +2 -3
  5. package/dist/cli/clean-empty.js.map +1 -1
  6. package/dist/cli/commands.d.ts.map +1 -1
  7. package/dist/cli/commands.js +1 -20
  8. package/dist/cli/commands.js.map +1 -1
  9. package/dist/cli/config-cmd.d.ts.map +1 -1
  10. package/dist/cli/config-cmd.js +4 -3
  11. package/dist/cli/config-cmd.js.map +1 -1
  12. package/dist/cli/dedup.d.ts.map +1 -1
  13. package/dist/cli/dedup.js +3 -11
  14. package/dist/cli/dedup.js.map +1 -1
  15. package/dist/cli/diff.d.ts.map +1 -1
  16. package/dist/cli/diff.js +3 -7
  17. package/dist/cli/diff.js.map +1 -1
  18. package/dist/cli/find.d.ts.map +1 -1
  19. package/dist/cli/find.js +2 -3
  20. package/dist/cli/find.js.map +1 -1
  21. package/dist/cli/flatten.d.ts.map +1 -1
  22. package/dist/cli/flatten.js +4 -11
  23. package/dist/cli/flatten.js.map +1 -1
  24. package/dist/cli/handle-cli-error.d.ts +7 -0
  25. package/dist/cli/handle-cli-error.d.ts.map +1 -0
  26. package/dist/cli/handle-cli-error.js +25 -0
  27. package/dist/cli/handle-cli-error.js.map +1 -0
  28. package/dist/cli/init.js +2 -2
  29. package/dist/cli/init.js.map +1 -1
  30. package/dist/cli/organize.d.ts.map +1 -1
  31. package/dist/cli/organize.js +4 -11
  32. package/dist/cli/organize.js.map +1 -1
  33. package/dist/cli/rename.d.ts +4 -2
  34. package/dist/cli/rename.d.ts.map +1 -1
  35. package/dist/cli/rename.js +166 -227
  36. package/dist/cli/rename.js.map +1 -1
  37. package/dist/cli/sanitize.d.ts.map +1 -1
  38. package/dist/cli/sanitize.js +4 -12
  39. package/dist/cli/sanitize.js.map +1 -1
  40. package/dist/cli/shared-config.d.ts +60 -0
  41. package/dist/cli/shared-config.d.ts.map +1 -0
  42. package/dist/cli/shared-config.js +64 -0
  43. package/dist/cli/shared-config.js.map +1 -0
  44. package/dist/cli/stats.d.ts.map +1 -1
  45. package/dist/cli/stats.js +2 -4
  46. package/dist/cli/stats.js.map +1 -1
  47. package/dist/cli/tree.d.ts.map +1 -1
  48. package/dist/cli/tree.js +2 -3
  49. package/dist/cli/tree.js.map +1 -1
  50. package/dist/cli/watch.d.ts +3 -1
  51. package/dist/cli/watch.d.ts.map +1 -1
  52. package/dist/cli/watch.js +19 -63
  53. package/dist/cli/watch.js.map +1 -1
  54. package/dist/parsers/pdf-parser.d.ts.map +1 -1
  55. package/dist/parsers/pdf-parser.js +39 -24
  56. package/dist/parsers/pdf-parser.js.map +1 -1
  57. package/dist/services/base-cloud-service.d.ts +32 -0
  58. package/dist/services/base-cloud-service.d.ts.map +1 -0
  59. package/dist/services/base-cloud-service.js +73 -0
  60. package/dist/services/base-cloud-service.js.map +1 -0
  61. package/dist/services/base-local-service.d.ts +18 -0
  62. package/dist/services/base-local-service.d.ts.map +1 -0
  63. package/dist/services/base-local-service.js +81 -0
  64. package/dist/services/base-local-service.js.map +1 -0
  65. package/dist/services/claude-service.d.ts +8 -6
  66. package/dist/services/claude-service.d.ts.map +1 -1
  67. package/dist/services/claude-service.js +40 -98
  68. package/dist/services/claude-service.js.map +1 -1
  69. package/dist/services/lmstudio-service.d.ts +35 -9
  70. package/dist/services/lmstudio-service.d.ts.map +1 -1
  71. package/dist/services/lmstudio-service.js +23 -101
  72. package/dist/services/lmstudio-service.js.map +1 -1
  73. package/dist/services/ollama-service.d.ts +23 -9
  74. package/dist/services/ollama-service.d.ts.map +1 -1
  75. package/dist/services/ollama-service.js +16 -87
  76. package/dist/services/ollama-service.js.map +1 -1
  77. package/dist/services/openai-service.d.ts +8 -6
  78. package/dist/services/openai-service.d.ts.map +1 -1
  79. package/dist/services/openai-service.js +36 -94
  80. package/dist/services/openai-service.js.map +1 -1
  81. package/dist/utils/ai-name-sanitizer.d.ts +14 -0
  82. package/dist/utils/ai-name-sanitizer.d.ts.map +1 -0
  83. package/dist/utils/ai-name-sanitizer.js +39 -0
  84. package/dist/utils/ai-name-sanitizer.js.map +1 -0
  85. package/dist/utils/assert-directory.d.ts +9 -0
  86. package/dist/utils/assert-directory.d.ts.map +1 -0
  87. package/dist/utils/assert-directory.js +15 -0
  88. package/dist/utils/assert-directory.js.map +1 -0
  89. package/dist/utils/file-info.d.ts +8 -0
  90. package/dist/utils/file-info.d.ts.map +1 -0
  91. package/dist/utils/file-info.js +25 -0
  92. package/dist/utils/file-info.js.map +1 -0
  93. package/dist/utils/record-session.d.ts +18 -0
  94. package/dist/utils/record-session.d.ts.map +1 -0
  95. package/dist/utils/record-session.js +24 -0
  96. package/dist/utils/record-session.js.map +1 -0
  97. package/dist/utils/ui.d.ts.map +1 -1
  98. package/dist/utils/ui.js +1 -7
  99. package/dist/utils/ui.js.map +1 -1
  100. package/package.json +17 -18
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-local-service.d.ts","sourceRoot":"","sources":["../../src/services/base-local-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOvE;;;;GAIG;AACH,8BAAsB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAE,YAAW,UAAU;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IAExB,SAAS,aAAa,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAMlE,OAAO,CAAC,gBAAgB;IAelB,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,SAAe,EAC/B,QAAQ,SAAY,EACpB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC;IA8BxB,2EAA2E;IAC3E,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;cAErF,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;CAqBrF"}
@@ -0,0 +1,81 @@
1
+ import { buildFileNamePrompt } from '../utils/ai-prompts.js';
2
+ import { AuthError, NetworkError, RateLimitError, ConfigError } from '../errors.js';
3
+ import { sanitizeLocalFileName } from '../utils/ai-name-sanitizer.js';
4
+ /**
5
+ * Shared skeleton for local AI providers (Ollama, LMStudio): localhost URL
6
+ * validation, HTTP request/status mapping, and the generateFileName flow.
7
+ * Subclasses supply the chat request payload and response extraction.
8
+ */
9
+ export class BaseLocalService {
10
+ name;
11
+ baseUrl;
12
+ model;
13
+ constructor(name, baseUrl, model) {
14
+ this.name = name;
15
+ this.baseUrl = this.validateLocalUrl(baseUrl);
16
+ this.model = model;
17
+ }
18
+ validateLocalUrl(url) {
19
+ let parsed;
20
+ try {
21
+ parsed = new URL(url);
22
+ }
23
+ catch {
24
+ throw new ConfigError(`Invalid ${this.name} base URL: ${url}`);
25
+ }
26
+ const hostname = parsed.hostname.toLowerCase();
27
+ const allowed = hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1' || hostname === '[::1]';
28
+ if (!allowed) {
29
+ throw new ConfigError(`${this.name} base URL must point to localhost (got: ${hostname})`);
30
+ }
31
+ return url;
32
+ }
33
+ async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language, context, imageData) {
34
+ try {
35
+ if (imageData && (!imageData.startsWith('data:image/') || !imageData.includes(','))) {
36
+ throw new NetworkError('Invalid image data format');
37
+ }
38
+ const prompt = buildFileNamePrompt({
39
+ content: imageData
40
+ ? 'Analyze this image and generate an appropriate filename based on what you see.'
41
+ : content,
42
+ originalName,
43
+ namingConvention: namingConvention,
44
+ category: category,
45
+ fileInfo,
46
+ language,
47
+ context
48
+ });
49
+ const responseContent = await this.requestCompletion(prompt, imageData);
50
+ if (responseContent) {
51
+ return { name: sanitizeLocalFileName(responseContent), inputTokens: undefined, outputTokens: undefined };
52
+ }
53
+ throw new NetworkError(`No response content from ${this.name}`);
54
+ }
55
+ catch (error) {
56
+ if (error instanceof AuthError || error instanceof NetworkError || error instanceof RateLimitError || error instanceof ConfigError)
57
+ throw error;
58
+ throw new NetworkError(`${this.name} service failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
59
+ }
60
+ }
61
+ async makeRequest(endpoint, payload) {
62
+ const url = `${this.baseUrl}${endpoint}`;
63
+ const response = await fetch(url, {
64
+ method: 'POST',
65
+ headers: { 'Content-Type': 'application/json' },
66
+ body: JSON.stringify(payload)
67
+ });
68
+ if (!response.ok) {
69
+ const errorText = await response.text();
70
+ if (response.status === 401 || response.status === 403) {
71
+ throw new AuthError(`${this.name} authentication failed`, { details: { status: response.status, body: errorText } });
72
+ }
73
+ if (response.status === 429) {
74
+ throw new RateLimitError(`${this.name} rate limit exceeded`, { details: { status: response.status } });
75
+ }
76
+ throw new NetworkError(`${this.name} API request failed: ${response.status} ${response.statusText}`, { details: { status: response.status, body: errorText } });
77
+ }
78
+ return response.json();
79
+ }
80
+ }
81
+ //# sourceMappingURL=base-local-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-local-service.js","sourceRoot":"","sources":["../../src/services/base-local-service.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
- import { AIProvider, FileInfo, AINameResult } from '../types/index.js';
2
- export declare class ClaudeService implements AIProvider {
3
- name: string;
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import { BaseCloudService, CloudApiError, TokenUsage } from './base-cloud-service.js';
3
+ export declare class ClaudeService extends BaseCloudService<Anthropic.Message> {
4
4
  private client;
5
- private model;
6
5
  constructor(apiKey: string, model?: string);
7
- generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo, language?: string, context?: string, imageData?: string): Promise<AINameResult>;
8
- private sanitizeFileName;
6
+ protected createTextCompletion(prompt: string): Promise<Anthropic.Message>;
7
+ protected createImageCompletion(prompt: string, imageData: string): Promise<Anthropic.Message>;
8
+ protected extractSuggestedName(response: Anthropic.Message): string;
9
+ protected extractTokenUsage(response: Anthropic.Message): TokenUsage;
10
+ protected asApiError(error: unknown): CloudApiError | undefined;
9
11
  }
10
12
  //# sourceMappingURL=claude-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-service.d.ts","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKvE,qBAAa,aAAc,YAAW,UAAU;IAC9C,IAAI,SAAY;IAChB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAKpC,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,GAAE,MAAqB,EACvC,QAAQ,GAAE,MAAkB,EAC5B,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC;IAoFxB,OAAO,CAAC,gBAAgB;CAkBzB"}
1
+ {"version":3,"file":"claude-service.d.ts","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEtF,qBAAa,aAAc,SAAQ,gBAAgB,CAAC,SAAS,CAAC,OAAO,CAAC;IACpE,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAK1C,SAAS,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;IAQ1E,SAAS,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;IAuB9F,SAAS,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM;IAMnE,SAAS,CAAC,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,GAAG,UAAU;IAOpE,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS;CAGhE"}
@@ -1,111 +1,53 @@
1
1
  import Anthropic from '@anthropic-ai/sdk';
2
- import { AuthError, NetworkError, RateLimitError } from '../errors.js';
3
- import { applyNamingConvention, stripWindowsIllegalChars } from '../utils/naming-conventions.js';
4
- import { buildFileNamePrompt } from '../utils/ai-prompts.js';
5
- export class ClaudeService {
6
- name = 'Claude';
2
+ import { BaseCloudService } from './base-cloud-service.js';
3
+ export class ClaudeService extends BaseCloudService {
7
4
  client;
8
- model;
9
5
  constructor(apiKey, model) {
6
+ super('Claude', model ?? 'claude-opus-4-8');
10
7
  this.client = new Anthropic({ apiKey });
11
- this.model = model ?? 'claude-sonnet-4-5-20250929';
12
8
  }
13
- async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language, context, imageData) {
14
- const convention = namingConvention;
15
- const fileCategory = category;
16
- try {
17
- let response;
18
- if (imageData) {
19
- if (!imageData.startsWith('data:image/') || !imageData.includes(',')) {
20
- throw new NetworkError('Invalid image data format');
21
- }
22
- const prompt = buildFileNamePrompt({
23
- content: 'Analyze this image and generate an appropriate filename based on what you see.',
24
- originalName,
25
- namingConvention: convention,
26
- category: fileCategory,
27
- fileInfo,
28
- language,
29
- context
30
- });
31
- response = await this.client.messages.create({
32
- model: this.model,
33
- max_tokens: 100,
34
- messages: [
9
+ createTextCompletion(prompt) {
10
+ return this.client.messages.create({
11
+ model: this.model,
12
+ max_tokens: 100,
13
+ messages: [{ role: 'user', content: prompt }]
14
+ });
15
+ }
16
+ createImageCompletion(prompt, imageData) {
17
+ return this.client.messages.create({
18
+ model: this.model,
19
+ max_tokens: 100,
20
+ messages: [
21
+ {
22
+ role: 'user',
23
+ content: [
24
+ { type: 'text', text: prompt },
35
25
  {
36
- role: 'user',
37
- content: [
38
- { type: 'text', text: prompt },
39
- {
40
- type: 'image',
41
- source: {
42
- type: 'base64',
43
- media_type: imageData.startsWith('data:image/png') ? 'image/png' : 'image/jpeg',
44
- data: imageData.split(',')[1]
45
- }
46
- }
47
- ]
26
+ type: 'image',
27
+ source: {
28
+ type: 'base64',
29
+ media_type: imageData.startsWith('data:image/png') ? 'image/png' : 'image/jpeg',
30
+ data: imageData.split(',')[1]
31
+ }
48
32
  }
49
33
  ]
50
- });
51
- }
52
- else {
53
- const prompt = buildFileNamePrompt({
54
- content,
55
- originalName,
56
- namingConvention: convention,
57
- category: fileCategory,
58
- fileInfo,
59
- language,
60
- context
61
- });
62
- response = await this.client.messages.create({
63
- model: this.model,
64
- max_tokens: 100,
65
- messages: [{ role: 'user', content: prompt }]
66
- });
67
- }
68
- const suggestedName = response.content[0].type === 'text'
69
- ? response.content[0].text.trim()
70
- : 'untitled-document';
71
- return {
72
- name: this.sanitizeFileName(suggestedName, convention),
73
- inputTokens: response.usage?.input_tokens,
74
- outputTokens: response.usage?.output_tokens
75
- };
76
- }
77
- catch (error) {
78
- if (error instanceof AuthError || error instanceof NetworkError || error instanceof RateLimitError)
79
- throw error;
80
- if (error instanceof Anthropic.APIError) {
81
- if (error.status === 401 || error.status === 403) {
82
- throw new AuthError(`Claude authentication failed: ${error.message}`, { details: { status: error.status } });
83
- }
84
- if (error.status === 429) {
85
- throw new RateLimitError(`Claude rate limit exceeded: ${error.message}`, { details: { status: error.status } });
86
34
  }
87
- throw new NetworkError(`Claude API error (${error.status}): ${error.message}`, { details: { status: error.status } });
88
- }
89
- throw new NetworkError(`Failed to generate filename with Claude: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
90
- }
35
+ ]
36
+ });
37
+ }
38
+ extractSuggestedName(response) {
39
+ return response.content[0].type === 'text'
40
+ ? response.content[0].text.trim()
41
+ : 'untitled-document';
42
+ }
43
+ extractTokenUsage(response) {
44
+ return {
45
+ inputTokens: response.usage?.input_tokens,
46
+ outputTokens: response.usage?.output_tokens
47
+ };
91
48
  }
92
- sanitizeFileName(name, convention) {
93
- const nameWithoutExt = name.replace(/\.[^/.]+$/, '');
94
- const safeForWindows = stripWindowsIllegalChars(nameWithoutExt);
95
- let cleaned = applyNamingConvention(safeForWindows, convention);
96
- if (!cleaned) {
97
- cleaned = applyNamingConvention('untitled document', convention);
98
- }
99
- else if (cleaned.length > 100) {
100
- cleaned = cleaned.substring(0, 100);
101
- if (convention === 'kebab-case') {
102
- cleaned = cleaned.replace(/-[^-]*$/, '');
103
- }
104
- else if (convention === 'snake_case') {
105
- cleaned = cleaned.replace(/_[^_]*$/, '');
106
- }
107
- }
108
- return cleaned;
49
+ asApiError(error) {
50
+ return error instanceof Anthropic.APIError ? error : undefined;
109
51
  }
110
52
  }
111
53
  //# sourceMappingURL=claude-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-service.js","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-service.js","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAA6B,MAAM,yBAAyB,CAAC;AAEtF,MAAM,OAAO,aAAc,SAAQ,gBAAmC;IAC5D,MAAM,CAAY;IAE1B,YAAY,MAAc,EAAE,KAAc;QACxC,KAAK,CAAC,QAAQ,EAAE,KAAK,IAAI,iBAAiB,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAES,oBAAoB,CAAC,MAAc;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;SAC9C,CAAC,CAAC;IACL,CAAC;IAES,qBAAqB,CAAC,MAAc,EAAE,SAAiB;QAC/D,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC9B;4BACE,IAAI,EAAE,OAAO;4BACb,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY;gCAC/E,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;6BAC9B;yBACF;qBACF;iBACF;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAES,oBAAoB,CAAC,QAA2B;QACxD,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM;YACxC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;YACjC,CAAC,CAAC,mBAAmB,CAAC;IAC1B,CAAC;IAES,iBAAiB,CAAC,QAA2B;QACrD,OAAO;YACL,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,YAAY;YACzC,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa;SAC5C,CAAC;IACJ,CAAC;IAES,UAAU,CAAC,KAAc;QACjC,OAAO,KAAK,YAAY,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,CAAC;CACF"}
@@ -1,14 +1,40 @@
1
- import { AIProvider, FileInfo, AINameResult } from '../types/index.js';
2
- export declare class LMStudioService implements AIProvider {
3
- name: string;
4
- private baseUrl;
5
- private model;
1
+ import { BaseLocalService } from './base-local-service.js';
2
+ interface OpenAICompatibleResponse {
3
+ choices: Array<{
4
+ message: {
5
+ content: string;
6
+ role: string;
7
+ };
8
+ finish_reason: string;
9
+ }>;
10
+ usage?: {
11
+ prompt_tokens: number;
12
+ completion_tokens: number;
13
+ total_tokens: number;
14
+ };
15
+ }
16
+ interface OpenAIMessage {
17
+ role: 'system' | 'user' | 'assistant';
18
+ content: string | Array<{
19
+ type: string;
20
+ text?: string;
21
+ image_url?: {
22
+ url: string;
23
+ };
24
+ }>;
25
+ }
26
+ interface LMStudioChatRequest {
27
+ model: string;
28
+ messages: OpenAIMessage[];
29
+ temperature: number;
30
+ max_tokens: number;
31
+ stream: boolean;
32
+ }
33
+ export declare class LMStudioService extends BaseLocalService<LMStudioChatRequest, OpenAICompatibleResponse> {
6
34
  constructor(baseUrl?: string, model?: string);
7
- private validateLocalUrl;
8
- generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo, language?: string, context?: string, imageData?: string): Promise<AINameResult>;
9
- private sanitizeFilename;
10
- private makeRequest;
35
+ protected requestCompletion(prompt: string, imageData?: string): Promise<string | undefined>;
11
36
  isAvailable(): Promise<boolean>;
12
37
  listModels(): Promise<string[]>;
13
38
  }
39
+ export {};
14
40
  //# sourceMappingURL=lmstudio-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lmstudio-service.d.ts","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAiCvE,qBAAa,eAAgB,YAAW,UAAU;IAChD,IAAI,SAAc;IAClB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAGpB,OAAO,SAA0B,EACjC,KAAK,SAAgB;IAMvB,OAAO,CAAC,gBAAgB;IAelB,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,SAAe,EAC/B,QAAQ,SAAY,EACpB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC;IAqDxB,OAAO,CAAC,gBAAgB;YAUV,WAAW;IA2BnB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAWtC"}
1
+ {"version":3,"file":"lmstudio-service.d.ts","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,UAAU,wBAAwB;IAChC,OAAO,EAAE,KAAK,CAAC;QACb,OAAO,EAAE;YACP,OAAO,EAAE,MAAM,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;QACF,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;IACH,KAAK,CAAC,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;CACvF;AAED,UAAU,mBAAmB;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AASD,qBAAa,eAAgB,SAAQ,gBAAgB,CAAC,mBAAmB,EAAE,wBAAwB,CAAC;gBAEhG,OAAO,SAA0B,EACjC,KAAK,SAAgB;cAKP,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA0B5F,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAWtC"}
@@ -1,108 +1,30 @@
1
- import { buildFileNamePrompt, AI_SYSTEM_PROMPT } from '../utils/ai-prompts.js';
2
- import { AuthError, NetworkError, RateLimitError, ConfigError } from '../errors.js';
3
- export class LMStudioService {
4
- name = 'LMStudio';
5
- baseUrl;
6
- model;
1
+ import { AI_SYSTEM_PROMPT } from '../utils/ai-prompts.js';
2
+ import { BaseLocalService } from './base-local-service.js';
3
+ export class LMStudioService extends BaseLocalService {
7
4
  constructor(baseUrl = 'http://localhost:1234', model = 'local-model') {
8
- this.baseUrl = this.validateLocalUrl(baseUrl);
9
- this.model = model;
5
+ super('LMStudio', baseUrl, model);
10
6
  }
11
- validateLocalUrl(url) {
12
- let parsed;
13
- try {
14
- parsed = new URL(url);
15
- }
16
- catch {
17
- throw new ConfigError(`Invalid LMStudio base URL: ${url}`);
18
- }
19
- const hostname = parsed.hostname.toLowerCase();
20
- const allowed = hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1' || hostname === '[::1]';
21
- if (!allowed) {
22
- throw new ConfigError(`LMStudio base URL must point to localhost (got: ${hostname})`);
23
- }
24
- return url;
25
- }
26
- async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language, context, imageData) {
27
- try {
28
- if (imageData && (!imageData.startsWith('data:image/') || !imageData.includes(','))) {
29
- throw new NetworkError('Invalid image data format');
30
- }
31
- const prompt = buildFileNamePrompt({
32
- content: imageData
33
- ? 'Analyze this image and generate an appropriate filename based on what you see.'
34
- : content,
35
- originalName,
36
- namingConvention: namingConvention,
37
- category: category,
38
- fileInfo,
39
- language,
40
- context
41
- });
42
- const userMessage = imageData
43
- ? {
44
- role: 'user',
45
- content: [
46
- { type: 'text', text: prompt },
47
- { type: 'image_url', image_url: { url: imageData } }
48
- ]
49
- }
50
- : { role: 'user', content: prompt };
51
- const response = await this.makeRequest('/v1/chat/completions', {
52
- model: this.model,
53
- messages: [
54
- { role: 'system', content: AI_SYSTEM_PROMPT },
55
- userMessage
56
- ],
57
- temperature: 0.3,
58
- max_tokens: 100,
59
- stream: false
60
- });
61
- if (response.choices?.[0]?.message?.content) {
62
- return {
63
- name: this.sanitizeFilename(response.choices[0].message.content),
64
- inputTokens: undefined,
65
- outputTokens: undefined
66
- };
7
+ async requestCompletion(prompt, imageData) {
8
+ const userMessage = imageData
9
+ ? {
10
+ role: 'user',
11
+ content: [
12
+ { type: 'text', text: prompt },
13
+ { type: 'image_url', image_url: { url: imageData } }
14
+ ]
67
15
  }
68
- throw new NetworkError('No response content from LMStudio');
69
- }
70
- catch (error) {
71
- if (error instanceof AuthError || error instanceof NetworkError || error instanceof RateLimitError || error instanceof ConfigError)
72
- throw error;
73
- throw new NetworkError(`LMStudio service failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
74
- }
75
- }
76
- sanitizeFilename(filename) {
77
- return filename
78
- .trim()
79
- .replace(/^["']|["']$/g, '') // Remove quotes
80
- .replace(/\.(txt|pdf|docx?|xlsx?|md|rtf)$/i, '') // Remove extensions
81
- .replace(/[<>:"/\\|?*]/g, '-') // Replace invalid characters
82
- .replace(/\s+/g, '-') // Replace spaces with hyphens
83
- .toLowerCase();
84
- }
85
- async makeRequest(endpoint, payload) {
86
- const url = `${this.baseUrl}${endpoint}`;
87
- const response = await fetch(url, {
88
- method: 'POST',
89
- headers: {
90
- 'Content-Type': 'application/json',
91
- },
92
- body: JSON.stringify(payload),
16
+ : { role: 'user', content: prompt };
17
+ const response = await this.makeRequest('/v1/chat/completions', {
18
+ model: this.model,
19
+ messages: [
20
+ { role: 'system', content: AI_SYSTEM_PROMPT },
21
+ userMessage
22
+ ],
23
+ temperature: 0.3,
24
+ max_tokens: 100,
25
+ stream: false
93
26
  });
94
- if (!response.ok) {
95
- const errorText = await response.text();
96
- if (response.status === 401 || response.status === 403) {
97
- throw new AuthError(`LMStudio authentication failed`, { details: { status: response.status, body: errorText } });
98
- }
99
- if (response.status === 429) {
100
- throw new RateLimitError(`LMStudio rate limit exceeded`, { details: { status: response.status } });
101
- }
102
- throw new NetworkError(`LMStudio API request failed: ${response.status} ${response.statusText}`, { details: { status: response.status, body: errorText } });
103
- }
104
- const data = await response.json();
105
- return data;
27
+ return response.choices?.[0]?.message?.content;
106
28
  }
107
29
  // Method to check if LMStudio service is available
108
30
  async isAvailable() {
@@ -1 +1 @@
1
- {"version":3,"file":"lmstudio-service.js","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lmstudio-service.js","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAqC3D,MAAM,OAAO,eAAgB,SAAQ,gBAA+D;IAClG,YACE,OAAO,GAAG,uBAAuB,EACjC,KAAK,GAAG,aAAa;QAErB,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAES,KAAK,CAAC,iBAAiB,CAAC,MAAc,EAAE,SAAkB;QAClE,MAAM,WAAW,GAAkB,SAAS;YAC1C,CAAC,CAAC;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;oBAC9B,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE;iBACrD;aACF;YACH,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAEtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,sBAAsB,EAAE;YAC9D,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE;gBAC7C,WAAW;aACZ;YACD,WAAW,EAAE,GAAG;YAChB,UAAU,EAAE,GAAG;YACf,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;IACjD,CAAC;IAED,mDAAmD;IACnD,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,YAAY,CAAC,CAAC;YAC1D,OAAO,QAAQ,CAAC,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,YAAY,CAAC,CAAC;YAC1D,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,OAAO,EAAE,CAAC;YAE5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,KAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
@@ -1,14 +1,28 @@
1
- import { AIProvider, FileInfo, AINameResult } from '../types/index.js';
2
- export declare class OllamaService implements AIProvider {
3
- name: string;
4
- private baseUrl;
5
- private model;
1
+ import { BaseLocalService } from './base-local-service.js';
2
+ interface OllamaResponse {
3
+ model: string;
4
+ response?: string;
5
+ message?: {
6
+ content: string;
7
+ role: string;
8
+ };
9
+ done: boolean;
10
+ }
11
+ interface OllamaChatMessage {
12
+ role: 'system' | 'user' | 'assistant';
13
+ content: string;
14
+ images?: string[];
15
+ }
16
+ interface OllamaChatRequest {
17
+ model: string;
18
+ messages: OllamaChatMessage[];
19
+ stream: boolean;
20
+ }
21
+ export declare class OllamaService extends BaseLocalService<OllamaChatRequest, OllamaResponse> {
6
22
  constructor(baseUrl?: string, model?: string);
7
- private validateLocalUrl;
8
- generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo, language?: string, context?: string, imageData?: string): Promise<AINameResult>;
9
- private sanitizeFilename;
10
- private makeRequest;
23
+ protected requestCompletion(prompt: string, imageData?: string): Promise<string | undefined>;
11
24
  isAvailable(): Promise<boolean>;
12
25
  listModels(): Promise<string[]>;
13
26
  }
27
+ export {};
14
28
  //# sourceMappingURL=ollama-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ollama-service.d.ts","sourceRoot":"","sources":["../../src/services/ollama-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAmBvE,qBAAa,aAAc,YAAW,UAAU;IAC9C,IAAI,SAAY;IAChB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,SAA2B,EAAE,KAAK,SAAa;IAKlE,OAAO,CAAC,gBAAgB;IAelB,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,SAAe,EAC/B,QAAQ,SAAY,EACpB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC;IAyCxB,OAAO,CAAC,gBAAgB;YAUV,WAAW;IAsBnB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAUtC"}
1
+ {"version":3,"file":"ollama-service.d.ts","sourceRoot":"","sources":["../../src/services/ollama-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,IAAI,EAAE,OAAO,CAAC;CACf;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;CACjB;AAMD,qBAAa,aAAc,SAAQ,gBAAgB,CAAC,iBAAiB,EAAE,cAAc,CAAC;gBACxE,OAAO,SAA2B,EAAE,KAAK,SAAa;cAIlD,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiB5F,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAUtC"}