@commit451/salamander 1.0.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 (59) hide show
  1. package/README.md +50 -0
  2. package/bin/salamander.js +2 -0
  3. package/dist/commands/create-runner.d.ts +2 -0
  4. package/dist/commands/create-runner.d.ts.map +1 -0
  5. package/dist/commands/create-runner.js +57 -0
  6. package/dist/commands/create-runner.js.map +1 -0
  7. package/dist/commands/delete-runner.d.ts +2 -0
  8. package/dist/commands/delete-runner.d.ts.map +1 -0
  9. package/dist/commands/delete-runner.js +55 -0
  10. package/dist/commands/delete-runner.js.map +1 -0
  11. package/dist/commands/runner-selection.d.ts +2 -0
  12. package/dist/commands/runner-selection.d.ts.map +1 -0
  13. package/dist/commands/runner-selection.js +82 -0
  14. package/dist/commands/runner-selection.js.map +1 -0
  15. package/dist/config/firebase.d.ts +4 -0
  16. package/dist/config/firebase.d.ts.map +1 -0
  17. package/dist/config/firebase.js +17 -0
  18. package/dist/config/firebase.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +128 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/services/auth.d.ts +35 -0
  24. package/dist/services/auth.d.ts.map +1 -0
  25. package/dist/services/auth.js +393 -0
  26. package/dist/services/auth.js.map +1 -0
  27. package/dist/services/command-listener.d.ts +8 -0
  28. package/dist/services/command-listener.d.ts.map +1 -0
  29. package/dist/services/command-listener.js +84 -0
  30. package/dist/services/command-listener.js.map +1 -0
  31. package/dist/services/config.d.ts +12 -0
  32. package/dist/services/config.d.ts.map +1 -0
  33. package/dist/services/config.js +26 -0
  34. package/dist/services/config.js.map +1 -0
  35. package/dist/services/executor.d.ts +13 -0
  36. package/dist/services/executor.d.ts.map +1 -0
  37. package/dist/services/executor.js +90 -0
  38. package/dist/services/executor.js.map +1 -0
  39. package/dist/services/runner.d.ts +19 -0
  40. package/dist/services/runner.d.ts.map +1 -0
  41. package/dist/services/runner.js +205 -0
  42. package/dist/services/runner.js.map +1 -0
  43. package/dist/types/runner.d.ts +40 -0
  44. package/dist/types/runner.d.ts.map +1 -0
  45. package/dist/types/runner.js +7 -0
  46. package/dist/types/runner.js.map +1 -0
  47. package/dist/utils/device.d.ts +4 -0
  48. package/dist/utils/device.d.ts.map +1 -0
  49. package/dist/utils/device.js +14 -0
  50. package/dist/utils/device.js.map +1 -0
  51. package/dist/utils/storage.d.ts +20 -0
  52. package/dist/utils/storage.d.ts.map +1 -0
  53. package/dist/utils/storage.js +49 -0
  54. package/dist/utils/storage.js.map +1 -0
  55. package/dist/utils/version.d.ts +15 -0
  56. package/dist/utils/version.d.ts.map +1 -0
  57. package/dist/utils/version.js +33 -0
  58. package/dist/utils/version.js.map +1 -0
  59. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Salamander CLI
2
+
3
+ Never be AFK.
4
+
5
+ Command-line interface for Salamander AI runners. This tool allows you to run AI-powered command execution on your local machine and receive commands from the Salamander app.
6
+
7
+ ## Installation
8
+ You should first install [Claude's CLI](https://docs.anthropic.com/en/docs/claude-code/cli-reference) so that your machine has the needed `claude` command available.
9
+
10
+ ```bash
11
+ npm install -g @commit451/salamander
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ### Start the CLI (main interface)
17
+ ```bash
18
+ salamander
19
+ ```
20
+
21
+ ### Create a new runner
22
+ ```bash
23
+ salamander create
24
+ ```
25
+
26
+ ### Start runner selection
27
+ ```bash
28
+ salamander start
29
+ ```
30
+
31
+ ### Logout
32
+ ```bash
33
+ salamander logout
34
+ ```
35
+
36
+ ## Development
37
+
38
+ ```bash
39
+ # Install dependencies
40
+ npm install
41
+
42
+ # Run in development mode
43
+ npm run dev
44
+
45
+ # Build the project
46
+ npm run build
47
+
48
+ # Run the built version
49
+ npm start
50
+ ```
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import('../dist/index.js').then(m => m.default()).catch(console.error);
@@ -0,0 +1,2 @@
1
+ export declare function createRunnerFlow(): Promise<void>;
2
+ //# sourceMappingURL=create-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-runner.d.ts","sourceRoot":"","sources":["../../src/commands/create-runner.ts"],"names":[],"mappings":"AAOA,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuDtD"}
@@ -0,0 +1,57 @@
1
+ import { input } from '@inquirer/prompts';
2
+ import { resolve } from 'path';
3
+ import { access } from 'fs/promises';
4
+ import chalk from 'chalk';
5
+ import { RunnerService } from '../services/runner.js';
6
+ import { RunnerType } from '../types/runner.js';
7
+ export async function createRunnerFlow() {
8
+ console.log(chalk.blue('\n🚀 Create New Runner'));
9
+ console.log('Set up a new runner to execute commands in a specific directory.\n');
10
+ try {
11
+ // Get runner name
12
+ const name = await input({
13
+ message: 'Runner name:',
14
+ validate: (value) => {
15
+ if (!value.trim()) {
16
+ return 'Please enter a runner name';
17
+ }
18
+ return true;
19
+ }
20
+ });
21
+ // Get directory path
22
+ const directoryInput = await input({
23
+ message: 'Directory path:',
24
+ default: process.cwd(),
25
+ validate: async (value) => {
26
+ try {
27
+ const fullPath = resolve(value);
28
+ await access(fullPath);
29
+ return true;
30
+ }
31
+ catch {
32
+ return 'Directory does not exist or is not accessible';
33
+ }
34
+ }
35
+ });
36
+ const directory = resolve(directoryInput);
37
+ // Default to claude runner type
38
+ const runnerType = RunnerType.CLAUDE;
39
+ console.log(chalk.yellow('⏳ Creating runner...'));
40
+ const runner = await RunnerService.createRunner({
41
+ name: name.trim(),
42
+ directory,
43
+ runnerType
44
+ });
45
+ console.log(chalk.green('✅ Runner created successfully!'));
46
+ console.log(chalk.gray(` ID: ${runner.id}`));
47
+ console.log(chalk.gray(` Name: ${runner.name}`));
48
+ console.log(chalk.gray(` Directory: ${runner.directory}`));
49
+ console.log(chalk.gray(` Type: ${runner.runnerType}`));
50
+ console.log('You can now start this runner to listen for commands.');
51
+ }
52
+ catch (error) {
53
+ console.error(chalk.red('❌ Error creating runner:'), error.message);
54
+ process.exit(1);
55
+ }
56
+ }
57
+ //# sourceMappingURL=create-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-runner.js","sourceRoot":"","sources":["../../src/commands/create-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAS,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,gBAAgB;IAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAElF,IAAI,CAAC;QACD,kBAAkB;QAClB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC;YACrB,OAAO,EAAE,cAAc;YACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAChB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;oBAChB,OAAO,4BAA4B,CAAC;gBACxC,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;SACJ,CAAC,CAAC;QAEH,qBAAqB;QACrB,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC;YAC/B,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;YACtB,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACtB,IAAI,CAAC;oBACD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;oBAChC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACvB,OAAO,IAAI,CAAC;gBAChB,CAAC;gBAAC,MAAM,CAAC;oBACL,OAAO,+CAA+C,CAAC;gBAC3D,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QAE1C,gCAAgC;QAChC,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC;QAErC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAElD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC;YAC5C,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YACjB,SAAS;YACT,UAAU;SACb,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IAEzE,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function deleteRunnerFlow(): Promise<void>;
2
+ //# sourceMappingURL=delete-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-runner.d.ts","sourceRoot":"","sources":["../../src/commands/delete-runner.ts"],"names":[],"mappings":"AAKA,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwDtD"}
@@ -0,0 +1,55 @@
1
+ import { select, confirm } from '@inquirer/prompts';
2
+ import chalk from 'chalk';
3
+ import { RunnerService } from '../services/runner.js';
4
+ export async function deleteRunnerFlow() {
5
+ console.log(chalk.blue('\n🗑️ Delete Runner'));
6
+ try {
7
+ const localRunners = await RunnerService.getLocalRunners();
8
+ if (localRunners.length === 0) {
9
+ console.log(chalk.yellow('⚠️ No runners found for this machine.'));
10
+ return;
11
+ }
12
+ console.log(chalk.green(`✅ Found ${localRunners.length} runner(s) for this machine`));
13
+ const choices = localRunners.map(runner => ({
14
+ name: formatRunnerChoice(runner),
15
+ value: runner.id,
16
+ description: `Delete runner in ${runner.directory}`
17
+ }));
18
+ const runnerId = await select({
19
+ message: 'Select a runner to delete:',
20
+ choices
21
+ });
22
+ const selectedRunner = localRunners.find(r => r.id === runnerId);
23
+ if (!selectedRunner) {
24
+ console.error(chalk.red('❌ Runner not found'));
25
+ return;
26
+ }
27
+ console.log(chalk.yellow('\n⚠️ This action cannot be undone!'));
28
+ console.log(chalk.gray(` Runner: ${selectedRunner.name}`));
29
+ console.log(chalk.gray(` Directory: ${selectedRunner.directory}`));
30
+ console.log(chalk.gray(` Type: ${selectedRunner.runnerType}`));
31
+ const confirmed = await confirm({
32
+ message: 'Are you sure you want to delete this runner?',
33
+ default: false
34
+ });
35
+ if (!confirmed) {
36
+ console.log(chalk.blue('👍 Delete cancelled'));
37
+ return;
38
+ }
39
+ console.log(chalk.yellow('⏳ Deleting runner...'));
40
+ await RunnerService.deleteRunner(runnerId);
41
+ console.log(chalk.green('✅ Runner deleted successfully!'));
42
+ console.log(chalk.gray(` Removed: ${selectedRunner.name}`));
43
+ }
44
+ catch (error) {
45
+ console.error(chalk.red('❌ Error deleting runner:'), error.message);
46
+ process.exit(1);
47
+ }
48
+ }
49
+ function formatRunnerChoice(runner) {
50
+ const lastMessage = runner.lastMessage
51
+ ? ` • ${runner.lastMessage.substring(0, 50)}${runner.lastMessage.length > 50 ? '...' : ''}`
52
+ : '';
53
+ return `🤖 ${chalk.bold(runner.name)} ${chalk.gray(`[${runner.runnerType}]`)}${chalk.dim(lastMessage)}`;
54
+ }
55
+ //# sourceMappingURL=delete-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-runner.js","sourceRoot":"","sources":["../../src/commands/delete-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runnerSelectionFlow(): Promise<void>;
2
+ //# sourceMappingURL=runner-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-selection.d.ts","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"AAQA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwEzD"}
@@ -0,0 +1,82 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import chalk from 'chalk';
3
+ import { RunnerService } from '../services/runner.js';
4
+ import { CommandListener } from '../services/command-listener.js';
5
+ import { createRunnerFlow } from './create-runner.js';
6
+ import { deleteRunnerFlow } from './delete-runner.js';
7
+ export async function runnerSelectionFlow() {
8
+ console.log(chalk.blue('🏃 Runner Selection'));
9
+ try {
10
+ const localRunners = await RunnerService.getLocalRunners();
11
+ if (localRunners.length === 0) {
12
+ console.log(chalk.yellow('⚠️ No runners found for this machine.'));
13
+ console.log('You need to create a runner first.');
14
+ const shouldCreate = await select({
15
+ message: 'What would you like to do?',
16
+ choices: [
17
+ { name: 'Create a new runner', value: 'create' },
18
+ { name: 'Exit', value: 'exit' }
19
+ ]
20
+ });
21
+ if (shouldCreate === 'create') {
22
+ await createRunnerFlow();
23
+ // After creating a runner, restart the selection process
24
+ return runnerSelectionFlow();
25
+ }
26
+ else {
27
+ console.log(chalk.blue('👋 Goodbye!'));
28
+ process.exit(0);
29
+ }
30
+ }
31
+ console.log(chalk.green(`✅ Found ${localRunners.length} runner(s) for this machine`));
32
+ const choices = [
33
+ ...localRunners.map(runner => ({
34
+ name: formatRunnerChoice(runner),
35
+ value: `run:${runner.id}`,
36
+ description: `Listen for commands in ${runner.directory}`
37
+ })),
38
+ { name: '➕ Create new runner', value: 'create' },
39
+ { name: '🗑️ Delete runner', value: 'delete' },
40
+ { name: '🚪 Exit', value: 'exit' }
41
+ ];
42
+ const selection = await select({
43
+ message: 'Select a runner to start or choose an action:',
44
+ choices
45
+ });
46
+ if (selection === 'create') {
47
+ await createRunnerFlow();
48
+ return runnerSelectionFlow();
49
+ }
50
+ else if (selection === 'delete') {
51
+ await deleteRunnerFlow();
52
+ return runnerSelectionFlow();
53
+ }
54
+ else if (selection === 'exit') {
55
+ console.log(chalk.blue('👋 Goodbye!'));
56
+ process.exit(0);
57
+ }
58
+ else if (selection.startsWith('run:')) {
59
+ const runnerId = selection.replace('run:', '');
60
+ const runner = localRunners.find(r => r.id === runnerId);
61
+ if (runner) {
62
+ const listener = new CommandListener();
63
+ await listener.startListening(runner);
64
+ }
65
+ else {
66
+ console.error(chalk.red('❌ Runner not found'));
67
+ return runnerSelectionFlow();
68
+ }
69
+ }
70
+ }
71
+ catch (error) {
72
+ console.error(chalk.red('❌ Error loading runners:'), error.message);
73
+ process.exit(1);
74
+ }
75
+ }
76
+ function formatRunnerChoice(runner) {
77
+ const lastMessage = runner.lastMessage
78
+ ? ` • ${runner.lastMessage.substring(0, 50)}${runner.lastMessage.length > 50 ? '...' : ''}`
79
+ : '';
80
+ return `🤖 ${chalk.bold(runner.name)} ${chalk.gray(`[${runner.runnerType}]`)}${chalk.dim(lastMessage)}`;
81
+ }
82
+ //# sourceMappingURL=runner-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-selection.js","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ declare const app: import("@firebase/app").FirebaseApp;
2
+ export declare const db: import("@firebase/firestore").Firestore;
3
+ export default app;
4
+ //# sourceMappingURL=firebase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase.d.ts","sourceRoot":"","sources":["../../src/config/firebase.ts"],"names":[],"mappings":"AAcA,QAAA,MAAM,GAAG,qCAAwE,CAAC;AAGlF,eAAO,MAAM,EAAE,yCAAoB,CAAC;AAEpC,eAAe,GAAG,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { initializeApp, getApps } from 'firebase/app';
2
+ import { getFirestore } from 'firebase/firestore';
3
+ const firebaseConfig = {
4
+ apiKey: "AIzaSyDXnEjvqq8lspDRlEJiDkztxWTmLYMoDGg",
5
+ authDomain: "salamander-ai.firebaseapp.com",
6
+ projectId: "salamander-ai",
7
+ storageBucket: "salamander-ai.firebasestorage.app",
8
+ messagingSenderId: "87955960620",
9
+ appId: "1:87955960620:web:85b30a28edf96c71d83289",
10
+ measurementId: "G-ZV0YR21B6X"
11
+ };
12
+ // Initialize Firebase (only if not already initialized)
13
+ const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
14
+ // Initialize services
15
+ export const db = getFirestore(app);
16
+ export default app;
17
+ //# sourceMappingURL=firebase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase.js","sourceRoot":"","sources":["../../src/config/firebase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,OAAO,EAAC,MAAM,cAAc,CAAC;AACpD,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAEhD,MAAM,cAAc,GAAG;IACnB,MAAM,EAAE,yCAAyC;IACjD,UAAU,EAAE,+BAA+B;IAC3C,SAAS,EAAE,eAAe;IAC1B,aAAa,EAAE,mCAAmC;IAClD,iBAAiB,EAAE,aAAa;IAChC,KAAK,EAAE,0CAA0C;IACjD,aAAa,EAAE,cAAc;CAChC,CAAC;AAEF,wDAAwD;AACxD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;AAElF,sBAAsB;AACtB,MAAM,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;AAEpC,eAAe,GAAG,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export default function main(): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsIA,MAAM,CAAC,OAAO,UAAU,IAAI,SAE3B"}
package/dist/index.js ADDED
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { readFileSync } from 'fs';
5
+ import { fileURLToPath } from 'url';
6
+ import { dirname, join } from 'path';
7
+ import { AuthService } from './services/auth.js';
8
+ import { ConfigService } from './services/config.js';
9
+ import { runnerSelectionFlow } from './commands/runner-selection.js';
10
+ import { createRunnerFlow } from './commands/create-runner.js';
11
+ import { deleteRunnerFlow } from './commands/delete-runner.js';
12
+ import { isVersionOutdated } from './utils/version.js';
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const packageJsonPath = join(__dirname, '..', 'package.json');
15
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
16
+ const CURRENT_VERSION = packageJson.version;
17
+ const program = new Command();
18
+ program
19
+ .name('salamander')
20
+ .description('Salamander AI Runner CLI - Execute AI commands in your local environment')
21
+ .version(CURRENT_VERSION);
22
+ program
23
+ .command('start')
24
+ .description('Start the runner selection interface')
25
+ .action(async () => {
26
+ await initializeAndRun(runnerSelectionFlow);
27
+ });
28
+ program
29
+ .command('create')
30
+ .description('Create a new runner')
31
+ .action(async () => {
32
+ await initializeAndRun(createRunnerFlow);
33
+ });
34
+ program
35
+ .command('delete')
36
+ .description('Delete an existing runner')
37
+ .action(async () => {
38
+ await initializeAndRun(deleteRunnerFlow);
39
+ });
40
+ program
41
+ .command('logout')
42
+ .description('Sign out from Salamander')
43
+ .action(async () => {
44
+ try {
45
+ await AuthService.initialize();
46
+ if (AuthService.isAuthenticated) {
47
+ await AuthService.signOut();
48
+ }
49
+ else {
50
+ console.log(chalk.yellow('⚠️ You are not currently signed in'));
51
+ }
52
+ }
53
+ catch (error) {
54
+ console.error(chalk.red('❌ Error during logout:'), error.message);
55
+ process.exit(1);
56
+ }
57
+ });
58
+ // Default action - if no command is specified, run the main flow
59
+ program.action(async () => {
60
+ await initializeAndRun(runnerSelectionFlow);
61
+ });
62
+ async function checkVersionAndPromptUpdate() {
63
+ try {
64
+ const minBuildVersion = ConfigService.getMinBuildCLI().toString();
65
+ if (isVersionOutdated(CURRENT_VERSION, minBuildVersion)) {
66
+ console.log(chalk.yellow('⚠️ Update Required'));
67
+ console.log(chalk.yellow(`Your CLI version (${CURRENT_VERSION}) is outdated.`));
68
+ console.log(chalk.yellow(`Minimum required version: ${minBuildVersion}`));
69
+ console.log('');
70
+ console.log(chalk.blue('Please run: npm install -g salamander-cli@latest'));
71
+ process.exit(1);
72
+ }
73
+ }
74
+ catch (error) {
75
+ // If version check fails, log warning but continue
76
+ console.log(chalk.yellow('⚠️ Could not check for updates'));
77
+ }
78
+ }
79
+ async function initializeAndRun(action) {
80
+ try {
81
+ console.log(chalk.blue('🦎 Salamander CLI'));
82
+ console.log(chalk.gray('Initializing...'));
83
+ // Fetch global configuration first
84
+ await ConfigService.fetchConfig();
85
+ console.log(chalk.gray('✓ Global config loaded'));
86
+ // Check if app is disabled
87
+ if (ConfigService.isAppDisabled()) {
88
+ console.log(chalk.red('❌ Salamander CLI is currently disabled. Please try again later.'));
89
+ process.exit(1);
90
+ }
91
+ // Check version and prompt for update if needed
92
+ await checkVersionAndPromptUpdate();
93
+ // Initialize Firebase Auth
94
+ await AuthService.initialize();
95
+ // Check if user is authenticated
96
+ if (!AuthService.isAuthenticated) {
97
+ const success = await AuthService.loginFlow();
98
+ if (!success) {
99
+ console.log(chalk.red('Authentication failed. Exiting...'));
100
+ process.exit(1);
101
+ }
102
+ }
103
+ else {
104
+ const userEmail = AuthService.user?.email || 'Unknown user';
105
+ console.log(chalk.green(`✅ Signed in as: ${userEmail}`));
106
+ }
107
+ // Run the specified action
108
+ await action();
109
+ }
110
+ catch (error) {
111
+ console.error(chalk.red('❌ An error occurred:'), error.message);
112
+ if (error.stack) {
113
+ console.error(chalk.gray(error.stack));
114
+ }
115
+ process.exit(1);
116
+ }
117
+ }
118
+ // Export default function for the bin script
119
+ export default function main() {
120
+ program.parse();
121
+ }
122
+ // If this file is run directly (not imported), execute main
123
+ if (import.meta.url.endsWith(process.argv[1]?.replace(/\\/g, '/') || '') ||
124
+ process.argv[1]?.includes('src/index.ts') ||
125
+ process.argv[1]?.includes('src\\index.ts')) {
126
+ main();
127
+ }
128
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { User } from 'firebase/auth';
2
+ interface UserInfo {
3
+ id: string;
4
+ email: string;
5
+ name: string;
6
+ picture?: string;
7
+ }
8
+ export declare class AuthService {
9
+ private static currentUser;
10
+ private static customUserInfo;
11
+ private static tokens;
12
+ private static oauth2Client;
13
+ private static authStateInitialized;
14
+ private static readonly config;
15
+ private static getOAuth2Client;
16
+ private static generateCodeVerifier;
17
+ private static generateCodeChallenge;
18
+ static initialize(): Promise<void>;
19
+ static get isAuthenticated(): boolean;
20
+ static get user(): User | null;
21
+ static get userInfo(): UserInfo | null;
22
+ static get userId(): string | null;
23
+ static get accessToken(): string | null;
24
+ static waitForAuthInit(): Promise<void>;
25
+ static ensureValidToken(): Promise<string | null>;
26
+ private static fetchUserInfo;
27
+ private static exchangeCodeForTokens;
28
+ private static refreshAccessToken;
29
+ private static openBrowser;
30
+ private static startLocalServer;
31
+ static loginFlow(): Promise<boolean>;
32
+ static signOut(): Promise<void>;
33
+ }
34
+ export {};
35
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"AASA,OAAO,EAAwE,IAAI,EAAC,MAAM,eAAe,CAAC;AAmB1G,UAAU,QAAQ;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAC,cAAc,CAAyB;IACtD,OAAO,CAAC,MAAM,CAAC,MAAM,CAA4B;IACjD,OAAO,CAAC,MAAM,CAAC,YAAY,CAA6B;IACxD,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAkB;IAErD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAI5B;IAEF,OAAO,CAAC,MAAM,CAAC,eAAe;IAU9B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAInC,OAAO,CAAC,MAAM,CAAC,qBAAqB;WAIvB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuFxC,MAAM,KAAK,eAAe,IAAI,OAAO,CAEpC;IAED,MAAM,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,CAE7B;IAED,MAAM,KAAK,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAErC;IAED,MAAM,KAAK,MAAM,IAAI,MAAM,GAAG,IAAI,CAEjC;IAED,MAAM,KAAK,WAAW,IAAI,MAAM,GAAG,IAAI,CAEtC;WAEY,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;WAMhC,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;mBAuClC,aAAa;mBAcb,qBAAqB;mBAiCrB,kBAAkB;mBAoBlB,WAAW;mBAsBX,gBAAgB;WAiDxB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;WAoG7B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAUxC"}