@yoooclaw/phone-notifications 1.10.6-beta.0 → 1.10.6-beta.2

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/dist/index.cjs CHANGED
@@ -5424,7 +5424,7 @@ function readBuildInjectedVersion() {
5424
5424
  if (false) {
5425
5425
  return void 0;
5426
5426
  }
5427
- const version = "1.10.6-beta.0".trim();
5427
+ const version = "1.10.6-beta.2".trim();
5428
5428
  return version || void 0;
5429
5429
  }
5430
5430
  function readPluginVersionFromPackageJson() {
@@ -6454,15 +6454,26 @@ function resolveLightRuleTask(ctx, name) {
6454
6454
  }
6455
6455
  return null;
6456
6456
  }
6457
+ function readOptionalString(value) {
6458
+ if (typeof value !== "string") return void 0;
6459
+ const trimmed = value.trim();
6460
+ return trimmed || void 0;
6461
+ }
6462
+ function isLegacyLightRuleWithoutType(raw) {
6463
+ return raw.type === void 0 && readOptionalString(raw.name) !== void 0 && readOptionalString(raw.description) !== void 0 && Array.isArray(raw.segments);
6464
+ }
6457
6465
  function readMeta(taskDir) {
6458
6466
  const metaPath = (0, import_node_path4.join)(taskDir, "meta.json");
6459
6467
  if (!(0, import_node_fs5.existsSync)(metaPath)) return null;
6460
6468
  try {
6461
6469
  const raw = JSON.parse((0, import_node_fs5.readFileSync)(metaPath, "utf-8"));
6462
- if (raw.type !== "light-rule") return null;
6463
- if (!raw.createdAt) {
6464
- raw.createdAt = (0, import_node_fs5.statSync)(metaPath).birthtime.toISOString();
6465
- }
6470
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
6471
+ if (raw.type !== "light-rule" && !isLegacyLightRuleWithoutType(raw)) return null;
6472
+ if (!Array.isArray(raw.segments)) return null;
6473
+ const name = readOptionalString(raw.name) ?? (0, import_node_path4.basename)(taskDir);
6474
+ const description = readOptionalString(raw.description) ?? readOptionalString(raw.reason) ?? name;
6475
+ const createdAt = readOptionalString(raw.createdAt) ?? (0, import_node_fs5.statSync)(metaPath).birthtime.toISOString();
6476
+ const enabled = typeof raw.enabled === "boolean" ? raw.enabled : true;
6466
6477
  const repeatTimes = normalizeRepeatTimes({
6467
6478
  repeat: raw.repeat,
6468
6479
  repeat_times: raw.repeat_times
@@ -6470,7 +6481,13 @@ function readMeta(taskDir) {
6470
6481
  assertAncsRepeatTimes(repeatTimes);
6471
6482
  return {
6472
6483
  ...raw,
6473
- repeat_times: repeatTimes
6484
+ name,
6485
+ type: "light-rule",
6486
+ description,
6487
+ segments: raw.segments,
6488
+ repeat_times: repeatTimes,
6489
+ enabled,
6490
+ createdAt
6474
6491
  };
6475
6492
  } catch {
6476
6493
  return null;
@@ -6676,6 +6693,7 @@ function registerLightRulesGateway(api, registry, logger, rememberBroadcast) {
6676
6693
  };
6677
6694
  registerGatewayMethodWithBroadcastCapture("lightrules.list", async ({ respond }) => {
6678
6695
  try {
6696
+ registry.reload();
6679
6697
  const rules = registry.list().map((rule) => ({
6680
6698
  ...rule,
6681
6699
  id: rule.name
@@ -7229,14 +7247,21 @@ function err(code, message) {
7229
7247
  const data = { ok: false, error: { code, message } };
7230
7248
  return { content: [{ type: "text", text: JSON.stringify(data) }], details: data };
7231
7249
  }
7250
+ function registerToolWithAliases(api, tool, aliases) {
7251
+ api.registerTool(tool);
7252
+ for (const alias of aliases) {
7253
+ api.registerTool({ ...tool, name: alias });
7254
+ }
7255
+ }
7232
7256
  function registerLightRulesTools(api, registry, logger) {
7233
- api.registerTool({
7257
+ registerToolWithAliases(api, {
7234
7258
  name: "lightrules.list",
7235
7259
  label: "List Light Rules",
7236
7260
  description: '\u5217\u51FA\u6240\u6709\u706F\u6548\u89C4\u5219\uFF08\u5305\u542B enabled/disabled \u72B6\u6001\uFF09\u3002\u5F53\u7528\u6237\u8BF4"\u5217\u51FA\u706F\u6548\u89C4\u5219"\u3001"\u6709\u54EA\u4E9B\u706F\u6548\u89C4\u5219"\u3001"\u67E5\u770B\u89C4\u5219"\u7B49\u65F6\u8C03\u7528\u3002\u6CE8\u610F\uFF1A\u706F\u6548\u89C4\u5219\u7684\u6240\u6709 CRUD \u64CD\u4F5C\u5FC5\u987B\u901A\u8FC7 lightrules.* \u5DE5\u5177\u5B8C\u6210\uFF0C\u7981\u6B62\u76F4\u63A5\u7528 write/edit \u4FEE\u6539 tasks/*/meta.json\u3002',
7237
7261
  parameters: { type: "object", properties: {}, additionalProperties: false },
7238
7262
  async execute(_toolCallId, _params) {
7239
7263
  try {
7264
+ registry.reload();
7240
7265
  const rules = registry.list().map((rule) => ({ ...rule, id: rule.name }));
7241
7266
  return ok({ ok: true, rules });
7242
7267
  } catch (e) {
@@ -7244,8 +7269,8 @@ function registerLightRulesTools(api, registry, logger) {
7244
7269
  return err("INTERNAL_ERROR", e?.message ?? "Unknown error");
7245
7270
  }
7246
7271
  }
7247
- });
7248
- api.registerTool({
7272
+ }, ["lightrules_list"]);
7273
+ registerToolWithAliases(api, {
7249
7274
  name: "lightrules.create",
7250
7275
  label: "Create Light Rule",
7251
7276
  description: '\u521B\u5EFA\u4E00\u6761\u706F\u6548\u89C4\u5219\uFF0C\u6307\u5B9A\u540D\u79F0\u3001\u81EA\u7136\u8BED\u8A00\u89E6\u53D1\u63CF\u8FF0\u548C\u706F\u6548\u53C2\u6570\u3002\u5F53\u7528\u6237\u8BF4"\u521B\u5EFA\u706F\u6548\u89C4\u5219"\u3001"\u65B0\u589E\u89C4\u5219"\u7B49\u65F6\u8C03\u7528\u3002',
@@ -7298,8 +7323,8 @@ function registerLightRulesTools(api, registry, logger) {
7298
7323
  return err("INTERNAL_ERROR", e?.message ?? "Unknown error");
7299
7324
  }
7300
7325
  }
7301
- });
7302
- api.registerTool({
7326
+ }, ["lightrules_create"]);
7327
+ registerToolWithAliases(api, {
7303
7328
  name: "lightrules.update",
7304
7329
  label: "Update Light Rule",
7305
7330
  description: '\u4FEE\u6539\u706F\u6548\u89C4\u5219\uFF08\u542F\u7528/\u7981\u7528\u3001\u6539\u63CF\u8FF0\u3001\u6539\u706F\u6548\u53C2\u6570\uFF09\u3002\u5F53\u7528\u6237\u8BF4"\u7981\u7528\u67D0\u6761\u89C4\u5219"\u3001"\u542F\u7528\u89C4\u5219"\u3001"\u4FEE\u6539\u706F\u6548\u89C4\u5219"\u7B49\u65F6\u8C03\u7528\u3002',
@@ -7356,8 +7381,8 @@ function registerLightRulesTools(api, registry, logger) {
7356
7381
  return err("INTERNAL_ERROR", e?.message ?? "Unknown error");
7357
7382
  }
7358
7383
  }
7359
- });
7360
- api.registerTool({
7384
+ }, ["lightrules_update"]);
7385
+ registerToolWithAliases(api, {
7361
7386
  name: "lightrules.delete",
7362
7387
  label: "Delete Light Rule",
7363
7388
  description: '\u5220\u9664\u4E00\u6761\u706F\u6548\u89C4\u5219\uFF08\u4E0D\u53EF\u6062\u590D\uFF09\u3002\u5F53\u7528\u6237\u8BF4"\u5220\u9664\u706F\u6548\u89C4\u5219"\u3001"\u79FB\u9664\u89C4\u5219"\u7B49\u65F6\u8C03\u7528\u3002',
@@ -7383,7 +7408,7 @@ function registerLightRulesTools(api, registry, logger) {
7383
7408
  return err("INTERNAL_ERROR", e?.message ?? "Unknown error");
7384
7409
  }
7385
7410
  }
7386
- });
7411
+ }, ["lightrules_delete"]);
7387
7412
  }
7388
7413
 
7389
7414
  // src/light-rules/evaluator-job.ts
@@ -8601,7 +8626,11 @@ var LIGHT_TOOLS = [
8601
8626
  "lightrules.list",
8602
8627
  "lightrules.create",
8603
8628
  "lightrules.update",
8604
- "lightrules.delete"
8629
+ "lightrules.delete",
8630
+ "lightrules_list",
8631
+ "lightrules_create",
8632
+ "lightrules_update",
8633
+ "lightrules_delete"
8605
8634
  ];
8606
8635
  function upsertLightControlAlsoAllow(cfg) {
8607
8636
  if (!isObject(cfg.tools)) cfg.tools = {};
@@ -11740,6 +11769,7 @@ var WsProxy = class {
11740
11769
  };
11741
11770
 
11742
11771
  // src/tunnel/proxy.ts
11772
+ var RELAY_TUNNEL_GATEWAY_CLIENT_INSTANCE_ID = "phone-notifications-relay-tunnel";
11743
11773
  var MAX_AUTO_PAIRING_APPROVALS = 3;
11744
11774
  var approveDevicePairingPromise = null;
11745
11775
  var approveDevicePairingWarned = false;
@@ -12144,7 +12174,8 @@ var TunnelProxy = class {
12144
12174
  id: clientId,
12145
12175
  version: "1.0.0",
12146
12176
  platform: process.platform,
12147
- mode: clientMode
12177
+ mode: clientMode,
12178
+ instanceId: RELAY_TUNNEL_GATEWAY_CLIENT_INSTANCE_ID
12148
12179
  },
12149
12180
  role,
12150
12181
  scopes,
@@ -12481,8 +12512,24 @@ function resolveExclusiveTunnelHint(params) {
12481
12512
  if (tailscaleMode) {
12482
12513
  return `gateway.tailscale.mode=${tailscaleMode}`;
12483
12514
  }
12515
+ const remoteUrl = trimToUndefined2(configData?.gateway?.remote?.url);
12516
+ if (remoteUrl && isExternalGatewayRemoteUrl(remoteUrl)) {
12517
+ return `gateway.remote.url=${remoteUrl}`;
12518
+ }
12484
12519
  return void 0;
12485
12520
  }
12521
+ function isExternalGatewayRemoteUrl(rawUrl) {
12522
+ let host;
12523
+ try {
12524
+ host = new URL(rawUrl).hostname.toLowerCase();
12525
+ } catch {
12526
+ return false;
12527
+ }
12528
+ if (host === "localhost" || host === "::1" || host === "[::1]") {
12529
+ return false;
12530
+ }
12531
+ return !/^127(?:\.\d{1,3}){0,3}$/.test(host);
12532
+ }
12486
12533
  function registerRelayTunnelLifecycle(deps) {
12487
12534
  const {
12488
12535
  api,
@@ -13100,6 +13147,7 @@ var index_default = {
13100
13147
  let broadcastFn = null;
13101
13148
  let cronService = null;
13102
13149
  let autoUpdateLifecycle = null;
13150
+ let tunnelService = null;
13103
13151
  const openclawDir = api.runtime.state.resolveStateDir();
13104
13152
  const logger = openclawDir ? new PluginFileLogger(api.logger, openclawDir) : createVersionAwareLogger(api.logger);
13105
13153
  const lightRuleCtx = {
@@ -13126,12 +13174,34 @@ var index_default = {
13126
13174
  autoUpdateLifecycle?.notifyBroadcastReady();
13127
13175
  }
13128
13176
  }
13177
+ function isDirectMobileGatewayRequest(opts) {
13178
+ const client = opts.client?.connect?.client;
13179
+ if (!client) return false;
13180
+ if (client.instanceId === RELAY_TUNNEL_GATEWAY_CLIENT_INSTANCE_ID) {
13181
+ return false;
13182
+ }
13183
+ return client.id === "openclaw-ios" || client.id === "openclaw-android";
13184
+ }
13185
+ async function deactivateRelayForDirectGatewayRequest(method, opts) {
13186
+ if (!tunnelService || !isDirectMobileGatewayRequest(opts)) return;
13187
+ const client = opts.client?.connect?.client;
13188
+ try {
13189
+ await tunnelService.deactivateForExternalTunnel(
13190
+ `gateway method ${method} from ${client?.id ?? "unknown"}`
13191
+ );
13192
+ } catch (err2) {
13193
+ logger.warn(
13194
+ `Relay tunnel: failed to deactivate after direct gateway method ${method}: ${err2?.message ?? String(err2)}`
13195
+ );
13196
+ }
13197
+ }
13129
13198
  function registerGatewayMethodWithBroadcastCapture(method, handler) {
13130
- api.registerGatewayMethod(method, (opts) => {
13199
+ api.registerGatewayMethod(method, async (opts) => {
13131
13200
  cacheBroadcast(opts.context?.broadcast);
13132
13201
  if (opts.context?.cron) {
13133
13202
  cronService = opts.context.cron;
13134
13203
  }
13204
+ await deactivateRelayForDirectGatewayRequest(method, opts);
13135
13205
  return handler(opts);
13136
13206
  });
13137
13207
  }
@@ -13170,7 +13240,7 @@ var index_default = {
13170
13240
  lightRuleRegistry.reload();
13171
13241
  }
13172
13242
  });
13173
- const tunnelService = registerRelayTunnelLifecycle({
13243
+ tunnelService = registerRelayTunnelLifecycle({
13174
13244
  api,
13175
13245
  config,
13176
13246
  logger,
@@ -13202,7 +13272,7 @@ var index_default = {
13202
13272
  registerLightRulesGateway(api, lightRuleRegistry, logger, cacheBroadcast);
13203
13273
  registerLightRulesTools(api, lightRuleRegistry, logger);
13204
13274
  logger.info(
13205
- "\u706F\u6548\u89C4\u5219\u65B9\u6CD5\u5DF2\u6CE8\u518C: lightrules.list / lightrules.create / lightrules.update / lightrules.delete"
13275
+ "\u706F\u6548\u89C4\u5219\u65B9\u6CD5\u5DF2\u6CE8\u518C: lightrules.list/create/update/delete + lightrules_* tool aliases"
13206
13276
  );
13207
13277
  autoUpdateLifecycle = registerAutoUpdateLifecycle({
13208
13278
  api,