@commit451/salamander 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -42
- package/bin/salamander.js +1 -1
- package/dist/commands/runner-selection.d.ts +1 -1
- package/dist/commands/runner-selection.d.ts.map +1 -1
- package/dist/commands/runner-selection.js +68 -12
- package/dist/commands/runner-selection.js.map +1 -1
- package/dist/services/auth.js +36 -36
- package/dist/services/command-listener.d.ts +1 -0
- package/dist/services/command-listener.d.ts.map +1 -1
- package/dist/services/command-listener.js +30 -7
- package/dist/services/command-listener.js.map +1 -1
- package/dist/services/crypto.d.ts +52 -0
- package/dist/services/crypto.d.ts.map +1 -0
- package/dist/services/crypto.js +104 -0
- package/dist/services/crypto.js.map +1 -0
- package/dist/services/key-manager.d.ts +45 -0
- package/dist/services/key-manager.d.ts.map +1 -0
- package/dist/services/key-manager.js +123 -0
- package/dist/services/key-manager.js.map +1 -0
- package/dist/services/multi-device-key-manager.d.ts +56 -0
- package/dist/services/multi-device-key-manager.d.ts.map +1 -0
- package/dist/services/multi-device-key-manager.js +159 -0
- package/dist/services/multi-device-key-manager.js.map +1 -0
- package/dist/services/runner.d.ts.map +1 -1
- package/dist/services/runner.js +56 -19
- package/dist/services/runner.js.map +1 -1
- package/dist/utils/storage.d.ts +5 -0
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/storage.js +14 -0
- package/dist/utils/storage.js.map +1 -1
- package/package.json +52 -52
package/README.md
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
# Salamander CLI
|
|
2
|
-
|
|
3
|
-
Never be AFK.
|
|
4
|
-
|
|
5
|
-
See [the site](https://salamander.space/) for usage.
|
|
6
|
-
|
|
7
|
-
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.
|
|
8
|
-
|
|
9
|
-
## Installation
|
|
10
|
-
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.
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
npm install -g @commit451/salamander
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Usage
|
|
17
|
-
|
|
18
|
-
### Start the CLI
|
|
19
|
-
```bash
|
|
20
|
-
salamander
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Development
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# Install dependencies
|
|
27
|
-
npm install
|
|
28
|
-
|
|
29
|
-
# Run in development mode
|
|
30
|
-
npm run dev
|
|
31
|
-
|
|
32
|
-
# Build the project
|
|
33
|
-
npm run build
|
|
34
|
-
|
|
35
|
-
# Run the built version
|
|
36
|
-
npm start
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Publish
|
|
40
|
-
```
|
|
41
|
-
npm run pub
|
|
42
|
-
```
|
|
1
|
+
# Salamander CLI
|
|
2
|
+
|
|
3
|
+
Never be AFK.
|
|
4
|
+
|
|
5
|
+
See [the site](https://salamander.space/) for usage.
|
|
6
|
+
|
|
7
|
+
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.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
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.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install -g @commit451/salamander
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
### Start the CLI
|
|
19
|
+
```bash
|
|
20
|
+
salamander
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Development
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Install dependencies
|
|
27
|
+
npm install
|
|
28
|
+
|
|
29
|
+
# Run in development mode
|
|
30
|
+
npm run dev
|
|
31
|
+
|
|
32
|
+
# Build the project
|
|
33
|
+
npm run build
|
|
34
|
+
|
|
35
|
+
# Run the built version
|
|
36
|
+
npm start
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Publish
|
|
40
|
+
```
|
|
41
|
+
npm run pub
|
|
42
|
+
```
|
package/bin/salamander.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
import('../dist/index.js').then(m => m.default()).catch(console.error);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function runnerSelectionFlow(): Promise<void>;
|
|
1
|
+
export declare function runnerSelectionFlow(checkDefault?: boolean): Promise<void>;
|
|
2
2
|
//# sourceMappingURL=runner-selection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-selection.d.ts","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner-selection.d.ts","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"AASA,wBAAsB,mBAAmB,CAAC,YAAY,GAAE,OAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA4HrF"}
|
|
@@ -4,10 +4,28 @@ import { RunnerService } from '../services/runner.js';
|
|
|
4
4
|
import { CommandListener } from '../services/command-listener.js';
|
|
5
5
|
import { createRunnerFlow } from './create-runner.js';
|
|
6
6
|
import { deleteRunnerFlow } from './delete-runner.js';
|
|
7
|
-
|
|
7
|
+
import { loadConfig, saveConfig } from '../utils/storage.js';
|
|
8
|
+
export async function runnerSelectionFlow(checkDefault = true) {
|
|
8
9
|
console.log(chalk.blue('🏃 Runner Selection'));
|
|
9
10
|
try {
|
|
10
11
|
const localRunners = await RunnerService.getAllRunners();
|
|
12
|
+
const config = await loadConfig();
|
|
13
|
+
const defaultRunnerId = config?.defaultRunnerId;
|
|
14
|
+
// Auto-start default runner on initial launch
|
|
15
|
+
if (checkDefault && defaultRunnerId) {
|
|
16
|
+
const defaultRunner = localRunners.find(r => r.id === defaultRunnerId);
|
|
17
|
+
if (defaultRunner) {
|
|
18
|
+
console.log(chalk.blue(`⭐ Auto-starting default runner: ${chalk.bold(defaultRunner.name)}`));
|
|
19
|
+
const listener = CommandListener.getInstance();
|
|
20
|
+
await listener.startListening(defaultRunner);
|
|
21
|
+
// User typed 'q', fall through to normal menu
|
|
22
|
+
return runnerSelectionFlow(false);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
console.log(chalk.yellow('⚠️ Default runner no longer exists. Clearing default setting.'));
|
|
26
|
+
await saveConfig({});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
11
29
|
if (localRunners.length === 0) {
|
|
12
30
|
console.log(chalk.yellow('⚠️ No runners found for this machine.'));
|
|
13
31
|
console.log('You need to create a runner first.');
|
|
@@ -20,8 +38,7 @@ export async function runnerSelectionFlow() {
|
|
|
20
38
|
});
|
|
21
39
|
if (shouldCreate === 'create') {
|
|
22
40
|
await createRunnerFlow();
|
|
23
|
-
|
|
24
|
-
return runnerSelectionFlow();
|
|
41
|
+
return runnerSelectionFlow(false);
|
|
25
42
|
}
|
|
26
43
|
else {
|
|
27
44
|
console.log(chalk.blue('👋 Goodbye!'));
|
|
@@ -31,25 +48,40 @@ export async function runnerSelectionFlow() {
|
|
|
31
48
|
console.log(chalk.green(`✅ Found ${localRunners.length} runner(s) for this machine`));
|
|
32
49
|
const choices = [
|
|
33
50
|
...localRunners.map(runner => ({
|
|
34
|
-
name: formatRunnerChoice(runner),
|
|
51
|
+
name: formatRunnerChoice(runner, defaultRunnerId),
|
|
35
52
|
value: `run:${runner.id}`,
|
|
36
53
|
description: `Listen for ${runner.runnerType} commands in ${runner.directory}`
|
|
37
54
|
})),
|
|
38
55
|
{ name: '➕ Create new runner', value: 'create' },
|
|
39
56
|
{ name: '🗑️ Delete runner', value: 'delete' },
|
|
40
|
-
{ name: '🚪 Exit', value: 'exit' }
|
|
41
57
|
];
|
|
58
|
+
// Add disable default option if a default is set and the runner still exists
|
|
59
|
+
if (defaultRunnerId) {
|
|
60
|
+
const defaultRunner = localRunners.find(r => r.id === defaultRunnerId);
|
|
61
|
+
if (defaultRunner) {
|
|
62
|
+
choices.push({
|
|
63
|
+
name: `🚫 Disable starting default runner (currently: ${defaultRunner.name})`,
|
|
64
|
+
value: 'disable-default'
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
choices.push({ name: '🚪 Exit', value: 'exit' });
|
|
42
69
|
const selection = await select({
|
|
43
70
|
message: 'Select a runner to start or choose an action:',
|
|
44
71
|
choices
|
|
45
72
|
});
|
|
46
73
|
if (selection === 'create') {
|
|
47
74
|
await createRunnerFlow();
|
|
48
|
-
return runnerSelectionFlow();
|
|
75
|
+
return runnerSelectionFlow(false);
|
|
49
76
|
}
|
|
50
77
|
else if (selection === 'delete') {
|
|
51
78
|
await deleteRunnerFlow();
|
|
52
|
-
return runnerSelectionFlow();
|
|
79
|
+
return runnerSelectionFlow(false);
|
|
80
|
+
}
|
|
81
|
+
else if (selection === 'disable-default') {
|
|
82
|
+
await saveConfig({});
|
|
83
|
+
console.log(chalk.green('✅ Default runner disabled. CLI will show menu on startup.'));
|
|
84
|
+
return runnerSelectionFlow(false);
|
|
53
85
|
}
|
|
54
86
|
else if (selection === 'exit') {
|
|
55
87
|
console.log(chalk.blue('👋 Goodbye!'));
|
|
@@ -59,12 +91,34 @@ export async function runnerSelectionFlow() {
|
|
|
59
91
|
const runnerId = selection.replace('run:', '');
|
|
60
92
|
const runner = localRunners.find(r => r.id === runnerId);
|
|
61
93
|
if (runner) {
|
|
62
|
-
|
|
63
|
-
await
|
|
94
|
+
// Show sub-menu for runner action
|
|
95
|
+
const action = await select({
|
|
96
|
+
message: `What would you like to do with "${runner.name}"?`,
|
|
97
|
+
choices: [
|
|
98
|
+
{ name: 'Start runner', value: 'start' },
|
|
99
|
+
{ name: 'Start and set as default (auto-start on launch)', value: 'start-default' },
|
|
100
|
+
{ name: 'Back to menu', value: 'back' },
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
if (action === 'start') {
|
|
104
|
+
const listener = CommandListener.getInstance();
|
|
105
|
+
await listener.startListening(runner);
|
|
106
|
+
return runnerSelectionFlow(false);
|
|
107
|
+
}
|
|
108
|
+
else if (action === 'start-default') {
|
|
109
|
+
await saveConfig({ defaultRunnerId: runner.id });
|
|
110
|
+
console.log(chalk.green(`⭐ "${runner.name}" set as default runner.`));
|
|
111
|
+
const listener = CommandListener.getInstance();
|
|
112
|
+
await listener.startListening(runner);
|
|
113
|
+
return runnerSelectionFlow(false);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
return runnerSelectionFlow(false);
|
|
117
|
+
}
|
|
64
118
|
}
|
|
65
119
|
else {
|
|
66
120
|
console.error(chalk.red('❌ Runner not found'));
|
|
67
|
-
return runnerSelectionFlow();
|
|
121
|
+
return runnerSelectionFlow(false);
|
|
68
122
|
}
|
|
69
123
|
}
|
|
70
124
|
}
|
|
@@ -72,7 +126,9 @@ export async function runnerSelectionFlow() {
|
|
|
72
126
|
process.exit(1);
|
|
73
127
|
}
|
|
74
128
|
}
|
|
75
|
-
function formatRunnerChoice(runner) {
|
|
76
|
-
|
|
129
|
+
function formatRunnerChoice(runner, defaultRunnerId) {
|
|
130
|
+
const isDefault = runner.id === defaultRunnerId;
|
|
131
|
+
const defaultBadge = isDefault ? chalk.yellow(' ⭐') : '';
|
|
132
|
+
return `🤖 ${chalk.bold(runner.name)} ${chalk.dim(`(${runner.directory})`)}${defaultBadge}`;
|
|
77
133
|
}
|
|
78
134
|
//# sourceMappingURL=runner-selection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-selection.js","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AACzC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAC,eAAe,EAAC,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"runner-selection.js","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"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"}
|
package/dist/services/auth.js
CHANGED
|
@@ -15,42 +15,42 @@ export class AuthService {
|
|
|
15
15
|
static WEB_APP_URL = 'https://salamander.space';
|
|
16
16
|
static generateAuthResponseHTML(isSuccess, title, message) {
|
|
17
17
|
const headingColor = isSuccess ? '#10b981' : '#f87171';
|
|
18
|
-
return `
|
|
19
|
-
<!DOCTYPE html>
|
|
20
|
-
<html>
|
|
21
|
-
<head>
|
|
22
|
-
<title>${title}</title>
|
|
23
|
-
<style>
|
|
24
|
-
body {
|
|
25
|
-
background-color: #111827;
|
|
26
|
-
color: #f9fafb;
|
|
27
|
-
font-family: 'Fira Code', 'JetBrains Mono', monospace;
|
|
28
|
-
text-align: center;
|
|
29
|
-
padding: 50px;
|
|
30
|
-
margin: 0;
|
|
31
|
-
}
|
|
32
|
-
h1 { color: ${headingColor}; }
|
|
33
|
-
.logo {
|
|
34
|
-
width: 48px;
|
|
35
|
-
height: 48px;
|
|
36
|
-
margin: 0 auto 24px;
|
|
37
|
-
background: #ff6b35;
|
|
38
|
-
border-radius: 8px;
|
|
39
|
-
display: flex;
|
|
40
|
-
align-items: center;
|
|
41
|
-
justify-content: center;
|
|
42
|
-
font-size: 24px;
|
|
43
|
-
color: white;
|
|
44
|
-
font-weight: bold;
|
|
45
|
-
}
|
|
46
|
-
</style>
|
|
47
|
-
</head>
|
|
48
|
-
<body>
|
|
49
|
-
<div class="logo">S</div>
|
|
50
|
-
<h1>${title}</h1>
|
|
51
|
-
<p>${message}</p>
|
|
52
|
-
</body>
|
|
53
|
-
</html>
|
|
18
|
+
return `
|
|
19
|
+
<!DOCTYPE html>
|
|
20
|
+
<html>
|
|
21
|
+
<head>
|
|
22
|
+
<title>${title}</title>
|
|
23
|
+
<style>
|
|
24
|
+
body {
|
|
25
|
+
background-color: #111827;
|
|
26
|
+
color: #f9fafb;
|
|
27
|
+
font-family: 'Fira Code', 'JetBrains Mono', monospace;
|
|
28
|
+
text-align: center;
|
|
29
|
+
padding: 50px;
|
|
30
|
+
margin: 0;
|
|
31
|
+
}
|
|
32
|
+
h1 { color: ${headingColor}; }
|
|
33
|
+
.logo {
|
|
34
|
+
width: 48px;
|
|
35
|
+
height: 48px;
|
|
36
|
+
margin: 0 auto 24px;
|
|
37
|
+
background: #ff6b35;
|
|
38
|
+
border-radius: 8px;
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
font-size: 24px;
|
|
43
|
+
color: white;
|
|
44
|
+
font-weight: bold;
|
|
45
|
+
}
|
|
46
|
+
</style>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<div class="logo">S</div>
|
|
50
|
+
<h1>${title}</h1>
|
|
51
|
+
<p>${message}</p>
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
54
54
|
`;
|
|
55
55
|
}
|
|
56
56
|
static async openBrowser(url) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-listener.d.ts","sourceRoot":"","sources":["../../src/services/command-listener.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAO1C,qBAAa,eAAe;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgC;IACvD,OAAO,CAAC,eAAe,CAAsC;IAC7D,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,EAAE,CAAmC;
|
|
1
|
+
{"version":3,"file":"command-listener.d.ts","sourceRoot":"","sources":["../../src/services/command-listener.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAO1C,qBAAa,eAAe;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgC;IACvD,OAAO,CAAC,eAAe,CAAsC;IAC7D,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,EAAE,CAAmC;IAC7C,OAAO,CAAC,WAAW,CAA6B;IAEhD,MAAM,CAAC,WAAW,IAAI,eAAe;IAO/B,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuJnD,OAAO,CAAC,uBAAuB;IAuEzB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBjC"}
|
|
@@ -10,6 +10,7 @@ export class CommandListener {
|
|
|
10
10
|
activeListeners = new Map();
|
|
11
11
|
isShuttingDown = false;
|
|
12
12
|
rl = null;
|
|
13
|
+
quitResolve = null;
|
|
13
14
|
static getInstance() {
|
|
14
15
|
if (!CommandListener.instance) {
|
|
15
16
|
CommandListener.instance = new CommandListener();
|
|
@@ -17,6 +18,8 @@ export class CommandListener {
|
|
|
17
18
|
return CommandListener.instance;
|
|
18
19
|
}
|
|
19
20
|
async startListening(runner) {
|
|
21
|
+
// Reset state for reuse after returning from menu
|
|
22
|
+
this.isShuttingDown = false;
|
|
20
23
|
if (this.activeListeners.has(runner.id)) {
|
|
21
24
|
console.log(chalk.yellow(`Already listening to runner "${runner.name}"`));
|
|
22
25
|
return;
|
|
@@ -58,7 +61,7 @@ export class CommandListener {
|
|
|
58
61
|
console.log(chalk.yellow(' This bypasses normal permission checks for file access and operations'));
|
|
59
62
|
console.log(chalk.yellow(' Be careful about what directories you run this in and what commands you execute'));
|
|
60
63
|
console.log('');
|
|
61
|
-
console.log(chalk.gray(`
|
|
64
|
+
console.log(chalk.gray(` Type 'q' to return to menu, or press Ctrl+C to exit`));
|
|
62
65
|
console.log(chalk.gray(` Keep in mind, if your machine goes to sleep, it won't process commands`));
|
|
63
66
|
// Set up non-blocking readline for local commands
|
|
64
67
|
this.setupLocalCommandPrompt(runner.id, encryptionCode);
|
|
@@ -133,6 +136,10 @@ export class CommandListener {
|
|
|
133
136
|
// Also handle uncaught exceptions
|
|
134
137
|
process.on('uncaughtException', cleanup);
|
|
135
138
|
process.on('unhandledRejection', cleanup);
|
|
139
|
+
// Wait until user types 'q' to return to menu
|
|
140
|
+
return new Promise((resolve) => {
|
|
141
|
+
this.quitResolve = resolve;
|
|
142
|
+
});
|
|
136
143
|
}
|
|
137
144
|
setupLocalCommandPrompt(runnerId, encryptionCode) {
|
|
138
145
|
if (this.isShuttingDown)
|
|
@@ -144,20 +151,36 @@ export class CommandListener {
|
|
|
144
151
|
output: process.stdout,
|
|
145
152
|
prompt: chalk.green('> ')
|
|
146
153
|
});
|
|
147
|
-
console.log(chalk.cyan(
|
|
154
|
+
console.log(chalk.cyan("\n💬 Enter a command, type 'q' to return to menu, or Ctrl+C to exit:"));
|
|
148
155
|
this.rl.prompt();
|
|
149
156
|
// Listen for line events (non-blocking)
|
|
150
157
|
this.rl.on('line', async (userInput) => {
|
|
151
158
|
if (this.isShuttingDown)
|
|
152
159
|
return;
|
|
160
|
+
const trimmedInput = userInput.trim();
|
|
161
|
+
// Handle quit command to return to menu
|
|
162
|
+
if (trimmedInput === 'q') {
|
|
163
|
+
console.log(chalk.blue('\nReturning to menu...'));
|
|
164
|
+
this.isShuttingDown = true;
|
|
165
|
+
await this.stopListening(runnerId);
|
|
166
|
+
// Clean up process handlers before returning to menu
|
|
167
|
+
process.removeAllListeners('SIGINT');
|
|
168
|
+
process.removeAllListeners('SIGTERM');
|
|
169
|
+
process.removeAllListeners('uncaughtException');
|
|
170
|
+
process.removeAllListeners('unhandledRejection');
|
|
171
|
+
if (this.quitResolve) {
|
|
172
|
+
this.quitResolve();
|
|
173
|
+
this.quitResolve = null;
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
153
177
|
// If user provided input, send it as a command
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
console.log(chalk.cyan(`📤 Sending command: ${command}`));
|
|
178
|
+
if (trimmedInput.length > 0) {
|
|
179
|
+
console.log(chalk.cyan(`📤 Sending command: ${trimmedInput}`));
|
|
157
180
|
try {
|
|
158
181
|
// Encrypt the command
|
|
159
|
-
const encryptResult = EncryptionService.encrypt(
|
|
160
|
-
const encryptedCommand = encryptResult.success ? encryptResult.encrypted :
|
|
182
|
+
const encryptResult = EncryptionService.encrypt(trimmedInput, encryptionCode);
|
|
183
|
+
const encryptedCommand = encryptResult.success ? encryptResult.encrypted : trimmedInput;
|
|
161
184
|
// Create a user message in Firestore
|
|
162
185
|
await RunnerService.createMessage(runnerId, {
|
|
163
186
|
content: encryptedCommand,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-listener.js","sourceRoot":"","sources":["../../src/services/command-listener.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAC,aAAa,EAAC,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAEnE,MAAM,OAAO,eAAe;IAChB,MAAM,CAAC,QAAQ,GAA2B,IAAI,CAAC;IAC/C,eAAe,GAA4B,IAAI,GAAG,EAAE,CAAC;IACrD,cAAc,GAAG,KAAK,CAAC;IACvB,EAAE,GAA8B,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"command-listener.js","sourceRoot":"","sources":["../../src/services/command-listener.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface KeyPair {
|
|
2
|
+
publicKey: string;
|
|
3
|
+
privateKey: string;
|
|
4
|
+
}
|
|
5
|
+
export interface EncryptedMessage {
|
|
6
|
+
encryptedData: string;
|
|
7
|
+
iv: string;
|
|
8
|
+
tag: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class CryptoService {
|
|
11
|
+
private static readonly ALGORITHM;
|
|
12
|
+
private static readonly IV_LENGTH;
|
|
13
|
+
private static readonly TAG_LENGTH;
|
|
14
|
+
private static readonly KEY_LENGTH;
|
|
15
|
+
/**
|
|
16
|
+
* Generate an ECDH key pair for key exchange
|
|
17
|
+
*/
|
|
18
|
+
static generateECDHKeyPair(): KeyPair;
|
|
19
|
+
/**
|
|
20
|
+
* Derive a shared secret from ECDH key exchange
|
|
21
|
+
*/
|
|
22
|
+
static deriveSharedSecret(privateKey: string, publicKey: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Encrypt a message using AES-256-GCM
|
|
25
|
+
*/
|
|
26
|
+
static encrypt(message: string, key: string): EncryptedMessage;
|
|
27
|
+
/**
|
|
28
|
+
* Decrypt a message using AES-256-GCM
|
|
29
|
+
*/
|
|
30
|
+
static decrypt(encryptedMessage: EncryptedMessage, key: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Generate a random 256-bit key for symmetric encryption
|
|
33
|
+
*/
|
|
34
|
+
static generateRandomKey(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Check if a message appears to be encrypted
|
|
37
|
+
*/
|
|
38
|
+
static isEncrypted(message: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Safely encrypt a message, handling both string and object inputs
|
|
41
|
+
*/
|
|
42
|
+
static safeEncrypt(data: any, key: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Safely decrypt a message, throwing error if decryption fails
|
|
45
|
+
*/
|
|
46
|
+
static safeDecrypt(encryptedData: string, key: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Create a hash of the key for identification purposes
|
|
49
|
+
*/
|
|
50
|
+
static createKeyHash(key: string): string;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/services/crypto.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAM;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAM;IACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAM;IAExC;;OAEG;IACH,MAAM,CAAC,mBAAmB,IAAI,OAAO;IAUrC;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAYxE;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB;IAmB9D;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAevE;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,MAAM;IAKlC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAS5C;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAMlD;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAS9D;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAG5C"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as crypto from 'node:crypto';
|
|
2
|
+
export class CryptoService {
|
|
3
|
+
static ALGORITHM = 'aes-256-gcm';
|
|
4
|
+
static IV_LENGTH = 16;
|
|
5
|
+
static TAG_LENGTH = 16;
|
|
6
|
+
static KEY_LENGTH = 32;
|
|
7
|
+
/**
|
|
8
|
+
* Generate an ECDH key pair for key exchange
|
|
9
|
+
*/
|
|
10
|
+
static generateECDHKeyPair() {
|
|
11
|
+
const ecdh = crypto.createECDH('secp256k1');
|
|
12
|
+
ecdh.generateKeys();
|
|
13
|
+
return {
|
|
14
|
+
publicKey: ecdh.getPublicKey('base64'),
|
|
15
|
+
privateKey: ecdh.getPrivateKey('base64')
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Derive a shared secret from ECDH key exchange
|
|
20
|
+
*/
|
|
21
|
+
static deriveSharedSecret(privateKey, publicKey) {
|
|
22
|
+
const ecdh = crypto.createECDH('secp256k1');
|
|
23
|
+
ecdh.setPrivateKey(privateKey, 'base64');
|
|
24
|
+
const sharedSecret = ecdh.computeSecret(publicKey, 'base64');
|
|
25
|
+
// Use HKDF to derive a proper encryption key
|
|
26
|
+
const derivedKey = crypto.hkdfSync('sha256', sharedSecret, '', 'salamander-e2e-encryption', CryptoService.KEY_LENGTH);
|
|
27
|
+
return Buffer.from(derivedKey).toString('base64');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Encrypt a message using AES-256-GCM
|
|
31
|
+
*/
|
|
32
|
+
static encrypt(message, key) {
|
|
33
|
+
const keyBuffer = Buffer.from(key, 'base64');
|
|
34
|
+
const iv = crypto.randomBytes(CryptoService.IV_LENGTH);
|
|
35
|
+
const cipher = crypto.createCipheriv(CryptoService.ALGORITHM, keyBuffer, iv);
|
|
36
|
+
cipher.setAAD(Buffer.from('salamander'));
|
|
37
|
+
let encryptedData = cipher.update(message, 'utf8', 'base64');
|
|
38
|
+
encryptedData += cipher.final('base64');
|
|
39
|
+
const tag = cipher.getAuthTag();
|
|
40
|
+
return {
|
|
41
|
+
encryptedData,
|
|
42
|
+
iv: iv.toString('base64'),
|
|
43
|
+
tag: tag.toString('base64')
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Decrypt a message using AES-256-GCM
|
|
48
|
+
*/
|
|
49
|
+
static decrypt(encryptedMessage, key) {
|
|
50
|
+
const keyBuffer = Buffer.from(key, 'base64');
|
|
51
|
+
const iv = Buffer.from(encryptedMessage.iv, 'base64');
|
|
52
|
+
const tag = Buffer.from(encryptedMessage.tag, 'base64');
|
|
53
|
+
const decipher = crypto.createDecipheriv(CryptoService.ALGORITHM, keyBuffer, iv);
|
|
54
|
+
decipher.setAAD(Buffer.from('salamander'));
|
|
55
|
+
decipher.setAuthTag(tag);
|
|
56
|
+
let decryptedData = decipher.update(encryptedMessage.encryptedData, 'base64', 'utf8');
|
|
57
|
+
decryptedData += decipher.final('utf8');
|
|
58
|
+
return decryptedData;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generate a random 256-bit key for symmetric encryption
|
|
62
|
+
*/
|
|
63
|
+
static generateRandomKey() {
|
|
64
|
+
const key = crypto.randomBytes(CryptoService.KEY_LENGTH);
|
|
65
|
+
return key.toString('base64');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if a message appears to be encrypted
|
|
69
|
+
*/
|
|
70
|
+
static isEncrypted(message) {
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(message);
|
|
73
|
+
return parsed.encryptedData && parsed.iv && parsed.tag;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Safely encrypt a message, handling both string and object inputs
|
|
81
|
+
*/
|
|
82
|
+
static safeEncrypt(data, key) {
|
|
83
|
+
const message = typeof data === 'string' ? data : JSON.stringify(data);
|
|
84
|
+
const encrypted = this.encrypt(message, key);
|
|
85
|
+
return JSON.stringify(encrypted);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Safely decrypt a message, throwing error if decryption fails
|
|
89
|
+
*/
|
|
90
|
+
static safeDecrypt(encryptedData, key) {
|
|
91
|
+
if (!this.isEncrypted(encryptedData)) {
|
|
92
|
+
throw new Error('Message is not encrypted - encryption is required');
|
|
93
|
+
}
|
|
94
|
+
const encryptedMessage = JSON.parse(encryptedData);
|
|
95
|
+
return this.decrypt(encryptedMessage, key);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Create a hash of the key for identification purposes
|
|
99
|
+
*/
|
|
100
|
+
static createKeyHash(key) {
|
|
101
|
+
return crypto.createHash('sha256').update(key).digest('hex').substring(0, 16);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/services/crypto.ts"],"names":[],"mappings":"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"}
|