@appkit/llamacpp-cli 1.3.2 → 1.4.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/cli.js +16 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/config-global.d.ts +6 -0
  5. package/dist/commands/config-global.d.ts.map +1 -0
  6. package/dist/commands/config-global.js +38 -0
  7. package/dist/commands/config-global.js.map +1 -0
  8. package/dist/commands/create.d.ts.map +1 -1
  9. package/dist/commands/create.js +15 -6
  10. package/dist/commands/create.js.map +1 -1
  11. package/dist/commands/list.js +2 -2
  12. package/dist/commands/list.js.map +1 -1
  13. package/dist/commands/pull.d.ts.map +1 -1
  14. package/dist/commands/pull.js +4 -1
  15. package/dist/commands/pull.js.map +1 -1
  16. package/dist/lib/model-downloader.d.ts +9 -3
  17. package/dist/lib/model-downloader.d.ts.map +1 -1
  18. package/dist/lib/model-downloader.js +34 -7
  19. package/dist/lib/model-downloader.js.map +1 -1
  20. package/dist/lib/model-scanner.d.ts +8 -2
  21. package/dist/lib/model-scanner.d.ts.map +1 -1
  22. package/dist/lib/model-scanner.js +36 -8
  23. package/dist/lib/model-scanner.js.map +1 -1
  24. package/dist/lib/models-dir-setup.d.ts +6 -0
  25. package/dist/lib/models-dir-setup.d.ts.map +1 -0
  26. package/dist/lib/models-dir-setup.js +75 -0
  27. package/dist/lib/models-dir-setup.js.map +1 -0
  28. package/dist/lib/state-manager.d.ts +8 -0
  29. package/dist/lib/state-manager.d.ts.map +1 -1
  30. package/dist/lib/state-manager.js +15 -0
  31. package/dist/lib/state-manager.js.map +1 -1
  32. package/dist/utils/file-utils.d.ts +1 -1
  33. package/dist/utils/file-utils.js +2 -2
  34. package/dist/utils/file-utils.js.map +1 -1
  35. package/dist/utils/prompt-utils.d.ts +9 -0
  36. package/dist/utils/prompt-utils.d.ts.map +1 -0
  37. package/dist/utils/prompt-utils.js +79 -0
  38. package/dist/utils/prompt-utils.js.map +1 -0
  39. package/package.json +1 -1
  40. package/src/cli.ts +16 -1
  41. package/src/commands/config-global.ts +38 -0
  42. package/src/commands/create.ts +16 -6
  43. package/src/commands/list.ts +2 -2
  44. package/src/commands/pull.ts +5 -1
  45. package/src/lib/model-downloader.ts +40 -8
  46. package/src/lib/model-scanner.ts +41 -9
  47. package/src/lib/models-dir-setup.ts +46 -0
  48. package/src/lib/state-manager.ts +17 -0
  49. package/src/utils/file-utils.ts +2 -2
  50. package/src/utils/prompt-utils.ts +47 -0
@@ -0,0 +1,46 @@
1
+ import * as fs from 'fs';
2
+ import chalk from 'chalk';
3
+ import { stateManager } from './state-manager';
4
+ import { expandHome } from '../utils/file-utils';
5
+ import { prompt } from '../utils/prompt-utils';
6
+
7
+ /**
8
+ * Ensure models directory exists, prompting user if needed
9
+ * Returns the final models directory path
10
+ */
11
+ export async function ensureModelsDirectory(): Promise<string> {
12
+ const configuredPath = await stateManager.getModelsDirectory();
13
+
14
+ // If directory exists, we're good
15
+ if (fs.existsSync(configuredPath)) {
16
+ return configuredPath;
17
+ }
18
+
19
+ // Directory doesn't exist - prompt user
20
+ console.log(chalk.yellow('⚠️ Models directory not found'));
21
+ console.log();
22
+ console.log(chalk.dim('The models directory is where GGUF model files are stored.'));
23
+ console.log(chalk.dim(`Configured path: ${configuredPath}`));
24
+ console.log();
25
+
26
+ const answer = await prompt(
27
+ 'Enter models directory path (press Enter to use default)',
28
+ configuredPath
29
+ );
30
+
31
+ const finalPath = expandHome(answer);
32
+
33
+ // If user changed the path, update config
34
+ if (finalPath !== configuredPath) {
35
+ console.log(chalk.dim(`Updating configuration to: ${finalPath}`));
36
+ await stateManager.setModelsDirectory(finalPath);
37
+ }
38
+
39
+ // Create the directory
40
+ console.log(chalk.dim(`Creating directory: ${finalPath}`));
41
+ fs.mkdirSync(finalPath, { recursive: true, mode: 0o755 });
42
+ console.log(chalk.green('✅ Models directory created'));
43
+ console.log();
44
+
45
+ return finalPath;
46
+ }
@@ -183,6 +183,23 @@ export class StateManager {
183
183
  const servers = await this.getAllServers();
184
184
  return new Set(servers.map((s) => s.port));
185
185
  }
186
+
187
+ /**
188
+ * Get the configured models directory
189
+ */
190
+ async getModelsDirectory(): Promise<string> {
191
+ const config = await this.loadGlobalConfig();
192
+ return config.modelsDirectory;
193
+ }
194
+
195
+ /**
196
+ * Set the models directory
197
+ */
198
+ async setModelsDirectory(directory: string): Promise<void> {
199
+ const config = await this.loadGlobalConfig();
200
+ config.modelsDirectory = directory;
201
+ await this.saveGlobalConfig(config);
202
+ }
186
203
  }
187
204
 
188
205
  // Export singleton instance
@@ -82,10 +82,10 @@ export function getGlobalConfigPath(): string {
82
82
  }
83
83
 
84
84
  /**
85
- * Get the models directory (~/models)
85
+ * Get the default models directory (~/.llamacpp/models)
86
86
  */
87
87
  export function getModelsDir(): string {
88
- return path.join(os.homedir(), 'models');
88
+ return path.join(getConfigDir(), 'models');
89
89
  }
90
90
 
91
91
  /**
@@ -0,0 +1,47 @@
1
+ import * as readline from 'readline';
2
+
3
+ /**
4
+ * Prompt user for input
5
+ */
6
+ export function prompt(question: string, defaultValue?: string): Promise<string> {
7
+ const rl = readline.createInterface({
8
+ input: process.stdin,
9
+ output: process.stdout,
10
+ });
11
+
12
+ return new Promise((resolve) => {
13
+ const promptText = defaultValue
14
+ ? `${question} [${defaultValue}]: `
15
+ : `${question}: `;
16
+
17
+ rl.question(promptText, (answer) => {
18
+ rl.close();
19
+ resolve(answer.trim() || defaultValue || '');
20
+ });
21
+ });
22
+ }
23
+
24
+ /**
25
+ * Prompt user for yes/no confirmation
26
+ */
27
+ export function confirm(question: string, defaultYes = true): Promise<boolean> {
28
+ const rl = readline.createInterface({
29
+ input: process.stdin,
30
+ output: process.stdout,
31
+ });
32
+
33
+ const suffix = defaultYes ? '[Y/n]' : '[y/N]';
34
+
35
+ return new Promise((resolve) => {
36
+ rl.question(`${question} ${suffix}: `, (answer) => {
37
+ rl.close();
38
+ const input = answer.trim().toLowerCase();
39
+
40
+ if (input === '') {
41
+ resolve(defaultYes);
42
+ } else {
43
+ resolve(input === 'y' || input === 'yes');
44
+ }
45
+ });
46
+ });
47
+ }