mirra-cc-bridge 0.1.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 +62 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +213 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/configure.d.ts +13 -0
- package/dist/commands/configure.d.ts.map +1 -0
- package/dist/commands/configure.js +101 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/commands/hook.d.ts +15 -0
- package/dist/commands/hook.d.ts.map +1 -0
- package/dist/commands/hook.js +181 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +19 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/register.d.ts +13 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +383 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/setup-hooks.d.ts +8 -0
- package/dist/commands/setup-hooks.d.ts.map +1 -0
- package/dist/commands/setup-hooks.js +114 -0
- package/dist/commands/setup-hooks.js.map +1 -0
- package/dist/commands/start.d.ts +16 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +168 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +156 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +88 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/session-manager.d.ts +72 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +315 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# mirra-cc-bridge
|
|
2
|
+
|
|
3
|
+
Bridge Claude Code to the Mirra mobile app - control your coding sessions from anywhere.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g mirra-cc-bridge
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
Just run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
mirra-cc-bridge
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
That's it! The setup wizard will guide you through:
|
|
20
|
+
1. Entering your Mirra API key (get it from the Mirra app settings)
|
|
21
|
+
2. Configuring Claude Code hooks automatically
|
|
22
|
+
|
|
23
|
+
Once set up, Claude Code output will automatically appear in your Mirra mobile app.
|
|
24
|
+
|
|
25
|
+
## Remote Control (Optional)
|
|
26
|
+
|
|
27
|
+
To control Claude Code from your phone when away from your computer:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
mirra-cc-bridge register
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This registers your PC as a Mirra resource. You'll need a tunnel URL (ngrok or Cloudflare Tunnel) for your PC to be reachable remotely.
|
|
34
|
+
|
|
35
|
+
## Commands
|
|
36
|
+
|
|
37
|
+
| Command | Description |
|
|
38
|
+
|---------|-------------|
|
|
39
|
+
| `mirra-cc-bridge` | Run setup (first time) or start the bridge server |
|
|
40
|
+
| `mirra-cc-bridge setup` | Re-run the setup wizard |
|
|
41
|
+
| `mirra-cc-bridge start` | Start the bridge HTTP server |
|
|
42
|
+
| `mirra-cc-bridge register` | Register PC for remote control |
|
|
43
|
+
| `mirra-cc-bridge status` | Show bridge status |
|
|
44
|
+
| `mirra-cc-bridge config` | Display current configuration |
|
|
45
|
+
|
|
46
|
+
## How It Works
|
|
47
|
+
|
|
48
|
+
1. **Claude Code Hooks**: When you run Claude Code locally, hooks send output to your Mirra mobile app in real-time.
|
|
49
|
+
|
|
50
|
+
2. **PC Resource** (optional): By registering your PC, the Mirra LLM can spawn Claude Code sessions on your behalf when you're away.
|
|
51
|
+
|
|
52
|
+
3. **Flow-Based Routing**: Replies from your phone are automatically routed to the correct Claude Code session.
|
|
53
|
+
|
|
54
|
+
## Requirements
|
|
55
|
+
|
|
56
|
+
- Node.js 18+
|
|
57
|
+
- Claude Code CLI installed
|
|
58
|
+
- Mirra account and API key
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Mirra Claude Code Bridge CLI
|
|
5
|
+
*
|
|
6
|
+
* Bridge Claude Code to your Mirra mobile app for remote coding sessions.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const commander_1 = require("commander");
|
|
13
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const setup_hooks_1 = require("./commands/setup-hooks");
|
|
16
|
+
const start_1 = require("./commands/start");
|
|
17
|
+
const register_1 = require("./commands/register");
|
|
18
|
+
const hook_1 = require("./commands/hook");
|
|
19
|
+
const status_1 = require("./commands/status");
|
|
20
|
+
const configure_1 = require("./commands/configure");
|
|
21
|
+
const MIRRA_ASCII = `
|
|
22
|
+
${chalk_1.default.cyan('███╗ ███╗██╗██████╗ ██████╗ █████╗ ')}
|
|
23
|
+
${chalk_1.default.cyan('████╗ ████║██║██╔══██╗██╔══██╗██╔══██╗')}
|
|
24
|
+
${chalk_1.default.cyan('██╔████╔██║██║██████╔╝██████╔╝███████║')}
|
|
25
|
+
${chalk_1.default.cyan('██║╚██╔╝██║██║██╔══██╗██╔══██╗██╔══██║')}
|
|
26
|
+
${chalk_1.default.cyan('██║ ╚═╝ ██║██║██║ ██║██║ ██║██║ ██║')}
|
|
27
|
+
${chalk_1.default.cyan('╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝')}
|
|
28
|
+
${chalk_1.default.gray(' claude code bridge v0.1.0 ')}
|
|
29
|
+
`;
|
|
30
|
+
/**
|
|
31
|
+
* Run the first-time setup wizard
|
|
32
|
+
*/
|
|
33
|
+
async function runSetupWizard() {
|
|
34
|
+
console.log(MIRRA_ASCII);
|
|
35
|
+
console.log(chalk_1.default.gray('Initializing bridge setup...\n'));
|
|
36
|
+
// Step 1: Configure API key
|
|
37
|
+
console.log(chalk_1.default.bold('[1/2]') + chalk_1.default.gray(' Configuring API key\n'));
|
|
38
|
+
await (0, configure_1.configure)({});
|
|
39
|
+
// Step 2: Setup hooks
|
|
40
|
+
console.log(chalk_1.default.bold('\n[2/2]') + chalk_1.default.gray(' Configuring Claude Code hooks\n'));
|
|
41
|
+
await (0, setup_hooks_1.setupHooks)();
|
|
42
|
+
// Mark setup as complete
|
|
43
|
+
(0, config_1.setConfigValue)('setupComplete', true);
|
|
44
|
+
console.log(chalk_1.default.bold.green('\n> Setup complete.\n'));
|
|
45
|
+
console.log(chalk_1.default.gray('Claude Code output will now sync to your Mirra app.'));
|
|
46
|
+
console.log(chalk_1.default.gray('Run ') + chalk_1.default.white('mirra-cc-bridge start') + chalk_1.default.gray(' to enable remote control.\n'));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Default action when running without a command
|
|
50
|
+
*/
|
|
51
|
+
async function defaultAction(options) {
|
|
52
|
+
// Check if this is first-time setup
|
|
53
|
+
if (!(0, config_1.isConfigured)()) {
|
|
54
|
+
await runSetupWizard();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Check if hooks are configured
|
|
58
|
+
if (!(0, config_1.hooksConfigured)()) {
|
|
59
|
+
console.log(chalk_1.default.gray('Hooks not configured. Setting them up...\n'));
|
|
60
|
+
await (0, setup_hooks_1.setupHooks)();
|
|
61
|
+
(0, config_1.setConfigValue)('setupComplete', true);
|
|
62
|
+
}
|
|
63
|
+
// Start the server
|
|
64
|
+
console.log(MIRRA_ASCII);
|
|
65
|
+
await (0, start_1.startServer)({ port: options.port || '3847' });
|
|
66
|
+
}
|
|
67
|
+
const program = new commander_1.Command();
|
|
68
|
+
program
|
|
69
|
+
.name('mirra-cc-bridge')
|
|
70
|
+
.description('Bridge Claude Code to Mirra mobile app')
|
|
71
|
+
.version('0.1.0')
|
|
72
|
+
.option('-p, --port <port>', 'Port to listen on', '3847')
|
|
73
|
+
.action(async (options) => {
|
|
74
|
+
try {
|
|
75
|
+
await defaultAction(options);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error(chalk_1.default.red('Error:'), error.message);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// Configure command
|
|
83
|
+
program
|
|
84
|
+
.command('configure')
|
|
85
|
+
.description('Configure the bridge with your Mirra API key')
|
|
86
|
+
.option('-k, --api-key <key>', 'Mirra API key')
|
|
87
|
+
.option('-d, --work-dir <dir>', 'Default working directory')
|
|
88
|
+
.action(async (options) => {
|
|
89
|
+
try {
|
|
90
|
+
await (0, configure_1.configure)(options);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error(chalk_1.default.red('Error:'), error.message);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
// Setup command (alias for the wizard)
|
|
98
|
+
program
|
|
99
|
+
.command('setup')
|
|
100
|
+
.description('Run the setup wizard')
|
|
101
|
+
.action(async () => {
|
|
102
|
+
try {
|
|
103
|
+
await runSetupWizard();
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error(chalk_1.default.red('Error:'), error.message);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
// Setup hooks command
|
|
111
|
+
program
|
|
112
|
+
.command('setup-hooks')
|
|
113
|
+
.description('Configure Claude Code hooks to send output to Mirra')
|
|
114
|
+
.action(async () => {
|
|
115
|
+
try {
|
|
116
|
+
await (0, setup_hooks_1.setupHooks)();
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error(chalk_1.default.red('Error:'), error.message);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
// Register command
|
|
124
|
+
program
|
|
125
|
+
.command('register')
|
|
126
|
+
.description('Register this PC as a Mirra resource for remote control')
|
|
127
|
+
.option('-n, --name <name>', 'Name for this PC')
|
|
128
|
+
.option('--tunnel <url>', 'Tunnel URL (from ngrok or cloudflare)')
|
|
129
|
+
.action(async (options) => {
|
|
130
|
+
if (!(0, config_1.isConfigured)()) {
|
|
131
|
+
console.log(chalk_1.default.yellow('Not configured yet. Running setup first...\n'));
|
|
132
|
+
await runSetupWizard();
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
await (0, register_1.registerPC)(options);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.error(chalk_1.default.red('Error:'), error.message);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// Start command
|
|
143
|
+
program
|
|
144
|
+
.command('start')
|
|
145
|
+
.description('Start the bridge service')
|
|
146
|
+
.option('-p, --port <port>', 'Port to listen on', '3847')
|
|
147
|
+
.action(async (options) => {
|
|
148
|
+
if (!(0, config_1.isConfigured)()) {
|
|
149
|
+
console.log(chalk_1.default.yellow('Not configured yet. Running setup first...\n'));
|
|
150
|
+
await runSetupWizard();
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
await (0, start_1.startServer)(options);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
console.error(chalk_1.default.red('Error:'), error.message);
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
// Status command
|
|
161
|
+
program
|
|
162
|
+
.command('status')
|
|
163
|
+
.description('Show bridge status and active sessions')
|
|
164
|
+
.action(async () => {
|
|
165
|
+
try {
|
|
166
|
+
await (0, status_1.showStatus)();
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.error(chalk_1.default.red('Error:'), error.message);
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// Hook command (called by Claude Code hooks)
|
|
174
|
+
program
|
|
175
|
+
.command('hook <event>')
|
|
176
|
+
.description('Handle a Claude Code hook event (internal use)')
|
|
177
|
+
.argument('[args...]', 'Additional arguments')
|
|
178
|
+
.action(async (event, args) => {
|
|
179
|
+
try {
|
|
180
|
+
await (0, hook_1.handleHook)(event, args);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
// Silent failure for hooks - don't disrupt Claude Code
|
|
184
|
+
console.error(error.message);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
// Config command
|
|
189
|
+
program
|
|
190
|
+
.command('config')
|
|
191
|
+
.description('Show current configuration')
|
|
192
|
+
.option('--path', 'Show config file path')
|
|
193
|
+
.action((options) => {
|
|
194
|
+
if (options.path) {
|
|
195
|
+
console.log((0, config_1.getConfigPath)());
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const config = (0, config_1.loadConfig)();
|
|
199
|
+
if (!config) {
|
|
200
|
+
console.log(chalk_1.default.yellow('Not configured. Run `mirra-cc-bridge configure` to set up.'));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
console.log(chalk_1.default.bold('Current configuration:'));
|
|
204
|
+
console.log(chalk_1.default.gray('─'.repeat(40)));
|
|
205
|
+
console.log(`API Key: ${config.apiKey ? chalk_1.default.green('configured') : chalk_1.default.red('not set')}`);
|
|
206
|
+
console.log(`User ID: ${config.userId || chalk_1.default.gray('not set')}`);
|
|
207
|
+
console.log(`Default Work Dir: ${config.defaultWorkDir || chalk_1.default.gray('not set')}`);
|
|
208
|
+
console.log(`PC Resource ID: ${config.pcResourceId || chalk_1.default.gray('not registered')}`);
|
|
209
|
+
console.log(`Config Path: ${chalk_1.default.gray((0, config_1.getConfigPath)())}`);
|
|
210
|
+
});
|
|
211
|
+
// Parse and run
|
|
212
|
+
program.parse();
|
|
213
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configure command - set up the bridge with API key and settings
|
|
3
|
+
*/
|
|
4
|
+
interface ConfigureOptions {
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
workDir?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Configure the bridge
|
|
10
|
+
*/
|
|
11
|
+
export declare function configure(options: ConfigureOptions): Promise<void>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=configure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../src/commands/configure.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuBD;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDxE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Configure command - set up the bridge with API key and settings
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.configure = configure;
|
|
43
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
44
|
+
const readline = __importStar(require("readline"));
|
|
45
|
+
const config_1 = require("../config");
|
|
46
|
+
/**
|
|
47
|
+
* Prompt for input
|
|
48
|
+
*/
|
|
49
|
+
function prompt(question, defaultValue) {
|
|
50
|
+
const rl = readline.createInterface({
|
|
51
|
+
input: process.stdin,
|
|
52
|
+
output: process.stdout,
|
|
53
|
+
});
|
|
54
|
+
const displayQuestion = defaultValue
|
|
55
|
+
? `${question} [${defaultValue}]: `
|
|
56
|
+
: `${question}: `;
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
rl.question(displayQuestion, (answer) => {
|
|
59
|
+
rl.close();
|
|
60
|
+
resolve(answer || defaultValue || '');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Configure the bridge
|
|
66
|
+
*/
|
|
67
|
+
async function configure(options) {
|
|
68
|
+
const existingConfig = (0, config_1.loadConfig)();
|
|
69
|
+
// Get API key
|
|
70
|
+
let apiKey = options.apiKey;
|
|
71
|
+
if (!apiKey) {
|
|
72
|
+
apiKey = await prompt('Enter your Mirra API key', existingConfig?.apiKey ? '(keep existing)' : undefined);
|
|
73
|
+
if (apiKey === '(keep existing)' && existingConfig?.apiKey) {
|
|
74
|
+
apiKey = existingConfig.apiKey;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!apiKey) {
|
|
78
|
+
throw new Error('API key is required');
|
|
79
|
+
}
|
|
80
|
+
// Validate API key format
|
|
81
|
+
if (!apiKey.startsWith('mirra_')) {
|
|
82
|
+
console.log(chalk_1.default.yellow('Warning: API key should start with "mirra_"'));
|
|
83
|
+
}
|
|
84
|
+
// Get default working directory
|
|
85
|
+
let workDir = options.workDir;
|
|
86
|
+
if (!workDir) {
|
|
87
|
+
workDir = await prompt('Default working directory', existingConfig?.defaultWorkDir || process.cwd());
|
|
88
|
+
}
|
|
89
|
+
// Save configuration
|
|
90
|
+
const config = {
|
|
91
|
+
...existingConfig,
|
|
92
|
+
apiKey,
|
|
93
|
+
defaultWorkDir: workDir,
|
|
94
|
+
};
|
|
95
|
+
(0, config_1.saveConfig)(config);
|
|
96
|
+
console.log(chalk_1.default.green('\n[+] Configuration saved'));
|
|
97
|
+
console.log(chalk_1.default.gray(` config: ${(0, config_1.getConfigPath)()}`));
|
|
98
|
+
console.log(chalk_1.default.gray(` key: ${apiKey.substring(0, 10)}...${apiKey.substring(apiKey.length - 4)}`));
|
|
99
|
+
console.log(chalk_1.default.gray(` dir: ${workDir}`));
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=configure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/commands/configure.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCH,8BAiDC;AAnFD,kDAA0B;AAC1B,mDAAqC;AACrC,sCAAkE;AAQlE;;GAEG;AACH,SAAS,MAAM,CAAC,QAAgB,EAAE,YAAqB;IACrD,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,YAAY;QAClC,CAAC,CAAC,GAAG,QAAQ,KAAK,YAAY,KAAK;QACnC,CAAC,CAAC,GAAG,QAAQ,IAAI,CAAC;IAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,EAAE;YACtC,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,IAAI,YAAY,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,SAAS,CAAC,OAAyB;IACvD,MAAM,cAAc,GAAG,IAAA,mBAAU,GAAE,CAAC;IAEpC,cAAc;IACd,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,MAAM,MAAM,CACnB,0BAA0B,EAC1B,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CACvD,CAAC;QAEF,IAAI,MAAM,KAAK,iBAAiB,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YAC3D,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC;QACjC,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,0BAA0B;IAC1B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,6CAA6C,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,gCAAgC;IAChC,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,MAAM,MAAM,CACpB,2BAA2B,EAC3B,cAAc,EAAE,cAAc,IAAI,OAAO,CAAC,GAAG,EAAE,CAChD,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,MAAM,GAAiB;QAC3B,GAAG,cAAc;QACjB,MAAM;QACN,cAAc,EAAE,OAAO;KACxB,CAAC;IAEF,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC;IAEnB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,eAAe,IAAA,sBAAa,GAAE,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAC9F,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook handler - called by Claude Code hooks to send output to Mirra
|
|
3
|
+
*
|
|
4
|
+
* This is invoked via:
|
|
5
|
+
* mirra-cc-bridge hook post-message
|
|
6
|
+
* mirra-cc-bridge hook post-tool
|
|
7
|
+
* mirra-cc-bridge hook stop
|
|
8
|
+
*
|
|
9
|
+
* Hook data is passed via stdin from Claude Code.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Main hook handler
|
|
13
|
+
*/
|
|
14
|
+
export declare function handleHook(event: string, args: string[]): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2KH;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7E"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hook handler - called by Claude Code hooks to send output to Mirra
|
|
4
|
+
*
|
|
5
|
+
* This is invoked via:
|
|
6
|
+
* mirra-cc-bridge hook post-message
|
|
7
|
+
* mirra-cc-bridge hook post-tool
|
|
8
|
+
* mirra-cc-bridge hook stop
|
|
9
|
+
*
|
|
10
|
+
* Hook data is passed via stdin from Claude Code.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.handleHook = handleHook;
|
|
14
|
+
const sdk_1 = require("@mirra-messenger/sdk");
|
|
15
|
+
const config_1 = require("../config");
|
|
16
|
+
/**
|
|
17
|
+
* Read all data from stdin
|
|
18
|
+
*/
|
|
19
|
+
async function readStdin() {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
let data = '';
|
|
22
|
+
// If stdin is not a TTY, read from it
|
|
23
|
+
if (!process.stdin.isTTY) {
|
|
24
|
+
process.stdin.setEncoding('utf-8');
|
|
25
|
+
process.stdin.on('data', (chunk) => {
|
|
26
|
+
data += chunk;
|
|
27
|
+
});
|
|
28
|
+
process.stdin.on('end', () => {
|
|
29
|
+
resolve(data);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// No stdin data
|
|
34
|
+
resolve('');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get SDK instance
|
|
40
|
+
*/
|
|
41
|
+
function getSDK() {
|
|
42
|
+
const config = (0, config_1.loadConfig)();
|
|
43
|
+
if (!config?.apiKey) {
|
|
44
|
+
throw new Error('Not configured. Run `mirra-cc-bridge configure` first.');
|
|
45
|
+
}
|
|
46
|
+
return new sdk_1.MirraSDK({
|
|
47
|
+
apiKey: config.apiKey,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get recipient ID (user's own ID for self-messaging)
|
|
52
|
+
*/
|
|
53
|
+
function getRecipientId() {
|
|
54
|
+
// First check environment variable (set when spawning via PC resource service)
|
|
55
|
+
const envRecipient = process.env.MIRRA_RECIPIENT_ID;
|
|
56
|
+
if (envRecipient) {
|
|
57
|
+
return envRecipient;
|
|
58
|
+
}
|
|
59
|
+
// Fall back to config
|
|
60
|
+
const config = (0, config_1.loadConfig)();
|
|
61
|
+
if (config?.userId) {
|
|
62
|
+
return config.userId;
|
|
63
|
+
}
|
|
64
|
+
throw new Error('Recipient ID not configured. Set MIRRA_RECIPIENT_ID env var or run `mirra-cc-bridge configure`.');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get session ID
|
|
68
|
+
*/
|
|
69
|
+
function getSessionId() {
|
|
70
|
+
// Check environment variable first
|
|
71
|
+
const envSession = process.env.MIRRA_SESSION_ID;
|
|
72
|
+
if (envSession) {
|
|
73
|
+
return envSession;
|
|
74
|
+
}
|
|
75
|
+
// Generate a default session ID based on timestamp
|
|
76
|
+
return `cc_local_${Date.now()}`;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Send a message to Mirra via the messaging adapter
|
|
80
|
+
*/
|
|
81
|
+
async function sendToMirra(message) {
|
|
82
|
+
const sdk = getSDK();
|
|
83
|
+
const recipientId = getRecipientId();
|
|
84
|
+
const sessionId = getSessionId();
|
|
85
|
+
await sdk.resources.call({
|
|
86
|
+
resourceId: 'mirra-messaging',
|
|
87
|
+
method: 'sendMessage',
|
|
88
|
+
params: {
|
|
89
|
+
recipientId,
|
|
90
|
+
content: JSON.stringify(message),
|
|
91
|
+
automation: {
|
|
92
|
+
source: 'sdk',
|
|
93
|
+
flowTitle: 'Claude Code Session',
|
|
94
|
+
// Critical for Flow-based reply routing: allows Flows to filter
|
|
95
|
+
// replies to this specific Claude Code session
|
|
96
|
+
sessionId,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Handle PostMessage hook - Claude's response text
|
|
103
|
+
*/
|
|
104
|
+
async function handlePostMessage(stdinData) {
|
|
105
|
+
if (!stdinData.trim()) {
|
|
106
|
+
return; // Nothing to send
|
|
107
|
+
}
|
|
108
|
+
const message = {
|
|
109
|
+
type: 'claude_code_output',
|
|
110
|
+
sessionId: getSessionId(),
|
|
111
|
+
timestamp: new Date().toISOString(),
|
|
112
|
+
data: {
|
|
113
|
+
content: stdinData,
|
|
114
|
+
role: 'assistant',
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
await sendToMirra(message);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Handle PostToolUse hook - tool execution results
|
|
121
|
+
*/
|
|
122
|
+
async function handlePostToolUse(stdinData, toolName) {
|
|
123
|
+
// Parse the tool use data from stdin
|
|
124
|
+
let toolData = {};
|
|
125
|
+
if (stdinData.trim()) {
|
|
126
|
+
try {
|
|
127
|
+
toolData = JSON.parse(stdinData);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// If not JSON, treat as plain text output
|
|
131
|
+
toolData = { output: stdinData };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const message = {
|
|
135
|
+
type: 'claude_code_tool',
|
|
136
|
+
sessionId: getSessionId(),
|
|
137
|
+
timestamp: new Date().toISOString(),
|
|
138
|
+
data: {
|
|
139
|
+
toolName: toolName || toolData.tool || 'unknown',
|
|
140
|
+
input: toolData.input,
|
|
141
|
+
output: toolData.output || toolData.result,
|
|
142
|
+
status: 'completed',
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
await sendToMirra(message);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Handle Stop hook - session ended
|
|
149
|
+
*/
|
|
150
|
+
async function handleStop(stdinData) {
|
|
151
|
+
const message = {
|
|
152
|
+
type: 'claude_code_status',
|
|
153
|
+
sessionId: getSessionId(),
|
|
154
|
+
timestamp: new Date().toISOString(),
|
|
155
|
+
data: {
|
|
156
|
+
status: 'stopped',
|
|
157
|
+
message: stdinData.trim() || 'Session ended',
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
await sendToMirra(message);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Main hook handler
|
|
164
|
+
*/
|
|
165
|
+
async function handleHook(event, args) {
|
|
166
|
+
const stdinData = await readStdin();
|
|
167
|
+
switch (event) {
|
|
168
|
+
case 'post-message':
|
|
169
|
+
await handlePostMessage(stdinData);
|
|
170
|
+
break;
|
|
171
|
+
case 'post-tool':
|
|
172
|
+
await handlePostToolUse(stdinData, args[0]);
|
|
173
|
+
break;
|
|
174
|
+
case 'stop':
|
|
175
|
+
await handleStop(stdinData);
|
|
176
|
+
break;
|
|
177
|
+
default:
|
|
178
|
+
throw new Error(`Unknown hook event: ${event}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command exports
|
|
3
|
+
*/
|
|
4
|
+
export { configure } from './configure';
|
|
5
|
+
export { setupHooks } from './setup-hooks';
|
|
6
|
+
export { registerPC } from './register';
|
|
7
|
+
export { startServer } from './start';
|
|
8
|
+
export { showStatus } from './status';
|
|
9
|
+
export { handleHook } from './hook';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Command exports
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.handleHook = exports.showStatus = exports.startServer = exports.registerPC = exports.setupHooks = exports.configure = void 0;
|
|
7
|
+
var configure_1 = require("./configure");
|
|
8
|
+
Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return configure_1.configure; } });
|
|
9
|
+
var setup_hooks_1 = require("./setup-hooks");
|
|
10
|
+
Object.defineProperty(exports, "setupHooks", { enumerable: true, get: function () { return setup_hooks_1.setupHooks; } });
|
|
11
|
+
var register_1 = require("./register");
|
|
12
|
+
Object.defineProperty(exports, "registerPC", { enumerable: true, get: function () { return register_1.registerPC; } });
|
|
13
|
+
var start_1 = require("./start");
|
|
14
|
+
Object.defineProperty(exports, "startServer", { enumerable: true, get: function () { return start_1.startServer; } });
|
|
15
|
+
var status_1 = require("./status");
|
|
16
|
+
Object.defineProperty(exports, "showStatus", { enumerable: true, get: function () { return status_1.showStatus; } });
|
|
17
|
+
var hook_1 = require("./hook");
|
|
18
|
+
Object.defineProperty(exports, "handleHook", { enumerable: true, get: function () { return hook_1.handleHook; } });
|
|
19
|
+
//# sourceMappingURL=index.js.map
|