@clawos-dev/clawd 0.2.644 → 0.2.645

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/cli.cjs CHANGED
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
450
450
  init_errors();
451
451
  init_en();
452
452
  makeIssue = (params) => {
453
- const { data, path: path107, errorMaps, issueData } = params;
454
- const fullPath = [...path107, ...issueData.path || []];
453
+ const { data, path: path108, errorMaps, issueData } = params;
454
+ const fullPath = [...path108, ...issueData.path || []];
455
455
  const fullIssue = {
456
456
  ...issueData,
457
457
  path: fullPath
@@ -762,11 +762,11 @@ var init_types = __esm({
762
762
  init_parseUtil();
763
763
  init_util();
764
764
  ParseInputLazyPath = class {
765
- constructor(parent, value, path107, key) {
765
+ constructor(parent, value, path108, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path107;
769
+ this._path = path108;
770
770
  this._key = key;
771
771
  }
772
772
  get path() {
@@ -6037,7 +6037,7 @@ function sharedConnectorSecrets(m3) {
6037
6037
  function requiredSecretEnvNames(m3) {
6038
6038
  return [.../* @__PURE__ */ new Set([...m3.secrets.flatMap((s2) => s2.env), ...sharedConnectorSecrets(m3).flatMap((s2) => s2.env)])];
6039
6039
  }
6040
- var EnvArtifactSchema, CLOUD_DEBIAN, CLOUD_ROOT_PROVIDES, CLOUD_BASE_PROVIDES, EnvPackageSchema, EnvSecretSchema, ConnectorNameSchema, CONNECTOR_KINDS, CONNECTOR_RUNNERS, CONNECTOR_PROTOCOLS, CREDENTIAL_SOURCES, CONNECTOR_AUTHS, ConnectorFieldSchema, EnvConnectorSchema, normalizeLegacyManifest, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
6040
+ var EnvArtifactSchema, CLOUD_DEBIAN, CLOUD_ROOT_PROVIDES, CLOUD_BASE_PROVIDES, EnvPackageSchema, EnvSecretSchema, ConnectorNameSchema, CONNECTOR_KINDS, CONNECTOR_RUNNERS, CONNECTOR_PROTOCOLS, CREDENTIAL_SOURCES, CONNECTOR_AUTHS, ConnectorFieldSchema, EnvConnectorSchema, normalizeLegacyManifest, PUBLISHER_TEST_NOTE_PREFIX, PublisherTestSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
6041
6041
  var init_environment_schemas = __esm({
6042
6042
  "../protocol/src/environment-schemas.ts"() {
6043
6043
  "use strict";
@@ -6141,7 +6141,15 @@ var init_environment_schemas = __esm({
6141
6141
  }
6142
6142
  return o2;
6143
6143
  };
6144
+ PUBLISHER_TEST_NOTE_PREFIX = "Publisher test: ";
6145
+ PublisherTestSchema = external_exports.object({
6146
+ version: external_exports.literal(1),
6147
+ entry: external_exports.string().max(240).regex(/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*\.mjs$/).refine((value) => !value.split("/").some((segment) => [".", ".."].includes(segment))),
6148
+ timeoutSeconds: external_exports.number().int().min(1).max(600),
6149
+ checks: external_exports.array(external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/)).min(1).max(64).refine((checks) => new Set(checks).size === checks.length)
6150
+ }).strict();
6144
6151
  MANIFEST_BODY = {
6152
+ test: PublisherTestSchema.optional(),
6145
6153
  packages: external_exports.array(EnvPackageSchema),
6146
6154
  secrets: external_exports.array(EnvSecretSchema),
6147
6155
  /**
@@ -6176,11 +6184,12 @@ var init_environment_schemas = __esm({
6176
6184
  });
6177
6185
 
6178
6186
  // ../protocol/src/release-schemas.ts
6179
- var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, VerificationSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
6187
+ var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, PublisherTestReceiptSchema, VerificationSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
6180
6188
  var init_release_schemas = __esm({
6181
6189
  "../protocol/src/release-schemas.ts"() {
6182
6190
  "use strict";
6183
6191
  init_zod();
6192
+ init_environment_schemas();
6184
6193
  DEPLOY_ENVIRONMENTS = ["integration", "production"];
6185
6194
  DeployEnvironmentSchema = external_exports.enum(DEPLOY_ENVIRONMENTS);
6186
6195
  ImageDigestSchema = external_exports.string().regex(/^[a-z0-9.-]+(?::[0-9]+)?\/[a-z0-9._/-]+@sha256:[a-f0-9]{64}$/);
@@ -6193,12 +6202,25 @@ var init_release_schemas = __esm({
6193
6202
  return false;
6194
6203
  }
6195
6204
  }, "\u6D4B\u8BD5\u9A8C\u8BC1\u5730\u5740\u5FC5\u987B\u660E\u786E\u6307\u5411 int HTTPS \u73AF\u5883");
6205
+ PublisherTestReceiptSchema = external_exports.object({
6206
+ version: external_exports.literal(1),
6207
+ runId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
6208
+ status: external_exports.literal("passed"),
6209
+ exitCode: external_exports.literal(0),
6210
+ result: external_exports.object({
6211
+ version: external_exports.literal(1),
6212
+ runId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
6213
+ checks: external_exports.array(external_exports.object({ name: external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/), status: external_exports.literal("passed"), reason: external_exports.string().max(1024).optional() }).strict()).min(1).max(64)
6214
+ }).strict(),
6215
+ execution: external_exports.object({ image: ImageDigestSchema, imageID: external_exports.string().min(1).max(512), engine: external_exports.enum(["codex", "pi"]), podUid: external_exports.string().min(1).max(512), jobUid: external_exports.string().min(1).max(512) }).strict()
6216
+ }).strict();
6196
6217
  VerificationSchema = external_exports.object({
6197
6218
  status: external_exports.literal("passed"),
6198
6219
  fingerprint: external_exports.string().regex(/^[a-f0-9]{64}$/),
6199
6220
  checks: external_exports.array(external_exports.string().regex(/^[a-z0-9-]+$/)),
6200
6221
  endpoint: IntegrationEndpointSchema,
6201
- verifiedAt: external_exports.string().refine((s2) => Number.isFinite(Date.parse(s2)))
6222
+ verifiedAt: external_exports.string().refine((s2) => Number.isFinite(Date.parse(s2))),
6223
+ test: PublisherTestReceiptSchema.optional()
6202
6224
  }).strict();
6203
6225
  VerifiedPersonaReleaseSchema = external_exports.object({
6204
6226
  version: external_exports.literal(1),
@@ -6209,8 +6231,13 @@ var init_release_schemas = __esm({
6209
6231
  baseImage: ImageDigestSchema,
6210
6232
  pipelineCommit: SourceCommitSchema,
6211
6233
  repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/),
6212
- verification: VerificationSchema.refine((v3) => v3.checks.includes("persona-smoke"))
6213
- }).strict();
6234
+ verification: VerificationSchema.refine((v3) => v3.checks.includes("persona-smoke")),
6235
+ test: PublisherTestSchema.optional()
6236
+ }).strict().refine((record4) => {
6237
+ if (!record4.test) return record4.verification.test === void 0;
6238
+ const receipt = record4.verification.test;
6239
+ return ["persona-dialogue", "persona-task", "persona-custom-test"].every((check) => record4.verification.checks.includes(check)) && receipt !== void 0 && receipt.execution.image === record4.image && receipt.runId === receipt.result.runId && receipt.result.checks.length === record4.test.checks.length && new Set(receipt.result.checks.map((check) => check.name)).size === record4.test.checks.length && receipt.result.checks.every((check) => record4.test.checks.includes(check.name));
6240
+ }, "Declared publisher acceptance requires complete candidate runtime evidence");
6214
6241
  VerifiedBaseReleaseSchema = external_exports.object({
6215
6242
  version: external_exports.literal(1),
6216
6243
  environment: external_exports.literal("integration"),
@@ -10053,8 +10080,8 @@ var require_req = __commonJS({
10053
10080
  if (req.originalUrl) {
10054
10081
  _req.url = req.originalUrl;
10055
10082
  } else {
10056
- const path107 = req.path;
10057
- _req.url = typeof path107 === "string" ? path107 : req.url ? req.url.path || req.url : void 0;
10083
+ const path108 = req.path;
10084
+ _req.url = typeof path108 === "string" ? path108 : req.url ? req.url.path || req.url : void 0;
10058
10085
  }
10059
10086
  if (req.query) {
10060
10087
  _req.query = req.query;
@@ -10219,14 +10246,14 @@ var require_redact = __commonJS({
10219
10246
  }
10220
10247
  return obj;
10221
10248
  }
10222
- function parsePath(path107) {
10249
+ function parsePath(path108) {
10223
10250
  const parts = [];
10224
10251
  let current = "";
10225
10252
  let inBrackets = false;
10226
10253
  let inQuotes = false;
10227
10254
  let quoteChar = "";
10228
- for (let i2 = 0; i2 < path107.length; i2++) {
10229
- const char = path107[i2];
10255
+ for (let i2 = 0; i2 < path108.length; i2++) {
10256
+ const char = path108[i2];
10230
10257
  if (!inBrackets && char === ".") {
10231
10258
  if (current) {
10232
10259
  parts.push(current);
@@ -10357,10 +10384,10 @@ var require_redact = __commonJS({
10357
10384
  return current;
10358
10385
  }
10359
10386
  function redactPaths(obj, paths, censor, remove = false) {
10360
- for (const path107 of paths) {
10361
- const parts = parsePath(path107);
10387
+ for (const path108 of paths) {
10388
+ const parts = parsePath(path108);
10362
10389
  if (parts.includes("*")) {
10363
- redactWildcardPath(obj, parts, censor, path107, remove);
10390
+ redactWildcardPath(obj, parts, censor, path108, remove);
10364
10391
  } else {
10365
10392
  if (remove) {
10366
10393
  removeKey(obj, parts);
@@ -10445,8 +10472,8 @@ var require_redact = __commonJS({
10445
10472
  }
10446
10473
  } else {
10447
10474
  if (afterWildcard.includes("*")) {
10448
- const wrappedCensor = typeof censor === "function" ? (value, path107) => {
10449
- const fullPath = [...pathArray.slice(0, pathLength), ...path107];
10475
+ const wrappedCensor = typeof censor === "function" ? (value, path108) => {
10476
+ const fullPath = [...pathArray.slice(0, pathLength), ...path108];
10450
10477
  return censor(value, fullPath);
10451
10478
  } : censor;
10452
10479
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10481,8 +10508,8 @@ var require_redact = __commonJS({
10481
10508
  return null;
10482
10509
  }
10483
10510
  const pathStructure = /* @__PURE__ */ new Map();
10484
- for (const path107 of pathsToClone) {
10485
- const parts = parsePath(path107);
10511
+ for (const path108 of pathsToClone) {
10512
+ const parts = parsePath(path108);
10486
10513
  let current = pathStructure;
10487
10514
  for (let i2 = 0; i2 < parts.length; i2++) {
10488
10515
  const part = parts[i2];
@@ -10534,24 +10561,24 @@ var require_redact = __commonJS({
10534
10561
  }
10535
10562
  return cloneSelectively(obj, pathStructure);
10536
10563
  }
10537
- function validatePath(path107) {
10538
- if (typeof path107 !== "string") {
10564
+ function validatePath(path108) {
10565
+ if (typeof path108 !== "string") {
10539
10566
  throw new Error("Paths must be (non-empty) strings");
10540
10567
  }
10541
- if (path107 === "") {
10568
+ if (path108 === "") {
10542
10569
  throw new Error("Invalid redaction path ()");
10543
10570
  }
10544
- if (path107.includes("..")) {
10545
- throw new Error(`Invalid redaction path (${path107})`);
10571
+ if (path108.includes("..")) {
10572
+ throw new Error(`Invalid redaction path (${path108})`);
10546
10573
  }
10547
- if (path107.includes(",")) {
10548
- throw new Error(`Invalid redaction path (${path107})`);
10574
+ if (path108.includes(",")) {
10575
+ throw new Error(`Invalid redaction path (${path108})`);
10549
10576
  }
10550
10577
  let bracketCount = 0;
10551
10578
  let inQuotes = false;
10552
10579
  let quoteChar = "";
10553
- for (let i2 = 0; i2 < path107.length; i2++) {
10554
- const char = path107[i2];
10580
+ for (let i2 = 0; i2 < path108.length; i2++) {
10581
+ const char = path108[i2];
10555
10582
  if ((char === '"' || char === "'") && bracketCount > 0) {
10556
10583
  if (!inQuotes) {
10557
10584
  inQuotes = true;
@@ -10565,20 +10592,20 @@ var require_redact = __commonJS({
10565
10592
  } else if (char === "]" && !inQuotes) {
10566
10593
  bracketCount--;
10567
10594
  if (bracketCount < 0) {
10568
- throw new Error(`Invalid redaction path (${path107})`);
10595
+ throw new Error(`Invalid redaction path (${path108})`);
10569
10596
  }
10570
10597
  }
10571
10598
  }
10572
10599
  if (bracketCount !== 0) {
10573
- throw new Error(`Invalid redaction path (${path107})`);
10600
+ throw new Error(`Invalid redaction path (${path108})`);
10574
10601
  }
10575
10602
  }
10576
10603
  function validatePaths(paths) {
10577
10604
  if (!Array.isArray(paths)) {
10578
10605
  throw new TypeError("paths must be an array");
10579
10606
  }
10580
- for (const path107 of paths) {
10581
- validatePath(path107);
10607
+ for (const path108 of paths) {
10608
+ validatePath(path108);
10582
10609
  }
10583
10610
  }
10584
10611
  function slowRedact(options = {}) {
@@ -10746,8 +10773,8 @@ var require_redaction = __commonJS({
10746
10773
  if (shape[k3] === null) {
10747
10774
  o2[k3] = (value) => topCensor(value, [k3]);
10748
10775
  } else {
10749
- const wrappedCensor = typeof censor === "function" ? (value, path107) => {
10750
- return censor(value, [k3, ...path107]);
10776
+ const wrappedCensor = typeof censor === "function" ? (value, path108) => {
10777
+ return censor(value, [k3, ...path108]);
10751
10778
  } : censor;
10752
10779
  o2[k3] = Redact({
10753
10780
  paths: shape[k3],
@@ -10965,10 +10992,10 @@ var require_atomic_sleep = __commonJS({
10965
10992
  var require_sonic_boom = __commonJS({
10966
10993
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
10967
10994
  "use strict";
10968
- var fs96 = require("fs");
10995
+ var fs97 = require("fs");
10969
10996
  var EventEmitter2 = require("events");
10970
10997
  var inherits = require("util").inherits;
10971
- var path107 = require("path");
10998
+ var path108 = require("path");
10972
10999
  var sleep2 = require_atomic_sleep();
10973
11000
  var assert = require("assert");
10974
11001
  var BUSY_WRITE_TIMEOUT = 100;
@@ -11022,20 +11049,20 @@ var require_sonic_boom = __commonJS({
11022
11049
  const mode = sonic.mode;
11023
11050
  if (sonic.sync) {
11024
11051
  try {
11025
- if (sonic.mkdir) fs96.mkdirSync(path107.dirname(file), { recursive: true });
11026
- const fd = fs96.openSync(file, flags, mode);
11052
+ if (sonic.mkdir) fs97.mkdirSync(path108.dirname(file), { recursive: true });
11053
+ const fd = fs97.openSync(file, flags, mode);
11027
11054
  fileOpened(null, fd);
11028
11055
  } catch (err) {
11029
11056
  fileOpened(err);
11030
11057
  throw err;
11031
11058
  }
11032
11059
  } else if (sonic.mkdir) {
11033
- fs96.mkdir(path107.dirname(file), { recursive: true }, (err) => {
11060
+ fs97.mkdir(path108.dirname(file), { recursive: true }, (err) => {
11034
11061
  if (err) return fileOpened(err);
11035
- fs96.open(file, flags, mode, fileOpened);
11062
+ fs97.open(file, flags, mode, fileOpened);
11036
11063
  });
11037
11064
  } else {
11038
- fs96.open(file, flags, mode, fileOpened);
11065
+ fs97.open(file, flags, mode, fileOpened);
11039
11066
  }
11040
11067
  }
11041
11068
  function SonicBoom(opts) {
@@ -11076,8 +11103,8 @@ var require_sonic_boom = __commonJS({
11076
11103
  this.flush = flushBuffer;
11077
11104
  this.flushSync = flushBufferSync;
11078
11105
  this._actualWrite = actualWriteBuffer;
11079
- fsWriteSync = () => fs96.writeSync(this.fd, this._writingBuf);
11080
- fsWrite = () => fs96.write(this.fd, this._writingBuf, this.release);
11106
+ fsWriteSync = () => fs97.writeSync(this.fd, this._writingBuf);
11107
+ fsWrite = () => fs97.write(this.fd, this._writingBuf, this.release);
11081
11108
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
11082
11109
  this._writingBuf = "";
11083
11110
  this.write = write;
@@ -11086,15 +11113,15 @@ var require_sonic_boom = __commonJS({
11086
11113
  this._actualWrite = actualWrite;
11087
11114
  fsWriteSync = () => {
11088
11115
  if (Buffer.isBuffer(this._writingBuf)) {
11089
- return fs96.writeSync(this.fd, this._writingBuf);
11116
+ return fs97.writeSync(this.fd, this._writingBuf);
11090
11117
  }
11091
- return fs96.writeSync(this.fd, this._writingBuf, "utf8");
11118
+ return fs97.writeSync(this.fd, this._writingBuf, "utf8");
11092
11119
  };
11093
11120
  fsWrite = () => {
11094
11121
  if (Buffer.isBuffer(this._writingBuf)) {
11095
- return fs96.write(this.fd, this._writingBuf, this.release);
11122
+ return fs97.write(this.fd, this._writingBuf, this.release);
11096
11123
  }
11097
- return fs96.write(this.fd, this._writingBuf, "utf8", this.release);
11124
+ return fs97.write(this.fd, this._writingBuf, "utf8", this.release);
11098
11125
  };
11099
11126
  } else {
11100
11127
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11151,7 +11178,7 @@ var require_sonic_boom = __commonJS({
11151
11178
  }
11152
11179
  }
11153
11180
  if (this._fsync) {
11154
- fs96.fsyncSync(this.fd);
11181
+ fs97.fsyncSync(this.fd);
11155
11182
  }
11156
11183
  const len = this._len;
11157
11184
  if (this._reopening) {
@@ -11265,7 +11292,7 @@ var require_sonic_boom = __commonJS({
11265
11292
  const onDrain = () => {
11266
11293
  if (!this._fsync) {
11267
11294
  try {
11268
- fs96.fsync(this.fd, (err) => {
11295
+ fs97.fsync(this.fd, (err) => {
11269
11296
  this._flushPending = false;
11270
11297
  cb(err);
11271
11298
  });
@@ -11367,7 +11394,7 @@ var require_sonic_boom = __commonJS({
11367
11394
  const fd = this.fd;
11368
11395
  this.once("ready", () => {
11369
11396
  if (fd !== this.fd) {
11370
- fs96.close(fd, (err) => {
11397
+ fs97.close(fd, (err) => {
11371
11398
  if (err) {
11372
11399
  return this.emit("error", err);
11373
11400
  }
@@ -11416,7 +11443,7 @@ var require_sonic_boom = __commonJS({
11416
11443
  buf = this._bufs[0];
11417
11444
  }
11418
11445
  try {
11419
- const n2 = Buffer.isBuffer(buf) ? fs96.writeSync(this.fd, buf) : fs96.writeSync(this.fd, buf, "utf8");
11446
+ const n2 = Buffer.isBuffer(buf) ? fs97.writeSync(this.fd, buf) : fs97.writeSync(this.fd, buf, "utf8");
11420
11447
  const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
11421
11448
  buf = releasedBufObj.writingBuf;
11422
11449
  this._len = releasedBufObj.len;
@@ -11432,7 +11459,7 @@ var require_sonic_boom = __commonJS({
11432
11459
  }
11433
11460
  }
11434
11461
  try {
11435
- fs96.fsyncSync(this.fd);
11462
+ fs97.fsyncSync(this.fd);
11436
11463
  } catch {
11437
11464
  }
11438
11465
  }
@@ -11453,7 +11480,7 @@ var require_sonic_boom = __commonJS({
11453
11480
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11454
11481
  }
11455
11482
  try {
11456
- const n2 = fs96.writeSync(this.fd, buf);
11483
+ const n2 = fs97.writeSync(this.fd, buf);
11457
11484
  buf = buf.subarray(n2);
11458
11485
  this._len = Math.max(this._len - n2, 0);
11459
11486
  if (buf.length <= 0) {
@@ -11481,13 +11508,13 @@ var require_sonic_boom = __commonJS({
11481
11508
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11482
11509
  if (this.sync) {
11483
11510
  try {
11484
- const written = Buffer.isBuffer(this._writingBuf) ? fs96.writeSync(this.fd, this._writingBuf) : fs96.writeSync(this.fd, this._writingBuf, "utf8");
11511
+ const written = Buffer.isBuffer(this._writingBuf) ? fs97.writeSync(this.fd, this._writingBuf) : fs97.writeSync(this.fd, this._writingBuf, "utf8");
11485
11512
  release2(null, written);
11486
11513
  } catch (err) {
11487
11514
  release2(err);
11488
11515
  }
11489
11516
  } else {
11490
- fs96.write(this.fd, this._writingBuf, release2);
11517
+ fs97.write(this.fd, this._writingBuf, release2);
11491
11518
  }
11492
11519
  }
11493
11520
  function actualWriteBuffer() {
@@ -11496,7 +11523,7 @@ var require_sonic_boom = __commonJS({
11496
11523
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11497
11524
  if (this.sync) {
11498
11525
  try {
11499
- const written = fs96.writeSync(this.fd, this._writingBuf);
11526
+ const written = fs97.writeSync(this.fd, this._writingBuf);
11500
11527
  release2(null, written);
11501
11528
  } catch (err) {
11502
11529
  release2(err);
@@ -11505,7 +11532,7 @@ var require_sonic_boom = __commonJS({
11505
11532
  if (kCopyBuffer) {
11506
11533
  this._writingBuf = Buffer.from(this._writingBuf);
11507
11534
  }
11508
- fs96.write(this.fd, this._writingBuf, release2);
11535
+ fs97.write(this.fd, this._writingBuf, release2);
11509
11536
  }
11510
11537
  }
11511
11538
  function actualClose(sonic) {
@@ -11521,12 +11548,12 @@ var require_sonic_boom = __commonJS({
11521
11548
  sonic._lens = [];
11522
11549
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11523
11550
  try {
11524
- fs96.fsync(sonic.fd, closeWrapped);
11551
+ fs97.fsync(sonic.fd, closeWrapped);
11525
11552
  } catch {
11526
11553
  }
11527
11554
  function closeWrapped() {
11528
11555
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11529
- fs96.close(sonic.fd, done);
11556
+ fs97.close(sonic.fd, done);
11530
11557
  } else {
11531
11558
  done();
11532
11559
  }
@@ -14661,11 +14688,11 @@ var init_lib = __esm({
14661
14688
  }
14662
14689
  }
14663
14690
  },
14664
- addToPath: function addToPath(path107, added, removed, oldPosInc, options) {
14665
- var last = path107.lastComponent;
14691
+ addToPath: function addToPath(path108, added, removed, oldPosInc, options) {
14692
+ var last = path108.lastComponent;
14666
14693
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14667
14694
  return {
14668
- oldPos: path107.oldPos + oldPosInc,
14695
+ oldPos: path108.oldPos + oldPosInc,
14669
14696
  lastComponent: {
14670
14697
  count: last.count + 1,
14671
14698
  added,
@@ -14675,7 +14702,7 @@ var init_lib = __esm({
14675
14702
  };
14676
14703
  } else {
14677
14704
  return {
14678
- oldPos: path107.oldPos + oldPosInc,
14705
+ oldPos: path108.oldPos + oldPosInc,
14679
14706
  lastComponent: {
14680
14707
  count: 1,
14681
14708
  added,
@@ -15257,10 +15284,10 @@ function attachmentToHistoryMessage(o2, ts) {
15257
15284
  const memories = raw.map((m3) => {
15258
15285
  if (!m3 || typeof m3 !== "object") return null;
15259
15286
  const rec6 = m3;
15260
- const path107 = typeof rec6.path === "string" ? rec6.path : null;
15287
+ const path108 = typeof rec6.path === "string" ? rec6.path : null;
15261
15288
  const content = typeof rec6.content === "string" ? rec6.content : null;
15262
- if (!path107 || content == null) return null;
15263
- const entry = { path: path107, content };
15289
+ if (!path108 || content == null) return null;
15290
+ const entry = { path: path108, content };
15264
15291
  if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
15265
15292
  return entry;
15266
15293
  }).filter((m3) => m3 !== null);
@@ -16110,10 +16137,10 @@ function parseAttachment(obj) {
16110
16137
  const memories = raw.map((m3) => {
16111
16138
  if (!m3 || typeof m3 !== "object") return null;
16112
16139
  const rec6 = m3;
16113
- const path107 = typeof rec6.path === "string" ? rec6.path : null;
16140
+ const path108 = typeof rec6.path === "string" ? rec6.path : null;
16114
16141
  const content = typeof rec6.content === "string" ? rec6.content : null;
16115
- if (!path107 || content == null) return null;
16116
- const out = { path: path107, content };
16142
+ if (!path108 || content == null) return null;
16143
+ const out = { path: path108, content };
16117
16144
  if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
16118
16145
  return out;
16119
16146
  }).filter((m3) => m3 !== null);
@@ -33468,8 +33495,8 @@ var require_utils = __commonJS({
33468
33495
  var result = transform[inputType][outputType](input);
33469
33496
  return result;
33470
33497
  };
33471
- exports2.resolve = function(path107) {
33472
- var parts = path107.split("/");
33498
+ exports2.resolve = function(path108) {
33499
+ var parts = path108.split("/");
33473
33500
  var result = [];
33474
33501
  for (var index = 0; index < parts.length; index++) {
33475
33502
  var part = parts[index];
@@ -39322,18 +39349,18 @@ var require_object = __commonJS({
39322
39349
  var object = new ZipObject(name, zipObjectContent, o2);
39323
39350
  this.files[name] = object;
39324
39351
  };
39325
- var parentFolder = function(path107) {
39326
- if (path107.slice(-1) === "/") {
39327
- path107 = path107.substring(0, path107.length - 1);
39352
+ var parentFolder = function(path108) {
39353
+ if (path108.slice(-1) === "/") {
39354
+ path108 = path108.substring(0, path108.length - 1);
39328
39355
  }
39329
- var lastSlash = path107.lastIndexOf("/");
39330
- return lastSlash > 0 ? path107.substring(0, lastSlash) : "";
39356
+ var lastSlash = path108.lastIndexOf("/");
39357
+ return lastSlash > 0 ? path108.substring(0, lastSlash) : "";
39331
39358
  };
39332
- var forceTrailingSlash = function(path107) {
39333
- if (path107.slice(-1) !== "/") {
39334
- path107 += "/";
39359
+ var forceTrailingSlash = function(path108) {
39360
+ if (path108.slice(-1) !== "/") {
39361
+ path108 += "/";
39335
39362
  }
39336
- return path107;
39363
+ return path108;
39337
39364
  };
39338
39365
  var folderAdd = function(name, createFolders) {
39339
39366
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -43951,7 +43978,7 @@ var require_websocket_server = __commonJS({
43951
43978
  // src/run-case/recorder.ts
43952
43979
  function startRunCaseRecorder(opts) {
43953
43980
  const now = opts.now ?? Date.now;
43954
- const dir = import_node_path86.default.dirname(opts.recordPath);
43981
+ const dir = import_node_path87.default.dirname(opts.recordPath);
43955
43982
  let stream = null;
43956
43983
  let closing = false;
43957
43984
  let closedSettled = false;
@@ -43965,8 +43992,8 @@ function startRunCaseRecorder(opts) {
43965
43992
  });
43966
43993
  const ensureStream = () => {
43967
43994
  if (stream) return stream;
43968
- import_node_fs67.default.mkdirSync(dir, { recursive: true });
43969
- stream = import_node_fs67.default.createWriteStream(opts.recordPath, { flags: "a" });
43995
+ import_node_fs68.default.mkdirSync(dir, { recursive: true });
43996
+ stream = import_node_fs68.default.createWriteStream(opts.recordPath, { flags: "a" });
43970
43997
  stream.on("close", () => closedResolve());
43971
43998
  return stream;
43972
43999
  };
@@ -43991,12 +44018,12 @@ function startRunCaseRecorder(opts) {
43991
44018
  };
43992
44019
  return { tap, close, closed };
43993
44020
  }
43994
- var import_node_fs67, import_node_path86;
44021
+ var import_node_fs68, import_node_path87;
43995
44022
  var init_recorder = __esm({
43996
44023
  "src/run-case/recorder.ts"() {
43997
44024
  "use strict";
43998
- import_node_fs67 = __toESM(require("fs"), 1);
43999
- import_node_path86 = __toESM(require("path"), 1);
44025
+ import_node_fs68 = __toESM(require("fs"), 1);
44026
+ import_node_path87 = __toESM(require("path"), 1);
44000
44027
  }
44001
44028
  });
44002
44029
 
@@ -44039,7 +44066,7 @@ var init_wire = __esm({
44039
44066
  // src/run-case/controller.ts
44040
44067
  async function runController(opts) {
44041
44068
  const now = opts.now ?? Date.now;
44042
- const cwd = opts.cwd ?? (0, import_node_fs68.mkdtempSync)(import_node_path87.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
44069
+ const cwd = opts.cwd ?? (0, import_node_fs69.mkdtempSync)(import_node_path88.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
44043
44070
  const ownsCwd = opts.cwd === void 0;
44044
44071
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
44045
44072
  const spawnCtx = { cwd };
@@ -44200,19 +44227,19 @@ async function runController(opts) {
44200
44227
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44201
44228
  if (ownsCwd) {
44202
44229
  try {
44203
- (0, import_node_fs68.rmSync)(cwd, { recursive: true, force: true });
44230
+ (0, import_node_fs69.rmSync)(cwd, { recursive: true, force: true });
44204
44231
  } catch {
44205
44232
  }
44206
44233
  }
44207
44234
  return exitCode ?? 0;
44208
44235
  }
44209
- var import_node_fs68, import_node_os32, import_node_path87;
44236
+ var import_node_fs69, import_node_os32, import_node_path88;
44210
44237
  var init_controller = __esm({
44211
44238
  "src/run-case/controller.ts"() {
44212
44239
  "use strict";
44213
- import_node_fs68 = require("fs");
44240
+ import_node_fs69 = require("fs");
44214
44241
  import_node_os32 = __toESM(require("os"), 1);
44215
- import_node_path87 = __toESM(require("path"), 1);
44242
+ import_node_path88 = __toESM(require("path"), 1);
44216
44243
  init_claude();
44217
44244
  init_stdout_splitter();
44218
44245
  init_permission_stdio();
@@ -45831,8 +45858,8 @@ function requireEnvironmentIdentity(stores, environment) {
45831
45858
  }
45832
45859
 
45833
45860
  // src/index.ts
45834
- var import_node_path85 = __toESM(require("path"), 1);
45835
- var import_node_fs66 = __toESM(require("fs"), 1);
45861
+ var import_node_path86 = __toESM(require("path"), 1);
45862
+ var import_node_fs67 = __toESM(require("fs"), 1);
45836
45863
  var import_node_os31 = __toESM(require("os"), 1);
45837
45864
  var import_node_crypto30 = require("crypto");
45838
45865
  var import_node_url6 = require("url");
@@ -52509,9 +52536,9 @@ var CentralClientError = class extends Error {
52509
52536
  cause;
52510
52537
  status;
52511
52538
  };
52512
- async function centralRequest(opts, path107, init) {
52539
+ async function centralRequest(opts, path108, init) {
52513
52540
  const f2 = opts.fetchImpl ?? globalThis.fetch;
52514
- const url = `${opts.api.replace(/\/+$/, "")}${path107}`;
52541
+ const url = `${opts.api.replace(/\/+$/, "")}${path108}`;
52515
52542
  const ctrl = new AbortController();
52516
52543
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52517
52544
  let res;
@@ -53463,8 +53490,8 @@ function turnStartInput(text, resolveImage) {
53463
53490
  const items = [];
53464
53491
  let leftover = text;
53465
53492
  for (const m3 of text.matchAll(SKILL_RE)) {
53466
- const [marker, name, path107] = m3;
53467
- items.push({ type: "skill", name, path: path107 });
53493
+ const [marker, name, path108] = m3;
53494
+ items.push({ type: "skill", name, path: path108 });
53468
53495
  leftover = leftover.replace(marker, "");
53469
53496
  }
53470
53497
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -56834,6 +56861,48 @@ function buildShiftInternalHandlers(deps) {
56834
56861
  // src/handlers/deploy.ts
56835
56862
  var import_node_crypto14 = require("crypto");
56836
56863
 
56864
+ // src/deploy/persona-test.ts
56865
+ var import_node_fs33 = __toESM(require("fs"), 1);
56866
+ var import_node_path36 = __toESM(require("path"), 1);
56867
+ init_protocol();
56868
+ var TEST_SCAN_NOTE_PREFIX = PUBLISHER_TEST_NOTE_PREFIX;
56869
+ function regularFile(root, relative5) {
56870
+ let current = root;
56871
+ for (const segment of relative5.split("/")) {
56872
+ current = import_node_path36.default.join(current, segment);
56873
+ if (import_node_fs33.default.lstatSync(current).isSymbolicLink()) throw new Error("symlink");
56874
+ }
56875
+ if (!import_node_fs33.default.statSync(current).isFile()) throw new Error("not a file");
56876
+ const resolved = import_node_fs33.default.realpathSync(current);
56877
+ if (!resolved.startsWith(root + import_node_path36.default.sep)) throw new Error("outside root");
56878
+ return resolved;
56879
+ }
56880
+ function discoverPublisherTest(dir) {
56881
+ try {
56882
+ const root = import_node_fs33.default.realpathSync(dir);
56883
+ try {
56884
+ import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd"));
56885
+ } catch (error) {
56886
+ if (error.code === "ENOENT") return { problems: [] };
56887
+ throw error;
56888
+ }
56889
+ if (import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd")).isSymbolicLink()) throw new Error("symlink");
56890
+ try {
56891
+ import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd/test.json"));
56892
+ } catch (error) {
56893
+ if (error.code === "ENOENT") return { problems: [] };
56894
+ throw error;
56895
+ }
56896
+ const file = regularFile(root, ".clawd/test.json");
56897
+ if (import_node_fs33.default.statSync(file).size > 64 * 1024) throw new Error("oversized");
56898
+ const test = PublisherTestSchema.parse(JSON.parse(import_node_fs33.default.readFileSync(file, "utf8")));
56899
+ regularFile(root, test.entry);
56900
+ return { test, problems: [] };
56901
+ } catch {
56902
+ return { problems: [".clawd/test.json \u6216\u6D4B\u8BD5\u5165\u53E3\u65E0\u6548\u3001\u4E0D\u53EF\u8BFB\u6216\u5305\u542B\u7B26\u53F7\u94FE\u63A5\uFF1B\u4FEE\u590D\u540E\u91CD\u65B0\u626B\u63CF"] };
56903
+ }
56904
+ }
56905
+
56837
56906
  // src/deploy/verified-release.ts
56838
56907
  var import_node_crypto12 = require("crypto");
56839
56908
 
@@ -57227,19 +57296,19 @@ function openHttpTurn(opts) {
57227
57296
 
57228
57297
  // src/deploy/repo.ts
57229
57298
  var import_promises5 = __toESM(require("fs/promises"), 1);
57230
- var import_node_path38 = __toESM(require("path"), 1);
57299
+ var import_node_path39 = __toESM(require("path"), 1);
57231
57300
  init_protocol();
57232
57301
 
57233
57302
  // src/deploy/deploy-file.ts
57234
57303
  var import_promises4 = __toESM(require("fs/promises"), 1);
57235
- var import_node_path37 = __toESM(require("path"), 1);
57304
+ var import_node_path38 = __toESM(require("path"), 1);
57236
57305
  var import_node_crypto11 = require("crypto");
57237
57306
  init_zod();
57238
57307
  init_protocol();
57239
57308
 
57240
57309
  // src/deploy/connectors.ts
57241
- var import_node_fs33 = __toESM(require("fs"), 1);
57242
- var import_node_path36 = __toESM(require("path"), 1);
57310
+ var import_node_fs34 = __toESM(require("fs"), 1);
57311
+ var import_node_path37 = __toESM(require("path"), 1);
57243
57312
  init_zod();
57244
57313
  init_protocol();
57245
57314
 
@@ -57327,11 +57396,11 @@ var PACKAGE_RUNNERS = /* @__PURE__ */ new Set(["npx", "uvx", "pnpx", "bunx"]);
57327
57396
  var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "deno", "python", "python3"]);
57328
57397
  var HOST_ARG_PLACEHOLDER = "CLAWD_PERSONA_DIR";
57329
57398
  function scanMcpConnectors(personaDir) {
57330
- const file = import_node_path36.default.join(personaDir, ".mcp.json");
57399
+ const file = import_node_path37.default.join(personaDir, ".mcp.json");
57331
57400
  const out = { readable: true, connectors: [], evidence: [], warnings: [] };
57332
57401
  let parsed;
57333
57402
  try {
57334
- parsed = JSON.parse(import_node_fs33.default.readFileSync(file, "utf8"));
57403
+ parsed = JSON.parse(import_node_fs34.default.readFileSync(file, "utf8"));
57335
57404
  } catch (e) {
57336
57405
  if (e.code === "ENOENT") return out;
57337
57406
  out.readable = false;
@@ -57426,8 +57495,8 @@ function mergeScannedConnectors(existing, scanned) {
57426
57495
  }
57427
57496
 
57428
57497
  // src/deploy/deploy-file.ts
57429
- var DEPLOY_FILE = import_node_path37.default.join(".clawd", "deploy.json");
57430
- var SCAN_FILE = import_node_path37.default.join(".clawd", "deploy-scan.json");
57498
+ var DEPLOY_FILE = import_node_path38.default.join(".clawd", "deploy.json");
57499
+ var SCAN_FILE = import_node_path38.default.join(".clawd", "deploy-scan.json");
57431
57500
  async function readJson(file) {
57432
57501
  let raw;
57433
57502
  try {
@@ -57443,14 +57512,14 @@ async function readJson(file) {
57443
57512
  }
57444
57513
  }
57445
57514
  async function writeJson(file, value) {
57446
- await import_promises4.default.mkdir(import_node_path37.default.dirname(file), { recursive: true });
57515
+ await import_promises4.default.mkdir(import_node_path38.default.dirname(file), { recursive: true });
57447
57516
  const tmp = `${file}.tmp-${process.pid}`;
57448
57517
  await import_promises4.default.writeFile(tmp, `${JSON.stringify(value, null, 2)}
57449
57518
  `);
57450
57519
  await import_promises4.default.rename(tmp, file);
57451
57520
  }
57452
57521
  async function readDeployFile(dir) {
57453
- const raw = await readJson(import_node_path37.default.join(dir, DEPLOY_FILE));
57522
+ const raw = await readJson(import_node_path38.default.join(dir, DEPLOY_FILE));
57454
57523
  if (raw === void 0) return void 0;
57455
57524
  const parsed = DeployFileSchema.safeParse(raw);
57456
57525
  if (!parsed.success) {
@@ -57460,18 +57529,18 @@ async function readDeployFile(dir) {
57460
57529
  return parsed.data;
57461
57530
  }
57462
57531
  async function writeDeployFile(dir, file) {
57463
- await writeJson(import_node_path37.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
57532
+ await writeJson(import_node_path38.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
57464
57533
  }
57465
57534
  async function readDeployFileRaw(dir) {
57466
57535
  try {
57467
- return await import_promises4.default.readFile(import_node_path37.default.join(dir, DEPLOY_FILE), "utf8");
57536
+ return await import_promises4.default.readFile(import_node_path38.default.join(dir, DEPLOY_FILE), "utf8");
57468
57537
  } catch (err) {
57469
57538
  if (err.code === "ENOENT") return void 0;
57470
57539
  throw err;
57471
57540
  }
57472
57541
  }
57473
57542
  async function restoreDeployFileRaw(dir, raw) {
57474
- const file = import_node_path37.default.join(dir, DEPLOY_FILE);
57543
+ const file = import_node_path38.default.join(dir, DEPLOY_FILE);
57475
57544
  if (raw === void 0) await import_promises4.default.rm(file, { force: true });
57476
57545
  else await import_promises4.default.writeFile(file, raw);
57477
57546
  }
@@ -57522,7 +57591,7 @@ function normalizeLegacyScan(raw) {
57522
57591
  return fix(raw);
57523
57592
  }
57524
57593
  async function readScanFile(dir) {
57525
- const raw = normalizeLegacyScan(await readJson(import_node_path37.default.join(dir, SCAN_FILE)));
57594
+ const raw = normalizeLegacyScan(await readJson(import_node_path38.default.join(dir, SCAN_FILE)));
57526
57595
  if (raw === void 0) return void 0;
57527
57596
  const badShape = (issues) => {
57528
57597
  const first = issues[0];
@@ -57548,7 +57617,7 @@ async function readScanFile(dir) {
57548
57617
  return parsed.data;
57549
57618
  }
57550
57619
  async function writeScanFile(dir, file) {
57551
- await writeJson(import_node_path37.default.join(dir, SCAN_FILE), DeployScanFileSchema.parse(file));
57620
+ await writeJson(import_node_path38.default.join(dir, SCAN_FILE), DeployScanFileSchema.parse(file));
57552
57621
  }
57553
57622
  function replaceScan(file, entry) {
57554
57623
  const idx = file.scans.findIndex((s2) => s2.id === entry.id);
@@ -61087,10 +61156,10 @@ function createGithubApi(args) {
61087
61156
  const seal = args.seal ?? sealWithSodium;
61088
61157
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
61089
61158
  const secretsPath = (slug, environment) => `/repos/${slug}/${environment ? `environments/${encodeURIComponent(environment)}` : "actions"}/secrets`;
61090
- async function request(method, path107, body) {
61159
+ async function request(method, path108, body) {
61091
61160
  let res;
61092
61161
  try {
61093
- res = await doFetch(`${API}${path107}`, {
61162
+ res = await doFetch(`${API}${path108}`, {
61094
61163
  method,
61095
61164
  headers: {
61096
61165
  Authorization: `Bearer ${args.token}`,
@@ -61115,8 +61184,8 @@ function createGithubApi(args) {
61115
61184
  }
61116
61185
  return { status: res.status, json };
61117
61186
  }
61118
- async function must(method, path107, what, body) {
61119
- const r2 = await request(method, path107, body);
61187
+ async function must(method, path108, what, body) {
61188
+ const r2 = await request(method, path108, body);
61120
61189
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
61121
61190
  return r2.json;
61122
61191
  }
@@ -61172,16 +61241,16 @@ function createGithubApi(args) {
61172
61241
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
61173
61242
  });
61174
61243
  },
61175
- async getJson(path107) {
61244
+ async getJson(path108) {
61176
61245
  try {
61177
- const r2 = await request("GET", path107);
61246
+ const r2 = await request("GET", path108);
61178
61247
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
61179
61248
  } catch {
61180
61249
  return void 0;
61181
61250
  }
61182
61251
  },
61183
- async getJsonStrict(path107) {
61184
- return must("GET", path107, "\u8BFB\u53D6\u53D1\u5E03\u8BB0\u5F55");
61252
+ async getJsonStrict(path108) {
61253
+ return must("GET", path108, "\u8BFB\u53D6\u53D1\u5E03\u8BB0\u5F55");
61185
61254
  },
61186
61255
  async downloadArtifact(slug, artifactId) {
61187
61256
  if (!Number.isSafeInteger(artifactId) || artifactId <= 0) throw new GithubApiError(0, "\u5236\u54C1 ID \u65E0\u6548");
@@ -61400,6 +61469,7 @@ function renderDeployWorkflow(config) {
61400
61469
  " sparse-checkout: |",
61401
61470
  " cloud-host/pipeline",
61402
61471
  " cloud-host/k8s",
61472
+ " cloud-host/src/persona-test-contract.mjs",
61403
61473
  "",
61404
61474
  " - name: \u8BFB\u90E8\u7F72\u6587\u4EF6",
61405
61475
  " id: plan",
@@ -61432,6 +61502,7 @@ function renderDeployWorkflow(config) {
61432
61502
  " - name: Check required credentials",
61433
61503
  " env:",
61434
61504
  " CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
61505
+ " CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
61435
61506
  " run: node clawos/cloud-host/pipeline/check-secrets.mjs",
61436
61507
  ""
61437
61508
  ];
@@ -61454,8 +61525,10 @@ function renderDeployWorkflow(config) {
61454
61525
  ` - name: ${script === "smoke" ? "Run real int smoke" : "Register the verified image"}`,
61455
61526
  " env:",
61456
61527
  " CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
61528
+ " CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
61457
61529
  " run: |",
61458
- ` IMAGE_REF=$(node clawos/cloud-host/pipeline/release.mjs validate --file candidate-release.json --component persona${script === "register" ? " --production" : ""})`,
61530
+ ` VALIDATE_PRODUCTION=''; if [ "\${{ inputs.environment }}" = 'production' ]; then VALIDATE_PRODUCTION='--production'; fi`,
61531
+ " IMAGE_REF=$(node clawos/cloud-host/pipeline/release.mjs validate --file candidate-release.json --component persona $VALIDATE_PRODUCTION)",
61459
61532
  ...script === "register" ? [" node clawos/cloud-host/pipeline/persona-candidate.mjs check-source"] : [],
61460
61533
  ` node clawos/cloud-host/pipeline/${script}.mjs \\`,
61461
61534
  ' --image "$IMAGE_REF" \\',
@@ -61547,6 +61620,7 @@ function renderDeployWorkflow(config) {
61547
61620
  " ALIBABA_CLOUD_ACCESS_KEY_ID: ${{ secrets.ALI_ACS_ACCESS_KEY_ID }}",
61548
61621
  " ALIBABA_CLOUD_ACCESS_KEY_SECRET: ${{ secrets.ALI_ACS_ACCESS_KEY_SECRET }}",
61549
61622
  " RELEASE_JSON: ${{ inputs.release_json }}",
61623
+ " CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
61550
61624
  " run: node clawos/cloud-host/pipeline/persona-candidate.mjs",
61551
61625
  "",
61552
61626
  ...upload("persona-candidate"),
@@ -61775,7 +61849,7 @@ var runCommand = (cmd, args, opts = {}) => new Promise((resolve9) => {
61775
61849
  });
61776
61850
 
61777
61851
  // src/deploy/repo.ts
61778
- var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path38.default.sep).join("/");
61852
+ var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path39.default.sep).join("/");
61779
61853
  var PERSONA_FILE_REL = ".clawd/persona.json";
61780
61854
  var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL];
61781
61855
  var RepoError = class extends Error {
@@ -61808,7 +61882,7 @@ async function prepareIntegration(exec, dir, auth) {
61808
61882
  for (const name of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"]) {
61809
61883
  const rel = await mustGit(exec, dir, ["rev-parse", "--git-path", name], "\u68C0\u67E5 Git \u64CD\u4F5C");
61810
61884
  try {
61811
- await import_promises5.default.stat(import_node_path38.default.resolve(dir, rel));
61885
+ await import_promises5.default.stat(import_node_path39.default.resolve(dir, rel));
61812
61886
  throw new RepoError("Git \u5408\u5E76\u6216\u53D8\u57FA\u8FD8\u672A\u5B8C\u6210\uFF0C\u5148\u5904\u7406\u518D\u53D1\u5E03");
61813
61887
  } catch (err) {
61814
61888
  if (err.code !== "ENOENT") throw err;
@@ -61869,7 +61943,7 @@ async function samePath(a2, b3) {
61869
61943
  try {
61870
61944
  return await import_promises5.default.realpath(x2);
61871
61945
  } catch {
61872
- return import_node_path38.default.resolve(x2);
61946
+ return import_node_path39.default.resolve(x2);
61873
61947
  }
61874
61948
  };
61875
61949
  return await real(a2) === await real(b3);
@@ -61895,7 +61969,7 @@ async function identityArgs(exec, dir) {
61895
61969
  return ["-c", "user.name=clawd", "-c", "user.email=clawd@clawos.local"];
61896
61970
  }
61897
61971
  async function writeGitignore(dir) {
61898
- const gi = import_node_path38.default.join(dir, ".gitignore");
61972
+ const gi = import_node_path39.default.join(dir, ".gitignore");
61899
61973
  let existing;
61900
61974
  try {
61901
61975
  existing = await import_promises5.default.readFile(gi, "utf8");
@@ -61906,18 +61980,18 @@ async function writeGitignore(dir) {
61906
61980
  }
61907
61981
  async function writeWorkflow(dir) {
61908
61982
  for (const [rel, body] of [[WORKFLOW_PATH, WORKFLOW_TEMPLATE], [UNPUBLISH_WORKFLOW_PATH, UNPUBLISH_WORKFLOW_TEMPLATE]]) {
61909
- const wf = import_node_path38.default.join(dir, rel);
61910
- await import_promises5.default.mkdir(import_node_path38.default.dirname(wf), { recursive: true });
61983
+ const wf = import_node_path39.default.join(dir, rel);
61984
+ await import_promises5.default.mkdir(import_node_path39.default.dirname(wf), { recursive: true });
61911
61985
  await import_promises5.default.writeFile(wf, body);
61912
61986
  }
61913
61987
  }
61914
61988
  async function writeDockerfile(dir, personaId2, image) {
61915
61989
  const baseImage = image.replace("registry-vpc.cn-hangzhou.aliyuncs.com/", "registry.cn-hangzhou.aliyuncs.com/");
61916
- await import_promises5.default.mkdir(import_node_path38.default.join(dir, ".clawd"), { recursive: true });
61917
- await import_promises5.default.writeFile(import_node_path38.default.join(dir, ".clawd", "base-image.txt"), `${baseImage}
61990
+ await import_promises5.default.mkdir(import_node_path39.default.join(dir, ".clawd"), { recursive: true });
61991
+ await import_promises5.default.writeFile(import_node_path39.default.join(dir, ".clawd", "base-image.txt"), `${baseImage}
61918
61992
  `);
61919
- await import_promises5.default.writeFile(import_node_path38.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2, baseImage));
61920
- await import_promises5.default.writeFile(import_node_path38.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
61993
+ await import_promises5.default.writeFile(import_node_path39.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2, baseImage));
61994
+ await import_promises5.default.writeFile(import_node_path39.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
61921
61995
  }
61922
61996
  var RepoAlreadyExistsError = class extends RepoError {
61923
61997
  constructor(slug) {
@@ -61956,7 +62030,7 @@ async function ensureRepo(exec, api, args) {
61956
62030
  const existing = await repoInfo(exec, dir);
61957
62031
  if (existing) return { created: false, url: existing.url };
61958
62032
  await writeGitignore(dir);
61959
- await import_promises5.default.rm(import_node_path38.default.join(dir, WORKFLOW_PATH), { force: true });
62033
+ await import_promises5.default.rm(import_node_path39.default.join(dir, WORKFLOW_PATH), { force: true });
61960
62034
  let created;
61961
62035
  try {
61962
62036
  created = await createOrgRepo(exec, api, { dir, org, repoName: personaId2, message: "clawd: \u4E0A\u4E91", auth: args.auth });
@@ -62056,7 +62130,8 @@ function validatePersonaRelease(raw, expected) {
62056
62130
  commit: record4.commit,
62057
62131
  baseImage: record4.baseImage,
62058
62132
  pipelineCommit: record4.pipelineCommit,
62059
- repository: record4.repository
62133
+ repository: record4.repository,
62134
+ ...record4.test ? { test: record4.test } : {}
62060
62135
  })).digest("hex");
62061
62136
  if (record4.verification.fingerprint !== fingerprint) throw new Error("\u5236\u54C1\u5DF2\u504F\u79BB\u6D4B\u8BD5\u65F6\u7684\u7248\u672C\uFF0C\u8BF7\u91CD\u65B0\u6D4B\u8BD5");
62062
62137
  return record4;
@@ -62084,6 +62159,7 @@ async function readVerifiedRelease(api, slug, run) {
62084
62159
  }) };
62085
62160
  }
62086
62161
  function requireDialogueVerification(release2, run) {
62162
+ if (release2.test && (!release2.verification.checks.includes("persona-custom-test") || !release2.verification.test)) throw new Error("\u53D1\u5E03\u8005\u6D4B\u8BD5\u672A\u901A\u8FC7\uFF0C\u8BF7\u91CD\u65B0\u53D1\u5E03\u6D4B\u8BD5\u73AF\u5883");
62087
62163
  if (!["persona-dialogue", "persona-task"].every((check) => release2.verification.checks.includes(check)) || !run.jobs.some((j2) => j2.key === DEPLOY_VERIFY_STAGE && j2.status === "done")) {
62088
62164
  throw new Error("\u8FD9\u6B21\u53D1\u5E03\u8FD8\u6CA1\u6709\u901A\u8FC7\u81EA\u52A8 Conversation / Task \u9A8C\u8BC1\uFF0C\u8BF7\u91CD\u65B0\u626B\u63CF\u5E76\u53D1\u5E03\u6D4B\u8BD5\u73AF\u5883");
62089
62165
  }
@@ -62172,9 +62248,9 @@ init_protocol();
62172
62248
 
62173
62249
  // src/deploy/artifact.ts
62174
62250
  var import_node_crypto13 = require("crypto");
62175
- var import_node_fs34 = __toESM(require("fs"), 1);
62251
+ var import_node_fs35 = __toESM(require("fs"), 1);
62176
62252
  var import_node_os11 = __toESM(require("os"), 1);
62177
- var import_node_path39 = __toESM(require("path"), 1);
62253
+ var import_node_path40 = __toESM(require("path"), 1);
62178
62254
  var import_node_stream3 = require("stream");
62179
62255
  var import_promises6 = require("stream/promises");
62180
62256
  var ARTIFACT_MAX_BYTES = 200 * 1024 * 1024;
@@ -62208,8 +62284,8 @@ function downloadArtifact(exec) {
62208
62284
  if (!res.ok || !res.body) throw new Error(`\u4E0B\u8F7D\u5931\u8D25 HTTP ${res.status}\uFF1A${url}`);
62209
62285
  const declared = Number(res.headers.get("content-length") ?? 0);
62210
62286
  if (declared > ARTIFACT_MAX_BYTES) throw new Error(`\u8D44\u4EA7 ${declared} \u5B57\u8282\uFF0C\u8D85\u8FC7\u4E0A\u9650 ${ARTIFACT_MAX_BYTES}\uFF1A${url}`);
62211
- const dir = await import_node_fs34.default.promises.mkdtemp(import_node_path39.default.join(import_node_os11.default.tmpdir(), "clawd-artifact-"));
62212
- const file = import_node_path39.default.join(dir, "pkg");
62287
+ const dir = await import_node_fs35.default.promises.mkdtemp(import_node_path40.default.join(import_node_os11.default.tmpdir(), "clawd-artifact-"));
62288
+ const file = import_node_path40.default.join(dir, "pkg");
62213
62289
  const hash = (0, import_node_crypto13.createHash)("sha256");
62214
62290
  let size = 0;
62215
62291
  const meter = new import_node_stream3.Transform({
@@ -62221,7 +62297,7 @@ function downloadArtifact(exec) {
62221
62297
  }
62222
62298
  });
62223
62299
  try {
62224
- await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter, import_node_fs34.default.createWriteStream(file));
62300
+ await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter, import_node_fs35.default.createWriteStream(file));
62225
62301
  let entries;
62226
62302
  if (listEntries) {
62227
62303
  const r2 = await exec("tar", ["-tzf", file], { timeoutMs: 3e4 });
@@ -62230,7 +62306,7 @@ function downloadArtifact(exec) {
62230
62306
  }
62231
62307
  return { sha256: hash.digest("hex"), size, ...entries ? { entries } : {} };
62232
62308
  } finally {
62233
- await import_node_fs34.default.promises.rm(dir, { recursive: true, force: true });
62309
+ await import_node_fs35.default.promises.rm(dir, { recursive: true, force: true });
62234
62310
  }
62235
62311
  };
62236
62312
  }
@@ -62283,12 +62359,12 @@ init_protocol();
62283
62359
  // src/deploy/publishing-config.ts
62284
62360
  async function requireIntegrationPublishingConfig(api, slug) {
62285
62361
  const base = `/repos/${slug}`;
62286
- async function rows(path107, field, absentEnvironment = false) {
62362
+ async function rows(path108, field, absentEnvironment = false) {
62287
62363
  const result = [];
62288
62364
  for (let page = 1; page <= 30; page++) {
62289
62365
  let raw;
62290
62366
  try {
62291
- raw = await api.getJsonStrict(`${path107}?per_page=100&page=${page}`);
62367
+ raw = await api.getJsonStrict(`${path108}?per_page=100&page=${page}`);
62292
62368
  } catch (error) {
62293
62369
  if (absentEnvironment && page === 1 && error instanceof GithubApiError && error.status === 404) return [];
62294
62370
  throw error;
@@ -62796,15 +62872,17 @@ function buildDeployHandlers(deps) {
62796
62872
  const lastDone = [...file.scans].reverse().find((s2) => s2.status === "done");
62797
62873
  const seed = scanBase.kind === "soft" && releasedEntry ? releasedEntry.manifest : { ...emptyDeployFile().manifest, connectors: (lastDone?.manifest.connectors ?? []).filter((c2) => c2.runner === "mcp") };
62798
62874
  const mcp = scanMcpConnectors(dir);
62875
+ const publisherTest = discoverPublisherTest(dir);
62876
+ const { test: _previousTest, ...seedWithoutTest } = seed;
62799
62877
  const mcpTargets = new Set(mcp.evidence.map((e) => e.target));
62800
62878
  const carriedEvidence = scanBase.kind === "soft" && releasedEntry ? releasedEntry.evidence : [];
62801
62879
  const entry = {
62802
62880
  id: newScanId(),
62803
62881
  status: "scanning",
62804
- manifest: { ...seed, connectors: mcp.readable ? mergeScannedConnectors(seed.connectors, mcp.connectors) : seed.connectors },
62882
+ manifest: { ...seedWithoutTest, ...publisherTest.test ? { test: publisherTest.test } : {}, connectors: mcp.readable ? mergeScannedConnectors(seed.connectors, mcp.connectors) : seed.connectors },
62805
62883
  evidence: [...carriedEvidence.filter((e) => !mcpTargets.has(e.target)), ...mcp.evidence.map(redactEvidence)],
62806
62884
  // Notes describe this scan's unresolved work; do not carry old notes into a new scan.
62807
- notes: mcp.warnings.map((w3) => `${MCP_SCAN_NOTE_PREFIX}${w3}`),
62885
+ notes: [...mcp.warnings.map((w3) => `${MCP_SCAN_NOTE_PREFIX}${w3}`), ...publisherTest.problems.map((problem) => TEST_SCAN_NOTE_PREFIX + problem)],
62808
62886
  startedAt: deps.now(),
62809
62887
  head: contentHead,
62810
62888
  baseKind: scanBase.kind,
@@ -63004,7 +63082,7 @@ function buildDeployHandlers(deps) {
63004
63082
  status: "done",
63005
63083
  finishedAt: deps.now(),
63006
63084
  // Redact free-text notes and preserve scanner warnings that the butler does not know about.
63007
- notes: [...scan.notes.filter((n2) => n2.startsWith(MCP_SCAN_NOTE_PREFIX)), ...args.notes.map(redactSecretValues)],
63085
+ notes: [...scan.notes.filter((n2) => n2.startsWith(MCP_SCAN_NOTE_PREFIX) || n2.startsWith(TEST_SCAN_NOTE_PREFIX)), ...args.notes.map(redactSecretValues)],
63008
63086
  error: void 0
63009
63087
  }));
63010
63088
  return view(args.personaId);
@@ -63068,6 +63146,10 @@ function buildDeployHandlers(deps) {
63068
63146
  if (repo2.branch !== "integration") throw invalid("\u8BF7\u91CD\u65B0\u626B\u63CF\uFF0C\u5207\u5230\u6D4B\u8BD5\u53D1\u5E03\u5206\u652F\u540E\u518D\u53D1\u5E03");
63069
63147
  const file = await readHistory(dir);
63070
63148
  const entry = mustScan(file, scanId);
63149
+ const publisherTest = discoverPublisherTest(dir);
63150
+ const testBlockers = [...publisherTest.problems, ...entry.notes.filter((note) => note.startsWith(TEST_SCAN_NOTE_PREFIX))];
63151
+ if (JSON.stringify(publisherTest.test) !== JSON.stringify(entry.manifest.test)) testBlockers.push("\u6D4B\u8BD5\u58F0\u660E\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u626B\u63CF");
63152
+ if (testBlockers.length) throw invalid("\u8FD8\u5DEE\uFF1A" + testBlockers.join("\uFF1B"));
63071
63153
  const pending = file.releases.find((r2) => r2.environment === "integration" && r2.scanId === scanId && !r2.pushed);
63072
63154
  if (pending) {
63073
63155
  try {
@@ -63305,14 +63387,14 @@ function buildDeployHandlers(deps) {
63305
63387
  }
63306
63388
 
63307
63389
  // src/tools/subscription-channels-store.ts
63308
- var import_node_fs36 = __toESM(require("fs"), 1);
63390
+ var import_node_fs37 = __toESM(require("fs"), 1);
63309
63391
  var import_node_os13 = __toESM(require("os"), 1);
63310
- var import_node_path41 = __toESM(require("path"), 1);
63392
+ var import_node_path42 = __toESM(require("path"), 1);
63311
63393
 
63312
63394
  // src/tools/subscription-channels-apply.ts
63313
- var import_node_fs35 = __toESM(require("fs"), 1);
63395
+ var import_node_fs36 = __toESM(require("fs"), 1);
63314
63396
  var import_node_os12 = __toESM(require("os"), 1);
63315
- var import_node_path40 = __toESM(require("path"), 1);
63397
+ var import_node_path41 = __toESM(require("path"), 1);
63316
63398
 
63317
63399
  // src/tools/codex-config-toml.ts
63318
63400
  function parseKey(src, start) {
@@ -63494,29 +63576,29 @@ function parseValueAt(s2, start) {
63494
63576
  const bare = /^[^\s,\]}#]+/.exec(s2.slice(i2));
63495
63577
  return bare ? { value: bare[0], end: i2 + bare[0].length } : null;
63496
63578
  }
63497
- function setPath(target, path107, value) {
63579
+ function setPath(target, path108, value) {
63498
63580
  let node = target;
63499
- for (const part of path107.slice(0, -1)) {
63581
+ for (const part of path108.slice(0, -1)) {
63500
63582
  const next = node[part];
63501
63583
  if (!next || typeof next !== "object" || Array.isArray(next)) node[part] = {};
63502
63584
  node = node[part];
63503
63585
  }
63504
- const last = path107[path107.length - 1];
63586
+ const last = path108[path108.length - 1];
63505
63587
  const existing = node[last];
63506
63588
  if (existing && typeof existing === "object" && !Array.isArray(existing) && value && typeof value === "object" && !Array.isArray(value)) {
63507
63589
  Object.assign(existing, value);
63508
63590
  } else node[last] = value;
63509
63591
  }
63510
- function readTomlTable(text, path107) {
63592
+ function readTomlTable(text, path108) {
63511
63593
  const result = {};
63512
63594
  let found = false;
63513
- const within = (full) => full.length >= path107.length && path107.every((part, i2) => full[i2] === part);
63595
+ const within = (full) => full.length >= path108.length && path108.every((part, i2) => full[i2] === part);
63514
63596
  const lines = scanToml(text);
63515
63597
  for (let index = 0; index < lines.length; index++) {
63516
63598
  const line = lines[index];
63517
63599
  if (line.kind === "header" && within(line.key)) {
63518
63600
  found = true;
63519
- if (line.key.length > path107.length) setPath(result, line.key.slice(path107.length), {});
63601
+ if (line.key.length > path108.length) setPath(result, line.key.slice(path108.length), {});
63520
63602
  continue;
63521
63603
  }
63522
63604
  if (line.kind !== "key") continue;
@@ -63528,16 +63610,16 @@ ${lines[++index].text}`;
63528
63610
  const parsed = parseTomlValue(raw);
63529
63611
  const value = parsed === void 0 ? UNREADABLE : parsed;
63530
63612
  found = true;
63531
- if (full.length === path107.length) {
63613
+ if (full.length === path108.length) {
63532
63614
  if (value && typeof value === "object" && !Array.isArray(value)) Object.assign(result, value);
63533
- } else setPath(result, full.slice(path107.length), value);
63615
+ } else setPath(result, full.slice(path108.length), value);
63534
63616
  }
63535
63617
  return found ? result : null;
63536
63618
  }
63537
63619
 
63538
63620
  // src/tools/subscription-channels-apply.ts
63539
63621
  var PROVIDER_ID = "cliproxyapi";
63540
- var isOwnProvider = (path107) => path107[0] === "model_providers" && path107[1] === PROVIDER_ID;
63622
+ var isOwnProvider = (path108) => path108[0] === "model_providers" && path108[1] === PROVIDER_ID;
63541
63623
  function stripCodexProvider(text) {
63542
63624
  const out = [];
63543
63625
  let dropping = false;
@@ -63565,31 +63647,31 @@ function stripCodexProvider(text) {
63565
63647
  return out.join("\n").trim();
63566
63648
  }
63567
63649
  function writeFileAtomic(file, data) {
63568
- const target = import_node_fs35.default.existsSync(file) && import_node_fs35.default.lstatSync(file).isSymbolicLink() ? import_node_fs35.default.realpathSync(file) : file;
63650
+ const target = import_node_fs36.default.existsSync(file) && import_node_fs36.default.lstatSync(file).isSymbolicLink() ? import_node_fs36.default.realpathSync(file) : file;
63569
63651
  const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
63570
- import_node_fs35.default.writeFileSync(tmp, data, { mode: 384 });
63571
- import_node_fs35.default.renameSync(tmp, target);
63652
+ import_node_fs36.default.writeFileSync(tmp, data, { mode: 384 });
63653
+ import_node_fs36.default.renameSync(tmp, target);
63572
63654
  }
63573
63655
  function snapshotFile(file) {
63574
- const original = import_node_fs35.default.existsSync(file) ? import_node_fs35.default.readFileSync(file) : null;
63656
+ const original = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
63575
63657
  return () => {
63576
- const current = import_node_fs35.default.existsSync(file) ? import_node_fs35.default.readFileSync(file) : null;
63658
+ const current = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
63577
63659
  if (original === null) {
63578
- if (current !== null) import_node_fs35.default.rmSync(file, { force: true });
63660
+ if (current !== null) import_node_fs36.default.rmSync(file, { force: true });
63579
63661
  return;
63580
63662
  }
63581
63663
  if (current !== null && current.equals(original)) return;
63582
63664
  writeFileAtomic(file, original);
63583
63665
  };
63584
63666
  }
63585
- var resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path40.default.join(import_node_os12.default.homedir(), ".codex");
63586
- var resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path40.default.join(import_node_os12.default.homedir(), ".pi", "agent");
63667
+ var resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path41.default.join(import_node_os12.default.homedir(), ".codex");
63668
+ var resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os12.default.homedir(), ".pi", "agent");
63587
63669
  var PI_SUBSCRIPTION_FILE = "cliproxyapi.json";
63588
63670
  function applyCodexSubscriptionChannel(opts) {
63589
63671
  const codexHome = resolveCodexHome2(opts.codexHome);
63590
- import_node_fs35.default.mkdirSync(codexHome, { recursive: true });
63591
- const configFile = import_node_path40.default.join(codexHome, "config.toml");
63592
- const original = import_node_fs35.default.existsSync(configFile) ? import_node_fs35.default.readFileSync(configFile, "utf8") : "";
63672
+ import_node_fs36.default.mkdirSync(codexHome, { recursive: true });
63673
+ const configFile = import_node_path41.default.join(codexHome, "config.toml");
63674
+ const original = import_node_fs36.default.existsSync(configFile) ? import_node_fs36.default.readFileSync(configFile, "utf8") : "";
63593
63675
  const rest = stripCodexProvider(original);
63594
63676
  let content;
63595
63677
  if (opts.channel) {
@@ -63616,8 +63698,8 @@ function applyCodexSubscriptionChannel(opts) {
63616
63698
  }
63617
63699
  function applyPiSubscriptionChannel(opts) {
63618
63700
  const agentDir = resolvePiAgentDir(opts.agentDir);
63619
- if (!import_node_fs35.default.existsSync(agentDir)) return false;
63620
- const configFile = import_node_path40.default.join(agentDir, PI_SUBSCRIPTION_FILE);
63701
+ if (!import_node_fs36.default.existsSync(agentDir)) return false;
63702
+ const configFile = import_node_path41.default.join(agentDir, PI_SUBSCRIPTION_FILE);
63621
63703
  if (opts.channel) {
63622
63704
  const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
63623
63705
  writeFileAtomic(configFile, JSON.stringify(data, null, 2) + "\n");
@@ -63646,7 +63728,7 @@ function providerKey(provider, codexHome) {
63646
63728
  }
63647
63729
  function readAuthKey2(codexHome) {
63648
63730
  try {
63649
- const key = JSON.parse(import_node_fs36.default.readFileSync(import_node_path41.default.join(codexHome, "auth.json"), "utf8")).OPENAI_API_KEY;
63731
+ const key = JSON.parse(import_node_fs37.default.readFileSync(import_node_path42.default.join(codexHome, "auth.json"), "utf8")).OPENAI_API_KEY;
63650
63732
  return typeof key === "string" && key ? key : null;
63651
63733
  } catch {
63652
63734
  return null;
@@ -63656,8 +63738,8 @@ var SubscriptionChannelStore = class {
63656
63738
  filePath;
63657
63739
  codexHome;
63658
63740
  constructor(options) {
63659
- this.filePath = import_node_path41.default.join(options.dataDir, CHANNELS_FILE_NAME);
63660
- this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path41.default.join(import_node_os13.default.homedir(), ".codex");
63741
+ this.filePath = import_node_path42.default.join(options.dataDir, CHANNELS_FILE_NAME);
63742
+ this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path42.default.join(import_node_os13.default.homedir(), ".codex");
63661
63743
  }
63662
63744
  /** 存储文件的快照(首次初始化 / 迁移先落盘);返回的函数把它恢复成此刻的样子,通道切换失败时回滚用 */
63663
63745
  snapshot() {
@@ -63754,9 +63836,9 @@ var SubscriptionChannelStore = class {
63754
63836
  return target;
63755
63837
  }
63756
63838
  readOrCreate() {
63757
- if (import_node_fs36.default.existsSync(this.filePath)) {
63839
+ if (import_node_fs37.default.existsSync(this.filePath)) {
63758
63840
  try {
63759
- const raw = JSON.parse(import_node_fs36.default.readFileSync(this.filePath, "utf8"));
63841
+ const raw = JSON.parse(import_node_fs37.default.readFileSync(this.filePath, "utf8"));
63760
63842
  if (raw && Array.isArray(raw.channels)) {
63761
63843
  return {
63762
63844
  activeChannelId: typeof raw.activeChannelId === "string" ? raw.activeChannelId : null,
@@ -63776,9 +63858,9 @@ var SubscriptionChannelStore = class {
63776
63858
  }
63777
63859
  tryMigrateFromCodexConfig() {
63778
63860
  try {
63779
- const configPath = import_node_path41.default.join(this.codexHome, "config.toml");
63780
- if (!import_node_fs36.default.existsSync(configPath)) return null;
63781
- const content = import_node_fs36.default.readFileSync(configPath, "utf8");
63861
+ const configPath = import_node_path42.default.join(this.codexHome, "config.toml");
63862
+ if (!import_node_fs37.default.existsSync(configPath)) return null;
63863
+ const content = import_node_fs37.default.readFileSync(configPath, "utf8");
63782
63864
  if (readTomlTable(content, [])?.model_provider !== "cliproxyapi") return null;
63783
63865
  const provider = readTomlTable(content, ["model_providers", "cliproxyapi"]);
63784
63866
  if (!provider) return null;
@@ -63805,8 +63887,8 @@ var SubscriptionChannelStore = class {
63805
63887
  return null;
63806
63888
  }
63807
63889
  write(data) {
63808
- const dir = import_node_path41.default.dirname(this.filePath);
63809
- import_node_fs36.default.mkdirSync(dir, { recursive: true });
63890
+ const dir = import_node_path42.default.dirname(this.filePath);
63891
+ import_node_fs37.default.mkdirSync(dir, { recursive: true });
63810
63892
  writeFileAtomic(this.filePath, JSON.stringify(data, null, 2) + "\n");
63811
63893
  }
63812
63894
  };
@@ -63869,8 +63951,8 @@ function refreshPathFromLoginShell() {
63869
63951
  timeout: 3e3,
63870
63952
  stdio: ["ignore", "pipe", "ignore"]
63871
63953
  });
63872
- const path107 = out.trim();
63873
- if (path107) process.env.PATH = path107;
63954
+ const path108 = out.trim();
63955
+ if (path108) process.env.PATH = path108;
63874
63956
  } catch {
63875
63957
  }
63876
63958
  }
@@ -64663,10 +64745,10 @@ function createCloudPersonaBotClient(opts) {
64663
64745
  const f2 = opts.fetchImpl ?? fetch;
64664
64746
  const base = opts.api.replace(/\/+$/, "");
64665
64747
  const route = (personaId2) => `/api/lark-bot/cloud/${encodeURIComponent(personaId2)}`;
64666
- async function request(method, path107, body) {
64748
+ async function request(method, path108, body) {
64667
64749
  const pass = opts.getLoginPass();
64668
64750
  if (!pass) throw new LarkBotCloudError("\u98DE\u4E66\u767B\u5F55\u540E\u624D\u80FD\u7BA1\u7406\u4E91 Persona \u7684 Bot", 401);
64669
- const response = await f2(base + path107, {
64751
+ const response = await f2(base + path108, {
64670
64752
  method,
64671
64753
  headers: { authorization: `Bearer ${pass}`, "content-type": "application/json" },
64672
64754
  ...body ? { body: JSON.stringify(body) } : {},
@@ -64675,7 +64757,7 @@ function createCloudPersonaBotClient(opts) {
64675
64757
  const json = await response.json().catch(() => ({}));
64676
64758
  if (!response.ok) {
64677
64759
  const detail = typeof json.message === "string" ? json.message : `HTTP ${response.status}`;
64678
- throw new LarkBotCloudError(`cloud bot ${method} ${path107}: ${detail}`, response.status);
64760
+ throw new LarkBotCloudError(`cloud bot ${method} ${path108}: ${detail}`, response.status);
64679
64761
  }
64680
64762
  return json;
64681
64763
  }
@@ -64691,15 +64773,15 @@ function createCloudPersonaBotClient(opts) {
64691
64773
  }
64692
64774
 
64693
64775
  // src/lark-bot-connector/binding-store.ts
64694
- var import_node_fs37 = __toESM(require("fs"), 1);
64695
- var import_node_path42 = __toESM(require("path"), 1);
64776
+ var import_node_fs38 = __toESM(require("fs"), 1);
64777
+ var import_node_path43 = __toESM(require("path"), 1);
64696
64778
  function createLarkBotBindingStore(personaRoot) {
64697
- const filePath = (personaId2) => import_node_path42.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
64779
+ const filePath = (personaId2) => import_node_path43.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
64698
64780
  const read = (personaId2) => {
64699
64781
  const file = filePath(personaId2);
64700
- if (!import_node_fs37.default.existsSync(file)) return null;
64782
+ if (!import_node_fs38.default.existsSync(file)) return null;
64701
64783
  try {
64702
- const raw = JSON.parse(import_node_fs37.default.readFileSync(file, "utf8"));
64784
+ const raw = JSON.parse(import_node_fs38.default.readFileSync(file, "utf8"));
64703
64785
  if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
64704
64786
  return raw;
64705
64787
  } catch {
@@ -64708,16 +64790,16 @@ function createLarkBotBindingStore(personaRoot) {
64708
64790
  };
64709
64791
  const write = (personaId2, meta) => {
64710
64792
  const file = filePath(personaId2);
64711
- import_node_fs37.default.mkdirSync(import_node_path42.default.dirname(file), { recursive: true });
64793
+ import_node_fs38.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
64712
64794
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
64713
- import_node_fs37.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
64714
- import_node_fs37.default.renameSync(tmp, file);
64795
+ import_node_fs38.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
64796
+ import_node_fs38.default.renameSync(tmp, file);
64715
64797
  };
64716
64798
  return {
64717
64799
  read,
64718
64800
  write,
64719
64801
  remove(personaId2) {
64720
- import_node_fs37.default.rmSync(filePath(personaId2), { force: true });
64802
+ import_node_fs38.default.rmSync(filePath(personaId2), { force: true });
64721
64803
  },
64722
64804
  addRemovedChat(personaId2, chatId) {
64723
64805
  const meta = read(personaId2);
@@ -64730,8 +64812,8 @@ function createLarkBotBindingStore(personaRoot) {
64730
64812
  }
64731
64813
 
64732
64814
  // src/lark-bot-connector/chat-router.ts
64733
- var import_node_fs38 = __toESM(require("fs"), 1);
64734
- var import_node_path43 = __toESM(require("path"), 1);
64815
+ var import_node_fs39 = __toESM(require("fs"), 1);
64816
+ var import_node_path44 = __toESM(require("path"), 1);
64735
64817
  init_protocol();
64736
64818
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
64737
64819
  var LOCAL_TURN_RETRIES = 2;
@@ -64809,9 +64891,9 @@ function createLarkChatRouter(deps) {
64809
64891
  continue;
64810
64892
  }
64811
64893
  const dir = deps.mediaRootFor(env.chatId);
64812
- import_node_fs38.default.mkdirSync(dir, { recursive: true });
64813
- const p3 = import_node_path43.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
64814
- import_node_fs38.default.writeFileSync(p3, r2.data);
64894
+ import_node_fs39.default.mkdirSync(dir, { recursive: true });
64895
+ const p3 = import_node_path44.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
64896
+ import_node_fs39.default.writeFileSync(p3, r2.data);
64815
64897
  lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
64816
64898
  } catch (err) {
64817
64899
  deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
@@ -64832,9 +64914,9 @@ function createLarkChatRouter(deps) {
64832
64914
  continue;
64833
64915
  }
64834
64916
  const dir = deps.mediaRootFor(env.chatId);
64835
- import_node_fs38.default.mkdirSync(dir, { recursive: true });
64836
- const p3 = import_node_path43.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
64837
- import_node_fs38.default.writeFileSync(p3, r2.data);
64917
+ import_node_fs39.default.mkdirSync(dir, { recursive: true });
64918
+ const p3 = import_node_path44.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
64919
+ import_node_fs39.default.writeFileSync(p3, r2.data);
64838
64920
  lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
64839
64921
  } catch (err) {
64840
64922
  deps.logger?.warn(`larkBot file fetch failed ${f2.key}: ${err.message}`);
@@ -65648,7 +65730,7 @@ async function forwardPeerExecToPeer(args) {
65648
65730
  init_protocol();
65649
65731
 
65650
65732
  // src/tools/codex-cloud-session.ts
65651
- var import_node_fs39 = __toESM(require("fs"), 1);
65733
+ var import_node_fs40 = __toESM(require("fs"), 1);
65652
65734
 
65653
65735
  // src/tools/cloud-portable-input.ts
65654
65736
  async function portableCloudInput(text, resolvers) {
@@ -65803,7 +65885,7 @@ function cloudImageInput(deps) {
65803
65885
  const mime = lookupMime(p3);
65804
65886
  if (!mime.startsWith("image/")) return null;
65805
65887
  try {
65806
- const bytes = (deps.readFile ?? import_node_fs39.default.readFileSync)(p3);
65888
+ const bytes = (deps.readFile ?? import_node_fs40.default.readFileSync)(p3);
65807
65889
  return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
65808
65890
  } catch (e) {
65809
65891
  deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
@@ -65905,7 +65987,7 @@ init_protocol();
65905
65987
 
65906
65988
  // src/tools/pi.ts
65907
65989
  var import_node_child_process13 = require("child_process");
65908
- var import_node_fs41 = __toESM(require("fs"), 1);
65990
+ var import_node_fs42 = __toESM(require("fs"), 1);
65909
65991
  init_protocol();
65910
65992
 
65911
65993
  // src/tools/pi-rpc-client.ts
@@ -66006,8 +66088,8 @@ var PiRpcClient = class {
66006
66088
  // src/tools/pi-session.ts
66007
66089
  var import_node_child_process12 = require("child_process");
66008
66090
  var import_node_crypto17 = require("crypto");
66009
- var import_node_fs40 = __toESM(require("fs"), 1);
66010
- var import_node_path44 = __toESM(require("path"), 1);
66091
+ var import_node_fs41 = __toESM(require("fs"), 1);
66092
+ var import_node_path45 = __toESM(require("path"), 1);
66011
66093
 
66012
66094
  // src/tools/pi-events.ts
66013
66095
  init_protocol();
@@ -66288,8 +66370,8 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
66288
66370
  function createPiSession(ctx, sink, deps = {}) {
66289
66371
  const cmd = process.env.PI_BIN ?? "pi";
66290
66372
  const sessionId = ctx.toolSessionId ?? (0, import_node_crypto17.randomUUID)();
66291
- const skillsDir = import_node_path44.default.join(ctx.cwd, ".claude", "skills");
66292
- const exists = deps.skillsDirExists ?? ((d2) => import_node_fs40.default.existsSync(d2));
66373
+ const skillsDir = import_node_path45.default.join(ctx.cwd, ".claude", "skills");
66374
+ const exists = deps.skillsDirExists ?? ((d2) => import_node_fs41.default.existsSync(d2));
66293
66375
  const args = buildPiArgs(ctx, {
66294
66376
  sessionId,
66295
66377
  skillsDir: exists(skillsDir) ? skillsDir : void 0,
@@ -66351,10 +66433,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
66351
66433
  };
66352
66434
  var PI_FULL_ACCESS = { id: "never", label: "Full Access", description: "pi \u65E0\u5BA1\u6279\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
66353
66435
  async function probePi(env = process.env) {
66354
- if (env.PI_BIN && import_node_fs41.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
66436
+ if (env.PI_BIN && import_node_fs42.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
66355
66437
  try {
66356
66438
  const out = (0, import_node_child_process13.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
66357
- if (out && import_node_fs41.default.existsSync(out)) return { available: true, path: out };
66439
+ if (out && import_node_fs42.default.existsSync(out)) return { available: true, path: out };
66358
66440
  } catch {
66359
66441
  }
66360
66442
  return { available: false };
@@ -66644,7 +66726,7 @@ var CloudPiAdapter = class {
66644
66726
  init_protocol();
66645
66727
 
66646
66728
  // src/tools/codex-skills.ts
66647
- var import_node_path45 = __toESM(require("path"), 1);
66729
+ var import_node_path46 = __toESM(require("path"), 1);
66648
66730
  function str4(v3) {
66649
66731
  return typeof v3 === "string" ? v3 : void 0;
66650
66732
  }
@@ -66659,13 +66741,13 @@ function mapSkillsListResponse(res) {
66659
66741
  const r2 = s2 ?? {};
66660
66742
  const name = str4(r2.name);
66661
66743
  if (!name) continue;
66662
- const path107 = str4(r2.path);
66744
+ const path108 = str4(r2.path);
66663
66745
  const description = str4(r2.description);
66664
66746
  const isPlugin = name.includes(":");
66665
66747
  out.push({
66666
66748
  name,
66667
66749
  source: isPlugin ? "plugin" : "project",
66668
- ...path107 ? { path: path107 } : {},
66750
+ ...path108 ? { path: path108 } : {},
66669
66751
  ...description ? { description } : {},
66670
66752
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
66671
66753
  });
@@ -66681,7 +66763,7 @@ async function listCodexSkills(cwd, deps = {}) {
66681
66763
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
66682
66764
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
66683
66765
  beforeRequest: (client) => {
66684
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path45.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66766
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path46.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66685
66767
  }
66686
66768
  });
66687
66769
  return mapSkillsListResponse(res);
@@ -66755,23 +66837,23 @@ function rec4(v3) {
66755
66837
  }
66756
66838
 
66757
66839
  // src/workspace/browser.ts
66758
- var import_node_fs42 = __toESM(require("fs"), 1);
66840
+ var import_node_fs43 = __toESM(require("fs"), 1);
66759
66841
  var import_node_os15 = __toESM(require("os"), 1);
66760
- var import_node_path46 = __toESM(require("path"), 1);
66842
+ var import_node_path47 = __toESM(require("path"), 1);
66761
66843
  init_protocol();
66762
66844
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
66763
66845
  function resolveInsideCwd(cwd, subpath) {
66764
- const absCwd = import_node_path46.default.resolve(cwd);
66765
- const joined = import_node_path46.default.resolve(absCwd, subpath ?? ".");
66766
- const rel = import_node_path46.default.relative(absCwd, joined);
66767
- if (rel.startsWith("..") || import_node_path46.default.isAbsolute(rel)) {
66846
+ const absCwd = import_node_path47.default.resolve(cwd);
66847
+ const joined = import_node_path47.default.resolve(absCwd, subpath ?? ".");
66848
+ const rel = import_node_path47.default.relative(absCwd, joined);
66849
+ if (rel.startsWith("..") || import_node_path47.default.isAbsolute(rel)) {
66768
66850
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
66769
66851
  }
66770
66852
  return joined;
66771
66853
  }
66772
66854
  function ensureCwd(cwd) {
66773
66855
  try {
66774
- const stat = import_node_fs42.default.statSync(cwd);
66856
+ const stat = import_node_fs43.default.statSync(cwd);
66775
66857
  if (!stat.isDirectory()) {
66776
66858
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
66777
66859
  }
@@ -66785,7 +66867,7 @@ var WorkspaceBrowser = class {
66785
66867
  const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os15.default.homedir();
66786
66868
  ensureCwd(cwd);
66787
66869
  const full = resolveInsideCwd(cwd, args.path);
66788
- const dirents = import_node_fs42.default.readdirSync(full, { withFileTypes: true });
66870
+ const dirents = import_node_fs43.default.readdirSync(full, { withFileTypes: true });
66789
66871
  const entries = [];
66790
66872
  for (const d2 of dirents) {
66791
66873
  if (!args.showHidden && d2.name.startsWith(".")) continue;
@@ -66795,7 +66877,7 @@ var WorkspaceBrowser = class {
66795
66877
  mtime: ""
66796
66878
  };
66797
66879
  try {
66798
- const st2 = import_node_fs42.default.statSync(import_node_path46.default.join(full, d2.name));
66880
+ const st2 = import_node_fs43.default.statSync(import_node_path47.default.join(full, d2.name));
66799
66881
  entry.mtime = new Date(st2.mtimeMs).toISOString();
66800
66882
  if (d2.isFile()) entry.size = st2.size;
66801
66883
  } catch {
@@ -66811,14 +66893,14 @@ var WorkspaceBrowser = class {
66811
66893
  read(args) {
66812
66894
  ensureCwd(args.cwd);
66813
66895
  const full = resolveInsideCwd(args.cwd, args.path);
66814
- const st2 = import_node_fs42.default.statSync(full);
66896
+ const st2 = import_node_fs43.default.statSync(full);
66815
66897
  if (!st2.isFile()) {
66816
66898
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
66817
66899
  }
66818
66900
  if (st2.size > MAX_FILE_BYTES2) {
66819
66901
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
66820
66902
  }
66821
- const buf = import_node_fs42.default.readFileSync(full);
66903
+ const buf = import_node_fs43.default.readFileSync(full);
66822
66904
  const isBinary = buf.includes(0);
66823
66905
  if (isBinary) {
66824
66906
  return {
@@ -66840,20 +66922,20 @@ var WorkspaceBrowser = class {
66840
66922
  };
66841
66923
 
66842
66924
  // src/skills/agents-scanner.ts
66843
- var import_node_fs43 = __toESM(require("fs"), 1);
66925
+ var import_node_fs44 = __toESM(require("fs"), 1);
66844
66926
  var import_node_os16 = __toESM(require("os"), 1);
66845
- var import_node_path47 = __toESM(require("path"), 1);
66927
+ var import_node_path48 = __toESM(require("path"), 1);
66846
66928
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
66847
66929
  function isDirLikeSync2(p3) {
66848
66930
  try {
66849
- return import_node_fs43.default.statSync(p3).isDirectory();
66931
+ return import_node_fs44.default.statSync(p3).isDirectory();
66850
66932
  } catch {
66851
66933
  return false;
66852
66934
  }
66853
66935
  }
66854
66936
  function fileExistsSync(p3) {
66855
66937
  try {
66856
- return import_node_fs43.default.statSync(p3).isFile();
66938
+ return import_node_fs44.default.statSync(p3).isFile();
66857
66939
  } catch {
66858
66940
  return false;
66859
66941
  }
@@ -66861,7 +66943,7 @@ function fileExistsSync(p3) {
66861
66943
  function parseAgentFile(filePath) {
66862
66944
  let content;
66863
66945
  try {
66864
- content = import_node_fs43.default.readFileSync(filePath, "utf8");
66946
+ content = import_node_fs44.default.readFileSync(filePath, "utf8");
66865
66947
  } catch {
66866
66948
  return {};
66867
66949
  }
@@ -66874,16 +66956,16 @@ function parseAgentFile(filePath) {
66874
66956
  function scanAgentsDir(dir, source, seen, out) {
66875
66957
  let entries;
66876
66958
  try {
66877
- entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
66959
+ entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66878
66960
  } catch {
66879
66961
  return;
66880
66962
  }
66881
66963
  for (const ent of entries) {
66882
66964
  if (!ent.name.endsWith(".md")) continue;
66883
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path47.default.join(dir, ent.name)))) {
66965
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path48.default.join(dir, ent.name)))) {
66884
66966
  continue;
66885
66967
  }
66886
- const filePath = import_node_path47.default.join(dir, ent.name);
66968
+ const filePath = import_node_path48.default.join(dir, ent.name);
66887
66969
  const baseName = ent.name.replace(/\.md$/, "");
66888
66970
  if (seen.has(baseName)) continue;
66889
66971
  seen.add(baseName);
@@ -66901,12 +66983,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
66901
66983
  function walk2(dir, namespaces) {
66902
66984
  let entries;
66903
66985
  try {
66904
- entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
66986
+ entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66905
66987
  } catch {
66906
66988
  return;
66907
66989
  }
66908
66990
  for (const ent of entries) {
66909
- const childPath = import_node_path47.default.join(dir, ent.name);
66991
+ const childPath = import_node_path48.default.join(dir, ent.name);
66910
66992
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
66911
66993
  walk2(childPath, [...namespaces, ent.name]);
66912
66994
  continue;
@@ -66931,13 +67013,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
66931
67013
  walk2(root, []);
66932
67014
  }
66933
67015
  function readInstalledPlugins2(home) {
66934
- const pluginsDir = import_node_path47.default.join(home, ".claude", "plugins");
66935
- const v22 = import_node_path47.default.join(pluginsDir, "installed_plugins_v2.json");
66936
- const v1 = import_node_path47.default.join(pluginsDir, "installed_plugins.json");
67016
+ const pluginsDir = import_node_path48.default.join(home, ".claude", "plugins");
67017
+ const v22 = import_node_path48.default.join(pluginsDir, "installed_plugins_v2.json");
67018
+ const v1 = import_node_path48.default.join(pluginsDir, "installed_plugins.json");
66937
67019
  let raw = null;
66938
67020
  for (const candidate of [v22, v1]) {
66939
67021
  try {
66940
- raw = import_node_fs43.default.readFileSync(candidate, "utf8");
67022
+ raw = import_node_fs44.default.readFileSync(candidate, "utf8");
66941
67023
  break;
66942
67024
  } catch {
66943
67025
  }
@@ -66962,19 +67044,19 @@ function readInstalledPlugins2(home) {
66962
67044
  return out;
66963
67045
  }
66964
67046
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
66965
- let cur = import_node_path47.default.resolve(startCwd);
66966
- const fsRoot = import_node_path47.default.parse(cur).root;
67047
+ let cur = import_node_path48.default.resolve(startCwd);
67048
+ const fsRoot = import_node_path48.default.parse(cur).root;
66967
67049
  while (true) {
66968
- scanAgentsDir(import_node_path47.default.join(cur, ".claude", "agents"), "project", seen, out);
67050
+ scanAgentsDir(import_node_path48.default.join(cur, ".claude", "agents"), "project", seen, out);
66969
67051
  let hasGit = false;
66970
67052
  try {
66971
- hasGit = import_node_fs43.default.existsSync(import_node_path47.default.join(cur, ".git"));
67053
+ hasGit = import_node_fs44.default.existsSync(import_node_path48.default.join(cur, ".git"));
66972
67054
  } catch {
66973
67055
  }
66974
67056
  if (hasGit) return;
66975
67057
  if (cur === home) return;
66976
67058
  if (cur === fsRoot) return;
66977
- const parent = import_node_path47.default.dirname(cur);
67059
+ const parent = import_node_path48.default.dirname(cur);
66978
67060
  if (parent === cur) return;
66979
67061
  cur = parent;
66980
67062
  }
@@ -67009,7 +67091,7 @@ var AgentsScanner = class {
67009
67091
  }
67010
67092
  const fsBlock = [];
67011
67093
  scanAgentsDir(
67012
- import_node_path47.default.join(this.home, ".claude", "agents"),
67094
+ import_node_path48.default.join(this.home, ".claude", "agents"),
67013
67095
  "global",
67014
67096
  seen,
67015
67097
  fsBlock
@@ -67023,7 +67105,7 @@ var AgentsScanner = class {
67023
67105
  ...this.extraPluginRoots
67024
67106
  ];
67025
67107
  for (const { name, root } of plugins) {
67026
- const agentsRoot = import_node_path47.default.join(root, "agents");
67108
+ const agentsRoot = import_node_path48.default.join(root, "agents");
67027
67109
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
67028
67110
  }
67029
67111
  return [...builtinBlock, ...fsBlock];
@@ -67031,15 +67113,15 @@ var AgentsScanner = class {
67031
67113
  };
67032
67114
 
67033
67115
  // src/observer/session-observer.ts
67034
- var import_node_fs45 = __toESM(require("fs"), 1);
67116
+ var import_node_fs46 = __toESM(require("fs"), 1);
67035
67117
  var import_node_os18 = __toESM(require("os"), 1);
67036
- var import_node_path49 = __toESM(require("path"), 1);
67118
+ var import_node_path50 = __toESM(require("path"), 1);
67037
67119
  init_claude_history();
67038
67120
 
67039
67121
  // src/observer/subagent-meta-observer.ts
67040
- var import_node_fs44 = __toESM(require("fs"), 1);
67122
+ var import_node_fs45 = __toESM(require("fs"), 1);
67041
67123
  var import_node_os17 = __toESM(require("os"), 1);
67042
- var import_node_path48 = __toESM(require("path"), 1);
67124
+ var import_node_path49 = __toESM(require("path"), 1);
67043
67125
  init_claude_history();
67044
67126
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
67045
67127
  var SubagentMetaObserver = class {
@@ -67052,7 +67134,7 @@ var SubagentMetaObserver = class {
67052
67134
  watches = /* @__PURE__ */ new Map();
67053
67135
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
67054
67136
  resolveSubagentDir(cwd, toolSessionId) {
67055
- return import_node_path48.default.join(
67137
+ return import_node_path49.default.join(
67056
67138
  this.home,
67057
67139
  ".claude",
67058
67140
  "projects",
@@ -67081,7 +67163,7 @@ var SubagentMetaObserver = class {
67081
67163
  attachWatcher(w3) {
67082
67164
  if (w3.watcher) return;
67083
67165
  try {
67084
- w3.watcher = import_node_fs44.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
67166
+ w3.watcher = import_node_fs45.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
67085
67167
  if (!name) return;
67086
67168
  const m3 = META_RE.exec(String(name));
67087
67169
  if (!m3) return;
@@ -67093,7 +67175,7 @@ var SubagentMetaObserver = class {
67093
67175
  scan(w3) {
67094
67176
  let entries;
67095
67177
  try {
67096
- entries = import_node_fs44.default.readdirSync(w3.dirPath);
67178
+ entries = import_node_fs45.default.readdirSync(w3.dirPath);
67097
67179
  } catch {
67098
67180
  return;
67099
67181
  }
@@ -67107,10 +67189,10 @@ var SubagentMetaObserver = class {
67107
67189
  if (!m3) return;
67108
67190
  const agentId = m3[1];
67109
67191
  if (w3.emitted.has(agentId)) return;
67110
- const file = import_node_path48.default.join(w3.dirPath, name);
67192
+ const file = import_node_path49.default.join(w3.dirPath, name);
67111
67193
  let raw;
67112
67194
  try {
67113
- raw = import_node_fs44.default.readFileSync(file, "utf8");
67195
+ raw = import_node_fs45.default.readFileSync(file, "utf8");
67114
67196
  } catch {
67115
67197
  return;
67116
67198
  }
@@ -67164,14 +67246,14 @@ var SessionObserver = class {
67164
67246
  metaObserver;
67165
67247
  resolveJsonlPath(cwd, toolSessionId, override) {
67166
67248
  if (override) return override;
67167
- return import_node_path49.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
67249
+ return import_node_path50.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
67168
67250
  }
67169
67251
  start(args) {
67170
67252
  this.stop(args.sessionId);
67171
67253
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
67172
67254
  let size = 0;
67173
67255
  try {
67174
- size = import_node_fs45.default.statSync(filePath).size;
67256
+ size = import_node_fs46.default.statSync(filePath).size;
67175
67257
  } catch {
67176
67258
  }
67177
67259
  const w3 = {
@@ -67184,16 +67266,16 @@ var SessionObserver = class {
67184
67266
  adapter: args.adapter,
67185
67267
  prevIsRejectSentinel: false,
67186
67268
  toolSessionId: args.toolSessionId,
67187
- sawFile: import_node_fs45.default.existsSync(filePath),
67269
+ sawFile: import_node_fs46.default.existsSync(filePath),
67188
67270
  lastRelocateScanMs: 0,
67189
67271
  pendingCwdDerive: false,
67190
67272
  lastDeriveMs: 0
67191
67273
  };
67192
67274
  try {
67193
- import_node_fs45.default.mkdirSync(import_node_path49.default.dirname(filePath), { recursive: true });
67275
+ import_node_fs46.default.mkdirSync(import_node_path50.default.dirname(filePath), { recursive: true });
67194
67276
  } catch {
67195
67277
  }
67196
- w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
67278
+ w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
67197
67279
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67198
67280
  this.poll(w3);
67199
67281
  });
@@ -67213,7 +67295,7 @@ var SessionObserver = class {
67213
67295
  // 读取或解析失败不阻塞 watcher 启动。
67214
67296
  hydrateMetaTail(w3, maxLines = 200) {
67215
67297
  try {
67216
- const raw = import_node_fs45.default.readFileSync(w3.filePath, "utf8");
67298
+ const raw = import_node_fs46.default.readFileSync(w3.filePath, "utf8");
67217
67299
  if (!raw) return;
67218
67300
  const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
67219
67301
  if (allLines.length === 0) return;
@@ -67237,7 +67319,7 @@ var SessionObserver = class {
67237
67319
  poll(w3) {
67238
67320
  let size = 0;
67239
67321
  try {
67240
- size = import_node_fs45.default.statSync(w3.filePath).size;
67322
+ size = import_node_fs46.default.statSync(w3.filePath).size;
67241
67323
  } catch {
67242
67324
  if (w3.sawFile) this.maybeRelocate(w3);
67243
67325
  return;
@@ -67248,11 +67330,11 @@ var SessionObserver = class {
67248
67330
  w3.buf = "";
67249
67331
  }
67250
67332
  if (size === w3.lastSize) return;
67251
- const fd = import_node_fs45.default.openSync(w3.filePath, "r");
67333
+ const fd = import_node_fs46.default.openSync(w3.filePath, "r");
67252
67334
  try {
67253
67335
  const len = size - w3.lastSize;
67254
67336
  const buf = Buffer.alloc(len);
67255
- import_node_fs45.default.readSync(fd, buf, 0, len, w3.lastSize);
67337
+ import_node_fs46.default.readSync(fd, buf, 0, len, w3.lastSize);
67256
67338
  w3.lastSize = size;
67257
67339
  w3.buf += buf.toString("utf8");
67258
67340
  let newlineIndex;
@@ -67275,7 +67357,7 @@ var SessionObserver = class {
67275
67357
  }
67276
67358
  }
67277
67359
  } finally {
67278
- import_node_fs45.default.closeSync(fd);
67360
+ import_node_fs46.default.closeSync(fd);
67279
67361
  }
67280
67362
  if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
67281
67363
  }
@@ -67285,7 +67367,7 @@ var SessionObserver = class {
67285
67367
  const now = Date.now();
67286
67368
  if (now - w3.lastRelocateScanMs < 1e3) return;
67287
67369
  w3.lastRelocateScanMs = now;
67288
- const projectsRoot = import_node_path49.default.join(this.home, ".claude", "projects");
67370
+ const projectsRoot = import_node_path50.default.join(this.home, ".claude", "projects");
67289
67371
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
67290
67372
  if (!found || found === w3.filePath) return;
67291
67373
  try {
@@ -67294,7 +67376,7 @@ var SessionObserver = class {
67294
67376
  }
67295
67377
  w3.filePath = found;
67296
67378
  try {
67297
- w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(found), { persistent: false }, (_event, changedName) => {
67379
+ w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(found), { persistent: false }, (_event, changedName) => {
67298
67380
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67299
67381
  this.poll(w3);
67300
67382
  });
@@ -67414,9 +67496,9 @@ function listRegistered() {
67414
67496
  // src/tools/title-generator.ts
67415
67497
  var import_node_child_process14 = require("child_process");
67416
67498
  init_protocol();
67417
- var import_node_fs46 = __toESM(require("fs"), 1);
67499
+ var import_node_fs47 = __toESM(require("fs"), 1);
67418
67500
  var import_node_os19 = __toESM(require("os"), 1);
67419
- var import_node_path50 = __toESM(require("path"), 1);
67501
+ var import_node_path51 = __toESM(require("path"), 1);
67420
67502
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
67421
67503
  var TITLE_INPUT_MAX_CHARS = 400;
67422
67504
  var DEFAULT_TITLE_GEN_TIMEOUT_MS = 45e3;
@@ -67507,21 +67589,21 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67507
67589
  }
67508
67590
  let workDir;
67509
67591
  try {
67510
- workDir = import_node_fs46.default.mkdtempSync(import_node_path50.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
67592
+ workDir = import_node_fs47.default.mkdtempSync(import_node_path51.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
67511
67593
  } catch {
67512
67594
  return null;
67513
67595
  }
67514
67596
  const cleanupWorkDir = () => {
67515
67597
  try {
67516
- import_node_fs46.default.rmSync(workDir, { recursive: true, force: true });
67598
+ import_node_fs47.default.rmSync(workDir, { recursive: true, force: true });
67517
67599
  } catch {
67518
67600
  }
67519
67601
  };
67520
- const outFile = import_node_path50.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
67521
- const schemaFile = import_node_path50.default.join(workDir, "title-schema.json");
67602
+ const outFile = import_node_path51.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
67603
+ const schemaFile = import_node_path51.default.join(workDir, "title-schema.json");
67522
67604
  if (tool === "codex") {
67523
67605
  try {
67524
- import_node_fs46.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
67606
+ import_node_fs47.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
67525
67607
  } catch {
67526
67608
  cleanupWorkDir();
67527
67609
  return null;
@@ -67576,7 +67658,7 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67576
67658
  if (tool === "claude" || tool === "pi") return finish(parseTitleJson(stdout));
67577
67659
  let fileText = "";
67578
67660
  try {
67579
- fileText = import_node_fs46.default.readFileSync(outFile, "utf8");
67661
+ fileText = import_node_fs47.default.readFileSync(outFile, "utf8");
67580
67662
  } catch {
67581
67663
  return finish(null);
67582
67664
  }
@@ -68254,8 +68336,8 @@ async function authenticate(token, deps) {
68254
68336
  }
68255
68337
 
68256
68338
  // src/legacy-cleanup.ts
68257
- var fs57 = __toESM(require("fs/promises"), 1);
68258
- var path58 = __toESM(require("path"), 1);
68339
+ var fs58 = __toESM(require("fs/promises"), 1);
68340
+ var path59 = __toESM(require("path"), 1);
68259
68341
  var LEGACY_FILES = [
68260
68342
  "personal-capability.json",
68261
68343
  "received-capabilities.json",
@@ -68264,9 +68346,9 @@ var LEGACY_FILES = [
68264
68346
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68265
68347
  const removed = [];
68266
68348
  for (const name of LEGACY_FILES) {
68267
- const p3 = path58.join(dataDir, name);
68349
+ const p3 = path59.join(dataDir, name);
68268
68350
  try {
68269
- await fs57.unlink(p3);
68351
+ await fs58.unlink(p3);
68270
68352
  removed.push(name);
68271
68353
  logger.debug("legacy capability file removed", { file: name });
68272
68354
  } catch (err) {
@@ -68278,13 +68360,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68278
68360
  }
68279
68361
 
68280
68362
  // src/inbox/inbox-store.ts
68281
- var fs58 = __toESM(require("fs"), 1);
68282
- var path59 = __toESM(require("path"), 1);
68363
+ var fs59 = __toESM(require("fs"), 1);
68364
+ var path60 = __toESM(require("path"), 1);
68283
68365
  var INBOX_SUBDIR = "inbox";
68284
68366
  var InboxStore = class {
68285
68367
  constructor(dataDir) {
68286
68368
  this.dataDir = dataDir;
68287
- fs58.mkdirSync(this.dirPath(), { recursive: true });
68369
+ fs59.mkdirSync(this.dirPath(), { recursive: true });
68288
68370
  }
68289
68371
  dataDir;
68290
68372
  /** sinceCreatedAt 缺省读全量,否则仅读时间戳更大的消息;读取失败返回空数组。 */
@@ -68292,7 +68374,7 @@ var InboxStore = class {
68292
68374
  const file = this.filePath(peerDeviceId);
68293
68375
  let raw;
68294
68376
  try {
68295
- raw = fs58.readFileSync(file, "utf8");
68377
+ raw = fs59.readFileSync(file, "utf8");
68296
68378
  } catch (err) {
68297
68379
  if (err?.code === "ENOENT") return [];
68298
68380
  return [];
@@ -68305,7 +68387,7 @@ var InboxStore = class {
68305
68387
  const dir = this.dirPath();
68306
68388
  let entries;
68307
68389
  try {
68308
- entries = fs58.readdirSync(dir);
68390
+ entries = fs59.readdirSync(dir);
68309
68391
  } catch (err) {
68310
68392
  if (err?.code === "ENOENT") return [];
68311
68393
  return [];
@@ -68318,9 +68400,9 @@ var InboxStore = class {
68318
68400
  if (existing.some((m3) => m3.id === message.id)) return;
68319
68401
  const file = this.filePath(message.peerDeviceId);
68320
68402
  const line = JSON.stringify(message) + "\n";
68321
- fs58.appendFileSync(file, line, { mode: 384 });
68403
+ fs59.appendFileSync(file, line, { mode: 384 });
68322
68404
  try {
68323
- fs58.chmodSync(file, 384);
68405
+ fs59.chmodSync(file, 384);
68324
68406
  } catch {
68325
68407
  }
68326
68408
  }
@@ -68343,7 +68425,7 @@ var InboxStore = class {
68343
68425
  removeByPeerDeviceId(peerDeviceId) {
68344
68426
  const file = this.filePath(peerDeviceId);
68345
68427
  try {
68346
- fs58.unlinkSync(file);
68428
+ fs59.unlinkSync(file);
68347
68429
  } catch (err) {
68348
68430
  if (err?.code === "ENOENT") return;
68349
68431
  }
@@ -68352,18 +68434,18 @@ var InboxStore = class {
68352
68434
  const file = this.filePath(peerDeviceId);
68353
68435
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
68354
68436
  const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
68355
- fs58.writeFileSync(tmp, content, { mode: 384 });
68356
- fs58.renameSync(tmp, file);
68437
+ fs59.writeFileSync(tmp, content, { mode: 384 });
68438
+ fs59.renameSync(tmp, file);
68357
68439
  try {
68358
- fs58.chmodSync(file, 384);
68440
+ fs59.chmodSync(file, 384);
68359
68441
  } catch {
68360
68442
  }
68361
68443
  }
68362
68444
  dirPath() {
68363
- return path59.join(this.dataDir, INBOX_SUBDIR);
68445
+ return path60.join(this.dataDir, INBOX_SUBDIR);
68364
68446
  }
68365
68447
  filePath(peerDeviceId) {
68366
- return path59.join(this.dirPath(), `${peerDeviceId}.jsonl`);
68448
+ return path60.join(this.dirPath(), `${peerDeviceId}.jsonl`);
68367
68449
  }
68368
68450
  };
68369
68451
  function parseAllLines(raw) {
@@ -68441,8 +68523,8 @@ var InboxManager = class {
68441
68523
  };
68442
68524
 
68443
68525
  // src/state/contact-store.ts
68444
- var fs59 = __toESM(require("fs"), 1);
68445
- var path60 = __toESM(require("path"), 1);
68526
+ var fs60 = __toESM(require("fs"), 1);
68527
+ var path61 = __toESM(require("path"), 1);
68446
68528
  var FILE_NAME = "contacts.json";
68447
68529
  var ContactStore = class {
68448
68530
  constructor(dataDir) {
@@ -68452,10 +68534,10 @@ var ContactStore = class {
68452
68534
  contacts = /* @__PURE__ */ new Map();
68453
68535
  load() {
68454
68536
  this.contacts.clear();
68455
- const file = path60.join(this.dataDir, FILE_NAME);
68537
+ const file = path61.join(this.dataDir, FILE_NAME);
68456
68538
  let raw;
68457
68539
  try {
68458
- raw = fs59.readFileSync(file, "utf8");
68540
+ raw = fs60.readFileSync(file, "utf8");
68459
68541
  } catch (err) {
68460
68542
  if (err?.code !== "ENOENT") this.renameBak(file);
68461
68543
  return;
@@ -68525,20 +68607,20 @@ var ContactStore = class {
68525
68607
  return true;
68526
68608
  }
68527
68609
  flush() {
68528
- const file = path60.join(this.dataDir, FILE_NAME);
68610
+ const file = path61.join(this.dataDir, FILE_NAME);
68529
68611
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
68530
68612
  const content = JSON.stringify(
68531
68613
  { contacts: Array.from(this.contacts.values()) },
68532
68614
  null,
68533
68615
  2
68534
68616
  );
68535
- fs59.mkdirSync(this.dataDir, { recursive: true });
68536
- fs59.writeFileSync(tmp, content, { mode: 384 });
68537
- fs59.renameSync(tmp, file);
68617
+ fs60.mkdirSync(this.dataDir, { recursive: true });
68618
+ fs60.writeFileSync(tmp, content, { mode: 384 });
68619
+ fs60.renameSync(tmp, file);
68538
68620
  }
68539
68621
  renameBak(file) {
68540
68622
  try {
68541
- fs59.renameSync(file, `${file}.bak`);
68623
+ fs60.renameSync(file, `${file}.bak`);
68542
68624
  } catch {
68543
68625
  }
68544
68626
  }
@@ -68646,61 +68728,61 @@ async function connectRemote(args) {
68646
68728
  }
68647
68729
 
68648
68730
  // src/migrations/2026-05-20-flatten-sessions.ts
68649
- var fs60 = __toESM(require("fs"), 1);
68650
- var path61 = __toESM(require("path"), 1);
68731
+ var fs61 = __toESM(require("fs"), 1);
68732
+ var path62 = __toESM(require("path"), 1);
68651
68733
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
68652
68734
  function migrateFlattenSessions(opts) {
68653
68735
  const dataDir = opts.dataDir;
68654
68736
  const now = opts.now ?? Date.now;
68655
- const sessionsDir = path61.join(dataDir, "sessions");
68656
- const flagPath = path61.join(sessionsDir, MIGRATION_FLAG_NAME);
68737
+ const sessionsDir = path62.join(dataDir, "sessions");
68738
+ const flagPath = path62.join(sessionsDir, MIGRATION_FLAG_NAME);
68657
68739
  if (existsSync3(flagPath)) {
68658
68740
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
68659
68741
  }
68660
68742
  let movedBare = 0;
68661
68743
  let movedVmOwner = 0;
68662
68744
  let archivedListener = 0;
68663
- const defaultDir = path61.join(sessionsDir, "default");
68745
+ const defaultDir = path62.join(sessionsDir, "default");
68664
68746
  if (existsSync3(defaultDir)) {
68665
68747
  for (const entry of readdirSafe(defaultDir)) {
68666
68748
  if (!entry.endsWith(".json")) continue;
68667
- const src = path61.join(defaultDir, entry);
68668
- const dst = path61.join(sessionsDir, entry);
68669
- fs60.renameSync(src, dst);
68749
+ const src = path62.join(defaultDir, entry);
68750
+ const dst = path62.join(sessionsDir, entry);
68751
+ fs61.renameSync(src, dst);
68670
68752
  movedBare += 1;
68671
68753
  }
68672
68754
  rmdirIfEmpty(defaultDir);
68673
68755
  }
68674
68756
  for (const pid of readdirSafe(sessionsDir)) {
68675
- const personaDir = path61.join(sessionsDir, pid);
68757
+ const personaDir = path62.join(sessionsDir, pid);
68676
68758
  if (!isDir(personaDir)) continue;
68677
68759
  if (pid === "default") continue;
68678
- const ownerSrc = path61.join(personaDir, "owner");
68760
+ const ownerSrc = path62.join(personaDir, "owner");
68679
68761
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
68680
- const ownerDst = path61.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68681
- fs60.mkdirSync(ownerDst, { recursive: true });
68762
+ const ownerDst = path62.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68763
+ fs61.mkdirSync(ownerDst, { recursive: true });
68682
68764
  for (const file of readdirSafe(ownerSrc)) {
68683
68765
  if (!file.endsWith(".json")) continue;
68684
- fs60.renameSync(path61.join(ownerSrc, file), path61.join(ownerDst, file));
68766
+ fs61.renameSync(path62.join(ownerSrc, file), path62.join(ownerDst, file));
68685
68767
  movedVmOwner += 1;
68686
68768
  }
68687
68769
  rmdirIfEmpty(ownerSrc);
68688
68770
  }
68689
- const listenerSrc = path61.join(personaDir, "listener");
68771
+ const listenerSrc = path62.join(personaDir, "listener");
68690
68772
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
68691
- const archiveDst = path61.join(dataDir, ".legacy", `listener-${pid}`);
68692
- fs60.mkdirSync(archiveDst, { recursive: true });
68773
+ const archiveDst = path62.join(dataDir, ".legacy", `listener-${pid}`);
68774
+ fs61.mkdirSync(archiveDst, { recursive: true });
68693
68775
  for (const file of readdirSafe(listenerSrc)) {
68694
68776
  if (!file.endsWith(".json")) continue;
68695
- fs60.renameSync(path61.join(listenerSrc, file), path61.join(archiveDst, file));
68777
+ fs61.renameSync(path62.join(listenerSrc, file), path62.join(archiveDst, file));
68696
68778
  archivedListener += 1;
68697
68779
  }
68698
68780
  rmdirIfEmpty(listenerSrc);
68699
68781
  }
68700
68782
  rmdirIfEmpty(personaDir);
68701
68783
  }
68702
- fs60.mkdirSync(sessionsDir, { recursive: true });
68703
- fs60.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68784
+ fs61.mkdirSync(sessionsDir, { recursive: true });
68785
+ fs61.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68704
68786
  return {
68705
68787
  skipped: false,
68706
68788
  flagWritten: true,
@@ -68711,7 +68793,7 @@ function migrateFlattenSessions(opts) {
68711
68793
  }
68712
68794
  function existsSync3(p3) {
68713
68795
  try {
68714
- fs60.statSync(p3);
68796
+ fs61.statSync(p3);
68715
68797
  return true;
68716
68798
  } catch {
68717
68799
  return false;
@@ -68719,62 +68801,62 @@ function existsSync3(p3) {
68719
68801
  }
68720
68802
  function isDir(p3) {
68721
68803
  try {
68722
- return fs60.statSync(p3).isDirectory();
68804
+ return fs61.statSync(p3).isDirectory();
68723
68805
  } catch {
68724
68806
  return false;
68725
68807
  }
68726
68808
  }
68727
68809
  function readdirSafe(p3) {
68728
68810
  try {
68729
- return fs60.readdirSync(p3);
68811
+ return fs61.readdirSync(p3);
68730
68812
  } catch {
68731
68813
  return [];
68732
68814
  }
68733
68815
  }
68734
68816
  function rmdirIfEmpty(p3) {
68735
68817
  try {
68736
- fs60.rmdirSync(p3);
68818
+ fs61.rmdirSync(p3);
68737
68819
  } catch {
68738
68820
  }
68739
68821
  }
68740
68822
 
68741
68823
  // src/migrations/2026-08-18-drop-seeded-projects.ts
68742
- var fs61 = __toESM(require("fs"), 1);
68743
- var path62 = __toESM(require("path"), 1);
68824
+ var fs62 = __toESM(require("fs"), 1);
68825
+ var path63 = __toESM(require("path"), 1);
68744
68826
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
68745
68827
  function dropSeededProjects(opts) {
68746
- fs61.mkdirSync(opts.dataDir, { recursive: true });
68747
- const flag = path62.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
68748
- if (fs61.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
68749
- const file = path62.join(opts.dataDir, "projects.json");
68828
+ fs62.mkdirSync(opts.dataDir, { recursive: true });
68829
+ const flag = path63.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
68830
+ if (fs62.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
68831
+ const file = path63.join(opts.dataDir, "projects.json");
68750
68832
  let raw = null;
68751
68833
  let dropped = 0;
68752
68834
  try {
68753
- raw = fs61.readFileSync(file, "utf8");
68835
+ raw = fs62.readFileSync(file, "utf8");
68754
68836
  dropped = JSON.parse(raw).projects?.length ?? 0;
68755
68837
  } catch {
68756
68838
  }
68757
68839
  let backup = null;
68758
68840
  if (raw != null && dropped > 0) {
68759
- const dir = path62.join(opts.dataDir, "backups");
68760
- fs61.mkdirSync(dir, { recursive: true });
68761
- backup = path62.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
68762
- fs61.writeFileSync(backup, raw);
68841
+ const dir = path63.join(opts.dataDir, "backups");
68842
+ fs62.mkdirSync(dir, { recursive: true });
68843
+ backup = path63.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
68844
+ fs62.writeFileSync(backup, raw);
68763
68845
  }
68764
68846
  if (raw != null || dropped > 0) {
68765
- fs61.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
68847
+ fs62.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
68766
68848
  }
68767
- fs61.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
68849
+ fs62.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
68768
68850
  return { skipped: false, dropped, backup };
68769
68851
  }
68770
68852
 
68771
68853
  // src/transport/http-router.ts
68772
- var import_node_fs48 = __toESM(require("fs"), 1);
68773
- var import_node_path53 = __toESM(require("path"), 1);
68854
+ var import_node_fs49 = __toESM(require("fs"), 1);
68855
+ var import_node_path54 = __toESM(require("path"), 1);
68774
68856
 
68775
68857
  // src/attachment/upload.ts
68776
- var import_node_fs47 = __toESM(require("fs"), 1);
68777
- var import_node_path51 = __toESM(require("path"), 1);
68858
+ var import_node_fs48 = __toESM(require("fs"), 1);
68859
+ var import_node_path52 = __toESM(require("path"), 1);
68778
68860
  var import_node_crypto19 = __toESM(require("crypto"), 1);
68779
68861
  var import_promises8 = require("stream/promises");
68780
68862
  var UploadError = class extends Error {
@@ -68786,22 +68868,22 @@ var UploadError = class extends Error {
68786
68868
  code;
68787
68869
  };
68788
68870
  function assertValidFileName(fileName) {
68789
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path51.default.basename(fileName)) {
68871
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path52.default.basename(fileName)) {
68790
68872
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
68791
68873
  }
68792
68874
  }
68793
68875
  var HASH_PREFIX_LEN = 16;
68794
68876
  async function writeUploadedAttachment(args) {
68795
68877
  assertValidFileName(args.fileName);
68796
- const attachmentsRoot = import_node_path51.default.join(args.baseDir, ".attachments");
68878
+ const attachmentsRoot = import_node_path52.default.join(args.baseDir, ".attachments");
68797
68879
  try {
68798
- import_node_fs47.default.mkdirSync(attachmentsRoot, { recursive: true });
68880
+ import_node_fs48.default.mkdirSync(attachmentsRoot, { recursive: true });
68799
68881
  } catch (err) {
68800
68882
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
68801
68883
  }
68802
68884
  const hasher = import_node_crypto19.default.createHash("sha256");
68803
68885
  let actualSize = 0;
68804
- const tmpPath = import_node_path51.default.join(
68886
+ const tmpPath = import_node_path52.default.join(
68805
68887
  attachmentsRoot,
68806
68888
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto19.default.randomBytes(4).toString("hex")}`
68807
68889
  );
@@ -68816,18 +68898,18 @@ async function writeUploadedAttachment(args) {
68816
68898
  yield buf;
68817
68899
  }
68818
68900
  },
68819
- import_node_fs47.default.createWriteStream(tmpPath, { mode: 384 })
68901
+ import_node_fs48.default.createWriteStream(tmpPath, { mode: 384 })
68820
68902
  );
68821
68903
  } catch (err) {
68822
68904
  try {
68823
- import_node_fs47.default.unlinkSync(tmpPath);
68905
+ import_node_fs48.default.unlinkSync(tmpPath);
68824
68906
  } catch {
68825
68907
  }
68826
68908
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
68827
68909
  }
68828
68910
  if (actualSize !== args.contentLength) {
68829
68911
  try {
68830
- import_node_fs47.default.unlinkSync(tmpPath);
68912
+ import_node_fs48.default.unlinkSync(tmpPath);
68831
68913
  } catch {
68832
68914
  }
68833
68915
  throw new UploadError(
@@ -68836,34 +68918,34 @@ async function writeUploadedAttachment(args) {
68836
68918
  );
68837
68919
  }
68838
68920
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
68839
- const hashDir = import_node_path51.default.join(attachmentsRoot, attachmentId);
68921
+ const hashDir = import_node_path52.default.join(attachmentsRoot, attachmentId);
68840
68922
  let finalFileName;
68841
68923
  let hashDirExists = false;
68842
68924
  try {
68843
- hashDirExists = import_node_fs47.default.statSync(hashDir).isDirectory();
68925
+ hashDirExists = import_node_fs48.default.statSync(hashDir).isDirectory();
68844
68926
  } catch {
68845
68927
  }
68846
68928
  if (hashDirExists) {
68847
- const existing = import_node_fs47.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68929
+ const existing = import_node_fs48.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68848
68930
  finalFileName = existing[0] ?? args.fileName;
68849
68931
  try {
68850
- import_node_fs47.default.unlinkSync(tmpPath);
68932
+ import_node_fs48.default.unlinkSync(tmpPath);
68851
68933
  } catch {
68852
68934
  }
68853
68935
  } else {
68854
68936
  try {
68855
- import_node_fs47.default.mkdirSync(hashDir, { recursive: true });
68937
+ import_node_fs48.default.mkdirSync(hashDir, { recursive: true });
68856
68938
  finalFileName = args.fileName;
68857
- import_node_fs47.default.renameSync(tmpPath, import_node_path51.default.join(hashDir, finalFileName));
68939
+ import_node_fs48.default.renameSync(tmpPath, import_node_path52.default.join(hashDir, finalFileName));
68858
68940
  } catch (err) {
68859
68941
  try {
68860
- import_node_fs47.default.unlinkSync(tmpPath);
68942
+ import_node_fs48.default.unlinkSync(tmpPath);
68861
68943
  } catch {
68862
68944
  }
68863
68945
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
68864
68946
  }
68865
68947
  }
68866
- const absPath = import_node_path51.default.join(hashDir, finalFileName);
68948
+ const absPath = import_node_path52.default.join(hashDir, finalFileName);
68867
68949
  const relPath = absPath;
68868
68950
  args.groupFileStore.upsert(args.scope, args.sessionId, {
68869
68951
  relPath: absPath,
@@ -68877,7 +68959,7 @@ async function writeUploadedAttachment(args) {
68877
68959
 
68878
68960
  // src/extension/import.ts
68879
68961
  var import_promises9 = __toESM(require("fs/promises"), 1);
68880
- var import_node_path52 = __toESM(require("path"), 1);
68962
+ var import_node_path53 = __toESM(require("path"), 1);
68881
68963
  var import_node_os20 = __toESM(require("os"), 1);
68882
68964
  var import_jszip2 = __toESM(require_lib3(), 1);
68883
68965
  var ImportError = class extends Error {
@@ -68895,7 +68977,7 @@ async function importZip(buf, root) {
68895
68977
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
68896
68978
  }
68897
68979
  for (const name of Object.keys(zip.files)) {
68898
- if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
68980
+ if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
68899
68981
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
68900
68982
  }
68901
68983
  }
@@ -68928,7 +69010,7 @@ async function importZip(buf, root) {
68928
69010
  );
68929
69011
  }
68930
69012
  }
68931
- const destDir = import_node_path52.default.join(root, manifest.id);
69013
+ const destDir = import_node_path53.default.join(root, manifest.id);
68932
69014
  let destExists = false;
68933
69015
  try {
68934
69016
  await import_promises9.default.access(destDir);
@@ -68938,15 +69020,15 @@ async function importZip(buf, root) {
68938
69020
  if (destExists) {
68939
69021
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
68940
69022
  }
68941
- const stage = await import_promises9.default.mkdtemp(import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
69023
+ const stage = await import_promises9.default.mkdtemp(import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
68942
69024
  try {
68943
69025
  for (const [name, entry] of Object.entries(zip.files)) {
68944
- const dest = import_node_path52.default.join(stage, name);
69026
+ const dest = import_node_path53.default.join(stage, name);
68945
69027
  if (entry.dir) {
68946
69028
  await import_promises9.default.mkdir(dest, { recursive: true });
68947
69029
  continue;
68948
69030
  }
68949
- await import_promises9.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
69031
+ await import_promises9.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
68950
69032
  const content = await entry.async("nodebuffer");
68951
69033
  await import_promises9.default.writeFile(dest, content);
68952
69034
  }
@@ -69000,7 +69082,7 @@ var SHARE_UI_ASSET_MIME = {
69000
69082
  ".wasm": "application/wasm"
69001
69083
  };
69002
69084
  function shareUiAssetMime(filePath) {
69003
- const ext = import_node_path53.default.extname(filePath).toLowerCase();
69085
+ const ext = import_node_path54.default.extname(filePath).toLowerCase();
69004
69086
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
69005
69087
  }
69006
69088
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -69099,7 +69181,7 @@ function isValidUploadFileName(fileName) {
69099
69181
  if (fileName === "." || fileName === "..") return false;
69100
69182
  if (fileName.startsWith(".")) return false;
69101
69183
  if (fileName.includes("/") || fileName.includes("\\")) return false;
69102
- return fileName === import_node_path53.default.basename(fileName);
69184
+ return fileName === import_node_path54.default.basename(fileName);
69103
69185
  }
69104
69186
  function createHttpRouter(deps) {
69105
69187
  return async (req, res) => {
@@ -69183,7 +69265,7 @@ function createHttpRouter(deps) {
69183
69265
  }
69184
69266
  let buf;
69185
69267
  try {
69186
- buf = await import_node_fs48.default.promises.readFile(abs);
69268
+ buf = await import_node_fs49.default.promises.readFile(abs);
69187
69269
  } catch {
69188
69270
  sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
69189
69271
  return true;
@@ -69329,7 +69411,7 @@ function createHttpRouter(deps) {
69329
69411
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
69330
69412
  return true;
69331
69413
  }
69332
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path53.default.basename(r2.absPath)));
69414
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path54.default.basename(r2.absPath)));
69333
69415
  return true;
69334
69416
  }
69335
69417
  const ctx = deps.authResolver.resolveFromHeader(
@@ -69450,7 +69532,7 @@ function createHttpRouter(deps) {
69450
69532
  return true;
69451
69533
  }
69452
69534
  let absPath;
69453
- if (import_node_path53.default.isAbsolute(pathParam)) {
69535
+ if (import_node_path54.default.isAbsolute(pathParam)) {
69454
69536
  absPath = pathParam;
69455
69537
  } else if (deps.sessionStore) {
69456
69538
  const file = deps.sessionStore.read(sid);
@@ -69458,7 +69540,7 @@ function createHttpRouter(deps) {
69458
69540
  sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
69459
69541
  return true;
69460
69542
  }
69461
- absPath = import_node_path53.default.join(file.cwd, pathParam);
69543
+ absPath = import_node_path54.default.join(file.cwd, pathParam);
69462
69544
  } else {
69463
69545
  sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
69464
69546
  return true;
@@ -69542,7 +69624,7 @@ function withCtx(ctx, body) {
69542
69624
  function streamFile(res, absPath, logger) {
69543
69625
  let stat;
69544
69626
  try {
69545
- stat = import_node_fs48.default.statSync(absPath);
69627
+ stat = import_node_fs49.default.statSync(absPath);
69546
69628
  } catch (err) {
69547
69629
  const code = err?.code;
69548
69630
  if (code === "ENOENT") {
@@ -69557,7 +69639,7 @@ function streamFile(res, absPath, logger) {
69557
69639
  return;
69558
69640
  }
69559
69641
  const mime = lookupMime(absPath);
69560
- const basename2 = import_node_path53.default.basename(absPath);
69642
+ const basename2 = import_node_path54.default.basename(absPath);
69561
69643
  res.writeHead(200, {
69562
69644
  "Content-Type": mime,
69563
69645
  "Content-Length": String(stat.size),
@@ -69565,7 +69647,7 @@ function streamFile(res, absPath, logger) {
69565
69647
  // Prevent MIME sniffing; explicit HTML MIME remains renderable.
69566
69648
  "X-Content-Type-Options": "nosniff"
69567
69649
  });
69568
- const stream = import_node_fs48.default.createReadStream(absPath);
69650
+ const stream = import_node_fs49.default.createReadStream(absPath);
69569
69651
  stream.on("error", (err) => {
69570
69652
  logger?.warn("streamFile read error", { absPath, err: err.message });
69571
69653
  res.destroy();
@@ -69574,8 +69656,8 @@ function streamFile(res, absPath, logger) {
69574
69656
  }
69575
69657
 
69576
69658
  // src/attachment/gc.ts
69577
- var import_node_fs49 = __toESM(require("fs"), 1);
69578
- var import_node_path54 = __toESM(require("path"), 1);
69659
+ var import_node_fs50 = __toESM(require("fs"), 1);
69660
+ var import_node_path55 = __toESM(require("path"), 1);
69579
69661
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
69580
69662
  function runAttachmentGc(args) {
69581
69663
  const now = (args.now ?? Date.now)();
@@ -69584,12 +69666,12 @@ function runAttachmentGc(args) {
69584
69666
  for (const { scope, sessionId } of args.sessionScopes) {
69585
69667
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
69586
69668
  if (entry.stale) continue;
69587
- if (import_node_path54.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69669
+ if (import_node_path55.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69588
69670
  }
69589
69671
  }
69590
69672
  const visited = /* @__PURE__ */ new Set();
69591
69673
  for (const { scope, sessionId } of args.sessionScopes) {
69592
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path54.default.join(
69674
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path55.default.join(
69593
69675
  args.dataDir,
69594
69676
  "sessions",
69595
69677
  ...scopeSubPath(scope).map(safeFileName),
@@ -69602,28 +69684,28 @@ function runAttachmentGc(args) {
69602
69684
  return true;
69603
69685
  });
69604
69686
  for (const rootDir of roots) {
69605
- const attRoot = import_node_path54.default.join(rootDir, ".attachments");
69687
+ const attRoot = import_node_path55.default.join(rootDir, ".attachments");
69606
69688
  let hashDirs;
69607
69689
  try {
69608
- hashDirs = import_node_fs49.default.readdirSync(attRoot);
69690
+ hashDirs = import_node_fs50.default.readdirSync(attRoot);
69609
69691
  } catch (err) {
69610
69692
  if (err.code === "ENOENT") continue;
69611
69693
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
69612
69694
  continue;
69613
69695
  }
69614
69696
  for (const hashDir of hashDirs) {
69615
- const hashDirAbs = import_node_path54.default.join(attRoot, hashDir);
69697
+ const hashDirAbs = import_node_path55.default.join(attRoot, hashDir);
69616
69698
  let files;
69617
69699
  try {
69618
- files = import_node_fs49.default.readdirSync(hashDirAbs);
69700
+ files = import_node_fs50.default.readdirSync(hashDirAbs);
69619
69701
  } catch {
69620
69702
  continue;
69621
69703
  }
69622
69704
  for (const name of files) {
69623
- const file = import_node_path54.default.join(hashDirAbs, name);
69705
+ const file = import_node_path55.default.join(hashDirAbs, name);
69624
69706
  let stat;
69625
69707
  try {
69626
- stat = import_node_fs49.default.statSync(file);
69708
+ stat = import_node_fs50.default.statSync(file);
69627
69709
  } catch {
69628
69710
  continue;
69629
69711
  }
@@ -69632,18 +69714,18 @@ function runAttachmentGc(args) {
69632
69714
  if (age < ttlMs) continue;
69633
69715
  if (liveAbs.has(file)) continue;
69634
69716
  try {
69635
- import_node_fs49.default.unlinkSync(file);
69717
+ import_node_fs50.default.unlinkSync(file);
69636
69718
  } catch (err) {
69637
69719
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
69638
69720
  }
69639
69721
  }
69640
69722
  try {
69641
- if (import_node_fs49.default.readdirSync(hashDirAbs).length === 0) import_node_fs49.default.rmdirSync(hashDirAbs);
69723
+ if (import_node_fs50.default.readdirSync(hashDirAbs).length === 0) import_node_fs50.default.rmdirSync(hashDirAbs);
69642
69724
  } catch {
69643
69725
  }
69644
69726
  }
69645
69727
  try {
69646
- if (import_node_fs49.default.readdirSync(attRoot).length === 0) import_node_fs49.default.rmdirSync(attRoot);
69728
+ if (import_node_fs50.default.readdirSync(attRoot).length === 0) import_node_fs50.default.rmdirSync(attRoot);
69647
69729
  } catch {
69648
69730
  }
69649
69731
  }
@@ -69651,8 +69733,8 @@ function runAttachmentGc(args) {
69651
69733
  }
69652
69734
 
69653
69735
  // src/attachment/group.ts
69654
- var import_node_fs50 = __toESM(require("fs"), 1);
69655
- var import_node_path55 = __toESM(require("path"), 1);
69736
+ var import_node_fs51 = __toESM(require("fs"), 1);
69737
+ var import_node_path56 = __toESM(require("path"), 1);
69656
69738
  var import_node_crypto20 = __toESM(require("crypto"), 1);
69657
69739
  init_protocol();
69658
69740
  var GroupFileStore = class {
@@ -69664,10 +69746,10 @@ var GroupFileStore = class {
69664
69746
  this.logger = opts.logger;
69665
69747
  }
69666
69748
  rootForScope(scope) {
69667
- return import_node_path55.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69749
+ return import_node_path56.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69668
69750
  }
69669
69751
  filePath(scope, sessionId) {
69670
- return import_node_path55.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69752
+ return import_node_path56.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69671
69753
  }
69672
69754
  cacheKey(scope, sessionId) {
69673
69755
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -69675,7 +69757,7 @@ var GroupFileStore = class {
69675
69757
  readFile(scope, sessionId) {
69676
69758
  const file = this.filePath(scope, sessionId);
69677
69759
  try {
69678
- const raw = import_node_fs50.default.readFileSync(file, "utf8");
69760
+ const raw = import_node_fs51.default.readFileSync(file, "utf8");
69679
69761
  const parsed = JSON.parse(raw);
69680
69762
  if (!Array.isArray(parsed)) {
69681
69763
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -69701,10 +69783,10 @@ var GroupFileStore = class {
69701
69783
  }
69702
69784
  writeFile(scope, sessionId, entries) {
69703
69785
  const file = this.filePath(scope, sessionId);
69704
- import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(file), { recursive: true });
69786
+ import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(file), { recursive: true });
69705
69787
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
69706
- import_node_fs50.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
69707
- import_node_fs50.default.renameSync(tmp, file);
69788
+ import_node_fs51.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
69789
+ import_node_fs51.default.renameSync(tmp, file);
69708
69790
  }
69709
69791
  list(scope, sessionId) {
69710
69792
  const key = this.cacheKey(scope, sessionId);
@@ -69768,7 +69850,7 @@ var GroupFileStore = class {
69768
69850
  /** Delete the separate manifest and cache; deleting a persona session file does not remove this store. */
69769
69851
  deleteSession(scope, sessionId) {
69770
69852
  try {
69771
- import_node_fs50.default.unlinkSync(this.filePath(scope, sessionId));
69853
+ import_node_fs51.default.unlinkSync(this.filePath(scope, sessionId));
69772
69854
  } catch (err) {
69773
69855
  if (err?.code !== "ENOENT") throw err;
69774
69856
  }
@@ -69776,7 +69858,7 @@ var GroupFileStore = class {
69776
69858
  }
69777
69859
  /** Remove all manifests and cache entries for this persona; these files live outside the persona directory. */
69778
69860
  deletePersona(personaId2) {
69779
- import_node_fs50.default.rmSync(import_node_path55.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
69861
+ import_node_fs51.default.rmSync(import_node_path56.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
69780
69862
  const prefix = `persona:${personaId2}:`;
69781
69863
  for (const key of this.cache.keys()) {
69782
69864
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -69785,10 +69867,10 @@ var GroupFileStore = class {
69785
69867
  };
69786
69868
 
69787
69869
  // src/discovery/state-file.ts
69788
- var import_node_fs51 = __toESM(require("fs"), 1);
69789
- var import_node_path56 = __toESM(require("path"), 1);
69870
+ var import_node_fs52 = __toESM(require("fs"), 1);
69871
+ var import_node_path57 = __toESM(require("path"), 1);
69790
69872
  function defaultStateFilePath(dataDir) {
69791
- return import_node_path56.default.join(dataDir, "state.json");
69873
+ return import_node_path57.default.join(dataDir, "state.json");
69792
69874
  }
69793
69875
  function isPidAlive(pid) {
69794
69876
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -69810,7 +69892,7 @@ var StateFileManager = class {
69810
69892
  }
69811
69893
  read() {
69812
69894
  try {
69813
- const raw = import_node_fs51.default.readFileSync(this.file, "utf8");
69895
+ const raw = import_node_fs52.default.readFileSync(this.file, "utf8");
69814
69896
  const parsed = JSON.parse(raw);
69815
69897
  return parsed;
69816
69898
  } catch {
@@ -69824,20 +69906,20 @@ var StateFileManager = class {
69824
69906
  return { status: "stale", existing };
69825
69907
  }
69826
69908
  write(state) {
69827
- import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
69909
+ import_node_fs52.default.mkdirSync(import_node_path57.default.dirname(this.file), { recursive: true });
69828
69910
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
69829
- import_node_fs51.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
69830
- import_node_fs51.default.renameSync(tmp, this.file);
69911
+ import_node_fs52.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
69912
+ import_node_fs52.default.renameSync(tmp, this.file);
69831
69913
  if (process.platform !== "win32") {
69832
69914
  try {
69833
- import_node_fs51.default.chmodSync(this.file, 384);
69915
+ import_node_fs52.default.chmodSync(this.file, 384);
69834
69916
  } catch {
69835
69917
  }
69836
69918
  }
69837
69919
  }
69838
69920
  delete() {
69839
69921
  try {
69840
- import_node_fs51.default.unlinkSync(this.file);
69922
+ import_node_fs52.default.unlinkSync(this.file);
69841
69923
  } catch {
69842
69924
  }
69843
69925
  }
@@ -69851,14 +69933,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
69851
69933
  }
69852
69934
 
69853
69935
  // src/tunnel/tunnel-manager.ts
69854
- var import_node_fs55 = __toESM(require("fs"), 1);
69855
- var import_node_path60 = __toESM(require("path"), 1);
69936
+ var import_node_fs56 = __toESM(require("fs"), 1);
69937
+ var import_node_path61 = __toESM(require("path"), 1);
69856
69938
  var import_node_crypto21 = __toESM(require("crypto"), 1);
69857
69939
  var import_node_child_process17 = require("child_process");
69858
69940
 
69859
69941
  // src/tunnel/tunnel-store.ts
69860
- var import_node_fs52 = __toESM(require("fs"), 1);
69861
- var import_node_path57 = __toESM(require("path"), 1);
69942
+ var import_node_fs53 = __toESM(require("fs"), 1);
69943
+ var import_node_path58 = __toESM(require("path"), 1);
69862
69944
  var TunnelStore = class {
69863
69945
  constructor(filePath) {
69864
69946
  this.filePath = filePath;
@@ -69866,7 +69948,7 @@ var TunnelStore = class {
69866
69948
  filePath;
69867
69949
  async get() {
69868
69950
  try {
69869
- const raw = await import_node_fs52.default.promises.readFile(this.filePath, "utf8");
69951
+ const raw = await import_node_fs53.default.promises.readFile(this.filePath, "utf8");
69870
69952
  const obj = JSON.parse(raw);
69871
69953
  if (!isPersistedTunnel(obj)) return null;
69872
69954
  return obj;
@@ -69877,22 +69959,22 @@ var TunnelStore = class {
69877
69959
  }
69878
69960
  }
69879
69961
  async set(v3) {
69880
- const dir = import_node_path57.default.dirname(this.filePath);
69881
- await import_node_fs52.default.promises.mkdir(dir, { recursive: true });
69962
+ const dir = import_node_path58.default.dirname(this.filePath);
69963
+ await import_node_fs53.default.promises.mkdir(dir, { recursive: true });
69882
69964
  const data = JSON.stringify(v3, null, 2);
69883
69965
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
69884
- await import_node_fs52.default.promises.writeFile(tmp, data, { mode: 384 });
69966
+ await import_node_fs53.default.promises.writeFile(tmp, data, { mode: 384 });
69885
69967
  if (process.platform !== "win32") {
69886
69968
  try {
69887
- await import_node_fs52.default.promises.chmod(tmp, 384);
69969
+ await import_node_fs53.default.promises.chmod(tmp, 384);
69888
69970
  } catch {
69889
69971
  }
69890
69972
  }
69891
- await import_node_fs52.default.promises.rename(tmp, this.filePath);
69973
+ await import_node_fs53.default.promises.rename(tmp, this.filePath);
69892
69974
  }
69893
69975
  async clear() {
69894
69976
  try {
69895
- await import_node_fs52.default.promises.unlink(this.filePath);
69977
+ await import_node_fs53.default.promises.unlink(this.filePath);
69896
69978
  } catch (err) {
69897
69979
  const code = err?.code;
69898
69980
  if (code !== "ENOENT") throw err;
@@ -69987,9 +70069,9 @@ function escape2(v3) {
69987
70069
  }
69988
70070
 
69989
70071
  // src/tunnel/frpc-binary.ts
69990
- var import_node_fs53 = __toESM(require("fs"), 1);
70072
+ var import_node_fs54 = __toESM(require("fs"), 1);
69991
70073
  var import_node_os21 = __toESM(require("os"), 1);
69992
- var import_node_path58 = __toESM(require("path"), 1);
70074
+ var import_node_path59 = __toESM(require("path"), 1);
69993
70075
  var import_node_child_process15 = require("child_process");
69994
70076
  var import_node_stream4 = require("stream");
69995
70077
  var import_promises10 = require("stream/promises");
@@ -70021,20 +70103,20 @@ function frpcDownloadUrl(version2, p3) {
70021
70103
  }
70022
70104
  async function ensureFrpcBinary(opts) {
70023
70105
  if (opts.override) {
70024
- if (!import_node_fs53.default.existsSync(opts.override)) {
70106
+ if (!import_node_fs54.default.existsSync(opts.override)) {
70025
70107
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
70026
70108
  }
70027
70109
  return opts.override;
70028
70110
  }
70029
70111
  const version2 = opts.version ?? FRPC_VERSION;
70030
70112
  const platform = opts.platform ?? detectPlatform();
70031
- const binDir = import_node_path58.default.join(opts.dataDir, "bin");
70032
- import_node_fs53.default.mkdirSync(binDir, { recursive: true });
70113
+ const binDir = import_node_path59.default.join(opts.dataDir, "bin");
70114
+ import_node_fs54.default.mkdirSync(binDir, { recursive: true });
70033
70115
  cleanupStaleArtifacts(binDir);
70034
- const stableBin = import_node_path58.default.join(binDir, "frpc");
70035
- if (import_node_fs53.default.existsSync(stableBin)) return stableBin;
70116
+ const stableBin = import_node_path59.default.join(binDir, "frpc");
70117
+ if (import_node_fs54.default.existsSync(stableBin)) return stableBin;
70036
70118
  const partialBin = `${stableBin}.partial`;
70037
- const tarballPath = import_node_path58.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
70119
+ const tarballPath = import_node_path59.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
70038
70120
  try {
70039
70121
  const url = frpcDownloadUrl(version2, platform);
70040
70122
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -70043,8 +70125,8 @@ async function ensureFrpcBinary(opts) {
70043
70125
  } else {
70044
70126
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
70045
70127
  }
70046
- import_node_fs53.default.chmodSync(partialBin, 493);
70047
- import_node_fs53.default.renameSync(partialBin, stableBin);
70128
+ import_node_fs54.default.chmodSync(partialBin, 493);
70129
+ import_node_fs54.default.renameSync(partialBin, stableBin);
70048
70130
  } finally {
70049
70131
  safeUnlink(tarballPath);
70050
70132
  safeUnlink(partialBin);
@@ -70054,15 +70136,15 @@ async function ensureFrpcBinary(opts) {
70054
70136
  function cleanupStaleArtifacts(binDir) {
70055
70137
  let entries;
70056
70138
  try {
70057
- entries = import_node_fs53.default.readdirSync(binDir);
70139
+ entries = import_node_fs54.default.readdirSync(binDir);
70058
70140
  } catch {
70059
70141
  return;
70060
70142
  }
70061
70143
  for (const name of entries) {
70062
70144
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
70063
- const full = import_node_path58.default.join(binDir, name);
70145
+ const full = import_node_path59.default.join(binDir, name);
70064
70146
  try {
70065
- import_node_fs53.default.rmSync(full, { recursive: true, force: true });
70147
+ import_node_fs54.default.rmSync(full, { recursive: true, force: true });
70066
70148
  } catch {
70067
70149
  }
70068
70150
  }
@@ -70070,7 +70152,7 @@ function cleanupStaleArtifacts(binDir) {
70070
70152
  }
70071
70153
  function safeUnlink(p3) {
70072
70154
  try {
70073
- import_node_fs53.default.unlinkSync(p3);
70155
+ import_node_fs54.default.unlinkSync(p3);
70074
70156
  } catch {
70075
70157
  }
70076
70158
  }
@@ -70081,13 +70163,13 @@ async function downloadToFile(url, dest, fetchImpl) {
70081
70163
  if (!res.ok || !res.body) {
70082
70164
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
70083
70165
  }
70084
- const out = import_node_fs53.default.createWriteStream(dest);
70166
+ const out = import_node_fs54.default.createWriteStream(dest);
70085
70167
  const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
70086
70168
  await (0, import_promises10.pipeline)(nodeStream, out);
70087
70169
  }
70088
70170
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
70089
- const work = import_node_path58.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
70090
- import_node_fs53.default.mkdirSync(work, { recursive: true });
70171
+ const work = import_node_path59.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
70172
+ import_node_fs54.default.mkdirSync(work, { recursive: true });
70091
70173
  try {
70092
70174
  await new Promise((resolve9, reject) => {
70093
70175
  const proc = (0, import_node_child_process15.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -70095,32 +70177,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
70095
70177
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
70096
70178
  });
70097
70179
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
70098
- const src = import_node_path58.default.join(work, dirName, "frpc");
70099
- if (!import_node_fs53.default.existsSync(src)) {
70180
+ const src = import_node_path59.default.join(work, dirName, "frpc");
70181
+ if (!import_node_fs54.default.existsSync(src)) {
70100
70182
  throw new Error(`frpc not found inside tarball at ${src}`);
70101
70183
  }
70102
- import_node_fs53.default.copyFileSync(src, destBin);
70184
+ import_node_fs54.default.copyFileSync(src, destBin);
70103
70185
  } finally {
70104
- import_node_fs53.default.rmSync(work, { recursive: true, force: true });
70186
+ import_node_fs54.default.rmSync(work, { recursive: true, force: true });
70105
70187
  }
70106
70188
  }
70107
70189
 
70108
70190
  // src/tunnel/frpc-process.ts
70109
- var import_node_fs54 = __toESM(require("fs"), 1);
70110
- var import_node_path59 = __toESM(require("path"), 1);
70191
+ var import_node_fs55 = __toESM(require("fs"), 1);
70192
+ var import_node_path60 = __toESM(require("path"), 1);
70111
70193
  var import_node_child_process16 = require("child_process");
70112
70194
  function frpcPidFilePath(dataDir) {
70113
- return import_node_path59.default.join(dataDir, "frpc.pid");
70195
+ return import_node_path60.default.join(dataDir, "frpc.pid");
70114
70196
  }
70115
70197
  function writeFrpcPid(dataDir, pid) {
70116
70198
  try {
70117
- import_node_fs54.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
70199
+ import_node_fs55.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
70118
70200
  } catch {
70119
70201
  }
70120
70202
  }
70121
70203
  function clearFrpcPid(dataDir) {
70122
70204
  try {
70123
- import_node_fs54.default.unlinkSync(frpcPidFilePath(dataDir));
70205
+ import_node_fs55.default.unlinkSync(frpcPidFilePath(dataDir));
70124
70206
  } catch {
70125
70207
  }
70126
70208
  }
@@ -70136,7 +70218,7 @@ function defaultIsPidAlive(pid) {
70136
70218
  }
70137
70219
  function defaultReadPidFile(file) {
70138
70220
  try {
70139
- return import_node_fs54.default.readFileSync(file, "utf8");
70221
+ return import_node_fs55.default.readFileSync(file, "utf8");
70140
70222
  } catch {
70141
70223
  return null;
70142
70224
  }
@@ -70152,7 +70234,7 @@ function defaultSleep2(ms) {
70152
70234
  }
70153
70235
  async function killStaleFrpc(deps) {
70154
70236
  const pidFile = frpcPidFilePath(deps.dataDir);
70155
- const tomlPath = import_node_path59.default.join(deps.dataDir, "frpc.toml");
70237
+ const tomlPath = import_node_path60.default.join(deps.dataDir, "frpc.toml");
70156
70238
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
70157
70239
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
70158
70240
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -70176,7 +70258,7 @@ async function killStaleFrpc(deps) {
70176
70258
  }
70177
70259
  if (victims.size === 0) {
70178
70260
  try {
70179
- import_node_fs54.default.unlinkSync(pidFile);
70261
+ import_node_fs55.default.unlinkSync(pidFile);
70180
70262
  } catch {
70181
70263
  }
70182
70264
  return;
@@ -70187,7 +70269,7 @@ async function killStaleFrpc(deps) {
70187
70269
  }
70188
70270
  await sleep2(deps.reapWaitMs ?? 300);
70189
70271
  try {
70190
- import_node_fs54.default.unlinkSync(pidFile);
70272
+ import_node_fs55.default.unlinkSync(pidFile);
70191
70273
  } catch {
70192
70274
  }
70193
70275
  }
@@ -70224,7 +70306,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
70224
70306
  var TunnelManager = class {
70225
70307
  constructor(deps) {
70226
70308
  this.deps = deps;
70227
- this.store = deps.store ?? new TunnelStore(import_node_path60.default.join(deps.dataDir, "tunnel.json"));
70309
+ this.store = deps.store ?? new TunnelStore(import_node_path61.default.join(deps.dataDir, "tunnel.json"));
70228
70310
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
70229
70311
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
70230
70312
  }
@@ -70349,7 +70431,7 @@ var TunnelManager = class {
70349
70431
  dataDir: this.deps.dataDir,
70350
70432
  override: this.deps.frpcBinaryOverride ?? void 0
70351
70433
  });
70352
- const tomlPath = import_node_path60.default.join(this.deps.dataDir, "frpc.toml");
70434
+ const tomlPath = import_node_path61.default.join(this.deps.dataDir, "frpc.toml");
70353
70435
  const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto21.default.randomBytes(3).toString("hex")}`;
70354
70436
  const toml = buildFrpcToml({
70355
70437
  serverAddr: t2.frpsHost,
@@ -70360,14 +70442,14 @@ var TunnelManager = class {
70360
70442
  localPort,
70361
70443
  logLevel: "info"
70362
70444
  });
70363
- await import_node_fs55.default.promises.writeFile(tomlPath, toml, { mode: 384 });
70445
+ await import_node_fs56.default.promises.writeFile(tomlPath, toml, { mode: 384 });
70364
70446
  const proc = (this.deps.spawnImpl ?? import_node_child_process17.spawn)(frpcBin, ["-c", tomlPath], {
70365
70447
  stdio: ["ignore", "pipe", "pipe"]
70366
70448
  });
70367
- const logDir = import_node_path60.default.join(this.deps.dataDir, "log");
70368
- import_node_fs55.default.mkdirSync(logDir, { recursive: true });
70369
- const logFilePath = import_node_path60.default.join(logDir, "frpc.log");
70370
- const logStream = import_node_fs55.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
70449
+ const logDir = import_node_path61.default.join(this.deps.dataDir, "log");
70450
+ import_node_fs56.default.mkdirSync(logDir, { recursive: true });
70451
+ const logFilePath = import_node_path61.default.join(logDir, "frpc.log");
70452
+ const logStream = import_node_fs56.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
70371
70453
  logStream.on("error", () => {
70372
70454
  });
70373
70455
  const tee = (chunk) => {
@@ -70450,27 +70532,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
70450
70532
 
70451
70533
  // src/tunnel/device-key.ts
70452
70534
  var import_node_os22 = __toESM(require("os"), 1);
70453
- var import_node_path61 = __toESM(require("path"), 1);
70535
+ var import_node_path62 = __toESM(require("path"), 1);
70454
70536
  var import_node_crypto22 = __toESM(require("crypto"), 1);
70455
70537
  var DERIVE_SALT = "clawd-tunnel-device-v1";
70456
70538
  function deriveStableDeviceKey(opts = {}) {
70457
70539
  const hostname = opts.hostname ?? import_node_os22.default.hostname();
70458
70540
  const uid = opts.uid ?? (typeof import_node_os22.default.userInfo === "function" ? import_node_os22.default.userInfo().uid : 0);
70459
70541
  const home = opts.home ?? import_node_os22.default.homedir();
70460
- const defaultDataDir = import_node_path61.default.resolve(import_node_path61.default.join(home, ".clawd"));
70461
- const normalizedDataDir = opts.dataDir ? import_node_path61.default.resolve(opts.dataDir) : null;
70542
+ const defaultDataDir = import_node_path62.default.resolve(import_node_path62.default.join(home, ".clawd"));
70543
+ const normalizedDataDir = opts.dataDir ? import_node_path62.default.resolve(opts.dataDir) : null;
70462
70544
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
70463
70545
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
70464
70546
  return import_node_crypto22.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
70465
70547
  }
70466
70548
 
70467
70549
  // src/auth-store.ts
70468
- var import_node_fs56 = __toESM(require("fs"), 1);
70469
- var import_node_path62 = __toESM(require("path"), 1);
70550
+ var import_node_fs57 = __toESM(require("fs"), 1);
70551
+ var import_node_path63 = __toESM(require("path"), 1);
70470
70552
  var import_node_crypto23 = __toESM(require("crypto"), 1);
70471
70553
  var AUTH_FILE_NAME = "auth.json";
70472
70554
  function authFilePath(dataDir) {
70473
- return import_node_path62.default.join(dataDir, AUTH_FILE_NAME);
70555
+ return import_node_path63.default.join(dataDir, AUTH_FILE_NAME);
70474
70556
  }
70475
70557
  function loadOrCreateAuthFile(opts) {
70476
70558
  const file = authFilePath(opts.dataDir);
@@ -70511,7 +70593,7 @@ function defaultGenerateOwnerPrincipalId() {
70511
70593
  }
70512
70594
  function readAuthFile(file) {
70513
70595
  try {
70514
- const raw = import_node_fs56.default.readFileSync(file, "utf8");
70596
+ const raw = import_node_fs57.default.readFileSync(file, "utf8");
70515
70597
  const parsed = JSON.parse(raw);
70516
70598
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
70517
70599
  return null;
@@ -70532,26 +70614,26 @@ function readAuthFile(file) {
70532
70614
  }
70533
70615
  }
70534
70616
  function writeAuthFile(file, content) {
70535
- import_node_fs56.default.mkdirSync(import_node_path62.default.dirname(file), { recursive: true });
70536
- import_node_fs56.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
70617
+ import_node_fs57.default.mkdirSync(import_node_path63.default.dirname(file), { recursive: true });
70618
+ import_node_fs57.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
70537
70619
  try {
70538
- import_node_fs56.default.chmodSync(file, 384);
70620
+ import_node_fs57.default.chmodSync(file, 384);
70539
70621
  } catch {
70540
70622
  }
70541
70623
  }
70542
70624
 
70543
70625
  // src/owner-profile.ts
70544
- var import_node_fs57 = __toESM(require("fs"), 1);
70626
+ var import_node_fs58 = __toESM(require("fs"), 1);
70545
70627
  var import_node_os23 = __toESM(require("os"), 1);
70546
- var import_node_path63 = __toESM(require("path"), 1);
70628
+ var import_node_path64 = __toESM(require("path"), 1);
70547
70629
  var PROFILE_FILENAME = "profile.json";
70548
70630
  function profilePath(dataDir) {
70549
- return import_node_path63.default.join(dataDir, PROFILE_FILENAME);
70631
+ return import_node_path64.default.join(dataDir, PROFILE_FILENAME);
70550
70632
  }
70551
70633
  function loadOwnerProfile(dataDir) {
70552
70634
  let raw;
70553
70635
  try {
70554
- raw = import_node_fs57.default.readFileSync(profilePath(dataDir), "utf8");
70636
+ raw = import_node_fs58.default.readFileSync(profilePath(dataDir), "utf8");
70555
70637
  } catch {
70556
70638
  return {};
70557
70639
  }
@@ -70567,7 +70649,7 @@ function loadOwnerProfile(dataDir) {
70567
70649
  }
70568
70650
  function patchOwnerProfile(dataDir, patch) {
70569
70651
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
70570
- import_node_fs57.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70652
+ import_node_fs58.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70571
70653
  return merged;
70572
70654
  }
70573
70655
  function loadOwnerDisplayName(dataDir) {
@@ -70583,18 +70665,18 @@ function loadOwnerDisplayName(dataDir) {
70583
70665
  }
70584
70666
 
70585
70667
  // src/feishu-auth/owner-identity-store.ts
70586
- var import_node_fs58 = __toESM(require("fs"), 1);
70587
- var import_node_path64 = __toESM(require("path"), 1);
70668
+ var import_node_fs59 = __toESM(require("fs"), 1);
70669
+ var import_node_path65 = __toESM(require("path"), 1);
70588
70670
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
70589
70671
  var OwnerIdentityStore = class {
70590
70672
  file;
70591
70673
  constructor(dataDir, environment = "production") {
70592
- this.file = import_node_path64.default.join(dataDir, environment === "production" ? OWNER_IDENTITY_FILE_NAME : "owner-identity.integration.json");
70674
+ this.file = import_node_path65.default.join(dataDir, environment === "production" ? OWNER_IDENTITY_FILE_NAME : "owner-identity.integration.json");
70593
70675
  }
70594
70676
  read() {
70595
70677
  let raw;
70596
70678
  try {
70597
- raw = import_node_fs58.default.readFileSync(this.file, "utf8");
70679
+ raw = import_node_fs59.default.readFileSync(this.file, "utf8");
70598
70680
  } catch {
70599
70681
  return null;
70600
70682
  }
@@ -70621,16 +70703,16 @@ var OwnerIdentityStore = class {
70621
70703
  };
70622
70704
  }
70623
70705
  write(record4) {
70624
- import_node_fs58.default.mkdirSync(import_node_path64.default.dirname(this.file), { recursive: true });
70625
- import_node_fs58.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
70706
+ import_node_fs59.default.mkdirSync(import_node_path65.default.dirname(this.file), { recursive: true });
70707
+ import_node_fs59.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
70626
70708
  try {
70627
- import_node_fs58.default.chmodSync(this.file, 384);
70709
+ import_node_fs59.default.chmodSync(this.file, 384);
70628
70710
  } catch {
70629
70711
  }
70630
70712
  }
70631
70713
  clear() {
70632
70714
  try {
70633
- import_node_fs58.default.unlinkSync(this.file);
70715
+ import_node_fs59.default.unlinkSync(this.file);
70634
70716
  } catch (err) {
70635
70717
  const code = err?.code;
70636
70718
  if (code !== "ENOENT") throw err;
@@ -71130,8 +71212,8 @@ function verifyConnectToken(args) {
71130
71212
  }
71131
71213
 
71132
71214
  // src/feishu-auth/server-key.ts
71133
- var fs75 = __toESM(require("fs"), 1);
71134
- var path77 = __toESM(require("path"), 1);
71215
+ var fs76 = __toESM(require("fs"), 1);
71216
+ var path78 = __toESM(require("path"), 1);
71135
71217
  var FILE_NAME2 = "server-signing-key.json";
71136
71218
  var ServerKeyStore = class {
71137
71219
  constructor(dataDir) {
@@ -71139,12 +71221,12 @@ var ServerKeyStore = class {
71139
71221
  }
71140
71222
  dataDir;
71141
71223
  filePath() {
71142
- return path77.join(this.dataDir, FILE_NAME2);
71224
+ return path78.join(this.dataDir, FILE_NAME2);
71143
71225
  }
71144
71226
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
71145
71227
  read() {
71146
71228
  try {
71147
- const raw = fs75.readFileSync(this.filePath(), "utf8");
71229
+ const raw = fs76.readFileSync(this.filePath(), "utf8");
71148
71230
  const parsed = JSON.parse(raw);
71149
71231
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
71150
71232
  return parsed.publicKeyPem;
@@ -71159,12 +71241,12 @@ var ServerKeyStore = class {
71159
71241
  publicKeyPem,
71160
71242
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
71161
71243
  };
71162
- fs75.mkdirSync(this.dataDir, { recursive: true });
71163
- fs75.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
71244
+ fs76.mkdirSync(this.dataDir, { recursive: true });
71245
+ fs76.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
71164
71246
  }
71165
71247
  clear() {
71166
71248
  try {
71167
- fs75.unlinkSync(this.filePath());
71249
+ fs76.unlinkSync(this.filePath());
71168
71250
  } catch {
71169
71251
  }
71170
71252
  }
@@ -71174,19 +71256,19 @@ var ServerKeyStore = class {
71174
71256
  init_protocol();
71175
71257
 
71176
71258
  // src/handlers/index.ts
71177
- var import_node_path81 = __toESM(require("path"), 1);
71259
+ var import_node_path82 = __toESM(require("path"), 1);
71178
71260
 
71179
71261
  // src/handlers/session.ts
71180
71262
  init_protocol();
71181
71263
 
71182
71264
  // src/session/fork.ts
71183
- var import_node_fs59 = __toESM(require("fs"), 1);
71265
+ var import_node_fs60 = __toESM(require("fs"), 1);
71184
71266
  var import_node_os24 = __toESM(require("os"), 1);
71185
- var import_node_path65 = __toESM(require("path"), 1);
71267
+ var import_node_path66 = __toESM(require("path"), 1);
71186
71268
  var import_node_crypto25 = require("crypto");
71187
71269
  init_claude_history();
71188
71270
  function readJsonlEntries(file) {
71189
- const raw = import_node_fs59.default.readFileSync(file, "utf8");
71271
+ const raw = import_node_fs60.default.readFileSync(file, "utf8");
71190
71272
  const out = [];
71191
71273
  for (const line of raw.split("\n")) {
71192
71274
  const t2 = line.trim();
@@ -71199,19 +71281,19 @@ function readJsonlEntries(file) {
71199
71281
  return out;
71200
71282
  }
71201
71283
  function forkSession(input) {
71202
- const baseDir = input.baseDir ?? import_node_path65.default.join(import_node_os24.default.homedir(), ".claude");
71203
- let projectDir = import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
71204
- let sourceFile = import_node_path65.default.join(projectDir, `${input.toolSessionId}.jsonl`);
71205
- if (!import_node_fs59.default.existsSync(sourceFile)) {
71284
+ const baseDir = input.baseDir ?? import_node_path66.default.join(import_node_os24.default.homedir(), ".claude");
71285
+ let projectDir = import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
71286
+ let sourceFile = import_node_path66.default.join(projectDir, `${input.toolSessionId}.jsonl`);
71287
+ if (!import_node_fs60.default.existsSync(sourceFile)) {
71206
71288
  const found = findTranscriptByToolSessionId(
71207
- import_node_path65.default.join(baseDir, "projects"),
71289
+ import_node_path66.default.join(baseDir, "projects"),
71208
71290
  input.toolSessionId
71209
71291
  );
71210
71292
  if (!found) {
71211
71293
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
71212
71294
  }
71213
71295
  sourceFile = found;
71214
- projectDir = import_node_path65.default.dirname(found);
71296
+ projectDir = import_node_path66.default.dirname(found);
71215
71297
  }
71216
71298
  const entries = readJsonlEntries(sourceFile);
71217
71299
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -71240,17 +71322,17 @@ function forkSession(input) {
71240
71322
  }
71241
71323
  forkedLines.push(JSON.stringify(forked));
71242
71324
  }
71243
- const outDir = input.targetCwd ? import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
71244
- const forkedFilePath = import_node_path65.default.join(outDir, `${forkedToolSessionId}.jsonl`);
71245
- import_node_fs59.default.mkdirSync(outDir, { recursive: true });
71246
- import_node_fs59.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
71325
+ const outDir = input.targetCwd ? import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
71326
+ const forkedFilePath = import_node_path66.default.join(outDir, `${forkedToolSessionId}.jsonl`);
71327
+ import_node_fs60.default.mkdirSync(outDir, { recursive: true });
71328
+ import_node_fs60.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
71247
71329
  return { forkedToolSessionId, forkedFilePath };
71248
71330
  }
71249
71331
 
71250
71332
  // src/tools/codex-fork.ts
71251
71333
  var import_node_child_process18 = require("child_process");
71252
- var import_node_fs60 = __toESM(require("fs"), 1);
71253
- var import_node_path66 = __toESM(require("path"), 1);
71334
+ var import_node_fs61 = __toESM(require("fs"), 1);
71335
+ var import_node_path67 = __toESM(require("path"), 1);
71254
71336
  function openCodexAppServer(home, cwd) {
71255
71337
  const proc = (0, import_node_child_process18.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
71256
71338
  cwd,
@@ -71270,7 +71352,7 @@ function openCodexAppServer(home, cwd) {
71270
71352
  async function forkCodexThread(input, deps = {}) {
71271
71353
  const source = locateCodexThread(input.roots, input.sourceThreadId);
71272
71354
  if (!source) throw new Error(`codex fork: source thread not found: ${input.sourceThreadId}`);
71273
- const rollout = parseCodexRollout(import_node_fs60.default.readFileSync(source.file, "utf8"));
71355
+ const rollout = parseCodexRollout(import_node_fs61.default.readFileSync(source.file, "utf8"));
71274
71356
  if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
71275
71357
  throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
71276
71358
  }
@@ -71305,7 +71387,7 @@ async function forkCodexThread(input, deps = {}) {
71305
71387
  if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
71306
71388
  throw new Error("codex fork: app-server returned no thread id");
71307
71389
  }
71308
- const forked = locateCodexThread([import_node_path66.default.join(owner2.home, "sessions")], forkedToolSessionId);
71390
+ const forked = locateCodexThread([import_node_path67.default.join(owner2.home, "sessions")], forkedToolSessionId);
71309
71391
  if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
71310
71392
  return { forkedToolSessionId, forkedFilePath: forked.file };
71311
71393
  })()]);
@@ -71316,19 +71398,19 @@ async function forkCodexThread(input, deps = {}) {
71316
71398
  }
71317
71399
 
71318
71400
  // src/session/external-scan.ts
71319
- var import_node_fs61 = __toESM(require("fs"), 1);
71401
+ var import_node_fs62 = __toESM(require("fs"), 1);
71320
71402
  var import_promises11 = __toESM(require("fs/promises"), 1);
71321
71403
  var import_node_os25 = __toESM(require("os"), 1);
71322
- var import_node_path67 = __toESM(require("path"), 1);
71404
+ var import_node_path68 = __toESM(require("path"), 1);
71323
71405
  var import_node_module = require("module");
71324
71406
  var import_node_child_process19 = require("child_process");
71325
71407
  var import_meta7 = {};
71326
71408
  function defaultRoots() {
71327
71409
  const home = import_node_os25.default.homedir();
71328
71410
  return {
71329
- claudeProjectsDir: import_node_path67.default.join(home, ".claude", "projects"),
71330
- codexDir: import_node_path67.default.join(home, ".codex"),
71331
- clawdDir: import_node_path67.default.join(home, ".clawd")
71411
+ claudeProjectsDir: import_node_path68.default.join(home, ".claude", "projects"),
71412
+ codexDir: import_node_path68.default.join(home, ".codex"),
71413
+ clawdDir: import_node_path68.default.join(home, ".clawd")
71332
71414
  };
71333
71415
  }
71334
71416
  function width(s2) {
@@ -71379,7 +71461,7 @@ function userText(msg) {
71379
71461
  }
71380
71462
  function isDir2(p3) {
71381
71463
  try {
71382
- return import_node_fs61.default.statSync(p3).isDirectory();
71464
+ return import_node_fs62.default.statSync(p3).isDirectory();
71383
71465
  } catch {
71384
71466
  return false;
71385
71467
  }
@@ -71388,7 +71470,7 @@ async function scanClaude(roots) {
71388
71470
  const out = [];
71389
71471
  let dirs;
71390
71472
  try {
71391
- dirs = import_node_fs61.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
71473
+ dirs = import_node_fs62.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
71392
71474
  } catch {
71393
71475
  return out;
71394
71476
  }
@@ -71396,16 +71478,16 @@ async function scanClaude(roots) {
71396
71478
  if (!d2.isDirectory()) continue;
71397
71479
  let files;
71398
71480
  try {
71399
- files = import_node_fs61.default.readdirSync(import_node_path67.default.join(roots.claudeProjectsDir, d2.name));
71481
+ files = import_node_fs62.default.readdirSync(import_node_path68.default.join(roots.claudeProjectsDir, d2.name));
71400
71482
  } catch {
71401
71483
  continue;
71402
71484
  }
71403
71485
  for (const name of files) {
71404
71486
  if (!name.endsWith(".jsonl")) continue;
71405
- const file = import_node_path67.default.join(roots.claudeProjectsDir, d2.name, name);
71487
+ const file = import_node_path68.default.join(roots.claudeProjectsDir, d2.name, name);
71406
71488
  let st2;
71407
71489
  try {
71408
- st2 = import_node_fs61.default.statSync(file);
71490
+ st2 = import_node_fs62.default.statSync(file);
71409
71491
  } catch {
71410
71492
  continue;
71411
71493
  }
@@ -71458,7 +71540,7 @@ async function scanClaude(roots) {
71458
71540
  return out;
71459
71541
  }
71460
71542
  async function countCodexTurns(rolloutPath) {
71461
- if (!rolloutPath || !import_node_fs61.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
71543
+ if (!rolloutPath || !import_node_fs62.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
71462
71544
  let turns = 0;
71463
71545
  let first = "";
71464
71546
  for await (const rec6 of jsonLines(rolloutPath)) {
@@ -71532,7 +71614,7 @@ async function codexFromRows(rows) {
71532
71614
  async function scanCodex(roots) {
71533
71615
  let dbs = [];
71534
71616
  try {
71535
- dbs = import_node_fs61.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path67.default.join(roots.codexDir, n2));
71617
+ dbs = import_node_fs62.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path68.default.join(roots.codexDir, n2));
71536
71618
  } catch {
71537
71619
  }
71538
71620
  if (!dbs.length) return [];
@@ -71541,14 +71623,14 @@ async function scanCodex(roots) {
71541
71623
  }
71542
71624
  async function scanExternalSessions(rootsIn) {
71543
71625
  const roots = { ...defaultRoots(), ...rootsIn };
71544
- const personaRoot = import_node_path67.default.join(roots.clawdDir, "personas");
71626
+ const personaRoot = import_node_path68.default.join(roots.clawdDir, "personas");
71545
71627
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
71546
71628
  const out = [];
71547
71629
  for (const c2 of all) {
71548
71630
  if (c2.skip) continue;
71549
71631
  if (c2.turns < 1) continue;
71550
71632
  if (!c2.cwd || !isDir2(c2.cwd)) continue;
71551
- if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path67.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path67.default.sep)) {
71633
+ if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path68.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path68.default.sep)) {
71552
71634
  continue;
71553
71635
  }
71554
71636
  out.push({
@@ -71565,13 +71647,13 @@ async function scanExternalSessions(rootsIn) {
71565
71647
  }
71566
71648
 
71567
71649
  // src/session/import-ledger.ts
71568
- var import_node_fs62 = __toESM(require("fs"), 1);
71569
- var import_node_path68 = __toESM(require("path"), 1);
71650
+ var import_node_fs63 = __toESM(require("fs"), 1);
71651
+ var import_node_path69 = __toESM(require("path"), 1);
71570
71652
  var LEDGER_FILENAME = "session-import-ledger.json";
71571
71653
  function readImportLedger(dataDir) {
71572
71654
  try {
71573
71655
  const parsed = JSON.parse(
71574
- import_node_fs62.default.readFileSync(import_node_path68.default.join(dataDir, LEDGER_FILENAME), "utf8")
71656
+ import_node_fs63.default.readFileSync(import_node_path69.default.join(dataDir, LEDGER_FILENAME), "utf8")
71575
71657
  );
71576
71658
  return Array.isArray(parsed) ? parsed : [];
71577
71659
  } catch {
@@ -71579,15 +71661,15 @@ function readImportLedger(dataDir) {
71579
71661
  }
71580
71662
  }
71581
71663
  function appendImportLedger(dataDir, entry) {
71582
- const file = import_node_path68.default.join(dataDir, LEDGER_FILENAME);
71664
+ const file = import_node_path69.default.join(dataDir, LEDGER_FILENAME);
71583
71665
  const entries = readImportLedger(dataDir);
71584
71666
  entries.push(entry);
71585
- import_node_fs62.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71667
+ import_node_fs63.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71586
71668
  }
71587
71669
 
71588
71670
  // src/handlers/session.ts
71589
71671
  init_protocol();
71590
- var import_node_path69 = __toESM(require("path"), 1);
71672
+ var import_node_path70 = __toESM(require("path"), 1);
71591
71673
  function canReadSearchHit(ctx, file) {
71592
71674
  if (!ctx || ctx.principal.kind === "owner") return true;
71593
71675
  return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
@@ -71868,7 +71950,7 @@ ${attribution}` } : args;
71868
71950
  `principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
71869
71951
  );
71870
71952
  }
71871
- if (source?.tool === "codex" && args.targetCwd && import_node_path69.default.resolve(args.targetCwd) !== import_node_path69.default.resolve(source.cwd)) {
71953
+ if (source?.tool === "codex" && args.targetCwd && import_node_path70.default.resolve(args.targetCwd) !== import_node_path70.default.resolve(source.cwd)) {
71872
71954
  throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
71873
71955
  }
71874
71956
  }
@@ -72145,7 +72227,7 @@ function buildPermissionHandlers(deps) {
72145
72227
  }
72146
72228
 
72147
72229
  // src/handlers/history.ts
72148
- var path84 = __toESM(require("path"), 1);
72230
+ var path85 = __toESM(require("path"), 1);
72149
72231
  init_protocol();
72150
72232
 
72151
72233
  // src/session/recent-dirs.ts
@@ -72163,7 +72245,7 @@ function listRecentDirs(store, limit = 50) {
72163
72245
  }
72164
72246
 
72165
72247
  // src/permission/persona-paths.ts
72166
- var path83 = __toESM(require("path"), 1);
72248
+ var path84 = __toESM(require("path"), 1);
72167
72249
  function getAllowedPersonaIds(grants, action) {
72168
72250
  const ids = /* @__PURE__ */ new Set();
72169
72251
  for (const g3 of grants) {
@@ -72176,42 +72258,42 @@ function getAllowedPersonaIds(grants, action) {
72176
72258
  return ids;
72177
72259
  }
72178
72260
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
72179
- const target = path83.resolve(absPath);
72261
+ const target = path84.resolve(absPath);
72180
72262
  if (userWorkDir) {
72181
- const u2 = path83.resolve(userWorkDir);
72182
- const usep = u2.endsWith(path83.sep) ? "" : path83.sep;
72263
+ const u2 = path84.resolve(userWorkDir);
72264
+ const usep = u2.endsWith(path84.sep) ? "" : path84.sep;
72183
72265
  if (target === u2 || target.startsWith(u2 + usep)) return true;
72184
72266
  }
72185
- const root = path83.resolve(personaRoot);
72186
- const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
72267
+ const root = path84.resolve(personaRoot);
72268
+ const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
72187
72269
  if (!target.startsWith(root + sep4)) return false;
72188
- const rel = path83.relative(root, target);
72270
+ const rel = path84.relative(root, target);
72189
72271
  if (!rel || rel.startsWith("..")) return false;
72190
- const personaId2 = rel.split(path83.sep)[0];
72272
+ const personaId2 = rel.split(path84.sep)[0];
72191
72273
  if (!personaId2) return false;
72192
72274
  const allowed = getAllowedPersonaIds(grants, action);
72193
72275
  if (allowed === "*") return true;
72194
72276
  return allowed.has(personaId2);
72195
72277
  }
72196
72278
  function personaIdFromPath(absPath, personaRoot) {
72197
- const root = path83.resolve(personaRoot);
72198
- const target = path83.resolve(absPath);
72199
- const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
72279
+ const root = path84.resolve(personaRoot);
72280
+ const target = path84.resolve(absPath);
72281
+ const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
72200
72282
  if (!target.startsWith(root + sep4)) return null;
72201
- const rel = path83.relative(root, target);
72283
+ const rel = path84.relative(root, target);
72202
72284
  if (!rel || rel.startsWith("..")) return null;
72203
- const id = rel.split(path83.sep)[0];
72285
+ const id = rel.split(path84.sep)[0];
72204
72286
  return id || null;
72205
72287
  }
72206
72288
  function isPathWithin(dir, absPath) {
72207
- const d2 = path83.resolve(dir);
72208
- const t2 = path83.resolve(absPath);
72209
- const sep4 = d2.endsWith(path83.sep) ? "" : path83.sep;
72289
+ const d2 = path84.resolve(dir);
72290
+ const t2 = path84.resolve(absPath);
72291
+ const sep4 = d2.endsWith(path84.sep) ? "" : path84.sep;
72210
72292
  return t2 === d2 || t2.startsWith(d2 + sep4);
72211
72293
  }
72212
72294
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
72213
72295
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
72214
- return personaIdFromPath(path83.resolve(absPath), personaRoot) === personaId2;
72296
+ return personaIdFromPath(path84.resolve(absPath), personaRoot) === personaId2;
72215
72297
  }
72216
72298
 
72217
72299
  // src/handlers/history.ts
@@ -72265,7 +72347,7 @@ function buildHistoryHandlers(deps) {
72265
72347
  if (!pid) return false;
72266
72348
  return isGuestPathAllowed(
72267
72349
  ctx.grants,
72268
- path84.join(personaRoot, pid),
72350
+ path85.join(personaRoot, pid),
72269
72351
  personaRoot,
72270
72352
  "read",
72271
72353
  userWorkDir
@@ -72277,7 +72359,7 @@ function buildHistoryHandlers(deps) {
72277
72359
  };
72278
72360
  const list = async (frame, _client, ctx) => {
72279
72361
  const args = HistoryListArgs.parse(frame);
72280
- assertGuestPath(ctx, path84.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
72362
+ assertGuestPath(ctx, path85.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
72281
72363
  const sessions = await history.listSessions(args);
72282
72364
  return { response: { type: "history:list", sessions } };
72283
72365
  };
@@ -72369,14 +72451,14 @@ function buildHistoryHandlers(deps) {
72369
72451
  };
72370
72452
  const subagents = async (frame, _client, ctx) => {
72371
72453
  const args = HistorySubagentsArgs.parse(frame);
72372
- assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
72454
+ assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
72373
72455
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
72374
72456
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
72375
72457
  return { response: { type: "history:subagents", subagents: subs } };
72376
72458
  };
72377
72459
  const subagentRead = async (frame, _client, ctx) => {
72378
72460
  const args = HistorySubagentReadArgs.parse(frame);
72379
- assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
72461
+ assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
72380
72462
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
72381
72463
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
72382
72464
  return { response: { type: "history:subagent-read", ...res } };
@@ -72386,7 +72468,7 @@ function buildHistoryHandlers(deps) {
72386
72468
  if (ctx?.principal.kind === "guest" && personaRoot) {
72387
72469
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72388
72470
  const filtered = dirs.filter(
72389
- (d2) => isGuestPathAllowed(ctx.grants, path84.resolve(d2.cwd), personaRoot, "read", userWorkDir)
72471
+ (d2) => isGuestPathAllowed(ctx.grants, path85.resolve(d2.cwd), personaRoot, "read", userWorkDir)
72390
72472
  );
72391
72473
  return { response: { type: "history:recentDirs", dirs: filtered } };
72392
72474
  }
@@ -72403,17 +72485,17 @@ function buildHistoryHandlers(deps) {
72403
72485
  }
72404
72486
 
72405
72487
  // src/handlers/projects.ts
72406
- var fs80 = __toESM(require("fs"), 1);
72488
+ var fs81 = __toESM(require("fs"), 1);
72407
72489
  var os27 = __toESM(require("os"), 1);
72408
- var path85 = __toESM(require("path"), 1);
72490
+ var path86 = __toESM(require("path"), 1);
72409
72491
  var import_node_child_process20 = require("child_process");
72410
72492
  init_protocol();
72411
- var DEFAULT_PROJECTS_ROOT = path85.join(os27.homedir(), "Documents", "ChatGPT");
72493
+ var DEFAULT_PROJECTS_ROOT = path86.join(os27.homedir(), "Documents", "ChatGPT");
72412
72494
  function allocateDir(root, name) {
72413
- let candidate = path85.join(root, name);
72495
+ let candidate = path86.join(root, name);
72414
72496
  let n2 = 2;
72415
- while (fs80.existsSync(candidate)) {
72416
- candidate = path85.join(root, `${name} ${n2}`);
72497
+ while (fs81.existsSync(candidate)) {
72498
+ candidate = path86.join(root, `${name} ${n2}`);
72417
72499
  n2 += 1;
72418
72500
  }
72419
72501
  return candidate;
@@ -72441,7 +72523,7 @@ function buildProjectHandlers(deps) {
72441
72523
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
72442
72524
  }
72443
72525
  try {
72444
- if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72526
+ if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
72445
72527
  } catch {
72446
72528
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72447
72529
  }
@@ -72457,7 +72539,7 @@ function buildProjectHandlers(deps) {
72457
72539
  let target;
72458
72540
  if (args.path) {
72459
72541
  try {
72460
- if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72542
+ if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
72461
72543
  } catch {
72462
72544
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72463
72545
  }
@@ -72465,15 +72547,15 @@ function buildProjectHandlers(deps) {
72465
72547
  } else {
72466
72548
  const name = args.name;
72467
72549
  try {
72468
- fs80.mkdirSync(root, { recursive: true });
72550
+ fs81.mkdirSync(root, { recursive: true });
72469
72551
  target = allocateDir(root, name);
72470
- fs80.mkdirSync(target);
72552
+ fs81.mkdirSync(target);
72471
72553
  } catch (err) {
72472
72554
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
72473
72555
  }
72474
72556
  const git2 = (0, import_node_child_process20.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
72475
72557
  if (git2.status !== 0) {
72476
- fs80.rmSync(target, { recursive: true, force: true });
72558
+ fs81.rmSync(target, { recursive: true, force: true });
72477
72559
  throw new ClawdError(
72478
72560
  ERROR_CODES.INVALID_CWD,
72479
72561
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -72498,7 +72580,7 @@ function buildProjectHandlers(deps) {
72498
72580
  }
72499
72581
 
72500
72582
  // src/handlers/workspace.ts
72501
- var path86 = __toESM(require("path"), 1);
72583
+ var path87 = __toESM(require("path"), 1);
72502
72584
  init_protocol();
72503
72585
  var os28 = __toESM(require("os"), 1);
72504
72586
  init_protocol();
@@ -72541,22 +72623,22 @@ function buildWorkspaceHandlers(deps) {
72541
72623
  const args = WorkspaceListArgs.parse(frame);
72542
72624
  const isGuest = ctx?.principal.kind === "guest";
72543
72625
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os28.homedir();
72544
- const resolvedCwd = path86.resolve(args.cwd ?? fallbackCwd);
72545
- const target = args.path ? path86.resolve(resolvedCwd, args.path) : resolvedCwd;
72626
+ const resolvedCwd = path87.resolve(args.cwd ?? fallbackCwd);
72627
+ const target = args.path ? path87.resolve(resolvedCwd, args.path) : resolvedCwd;
72546
72628
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
72547
72629
  const res = workspace.list({ ...args, cwd: resolvedCwd });
72548
72630
  return { response: { type: "workspace:list", ...res } };
72549
72631
  };
72550
72632
  const read = async (frame, _client, ctx) => {
72551
72633
  const args = WorkspaceReadArgs.parse(frame);
72552
- const target = path86.isAbsolute(args.path) ? path86.resolve(args.path) : path86.resolve(args.cwd, args.path);
72634
+ const target = path87.isAbsolute(args.path) ? path87.resolve(args.path) : path87.resolve(args.cwd, args.path);
72553
72635
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
72554
72636
  const res = workspace.read(args);
72555
72637
  return { response: { type: "workspace:read", ...res } };
72556
72638
  };
72557
72639
  const skillsList = async (frame, _client, ctx) => {
72558
72640
  const args = SkillsListArgs.parse(frame);
72559
- const cwdAbs = path86.resolve(args.cwd);
72641
+ const cwdAbs = path87.resolve(args.cwd);
72560
72642
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
72561
72643
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
72562
72644
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -72568,7 +72650,7 @@ function buildWorkspaceHandlers(deps) {
72568
72650
  };
72569
72651
  const agentsList = async (frame, _client, ctx) => {
72570
72652
  const args = AgentsListArgs.parse(frame);
72571
- const cwdAbs = path86.resolve(args.cwd);
72653
+ const cwdAbs = path87.resolve(args.cwd);
72572
72654
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
72573
72655
  if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
72574
72656
  return { response: { type: "agents:list", agents: [] } };
@@ -72590,20 +72672,20 @@ function buildWorkspaceHandlers(deps) {
72590
72672
  }
72591
72673
 
72592
72674
  // src/handlers/git.ts
72593
- var path88 = __toESM(require("path"), 1);
72675
+ var path89 = __toESM(require("path"), 1);
72594
72676
  init_protocol();
72595
72677
  init_protocol();
72596
72678
 
72597
72679
  // src/workspace/git.ts
72598
72680
  var import_node_child_process21 = require("child_process");
72599
- var import_node_fs63 = __toESM(require("fs"), 1);
72600
- var import_node_path70 = __toESM(require("path"), 1);
72681
+ var import_node_fs64 = __toESM(require("fs"), 1);
72682
+ var import_node_path71 = __toESM(require("path"), 1);
72601
72683
  var import_node_util2 = require("util");
72602
72684
  var pexec = (0, import_node_util2.promisify)(import_node_child_process21.execFile);
72603
72685
  function normalizePath(p3) {
72604
- const resolved = import_node_path70.default.resolve(p3);
72686
+ const resolved = import_node_path71.default.resolve(p3);
72605
72687
  try {
72606
- return import_node_fs63.default.realpathSync(resolved);
72688
+ return import_node_fs64.default.realpathSync(resolved);
72607
72689
  } catch {
72608
72690
  return resolved;
72609
72691
  }
@@ -72677,7 +72759,7 @@ async function listGitBranches(cwd) {
72677
72759
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
72678
72760
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
72679
72761
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72680
- if (!isGuestPathAllowed(ctx.grants, path88.resolve(cwd), personaRoot, "read", userWorkDir)) {
72762
+ if (!isGuestPathAllowed(ctx.grants, path89.resolve(cwd), personaRoot, "read", userWorkDir)) {
72681
72763
  throw new ClawdError(
72682
72764
  ERROR_CODES.UNAUTHORIZED,
72683
72765
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -72934,12 +73016,12 @@ async function queryCodexAccount(deps = {}) {
72934
73016
  }
72935
73017
 
72936
73018
  // src/tools/pi-account.ts
72937
- var import_node_fs64 = __toESM(require("fs"), 1);
72938
- var import_node_path71 = __toESM(require("path"), 1);
73019
+ var import_node_fs65 = __toESM(require("fs"), 1);
73020
+ var import_node_path72 = __toESM(require("path"), 1);
72939
73021
  function readPiCredentials(agentDir) {
72940
73022
  let raw;
72941
73023
  try {
72942
- raw = JSON.parse(import_node_fs64.default.readFileSync(import_node_path71.default.join(agentDir, "auth.json"), "utf8"));
73024
+ raw = JSON.parse(import_node_fs65.default.readFileSync(import_node_path72.default.join(agentDir, "auth.json"), "utf8"));
72943
73025
  } catch {
72944
73026
  return {};
72945
73027
  }
@@ -73023,8 +73105,8 @@ function buildEngineHandlers(deps, overrides = {}) {
73023
73105
  }
73024
73106
 
73025
73107
  // src/handlers/channels.ts
73026
- var import_node_fs65 = __toESM(require("fs"), 1);
73027
- var import_node_path72 = __toESM(require("path"), 1);
73108
+ var import_node_fs66 = __toESM(require("fs"), 1);
73109
+ var import_node_path73 = __toESM(require("path"), 1);
73028
73110
  function buildChannelsHandlers(deps) {
73029
73111
  let queue = Promise.resolve();
73030
73112
  const serialized = (fn) => (frame, context) => {
@@ -73038,8 +73120,8 @@ function buildChannelsHandlers(deps) {
73038
73120
  const codexHome = resolveCodexHome2(deps.codexHome);
73039
73121
  const agentDir = resolvePiAgentDir(deps.agentDir);
73040
73122
  const restoreStore = deps.store.snapshot();
73041
- const restoreCodex = snapshotFile(import_node_path72.default.join(codexHome, "config.toml"));
73042
- const restorePi = import_node_fs65.default.existsSync(agentDir) ? snapshotFile(import_node_path72.default.join(agentDir, PI_SUBSCRIPTION_FILE)) : null;
73123
+ const restoreCodex = snapshotFile(import_node_path73.default.join(codexHome, "config.toml"));
73124
+ const restorePi = import_node_fs66.default.existsSync(agentDir) ? snapshotFile(import_node_path73.default.join(agentDir, PI_SUBSCRIPTION_FILE)) : null;
73043
73125
  let next;
73044
73126
  try {
73045
73127
  next = mutate();
@@ -74001,21 +74083,21 @@ function computeMethodAccess(args) {
74001
74083
  }
74002
74084
 
74003
74085
  // src/version.ts
74004
- var version = "0.2.644".length > 0 ? "0.2.644" : "dev";
74086
+ var version = "0.2.645".length > 0 ? "0.2.645" : "dev";
74005
74087
 
74006
74088
  // src/cli-probe/probe.ts
74007
- var fs84 = __toESM(require("fs"), 1);
74008
- var path91 = __toESM(require("path"), 1);
74089
+ var fs85 = __toESM(require("fs"), 1);
74090
+ var path92 = __toESM(require("path"), 1);
74009
74091
  var PKG_NAME = "@clawos-dev/clawd";
74010
74092
  var BIN_NAME = "clawd";
74011
74093
  var MAX_PARENT_HOPS = 5;
74012
74094
  function probeGlobalCli(pathEnv) {
74013
74095
  if (!pathEnv) return null;
74014
- for (const dir of pathEnv.split(path91.delimiter)) {
74096
+ for (const dir of pathEnv.split(path92.delimiter)) {
74015
74097
  if (!dir) continue;
74016
74098
  let real;
74017
74099
  try {
74018
- real = fs84.realpathSync(path91.join(dir, BIN_NAME));
74100
+ real = fs85.realpathSync(path92.join(dir, BIN_NAME));
74019
74101
  } catch {
74020
74102
  continue;
74021
74103
  }
@@ -74025,15 +74107,15 @@ function probeGlobalCli(pathEnv) {
74025
74107
  return null;
74026
74108
  }
74027
74109
  function readOwnPackageVersion(entryPath) {
74028
- let dir = path91.dirname(entryPath);
74110
+ let dir = path92.dirname(entryPath);
74029
74111
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
74030
74112
  try {
74031
- const raw = fs84.readFileSync(path91.join(dir, "package.json"), "utf8");
74113
+ const raw = fs85.readFileSync(path92.join(dir, "package.json"), "utf8");
74032
74114
  const pkg = JSON.parse(raw);
74033
74115
  if (pkg.name !== PKG_NAME) return null;
74034
74116
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
74035
74117
  } catch {
74036
- const parent = path91.dirname(dir);
74118
+ const parent = path92.dirname(dir);
74037
74119
  if (parent === dir) return null;
74038
74120
  dir = parent;
74039
74121
  }
@@ -74206,7 +74288,7 @@ function buildPersonaHandlers(deps) {
74206
74288
  }
74207
74289
 
74208
74290
  // src/handlers/attachment.ts
74209
- var import_node_path73 = __toESM(require("path"), 1);
74291
+ var import_node_path74 = __toESM(require("path"), 1);
74210
74292
  init_protocol();
74211
74293
  init_protocol();
74212
74294
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -74285,12 +74367,12 @@ function buildAttachmentHandlers(deps) {
74285
74367
  `session ${args.sessionId} scope unresolved`
74286
74368
  );
74287
74369
  }
74288
- const cwdAbs = import_node_path73.default.resolve(sessionFile.cwd);
74289
- const candidateAbs = import_node_path73.default.isAbsolute(args.relPath) ? import_node_path73.default.resolve(args.relPath) : import_node_path73.default.resolve(cwdAbs, args.relPath);
74370
+ const cwdAbs = import_node_path74.default.resolve(sessionFile.cwd);
74371
+ const candidateAbs = import_node_path74.default.isAbsolute(args.relPath) ? import_node_path74.default.resolve(args.relPath) : import_node_path74.default.resolve(cwdAbs, args.relPath);
74290
74372
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
74291
74373
  const entries = deps.groupFileStore.list(scope, args.sessionId);
74292
74374
  const entry = entries.find((e) => {
74293
- const storedAbs = import_node_path73.default.isAbsolute(e.relPath) ? import_node_path73.default.resolve(e.relPath) : import_node_path73.default.resolve(cwdAbs, e.relPath);
74375
+ const storedAbs = import_node_path74.default.isAbsolute(e.relPath) ? import_node_path74.default.resolve(e.relPath) : import_node_path74.default.resolve(cwdAbs, e.relPath);
74294
74376
  return storedAbs === candidateAbs && !e.stale;
74295
74377
  });
74296
74378
  if (!entry) {
@@ -74314,7 +74396,7 @@ function buildAttachmentHandlers(deps) {
74314
74396
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
74315
74397
  const f2 = deps.sessionStore.read(sessionId);
74316
74398
  if (!f2) return;
74317
- assertGuestAttachmentPath(ctx, import_node_path73.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
74399
+ assertGuestAttachmentPath(ctx, import_node_path74.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
74318
74400
  }
74319
74401
  const groupAdd = async (frame, _client, ctx) => {
74320
74402
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -74329,8 +74411,8 @@ function buildAttachmentHandlers(deps) {
74329
74411
  if (!scope) {
74330
74412
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
74331
74413
  }
74332
- const cwdAbs = import_node_path73.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
74333
- const candidateAbs = import_node_path73.default.isAbsolute(args.relPath) ? import_node_path73.default.resolve(args.relPath) : import_node_path73.default.resolve(cwdAbs, args.relPath);
74414
+ const cwdAbs = import_node_path74.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
74415
+ const candidateAbs = import_node_path74.default.isAbsolute(args.relPath) ? import_node_path74.default.resolve(args.relPath) : import_node_path74.default.resolve(cwdAbs, args.relPath);
74334
74416
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
74335
74417
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
74336
74418
  const size = 0;
@@ -74389,19 +74471,19 @@ function buildAttachmentHandlers(deps) {
74389
74471
 
74390
74472
  // src/handlers/extension.ts
74391
74473
  var import_promises15 = __toESM(require("fs/promises"), 1);
74392
- var import_node_path78 = __toESM(require("path"), 1);
74474
+ var import_node_path79 = __toESM(require("path"), 1);
74393
74475
  init_protocol();
74394
74476
 
74395
74477
  // src/extension/bundle-zip.ts
74396
74478
  var import_promises12 = __toESM(require("fs/promises"), 1);
74397
- var import_node_path74 = __toESM(require("path"), 1);
74479
+ var import_node_path75 = __toESM(require("path"), 1);
74398
74480
  var import_node_crypto26 = __toESM(require("crypto"), 1);
74399
74481
  var import_jszip3 = __toESM(require_lib3(), 1);
74400
74482
  async function bundleExtensionDir(dir) {
74401
74483
  const entries = await listFilesSorted(dir);
74402
74484
  const zip = new import_jszip3.default();
74403
74485
  for (const rel of entries) {
74404
- const abs = import_node_path74.default.join(dir, rel);
74486
+ const abs = import_node_path75.default.join(dir, rel);
74405
74487
  const content = await import_promises12.default.readFile(abs);
74406
74488
  zip.file(rel, content, { date: FIXED_DATE });
74407
74489
  }
@@ -74422,7 +74504,7 @@ async function listFilesSorted(rootDir) {
74422
74504
  return out;
74423
74505
  }
74424
74506
  async function walk(absRoot, relPrefix, out) {
74425
- const dirAbs = import_node_path74.default.join(absRoot, relPrefix);
74507
+ const dirAbs = import_node_path75.default.join(absRoot, relPrefix);
74426
74508
  const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
74427
74509
  for (const e of entries) {
74428
74510
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -74476,25 +74558,25 @@ function computePublishCheck(args) {
74476
74558
 
74477
74559
  // src/extension/install-flow.ts
74478
74560
  var import_promises13 = __toESM(require("fs/promises"), 1);
74479
- var import_node_path76 = __toESM(require("path"), 1);
74561
+ var import_node_path77 = __toESM(require("path"), 1);
74480
74562
  var import_node_os28 = __toESM(require("os"), 1);
74481
74563
  var import_node_crypto27 = __toESM(require("crypto"), 1);
74482
74564
  var import_jszip4 = __toESM(require_lib3(), 1);
74483
74565
 
74484
74566
  // src/extension/paths.ts
74485
74567
  var import_node_os27 = __toESM(require("os"), 1);
74486
- var import_node_path75 = __toESM(require("path"), 1);
74568
+ var import_node_path76 = __toESM(require("path"), 1);
74487
74569
  function clawdHomeRoot(override) {
74488
- return override ?? process.env.CLAWD_HOME ?? import_node_path75.default.join(import_node_os27.default.homedir(), ".clawd");
74570
+ return override ?? process.env.CLAWD_HOME ?? import_node_path76.default.join(import_node_os27.default.homedir(), ".clawd");
74489
74571
  }
74490
74572
  function extensionsRoot(override) {
74491
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions");
74573
+ return import_node_path76.default.join(clawdHomeRoot(override), "extensions");
74492
74574
  }
74493
74575
  function publishedChannelsFile(override) {
74494
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions-published.json");
74576
+ return import_node_path76.default.join(clawdHomeRoot(override), "extensions-published.json");
74495
74577
  }
74496
74578
  function bundleCacheRoot(override) {
74497
- return import_node_path75.default.join(clawdHomeRoot(override), "extension-bundles");
74579
+ return import_node_path76.default.join(clawdHomeRoot(override), "extension-bundles");
74498
74580
  }
74499
74581
 
74500
74582
  // src/extension/install-flow.ts
@@ -74521,7 +74603,7 @@ async function installFromChannel(args, deps) {
74521
74603
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74522
74604
  }
74523
74605
  for (const name of Object.keys(zip.files)) {
74524
- if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74606
+ if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74525
74607
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74526
74608
  }
74527
74609
  }
@@ -74553,7 +74635,7 @@ async function installFromChannel(args, deps) {
74553
74635
  );
74554
74636
  }
74555
74637
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
74556
- const destDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74638
+ const destDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74557
74639
  let destExists = false;
74558
74640
  try {
74559
74641
  await import_promises13.default.access(destDir);
@@ -74567,16 +74649,16 @@ async function installFromChannel(args, deps) {
74567
74649
  );
74568
74650
  }
74569
74651
  const stage = await import_promises13.default.mkdtemp(
74570
- import_node_path76.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74652
+ import_node_path77.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74571
74653
  );
74572
74654
  try {
74573
74655
  for (const [name, entry] of Object.entries(zip.files)) {
74574
- const dest = import_node_path76.default.join(stage, name);
74656
+ const dest = import_node_path77.default.join(stage, name);
74575
74657
  if (entry.dir) {
74576
74658
  await import_promises13.default.mkdir(dest, { recursive: true });
74577
74659
  continue;
74578
74660
  }
74579
- await import_promises13.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74661
+ await import_promises13.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
74580
74662
  if (name === "manifest.json") {
74581
74663
  const rewritten = { ...parsed.data, id: localExtId };
74582
74664
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74597,7 +74679,7 @@ async function installFromChannel(args, deps) {
74597
74679
 
74598
74680
  // src/extension/update-flow.ts
74599
74681
  var import_promises14 = __toESM(require("fs/promises"), 1);
74600
- var import_node_path77 = __toESM(require("path"), 1);
74682
+ var import_node_path78 = __toESM(require("path"), 1);
74601
74683
  var import_node_os29 = __toESM(require("os"), 1);
74602
74684
  var import_node_crypto28 = __toESM(require("crypto"), 1);
74603
74685
  var import_jszip5 = __toESM(require_lib3(), 1);
@@ -74614,11 +74696,11 @@ async function updateFromChannel(args, deps) {
74614
74696
  channelRef.extId,
74615
74697
  channelRef.ownerPrincipalId
74616
74698
  );
74617
- const liveDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74699
+ const liveDir = import_node_path78.default.join(deps.extensionsRoot, localExtId);
74618
74700
  const prevDir = `${liveDir}.prev`;
74619
74701
  let existingVersion;
74620
74702
  try {
74621
- const raw = await import_promises14.default.readFile(import_node_path77.default.join(liveDir, "manifest.json"), "utf8");
74703
+ const raw = await import_promises14.default.readFile(import_node_path78.default.join(liveDir, "manifest.json"), "utf8");
74622
74704
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
74623
74705
  if (!parsed2.success) {
74624
74706
  throw new UpdateError(
@@ -74651,7 +74733,7 @@ async function updateFromChannel(args, deps) {
74651
74733
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74652
74734
  }
74653
74735
  for (const name of Object.keys(zip.files)) {
74654
- if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74736
+ if (name.includes("..") || name.startsWith("/") || import_node_path78.default.isAbsolute(name)) {
74655
74737
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74656
74738
  }
74657
74739
  }
@@ -74686,16 +74768,16 @@ async function updateFromChannel(args, deps) {
74686
74768
  await import_promises14.default.rm(prevDir, { recursive: true, force: true });
74687
74769
  await import_promises14.default.rename(liveDir, prevDir);
74688
74770
  const stage = await import_promises14.default.mkdtemp(
74689
- import_node_path77.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74771
+ import_node_path78.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74690
74772
  );
74691
74773
  try {
74692
74774
  for (const [name, entry] of Object.entries(zip.files)) {
74693
- const dest = import_node_path77.default.join(stage, name);
74775
+ const dest = import_node_path78.default.join(stage, name);
74694
74776
  if (entry.dir) {
74695
74777
  await import_promises14.default.mkdir(dest, { recursive: true });
74696
74778
  continue;
74697
74779
  }
74698
- await import_promises14.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
74780
+ await import_promises14.default.mkdir(import_node_path78.default.dirname(dest), { recursive: true });
74699
74781
  if (name === "manifest.json") {
74700
74782
  const rewritten = { ...parsed.data, id: localExtId };
74701
74783
  await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74762,7 +74844,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74762
74844
  );
74763
74845
  }
74764
74846
  }
74765
- const manifestPath = import_node_path78.default.join(root, extId, "manifest.json");
74847
+ const manifestPath = import_node_path79.default.join(root, extId, "manifest.json");
74766
74848
  const manifest = await readManifest(root, extId);
74767
74849
  const next = { ...manifest, version: newVersion };
74768
74850
  const tmp = `${manifestPath}.tmp`;
@@ -74770,7 +74852,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74770
74852
  await import_promises15.default.rename(tmp, manifestPath);
74771
74853
  }
74772
74854
  async function readManifest(root, extId) {
74773
- const file = import_node_path78.default.join(root, extId, "manifest.json");
74855
+ const file = import_node_path79.default.join(root, extId, "manifest.json");
74774
74856
  let raw;
74775
74857
  try {
74776
74858
  raw = await import_promises15.default.readFile(file, "utf8");
@@ -74854,7 +74936,7 @@ function buildExtensionHandlers(deps) {
74854
74936
  };
74855
74937
  async function buildSnapshotMeta(extId) {
74856
74938
  const manifest = await readManifest(deps.root, extId);
74857
- const { sha256, buffer } = await bundleExtensionDir(import_node_path78.default.join(deps.root, extId));
74939
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path79.default.join(deps.root, extId));
74858
74940
  return { manifest, contentHash: sha256, buffer };
74859
74941
  }
74860
74942
  const publish = async (frame, _client, ctx) => {
@@ -75681,7 +75763,7 @@ function buildVisitorHandlers(deps) {
75681
75763
 
75682
75764
  // src/extension/registry.ts
75683
75765
  var import_promises17 = __toESM(require("fs/promises"), 1);
75684
- var import_node_path79 = __toESM(require("path"), 1);
75766
+ var import_node_path80 = __toESM(require("path"), 1);
75685
75767
  async function loadAll(root) {
75686
75768
  let entries;
75687
75769
  try {
@@ -75694,13 +75776,13 @@ async function loadAll(root) {
75694
75776
  for (const ent of entries) {
75695
75777
  if (!ent.isDirectory()) continue;
75696
75778
  if (ent.name.startsWith(".")) continue;
75697
- records.push(await loadOne(import_node_path79.default.join(root, ent.name), ent.name));
75779
+ records.push(await loadOne(import_node_path80.default.join(root, ent.name), ent.name));
75698
75780
  }
75699
75781
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
75700
75782
  return records;
75701
75783
  }
75702
75784
  async function loadOne(dir, dirName) {
75703
- const manifestPath = import_node_path79.default.join(dir, "manifest.json");
75785
+ const manifestPath = import_node_path80.default.join(dir, "manifest.json");
75704
75786
  let raw;
75705
75787
  try {
75706
75788
  raw = await import_promises17.default.readFile(manifestPath, "utf8");
@@ -75745,7 +75827,7 @@ async function loadOne(dir, dirName) {
75745
75827
 
75746
75828
  // src/extension/uninstall.ts
75747
75829
  var import_promises18 = __toESM(require("fs/promises"), 1);
75748
- var import_node_path80 = __toESM(require("path"), 1);
75830
+ var import_node_path81 = __toESM(require("path"), 1);
75749
75831
  var UninstallError = class extends Error {
75750
75832
  constructor(code, message) {
75751
75833
  super(message);
@@ -75754,7 +75836,7 @@ var UninstallError = class extends Error {
75754
75836
  code;
75755
75837
  };
75756
75838
  async function uninstall(deps) {
75757
- const dir = import_node_path80.default.join(deps.root, deps.extId);
75839
+ const dir = import_node_path81.default.join(deps.root, deps.extId);
75758
75840
  try {
75759
75841
  await import_promises18.default.access(dir);
75760
75842
  } catch {
@@ -75970,7 +76052,7 @@ function buildMethodHandlers(deps) {
75970
76052
  broadcast: deps.broadcastToOwners
75971
76053
  }),
75972
76054
  ...buildMasterHandlers({
75973
- authorityTablePath: import_node_path81.default.join(deps.masterDataDir, "master-authority.json")
76055
+ authorityTablePath: import_node_path82.default.join(deps.masterDataDir, "master-authority.json")
75974
76056
  }),
75975
76057
  ...buildTopicHandlers({
75976
76058
  topicStore: deps.topicStore,
@@ -76112,7 +76194,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
76112
76194
 
76113
76195
  // src/extension/runtime.ts
76114
76196
  var import_node_child_process26 = require("child_process");
76115
- var import_node_path82 = __toESM(require("path"), 1);
76197
+ var import_node_path83 = __toESM(require("path"), 1);
76116
76198
  var import_promises19 = require("timers/promises");
76117
76199
 
76118
76200
  // src/extension/port-allocator.ts
@@ -76213,7 +76295,7 @@ var Runtime = class {
76213
76295
  /\$CLAWOS_EXT_PORT/g,
76214
76296
  String(port)
76215
76297
  );
76216
- const dir = import_node_path82.default.join(this.root, extId);
76298
+ const dir = import_node_path83.default.join(this.root, extId);
76217
76299
  const env = {
76218
76300
  ...process.env,
76219
76301
  CLAWOS_EXT_PORT: String(port),
@@ -76325,7 +76407,7 @@ ${handle.stderrTail}`
76325
76407
 
76326
76408
  // src/extension/published-channels.ts
76327
76409
  var import_promises20 = __toESM(require("fs/promises"), 1);
76328
- var import_node_path83 = __toESM(require("path"), 1);
76410
+ var import_node_path84 = __toESM(require("path"), 1);
76329
76411
  init_zod();
76330
76412
  var PublishedChannelsError = class extends Error {
76331
76413
  constructor(code, message) {
@@ -76422,7 +76504,7 @@ var PublishedChannelStore = class {
76422
76504
  )
76423
76505
  };
76424
76506
  const tmp = `${this.filePath}.tmp`;
76425
- await import_promises20.default.mkdir(import_node_path83.default.dirname(this.filePath), { recursive: true });
76507
+ await import_promises20.default.mkdir(import_node_path84.default.dirname(this.filePath), { recursive: true });
76426
76508
  await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
76427
76509
  await import_promises20.default.rename(tmp, this.filePath);
76428
76510
  }
@@ -76430,7 +76512,7 @@ var PublishedChannelStore = class {
76430
76512
 
76431
76513
  // src/extension/bundle-cache.ts
76432
76514
  var import_promises21 = __toESM(require("fs/promises"), 1);
76433
- var import_node_path84 = __toESM(require("path"), 1);
76515
+ var import_node_path85 = __toESM(require("path"), 1);
76434
76516
  var BundleCache = class {
76435
76517
  constructor(rootDir) {
76436
76518
  this.rootDir = rootDir;
@@ -76439,13 +76521,13 @@ var BundleCache = class {
76439
76521
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
76440
76522
  async write(snapshotHash, buffer) {
76441
76523
  await import_promises21.default.mkdir(this.rootDir, { recursive: true });
76442
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
76524
+ const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
76443
76525
  const tmp = `${file}.tmp`;
76444
76526
  await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
76445
76527
  await import_promises21.default.rename(tmp, file);
76446
76528
  }
76447
76529
  async read(snapshotHash) {
76448
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
76530
+ const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
76449
76531
  try {
76450
76532
  return await import_promises21.default.readFile(file);
76451
76533
  } catch (e) {
@@ -76454,7 +76536,7 @@ var BundleCache = class {
76454
76536
  }
76455
76537
  }
76456
76538
  async delete(snapshotHash) {
76457
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
76539
+ const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
76458
76540
  await import_promises21.default.rm(file, { force: true });
76459
76541
  }
76460
76542
  };
@@ -76477,24 +76559,24 @@ async function startDaemon(config) {
76477
76559
  sampling: logShippingCfg.sampling,
76478
76560
  homeDir: import_node_os31.default.homedir()
76479
76561
  });
76480
- const logDir = import_node_path85.default.join(config.dataDir, "log");
76481
- import_node_fs66.default.mkdirSync(logDir, { recursive: true });
76562
+ const logDir = import_node_path86.default.join(config.dataDir, "log");
76563
+ import_node_fs67.default.mkdirSync(logDir, { recursive: true });
76482
76564
  const logger = createLogger({
76483
76565
  level: config.logLevel,
76484
- file: import_node_path85.default.join(logDir, "clawd.log"),
76566
+ file: import_node_path86.default.join(logDir, "clawd.log"),
76485
76567
  logClient
76486
76568
  });
76487
76569
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
76488
76570
  const screenIdleProbeLogger = createFileOnlyLogger({
76489
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log"),
76571
+ file: import_node_path86.default.join(logDir, "screen-idle-probe.log"),
76490
76572
  level: "debug"
76491
76573
  });
76492
76574
  logger.info("screen-idle probe logger enabled", {
76493
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log")
76575
+ file: import_node_path86.default.join(logDir, "screen-idle-probe.log")
76494
76576
  });
76495
76577
  const CAP_TARGETS = [
76496
- import_node_path85.default.join(logDir, "clawd.log"),
76497
- import_node_path85.default.join(logDir, "screen-idle-probe.log")
76578
+ import_node_path86.default.join(logDir, "clawd.log"),
76579
+ import_node_path86.default.join(logDir, "screen-idle-probe.log")
76498
76580
  ];
76499
76581
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
76500
76582
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -76610,11 +76692,11 @@ async function startDaemon(config) {
76610
76692
  const agents = new AgentsScanner();
76611
76693
  const history = new ClaudeHistoryReader();
76612
76694
  let transport = null;
76613
- const personaStore = new PersonaStore(import_node_path85.default.join(config.dataDir, "personas"));
76695
+ const personaStore = new PersonaStore(import_node_path86.default.join(config.dataDir, "personas"));
76614
76696
  const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
76615
76697
  const activeSubscriptionChannel = subscriptionChannelStore.getActive();
76616
76698
  if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
76617
- const usersRoot = import_node_path85.default.join(config.dataDir, "users");
76699
+ const usersRoot = import_node_path86.default.join(config.dataDir, "users");
76618
76700
  const defaultsRoot = findDefaultsRoot(logger);
76619
76701
  if (defaultsRoot) {
76620
76702
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -76631,7 +76713,7 @@ async function startDaemon(config) {
76631
76713
  retirePersonaBuilder({ store: personaStore, logger });
76632
76714
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
76633
76715
  const dispatchStore = createDispatchStore({
76634
- filePath: import_node_path85.default.join(config.dataDir, "dispatch.json"),
76716
+ filePath: import_node_path86.default.join(config.dataDir, "dispatch.json"),
76635
76717
  now: () => Date.now(),
76636
76718
  onFlushError: (err) => logger.error("dispatch store flush failed", {
76637
76719
  reason: err instanceof Error ? err.message : String(err)
@@ -76640,7 +76722,7 @@ async function startDaemon(config) {
76640
76722
  await dispatchStore.load();
76641
76723
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
76642
76724
  const channelStore = createChannelStore({
76643
- filePath: import_node_path85.default.join(config.dataDir, "channels.json"),
76725
+ filePath: import_node_path86.default.join(config.dataDir, "channels.json"),
76644
76726
  now: () => Date.now(),
76645
76727
  genId: () => `ch-${(0, import_node_crypto30.randomUUID)().slice(0, 8)}`,
76646
76728
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -76649,7 +76731,7 @@ async function startDaemon(config) {
76649
76731
  });
76650
76732
  await channelStore.load();
76651
76733
  const topicStore = createTopicStore({
76652
- filePath: import_node_path85.default.join(config.dataDir, "topics.json"),
76734
+ filePath: import_node_path86.default.join(config.dataDir, "topics.json"),
76653
76735
  now: () => Date.now(),
76654
76736
  genId: () => `tp-${(0, import_node_crypto30.randomUUID)().slice(0, 8)}`,
76655
76737
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -76676,12 +76758,12 @@ async function startDaemon(config) {
76676
76758
  });
76677
76759
  }
76678
76760
  });
76679
- const here = typeof __dirname === "string" ? __dirname : import_node_path85.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76761
+ const here = typeof __dirname === "string" ? __dirname : import_node_path86.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76680
76762
  const mcpConfigs = [];
76681
76763
  const secretsBundleRoot = findSecretsBundleRoot(logger);
76682
- const localSecretsDir = import_node_path85.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76764
+ const localSecretsDir = import_node_path86.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76683
76765
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
76684
- const githubTokenFile = import_node_path85.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76766
+ const githubTokenFile = import_node_path86.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76685
76767
  const githubIdentity = createGithubIdentity({
76686
76768
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
76687
76769
  store: (token) => storeGithubAuth({
@@ -76719,20 +76801,20 @@ async function startDaemon(config) {
76719
76801
  void githubIdentity.refresh();
76720
76802
  return renderPersonaMcpSecrets({
76721
76803
  personaId: personaId2,
76722
- personaDir: import_node_path85.default.join(config.dataDir, "personas", personaId2),
76804
+ personaDir: import_node_path86.default.join(config.dataDir, "personas", personaId2),
76723
76805
  secrets,
76724
- outDir: import_node_path85.default.join(config.dataDir, "persona-mcp"),
76806
+ outDir: import_node_path86.default.join(config.dataDir, "persona-mcp"),
76725
76807
  logger
76726
76808
  });
76727
76809
  };
76728
76810
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
76729
76811
  const dispatchServerCandidates = [
76730
- import_node_path85.default.join(here, "dispatch", "mcp-server.cjs"),
76731
- import_node_path85.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76812
+ import_node_path86.default.join(here, "dispatch", "mcp-server.cjs"),
76813
+ import_node_path86.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76732
76814
  ];
76733
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76815
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76734
76816
  if (dispatchServerScriptPath) {
76735
- const dispatchLogPath = import_node_path85.default.join(logDir, "dispatch-mcp-server.log");
76817
+ const dispatchLogPath = import_node_path86.default.join(logDir, "dispatch-mcp-server.log");
76736
76818
  const dispatchCfgPath = writeDispatchMcpConfig({
76737
76819
  dataDir: config.dataDir,
76738
76820
  serverScriptPath: dispatchServerScriptPath,
@@ -76752,12 +76834,12 @@ async function startDaemon(config) {
76752
76834
  });
76753
76835
  }
76754
76836
  const ticketServerCandidates = [
76755
- import_node_path85.default.join(here, "ticket", "mcp-server.cjs"),
76756
- import_node_path85.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
76837
+ import_node_path86.default.join(here, "ticket", "mcp-server.cjs"),
76838
+ import_node_path86.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
76757
76839
  ];
76758
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76840
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76759
76841
  if (ticketServerScriptPath) {
76760
- const ticketLogPath = import_node_path85.default.join(logDir, "ticket-mcp-server.log");
76842
+ const ticketLogPath = import_node_path86.default.join(logDir, "ticket-mcp-server.log");
76761
76843
  const ticketCfgPath = writeTicketMcpConfig({
76762
76844
  dataDir: config.dataDir,
76763
76845
  serverScriptPath: ticketServerScriptPath,
@@ -76779,12 +76861,12 @@ async function startDaemon(config) {
76779
76861
  });
76780
76862
  }
76781
76863
  const shiftServerCandidates = [
76782
- import_node_path85.default.join(here, "shift", "mcp-server.cjs"),
76783
- import_node_path85.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
76864
+ import_node_path86.default.join(here, "shift", "mcp-server.cjs"),
76865
+ import_node_path86.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
76784
76866
  ];
76785
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76867
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76786
76868
  if (shiftServerScriptPath) {
76787
- const shiftLogPath = import_node_path85.default.join(logDir, "shift-mcp-server.log");
76869
+ const shiftLogPath = import_node_path86.default.join(logDir, "shift-mcp-server.log");
76788
76870
  const shiftCfgPath = await writeShiftMcpConfig({
76789
76871
  dataDir: config.dataDir,
76790
76872
  serverScriptPath: shiftServerScriptPath,
@@ -76805,12 +76887,12 @@ async function startDaemon(config) {
76805
76887
  );
76806
76888
  }
76807
76889
  const inboxServerCandidates = [
76808
- import_node_path85.default.join(here, "inbox", "mcp-server.cjs"),
76809
- import_node_path85.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
76890
+ import_node_path86.default.join(here, "inbox", "mcp-server.cjs"),
76891
+ import_node_path86.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
76810
76892
  ];
76811
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76893
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76812
76894
  if (inboxServerScriptPath) {
76813
- const inboxLogPath = import_node_path85.default.join(logDir, "inbox-mcp-server.log");
76895
+ const inboxLogPath = import_node_path86.default.join(logDir, "inbox-mcp-server.log");
76814
76896
  const inboxCfgPath = await writeInboxMcpConfig({
76815
76897
  dataDir: config.dataDir,
76816
76898
  serverScriptPath: inboxServerScriptPath,
@@ -76831,10 +76913,10 @@ async function startDaemon(config) {
76831
76913
  );
76832
76914
  }
76833
76915
  const peerOpsServerCandidates = [
76834
- import_node_path85.default.join(here, "peer-ops", "mcp-server.cjs"),
76835
- import_node_path85.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
76916
+ import_node_path86.default.join(here, "peer-ops", "mcp-server.cjs"),
76917
+ import_node_path86.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
76836
76918
  ];
76837
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76919
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76838
76920
  if (peerOpsServerScriptPath) {
76839
76921
  const peerOpsCfgPath = writePeerOpsMcpConfig({
76840
76922
  dataDir: config.dataDir,
@@ -76854,12 +76936,12 @@ async function startDaemon(config) {
76854
76936
  );
76855
76937
  }
76856
76938
  const rpcToolServerCandidates = [
76857
- import_node_path85.default.join(here, "rpc-tool", "mcp-server.cjs"),
76858
- import_node_path85.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
76939
+ import_node_path86.default.join(here, "rpc-tool", "mcp-server.cjs"),
76940
+ import_node_path86.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
76859
76941
  ];
76860
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76942
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76861
76943
  if (rpcToolServerScriptPath) {
76862
- const rpcToolLogPath = import_node_path85.default.join(logDir, "rpc-tool-mcp-server.log");
76944
+ const rpcToolLogPath = import_node_path86.default.join(logDir, "rpc-tool-mcp-server.log");
76863
76945
  const rpcToolCfgPath = writeRpcToolMcpConfig({
76864
76946
  dataDir: config.dataDir,
76865
76947
  serverScriptPath: rpcToolServerScriptPath,
@@ -76880,7 +76962,7 @@ async function startDaemon(config) {
76880
76962
  );
76881
76963
  }
76882
76964
  const shiftStore = createShiftStore({
76883
- filePath: import_node_path85.default.join(config.dataDir, "shift.json"),
76965
+ filePath: import_node_path86.default.join(config.dataDir, "shift.json"),
76884
76966
  ownerIdProvider: () => ownerPrincipalId,
76885
76967
  now: () => Date.now()
76886
76968
  });
@@ -76897,7 +76979,7 @@ async function startDaemon(config) {
76897
76979
  getAdapter,
76898
76980
  historyReader: history,
76899
76981
  dataDir: config.dataDir,
76900
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76982
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
76901
76983
  // Registry defaults are read only after startup, when the later registry binding is initialized.
76902
76984
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
76903
76985
  usersRoot,
@@ -76938,10 +77020,10 @@ async function startDaemon(config) {
76938
77020
  // File edits update the group manifest without making optional stat/manifest failures fail the engine turn.
76939
77021
  attachmentGroup: {
76940
77022
  onFileEdit: (input) => {
76941
- const absPath = import_node_path85.default.isAbsolute(input.relPath) ? input.relPath : import_node_path85.default.join(input.cwd, input.relPath);
77023
+ const absPath = import_node_path86.default.isAbsolute(input.relPath) ? input.relPath : import_node_path86.default.join(input.cwd, input.relPath);
76942
77024
  let size = 0;
76943
77025
  try {
76944
- size = import_node_fs66.default.statSync(absPath).size;
77026
+ size = import_node_fs67.default.statSync(absPath).size;
76945
77027
  } catch (err) {
76946
77028
  logger.warn("attachment.onFileEdit stat failed", {
76947
77029
  sessionId: input.sessionId,
@@ -76982,9 +77064,9 @@ async function startDaemon(config) {
76982
77064
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
76983
77065
  }
76984
77066
  const projectsStore = new ProjectsStore({
76985
- file: import_node_path85.default.join(config.dataDir, "projects.json"),
77067
+ file: import_node_path86.default.join(config.dataDir, "projects.json"),
76986
77068
  clawdDir: config.dataDir,
76987
- codexStateFile: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
77069
+ codexStateFile: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
76988
77070
  logger
76989
77071
  });
76990
77072
  const observer = new SessionObserver({
@@ -77053,13 +77135,13 @@ async function startDaemon(config) {
77053
77135
  runner?.confirmCloudCancelled();
77054
77136
  });
77055
77137
  registerAdapter("claude", claudeAdapter);
77056
- const codexIsolatedHome = import_node_path85.default.join(config.dataDir, "codex-home");
77138
+ const codexIsolatedHome = import_node_path86.default.join(config.dataDir, "codex-home");
77057
77139
  try {
77058
- import_node_fs66.default.mkdirSync(codexIsolatedHome, { recursive: true });
77140
+ import_node_fs67.default.mkdirSync(codexIsolatedHome, { recursive: true });
77059
77141
  for (const f2 of ["auth.json", "config.toml"]) {
77060
- const link = import_node_path85.default.join(codexIsolatedHome, f2);
77061
- const target = import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", f2);
77062
- if (!import_node_fs66.default.existsSync(link) && import_node_fs66.default.existsSync(target)) import_node_fs66.default.symlinkSync(target, link);
77142
+ const link = import_node_path86.default.join(codexIsolatedHome, f2);
77143
+ const target = import_node_path86.default.join(import_node_os31.default.homedir(), ".codex", f2);
77144
+ if (!import_node_fs67.default.existsSync(link) && import_node_fs67.default.existsSync(target)) import_node_fs67.default.symlinkSync(target, link);
77063
77145
  }
77064
77146
  } catch (err) {
77065
77147
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -77070,16 +77152,16 @@ async function startDaemon(config) {
77070
77152
  logger,
77071
77153
  historyReader: new CodexHistoryReader({
77072
77154
  roots: codexRolloutRoots(config.dataDir),
77073
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
77155
+ sharedHome: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex"),
77074
77156
  logger
77075
77157
  }),
77076
77158
  codexHomeFor: (cwd) => resolveCodexHome({
77077
77159
  cwd,
77078
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
77160
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
77079
77161
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
77080
77162
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
77081
77163
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
77082
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
77164
+ sharedHome: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex"),
77083
77165
  isolatedHome: codexIsolatedHome
77084
77166
  }),
77085
77167
  codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
@@ -77109,10 +77191,10 @@ async function startDaemon(config) {
77109
77191
  );
77110
77192
  registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, clientForEnvironment: gatewayForEnvironment, history: cloudHistorySource, logger }));
77111
77193
  const piMcpBridgeCandidates = [
77112
- import_node_path85.default.join(here, "pi-mcp-bridge", "extension.cjs"),
77113
- import_node_path85.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
77194
+ import_node_path86.default.join(here, "pi-mcp-bridge", "extension.cjs"),
77195
+ import_node_path86.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
77114
77196
  ];
77115
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
77197
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
77116
77198
  if (piMcpBridgePath) {
77117
77199
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
77118
77200
  } else {
@@ -77427,10 +77509,10 @@ async function startDaemon(config) {
77427
77509
  getSignSecret: () => authFile.token,
77428
77510
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
77429
77511
  // Guest attachment paths are guarded against persona and caller work roots.
77430
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
77512
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
77431
77513
  usersRoot
77432
77514
  },
77433
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
77515
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
77434
77516
  usersRoot,
77435
77517
  getOwnerIdentity,
77436
77518
  ownerPrincipalId,
@@ -77717,7 +77799,7 @@ async function startDaemon(config) {
77717
77799
  });
77718
77800
  shiftScheduler.start();
77719
77801
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
77720
- const larkBotStore = createLarkBotBindingStore(import_node_path85.default.join(config.dataDir, "personas"));
77802
+ const larkBotStore = createLarkBotBindingStore(import_node_path86.default.join(config.dataDir, "personas"));
77721
77803
  const larkBotCloud = createLarkBotCloudClient({
77722
77804
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
77723
77805
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -77728,7 +77810,7 @@ async function startDaemon(config) {
77728
77810
  cloud: larkBotCloud,
77729
77811
  store: larkBotStore,
77730
77812
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
77731
- mediaRootFor: (chatId) => import_node_path85.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
77813
+ mediaRootFor: (chatId) => import_node_path86.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
77732
77814
  isShuttingDown: () => larkDraining,
77733
77815
  logger: {
77734
77816
  warn: (msg) => logger.warn(msg),
@@ -78027,8 +78109,8 @@ async function startDaemon(config) {
78027
78109
  const lines = [
78028
78110
  `Tunnel: ${r2.url}`,
78029
78111
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
78030
- `Frpc config: ${import_node_path85.default.join(config.dataDir, "frpc.toml")}`,
78031
- `Frpc log: ${import_node_path85.default.join(logDir, "frpc.log")}`
78112
+ `Frpc config: ${import_node_path86.default.join(config.dataDir, "frpc.toml")}`,
78113
+ `Frpc log: ${import_node_path86.default.join(logDir, "frpc.log")}`
78032
78114
  ];
78033
78115
  const width2 = Math.max(...lines.map((l2) => l2.length));
78034
78116
  const bar = "\u2550".repeat(width2 + 4);
@@ -78041,8 +78123,8 @@ ${bar}
78041
78123
 
78042
78124
  `);
78043
78125
  try {
78044
- const connectPath = import_node_path85.default.join(config.dataDir, "connect.txt");
78045
- import_node_fs66.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
78126
+ const connectPath = import_node_path86.default.join(config.dataDir, "connect.txt");
78127
+ import_node_fs67.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
78046
78128
  } catch {
78047
78129
  }
78048
78130
  } catch (err) {
@@ -78140,9 +78222,9 @@ ${bar}
78140
78222
  };
78141
78223
  }
78142
78224
  function migrateDropPersonsDir(dataDir) {
78143
- const dir = import_node_path85.default.join(dataDir, "persons");
78225
+ const dir = import_node_path86.default.join(dataDir, "persons");
78144
78226
  try {
78145
- import_node_fs66.default.rmSync(dir, { recursive: true, force: true });
78227
+ import_node_fs67.default.rmSync(dir, { recursive: true, force: true });
78146
78228
  } catch {
78147
78229
  }
78148
78230
  }