claude-phone-local 2.0.10 → 2.0.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-phone-local",
3
- "version": "2.0.10",
3
+ "version": "2.0.11",
4
4
  "description": "Local/offline fork of NetworkChuck's claude-phone: talk to Claude Code over 3CX/SIP with faster-whisper STT + Piper TTS in one Docker container.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -131,7 +131,12 @@ router.post('/outbound-call', async function(req, res) {
131
131
  var timeoutSeconds = req.body.timeoutSeconds || 30;
132
132
  var webhookUrl = req.body.webhookUrl;
133
133
 
134
- // Look up device configuration
134
+ // Look up device configuration. This also decides the outbound SIP
135
+ // identity/credentials (see initiateOutboundCall) - without a device, the
136
+ // call goes out as a hardcoded placeholder caller ID that 3CX has never
137
+ // provisioned and rejects with 403. Default to the registered device
138
+ // (Maya) rather than leaving deviceConfig null, since it's the only
139
+ // identity actually authorized to place calls on this SBC.
135
140
  var deviceConfig = null;
136
141
  if (deviceParam && deviceRegistry) {
137
142
  // Use get() which tries extension first, then name (case-insensitive)
@@ -148,6 +153,23 @@ router.post('/outbound-call', async function(req, res) {
148
153
  }
149
154
  }
150
155
 
156
+ if (!deviceConfig && deviceRegistry) {
157
+ // getDefault() returns a hardcoded placeholder (fake ext 9000, fake
158
+ // creds) left over from the upstream fork - using it here would trade
159
+ // one unauthorized SIP identity for another. Use the first actually
160
+ // configured device instead, since that's a real registered identity
161
+ // this SBC will accept.
162
+ var allDevices = deviceRegistry.getAllDevices ? deviceRegistry.getAllDevices() : {};
163
+ var firstConfiguredDevice = Object.values(allDevices)[0] || null;
164
+ if (firstConfiguredDevice) {
165
+ deviceConfig = firstConfiguredDevice;
166
+ logger.info('No device specified, using first configured device for outbound identity', {
167
+ device: deviceConfig.name,
168
+ extension: deviceConfig.extension
169
+ });
170
+ }
171
+ }
172
+
151
173
  // Check if infrastructure is available
152
174
  if (!srf || !mediaServer) {
153
175
  logger.error('Infrastructure not ready', {