@yoooclaw/phone-notifications 1.6.2 → 1.7.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/dist/index.js CHANGED
@@ -3647,7 +3647,7 @@ var require_websocket_server = __commonJS({
3647
3647
  });
3648
3648
 
3649
3649
  // src/index.ts
3650
- import { readFileSync as readFileSync13 } from "fs";
3650
+ import { readFileSync as readFileSync14 } from "fs";
3651
3651
  import { basename as basename2, dirname as dirname5 } from "path";
3652
3652
 
3653
3653
  // src/light/protocol.ts
@@ -3793,8 +3793,75 @@ function quantizeWindow(value) {
3793
3793
  import { randomUUID } from "crypto";
3794
3794
 
3795
3795
  // src/env.ts
3796
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
3797
- import { join, dirname } from "path";
3796
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
3797
+ import { dirname } from "path";
3798
+
3799
+ // src/host.ts
3800
+ import { existsSync, readFileSync } from "fs";
3801
+ import { join } from "path";
3802
+ function trimToUndefined(value) {
3803
+ if (typeof value !== "string") {
3804
+ return void 0;
3805
+ }
3806
+ const trimmed = value.trim();
3807
+ return trimmed || void 0;
3808
+ }
3809
+ function homeDir() {
3810
+ return process.env.HOME || process.env.USERPROFILE || "/tmp";
3811
+ }
3812
+ function candidateMetaPaths() {
3813
+ const home = homeDir();
3814
+ return [
3815
+ join(home, ".qclaw", "qclaw.json"),
3816
+ join(home, ".qclow", "qclaw.json")
3817
+ ];
3818
+ }
3819
+ function loadQClawMeta() {
3820
+ for (const metaPath of candidateMetaPaths()) {
3821
+ if (!existsSync(metaPath)) {
3822
+ continue;
3823
+ }
3824
+ try {
3825
+ const parsed = JSON.parse(readFileSync(metaPath, "utf-8"));
3826
+ return {
3827
+ stateDir: trimToUndefined(parsed?.stateDir),
3828
+ configPath: trimToUndefined(parsed?.configPath)
3829
+ };
3830
+ } catch {
3831
+ }
3832
+ }
3833
+ return void 0;
3834
+ }
3835
+ function resolveStateDirFromEnv() {
3836
+ return trimToUndefined(process.env.OPENCLAW_STATE_DIR) ?? trimToUndefined(process.env.QCLAW_STATE_DIR) ?? trimToUndefined(process.env.OPENCLAW_ROOT) ?? trimToUndefined(process.env.OPENCLAW_HOME) ?? trimToUndefined(process.env.QCLAW_HOME);
3837
+ }
3838
+ function resolveStateDir() {
3839
+ const envDir = resolveStateDirFromEnv();
3840
+ if (envDir) {
3841
+ return envDir;
3842
+ }
3843
+ const meta = loadQClawMeta();
3844
+ if (meta?.stateDir) {
3845
+ return meta.stateDir;
3846
+ }
3847
+ return join(homeDir(), ".openclaw");
3848
+ }
3849
+ function resolveConfigPath(stateDir = resolveStateDir()) {
3850
+ const envConfigPath = trimToUndefined(process.env.OPENCLAW_CONFIG_PATH) ?? trimToUndefined(process.env.QCLAW_CONFIG_PATH);
3851
+ if (envConfigPath) {
3852
+ return envConfigPath;
3853
+ }
3854
+ const meta = loadQClawMeta();
3855
+ if (meta?.configPath && (!meta.stateDir || !stateDir || meta.stateDir === stateDir)) {
3856
+ return meta.configPath;
3857
+ }
3858
+ return join(stateDir, "openclaw.json");
3859
+ }
3860
+ function resolveStateFile(filename) {
3861
+ return join(resolveStateDir(), filename);
3862
+ }
3863
+
3864
+ // src/env.ts
3798
3865
  var ENV_CONFIG = {
3799
3866
  development: {
3800
3867
  lightApiUrl: "https://openclaw-service-dev.yoootek.com/api/message/tob/sendMessage",
@@ -3809,14 +3876,13 @@ var ENV_CONFIG = {
3809
3876
  };
3810
3877
  var VALID_ENVS = new Set(Object.keys(ENV_CONFIG));
3811
3878
  function envFilePath() {
3812
- const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
3813
- return join(home, ".openclaw", "env.json");
3879
+ return resolveStateFile("env.json");
3814
3880
  }
3815
3881
  function loadEnvName() {
3816
3882
  const filePath = envFilePath();
3817
- if (!existsSync(filePath)) return "production";
3883
+ if (!existsSync2(filePath)) return "production";
3818
3884
  try {
3819
- const data = JSON.parse(readFileSync(filePath, "utf-8"));
3885
+ const data = JSON.parse(readFileSync2(filePath, "utf-8"));
3820
3886
  if (data.env && VALID_ENVS.has(data.env)) return data.env;
3821
3887
  } catch {
3822
3888
  }
@@ -3887,27 +3953,26 @@ async function sendLightEffect(apiKey, segments, logger, repeat) {
3887
3953
  }
3888
3954
 
3889
3955
  // src/notification/app-name-map.ts
3890
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
3891
- import { join as join3 } from "path";
3956
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
3957
+ import { join as join2 } from "path";
3892
3958
 
3893
3959
  // src/auth/credentials.ts
3894
3960
  import {
3895
- existsSync as existsSync2,
3961
+ existsSync as existsSync3,
3896
3962
  mkdirSync as mkdirSync2,
3897
- readFileSync as readFileSync2,
3963
+ readFileSync as readFileSync3,
3898
3964
  writeFileSync as writeFileSync2,
3899
3965
  watch
3900
3966
  } from "fs";
3901
- import { join as join2, dirname as dirname2, basename } from "path";
3967
+ import { dirname as dirname2, basename } from "path";
3902
3968
  function credentialsPath() {
3903
- const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
3904
- return join2(home, ".openclaw", "credentials.json");
3969
+ return resolveStateFile("credentials.json");
3905
3970
  }
3906
3971
  function readCredentials() {
3907
3972
  const path2 = credentialsPath();
3908
- if (!existsSync2(path2)) return {};
3973
+ if (!existsSync3(path2)) return {};
3909
3974
  try {
3910
- return JSON.parse(readFileSync2(path2, "utf-8"));
3975
+ return JSON.parse(readFileSync3(path2, "utf-8"));
3911
3976
  } catch {
3912
3977
  return {};
3913
3978
  }
@@ -3928,7 +3993,7 @@ function requireApiKey() {
3928
3993
  const apiKey = loadApiKey();
3929
3994
  if (!apiKey) {
3930
3995
  throw new Error(
3931
- "API Key \u672A\u8BBE\u7F6E\uFF0C\u8BF7\u5148\u6267\u884C openclaw ntf auth set-api-key <apiKey>\uFF08\u82E5 ntf \u547D\u4EE4\u51B2\u7A81\uFF0C\u53EF\u4F7F\u7528 openclaw phone-notifications auth set-api-key <apiKey>\uFF09"
3996
+ `API Key \u672A\u8BBE\u7F6E\uFF0C\u8BF7\u5148\u5199\u5165 ${credentialsPath()}\uFF0C\u6216\u901A\u8FC7\u5BBF\u4E3B CLI \u6267\u884C ntf auth set-api-key <apiKey>`
3932
3997
  );
3933
3998
  }
3934
3999
  return apiKey;
@@ -3977,7 +4042,7 @@ function isAppNameMapApiResponse(v) {
3977
4042
  );
3978
4043
  }
3979
4044
  function getCachePath(stateDir) {
3980
- return join3(stateDir, "plugins", PLUGIN_STATE_DIR, CACHE_FILE);
4045
+ return join2(stateDir, "plugins", PLUGIN_STATE_DIR, CACHE_FILE);
3981
4046
  }
3982
4047
  function createAppNameMapProvider(opts) {
3983
4048
  const { stateDir, logger } = opts;
@@ -3989,9 +4054,9 @@ function createAppNameMapProvider(opts) {
3989
4054
  let inFlightFetch = null;
3990
4055
  function loadFromDisk() {
3991
4056
  const path2 = getCachePath(stateDir);
3992
- if (!existsSync3(path2)) return;
4057
+ if (!existsSync4(path2)) return;
3993
4058
  try {
3994
- const raw = JSON.parse(readFileSync3(path2, "utf-8"));
4059
+ const raw = JSON.parse(readFileSync4(path2, "utf-8"));
3995
4060
  if (!isRecordOfStrings(raw)) return;
3996
4061
  map.clear();
3997
4062
  for (const [k, v] of Object.entries(raw)) map.set(k, v);
@@ -4035,7 +4100,7 @@ function createAppNameMapProvider(opts) {
4035
4100
  logger.warn("[app-name-map] refresh succeeded but got 0 entries");
4036
4101
  return;
4037
4102
  }
4038
- const dir = join3(stateDir, "plugins", PLUGIN_STATE_DIR);
4103
+ const dir = join2(stateDir, "plugins", PLUGIN_STATE_DIR);
4039
4104
  mkdirSync3(dir, { recursive: true });
4040
4105
  const cachePath = getCachePath(stateDir);
4041
4106
  writeFileSync3(cachePath, JSON.stringify(Object.fromEntries(map), null, 2), "utf-8");
@@ -4087,19 +4152,19 @@ import {
4087
4152
  mkdirSync as mkdirSync4,
4088
4153
  appendFileSync,
4089
4154
  readdirSync,
4090
- readFileSync as readFileSync4,
4155
+ readFileSync as readFileSync5,
4091
4156
  writeFileSync as writeFileSync4,
4092
- existsSync as existsSync4,
4157
+ existsSync as existsSync5,
4093
4158
  rmSync,
4094
4159
  constants
4095
4160
  } from "fs";
4096
4161
  import { createHash } from "crypto";
4097
- import { join as join4 } from "path";
4162
+ import { join as join3 } from "path";
4098
4163
  var NOTIFICATION_DIR_NAME = "notifications";
4099
4164
  var ID_INDEX_DIR_NAME = ".ids";
4100
4165
  var CONTENT_KEY_INDEX_DIR_NAME = ".keys";
4101
4166
  function getStateFallbackNotificationDir(stateDir) {
4102
- return join4(stateDir, "plugins", "phone-notifications", NOTIFICATION_DIR_NAME);
4167
+ return join3(stateDir, "plugins", "phone-notifications", NOTIFICATION_DIR_NAME);
4103
4168
  }
4104
4169
  function ensureWritableDirectory(dir) {
4105
4170
  try {
@@ -4117,7 +4182,7 @@ function resolveNotificationStorageDir(ctx, logger) {
4117
4182
  return stateNotifDir;
4118
4183
  }
4119
4184
  if (ctx.workspaceDir) {
4120
- const workspaceDir = join4(ctx.workspaceDir, NOTIFICATION_DIR_NAME);
4185
+ const workspaceDir = join3(ctx.workspaceDir, NOTIFICATION_DIR_NAME);
4121
4186
  if (ensureWritableDirectory(workspaceDir)) {
4122
4187
  logger.warn(
4123
4188
  `stateDir \u4E0D\u53EF\u7528\uFF0C\u901A\u77E5\u5DF2\u56DE\u9000\u5230 workspace \u8DEF\u5F84: ${workspaceDir}`
@@ -4132,8 +4197,8 @@ var NotificationStorage = class {
4132
4197
  this.config = config;
4133
4198
  this.logger = logger;
4134
4199
  this.dir = dir;
4135
- this.idIndexDir = join4(dir, ID_INDEX_DIR_NAME);
4136
- this.contentKeyIndexDir = join4(dir, CONTENT_KEY_INDEX_DIR_NAME);
4200
+ this.idIndexDir = join3(dir, ID_INDEX_DIR_NAME);
4201
+ this.contentKeyIndexDir = join3(dir, CONTENT_KEY_INDEX_DIR_NAME);
4137
4202
  this.resolveDisplayName = resolveDisplayName;
4138
4203
  }
4139
4204
  dir;
@@ -4170,7 +4235,7 @@ var NotificationStorage = class {
4170
4235
  return "invalid";
4171
4236
  }
4172
4237
  const dateKey = this.formatDate(ts);
4173
- const filePath = join4(this.dir, `${dateKey}.json`);
4238
+ const filePath = join3(this.dir, `${dateKey}.json`);
4174
4239
  const normalizedId = typeof n.id === "string" ? n.id.trim() : "";
4175
4240
  const entry = this.buildStoredNotification(n);
4176
4241
  return this.withDateWriteLock(dateKey, async () => {
@@ -4224,7 +4289,7 @@ var NotificationStorage = class {
4224
4289
  return `${year}-${month}-${day}`;
4225
4290
  }
4226
4291
  getIdIndexPath(dateKey) {
4227
- return join4(this.idIndexDir, `${dateKey}.ids`);
4292
+ return join3(this.idIndexDir, `${dateKey}.ids`);
4228
4293
  }
4229
4294
  getIdSet(dateKey) {
4230
4295
  const cached = this.idCache.get(dateKey);
@@ -4233,8 +4298,8 @@ var NotificationStorage = class {
4233
4298
  }
4234
4299
  const idPath = this.getIdIndexPath(dateKey);
4235
4300
  const ids = /* @__PURE__ */ new Set();
4236
- if (existsSync4(idPath)) {
4237
- const lines = readFileSync4(idPath, "utf-8").split(/\r?\n/);
4301
+ if (existsSync5(idPath)) {
4302
+ const lines = readFileSync5(idPath, "utf-8").split(/\r?\n/);
4238
4303
  for (const line of lines) {
4239
4304
  const id = line.trim();
4240
4305
  if (id) {
@@ -4246,7 +4311,7 @@ var NotificationStorage = class {
4246
4311
  return ids;
4247
4312
  }
4248
4313
  getContentKeyIndexPath(dateKey) {
4249
- return join4(this.contentKeyIndexDir, `${dateKey}.keys`);
4314
+ return join3(this.contentKeyIndexDir, `${dateKey}.keys`);
4250
4315
  }
4251
4316
  getContentKeySet(dateKey, filePath) {
4252
4317
  const cached = this.contentKeyCache.get(dateKey);
@@ -4255,15 +4320,15 @@ var NotificationStorage = class {
4255
4320
  }
4256
4321
  const keyPath = this.getContentKeyIndexPath(dateKey);
4257
4322
  const keys = /* @__PURE__ */ new Set();
4258
- if (existsSync4(keyPath)) {
4259
- const lines = readFileSync4(keyPath, "utf-8").split(/\r?\n/);
4323
+ if (existsSync5(keyPath)) {
4324
+ const lines = readFileSync5(keyPath, "utf-8").split(/\r?\n/);
4260
4325
  for (const line of lines) {
4261
4326
  const key = line.trim();
4262
4327
  if (key) {
4263
4328
  keys.add(key);
4264
4329
  }
4265
4330
  }
4266
- } else if (existsSync4(filePath)) {
4331
+ } else if (existsSync5(filePath)) {
4267
4332
  for (const item of this.readStoredNotifications(filePath)) {
4268
4333
  keys.add(this.buildNotificationContentKey(item));
4269
4334
  }
@@ -4306,11 +4371,11 @@ var NotificationStorage = class {
4306
4371
  return createHash("sha256").update(entry.appName).update("").update(entry.title).update("").update(entry.content).digest("hex");
4307
4372
  }
4308
4373
  readStoredNotifications(filePath) {
4309
- if (!existsSync4(filePath)) {
4374
+ if (!existsSync5(filePath)) {
4310
4375
  return [];
4311
4376
  }
4312
4377
  try {
4313
- const parsed = JSON.parse(readFileSync4(filePath, "utf-8"));
4378
+ const parsed = JSON.parse(readFileSync5(filePath, "utf-8"));
4314
4379
  return Array.isArray(parsed) ? parsed : [];
4315
4380
  } catch {
4316
4381
  return [];
@@ -4351,10 +4416,10 @@ var NotificationStorage = class {
4351
4416
  if (entry.isFile()) {
4352
4417
  const match = dateFilePattern.exec(entry.name);
4353
4418
  if (match && match[1] < cutoffDate) {
4354
- rmSync(join4(this.dir, entry.name), { force: true });
4419
+ rmSync(join3(this.dir, entry.name), { force: true });
4355
4420
  }
4356
4421
  } else if (entry.isDirectory() && dateDirPattern.test(entry.name) && entry.name < cutoffDate) {
4357
- rmSync(join4(this.dir, entry.name), { recursive: true, force: true });
4422
+ rmSync(join3(this.dir, entry.name), { recursive: true, force: true });
4358
4423
  }
4359
4424
  }
4360
4425
  } catch {
@@ -4367,7 +4432,7 @@ var NotificationStorage = class {
4367
4432
  if (!entry.isFile()) continue;
4368
4433
  const match = /^(\d{4}-\d{2}-\d{2})\.ids$/.exec(entry.name);
4369
4434
  if (match && match[1] < cutoffDate) {
4370
- rmSync(join4(this.idIndexDir, entry.name), { force: true });
4435
+ rmSync(join3(this.idIndexDir, entry.name), { force: true });
4371
4436
  this.idCache.delete(match[1]);
4372
4437
  }
4373
4438
  }
@@ -4381,7 +4446,7 @@ var NotificationStorage = class {
4381
4446
  if (!entry.isFile()) continue;
4382
4447
  const match = /^(\d{4}-\d{2}-\d{2})\.keys$/.exec(entry.name);
4383
4448
  if (match && match[1] < cutoffDate) {
4384
- rmSync(join4(this.contentKeyIndexDir, entry.name), { force: true });
4449
+ rmSync(join3(this.contentKeyIndexDir, entry.name), { force: true });
4385
4450
  this.contentKeyCache.delete(match[1]);
4386
4451
  }
4387
4452
  }
@@ -4396,24 +4461,24 @@ var NotificationStorage = class {
4396
4461
  };
4397
4462
 
4398
4463
  // src/cli/auth.ts
4399
- import { existsSync as existsSync6, rmSync as rmSync2 } from "fs";
4464
+ import { existsSync as existsSync7, rmSync as rmSync2 } from "fs";
4400
4465
 
4401
4466
  // src/cli/helpers.ts
4402
- import { existsSync as existsSync5, readFileSync as readFileSync5, readdirSync as readdirSync2 } from "fs";
4403
- import { join as join5 } from "path";
4467
+ import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync2 } from "fs";
4468
+ import { join as join4 } from "path";
4404
4469
  function resolveNotificationsDir(ctx) {
4405
4470
  if (ctx.stateDir) {
4406
- const dir = join5(
4471
+ const dir = join4(
4407
4472
  ctx.stateDir,
4408
4473
  "plugins",
4409
4474
  "phone-notifications",
4410
4475
  "notifications"
4411
4476
  );
4412
- if (existsSync5(dir)) return dir;
4477
+ if (existsSync6(dir)) return dir;
4413
4478
  }
4414
4479
  if (ctx.workspaceDir) {
4415
- const dir = join5(ctx.workspaceDir, "notifications");
4416
- if (existsSync5(dir)) return dir;
4480
+ const dir = join4(ctx.workspaceDir, "notifications");
4481
+ if (existsSync6(dir)) return dir;
4417
4482
  }
4418
4483
  return null;
4419
4484
  }
@@ -4428,10 +4493,10 @@ function listDateKeys(dir) {
4428
4493
  return keys.sort().reverse();
4429
4494
  }
4430
4495
  function readDateFile(dir, dateKey) {
4431
- const filePath = join5(dir, `${dateKey}.json`);
4432
- if (!existsSync5(filePath)) return [];
4496
+ const filePath = join4(dir, `${dateKey}.json`);
4497
+ if (!existsSync6(filePath)) return [];
4433
4498
  try {
4434
- return JSON.parse(readFileSync5(filePath, "utf-8"));
4499
+ return JSON.parse(readFileSync6(filePath, "utf-8"));
4435
4500
  } catch {
4436
4501
  return [];
4437
4502
  }
@@ -4496,7 +4561,7 @@ function registerAuthCli(program) {
4496
4561
  });
4497
4562
  auth.command("clear").description("\u6E05\u9664\u5DF2\u4FDD\u5B58\u7684\u8BA4\u8BC1\u4FE1\u606F").action(() => {
4498
4563
  const path2 = credentialsPath();
4499
- if (existsSync6(path2)) {
4564
+ if (existsSync7(path2)) {
4500
4565
  const creds = readCredentials();
4501
4566
  delete creds.apiKey;
4502
4567
  delete creds.token;
@@ -4596,16 +4661,16 @@ function registerNtfStats(ntf, ctx) {
4596
4661
  }
4597
4662
 
4598
4663
  // src/cli/ntf-sync.ts
4599
- import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
4600
- import { join as join6 } from "path";
4664
+ import { existsSync as existsSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
4665
+ import { join as join5 } from "path";
4601
4666
  function checkpointPath(dir) {
4602
- return join6(dir, ".checkpoint.json");
4667
+ return join5(dir, ".checkpoint.json");
4603
4668
  }
4604
4669
  function readCheckpoint(dir) {
4605
4670
  const p = checkpointPath(dir);
4606
- if (!existsSync7(p)) return {};
4671
+ if (!existsSync8(p)) return {};
4607
4672
  try {
4608
- return JSON.parse(readFileSync6(p, "utf-8"));
4673
+ return JSON.parse(readFileSync7(p, "utf-8"));
4609
4674
  } catch {
4610
4675
  return {};
4611
4676
  }
@@ -4685,30 +4750,30 @@ function registerNtfSync(ntf, ctx) {
4685
4750
 
4686
4751
  // src/cli/ntf-monitor.ts
4687
4752
  import {
4688
- existsSync as existsSync8,
4753
+ existsSync as existsSync9,
4689
4754
  mkdirSync as mkdirSync5,
4690
- readFileSync as readFileSync7,
4755
+ readFileSync as readFileSync8,
4691
4756
  writeFileSync as writeFileSync6,
4692
4757
  rmSync as rmSync3,
4693
4758
  readdirSync as readdirSync3
4694
4759
  } from "fs";
4695
- import { join as join7 } from "path";
4760
+ import { join as join6 } from "path";
4696
4761
  function tasksDir(ctx) {
4697
4762
  const base = ctx.workspaceDir || ctx.stateDir;
4698
4763
  if (!base) throw new Error("workspaceDir and stateDir both unavailable");
4699
- return join7(base, "tasks");
4764
+ return join6(base, "tasks");
4700
4765
  }
4701
4766
  function readMeta(taskDir) {
4702
- const metaPath = join7(taskDir, "meta.json");
4703
- if (!existsSync8(metaPath)) return null;
4767
+ const metaPath = join6(taskDir, "meta.json");
4768
+ if (!existsSync9(metaPath)) return null;
4704
4769
  try {
4705
- return JSON.parse(readFileSync7(metaPath, "utf-8"));
4770
+ return JSON.parse(readFileSync8(metaPath, "utf-8"));
4706
4771
  } catch {
4707
4772
  return null;
4708
4773
  }
4709
4774
  }
4710
4775
  function writeMeta(taskDir, meta) {
4711
- writeFileSync6(join7(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
4776
+ writeFileSync6(join6(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
4712
4777
  }
4713
4778
  function generateFetchPy(name, matchRules) {
4714
4779
  const appName = matchRules.appName || "";
@@ -4785,27 +4850,27 @@ function registerNtfMonitor(ntf, ctx) {
4785
4850
  const monitor = ntf.command("monitor").description("\u901A\u77E5\u76D1\u63A7\u4EFB\u52A1\u7BA1\u7406");
4786
4851
  monitor.command("list").description("\u5217\u51FA\u6240\u6709\u76D1\u63A7\u4EFB\u52A1").action(() => {
4787
4852
  const dir = tasksDir(ctx);
4788
- if (!existsSync8(dir)) {
4853
+ if (!existsSync9(dir)) {
4789
4854
  output({ ok: true, tasks: [] });
4790
4855
  return;
4791
4856
  }
4792
4857
  const tasks = [];
4793
4858
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
4794
4859
  if (!entry.isDirectory()) continue;
4795
- const meta = readMeta(join7(dir, entry.name));
4860
+ const meta = readMeta(join6(dir, entry.name));
4796
4861
  if (meta) tasks.push(meta);
4797
4862
  }
4798
4863
  output({ ok: true, tasks });
4799
4864
  });
4800
4865
  monitor.command("show <name>").description("\u67E5\u770B\u76D1\u63A7\u4EFB\u52A1\u8BE6\u60C5").action((name) => {
4801
- const taskDir = join7(tasksDir(ctx), name);
4866
+ const taskDir = join6(tasksDir(ctx), name);
4802
4867
  const meta = readMeta(taskDir);
4803
4868
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
4804
- const checkpointPath2 = join7(taskDir, "checkpoint.json");
4869
+ const checkpointPath2 = join6(taskDir, "checkpoint.json");
4805
4870
  let checkpoint = {};
4806
- if (existsSync8(checkpointPath2)) {
4871
+ if (existsSync9(checkpointPath2)) {
4807
4872
  try {
4808
- checkpoint = JSON.parse(readFileSync7(checkpointPath2, "utf-8"));
4873
+ checkpoint = JSON.parse(readFileSync8(checkpointPath2, "utf-8"));
4809
4874
  } catch {
4810
4875
  }
4811
4876
  }
@@ -4820,8 +4885,8 @@ function registerNtfMonitor(ntf, ctx) {
4820
4885
  monitor.command("create <name>").description("\u521B\u5EFA\u76D1\u63A7\u4EFB\u52A1").requiredOption("--description <text>", "\u4EFB\u52A1\u63CF\u8FF0").requiredOption("--match-rules <json>", "\u5339\u914D\u89C4\u5219 JSON").requiredOption("--schedule <cron>", "cron \u8868\u8FBE\u5F0F").action(
4821
4886
  (name, opts) => {
4822
4887
  const dir = tasksDir(ctx);
4823
- const taskDir = join7(dir, name);
4824
- if (existsSync8(taskDir)) {
4888
+ const taskDir = join6(dir, name);
4889
+ if (existsSync9(taskDir)) {
4825
4890
  exitError("ALREADY_EXISTS", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u5DF2\u5B58\u5728`);
4826
4891
  }
4827
4892
  let matchRules;
@@ -4844,12 +4909,12 @@ function registerNtfMonitor(ntf, ctx) {
4844
4909
  };
4845
4910
  writeMeta(taskDir, meta);
4846
4911
  writeFileSync6(
4847
- join7(taskDir, "fetch.py"),
4912
+ join6(taskDir, "fetch.py"),
4848
4913
  generateFetchPy(name, matchRules),
4849
4914
  "utf-8"
4850
4915
  );
4851
4916
  writeFileSync6(
4852
- join7(taskDir, "README.md"),
4917
+ join6(taskDir, "README.md"),
4853
4918
  generateReadme(name, opts.description),
4854
4919
  "utf-8"
4855
4920
  );
@@ -4877,8 +4942,8 @@ function registerNtfMonitor(ntf, ctx) {
4877
4942
  }
4878
4943
  );
4879
4944
  monitor.command("delete <name>").description("\u5220\u9664\u76D1\u63A7\u4EFB\u52A1").option("--yes", "\u8DF3\u8FC7\u786E\u8BA4").action((name, opts) => {
4880
- const taskDir = join7(tasksDir(ctx), name);
4881
- if (!existsSync8(taskDir)) {
4945
+ const taskDir = join6(tasksDir(ctx), name);
4946
+ if (!existsSync9(taskDir)) {
4882
4947
  exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
4883
4948
  }
4884
4949
  if (!opts.yes) {
@@ -4903,7 +4968,7 @@ function registerNtfMonitor(ntf, ctx) {
4903
4968
  });
4904
4969
  });
4905
4970
  monitor.command("enable <name>").description("\u542F\u7528\u76D1\u63A7\u4EFB\u52A1").action((name) => {
4906
- const taskDir = join7(tasksDir(ctx), name);
4971
+ const taskDir = join6(tasksDir(ctx), name);
4907
4972
  const meta = readMeta(taskDir);
4908
4973
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
4909
4974
  meta.enabled = true;
@@ -4911,7 +4976,7 @@ function registerNtfMonitor(ntf, ctx) {
4911
4976
  output({ ok: true, name, enabled: true });
4912
4977
  });
4913
4978
  monitor.command("disable <name>").description("\u6682\u505C\u76D1\u63A7\u4EFB\u52A1").action((name) => {
4914
- const taskDir = join7(tasksDir(ctx), name);
4979
+ const taskDir = join6(tasksDir(ctx), name);
4915
4980
  const meta = readMeta(taskDir);
4916
4981
  if (!meta) exitError("NOT_FOUND", `\u76D1\u63A7\u4EFB\u52A1 '${name}' \u4E0D\u5B58\u5728`);
4917
4982
  meta.enabled = false;
@@ -4921,8 +4986,8 @@ function registerNtfMonitor(ntf, ctx) {
4921
4986
  }
4922
4987
 
4923
4988
  // src/cli/light-rules.ts
4924
- import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
4925
- import { join as join8 } from "path";
4989
+ import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
4990
+ import { join as join7 } from "path";
4926
4991
 
4927
4992
  // src/light/validators.ts
4928
4993
  var VALID_MODES = ["wave", "breath", "strobe", "steady", "wave_rainbow"];
@@ -4987,12 +5052,12 @@ var LIGHT_RULES_SECTION = "## \u706F\u6548\u89C4\u5219";
4987
5052
  function memoryPath(ctx) {
4988
5053
  const base = ctx.workspaceDir || ctx.stateDir;
4989
5054
  if (!base) throw new Error("workspaceDir and stateDir both unavailable");
4990
- return join8(base, "MEMORY.md");
5055
+ return join7(base, "MEMORY.md");
4991
5056
  }
4992
5057
  function readMemory(ctx) {
4993
5058
  const p = memoryPath(ctx);
4994
- if (!existsSync9(p)) return "";
4995
- return readFileSync8(p, "utf-8");
5059
+ if (!existsSync10(p)) return "";
5060
+ return readFileSync9(p, "utf-8");
4996
5061
  }
4997
5062
  function writeMemory(ctx, content) {
4998
5063
  writeFileSync7(memoryPath(ctx), content, "utf-8");
@@ -5174,15 +5239,15 @@ function registerLightSend(light) {
5174
5239
  }
5175
5240
 
5176
5241
  // src/cli/tunnel-status.ts
5177
- import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
5178
- import { join as join9 } from "path";
5179
- var STATUS_REL_PATH = join9("plugins", "phone-notifications", "tunnel-status.json");
5242
+ import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
5243
+ import { join as join8 } from "path";
5244
+ var STATUS_REL_PATH = join8("plugins", "phone-notifications", "tunnel-status.json");
5180
5245
  function readTunnelStatus(ctx) {
5181
5246
  if (!ctx.stateDir) return null;
5182
- const filePath = join9(ctx.stateDir, STATUS_REL_PATH);
5183
- if (!existsSync10(filePath)) return null;
5247
+ const filePath = join8(ctx.stateDir, STATUS_REL_PATH);
5248
+ if (!existsSync11(filePath)) return null;
5184
5249
  try {
5185
- return JSON.parse(readFileSync9(filePath, "utf-8"));
5250
+ return JSON.parse(readFileSync10(filePath, "utf-8"));
5186
5251
  } catch {
5187
5252
  return null;
5188
5253
  }
@@ -5250,17 +5315,17 @@ function registerNtfStoragePath(ntf, ctx) {
5250
5315
  }
5251
5316
 
5252
5317
  // src/cli/log-search.ts
5253
- import { existsSync as existsSync11, readFileSync as readFileSync10, readdirSync as readdirSync4 } from "fs";
5254
- import { join as join10 } from "path";
5318
+ import { existsSync as existsSync12, readFileSync as readFileSync11, readdirSync as readdirSync4 } from "fs";
5319
+ import { join as join9 } from "path";
5255
5320
  function resolveLogsDir(ctx) {
5256
5321
  if (ctx.stateDir) {
5257
- const dir = join10(
5322
+ const dir = join9(
5258
5323
  ctx.stateDir,
5259
5324
  "plugins",
5260
5325
  "phone-notifications",
5261
5326
  "logs"
5262
5327
  );
5263
- if (existsSync11(dir)) return dir;
5328
+ if (existsSync12(dir)) return dir;
5264
5329
  }
5265
5330
  return null;
5266
5331
  }
@@ -5275,9 +5340,9 @@ function listLogDateKeys(dir) {
5275
5340
  return keys.sort().reverse();
5276
5341
  }
5277
5342
  function collectLogLines(dir, dateKey, keyword, limit, collected) {
5278
- const filePath = join10(dir, `${dateKey}.log`);
5279
- if (!existsSync11(filePath)) return;
5280
- const content = readFileSync10(filePath, "utf-8");
5343
+ const filePath = join9(dir, `${dateKey}.log`);
5344
+ if (!existsSync12(filePath)) return;
5345
+ const content = readFileSync11(filePath, "utf-8");
5281
5346
  const lowerKeyword = keyword?.toLowerCase();
5282
5347
  for (const line of content.split("\n")) {
5283
5348
  if (collected.length >= limit) return;
@@ -5343,12 +5408,12 @@ function registerEnvCli(ntf) {
5343
5408
  }
5344
5409
 
5345
5410
  // src/version.ts
5346
- import { readFileSync as readFileSync11 } from "fs";
5411
+ import { readFileSync as readFileSync12 } from "fs";
5347
5412
  function readPluginVersion() {
5348
5413
  try {
5349
5414
  const packageJsonUrl = new URL("../package.json", import.meta.url);
5350
5415
  const packageJson = JSON.parse(
5351
- readFileSync11(packageJsonUrl, "utf-8")
5416
+ readFileSync12(packageJsonUrl, "utf-8")
5352
5417
  );
5353
5418
  return packageJson.version ?? "unknown";
5354
5419
  } catch {
@@ -5378,11 +5443,11 @@ import {
5378
5443
  closeSync,
5379
5444
  mkdirSync as mkdirSync7,
5380
5445
  openSync,
5381
- readFileSync as readFileSync12,
5446
+ readFileSync as readFileSync13,
5382
5447
  unlinkSync,
5383
5448
  writeFileSync as writeFileSync9
5384
5449
  } from "fs";
5385
- import { dirname as dirname4, join as join11 } from "path";
5450
+ import { dirname as dirname4, join as join10 } from "path";
5386
5451
 
5387
5452
  // src/tunnel/relay-client.ts
5388
5453
  import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync6 } from "fs";
@@ -5716,11 +5781,11 @@ function buildDeviceAuthPayload(params) {
5716
5781
  params.nonce
5717
5782
  ].join("|");
5718
5783
  }
5719
- function resolveStateDir() {
5720
- return process.env.OPENCLAW_STATE_DIR ?? path.join(process.env.HOME ?? "/root", ".openclaw");
5784
+ function resolveStateDir2() {
5785
+ return resolveStateDir();
5721
5786
  }
5722
5787
  function loadOrCreateDeviceIdentity() {
5723
- const filePath = path.join(resolveStateDir(), "identity", "device.json");
5788
+ const filePath = path.join(resolveStateDir2(), "identity", "device.json");
5724
5789
  try {
5725
5790
  if (fs.existsSync(filePath)) {
5726
5791
  const raw = fs.readFileSync(filePath, "utf8");
@@ -6270,7 +6335,7 @@ function createTunnelService(opts) {
6270
6335
  }
6271
6336
  function readLockOwner(filePath) {
6272
6337
  try {
6273
- const parsed = JSON.parse(readFileSync12(filePath, "utf-8"));
6338
+ const parsed = JSON.parse(readFileSync13(filePath, "utf-8"));
6274
6339
  return typeof parsed.pid === "number" ? parsed.pid : null;
6275
6340
  } catch {
6276
6341
  return null;
@@ -6356,12 +6421,12 @@ function createTunnelService(opts) {
6356
6421
  return;
6357
6422
  }
6358
6423
  const { logger } = opts;
6359
- const baseStateDir = join11(ctx.stateDir, "plugins", "phone-notifications");
6424
+ const baseStateDir = join10(ctx.stateDir, "plugins", "phone-notifications");
6360
6425
  logger.info(
6361
6426
  `Relay tunnel: starting (pid=${process.pid}, url=${opts.tunnelUrl}, heartbeat=${opts.heartbeatSec ?? DEFAULT_HEARTBEAT_SEC}s, backoff=${opts.reconnectBackoffMs ?? DEFAULT_RECONNECT_BACKOFF_MS}ms, gateway=${opts.gatewayBaseUrl}, hasGatewayToken=${!!opts.gatewayToken}, hasGatewayPwd=${!!opts.gatewayPassword})`
6362
6427
  );
6363
- const statusFilePath = join11(baseStateDir, "tunnel-status.json");
6364
- const lockPath = join11(baseStateDir, "relay-tunnel.lock");
6428
+ const statusFilePath = join10(baseStateDir, "tunnel-status.json");
6429
+ const lockPath = join10(baseStateDir, "relay-tunnel.lock");
6365
6430
  if (!acquireLock(lockPath)) {
6366
6431
  return;
6367
6432
  }
@@ -6410,11 +6475,11 @@ function createTunnelService(opts) {
6410
6475
 
6411
6476
  // src/logger.ts
6412
6477
  import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync8 } from "fs";
6413
- import { join as join12 } from "path";
6478
+ import { join as join11 } from "path";
6414
6479
  var PluginFileLogger = class {
6415
6480
  constructor(upstream, stateDir) {
6416
6481
  this.upstream = upstream;
6417
- this.logsDir = join12(stateDir, "plugins", "phone-notifications", "logs");
6482
+ this.logsDir = join11(stateDir, "plugins", "phone-notifications", "logs");
6418
6483
  mkdirSync8(this.logsDir, { recursive: true });
6419
6484
  }
6420
6485
  logsDir;
@@ -6437,7 +6502,7 @@ var PluginFileLogger = class {
6437
6502
  const line = `${time} [${level}] ${msg}
6438
6503
  `;
6439
6504
  try {
6440
- appendFileSync2(join12(this.logsDir, `${dateKey}.log`), line);
6505
+ appendFileSync2(join11(this.logsDir, `${dateKey}.log`), line);
6441
6506
  } catch {
6442
6507
  }
6443
6508
  }
@@ -6458,7 +6523,7 @@ function readBody(req) {
6458
6523
  req.on("error", reject);
6459
6524
  });
6460
6525
  }
6461
- function trimToUndefined(value) {
6526
+ function trimToUndefined2(value) {
6462
6527
  if (typeof value !== "string") {
6463
6528
  return void 0;
6464
6529
  }
@@ -6475,21 +6540,21 @@ function createEmptyIngestResult() {
6475
6540
  };
6476
6541
  }
6477
6542
  function resolveLocalGatewayAuth(params) {
6478
- const envGatewayToken = trimToUndefined(process.env.OPENCLAW_GATEWAY_TOKEN) ?? trimToUndefined(process.env.CLAWDBOT_GATEWAY_TOKEN);
6479
- const envGatewayPassword = trimToUndefined(process.env.OPENCLAW_GATEWAY_PASSWORD) ?? trimToUndefined(process.env.CLAWDBOT_GATEWAY_PASSWORD);
6543
+ const envGatewayToken = trimToUndefined2(process.env.OPENCLAW_GATEWAY_TOKEN) ?? trimToUndefined2(process.env.QCLAW_GATEWAY_TOKEN) ?? trimToUndefined2(process.env.CLAWDBOT_GATEWAY_TOKEN);
6544
+ const envGatewayPassword = trimToUndefined2(process.env.OPENCLAW_GATEWAY_PASSWORD) ?? trimToUndefined2(process.env.QCLAW_GATEWAY_PASSWORD) ?? trimToUndefined2(process.env.CLAWDBOT_GATEWAY_PASSWORD);
6480
6545
  let configGatewayAuthMode;
6481
6546
  let configGatewayToken;
6482
6547
  let configGatewayPassword;
6483
- const configPath = params.stateDir ? `${params.stateDir}/openclaw.json` : void 0;
6548
+ const configPath = params.stateDir ? resolveConfigPath(params.stateDir) : void 0;
6484
6549
  if (configPath) {
6485
6550
  try {
6486
- const configData = JSON.parse(readFileSync13(configPath, "utf-8"));
6487
- const rawGatewayAuthMode = trimToUndefined(configData?.gateway?.auth?.mode);
6551
+ const configData = JSON.parse(readFileSync14(configPath, "utf-8"));
6552
+ const rawGatewayAuthMode = trimToUndefined2(configData?.gateway?.auth?.mode);
6488
6553
  if (rawGatewayAuthMode === "token" || rawGatewayAuthMode === "password") {
6489
6554
  configGatewayAuthMode = rawGatewayAuthMode;
6490
6555
  }
6491
- configGatewayToken = trimToUndefined(configData?.gateway?.auth?.token);
6492
- configGatewayPassword = trimToUndefined(configData?.gateway?.auth?.password);
6556
+ configGatewayToken = trimToUndefined2(configData?.gateway?.auth?.token);
6557
+ configGatewayPassword = trimToUndefined2(configData?.gateway?.auth?.password);
6493
6558
  } catch (err) {
6494
6559
  if (err?.code !== "ENOENT") {
6495
6560
  params.logger.warn(
@@ -6541,7 +6606,7 @@ var index_default = {
6541
6606
  });
6542
6607
  const tunnelUrl = getEnvUrls().relayTunnelUrl;
6543
6608
  if (tunnelUrl) {
6544
- const gatewayPort = process.env.OPENCLAW_GATEWAY_PORT || "18789";
6609
+ const gatewayPort = process.env.OPENCLAW_GATEWAY_PORT ?? process.env.QCLAW_GATEWAY_PORT ?? "18789";
6545
6610
  const { gatewayAuthMode, gatewayToken, gatewayPassword } = resolveLocalGatewayAuth({
6546
6611
  stateDir: openclawDir,
6547
6612
  logger