@clawos-dev/clawd 0.2.644 → 0.2.646

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() {
@@ -6013,9 +6013,15 @@ var init_github_auth_schemas = __esm({
6013
6013
  });
6014
6014
 
6015
6015
  // ../protocol/src/environment-schemas.ts
6016
+ function isFeishuBotConnector(c2) {
6017
+ return c2.name === "feishu" && c2.runner === "cli" && c2.kind === "env" && c2.credentialSource === "shared";
6018
+ }
6016
6019
  function connectorBlockers(c2) {
6017
6020
  if (!c2.credentialSource) return [`\u8FDE\u63A5\u5668 ${c2.name} \u8FD8\u6CA1\u9009\u7528\u8C01\u7684\u8D26\u53F7`];
6018
6021
  const out = [];
6022
+ if (isFeishuBotConnector(c2)) {
6023
+ return FEISHU_BOT_FIELDS.filter((f2) => !c2.fields.includes(f2)).map((f2) => `\u8FDE\u63A5\u5668 feishu \u7684 Lark App Bot \u7F3A\u5C11 ${f2 === "LARKSUITE_CLI_APP_ID" ? "App ID" : "App Secret"}`);
6024
+ }
6019
6025
  if (c2.credentialSource === "personal") {
6020
6026
  if (!c2.auth) out.push(`\u8FDE\u63A5\u5668 ${c2.name} \u8FD8\u6CA1\u9009\u7528\u6237\u600E\u4E48\u5173\u8054\u8D26\u53F7`);
6021
6027
  else if (c2.auth === "oauth" && c2.kind === "env") out.push(`\u8FDE\u63A5\u5668 ${c2.name} \u662F\u8FDB\u7A0B\u578B\uFF08stdio MCP / CLI\uFF09\uFF0C\u53EA\u80FD\u7C98\u8D34 API key\uFF0C\u8D70\u4E0D\u4E86 OAuth`);
@@ -6037,7 +6043,7 @@ function sharedConnectorSecrets(m3) {
6037
6043
  function requiredSecretEnvNames(m3) {
6038
6044
  return [.../* @__PURE__ */ new Set([...m3.secrets.flatMap((s2) => s2.env), ...sharedConnectorSecrets(m3).flatMap((s2) => s2.env)])];
6039
6045
  }
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;
6046
+ 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, FEISHU_BOT_FIELDS, normalizeLegacyManifest, PUBLISHER_TEST_NOTE_PREFIX, PublisherTestSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
6041
6047
  var init_environment_schemas = __esm({
6042
6048
  "../protocol/src/environment-schemas.ts"() {
6043
6049
  "use strict";
@@ -6128,6 +6134,7 @@ var init_environment_schemas = __esm({
6128
6134
  fields: external_exports.array(ConnectorFieldSchema).default([]),
6129
6135
  http: external_exports.object({ url: external_exports.string().min(1), headers: external_exports.record(external_exports.string(), external_exports.string()) }).optional()
6130
6136
  });
6137
+ FEISHU_BOT_FIELDS = ["LARKSUITE_CLI_APP_ID", "LARKSUITE_CLI_APP_SECRET"];
6131
6138
  normalizeLegacyManifest = (v3) => {
6132
6139
  if (!v3 || typeof v3 !== "object") return v3;
6133
6140
  let o2 = v3;
@@ -6141,7 +6148,15 @@ var init_environment_schemas = __esm({
6141
6148
  }
6142
6149
  return o2;
6143
6150
  };
6151
+ PUBLISHER_TEST_NOTE_PREFIX = "Publisher test: ";
6152
+ PublisherTestSchema = external_exports.object({
6153
+ version: external_exports.literal(1),
6154
+ entry: external_exports.string().max(240).regex(/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*\.mjs$/).refine((value) => !value.split("/").some((segment) => [".", ".."].includes(segment))),
6155
+ timeoutSeconds: external_exports.number().int().min(1).max(600),
6156
+ 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)
6157
+ }).strict();
6144
6158
  MANIFEST_BODY = {
6159
+ test: PublisherTestSchema.optional(),
6145
6160
  packages: external_exports.array(EnvPackageSchema),
6146
6161
  secrets: external_exports.array(EnvSecretSchema),
6147
6162
  /**
@@ -6176,11 +6191,12 @@ var init_environment_schemas = __esm({
6176
6191
  });
6177
6192
 
6178
6193
  // ../protocol/src/release-schemas.ts
6179
- var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, VerificationSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
6194
+ var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, PublisherTestReceiptSchema, VerificationSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
6180
6195
  var init_release_schemas = __esm({
6181
6196
  "../protocol/src/release-schemas.ts"() {
6182
6197
  "use strict";
6183
6198
  init_zod();
6199
+ init_environment_schemas();
6184
6200
  DEPLOY_ENVIRONMENTS = ["integration", "production"];
6185
6201
  DeployEnvironmentSchema = external_exports.enum(DEPLOY_ENVIRONMENTS);
6186
6202
  ImageDigestSchema = external_exports.string().regex(/^[a-z0-9.-]+(?::[0-9]+)?\/[a-z0-9._/-]+@sha256:[a-f0-9]{64}$/);
@@ -6193,12 +6209,25 @@ var init_release_schemas = __esm({
6193
6209
  return false;
6194
6210
  }
6195
6211
  }, "\u6D4B\u8BD5\u9A8C\u8BC1\u5730\u5740\u5FC5\u987B\u660E\u786E\u6307\u5411 int HTTPS \u73AF\u5883");
6212
+ PublisherTestReceiptSchema = external_exports.object({
6213
+ version: external_exports.literal(1),
6214
+ runId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
6215
+ status: external_exports.literal("passed"),
6216
+ exitCode: external_exports.literal(0),
6217
+ result: external_exports.object({
6218
+ version: external_exports.literal(1),
6219
+ runId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
6220
+ 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)
6221
+ }).strict(),
6222
+ 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()
6223
+ }).strict();
6196
6224
  VerificationSchema = external_exports.object({
6197
6225
  status: external_exports.literal("passed"),
6198
6226
  fingerprint: external_exports.string().regex(/^[a-f0-9]{64}$/),
6199
6227
  checks: external_exports.array(external_exports.string().regex(/^[a-z0-9-]+$/)),
6200
6228
  endpoint: IntegrationEndpointSchema,
6201
- verifiedAt: external_exports.string().refine((s2) => Number.isFinite(Date.parse(s2)))
6229
+ verifiedAt: external_exports.string().refine((s2) => Number.isFinite(Date.parse(s2))),
6230
+ test: PublisherTestReceiptSchema.optional()
6202
6231
  }).strict();
6203
6232
  VerifiedPersonaReleaseSchema = external_exports.object({
6204
6233
  version: external_exports.literal(1),
@@ -6209,8 +6238,13 @@ var init_release_schemas = __esm({
6209
6238
  baseImage: ImageDigestSchema,
6210
6239
  pipelineCommit: SourceCommitSchema,
6211
6240
  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();
6241
+ verification: VerificationSchema.refine((v3) => v3.checks.includes("persona-smoke")),
6242
+ test: PublisherTestSchema.optional()
6243
+ }).strict().refine((record4) => {
6244
+ if (!record4.test) return record4.verification.test === void 0;
6245
+ const receipt = record4.verification.test;
6246
+ 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));
6247
+ }, "Declared publisher acceptance requires complete candidate runtime evidence");
6214
6248
  VerifiedBaseReleaseSchema = external_exports.object({
6215
6249
  version: external_exports.literal(1),
6216
6250
  environment: external_exports.literal("integration"),
@@ -10053,8 +10087,8 @@ var require_req = __commonJS({
10053
10087
  if (req.originalUrl) {
10054
10088
  _req.url = req.originalUrl;
10055
10089
  } else {
10056
- const path107 = req.path;
10057
- _req.url = typeof path107 === "string" ? path107 : req.url ? req.url.path || req.url : void 0;
10090
+ const path108 = req.path;
10091
+ _req.url = typeof path108 === "string" ? path108 : req.url ? req.url.path || req.url : void 0;
10058
10092
  }
10059
10093
  if (req.query) {
10060
10094
  _req.query = req.query;
@@ -10219,14 +10253,14 @@ var require_redact = __commonJS({
10219
10253
  }
10220
10254
  return obj;
10221
10255
  }
10222
- function parsePath(path107) {
10256
+ function parsePath(path108) {
10223
10257
  const parts = [];
10224
10258
  let current = "";
10225
10259
  let inBrackets = false;
10226
10260
  let inQuotes = false;
10227
10261
  let quoteChar = "";
10228
- for (let i2 = 0; i2 < path107.length; i2++) {
10229
- const char = path107[i2];
10262
+ for (let i2 = 0; i2 < path108.length; i2++) {
10263
+ const char = path108[i2];
10230
10264
  if (!inBrackets && char === ".") {
10231
10265
  if (current) {
10232
10266
  parts.push(current);
@@ -10357,10 +10391,10 @@ var require_redact = __commonJS({
10357
10391
  return current;
10358
10392
  }
10359
10393
  function redactPaths(obj, paths, censor, remove = false) {
10360
- for (const path107 of paths) {
10361
- const parts = parsePath(path107);
10394
+ for (const path108 of paths) {
10395
+ const parts = parsePath(path108);
10362
10396
  if (parts.includes("*")) {
10363
- redactWildcardPath(obj, parts, censor, path107, remove);
10397
+ redactWildcardPath(obj, parts, censor, path108, remove);
10364
10398
  } else {
10365
10399
  if (remove) {
10366
10400
  removeKey(obj, parts);
@@ -10445,8 +10479,8 @@ var require_redact = __commonJS({
10445
10479
  }
10446
10480
  } else {
10447
10481
  if (afterWildcard.includes("*")) {
10448
- const wrappedCensor = typeof censor === "function" ? (value, path107) => {
10449
- const fullPath = [...pathArray.slice(0, pathLength), ...path107];
10482
+ const wrappedCensor = typeof censor === "function" ? (value, path108) => {
10483
+ const fullPath = [...pathArray.slice(0, pathLength), ...path108];
10450
10484
  return censor(value, fullPath);
10451
10485
  } : censor;
10452
10486
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10481,8 +10515,8 @@ var require_redact = __commonJS({
10481
10515
  return null;
10482
10516
  }
10483
10517
  const pathStructure = /* @__PURE__ */ new Map();
10484
- for (const path107 of pathsToClone) {
10485
- const parts = parsePath(path107);
10518
+ for (const path108 of pathsToClone) {
10519
+ const parts = parsePath(path108);
10486
10520
  let current = pathStructure;
10487
10521
  for (let i2 = 0; i2 < parts.length; i2++) {
10488
10522
  const part = parts[i2];
@@ -10534,24 +10568,24 @@ var require_redact = __commonJS({
10534
10568
  }
10535
10569
  return cloneSelectively(obj, pathStructure);
10536
10570
  }
10537
- function validatePath(path107) {
10538
- if (typeof path107 !== "string") {
10571
+ function validatePath(path108) {
10572
+ if (typeof path108 !== "string") {
10539
10573
  throw new Error("Paths must be (non-empty) strings");
10540
10574
  }
10541
- if (path107 === "") {
10575
+ if (path108 === "") {
10542
10576
  throw new Error("Invalid redaction path ()");
10543
10577
  }
10544
- if (path107.includes("..")) {
10545
- throw new Error(`Invalid redaction path (${path107})`);
10578
+ if (path108.includes("..")) {
10579
+ throw new Error(`Invalid redaction path (${path108})`);
10546
10580
  }
10547
- if (path107.includes(",")) {
10548
- throw new Error(`Invalid redaction path (${path107})`);
10581
+ if (path108.includes(",")) {
10582
+ throw new Error(`Invalid redaction path (${path108})`);
10549
10583
  }
10550
10584
  let bracketCount = 0;
10551
10585
  let inQuotes = false;
10552
10586
  let quoteChar = "";
10553
- for (let i2 = 0; i2 < path107.length; i2++) {
10554
- const char = path107[i2];
10587
+ for (let i2 = 0; i2 < path108.length; i2++) {
10588
+ const char = path108[i2];
10555
10589
  if ((char === '"' || char === "'") && bracketCount > 0) {
10556
10590
  if (!inQuotes) {
10557
10591
  inQuotes = true;
@@ -10565,20 +10599,20 @@ var require_redact = __commonJS({
10565
10599
  } else if (char === "]" && !inQuotes) {
10566
10600
  bracketCount--;
10567
10601
  if (bracketCount < 0) {
10568
- throw new Error(`Invalid redaction path (${path107})`);
10602
+ throw new Error(`Invalid redaction path (${path108})`);
10569
10603
  }
10570
10604
  }
10571
10605
  }
10572
10606
  if (bracketCount !== 0) {
10573
- throw new Error(`Invalid redaction path (${path107})`);
10607
+ throw new Error(`Invalid redaction path (${path108})`);
10574
10608
  }
10575
10609
  }
10576
10610
  function validatePaths(paths) {
10577
10611
  if (!Array.isArray(paths)) {
10578
10612
  throw new TypeError("paths must be an array");
10579
10613
  }
10580
- for (const path107 of paths) {
10581
- validatePath(path107);
10614
+ for (const path108 of paths) {
10615
+ validatePath(path108);
10582
10616
  }
10583
10617
  }
10584
10618
  function slowRedact(options = {}) {
@@ -10746,8 +10780,8 @@ var require_redaction = __commonJS({
10746
10780
  if (shape[k3] === null) {
10747
10781
  o2[k3] = (value) => topCensor(value, [k3]);
10748
10782
  } else {
10749
- const wrappedCensor = typeof censor === "function" ? (value, path107) => {
10750
- return censor(value, [k3, ...path107]);
10783
+ const wrappedCensor = typeof censor === "function" ? (value, path108) => {
10784
+ return censor(value, [k3, ...path108]);
10751
10785
  } : censor;
10752
10786
  o2[k3] = Redact({
10753
10787
  paths: shape[k3],
@@ -10965,10 +10999,10 @@ var require_atomic_sleep = __commonJS({
10965
10999
  var require_sonic_boom = __commonJS({
10966
11000
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
10967
11001
  "use strict";
10968
- var fs96 = require("fs");
11002
+ var fs97 = require("fs");
10969
11003
  var EventEmitter2 = require("events");
10970
11004
  var inherits = require("util").inherits;
10971
- var path107 = require("path");
11005
+ var path108 = require("path");
10972
11006
  var sleep2 = require_atomic_sleep();
10973
11007
  var assert = require("assert");
10974
11008
  var BUSY_WRITE_TIMEOUT = 100;
@@ -11022,20 +11056,20 @@ var require_sonic_boom = __commonJS({
11022
11056
  const mode = sonic.mode;
11023
11057
  if (sonic.sync) {
11024
11058
  try {
11025
- if (sonic.mkdir) fs96.mkdirSync(path107.dirname(file), { recursive: true });
11026
- const fd = fs96.openSync(file, flags, mode);
11059
+ if (sonic.mkdir) fs97.mkdirSync(path108.dirname(file), { recursive: true });
11060
+ const fd = fs97.openSync(file, flags, mode);
11027
11061
  fileOpened(null, fd);
11028
11062
  } catch (err) {
11029
11063
  fileOpened(err);
11030
11064
  throw err;
11031
11065
  }
11032
11066
  } else if (sonic.mkdir) {
11033
- fs96.mkdir(path107.dirname(file), { recursive: true }, (err) => {
11067
+ fs97.mkdir(path108.dirname(file), { recursive: true }, (err) => {
11034
11068
  if (err) return fileOpened(err);
11035
- fs96.open(file, flags, mode, fileOpened);
11069
+ fs97.open(file, flags, mode, fileOpened);
11036
11070
  });
11037
11071
  } else {
11038
- fs96.open(file, flags, mode, fileOpened);
11072
+ fs97.open(file, flags, mode, fileOpened);
11039
11073
  }
11040
11074
  }
11041
11075
  function SonicBoom(opts) {
@@ -11076,8 +11110,8 @@ var require_sonic_boom = __commonJS({
11076
11110
  this.flush = flushBuffer;
11077
11111
  this.flushSync = flushBufferSync;
11078
11112
  this._actualWrite = actualWriteBuffer;
11079
- fsWriteSync = () => fs96.writeSync(this.fd, this._writingBuf);
11080
- fsWrite = () => fs96.write(this.fd, this._writingBuf, this.release);
11113
+ fsWriteSync = () => fs97.writeSync(this.fd, this._writingBuf);
11114
+ fsWrite = () => fs97.write(this.fd, this._writingBuf, this.release);
11081
11115
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
11082
11116
  this._writingBuf = "";
11083
11117
  this.write = write;
@@ -11086,15 +11120,15 @@ var require_sonic_boom = __commonJS({
11086
11120
  this._actualWrite = actualWrite;
11087
11121
  fsWriteSync = () => {
11088
11122
  if (Buffer.isBuffer(this._writingBuf)) {
11089
- return fs96.writeSync(this.fd, this._writingBuf);
11123
+ return fs97.writeSync(this.fd, this._writingBuf);
11090
11124
  }
11091
- return fs96.writeSync(this.fd, this._writingBuf, "utf8");
11125
+ return fs97.writeSync(this.fd, this._writingBuf, "utf8");
11092
11126
  };
11093
11127
  fsWrite = () => {
11094
11128
  if (Buffer.isBuffer(this._writingBuf)) {
11095
- return fs96.write(this.fd, this._writingBuf, this.release);
11129
+ return fs97.write(this.fd, this._writingBuf, this.release);
11096
11130
  }
11097
- return fs96.write(this.fd, this._writingBuf, "utf8", this.release);
11131
+ return fs97.write(this.fd, this._writingBuf, "utf8", this.release);
11098
11132
  };
11099
11133
  } else {
11100
11134
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11151,7 +11185,7 @@ var require_sonic_boom = __commonJS({
11151
11185
  }
11152
11186
  }
11153
11187
  if (this._fsync) {
11154
- fs96.fsyncSync(this.fd);
11188
+ fs97.fsyncSync(this.fd);
11155
11189
  }
11156
11190
  const len = this._len;
11157
11191
  if (this._reopening) {
@@ -11265,7 +11299,7 @@ var require_sonic_boom = __commonJS({
11265
11299
  const onDrain = () => {
11266
11300
  if (!this._fsync) {
11267
11301
  try {
11268
- fs96.fsync(this.fd, (err) => {
11302
+ fs97.fsync(this.fd, (err) => {
11269
11303
  this._flushPending = false;
11270
11304
  cb(err);
11271
11305
  });
@@ -11367,7 +11401,7 @@ var require_sonic_boom = __commonJS({
11367
11401
  const fd = this.fd;
11368
11402
  this.once("ready", () => {
11369
11403
  if (fd !== this.fd) {
11370
- fs96.close(fd, (err) => {
11404
+ fs97.close(fd, (err) => {
11371
11405
  if (err) {
11372
11406
  return this.emit("error", err);
11373
11407
  }
@@ -11416,7 +11450,7 @@ var require_sonic_boom = __commonJS({
11416
11450
  buf = this._bufs[0];
11417
11451
  }
11418
11452
  try {
11419
- const n2 = Buffer.isBuffer(buf) ? fs96.writeSync(this.fd, buf) : fs96.writeSync(this.fd, buf, "utf8");
11453
+ const n2 = Buffer.isBuffer(buf) ? fs97.writeSync(this.fd, buf) : fs97.writeSync(this.fd, buf, "utf8");
11420
11454
  const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
11421
11455
  buf = releasedBufObj.writingBuf;
11422
11456
  this._len = releasedBufObj.len;
@@ -11432,7 +11466,7 @@ var require_sonic_boom = __commonJS({
11432
11466
  }
11433
11467
  }
11434
11468
  try {
11435
- fs96.fsyncSync(this.fd);
11469
+ fs97.fsyncSync(this.fd);
11436
11470
  } catch {
11437
11471
  }
11438
11472
  }
@@ -11453,7 +11487,7 @@ var require_sonic_boom = __commonJS({
11453
11487
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11454
11488
  }
11455
11489
  try {
11456
- const n2 = fs96.writeSync(this.fd, buf);
11490
+ const n2 = fs97.writeSync(this.fd, buf);
11457
11491
  buf = buf.subarray(n2);
11458
11492
  this._len = Math.max(this._len - n2, 0);
11459
11493
  if (buf.length <= 0) {
@@ -11481,13 +11515,13 @@ var require_sonic_boom = __commonJS({
11481
11515
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11482
11516
  if (this.sync) {
11483
11517
  try {
11484
- const written = Buffer.isBuffer(this._writingBuf) ? fs96.writeSync(this.fd, this._writingBuf) : fs96.writeSync(this.fd, this._writingBuf, "utf8");
11518
+ const written = Buffer.isBuffer(this._writingBuf) ? fs97.writeSync(this.fd, this._writingBuf) : fs97.writeSync(this.fd, this._writingBuf, "utf8");
11485
11519
  release2(null, written);
11486
11520
  } catch (err) {
11487
11521
  release2(err);
11488
11522
  }
11489
11523
  } else {
11490
- fs96.write(this.fd, this._writingBuf, release2);
11524
+ fs97.write(this.fd, this._writingBuf, release2);
11491
11525
  }
11492
11526
  }
11493
11527
  function actualWriteBuffer() {
@@ -11496,7 +11530,7 @@ var require_sonic_boom = __commonJS({
11496
11530
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11497
11531
  if (this.sync) {
11498
11532
  try {
11499
- const written = fs96.writeSync(this.fd, this._writingBuf);
11533
+ const written = fs97.writeSync(this.fd, this._writingBuf);
11500
11534
  release2(null, written);
11501
11535
  } catch (err) {
11502
11536
  release2(err);
@@ -11505,7 +11539,7 @@ var require_sonic_boom = __commonJS({
11505
11539
  if (kCopyBuffer) {
11506
11540
  this._writingBuf = Buffer.from(this._writingBuf);
11507
11541
  }
11508
- fs96.write(this.fd, this._writingBuf, release2);
11542
+ fs97.write(this.fd, this._writingBuf, release2);
11509
11543
  }
11510
11544
  }
11511
11545
  function actualClose(sonic) {
@@ -11521,12 +11555,12 @@ var require_sonic_boom = __commonJS({
11521
11555
  sonic._lens = [];
11522
11556
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11523
11557
  try {
11524
- fs96.fsync(sonic.fd, closeWrapped);
11558
+ fs97.fsync(sonic.fd, closeWrapped);
11525
11559
  } catch {
11526
11560
  }
11527
11561
  function closeWrapped() {
11528
11562
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11529
- fs96.close(sonic.fd, done);
11563
+ fs97.close(sonic.fd, done);
11530
11564
  } else {
11531
11565
  done();
11532
11566
  }
@@ -14661,11 +14695,11 @@ var init_lib = __esm({
14661
14695
  }
14662
14696
  }
14663
14697
  },
14664
- addToPath: function addToPath(path107, added, removed, oldPosInc, options) {
14665
- var last = path107.lastComponent;
14698
+ addToPath: function addToPath(path108, added, removed, oldPosInc, options) {
14699
+ var last = path108.lastComponent;
14666
14700
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14667
14701
  return {
14668
- oldPos: path107.oldPos + oldPosInc,
14702
+ oldPos: path108.oldPos + oldPosInc,
14669
14703
  lastComponent: {
14670
14704
  count: last.count + 1,
14671
14705
  added,
@@ -14675,7 +14709,7 @@ var init_lib = __esm({
14675
14709
  };
14676
14710
  } else {
14677
14711
  return {
14678
- oldPos: path107.oldPos + oldPosInc,
14712
+ oldPos: path108.oldPos + oldPosInc,
14679
14713
  lastComponent: {
14680
14714
  count: 1,
14681
14715
  added,
@@ -15257,10 +15291,10 @@ function attachmentToHistoryMessage(o2, ts) {
15257
15291
  const memories = raw.map((m3) => {
15258
15292
  if (!m3 || typeof m3 !== "object") return null;
15259
15293
  const rec6 = m3;
15260
- const path107 = typeof rec6.path === "string" ? rec6.path : null;
15294
+ const path108 = typeof rec6.path === "string" ? rec6.path : null;
15261
15295
  const content = typeof rec6.content === "string" ? rec6.content : null;
15262
- if (!path107 || content == null) return null;
15263
- const entry = { path: path107, content };
15296
+ if (!path108 || content == null) return null;
15297
+ const entry = { path: path108, content };
15264
15298
  if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
15265
15299
  return entry;
15266
15300
  }).filter((m3) => m3 !== null);
@@ -16110,10 +16144,10 @@ function parseAttachment(obj) {
16110
16144
  const memories = raw.map((m3) => {
16111
16145
  if (!m3 || typeof m3 !== "object") return null;
16112
16146
  const rec6 = m3;
16113
- const path107 = typeof rec6.path === "string" ? rec6.path : null;
16147
+ const path108 = typeof rec6.path === "string" ? rec6.path : null;
16114
16148
  const content = typeof rec6.content === "string" ? rec6.content : null;
16115
- if (!path107 || content == null) return null;
16116
- const out = { path: path107, content };
16149
+ if (!path108 || content == null) return null;
16150
+ const out = { path: path108, content };
16117
16151
  if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
16118
16152
  return out;
16119
16153
  }).filter((m3) => m3 !== null);
@@ -33468,8 +33502,8 @@ var require_utils = __commonJS({
33468
33502
  var result = transform[inputType][outputType](input);
33469
33503
  return result;
33470
33504
  };
33471
- exports2.resolve = function(path107) {
33472
- var parts = path107.split("/");
33505
+ exports2.resolve = function(path108) {
33506
+ var parts = path108.split("/");
33473
33507
  var result = [];
33474
33508
  for (var index = 0; index < parts.length; index++) {
33475
33509
  var part = parts[index];
@@ -39322,18 +39356,18 @@ var require_object = __commonJS({
39322
39356
  var object = new ZipObject(name, zipObjectContent, o2);
39323
39357
  this.files[name] = object;
39324
39358
  };
39325
- var parentFolder = function(path107) {
39326
- if (path107.slice(-1) === "/") {
39327
- path107 = path107.substring(0, path107.length - 1);
39359
+ var parentFolder = function(path108) {
39360
+ if (path108.slice(-1) === "/") {
39361
+ path108 = path108.substring(0, path108.length - 1);
39328
39362
  }
39329
- var lastSlash = path107.lastIndexOf("/");
39330
- return lastSlash > 0 ? path107.substring(0, lastSlash) : "";
39363
+ var lastSlash = path108.lastIndexOf("/");
39364
+ return lastSlash > 0 ? path108.substring(0, lastSlash) : "";
39331
39365
  };
39332
- var forceTrailingSlash = function(path107) {
39333
- if (path107.slice(-1) !== "/") {
39334
- path107 += "/";
39366
+ var forceTrailingSlash = function(path108) {
39367
+ if (path108.slice(-1) !== "/") {
39368
+ path108 += "/";
39335
39369
  }
39336
- return path107;
39370
+ return path108;
39337
39371
  };
39338
39372
  var folderAdd = function(name, createFolders) {
39339
39373
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -43951,7 +43985,7 @@ var require_websocket_server = __commonJS({
43951
43985
  // src/run-case/recorder.ts
43952
43986
  function startRunCaseRecorder(opts) {
43953
43987
  const now = opts.now ?? Date.now;
43954
- const dir = import_node_path86.default.dirname(opts.recordPath);
43988
+ const dir = import_node_path87.default.dirname(opts.recordPath);
43955
43989
  let stream = null;
43956
43990
  let closing = false;
43957
43991
  let closedSettled = false;
@@ -43965,8 +43999,8 @@ function startRunCaseRecorder(opts) {
43965
43999
  });
43966
44000
  const ensureStream = () => {
43967
44001
  if (stream) return stream;
43968
- import_node_fs67.default.mkdirSync(dir, { recursive: true });
43969
- stream = import_node_fs67.default.createWriteStream(opts.recordPath, { flags: "a" });
44002
+ import_node_fs68.default.mkdirSync(dir, { recursive: true });
44003
+ stream = import_node_fs68.default.createWriteStream(opts.recordPath, { flags: "a" });
43970
44004
  stream.on("close", () => closedResolve());
43971
44005
  return stream;
43972
44006
  };
@@ -43991,12 +44025,12 @@ function startRunCaseRecorder(opts) {
43991
44025
  };
43992
44026
  return { tap, close, closed };
43993
44027
  }
43994
- var import_node_fs67, import_node_path86;
44028
+ var import_node_fs68, import_node_path87;
43995
44029
  var init_recorder = __esm({
43996
44030
  "src/run-case/recorder.ts"() {
43997
44031
  "use strict";
43998
- import_node_fs67 = __toESM(require("fs"), 1);
43999
- import_node_path86 = __toESM(require("path"), 1);
44032
+ import_node_fs68 = __toESM(require("fs"), 1);
44033
+ import_node_path87 = __toESM(require("path"), 1);
44000
44034
  }
44001
44035
  });
44002
44036
 
@@ -44039,7 +44073,7 @@ var init_wire = __esm({
44039
44073
  // src/run-case/controller.ts
44040
44074
  async function runController(opts) {
44041
44075
  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-"));
44076
+ const cwd = opts.cwd ?? (0, import_node_fs69.mkdtempSync)(import_node_path88.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
44043
44077
  const ownsCwd = opts.cwd === void 0;
44044
44078
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
44045
44079
  const spawnCtx = { cwd };
@@ -44200,19 +44234,19 @@ async function runController(opts) {
44200
44234
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44201
44235
  if (ownsCwd) {
44202
44236
  try {
44203
- (0, import_node_fs68.rmSync)(cwd, { recursive: true, force: true });
44237
+ (0, import_node_fs69.rmSync)(cwd, { recursive: true, force: true });
44204
44238
  } catch {
44205
44239
  }
44206
44240
  }
44207
44241
  return exitCode ?? 0;
44208
44242
  }
44209
- var import_node_fs68, import_node_os32, import_node_path87;
44243
+ var import_node_fs69, import_node_os32, import_node_path88;
44210
44244
  var init_controller = __esm({
44211
44245
  "src/run-case/controller.ts"() {
44212
44246
  "use strict";
44213
- import_node_fs68 = require("fs");
44247
+ import_node_fs69 = require("fs");
44214
44248
  import_node_os32 = __toESM(require("os"), 1);
44215
- import_node_path87 = __toESM(require("path"), 1);
44249
+ import_node_path88 = __toESM(require("path"), 1);
44216
44250
  init_claude();
44217
44251
  init_stdout_splitter();
44218
44252
  init_permission_stdio();
@@ -45831,8 +45865,8 @@ function requireEnvironmentIdentity(stores, environment) {
45831
45865
  }
45832
45866
 
45833
45867
  // src/index.ts
45834
- var import_node_path85 = __toESM(require("path"), 1);
45835
- var import_node_fs66 = __toESM(require("fs"), 1);
45868
+ var import_node_path86 = __toESM(require("path"), 1);
45869
+ var import_node_fs67 = __toESM(require("fs"), 1);
45836
45870
  var import_node_os31 = __toESM(require("os"), 1);
45837
45871
  var import_node_crypto30 = require("crypto");
45838
45872
  var import_node_url6 = require("url");
@@ -52509,9 +52543,9 @@ var CentralClientError = class extends Error {
52509
52543
  cause;
52510
52544
  status;
52511
52545
  };
52512
- async function centralRequest(opts, path107, init) {
52546
+ async function centralRequest(opts, path108, init) {
52513
52547
  const f2 = opts.fetchImpl ?? globalThis.fetch;
52514
- const url = `${opts.api.replace(/\/+$/, "")}${path107}`;
52548
+ const url = `${opts.api.replace(/\/+$/, "")}${path108}`;
52515
52549
  const ctrl = new AbortController();
52516
52550
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52517
52551
  let res;
@@ -53463,8 +53497,8 @@ function turnStartInput(text, resolveImage) {
53463
53497
  const items = [];
53464
53498
  let leftover = text;
53465
53499
  for (const m3 of text.matchAll(SKILL_RE)) {
53466
- const [marker, name, path107] = m3;
53467
- items.push({ type: "skill", name, path: path107 });
53500
+ const [marker, name, path108] = m3;
53501
+ items.push({ type: "skill", name, path: path108 });
53468
53502
  leftover = leftover.replace(marker, "");
53469
53503
  }
53470
53504
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -56834,6 +56868,48 @@ function buildShiftInternalHandlers(deps) {
56834
56868
  // src/handlers/deploy.ts
56835
56869
  var import_node_crypto14 = require("crypto");
56836
56870
 
56871
+ // src/deploy/persona-test.ts
56872
+ var import_node_fs33 = __toESM(require("fs"), 1);
56873
+ var import_node_path36 = __toESM(require("path"), 1);
56874
+ init_protocol();
56875
+ var TEST_SCAN_NOTE_PREFIX = PUBLISHER_TEST_NOTE_PREFIX;
56876
+ function regularFile(root, relative5) {
56877
+ let current = root;
56878
+ for (const segment of relative5.split("/")) {
56879
+ current = import_node_path36.default.join(current, segment);
56880
+ if (import_node_fs33.default.lstatSync(current).isSymbolicLink()) throw new Error("symlink");
56881
+ }
56882
+ if (!import_node_fs33.default.statSync(current).isFile()) throw new Error("not a file");
56883
+ const resolved = import_node_fs33.default.realpathSync(current);
56884
+ if (!resolved.startsWith(root + import_node_path36.default.sep)) throw new Error("outside root");
56885
+ return resolved;
56886
+ }
56887
+ function discoverPublisherTest(dir) {
56888
+ try {
56889
+ const root = import_node_fs33.default.realpathSync(dir);
56890
+ try {
56891
+ import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd"));
56892
+ } catch (error) {
56893
+ if (error.code === "ENOENT") return { problems: [] };
56894
+ throw error;
56895
+ }
56896
+ if (import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd")).isSymbolicLink()) throw new Error("symlink");
56897
+ try {
56898
+ import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd/test.json"));
56899
+ } catch (error) {
56900
+ if (error.code === "ENOENT") return { problems: [] };
56901
+ throw error;
56902
+ }
56903
+ const file = regularFile(root, ".clawd/test.json");
56904
+ if (import_node_fs33.default.statSync(file).size > 64 * 1024) throw new Error("oversized");
56905
+ const test = PublisherTestSchema.parse(JSON.parse(import_node_fs33.default.readFileSync(file, "utf8")));
56906
+ regularFile(root, test.entry);
56907
+ return { test, problems: [] };
56908
+ } catch {
56909
+ 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"] };
56910
+ }
56911
+ }
56912
+
56837
56913
  // src/deploy/verified-release.ts
56838
56914
  var import_node_crypto12 = require("crypto");
56839
56915
 
@@ -57227,19 +57303,19 @@ function openHttpTurn(opts) {
57227
57303
 
57228
57304
  // src/deploy/repo.ts
57229
57305
  var import_promises5 = __toESM(require("fs/promises"), 1);
57230
- var import_node_path38 = __toESM(require("path"), 1);
57306
+ var import_node_path39 = __toESM(require("path"), 1);
57231
57307
  init_protocol();
57232
57308
 
57233
57309
  // src/deploy/deploy-file.ts
57234
57310
  var import_promises4 = __toESM(require("fs/promises"), 1);
57235
- var import_node_path37 = __toESM(require("path"), 1);
57311
+ var import_node_path38 = __toESM(require("path"), 1);
57236
57312
  var import_node_crypto11 = require("crypto");
57237
57313
  init_zod();
57238
57314
  init_protocol();
57239
57315
 
57240
57316
  // src/deploy/connectors.ts
57241
- var import_node_fs33 = __toESM(require("fs"), 1);
57242
- var import_node_path36 = __toESM(require("path"), 1);
57317
+ var import_node_fs34 = __toESM(require("fs"), 1);
57318
+ var import_node_path37 = __toESM(require("path"), 1);
57243
57319
  init_zod();
57244
57320
  init_protocol();
57245
57321
 
@@ -57327,11 +57403,11 @@ var PACKAGE_RUNNERS = /* @__PURE__ */ new Set(["npx", "uvx", "pnpx", "bunx"]);
57327
57403
  var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "deno", "python", "python3"]);
57328
57404
  var HOST_ARG_PLACEHOLDER = "CLAWD_PERSONA_DIR";
57329
57405
  function scanMcpConnectors(personaDir) {
57330
- const file = import_node_path36.default.join(personaDir, ".mcp.json");
57406
+ const file = import_node_path37.default.join(personaDir, ".mcp.json");
57331
57407
  const out = { readable: true, connectors: [], evidence: [], warnings: [] };
57332
57408
  let parsed;
57333
57409
  try {
57334
- parsed = JSON.parse(import_node_fs33.default.readFileSync(file, "utf8"));
57410
+ parsed = JSON.parse(import_node_fs34.default.readFileSync(file, "utf8"));
57335
57411
  } catch (e) {
57336
57412
  if (e.code === "ENOENT") return out;
57337
57413
  out.readable = false;
@@ -57410,6 +57486,7 @@ function cliConnectorFromFinding(item) {
57410
57486
  }
57411
57487
  function mergeConnector(existing, incoming) {
57412
57488
  if (!existing) return incoming;
57489
+ if (isFeishuBotConnector(existing) && incoming.name === existing.name && incoming.runner === "cli") return existing;
57413
57490
  const reviewed = existing.credentialSource !== void 0;
57414
57491
  return {
57415
57492
  ...incoming,
@@ -57426,8 +57503,8 @@ function mergeScannedConnectors(existing, scanned) {
57426
57503
  }
57427
57504
 
57428
57505
  // 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");
57506
+ var DEPLOY_FILE = import_node_path38.default.join(".clawd", "deploy.json");
57507
+ var SCAN_FILE = import_node_path38.default.join(".clawd", "deploy-scan.json");
57431
57508
  async function readJson(file) {
57432
57509
  let raw;
57433
57510
  try {
@@ -57443,14 +57520,14 @@ async function readJson(file) {
57443
57520
  }
57444
57521
  }
57445
57522
  async function writeJson(file, value) {
57446
- await import_promises4.default.mkdir(import_node_path37.default.dirname(file), { recursive: true });
57523
+ await import_promises4.default.mkdir(import_node_path38.default.dirname(file), { recursive: true });
57447
57524
  const tmp = `${file}.tmp-${process.pid}`;
57448
57525
  await import_promises4.default.writeFile(tmp, `${JSON.stringify(value, null, 2)}
57449
57526
  `);
57450
57527
  await import_promises4.default.rename(tmp, file);
57451
57528
  }
57452
57529
  async function readDeployFile(dir) {
57453
- const raw = await readJson(import_node_path37.default.join(dir, DEPLOY_FILE));
57530
+ const raw = await readJson(import_node_path38.default.join(dir, DEPLOY_FILE));
57454
57531
  if (raw === void 0) return void 0;
57455
57532
  const parsed = DeployFileSchema.safeParse(raw);
57456
57533
  if (!parsed.success) {
@@ -57460,18 +57537,18 @@ async function readDeployFile(dir) {
57460
57537
  return parsed.data;
57461
57538
  }
57462
57539
  async function writeDeployFile(dir, file) {
57463
- await writeJson(import_node_path37.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
57540
+ await writeJson(import_node_path38.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
57464
57541
  }
57465
57542
  async function readDeployFileRaw(dir) {
57466
57543
  try {
57467
- return await import_promises4.default.readFile(import_node_path37.default.join(dir, DEPLOY_FILE), "utf8");
57544
+ return await import_promises4.default.readFile(import_node_path38.default.join(dir, DEPLOY_FILE), "utf8");
57468
57545
  } catch (err) {
57469
57546
  if (err.code === "ENOENT") return void 0;
57470
57547
  throw err;
57471
57548
  }
57472
57549
  }
57473
57550
  async function restoreDeployFileRaw(dir, raw) {
57474
- const file = import_node_path37.default.join(dir, DEPLOY_FILE);
57551
+ const file = import_node_path38.default.join(dir, DEPLOY_FILE);
57475
57552
  if (raw === void 0) await import_promises4.default.rm(file, { force: true });
57476
57553
  else await import_promises4.default.writeFile(file, raw);
57477
57554
  }
@@ -57522,7 +57599,7 @@ function normalizeLegacyScan(raw) {
57522
57599
  return fix(raw);
57523
57600
  }
57524
57601
  async function readScanFile(dir) {
57525
- const raw = normalizeLegacyScan(await readJson(import_node_path37.default.join(dir, SCAN_FILE)));
57602
+ const raw = normalizeLegacyScan(await readJson(import_node_path38.default.join(dir, SCAN_FILE)));
57526
57603
  if (raw === void 0) return void 0;
57527
57604
  const badShape = (issues) => {
57528
57605
  const first = issues[0];
@@ -57548,7 +57625,7 @@ async function readScanFile(dir) {
57548
57625
  return parsed.data;
57549
57626
  }
57550
57627
  async function writeScanFile(dir, file) {
57551
- await writeJson(import_node_path37.default.join(dir, SCAN_FILE), DeployScanFileSchema.parse(file));
57628
+ await writeJson(import_node_path38.default.join(dir, SCAN_FILE), DeployScanFileSchema.parse(file));
57552
57629
  }
57553
57630
  function replaceScan(file, entry) {
57554
57631
  const idx = file.scans.findIndex((s2) => s2.id === entry.id);
@@ -61087,10 +61164,10 @@ function createGithubApi(args) {
61087
61164
  const seal = args.seal ?? sealWithSodium;
61088
61165
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
61089
61166
  const secretsPath = (slug, environment) => `/repos/${slug}/${environment ? `environments/${encodeURIComponent(environment)}` : "actions"}/secrets`;
61090
- async function request(method, path107, body) {
61167
+ async function request(method, path108, body) {
61091
61168
  let res;
61092
61169
  try {
61093
- res = await doFetch(`${API}${path107}`, {
61170
+ res = await doFetch(`${API}${path108}`, {
61094
61171
  method,
61095
61172
  headers: {
61096
61173
  Authorization: `Bearer ${args.token}`,
@@ -61115,8 +61192,8 @@ function createGithubApi(args) {
61115
61192
  }
61116
61193
  return { status: res.status, json };
61117
61194
  }
61118
- async function must(method, path107, what, body) {
61119
- const r2 = await request(method, path107, body);
61195
+ async function must(method, path108, what, body) {
61196
+ const r2 = await request(method, path108, body);
61120
61197
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
61121
61198
  return r2.json;
61122
61199
  }
@@ -61172,16 +61249,16 @@ function createGithubApi(args) {
61172
61249
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
61173
61250
  });
61174
61251
  },
61175
- async getJson(path107) {
61252
+ async getJson(path108) {
61176
61253
  try {
61177
- const r2 = await request("GET", path107);
61254
+ const r2 = await request("GET", path108);
61178
61255
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
61179
61256
  } catch {
61180
61257
  return void 0;
61181
61258
  }
61182
61259
  },
61183
- async getJsonStrict(path107) {
61184
- return must("GET", path107, "\u8BFB\u53D6\u53D1\u5E03\u8BB0\u5F55");
61260
+ async getJsonStrict(path108) {
61261
+ return must("GET", path108, "\u8BFB\u53D6\u53D1\u5E03\u8BB0\u5F55");
61185
61262
  },
61186
61263
  async downloadArtifact(slug, artifactId) {
61187
61264
  if (!Number.isSafeInteger(artifactId) || artifactId <= 0) throw new GithubApiError(0, "\u5236\u54C1 ID \u65E0\u6548");
@@ -61400,6 +61477,7 @@ function renderDeployWorkflow(config) {
61400
61477
  " sparse-checkout: |",
61401
61478
  " cloud-host/pipeline",
61402
61479
  " cloud-host/k8s",
61480
+ " cloud-host/src/persona-test-contract.mjs",
61403
61481
  "",
61404
61482
  " - name: \u8BFB\u90E8\u7F72\u6587\u4EF6",
61405
61483
  " id: plan",
@@ -61432,6 +61510,7 @@ function renderDeployWorkflow(config) {
61432
61510
  " - name: Check required credentials",
61433
61511
  " env:",
61434
61512
  " CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
61513
+ " CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
61435
61514
  " run: node clawos/cloud-host/pipeline/check-secrets.mjs",
61436
61515
  ""
61437
61516
  ];
@@ -61454,8 +61533,10 @@ function renderDeployWorkflow(config) {
61454
61533
  ` - name: ${script === "smoke" ? "Run real int smoke" : "Register the verified image"}`,
61455
61534
  " env:",
61456
61535
  " CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
61536
+ " CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
61457
61537
  " run: |",
61458
- ` IMAGE_REF=$(node clawos/cloud-host/pipeline/release.mjs validate --file candidate-release.json --component persona${script === "register" ? " --production" : ""})`,
61538
+ ` VALIDATE_PRODUCTION=''; if [ "\${{ inputs.environment }}" = 'production' ]; then VALIDATE_PRODUCTION='--production'; fi`,
61539
+ " IMAGE_REF=$(node clawos/cloud-host/pipeline/release.mjs validate --file candidate-release.json --component persona $VALIDATE_PRODUCTION)",
61459
61540
  ...script === "register" ? [" node clawos/cloud-host/pipeline/persona-candidate.mjs check-source"] : [],
61460
61541
  ` node clawos/cloud-host/pipeline/${script}.mjs \\`,
61461
61542
  ' --image "$IMAGE_REF" \\',
@@ -61547,6 +61628,7 @@ function renderDeployWorkflow(config) {
61547
61628
  " ALIBABA_CLOUD_ACCESS_KEY_ID: ${{ secrets.ALI_ACS_ACCESS_KEY_ID }}",
61548
61629
  " ALIBABA_CLOUD_ACCESS_KEY_SECRET: ${{ secrets.ALI_ACS_ACCESS_KEY_SECRET }}",
61549
61630
  " RELEASE_JSON: ${{ inputs.release_json }}",
61631
+ " CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
61550
61632
  " run: node clawos/cloud-host/pipeline/persona-candidate.mjs",
61551
61633
  "",
61552
61634
  ...upload("persona-candidate"),
@@ -61775,7 +61857,7 @@ var runCommand = (cmd, args, opts = {}) => new Promise((resolve9) => {
61775
61857
  });
61776
61858
 
61777
61859
  // src/deploy/repo.ts
61778
- var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path38.default.sep).join("/");
61860
+ var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path39.default.sep).join("/");
61779
61861
  var PERSONA_FILE_REL = ".clawd/persona.json";
61780
61862
  var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL];
61781
61863
  var RepoError = class extends Error {
@@ -61808,7 +61890,7 @@ async function prepareIntegration(exec, dir, auth) {
61808
61890
  for (const name of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"]) {
61809
61891
  const rel = await mustGit(exec, dir, ["rev-parse", "--git-path", name], "\u68C0\u67E5 Git \u64CD\u4F5C");
61810
61892
  try {
61811
- await import_promises5.default.stat(import_node_path38.default.resolve(dir, rel));
61893
+ await import_promises5.default.stat(import_node_path39.default.resolve(dir, rel));
61812
61894
  throw new RepoError("Git \u5408\u5E76\u6216\u53D8\u57FA\u8FD8\u672A\u5B8C\u6210\uFF0C\u5148\u5904\u7406\u518D\u53D1\u5E03");
61813
61895
  } catch (err) {
61814
61896
  if (err.code !== "ENOENT") throw err;
@@ -61869,7 +61951,7 @@ async function samePath(a2, b3) {
61869
61951
  try {
61870
61952
  return await import_promises5.default.realpath(x2);
61871
61953
  } catch {
61872
- return import_node_path38.default.resolve(x2);
61954
+ return import_node_path39.default.resolve(x2);
61873
61955
  }
61874
61956
  };
61875
61957
  return await real(a2) === await real(b3);
@@ -61895,7 +61977,7 @@ async function identityArgs(exec, dir) {
61895
61977
  return ["-c", "user.name=clawd", "-c", "user.email=clawd@clawos.local"];
61896
61978
  }
61897
61979
  async function writeGitignore(dir) {
61898
- const gi = import_node_path38.default.join(dir, ".gitignore");
61980
+ const gi = import_node_path39.default.join(dir, ".gitignore");
61899
61981
  let existing;
61900
61982
  try {
61901
61983
  existing = await import_promises5.default.readFile(gi, "utf8");
@@ -61906,18 +61988,18 @@ async function writeGitignore(dir) {
61906
61988
  }
61907
61989
  async function writeWorkflow(dir) {
61908
61990
  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 });
61991
+ const wf = import_node_path39.default.join(dir, rel);
61992
+ await import_promises5.default.mkdir(import_node_path39.default.dirname(wf), { recursive: true });
61911
61993
  await import_promises5.default.writeFile(wf, body);
61912
61994
  }
61913
61995
  }
61914
61996
  async function writeDockerfile(dir, personaId2, image) {
61915
61997
  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}
61998
+ await import_promises5.default.mkdir(import_node_path39.default.join(dir, ".clawd"), { recursive: true });
61999
+ await import_promises5.default.writeFile(import_node_path39.default.join(dir, ".clawd", "base-image.txt"), `${baseImage}
61918
62000
  `);
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);
62001
+ await import_promises5.default.writeFile(import_node_path39.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2, baseImage));
62002
+ await import_promises5.default.writeFile(import_node_path39.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
61921
62003
  }
61922
62004
  var RepoAlreadyExistsError = class extends RepoError {
61923
62005
  constructor(slug) {
@@ -61956,7 +62038,7 @@ async function ensureRepo(exec, api, args) {
61956
62038
  const existing = await repoInfo(exec, dir);
61957
62039
  if (existing) return { created: false, url: existing.url };
61958
62040
  await writeGitignore(dir);
61959
- await import_promises5.default.rm(import_node_path38.default.join(dir, WORKFLOW_PATH), { force: true });
62041
+ await import_promises5.default.rm(import_node_path39.default.join(dir, WORKFLOW_PATH), { force: true });
61960
62042
  let created;
61961
62043
  try {
61962
62044
  created = await createOrgRepo(exec, api, { dir, org, repoName: personaId2, message: "clawd: \u4E0A\u4E91", auth: args.auth });
@@ -62056,7 +62138,8 @@ function validatePersonaRelease(raw, expected) {
62056
62138
  commit: record4.commit,
62057
62139
  baseImage: record4.baseImage,
62058
62140
  pipelineCommit: record4.pipelineCommit,
62059
- repository: record4.repository
62141
+ repository: record4.repository,
62142
+ ...record4.test ? { test: record4.test } : {}
62060
62143
  })).digest("hex");
62061
62144
  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
62145
  return record4;
@@ -62084,6 +62167,7 @@ async function readVerifiedRelease(api, slug, run) {
62084
62167
  }) };
62085
62168
  }
62086
62169
  function requireDialogueVerification(release2, run) {
62170
+ 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
62171
  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
62172
  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
62173
  }
@@ -62172,9 +62256,9 @@ init_protocol();
62172
62256
 
62173
62257
  // src/deploy/artifact.ts
62174
62258
  var import_node_crypto13 = require("crypto");
62175
- var import_node_fs34 = __toESM(require("fs"), 1);
62259
+ var import_node_fs35 = __toESM(require("fs"), 1);
62176
62260
  var import_node_os11 = __toESM(require("os"), 1);
62177
- var import_node_path39 = __toESM(require("path"), 1);
62261
+ var import_node_path40 = __toESM(require("path"), 1);
62178
62262
  var import_node_stream3 = require("stream");
62179
62263
  var import_promises6 = require("stream/promises");
62180
62264
  var ARTIFACT_MAX_BYTES = 200 * 1024 * 1024;
@@ -62208,8 +62292,8 @@ function downloadArtifact(exec) {
62208
62292
  if (!res.ok || !res.body) throw new Error(`\u4E0B\u8F7D\u5931\u8D25 HTTP ${res.status}\uFF1A${url}`);
62209
62293
  const declared = Number(res.headers.get("content-length") ?? 0);
62210
62294
  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");
62295
+ const dir = await import_node_fs35.default.promises.mkdtemp(import_node_path40.default.join(import_node_os11.default.tmpdir(), "clawd-artifact-"));
62296
+ const file = import_node_path40.default.join(dir, "pkg");
62213
62297
  const hash = (0, import_node_crypto13.createHash)("sha256");
62214
62298
  let size = 0;
62215
62299
  const meter = new import_node_stream3.Transform({
@@ -62221,7 +62305,7 @@ function downloadArtifact(exec) {
62221
62305
  }
62222
62306
  });
62223
62307
  try {
62224
- await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter, import_node_fs34.default.createWriteStream(file));
62308
+ await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter, import_node_fs35.default.createWriteStream(file));
62225
62309
  let entries;
62226
62310
  if (listEntries) {
62227
62311
  const r2 = await exec("tar", ["-tzf", file], { timeoutMs: 3e4 });
@@ -62230,7 +62314,7 @@ function downloadArtifact(exec) {
62230
62314
  }
62231
62315
  return { sha256: hash.digest("hex"), size, ...entries ? { entries } : {} };
62232
62316
  } finally {
62233
- await import_node_fs34.default.promises.rm(dir, { recursive: true, force: true });
62317
+ await import_node_fs35.default.promises.rm(dir, { recursive: true, force: true });
62234
62318
  }
62235
62319
  };
62236
62320
  }
@@ -62283,12 +62367,12 @@ init_protocol();
62283
62367
  // src/deploy/publishing-config.ts
62284
62368
  async function requireIntegrationPublishingConfig(api, slug) {
62285
62369
  const base = `/repos/${slug}`;
62286
- async function rows(path107, field, absentEnvironment = false) {
62370
+ async function rows(path108, field, absentEnvironment = false) {
62287
62371
  const result = [];
62288
62372
  for (let page = 1; page <= 30; page++) {
62289
62373
  let raw;
62290
62374
  try {
62291
- raw = await api.getJsonStrict(`${path107}?per_page=100&page=${page}`);
62375
+ raw = await api.getJsonStrict(`${path108}?per_page=100&page=${page}`);
62292
62376
  } catch (error) {
62293
62377
  if (absentEnvironment && page === 1 && error instanceof GithubApiError && error.status === 404) return [];
62294
62378
  throw error;
@@ -62796,15 +62880,17 @@ function buildDeployHandlers(deps) {
62796
62880
  const lastDone = [...file.scans].reverse().find((s2) => s2.status === "done");
62797
62881
  const seed = scanBase.kind === "soft" && releasedEntry ? releasedEntry.manifest : { ...emptyDeployFile().manifest, connectors: (lastDone?.manifest.connectors ?? []).filter((c2) => c2.runner === "mcp") };
62798
62882
  const mcp = scanMcpConnectors(dir);
62883
+ const publisherTest = discoverPublisherTest(dir);
62884
+ const { test: _previousTest, ...seedWithoutTest } = seed;
62799
62885
  const mcpTargets = new Set(mcp.evidence.map((e) => e.target));
62800
62886
  const carriedEvidence = scanBase.kind === "soft" && releasedEntry ? releasedEntry.evidence : [];
62801
62887
  const entry = {
62802
62888
  id: newScanId(),
62803
62889
  status: "scanning",
62804
- manifest: { ...seed, connectors: mcp.readable ? mergeScannedConnectors(seed.connectors, mcp.connectors) : seed.connectors },
62890
+ manifest: { ...seedWithoutTest, ...publisherTest.test ? { test: publisherTest.test } : {}, connectors: mcp.readable ? mergeScannedConnectors(seed.connectors, mcp.connectors) : seed.connectors },
62805
62891
  evidence: [...carriedEvidence.filter((e) => !mcpTargets.has(e.target)), ...mcp.evidence.map(redactEvidence)],
62806
62892
  // 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}`),
62893
+ notes: [...mcp.warnings.map((w3) => `${MCP_SCAN_NOTE_PREFIX}${w3}`), ...publisherTest.problems.map((problem) => TEST_SCAN_NOTE_PREFIX + problem)],
62808
62894
  startedAt: deps.now(),
62809
62895
  head: contentHead,
62810
62896
  baseKind: scanBase.kind,
@@ -62983,7 +63069,11 @@ function buildDeployHandlers(deps) {
62983
63069
  } catch (err) {
62984
63070
  throw invalid(err instanceof Error ? err.message : String(err));
62985
63071
  }
62986
- if (args.kind === "connector") item = cliConnectorFromFinding(item);
63072
+ if (args.kind === "connector") {
63073
+ const incoming = cliConnectorFromFinding(item);
63074
+ const previous = scan.manifest.connectors.some((c2) => c2.name === incoming.name) ? void 0 : [...file.scans].reverse().find((s2) => s2.status === "done")?.manifest.connectors.find((c2) => c2.name === incoming.name && isFeishuBotConnector(c2));
63075
+ item = mergeConnector(previous, incoming);
63076
+ }
62987
63077
  if (args.kind === "package") item = await settlePackage(item);
62988
63078
  const target = `${args.kind}:${item.name}`;
62989
63079
  await writeScanFile(dir, replaceScan(file, {
@@ -63004,7 +63094,7 @@ function buildDeployHandlers(deps) {
63004
63094
  status: "done",
63005
63095
  finishedAt: deps.now(),
63006
63096
  // 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)],
63097
+ notes: [...scan.notes.filter((n2) => n2.startsWith(MCP_SCAN_NOTE_PREFIX) || n2.startsWith(TEST_SCAN_NOTE_PREFIX)), ...args.notes.map(redactSecretValues)],
63008
63098
  error: void 0
63009
63099
  }));
63010
63100
  return view(args.personaId);
@@ -63068,6 +63158,10 @@ function buildDeployHandlers(deps) {
63068
63158
  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
63159
  const file = await readHistory(dir);
63070
63160
  const entry = mustScan(file, scanId);
63161
+ const publisherTest = discoverPublisherTest(dir);
63162
+ const testBlockers = [...publisherTest.problems, ...entry.notes.filter((note) => note.startsWith(TEST_SCAN_NOTE_PREFIX))];
63163
+ 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");
63164
+ if (testBlockers.length) throw invalid("\u8FD8\u5DEE\uFF1A" + testBlockers.join("\uFF1B"));
63071
63165
  const pending = file.releases.find((r2) => r2.environment === "integration" && r2.scanId === scanId && !r2.pushed);
63072
63166
  if (pending) {
63073
63167
  try {
@@ -63305,14 +63399,14 @@ function buildDeployHandlers(deps) {
63305
63399
  }
63306
63400
 
63307
63401
  // src/tools/subscription-channels-store.ts
63308
- var import_node_fs36 = __toESM(require("fs"), 1);
63402
+ var import_node_fs37 = __toESM(require("fs"), 1);
63309
63403
  var import_node_os13 = __toESM(require("os"), 1);
63310
- var import_node_path41 = __toESM(require("path"), 1);
63404
+ var import_node_path42 = __toESM(require("path"), 1);
63311
63405
 
63312
63406
  // src/tools/subscription-channels-apply.ts
63313
- var import_node_fs35 = __toESM(require("fs"), 1);
63407
+ var import_node_fs36 = __toESM(require("fs"), 1);
63314
63408
  var import_node_os12 = __toESM(require("os"), 1);
63315
- var import_node_path40 = __toESM(require("path"), 1);
63409
+ var import_node_path41 = __toESM(require("path"), 1);
63316
63410
 
63317
63411
  // src/tools/codex-config-toml.ts
63318
63412
  function parseKey(src, start) {
@@ -63494,29 +63588,29 @@ function parseValueAt(s2, start) {
63494
63588
  const bare = /^[^\s,\]}#]+/.exec(s2.slice(i2));
63495
63589
  return bare ? { value: bare[0], end: i2 + bare[0].length } : null;
63496
63590
  }
63497
- function setPath(target, path107, value) {
63591
+ function setPath(target, path108, value) {
63498
63592
  let node = target;
63499
- for (const part of path107.slice(0, -1)) {
63593
+ for (const part of path108.slice(0, -1)) {
63500
63594
  const next = node[part];
63501
63595
  if (!next || typeof next !== "object" || Array.isArray(next)) node[part] = {};
63502
63596
  node = node[part];
63503
63597
  }
63504
- const last = path107[path107.length - 1];
63598
+ const last = path108[path108.length - 1];
63505
63599
  const existing = node[last];
63506
63600
  if (existing && typeof existing === "object" && !Array.isArray(existing) && value && typeof value === "object" && !Array.isArray(value)) {
63507
63601
  Object.assign(existing, value);
63508
63602
  } else node[last] = value;
63509
63603
  }
63510
- function readTomlTable(text, path107) {
63604
+ function readTomlTable(text, path108) {
63511
63605
  const result = {};
63512
63606
  let found = false;
63513
- const within = (full) => full.length >= path107.length && path107.every((part, i2) => full[i2] === part);
63607
+ const within = (full) => full.length >= path108.length && path108.every((part, i2) => full[i2] === part);
63514
63608
  const lines = scanToml(text);
63515
63609
  for (let index = 0; index < lines.length; index++) {
63516
63610
  const line = lines[index];
63517
63611
  if (line.kind === "header" && within(line.key)) {
63518
63612
  found = true;
63519
- if (line.key.length > path107.length) setPath(result, line.key.slice(path107.length), {});
63613
+ if (line.key.length > path108.length) setPath(result, line.key.slice(path108.length), {});
63520
63614
  continue;
63521
63615
  }
63522
63616
  if (line.kind !== "key") continue;
@@ -63528,16 +63622,16 @@ ${lines[++index].text}`;
63528
63622
  const parsed = parseTomlValue(raw);
63529
63623
  const value = parsed === void 0 ? UNREADABLE : parsed;
63530
63624
  found = true;
63531
- if (full.length === path107.length) {
63625
+ if (full.length === path108.length) {
63532
63626
  if (value && typeof value === "object" && !Array.isArray(value)) Object.assign(result, value);
63533
- } else setPath(result, full.slice(path107.length), value);
63627
+ } else setPath(result, full.slice(path108.length), value);
63534
63628
  }
63535
63629
  return found ? result : null;
63536
63630
  }
63537
63631
 
63538
63632
  // src/tools/subscription-channels-apply.ts
63539
63633
  var PROVIDER_ID = "cliproxyapi";
63540
- var isOwnProvider = (path107) => path107[0] === "model_providers" && path107[1] === PROVIDER_ID;
63634
+ var isOwnProvider = (path108) => path108[0] === "model_providers" && path108[1] === PROVIDER_ID;
63541
63635
  function stripCodexProvider(text) {
63542
63636
  const out = [];
63543
63637
  let dropping = false;
@@ -63565,31 +63659,31 @@ function stripCodexProvider(text) {
63565
63659
  return out.join("\n").trim();
63566
63660
  }
63567
63661
  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;
63662
+ const target = import_node_fs36.default.existsSync(file) && import_node_fs36.default.lstatSync(file).isSymbolicLink() ? import_node_fs36.default.realpathSync(file) : file;
63569
63663
  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);
63664
+ import_node_fs36.default.writeFileSync(tmp, data, { mode: 384 });
63665
+ import_node_fs36.default.renameSync(tmp, target);
63572
63666
  }
63573
63667
  function snapshotFile(file) {
63574
- const original = import_node_fs35.default.existsSync(file) ? import_node_fs35.default.readFileSync(file) : null;
63668
+ const original = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
63575
63669
  return () => {
63576
- const current = import_node_fs35.default.existsSync(file) ? import_node_fs35.default.readFileSync(file) : null;
63670
+ const current = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
63577
63671
  if (original === null) {
63578
- if (current !== null) import_node_fs35.default.rmSync(file, { force: true });
63672
+ if (current !== null) import_node_fs36.default.rmSync(file, { force: true });
63579
63673
  return;
63580
63674
  }
63581
63675
  if (current !== null && current.equals(original)) return;
63582
63676
  writeFileAtomic(file, original);
63583
63677
  };
63584
63678
  }
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");
63679
+ var resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path41.default.join(import_node_os12.default.homedir(), ".codex");
63680
+ var resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os12.default.homedir(), ".pi", "agent");
63587
63681
  var PI_SUBSCRIPTION_FILE = "cliproxyapi.json";
63588
63682
  function applyCodexSubscriptionChannel(opts) {
63589
63683
  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") : "";
63684
+ import_node_fs36.default.mkdirSync(codexHome, { recursive: true });
63685
+ const configFile = import_node_path41.default.join(codexHome, "config.toml");
63686
+ const original = import_node_fs36.default.existsSync(configFile) ? import_node_fs36.default.readFileSync(configFile, "utf8") : "";
63593
63687
  const rest = stripCodexProvider(original);
63594
63688
  let content;
63595
63689
  if (opts.channel) {
@@ -63616,8 +63710,8 @@ function applyCodexSubscriptionChannel(opts) {
63616
63710
  }
63617
63711
  function applyPiSubscriptionChannel(opts) {
63618
63712
  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);
63713
+ if (!import_node_fs36.default.existsSync(agentDir)) return false;
63714
+ const configFile = import_node_path41.default.join(agentDir, PI_SUBSCRIPTION_FILE);
63621
63715
  if (opts.channel) {
63622
63716
  const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
63623
63717
  writeFileAtomic(configFile, JSON.stringify(data, null, 2) + "\n");
@@ -63646,7 +63740,7 @@ function providerKey(provider, codexHome) {
63646
63740
  }
63647
63741
  function readAuthKey2(codexHome) {
63648
63742
  try {
63649
- const key = JSON.parse(import_node_fs36.default.readFileSync(import_node_path41.default.join(codexHome, "auth.json"), "utf8")).OPENAI_API_KEY;
63743
+ const key = JSON.parse(import_node_fs37.default.readFileSync(import_node_path42.default.join(codexHome, "auth.json"), "utf8")).OPENAI_API_KEY;
63650
63744
  return typeof key === "string" && key ? key : null;
63651
63745
  } catch {
63652
63746
  return null;
@@ -63656,8 +63750,8 @@ var SubscriptionChannelStore = class {
63656
63750
  filePath;
63657
63751
  codexHome;
63658
63752
  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");
63753
+ this.filePath = import_node_path42.default.join(options.dataDir, CHANNELS_FILE_NAME);
63754
+ this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path42.default.join(import_node_os13.default.homedir(), ".codex");
63661
63755
  }
63662
63756
  /** 存储文件的快照(首次初始化 / 迁移先落盘);返回的函数把它恢复成此刻的样子,通道切换失败时回滚用 */
63663
63757
  snapshot() {
@@ -63754,9 +63848,9 @@ var SubscriptionChannelStore = class {
63754
63848
  return target;
63755
63849
  }
63756
63850
  readOrCreate() {
63757
- if (import_node_fs36.default.existsSync(this.filePath)) {
63851
+ if (import_node_fs37.default.existsSync(this.filePath)) {
63758
63852
  try {
63759
- const raw = JSON.parse(import_node_fs36.default.readFileSync(this.filePath, "utf8"));
63853
+ const raw = JSON.parse(import_node_fs37.default.readFileSync(this.filePath, "utf8"));
63760
63854
  if (raw && Array.isArray(raw.channels)) {
63761
63855
  return {
63762
63856
  activeChannelId: typeof raw.activeChannelId === "string" ? raw.activeChannelId : null,
@@ -63776,9 +63870,9 @@ var SubscriptionChannelStore = class {
63776
63870
  }
63777
63871
  tryMigrateFromCodexConfig() {
63778
63872
  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");
63873
+ const configPath = import_node_path42.default.join(this.codexHome, "config.toml");
63874
+ if (!import_node_fs37.default.existsSync(configPath)) return null;
63875
+ const content = import_node_fs37.default.readFileSync(configPath, "utf8");
63782
63876
  if (readTomlTable(content, [])?.model_provider !== "cliproxyapi") return null;
63783
63877
  const provider = readTomlTable(content, ["model_providers", "cliproxyapi"]);
63784
63878
  if (!provider) return null;
@@ -63805,8 +63899,8 @@ var SubscriptionChannelStore = class {
63805
63899
  return null;
63806
63900
  }
63807
63901
  write(data) {
63808
- const dir = import_node_path41.default.dirname(this.filePath);
63809
- import_node_fs36.default.mkdirSync(dir, { recursive: true });
63902
+ const dir = import_node_path42.default.dirname(this.filePath);
63903
+ import_node_fs37.default.mkdirSync(dir, { recursive: true });
63810
63904
  writeFileAtomic(this.filePath, JSON.stringify(data, null, 2) + "\n");
63811
63905
  }
63812
63906
  };
@@ -63869,8 +63963,8 @@ function refreshPathFromLoginShell() {
63869
63963
  timeout: 3e3,
63870
63964
  stdio: ["ignore", "pipe", "ignore"]
63871
63965
  });
63872
- const path107 = out.trim();
63873
- if (path107) process.env.PATH = path107;
63966
+ const path108 = out.trim();
63967
+ if (path108) process.env.PATH = path108;
63874
63968
  } catch {
63875
63969
  }
63876
63970
  }
@@ -64663,10 +64757,10 @@ function createCloudPersonaBotClient(opts) {
64663
64757
  const f2 = opts.fetchImpl ?? fetch;
64664
64758
  const base = opts.api.replace(/\/+$/, "");
64665
64759
  const route = (personaId2) => `/api/lark-bot/cloud/${encodeURIComponent(personaId2)}`;
64666
- async function request(method, path107, body) {
64760
+ async function request(method, path108, body) {
64667
64761
  const pass = opts.getLoginPass();
64668
64762
  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, {
64763
+ const response = await f2(base + path108, {
64670
64764
  method,
64671
64765
  headers: { authorization: `Bearer ${pass}`, "content-type": "application/json" },
64672
64766
  ...body ? { body: JSON.stringify(body) } : {},
@@ -64675,7 +64769,7 @@ function createCloudPersonaBotClient(opts) {
64675
64769
  const json = await response.json().catch(() => ({}));
64676
64770
  if (!response.ok) {
64677
64771
  const detail = typeof json.message === "string" ? json.message : `HTTP ${response.status}`;
64678
- throw new LarkBotCloudError(`cloud bot ${method} ${path107}: ${detail}`, response.status);
64772
+ throw new LarkBotCloudError(`cloud bot ${method} ${path108}: ${detail}`, response.status);
64679
64773
  }
64680
64774
  return json;
64681
64775
  }
@@ -64691,15 +64785,15 @@ function createCloudPersonaBotClient(opts) {
64691
64785
  }
64692
64786
 
64693
64787
  // 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);
64788
+ var import_node_fs38 = __toESM(require("fs"), 1);
64789
+ var import_node_path43 = __toESM(require("path"), 1);
64696
64790
  function createLarkBotBindingStore(personaRoot) {
64697
- const filePath = (personaId2) => import_node_path42.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
64791
+ const filePath = (personaId2) => import_node_path43.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
64698
64792
  const read = (personaId2) => {
64699
64793
  const file = filePath(personaId2);
64700
- if (!import_node_fs37.default.existsSync(file)) return null;
64794
+ if (!import_node_fs38.default.existsSync(file)) return null;
64701
64795
  try {
64702
- const raw = JSON.parse(import_node_fs37.default.readFileSync(file, "utf8"));
64796
+ const raw = JSON.parse(import_node_fs38.default.readFileSync(file, "utf8"));
64703
64797
  if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
64704
64798
  return raw;
64705
64799
  } catch {
@@ -64708,16 +64802,16 @@ function createLarkBotBindingStore(personaRoot) {
64708
64802
  };
64709
64803
  const write = (personaId2, meta) => {
64710
64804
  const file = filePath(personaId2);
64711
- import_node_fs37.default.mkdirSync(import_node_path42.default.dirname(file), { recursive: true });
64805
+ import_node_fs38.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
64712
64806
  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);
64807
+ import_node_fs38.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
64808
+ import_node_fs38.default.renameSync(tmp, file);
64715
64809
  };
64716
64810
  return {
64717
64811
  read,
64718
64812
  write,
64719
64813
  remove(personaId2) {
64720
- import_node_fs37.default.rmSync(filePath(personaId2), { force: true });
64814
+ import_node_fs38.default.rmSync(filePath(personaId2), { force: true });
64721
64815
  },
64722
64816
  addRemovedChat(personaId2, chatId) {
64723
64817
  const meta = read(personaId2);
@@ -64730,8 +64824,8 @@ function createLarkBotBindingStore(personaRoot) {
64730
64824
  }
64731
64825
 
64732
64826
  // 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);
64827
+ var import_node_fs39 = __toESM(require("fs"), 1);
64828
+ var import_node_path44 = __toESM(require("path"), 1);
64735
64829
  init_protocol();
64736
64830
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
64737
64831
  var LOCAL_TURN_RETRIES = 2;
@@ -64809,9 +64903,9 @@ function createLarkChatRouter(deps) {
64809
64903
  continue;
64810
64904
  }
64811
64905
  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);
64906
+ import_node_fs39.default.mkdirSync(dir, { recursive: true });
64907
+ const p3 = import_node_path44.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
64908
+ import_node_fs39.default.writeFileSync(p3, r2.data);
64815
64909
  lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
64816
64910
  } catch (err) {
64817
64911
  deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
@@ -64832,9 +64926,9 @@ function createLarkChatRouter(deps) {
64832
64926
  continue;
64833
64927
  }
64834
64928
  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);
64929
+ import_node_fs39.default.mkdirSync(dir, { recursive: true });
64930
+ const p3 = import_node_path44.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
64931
+ import_node_fs39.default.writeFileSync(p3, r2.data);
64838
64932
  lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
64839
64933
  } catch (err) {
64840
64934
  deps.logger?.warn(`larkBot file fetch failed ${f2.key}: ${err.message}`);
@@ -65648,7 +65742,7 @@ async function forwardPeerExecToPeer(args) {
65648
65742
  init_protocol();
65649
65743
 
65650
65744
  // src/tools/codex-cloud-session.ts
65651
- var import_node_fs39 = __toESM(require("fs"), 1);
65745
+ var import_node_fs40 = __toESM(require("fs"), 1);
65652
65746
 
65653
65747
  // src/tools/cloud-portable-input.ts
65654
65748
  async function portableCloudInput(text, resolvers) {
@@ -65803,7 +65897,7 @@ function cloudImageInput(deps) {
65803
65897
  const mime = lookupMime(p3);
65804
65898
  if (!mime.startsWith("image/")) return null;
65805
65899
  try {
65806
- const bytes = (deps.readFile ?? import_node_fs39.default.readFileSync)(p3);
65900
+ const bytes = (deps.readFile ?? import_node_fs40.default.readFileSync)(p3);
65807
65901
  return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
65808
65902
  } catch (e) {
65809
65903
  deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
@@ -65905,7 +65999,7 @@ init_protocol();
65905
65999
 
65906
66000
  // src/tools/pi.ts
65907
66001
  var import_node_child_process13 = require("child_process");
65908
- var import_node_fs41 = __toESM(require("fs"), 1);
66002
+ var import_node_fs42 = __toESM(require("fs"), 1);
65909
66003
  init_protocol();
65910
66004
 
65911
66005
  // src/tools/pi-rpc-client.ts
@@ -66006,8 +66100,8 @@ var PiRpcClient = class {
66006
66100
  // src/tools/pi-session.ts
66007
66101
  var import_node_child_process12 = require("child_process");
66008
66102
  var import_node_crypto17 = require("crypto");
66009
- var import_node_fs40 = __toESM(require("fs"), 1);
66010
- var import_node_path44 = __toESM(require("path"), 1);
66103
+ var import_node_fs41 = __toESM(require("fs"), 1);
66104
+ var import_node_path45 = __toESM(require("path"), 1);
66011
66105
 
66012
66106
  // src/tools/pi-events.ts
66013
66107
  init_protocol();
@@ -66288,8 +66382,8 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
66288
66382
  function createPiSession(ctx, sink, deps = {}) {
66289
66383
  const cmd = process.env.PI_BIN ?? "pi";
66290
66384
  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));
66385
+ const skillsDir = import_node_path45.default.join(ctx.cwd, ".claude", "skills");
66386
+ const exists = deps.skillsDirExists ?? ((d2) => import_node_fs41.default.existsSync(d2));
66293
66387
  const args = buildPiArgs(ctx, {
66294
66388
  sessionId,
66295
66389
  skillsDir: exists(skillsDir) ? skillsDir : void 0,
@@ -66351,10 +66445,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
66351
66445
  };
66352
66446
  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
66447
  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 };
66448
+ if (env.PI_BIN && import_node_fs42.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
66355
66449
  try {
66356
66450
  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 };
66451
+ if (out && import_node_fs42.default.existsSync(out)) return { available: true, path: out };
66358
66452
  } catch {
66359
66453
  }
66360
66454
  return { available: false };
@@ -66644,7 +66738,7 @@ var CloudPiAdapter = class {
66644
66738
  init_protocol();
66645
66739
 
66646
66740
  // src/tools/codex-skills.ts
66647
- var import_node_path45 = __toESM(require("path"), 1);
66741
+ var import_node_path46 = __toESM(require("path"), 1);
66648
66742
  function str4(v3) {
66649
66743
  return typeof v3 === "string" ? v3 : void 0;
66650
66744
  }
@@ -66659,13 +66753,13 @@ function mapSkillsListResponse(res) {
66659
66753
  const r2 = s2 ?? {};
66660
66754
  const name = str4(r2.name);
66661
66755
  if (!name) continue;
66662
- const path107 = str4(r2.path);
66756
+ const path108 = str4(r2.path);
66663
66757
  const description = str4(r2.description);
66664
66758
  const isPlugin = name.includes(":");
66665
66759
  out.push({
66666
66760
  name,
66667
66761
  source: isPlugin ? "plugin" : "project",
66668
- ...path107 ? { path: path107 } : {},
66762
+ ...path108 ? { path: path108 } : {},
66669
66763
  ...description ? { description } : {},
66670
66764
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
66671
66765
  });
@@ -66681,7 +66775,7 @@ async function listCodexSkills(cwd, deps = {}) {
66681
66775
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
66682
66776
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
66683
66777
  beforeRequest: (client) => {
66684
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path45.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66778
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path46.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66685
66779
  }
66686
66780
  });
66687
66781
  return mapSkillsListResponse(res);
@@ -66755,23 +66849,23 @@ function rec4(v3) {
66755
66849
  }
66756
66850
 
66757
66851
  // src/workspace/browser.ts
66758
- var import_node_fs42 = __toESM(require("fs"), 1);
66852
+ var import_node_fs43 = __toESM(require("fs"), 1);
66759
66853
  var import_node_os15 = __toESM(require("os"), 1);
66760
- var import_node_path46 = __toESM(require("path"), 1);
66854
+ var import_node_path47 = __toESM(require("path"), 1);
66761
66855
  init_protocol();
66762
66856
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
66763
66857
  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)) {
66858
+ const absCwd = import_node_path47.default.resolve(cwd);
66859
+ const joined = import_node_path47.default.resolve(absCwd, subpath ?? ".");
66860
+ const rel = import_node_path47.default.relative(absCwd, joined);
66861
+ if (rel.startsWith("..") || import_node_path47.default.isAbsolute(rel)) {
66768
66862
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
66769
66863
  }
66770
66864
  return joined;
66771
66865
  }
66772
66866
  function ensureCwd(cwd) {
66773
66867
  try {
66774
- const stat = import_node_fs42.default.statSync(cwd);
66868
+ const stat = import_node_fs43.default.statSync(cwd);
66775
66869
  if (!stat.isDirectory()) {
66776
66870
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
66777
66871
  }
@@ -66785,7 +66879,7 @@ var WorkspaceBrowser = class {
66785
66879
  const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os15.default.homedir();
66786
66880
  ensureCwd(cwd);
66787
66881
  const full = resolveInsideCwd(cwd, args.path);
66788
- const dirents = import_node_fs42.default.readdirSync(full, { withFileTypes: true });
66882
+ const dirents = import_node_fs43.default.readdirSync(full, { withFileTypes: true });
66789
66883
  const entries = [];
66790
66884
  for (const d2 of dirents) {
66791
66885
  if (!args.showHidden && d2.name.startsWith(".")) continue;
@@ -66795,7 +66889,7 @@ var WorkspaceBrowser = class {
66795
66889
  mtime: ""
66796
66890
  };
66797
66891
  try {
66798
- const st2 = import_node_fs42.default.statSync(import_node_path46.default.join(full, d2.name));
66892
+ const st2 = import_node_fs43.default.statSync(import_node_path47.default.join(full, d2.name));
66799
66893
  entry.mtime = new Date(st2.mtimeMs).toISOString();
66800
66894
  if (d2.isFile()) entry.size = st2.size;
66801
66895
  } catch {
@@ -66811,14 +66905,14 @@ var WorkspaceBrowser = class {
66811
66905
  read(args) {
66812
66906
  ensureCwd(args.cwd);
66813
66907
  const full = resolveInsideCwd(args.cwd, args.path);
66814
- const st2 = import_node_fs42.default.statSync(full);
66908
+ const st2 = import_node_fs43.default.statSync(full);
66815
66909
  if (!st2.isFile()) {
66816
66910
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
66817
66911
  }
66818
66912
  if (st2.size > MAX_FILE_BYTES2) {
66819
66913
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
66820
66914
  }
66821
- const buf = import_node_fs42.default.readFileSync(full);
66915
+ const buf = import_node_fs43.default.readFileSync(full);
66822
66916
  const isBinary = buf.includes(0);
66823
66917
  if (isBinary) {
66824
66918
  return {
@@ -66840,20 +66934,20 @@ var WorkspaceBrowser = class {
66840
66934
  };
66841
66935
 
66842
66936
  // src/skills/agents-scanner.ts
66843
- var import_node_fs43 = __toESM(require("fs"), 1);
66937
+ var import_node_fs44 = __toESM(require("fs"), 1);
66844
66938
  var import_node_os16 = __toESM(require("os"), 1);
66845
- var import_node_path47 = __toESM(require("path"), 1);
66939
+ var import_node_path48 = __toESM(require("path"), 1);
66846
66940
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
66847
66941
  function isDirLikeSync2(p3) {
66848
66942
  try {
66849
- return import_node_fs43.default.statSync(p3).isDirectory();
66943
+ return import_node_fs44.default.statSync(p3).isDirectory();
66850
66944
  } catch {
66851
66945
  return false;
66852
66946
  }
66853
66947
  }
66854
66948
  function fileExistsSync(p3) {
66855
66949
  try {
66856
- return import_node_fs43.default.statSync(p3).isFile();
66950
+ return import_node_fs44.default.statSync(p3).isFile();
66857
66951
  } catch {
66858
66952
  return false;
66859
66953
  }
@@ -66861,7 +66955,7 @@ function fileExistsSync(p3) {
66861
66955
  function parseAgentFile(filePath) {
66862
66956
  let content;
66863
66957
  try {
66864
- content = import_node_fs43.default.readFileSync(filePath, "utf8");
66958
+ content = import_node_fs44.default.readFileSync(filePath, "utf8");
66865
66959
  } catch {
66866
66960
  return {};
66867
66961
  }
@@ -66874,16 +66968,16 @@ function parseAgentFile(filePath) {
66874
66968
  function scanAgentsDir(dir, source, seen, out) {
66875
66969
  let entries;
66876
66970
  try {
66877
- entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
66971
+ entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66878
66972
  } catch {
66879
66973
  return;
66880
66974
  }
66881
66975
  for (const ent of entries) {
66882
66976
  if (!ent.name.endsWith(".md")) continue;
66883
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path47.default.join(dir, ent.name)))) {
66977
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path48.default.join(dir, ent.name)))) {
66884
66978
  continue;
66885
66979
  }
66886
- const filePath = import_node_path47.default.join(dir, ent.name);
66980
+ const filePath = import_node_path48.default.join(dir, ent.name);
66887
66981
  const baseName = ent.name.replace(/\.md$/, "");
66888
66982
  if (seen.has(baseName)) continue;
66889
66983
  seen.add(baseName);
@@ -66901,12 +66995,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
66901
66995
  function walk2(dir, namespaces) {
66902
66996
  let entries;
66903
66997
  try {
66904
- entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
66998
+ entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66905
66999
  } catch {
66906
67000
  return;
66907
67001
  }
66908
67002
  for (const ent of entries) {
66909
- const childPath = import_node_path47.default.join(dir, ent.name);
67003
+ const childPath = import_node_path48.default.join(dir, ent.name);
66910
67004
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
66911
67005
  walk2(childPath, [...namespaces, ent.name]);
66912
67006
  continue;
@@ -66931,13 +67025,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
66931
67025
  walk2(root, []);
66932
67026
  }
66933
67027
  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");
67028
+ const pluginsDir = import_node_path48.default.join(home, ".claude", "plugins");
67029
+ const v22 = import_node_path48.default.join(pluginsDir, "installed_plugins_v2.json");
67030
+ const v1 = import_node_path48.default.join(pluginsDir, "installed_plugins.json");
66937
67031
  let raw = null;
66938
67032
  for (const candidate of [v22, v1]) {
66939
67033
  try {
66940
- raw = import_node_fs43.default.readFileSync(candidate, "utf8");
67034
+ raw = import_node_fs44.default.readFileSync(candidate, "utf8");
66941
67035
  break;
66942
67036
  } catch {
66943
67037
  }
@@ -66962,19 +67056,19 @@ function readInstalledPlugins2(home) {
66962
67056
  return out;
66963
67057
  }
66964
67058
  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;
67059
+ let cur = import_node_path48.default.resolve(startCwd);
67060
+ const fsRoot = import_node_path48.default.parse(cur).root;
66967
67061
  while (true) {
66968
- scanAgentsDir(import_node_path47.default.join(cur, ".claude", "agents"), "project", seen, out);
67062
+ scanAgentsDir(import_node_path48.default.join(cur, ".claude", "agents"), "project", seen, out);
66969
67063
  let hasGit = false;
66970
67064
  try {
66971
- hasGit = import_node_fs43.default.existsSync(import_node_path47.default.join(cur, ".git"));
67065
+ hasGit = import_node_fs44.default.existsSync(import_node_path48.default.join(cur, ".git"));
66972
67066
  } catch {
66973
67067
  }
66974
67068
  if (hasGit) return;
66975
67069
  if (cur === home) return;
66976
67070
  if (cur === fsRoot) return;
66977
- const parent = import_node_path47.default.dirname(cur);
67071
+ const parent = import_node_path48.default.dirname(cur);
66978
67072
  if (parent === cur) return;
66979
67073
  cur = parent;
66980
67074
  }
@@ -67009,7 +67103,7 @@ var AgentsScanner = class {
67009
67103
  }
67010
67104
  const fsBlock = [];
67011
67105
  scanAgentsDir(
67012
- import_node_path47.default.join(this.home, ".claude", "agents"),
67106
+ import_node_path48.default.join(this.home, ".claude", "agents"),
67013
67107
  "global",
67014
67108
  seen,
67015
67109
  fsBlock
@@ -67023,7 +67117,7 @@ var AgentsScanner = class {
67023
67117
  ...this.extraPluginRoots
67024
67118
  ];
67025
67119
  for (const { name, root } of plugins) {
67026
- const agentsRoot = import_node_path47.default.join(root, "agents");
67120
+ const agentsRoot = import_node_path48.default.join(root, "agents");
67027
67121
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
67028
67122
  }
67029
67123
  return [...builtinBlock, ...fsBlock];
@@ -67031,15 +67125,15 @@ var AgentsScanner = class {
67031
67125
  };
67032
67126
 
67033
67127
  // src/observer/session-observer.ts
67034
- var import_node_fs45 = __toESM(require("fs"), 1);
67128
+ var import_node_fs46 = __toESM(require("fs"), 1);
67035
67129
  var import_node_os18 = __toESM(require("os"), 1);
67036
- var import_node_path49 = __toESM(require("path"), 1);
67130
+ var import_node_path50 = __toESM(require("path"), 1);
67037
67131
  init_claude_history();
67038
67132
 
67039
67133
  // src/observer/subagent-meta-observer.ts
67040
- var import_node_fs44 = __toESM(require("fs"), 1);
67134
+ var import_node_fs45 = __toESM(require("fs"), 1);
67041
67135
  var import_node_os17 = __toESM(require("os"), 1);
67042
- var import_node_path48 = __toESM(require("path"), 1);
67136
+ var import_node_path49 = __toESM(require("path"), 1);
67043
67137
  init_claude_history();
67044
67138
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
67045
67139
  var SubagentMetaObserver = class {
@@ -67052,7 +67146,7 @@ var SubagentMetaObserver = class {
67052
67146
  watches = /* @__PURE__ */ new Map();
67053
67147
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
67054
67148
  resolveSubagentDir(cwd, toolSessionId) {
67055
- return import_node_path48.default.join(
67149
+ return import_node_path49.default.join(
67056
67150
  this.home,
67057
67151
  ".claude",
67058
67152
  "projects",
@@ -67081,7 +67175,7 @@ var SubagentMetaObserver = class {
67081
67175
  attachWatcher(w3) {
67082
67176
  if (w3.watcher) return;
67083
67177
  try {
67084
- w3.watcher = import_node_fs44.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
67178
+ w3.watcher = import_node_fs45.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
67085
67179
  if (!name) return;
67086
67180
  const m3 = META_RE.exec(String(name));
67087
67181
  if (!m3) return;
@@ -67093,7 +67187,7 @@ var SubagentMetaObserver = class {
67093
67187
  scan(w3) {
67094
67188
  let entries;
67095
67189
  try {
67096
- entries = import_node_fs44.default.readdirSync(w3.dirPath);
67190
+ entries = import_node_fs45.default.readdirSync(w3.dirPath);
67097
67191
  } catch {
67098
67192
  return;
67099
67193
  }
@@ -67107,10 +67201,10 @@ var SubagentMetaObserver = class {
67107
67201
  if (!m3) return;
67108
67202
  const agentId = m3[1];
67109
67203
  if (w3.emitted.has(agentId)) return;
67110
- const file = import_node_path48.default.join(w3.dirPath, name);
67204
+ const file = import_node_path49.default.join(w3.dirPath, name);
67111
67205
  let raw;
67112
67206
  try {
67113
- raw = import_node_fs44.default.readFileSync(file, "utf8");
67207
+ raw = import_node_fs45.default.readFileSync(file, "utf8");
67114
67208
  } catch {
67115
67209
  return;
67116
67210
  }
@@ -67164,14 +67258,14 @@ var SessionObserver = class {
67164
67258
  metaObserver;
67165
67259
  resolveJsonlPath(cwd, toolSessionId, override) {
67166
67260
  if (override) return override;
67167
- return import_node_path49.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
67261
+ return import_node_path50.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
67168
67262
  }
67169
67263
  start(args) {
67170
67264
  this.stop(args.sessionId);
67171
67265
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
67172
67266
  let size = 0;
67173
67267
  try {
67174
- size = import_node_fs45.default.statSync(filePath).size;
67268
+ size = import_node_fs46.default.statSync(filePath).size;
67175
67269
  } catch {
67176
67270
  }
67177
67271
  const w3 = {
@@ -67184,16 +67278,16 @@ var SessionObserver = class {
67184
67278
  adapter: args.adapter,
67185
67279
  prevIsRejectSentinel: false,
67186
67280
  toolSessionId: args.toolSessionId,
67187
- sawFile: import_node_fs45.default.existsSync(filePath),
67281
+ sawFile: import_node_fs46.default.existsSync(filePath),
67188
67282
  lastRelocateScanMs: 0,
67189
67283
  pendingCwdDerive: false,
67190
67284
  lastDeriveMs: 0
67191
67285
  };
67192
67286
  try {
67193
- import_node_fs45.default.mkdirSync(import_node_path49.default.dirname(filePath), { recursive: true });
67287
+ import_node_fs46.default.mkdirSync(import_node_path50.default.dirname(filePath), { recursive: true });
67194
67288
  } catch {
67195
67289
  }
67196
- w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
67290
+ w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
67197
67291
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67198
67292
  this.poll(w3);
67199
67293
  });
@@ -67213,7 +67307,7 @@ var SessionObserver = class {
67213
67307
  // 读取或解析失败不阻塞 watcher 启动。
67214
67308
  hydrateMetaTail(w3, maxLines = 200) {
67215
67309
  try {
67216
- const raw = import_node_fs45.default.readFileSync(w3.filePath, "utf8");
67310
+ const raw = import_node_fs46.default.readFileSync(w3.filePath, "utf8");
67217
67311
  if (!raw) return;
67218
67312
  const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
67219
67313
  if (allLines.length === 0) return;
@@ -67237,7 +67331,7 @@ var SessionObserver = class {
67237
67331
  poll(w3) {
67238
67332
  let size = 0;
67239
67333
  try {
67240
- size = import_node_fs45.default.statSync(w3.filePath).size;
67334
+ size = import_node_fs46.default.statSync(w3.filePath).size;
67241
67335
  } catch {
67242
67336
  if (w3.sawFile) this.maybeRelocate(w3);
67243
67337
  return;
@@ -67248,11 +67342,11 @@ var SessionObserver = class {
67248
67342
  w3.buf = "";
67249
67343
  }
67250
67344
  if (size === w3.lastSize) return;
67251
- const fd = import_node_fs45.default.openSync(w3.filePath, "r");
67345
+ const fd = import_node_fs46.default.openSync(w3.filePath, "r");
67252
67346
  try {
67253
67347
  const len = size - w3.lastSize;
67254
67348
  const buf = Buffer.alloc(len);
67255
- import_node_fs45.default.readSync(fd, buf, 0, len, w3.lastSize);
67349
+ import_node_fs46.default.readSync(fd, buf, 0, len, w3.lastSize);
67256
67350
  w3.lastSize = size;
67257
67351
  w3.buf += buf.toString("utf8");
67258
67352
  let newlineIndex;
@@ -67275,7 +67369,7 @@ var SessionObserver = class {
67275
67369
  }
67276
67370
  }
67277
67371
  } finally {
67278
- import_node_fs45.default.closeSync(fd);
67372
+ import_node_fs46.default.closeSync(fd);
67279
67373
  }
67280
67374
  if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
67281
67375
  }
@@ -67285,7 +67379,7 @@ var SessionObserver = class {
67285
67379
  const now = Date.now();
67286
67380
  if (now - w3.lastRelocateScanMs < 1e3) return;
67287
67381
  w3.lastRelocateScanMs = now;
67288
- const projectsRoot = import_node_path49.default.join(this.home, ".claude", "projects");
67382
+ const projectsRoot = import_node_path50.default.join(this.home, ".claude", "projects");
67289
67383
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
67290
67384
  if (!found || found === w3.filePath) return;
67291
67385
  try {
@@ -67294,7 +67388,7 @@ var SessionObserver = class {
67294
67388
  }
67295
67389
  w3.filePath = found;
67296
67390
  try {
67297
- w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(found), { persistent: false }, (_event, changedName) => {
67391
+ w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(found), { persistent: false }, (_event, changedName) => {
67298
67392
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67299
67393
  this.poll(w3);
67300
67394
  });
@@ -67414,9 +67508,9 @@ function listRegistered() {
67414
67508
  // src/tools/title-generator.ts
67415
67509
  var import_node_child_process14 = require("child_process");
67416
67510
  init_protocol();
67417
- var import_node_fs46 = __toESM(require("fs"), 1);
67511
+ var import_node_fs47 = __toESM(require("fs"), 1);
67418
67512
  var import_node_os19 = __toESM(require("os"), 1);
67419
- var import_node_path50 = __toESM(require("path"), 1);
67513
+ var import_node_path51 = __toESM(require("path"), 1);
67420
67514
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
67421
67515
  var TITLE_INPUT_MAX_CHARS = 400;
67422
67516
  var DEFAULT_TITLE_GEN_TIMEOUT_MS = 45e3;
@@ -67507,21 +67601,21 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67507
67601
  }
67508
67602
  let workDir;
67509
67603
  try {
67510
- workDir = import_node_fs46.default.mkdtempSync(import_node_path50.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
67604
+ workDir = import_node_fs47.default.mkdtempSync(import_node_path51.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
67511
67605
  } catch {
67512
67606
  return null;
67513
67607
  }
67514
67608
  const cleanupWorkDir = () => {
67515
67609
  try {
67516
- import_node_fs46.default.rmSync(workDir, { recursive: true, force: true });
67610
+ import_node_fs47.default.rmSync(workDir, { recursive: true, force: true });
67517
67611
  } catch {
67518
67612
  }
67519
67613
  };
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");
67614
+ const outFile = import_node_path51.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
67615
+ const schemaFile = import_node_path51.default.join(workDir, "title-schema.json");
67522
67616
  if (tool === "codex") {
67523
67617
  try {
67524
- import_node_fs46.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
67618
+ import_node_fs47.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
67525
67619
  } catch {
67526
67620
  cleanupWorkDir();
67527
67621
  return null;
@@ -67576,7 +67670,7 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67576
67670
  if (tool === "claude" || tool === "pi") return finish(parseTitleJson(stdout));
67577
67671
  let fileText = "";
67578
67672
  try {
67579
- fileText = import_node_fs46.default.readFileSync(outFile, "utf8");
67673
+ fileText = import_node_fs47.default.readFileSync(outFile, "utf8");
67580
67674
  } catch {
67581
67675
  return finish(null);
67582
67676
  }
@@ -68254,8 +68348,8 @@ async function authenticate(token, deps) {
68254
68348
  }
68255
68349
 
68256
68350
  // src/legacy-cleanup.ts
68257
- var fs57 = __toESM(require("fs/promises"), 1);
68258
- var path58 = __toESM(require("path"), 1);
68351
+ var fs58 = __toESM(require("fs/promises"), 1);
68352
+ var path59 = __toESM(require("path"), 1);
68259
68353
  var LEGACY_FILES = [
68260
68354
  "personal-capability.json",
68261
68355
  "received-capabilities.json",
@@ -68264,9 +68358,9 @@ var LEGACY_FILES = [
68264
68358
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68265
68359
  const removed = [];
68266
68360
  for (const name of LEGACY_FILES) {
68267
- const p3 = path58.join(dataDir, name);
68361
+ const p3 = path59.join(dataDir, name);
68268
68362
  try {
68269
- await fs57.unlink(p3);
68363
+ await fs58.unlink(p3);
68270
68364
  removed.push(name);
68271
68365
  logger.debug("legacy capability file removed", { file: name });
68272
68366
  } catch (err) {
@@ -68278,13 +68372,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68278
68372
  }
68279
68373
 
68280
68374
  // src/inbox/inbox-store.ts
68281
- var fs58 = __toESM(require("fs"), 1);
68282
- var path59 = __toESM(require("path"), 1);
68375
+ var fs59 = __toESM(require("fs"), 1);
68376
+ var path60 = __toESM(require("path"), 1);
68283
68377
  var INBOX_SUBDIR = "inbox";
68284
68378
  var InboxStore = class {
68285
68379
  constructor(dataDir) {
68286
68380
  this.dataDir = dataDir;
68287
- fs58.mkdirSync(this.dirPath(), { recursive: true });
68381
+ fs59.mkdirSync(this.dirPath(), { recursive: true });
68288
68382
  }
68289
68383
  dataDir;
68290
68384
  /** sinceCreatedAt 缺省读全量,否则仅读时间戳更大的消息;读取失败返回空数组。 */
@@ -68292,7 +68386,7 @@ var InboxStore = class {
68292
68386
  const file = this.filePath(peerDeviceId);
68293
68387
  let raw;
68294
68388
  try {
68295
- raw = fs58.readFileSync(file, "utf8");
68389
+ raw = fs59.readFileSync(file, "utf8");
68296
68390
  } catch (err) {
68297
68391
  if (err?.code === "ENOENT") return [];
68298
68392
  return [];
@@ -68305,7 +68399,7 @@ var InboxStore = class {
68305
68399
  const dir = this.dirPath();
68306
68400
  let entries;
68307
68401
  try {
68308
- entries = fs58.readdirSync(dir);
68402
+ entries = fs59.readdirSync(dir);
68309
68403
  } catch (err) {
68310
68404
  if (err?.code === "ENOENT") return [];
68311
68405
  return [];
@@ -68318,9 +68412,9 @@ var InboxStore = class {
68318
68412
  if (existing.some((m3) => m3.id === message.id)) return;
68319
68413
  const file = this.filePath(message.peerDeviceId);
68320
68414
  const line = JSON.stringify(message) + "\n";
68321
- fs58.appendFileSync(file, line, { mode: 384 });
68415
+ fs59.appendFileSync(file, line, { mode: 384 });
68322
68416
  try {
68323
- fs58.chmodSync(file, 384);
68417
+ fs59.chmodSync(file, 384);
68324
68418
  } catch {
68325
68419
  }
68326
68420
  }
@@ -68343,7 +68437,7 @@ var InboxStore = class {
68343
68437
  removeByPeerDeviceId(peerDeviceId) {
68344
68438
  const file = this.filePath(peerDeviceId);
68345
68439
  try {
68346
- fs58.unlinkSync(file);
68440
+ fs59.unlinkSync(file);
68347
68441
  } catch (err) {
68348
68442
  if (err?.code === "ENOENT") return;
68349
68443
  }
@@ -68352,18 +68446,18 @@ var InboxStore = class {
68352
68446
  const file = this.filePath(peerDeviceId);
68353
68447
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
68354
68448
  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);
68449
+ fs59.writeFileSync(tmp, content, { mode: 384 });
68450
+ fs59.renameSync(tmp, file);
68357
68451
  try {
68358
- fs58.chmodSync(file, 384);
68452
+ fs59.chmodSync(file, 384);
68359
68453
  } catch {
68360
68454
  }
68361
68455
  }
68362
68456
  dirPath() {
68363
- return path59.join(this.dataDir, INBOX_SUBDIR);
68457
+ return path60.join(this.dataDir, INBOX_SUBDIR);
68364
68458
  }
68365
68459
  filePath(peerDeviceId) {
68366
- return path59.join(this.dirPath(), `${peerDeviceId}.jsonl`);
68460
+ return path60.join(this.dirPath(), `${peerDeviceId}.jsonl`);
68367
68461
  }
68368
68462
  };
68369
68463
  function parseAllLines(raw) {
@@ -68441,8 +68535,8 @@ var InboxManager = class {
68441
68535
  };
68442
68536
 
68443
68537
  // src/state/contact-store.ts
68444
- var fs59 = __toESM(require("fs"), 1);
68445
- var path60 = __toESM(require("path"), 1);
68538
+ var fs60 = __toESM(require("fs"), 1);
68539
+ var path61 = __toESM(require("path"), 1);
68446
68540
  var FILE_NAME = "contacts.json";
68447
68541
  var ContactStore = class {
68448
68542
  constructor(dataDir) {
@@ -68452,10 +68546,10 @@ var ContactStore = class {
68452
68546
  contacts = /* @__PURE__ */ new Map();
68453
68547
  load() {
68454
68548
  this.contacts.clear();
68455
- const file = path60.join(this.dataDir, FILE_NAME);
68549
+ const file = path61.join(this.dataDir, FILE_NAME);
68456
68550
  let raw;
68457
68551
  try {
68458
- raw = fs59.readFileSync(file, "utf8");
68552
+ raw = fs60.readFileSync(file, "utf8");
68459
68553
  } catch (err) {
68460
68554
  if (err?.code !== "ENOENT") this.renameBak(file);
68461
68555
  return;
@@ -68525,20 +68619,20 @@ var ContactStore = class {
68525
68619
  return true;
68526
68620
  }
68527
68621
  flush() {
68528
- const file = path60.join(this.dataDir, FILE_NAME);
68622
+ const file = path61.join(this.dataDir, FILE_NAME);
68529
68623
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
68530
68624
  const content = JSON.stringify(
68531
68625
  { contacts: Array.from(this.contacts.values()) },
68532
68626
  null,
68533
68627
  2
68534
68628
  );
68535
- fs59.mkdirSync(this.dataDir, { recursive: true });
68536
- fs59.writeFileSync(tmp, content, { mode: 384 });
68537
- fs59.renameSync(tmp, file);
68629
+ fs60.mkdirSync(this.dataDir, { recursive: true });
68630
+ fs60.writeFileSync(tmp, content, { mode: 384 });
68631
+ fs60.renameSync(tmp, file);
68538
68632
  }
68539
68633
  renameBak(file) {
68540
68634
  try {
68541
- fs59.renameSync(file, `${file}.bak`);
68635
+ fs60.renameSync(file, `${file}.bak`);
68542
68636
  } catch {
68543
68637
  }
68544
68638
  }
@@ -68646,61 +68740,61 @@ async function connectRemote(args) {
68646
68740
  }
68647
68741
 
68648
68742
  // src/migrations/2026-05-20-flatten-sessions.ts
68649
- var fs60 = __toESM(require("fs"), 1);
68650
- var path61 = __toESM(require("path"), 1);
68743
+ var fs61 = __toESM(require("fs"), 1);
68744
+ var path62 = __toESM(require("path"), 1);
68651
68745
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
68652
68746
  function migrateFlattenSessions(opts) {
68653
68747
  const dataDir = opts.dataDir;
68654
68748
  const now = opts.now ?? Date.now;
68655
- const sessionsDir = path61.join(dataDir, "sessions");
68656
- const flagPath = path61.join(sessionsDir, MIGRATION_FLAG_NAME);
68749
+ const sessionsDir = path62.join(dataDir, "sessions");
68750
+ const flagPath = path62.join(sessionsDir, MIGRATION_FLAG_NAME);
68657
68751
  if (existsSync3(flagPath)) {
68658
68752
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
68659
68753
  }
68660
68754
  let movedBare = 0;
68661
68755
  let movedVmOwner = 0;
68662
68756
  let archivedListener = 0;
68663
- const defaultDir = path61.join(sessionsDir, "default");
68757
+ const defaultDir = path62.join(sessionsDir, "default");
68664
68758
  if (existsSync3(defaultDir)) {
68665
68759
  for (const entry of readdirSafe(defaultDir)) {
68666
68760
  if (!entry.endsWith(".json")) continue;
68667
- const src = path61.join(defaultDir, entry);
68668
- const dst = path61.join(sessionsDir, entry);
68669
- fs60.renameSync(src, dst);
68761
+ const src = path62.join(defaultDir, entry);
68762
+ const dst = path62.join(sessionsDir, entry);
68763
+ fs61.renameSync(src, dst);
68670
68764
  movedBare += 1;
68671
68765
  }
68672
68766
  rmdirIfEmpty(defaultDir);
68673
68767
  }
68674
68768
  for (const pid of readdirSafe(sessionsDir)) {
68675
- const personaDir = path61.join(sessionsDir, pid);
68769
+ const personaDir = path62.join(sessionsDir, pid);
68676
68770
  if (!isDir(personaDir)) continue;
68677
68771
  if (pid === "default") continue;
68678
- const ownerSrc = path61.join(personaDir, "owner");
68772
+ const ownerSrc = path62.join(personaDir, "owner");
68679
68773
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
68680
- const ownerDst = path61.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68681
- fs60.mkdirSync(ownerDst, { recursive: true });
68774
+ const ownerDst = path62.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68775
+ fs61.mkdirSync(ownerDst, { recursive: true });
68682
68776
  for (const file of readdirSafe(ownerSrc)) {
68683
68777
  if (!file.endsWith(".json")) continue;
68684
- fs60.renameSync(path61.join(ownerSrc, file), path61.join(ownerDst, file));
68778
+ fs61.renameSync(path62.join(ownerSrc, file), path62.join(ownerDst, file));
68685
68779
  movedVmOwner += 1;
68686
68780
  }
68687
68781
  rmdirIfEmpty(ownerSrc);
68688
68782
  }
68689
- const listenerSrc = path61.join(personaDir, "listener");
68783
+ const listenerSrc = path62.join(personaDir, "listener");
68690
68784
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
68691
- const archiveDst = path61.join(dataDir, ".legacy", `listener-${pid}`);
68692
- fs60.mkdirSync(archiveDst, { recursive: true });
68785
+ const archiveDst = path62.join(dataDir, ".legacy", `listener-${pid}`);
68786
+ fs61.mkdirSync(archiveDst, { recursive: true });
68693
68787
  for (const file of readdirSafe(listenerSrc)) {
68694
68788
  if (!file.endsWith(".json")) continue;
68695
- fs60.renameSync(path61.join(listenerSrc, file), path61.join(archiveDst, file));
68789
+ fs61.renameSync(path62.join(listenerSrc, file), path62.join(archiveDst, file));
68696
68790
  archivedListener += 1;
68697
68791
  }
68698
68792
  rmdirIfEmpty(listenerSrc);
68699
68793
  }
68700
68794
  rmdirIfEmpty(personaDir);
68701
68795
  }
68702
- fs60.mkdirSync(sessionsDir, { recursive: true });
68703
- fs60.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68796
+ fs61.mkdirSync(sessionsDir, { recursive: true });
68797
+ fs61.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68704
68798
  return {
68705
68799
  skipped: false,
68706
68800
  flagWritten: true,
@@ -68711,7 +68805,7 @@ function migrateFlattenSessions(opts) {
68711
68805
  }
68712
68806
  function existsSync3(p3) {
68713
68807
  try {
68714
- fs60.statSync(p3);
68808
+ fs61.statSync(p3);
68715
68809
  return true;
68716
68810
  } catch {
68717
68811
  return false;
@@ -68719,62 +68813,62 @@ function existsSync3(p3) {
68719
68813
  }
68720
68814
  function isDir(p3) {
68721
68815
  try {
68722
- return fs60.statSync(p3).isDirectory();
68816
+ return fs61.statSync(p3).isDirectory();
68723
68817
  } catch {
68724
68818
  return false;
68725
68819
  }
68726
68820
  }
68727
68821
  function readdirSafe(p3) {
68728
68822
  try {
68729
- return fs60.readdirSync(p3);
68823
+ return fs61.readdirSync(p3);
68730
68824
  } catch {
68731
68825
  return [];
68732
68826
  }
68733
68827
  }
68734
68828
  function rmdirIfEmpty(p3) {
68735
68829
  try {
68736
- fs60.rmdirSync(p3);
68830
+ fs61.rmdirSync(p3);
68737
68831
  } catch {
68738
68832
  }
68739
68833
  }
68740
68834
 
68741
68835
  // src/migrations/2026-08-18-drop-seeded-projects.ts
68742
- var fs61 = __toESM(require("fs"), 1);
68743
- var path62 = __toESM(require("path"), 1);
68836
+ var fs62 = __toESM(require("fs"), 1);
68837
+ var path63 = __toESM(require("path"), 1);
68744
68838
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
68745
68839
  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");
68840
+ fs62.mkdirSync(opts.dataDir, { recursive: true });
68841
+ const flag = path63.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
68842
+ if (fs62.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
68843
+ const file = path63.join(opts.dataDir, "projects.json");
68750
68844
  let raw = null;
68751
68845
  let dropped = 0;
68752
68846
  try {
68753
- raw = fs61.readFileSync(file, "utf8");
68847
+ raw = fs62.readFileSync(file, "utf8");
68754
68848
  dropped = JSON.parse(raw).projects?.length ?? 0;
68755
68849
  } catch {
68756
68850
  }
68757
68851
  let backup = null;
68758
68852
  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);
68853
+ const dir = path63.join(opts.dataDir, "backups");
68854
+ fs62.mkdirSync(dir, { recursive: true });
68855
+ backup = path63.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
68856
+ fs62.writeFileSync(backup, raw);
68763
68857
  }
68764
68858
  if (raw != null || dropped > 0) {
68765
- fs61.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
68859
+ fs62.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
68766
68860
  }
68767
- fs61.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
68861
+ fs62.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
68768
68862
  return { skipped: false, dropped, backup };
68769
68863
  }
68770
68864
 
68771
68865
  // src/transport/http-router.ts
68772
- var import_node_fs48 = __toESM(require("fs"), 1);
68773
- var import_node_path53 = __toESM(require("path"), 1);
68866
+ var import_node_fs49 = __toESM(require("fs"), 1);
68867
+ var import_node_path54 = __toESM(require("path"), 1);
68774
68868
 
68775
68869
  // src/attachment/upload.ts
68776
- var import_node_fs47 = __toESM(require("fs"), 1);
68777
- var import_node_path51 = __toESM(require("path"), 1);
68870
+ var import_node_fs48 = __toESM(require("fs"), 1);
68871
+ var import_node_path52 = __toESM(require("path"), 1);
68778
68872
  var import_node_crypto19 = __toESM(require("crypto"), 1);
68779
68873
  var import_promises8 = require("stream/promises");
68780
68874
  var UploadError = class extends Error {
@@ -68786,22 +68880,22 @@ var UploadError = class extends Error {
68786
68880
  code;
68787
68881
  };
68788
68882
  function assertValidFileName(fileName) {
68789
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path51.default.basename(fileName)) {
68883
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path52.default.basename(fileName)) {
68790
68884
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
68791
68885
  }
68792
68886
  }
68793
68887
  var HASH_PREFIX_LEN = 16;
68794
68888
  async function writeUploadedAttachment(args) {
68795
68889
  assertValidFileName(args.fileName);
68796
- const attachmentsRoot = import_node_path51.default.join(args.baseDir, ".attachments");
68890
+ const attachmentsRoot = import_node_path52.default.join(args.baseDir, ".attachments");
68797
68891
  try {
68798
- import_node_fs47.default.mkdirSync(attachmentsRoot, { recursive: true });
68892
+ import_node_fs48.default.mkdirSync(attachmentsRoot, { recursive: true });
68799
68893
  } catch (err) {
68800
68894
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
68801
68895
  }
68802
68896
  const hasher = import_node_crypto19.default.createHash("sha256");
68803
68897
  let actualSize = 0;
68804
- const tmpPath = import_node_path51.default.join(
68898
+ const tmpPath = import_node_path52.default.join(
68805
68899
  attachmentsRoot,
68806
68900
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto19.default.randomBytes(4).toString("hex")}`
68807
68901
  );
@@ -68816,18 +68910,18 @@ async function writeUploadedAttachment(args) {
68816
68910
  yield buf;
68817
68911
  }
68818
68912
  },
68819
- import_node_fs47.default.createWriteStream(tmpPath, { mode: 384 })
68913
+ import_node_fs48.default.createWriteStream(tmpPath, { mode: 384 })
68820
68914
  );
68821
68915
  } catch (err) {
68822
68916
  try {
68823
- import_node_fs47.default.unlinkSync(tmpPath);
68917
+ import_node_fs48.default.unlinkSync(tmpPath);
68824
68918
  } catch {
68825
68919
  }
68826
68920
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
68827
68921
  }
68828
68922
  if (actualSize !== args.contentLength) {
68829
68923
  try {
68830
- import_node_fs47.default.unlinkSync(tmpPath);
68924
+ import_node_fs48.default.unlinkSync(tmpPath);
68831
68925
  } catch {
68832
68926
  }
68833
68927
  throw new UploadError(
@@ -68836,34 +68930,34 @@ async function writeUploadedAttachment(args) {
68836
68930
  );
68837
68931
  }
68838
68932
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
68839
- const hashDir = import_node_path51.default.join(attachmentsRoot, attachmentId);
68933
+ const hashDir = import_node_path52.default.join(attachmentsRoot, attachmentId);
68840
68934
  let finalFileName;
68841
68935
  let hashDirExists = false;
68842
68936
  try {
68843
- hashDirExists = import_node_fs47.default.statSync(hashDir).isDirectory();
68937
+ hashDirExists = import_node_fs48.default.statSync(hashDir).isDirectory();
68844
68938
  } catch {
68845
68939
  }
68846
68940
  if (hashDirExists) {
68847
- const existing = import_node_fs47.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68941
+ const existing = import_node_fs48.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68848
68942
  finalFileName = existing[0] ?? args.fileName;
68849
68943
  try {
68850
- import_node_fs47.default.unlinkSync(tmpPath);
68944
+ import_node_fs48.default.unlinkSync(tmpPath);
68851
68945
  } catch {
68852
68946
  }
68853
68947
  } else {
68854
68948
  try {
68855
- import_node_fs47.default.mkdirSync(hashDir, { recursive: true });
68949
+ import_node_fs48.default.mkdirSync(hashDir, { recursive: true });
68856
68950
  finalFileName = args.fileName;
68857
- import_node_fs47.default.renameSync(tmpPath, import_node_path51.default.join(hashDir, finalFileName));
68951
+ import_node_fs48.default.renameSync(tmpPath, import_node_path52.default.join(hashDir, finalFileName));
68858
68952
  } catch (err) {
68859
68953
  try {
68860
- import_node_fs47.default.unlinkSync(tmpPath);
68954
+ import_node_fs48.default.unlinkSync(tmpPath);
68861
68955
  } catch {
68862
68956
  }
68863
68957
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
68864
68958
  }
68865
68959
  }
68866
- const absPath = import_node_path51.default.join(hashDir, finalFileName);
68960
+ const absPath = import_node_path52.default.join(hashDir, finalFileName);
68867
68961
  const relPath = absPath;
68868
68962
  args.groupFileStore.upsert(args.scope, args.sessionId, {
68869
68963
  relPath: absPath,
@@ -68877,7 +68971,7 @@ async function writeUploadedAttachment(args) {
68877
68971
 
68878
68972
  // src/extension/import.ts
68879
68973
  var import_promises9 = __toESM(require("fs/promises"), 1);
68880
- var import_node_path52 = __toESM(require("path"), 1);
68974
+ var import_node_path53 = __toESM(require("path"), 1);
68881
68975
  var import_node_os20 = __toESM(require("os"), 1);
68882
68976
  var import_jszip2 = __toESM(require_lib3(), 1);
68883
68977
  var ImportError = class extends Error {
@@ -68895,7 +68989,7 @@ async function importZip(buf, root) {
68895
68989
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
68896
68990
  }
68897
68991
  for (const name of Object.keys(zip.files)) {
68898
- if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
68992
+ if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
68899
68993
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
68900
68994
  }
68901
68995
  }
@@ -68928,7 +69022,7 @@ async function importZip(buf, root) {
68928
69022
  );
68929
69023
  }
68930
69024
  }
68931
- const destDir = import_node_path52.default.join(root, manifest.id);
69025
+ const destDir = import_node_path53.default.join(root, manifest.id);
68932
69026
  let destExists = false;
68933
69027
  try {
68934
69028
  await import_promises9.default.access(destDir);
@@ -68938,15 +69032,15 @@ async function importZip(buf, root) {
68938
69032
  if (destExists) {
68939
69033
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
68940
69034
  }
68941
- const stage = await import_promises9.default.mkdtemp(import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
69035
+ const stage = await import_promises9.default.mkdtemp(import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
68942
69036
  try {
68943
69037
  for (const [name, entry] of Object.entries(zip.files)) {
68944
- const dest = import_node_path52.default.join(stage, name);
69038
+ const dest = import_node_path53.default.join(stage, name);
68945
69039
  if (entry.dir) {
68946
69040
  await import_promises9.default.mkdir(dest, { recursive: true });
68947
69041
  continue;
68948
69042
  }
68949
- await import_promises9.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
69043
+ await import_promises9.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
68950
69044
  const content = await entry.async("nodebuffer");
68951
69045
  await import_promises9.default.writeFile(dest, content);
68952
69046
  }
@@ -69000,7 +69094,7 @@ var SHARE_UI_ASSET_MIME = {
69000
69094
  ".wasm": "application/wasm"
69001
69095
  };
69002
69096
  function shareUiAssetMime(filePath) {
69003
- const ext = import_node_path53.default.extname(filePath).toLowerCase();
69097
+ const ext = import_node_path54.default.extname(filePath).toLowerCase();
69004
69098
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
69005
69099
  }
69006
69100
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -69099,7 +69193,7 @@ function isValidUploadFileName(fileName) {
69099
69193
  if (fileName === "." || fileName === "..") return false;
69100
69194
  if (fileName.startsWith(".")) return false;
69101
69195
  if (fileName.includes("/") || fileName.includes("\\")) return false;
69102
- return fileName === import_node_path53.default.basename(fileName);
69196
+ return fileName === import_node_path54.default.basename(fileName);
69103
69197
  }
69104
69198
  function createHttpRouter(deps) {
69105
69199
  return async (req, res) => {
@@ -69183,7 +69277,7 @@ function createHttpRouter(deps) {
69183
69277
  }
69184
69278
  let buf;
69185
69279
  try {
69186
- buf = await import_node_fs48.default.promises.readFile(abs);
69280
+ buf = await import_node_fs49.default.promises.readFile(abs);
69187
69281
  } catch {
69188
69282
  sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
69189
69283
  return true;
@@ -69329,7 +69423,7 @@ function createHttpRouter(deps) {
69329
69423
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
69330
69424
  return true;
69331
69425
  }
69332
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path53.default.basename(r2.absPath)));
69426
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path54.default.basename(r2.absPath)));
69333
69427
  return true;
69334
69428
  }
69335
69429
  const ctx = deps.authResolver.resolveFromHeader(
@@ -69450,7 +69544,7 @@ function createHttpRouter(deps) {
69450
69544
  return true;
69451
69545
  }
69452
69546
  let absPath;
69453
- if (import_node_path53.default.isAbsolute(pathParam)) {
69547
+ if (import_node_path54.default.isAbsolute(pathParam)) {
69454
69548
  absPath = pathParam;
69455
69549
  } else if (deps.sessionStore) {
69456
69550
  const file = deps.sessionStore.read(sid);
@@ -69458,7 +69552,7 @@ function createHttpRouter(deps) {
69458
69552
  sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
69459
69553
  return true;
69460
69554
  }
69461
- absPath = import_node_path53.default.join(file.cwd, pathParam);
69555
+ absPath = import_node_path54.default.join(file.cwd, pathParam);
69462
69556
  } else {
69463
69557
  sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
69464
69558
  return true;
@@ -69542,7 +69636,7 @@ function withCtx(ctx, body) {
69542
69636
  function streamFile(res, absPath, logger) {
69543
69637
  let stat;
69544
69638
  try {
69545
- stat = import_node_fs48.default.statSync(absPath);
69639
+ stat = import_node_fs49.default.statSync(absPath);
69546
69640
  } catch (err) {
69547
69641
  const code = err?.code;
69548
69642
  if (code === "ENOENT") {
@@ -69557,7 +69651,7 @@ function streamFile(res, absPath, logger) {
69557
69651
  return;
69558
69652
  }
69559
69653
  const mime = lookupMime(absPath);
69560
- const basename2 = import_node_path53.default.basename(absPath);
69654
+ const basename2 = import_node_path54.default.basename(absPath);
69561
69655
  res.writeHead(200, {
69562
69656
  "Content-Type": mime,
69563
69657
  "Content-Length": String(stat.size),
@@ -69565,7 +69659,7 @@ function streamFile(res, absPath, logger) {
69565
69659
  // Prevent MIME sniffing; explicit HTML MIME remains renderable.
69566
69660
  "X-Content-Type-Options": "nosniff"
69567
69661
  });
69568
- const stream = import_node_fs48.default.createReadStream(absPath);
69662
+ const stream = import_node_fs49.default.createReadStream(absPath);
69569
69663
  stream.on("error", (err) => {
69570
69664
  logger?.warn("streamFile read error", { absPath, err: err.message });
69571
69665
  res.destroy();
@@ -69574,8 +69668,8 @@ function streamFile(res, absPath, logger) {
69574
69668
  }
69575
69669
 
69576
69670
  // src/attachment/gc.ts
69577
- var import_node_fs49 = __toESM(require("fs"), 1);
69578
- var import_node_path54 = __toESM(require("path"), 1);
69671
+ var import_node_fs50 = __toESM(require("fs"), 1);
69672
+ var import_node_path55 = __toESM(require("path"), 1);
69579
69673
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
69580
69674
  function runAttachmentGc(args) {
69581
69675
  const now = (args.now ?? Date.now)();
@@ -69584,12 +69678,12 @@ function runAttachmentGc(args) {
69584
69678
  for (const { scope, sessionId } of args.sessionScopes) {
69585
69679
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
69586
69680
  if (entry.stale) continue;
69587
- if (import_node_path54.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69681
+ if (import_node_path55.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69588
69682
  }
69589
69683
  }
69590
69684
  const visited = /* @__PURE__ */ new Set();
69591
69685
  for (const { scope, sessionId } of args.sessionScopes) {
69592
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path54.default.join(
69686
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path55.default.join(
69593
69687
  args.dataDir,
69594
69688
  "sessions",
69595
69689
  ...scopeSubPath(scope).map(safeFileName),
@@ -69602,28 +69696,28 @@ function runAttachmentGc(args) {
69602
69696
  return true;
69603
69697
  });
69604
69698
  for (const rootDir of roots) {
69605
- const attRoot = import_node_path54.default.join(rootDir, ".attachments");
69699
+ const attRoot = import_node_path55.default.join(rootDir, ".attachments");
69606
69700
  let hashDirs;
69607
69701
  try {
69608
- hashDirs = import_node_fs49.default.readdirSync(attRoot);
69702
+ hashDirs = import_node_fs50.default.readdirSync(attRoot);
69609
69703
  } catch (err) {
69610
69704
  if (err.code === "ENOENT") continue;
69611
69705
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
69612
69706
  continue;
69613
69707
  }
69614
69708
  for (const hashDir of hashDirs) {
69615
- const hashDirAbs = import_node_path54.default.join(attRoot, hashDir);
69709
+ const hashDirAbs = import_node_path55.default.join(attRoot, hashDir);
69616
69710
  let files;
69617
69711
  try {
69618
- files = import_node_fs49.default.readdirSync(hashDirAbs);
69712
+ files = import_node_fs50.default.readdirSync(hashDirAbs);
69619
69713
  } catch {
69620
69714
  continue;
69621
69715
  }
69622
69716
  for (const name of files) {
69623
- const file = import_node_path54.default.join(hashDirAbs, name);
69717
+ const file = import_node_path55.default.join(hashDirAbs, name);
69624
69718
  let stat;
69625
69719
  try {
69626
- stat = import_node_fs49.default.statSync(file);
69720
+ stat = import_node_fs50.default.statSync(file);
69627
69721
  } catch {
69628
69722
  continue;
69629
69723
  }
@@ -69632,18 +69726,18 @@ function runAttachmentGc(args) {
69632
69726
  if (age < ttlMs) continue;
69633
69727
  if (liveAbs.has(file)) continue;
69634
69728
  try {
69635
- import_node_fs49.default.unlinkSync(file);
69729
+ import_node_fs50.default.unlinkSync(file);
69636
69730
  } catch (err) {
69637
69731
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
69638
69732
  }
69639
69733
  }
69640
69734
  try {
69641
- if (import_node_fs49.default.readdirSync(hashDirAbs).length === 0) import_node_fs49.default.rmdirSync(hashDirAbs);
69735
+ if (import_node_fs50.default.readdirSync(hashDirAbs).length === 0) import_node_fs50.default.rmdirSync(hashDirAbs);
69642
69736
  } catch {
69643
69737
  }
69644
69738
  }
69645
69739
  try {
69646
- if (import_node_fs49.default.readdirSync(attRoot).length === 0) import_node_fs49.default.rmdirSync(attRoot);
69740
+ if (import_node_fs50.default.readdirSync(attRoot).length === 0) import_node_fs50.default.rmdirSync(attRoot);
69647
69741
  } catch {
69648
69742
  }
69649
69743
  }
@@ -69651,8 +69745,8 @@ function runAttachmentGc(args) {
69651
69745
  }
69652
69746
 
69653
69747
  // src/attachment/group.ts
69654
- var import_node_fs50 = __toESM(require("fs"), 1);
69655
- var import_node_path55 = __toESM(require("path"), 1);
69748
+ var import_node_fs51 = __toESM(require("fs"), 1);
69749
+ var import_node_path56 = __toESM(require("path"), 1);
69656
69750
  var import_node_crypto20 = __toESM(require("crypto"), 1);
69657
69751
  init_protocol();
69658
69752
  var GroupFileStore = class {
@@ -69664,10 +69758,10 @@ var GroupFileStore = class {
69664
69758
  this.logger = opts.logger;
69665
69759
  }
69666
69760
  rootForScope(scope) {
69667
- return import_node_path55.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69761
+ return import_node_path56.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69668
69762
  }
69669
69763
  filePath(scope, sessionId) {
69670
- return import_node_path55.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69764
+ return import_node_path56.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69671
69765
  }
69672
69766
  cacheKey(scope, sessionId) {
69673
69767
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -69675,7 +69769,7 @@ var GroupFileStore = class {
69675
69769
  readFile(scope, sessionId) {
69676
69770
  const file = this.filePath(scope, sessionId);
69677
69771
  try {
69678
- const raw = import_node_fs50.default.readFileSync(file, "utf8");
69772
+ const raw = import_node_fs51.default.readFileSync(file, "utf8");
69679
69773
  const parsed = JSON.parse(raw);
69680
69774
  if (!Array.isArray(parsed)) {
69681
69775
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -69701,10 +69795,10 @@ var GroupFileStore = class {
69701
69795
  }
69702
69796
  writeFile(scope, sessionId, entries) {
69703
69797
  const file = this.filePath(scope, sessionId);
69704
- import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(file), { recursive: true });
69798
+ import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(file), { recursive: true });
69705
69799
  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);
69800
+ import_node_fs51.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
69801
+ import_node_fs51.default.renameSync(tmp, file);
69708
69802
  }
69709
69803
  list(scope, sessionId) {
69710
69804
  const key = this.cacheKey(scope, sessionId);
@@ -69768,7 +69862,7 @@ var GroupFileStore = class {
69768
69862
  /** Delete the separate manifest and cache; deleting a persona session file does not remove this store. */
69769
69863
  deleteSession(scope, sessionId) {
69770
69864
  try {
69771
- import_node_fs50.default.unlinkSync(this.filePath(scope, sessionId));
69865
+ import_node_fs51.default.unlinkSync(this.filePath(scope, sessionId));
69772
69866
  } catch (err) {
69773
69867
  if (err?.code !== "ENOENT") throw err;
69774
69868
  }
@@ -69776,7 +69870,7 @@ var GroupFileStore = class {
69776
69870
  }
69777
69871
  /** Remove all manifests and cache entries for this persona; these files live outside the persona directory. */
69778
69872
  deletePersona(personaId2) {
69779
- import_node_fs50.default.rmSync(import_node_path55.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
69873
+ import_node_fs51.default.rmSync(import_node_path56.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
69780
69874
  const prefix = `persona:${personaId2}:`;
69781
69875
  for (const key of this.cache.keys()) {
69782
69876
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -69785,10 +69879,10 @@ var GroupFileStore = class {
69785
69879
  };
69786
69880
 
69787
69881
  // src/discovery/state-file.ts
69788
- var import_node_fs51 = __toESM(require("fs"), 1);
69789
- var import_node_path56 = __toESM(require("path"), 1);
69882
+ var import_node_fs52 = __toESM(require("fs"), 1);
69883
+ var import_node_path57 = __toESM(require("path"), 1);
69790
69884
  function defaultStateFilePath(dataDir) {
69791
- return import_node_path56.default.join(dataDir, "state.json");
69885
+ return import_node_path57.default.join(dataDir, "state.json");
69792
69886
  }
69793
69887
  function isPidAlive(pid) {
69794
69888
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -69810,7 +69904,7 @@ var StateFileManager = class {
69810
69904
  }
69811
69905
  read() {
69812
69906
  try {
69813
- const raw = import_node_fs51.default.readFileSync(this.file, "utf8");
69907
+ const raw = import_node_fs52.default.readFileSync(this.file, "utf8");
69814
69908
  const parsed = JSON.parse(raw);
69815
69909
  return parsed;
69816
69910
  } catch {
@@ -69824,20 +69918,20 @@ var StateFileManager = class {
69824
69918
  return { status: "stale", existing };
69825
69919
  }
69826
69920
  write(state) {
69827
- import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
69921
+ import_node_fs52.default.mkdirSync(import_node_path57.default.dirname(this.file), { recursive: true });
69828
69922
  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);
69923
+ import_node_fs52.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
69924
+ import_node_fs52.default.renameSync(tmp, this.file);
69831
69925
  if (process.platform !== "win32") {
69832
69926
  try {
69833
- import_node_fs51.default.chmodSync(this.file, 384);
69927
+ import_node_fs52.default.chmodSync(this.file, 384);
69834
69928
  } catch {
69835
69929
  }
69836
69930
  }
69837
69931
  }
69838
69932
  delete() {
69839
69933
  try {
69840
- import_node_fs51.default.unlinkSync(this.file);
69934
+ import_node_fs52.default.unlinkSync(this.file);
69841
69935
  } catch {
69842
69936
  }
69843
69937
  }
@@ -69851,14 +69945,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
69851
69945
  }
69852
69946
 
69853
69947
  // src/tunnel/tunnel-manager.ts
69854
- var import_node_fs55 = __toESM(require("fs"), 1);
69855
- var import_node_path60 = __toESM(require("path"), 1);
69948
+ var import_node_fs56 = __toESM(require("fs"), 1);
69949
+ var import_node_path61 = __toESM(require("path"), 1);
69856
69950
  var import_node_crypto21 = __toESM(require("crypto"), 1);
69857
69951
  var import_node_child_process17 = require("child_process");
69858
69952
 
69859
69953
  // src/tunnel/tunnel-store.ts
69860
- var import_node_fs52 = __toESM(require("fs"), 1);
69861
- var import_node_path57 = __toESM(require("path"), 1);
69954
+ var import_node_fs53 = __toESM(require("fs"), 1);
69955
+ var import_node_path58 = __toESM(require("path"), 1);
69862
69956
  var TunnelStore = class {
69863
69957
  constructor(filePath) {
69864
69958
  this.filePath = filePath;
@@ -69866,7 +69960,7 @@ var TunnelStore = class {
69866
69960
  filePath;
69867
69961
  async get() {
69868
69962
  try {
69869
- const raw = await import_node_fs52.default.promises.readFile(this.filePath, "utf8");
69963
+ const raw = await import_node_fs53.default.promises.readFile(this.filePath, "utf8");
69870
69964
  const obj = JSON.parse(raw);
69871
69965
  if (!isPersistedTunnel(obj)) return null;
69872
69966
  return obj;
@@ -69877,22 +69971,22 @@ var TunnelStore = class {
69877
69971
  }
69878
69972
  }
69879
69973
  async set(v3) {
69880
- const dir = import_node_path57.default.dirname(this.filePath);
69881
- await import_node_fs52.default.promises.mkdir(dir, { recursive: true });
69974
+ const dir = import_node_path58.default.dirname(this.filePath);
69975
+ await import_node_fs53.default.promises.mkdir(dir, { recursive: true });
69882
69976
  const data = JSON.stringify(v3, null, 2);
69883
69977
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
69884
- await import_node_fs52.default.promises.writeFile(tmp, data, { mode: 384 });
69978
+ await import_node_fs53.default.promises.writeFile(tmp, data, { mode: 384 });
69885
69979
  if (process.platform !== "win32") {
69886
69980
  try {
69887
- await import_node_fs52.default.promises.chmod(tmp, 384);
69981
+ await import_node_fs53.default.promises.chmod(tmp, 384);
69888
69982
  } catch {
69889
69983
  }
69890
69984
  }
69891
- await import_node_fs52.default.promises.rename(tmp, this.filePath);
69985
+ await import_node_fs53.default.promises.rename(tmp, this.filePath);
69892
69986
  }
69893
69987
  async clear() {
69894
69988
  try {
69895
- await import_node_fs52.default.promises.unlink(this.filePath);
69989
+ await import_node_fs53.default.promises.unlink(this.filePath);
69896
69990
  } catch (err) {
69897
69991
  const code = err?.code;
69898
69992
  if (code !== "ENOENT") throw err;
@@ -69987,9 +70081,9 @@ function escape2(v3) {
69987
70081
  }
69988
70082
 
69989
70083
  // src/tunnel/frpc-binary.ts
69990
- var import_node_fs53 = __toESM(require("fs"), 1);
70084
+ var import_node_fs54 = __toESM(require("fs"), 1);
69991
70085
  var import_node_os21 = __toESM(require("os"), 1);
69992
- var import_node_path58 = __toESM(require("path"), 1);
70086
+ var import_node_path59 = __toESM(require("path"), 1);
69993
70087
  var import_node_child_process15 = require("child_process");
69994
70088
  var import_node_stream4 = require("stream");
69995
70089
  var import_promises10 = require("stream/promises");
@@ -70021,20 +70115,20 @@ function frpcDownloadUrl(version2, p3) {
70021
70115
  }
70022
70116
  async function ensureFrpcBinary(opts) {
70023
70117
  if (opts.override) {
70024
- if (!import_node_fs53.default.existsSync(opts.override)) {
70118
+ if (!import_node_fs54.default.existsSync(opts.override)) {
70025
70119
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
70026
70120
  }
70027
70121
  return opts.override;
70028
70122
  }
70029
70123
  const version2 = opts.version ?? FRPC_VERSION;
70030
70124
  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 });
70125
+ const binDir = import_node_path59.default.join(opts.dataDir, "bin");
70126
+ import_node_fs54.default.mkdirSync(binDir, { recursive: true });
70033
70127
  cleanupStaleArtifacts(binDir);
70034
- const stableBin = import_node_path58.default.join(binDir, "frpc");
70035
- if (import_node_fs53.default.existsSync(stableBin)) return stableBin;
70128
+ const stableBin = import_node_path59.default.join(binDir, "frpc");
70129
+ if (import_node_fs54.default.existsSync(stableBin)) return stableBin;
70036
70130
  const partialBin = `${stableBin}.partial`;
70037
- const tarballPath = import_node_path58.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
70131
+ const tarballPath = import_node_path59.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
70038
70132
  try {
70039
70133
  const url = frpcDownloadUrl(version2, platform);
70040
70134
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -70043,8 +70137,8 @@ async function ensureFrpcBinary(opts) {
70043
70137
  } else {
70044
70138
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
70045
70139
  }
70046
- import_node_fs53.default.chmodSync(partialBin, 493);
70047
- import_node_fs53.default.renameSync(partialBin, stableBin);
70140
+ import_node_fs54.default.chmodSync(partialBin, 493);
70141
+ import_node_fs54.default.renameSync(partialBin, stableBin);
70048
70142
  } finally {
70049
70143
  safeUnlink(tarballPath);
70050
70144
  safeUnlink(partialBin);
@@ -70054,15 +70148,15 @@ async function ensureFrpcBinary(opts) {
70054
70148
  function cleanupStaleArtifacts(binDir) {
70055
70149
  let entries;
70056
70150
  try {
70057
- entries = import_node_fs53.default.readdirSync(binDir);
70151
+ entries = import_node_fs54.default.readdirSync(binDir);
70058
70152
  } catch {
70059
70153
  return;
70060
70154
  }
70061
70155
  for (const name of entries) {
70062
70156
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
70063
- const full = import_node_path58.default.join(binDir, name);
70157
+ const full = import_node_path59.default.join(binDir, name);
70064
70158
  try {
70065
- import_node_fs53.default.rmSync(full, { recursive: true, force: true });
70159
+ import_node_fs54.default.rmSync(full, { recursive: true, force: true });
70066
70160
  } catch {
70067
70161
  }
70068
70162
  }
@@ -70070,7 +70164,7 @@ function cleanupStaleArtifacts(binDir) {
70070
70164
  }
70071
70165
  function safeUnlink(p3) {
70072
70166
  try {
70073
- import_node_fs53.default.unlinkSync(p3);
70167
+ import_node_fs54.default.unlinkSync(p3);
70074
70168
  } catch {
70075
70169
  }
70076
70170
  }
@@ -70081,13 +70175,13 @@ async function downloadToFile(url, dest, fetchImpl) {
70081
70175
  if (!res.ok || !res.body) {
70082
70176
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
70083
70177
  }
70084
- const out = import_node_fs53.default.createWriteStream(dest);
70178
+ const out = import_node_fs54.default.createWriteStream(dest);
70085
70179
  const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
70086
70180
  await (0, import_promises10.pipeline)(nodeStream, out);
70087
70181
  }
70088
70182
  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 });
70183
+ const work = import_node_path59.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
70184
+ import_node_fs54.default.mkdirSync(work, { recursive: true });
70091
70185
  try {
70092
70186
  await new Promise((resolve9, reject) => {
70093
70187
  const proc = (0, import_node_child_process15.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -70095,32 +70189,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
70095
70189
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
70096
70190
  });
70097
70191
  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)) {
70192
+ const src = import_node_path59.default.join(work, dirName, "frpc");
70193
+ if (!import_node_fs54.default.existsSync(src)) {
70100
70194
  throw new Error(`frpc not found inside tarball at ${src}`);
70101
70195
  }
70102
- import_node_fs53.default.copyFileSync(src, destBin);
70196
+ import_node_fs54.default.copyFileSync(src, destBin);
70103
70197
  } finally {
70104
- import_node_fs53.default.rmSync(work, { recursive: true, force: true });
70198
+ import_node_fs54.default.rmSync(work, { recursive: true, force: true });
70105
70199
  }
70106
70200
  }
70107
70201
 
70108
70202
  // src/tunnel/frpc-process.ts
70109
- var import_node_fs54 = __toESM(require("fs"), 1);
70110
- var import_node_path59 = __toESM(require("path"), 1);
70203
+ var import_node_fs55 = __toESM(require("fs"), 1);
70204
+ var import_node_path60 = __toESM(require("path"), 1);
70111
70205
  var import_node_child_process16 = require("child_process");
70112
70206
  function frpcPidFilePath(dataDir) {
70113
- return import_node_path59.default.join(dataDir, "frpc.pid");
70207
+ return import_node_path60.default.join(dataDir, "frpc.pid");
70114
70208
  }
70115
70209
  function writeFrpcPid(dataDir, pid) {
70116
70210
  try {
70117
- import_node_fs54.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
70211
+ import_node_fs55.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
70118
70212
  } catch {
70119
70213
  }
70120
70214
  }
70121
70215
  function clearFrpcPid(dataDir) {
70122
70216
  try {
70123
- import_node_fs54.default.unlinkSync(frpcPidFilePath(dataDir));
70217
+ import_node_fs55.default.unlinkSync(frpcPidFilePath(dataDir));
70124
70218
  } catch {
70125
70219
  }
70126
70220
  }
@@ -70136,7 +70230,7 @@ function defaultIsPidAlive(pid) {
70136
70230
  }
70137
70231
  function defaultReadPidFile(file) {
70138
70232
  try {
70139
- return import_node_fs54.default.readFileSync(file, "utf8");
70233
+ return import_node_fs55.default.readFileSync(file, "utf8");
70140
70234
  } catch {
70141
70235
  return null;
70142
70236
  }
@@ -70152,7 +70246,7 @@ function defaultSleep2(ms) {
70152
70246
  }
70153
70247
  async function killStaleFrpc(deps) {
70154
70248
  const pidFile = frpcPidFilePath(deps.dataDir);
70155
- const tomlPath = import_node_path59.default.join(deps.dataDir, "frpc.toml");
70249
+ const tomlPath = import_node_path60.default.join(deps.dataDir, "frpc.toml");
70156
70250
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
70157
70251
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
70158
70252
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -70176,7 +70270,7 @@ async function killStaleFrpc(deps) {
70176
70270
  }
70177
70271
  if (victims.size === 0) {
70178
70272
  try {
70179
- import_node_fs54.default.unlinkSync(pidFile);
70273
+ import_node_fs55.default.unlinkSync(pidFile);
70180
70274
  } catch {
70181
70275
  }
70182
70276
  return;
@@ -70187,7 +70281,7 @@ async function killStaleFrpc(deps) {
70187
70281
  }
70188
70282
  await sleep2(deps.reapWaitMs ?? 300);
70189
70283
  try {
70190
- import_node_fs54.default.unlinkSync(pidFile);
70284
+ import_node_fs55.default.unlinkSync(pidFile);
70191
70285
  } catch {
70192
70286
  }
70193
70287
  }
@@ -70224,7 +70318,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
70224
70318
  var TunnelManager = class {
70225
70319
  constructor(deps) {
70226
70320
  this.deps = deps;
70227
- this.store = deps.store ?? new TunnelStore(import_node_path60.default.join(deps.dataDir, "tunnel.json"));
70321
+ this.store = deps.store ?? new TunnelStore(import_node_path61.default.join(deps.dataDir, "tunnel.json"));
70228
70322
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
70229
70323
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
70230
70324
  }
@@ -70349,7 +70443,7 @@ var TunnelManager = class {
70349
70443
  dataDir: this.deps.dataDir,
70350
70444
  override: this.deps.frpcBinaryOverride ?? void 0
70351
70445
  });
70352
- const tomlPath = import_node_path60.default.join(this.deps.dataDir, "frpc.toml");
70446
+ const tomlPath = import_node_path61.default.join(this.deps.dataDir, "frpc.toml");
70353
70447
  const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto21.default.randomBytes(3).toString("hex")}`;
70354
70448
  const toml = buildFrpcToml({
70355
70449
  serverAddr: t2.frpsHost,
@@ -70360,14 +70454,14 @@ var TunnelManager = class {
70360
70454
  localPort,
70361
70455
  logLevel: "info"
70362
70456
  });
70363
- await import_node_fs55.default.promises.writeFile(tomlPath, toml, { mode: 384 });
70457
+ await import_node_fs56.default.promises.writeFile(tomlPath, toml, { mode: 384 });
70364
70458
  const proc = (this.deps.spawnImpl ?? import_node_child_process17.spawn)(frpcBin, ["-c", tomlPath], {
70365
70459
  stdio: ["ignore", "pipe", "pipe"]
70366
70460
  });
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 });
70461
+ const logDir = import_node_path61.default.join(this.deps.dataDir, "log");
70462
+ import_node_fs56.default.mkdirSync(logDir, { recursive: true });
70463
+ const logFilePath = import_node_path61.default.join(logDir, "frpc.log");
70464
+ const logStream = import_node_fs56.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
70371
70465
  logStream.on("error", () => {
70372
70466
  });
70373
70467
  const tee = (chunk) => {
@@ -70450,27 +70544,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
70450
70544
 
70451
70545
  // src/tunnel/device-key.ts
70452
70546
  var import_node_os22 = __toESM(require("os"), 1);
70453
- var import_node_path61 = __toESM(require("path"), 1);
70547
+ var import_node_path62 = __toESM(require("path"), 1);
70454
70548
  var import_node_crypto22 = __toESM(require("crypto"), 1);
70455
70549
  var DERIVE_SALT = "clawd-tunnel-device-v1";
70456
70550
  function deriveStableDeviceKey(opts = {}) {
70457
70551
  const hostname = opts.hostname ?? import_node_os22.default.hostname();
70458
70552
  const uid = opts.uid ?? (typeof import_node_os22.default.userInfo === "function" ? import_node_os22.default.userInfo().uid : 0);
70459
70553
  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;
70554
+ const defaultDataDir = import_node_path62.default.resolve(import_node_path62.default.join(home, ".clawd"));
70555
+ const normalizedDataDir = opts.dataDir ? import_node_path62.default.resolve(opts.dataDir) : null;
70462
70556
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
70463
70557
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
70464
70558
  return import_node_crypto22.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
70465
70559
  }
70466
70560
 
70467
70561
  // src/auth-store.ts
70468
- var import_node_fs56 = __toESM(require("fs"), 1);
70469
- var import_node_path62 = __toESM(require("path"), 1);
70562
+ var import_node_fs57 = __toESM(require("fs"), 1);
70563
+ var import_node_path63 = __toESM(require("path"), 1);
70470
70564
  var import_node_crypto23 = __toESM(require("crypto"), 1);
70471
70565
  var AUTH_FILE_NAME = "auth.json";
70472
70566
  function authFilePath(dataDir) {
70473
- return import_node_path62.default.join(dataDir, AUTH_FILE_NAME);
70567
+ return import_node_path63.default.join(dataDir, AUTH_FILE_NAME);
70474
70568
  }
70475
70569
  function loadOrCreateAuthFile(opts) {
70476
70570
  const file = authFilePath(opts.dataDir);
@@ -70511,7 +70605,7 @@ function defaultGenerateOwnerPrincipalId() {
70511
70605
  }
70512
70606
  function readAuthFile(file) {
70513
70607
  try {
70514
- const raw = import_node_fs56.default.readFileSync(file, "utf8");
70608
+ const raw = import_node_fs57.default.readFileSync(file, "utf8");
70515
70609
  const parsed = JSON.parse(raw);
70516
70610
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
70517
70611
  return null;
@@ -70532,26 +70626,26 @@ function readAuthFile(file) {
70532
70626
  }
70533
70627
  }
70534
70628
  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 });
70629
+ import_node_fs57.default.mkdirSync(import_node_path63.default.dirname(file), { recursive: true });
70630
+ import_node_fs57.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
70537
70631
  try {
70538
- import_node_fs56.default.chmodSync(file, 384);
70632
+ import_node_fs57.default.chmodSync(file, 384);
70539
70633
  } catch {
70540
70634
  }
70541
70635
  }
70542
70636
 
70543
70637
  // src/owner-profile.ts
70544
- var import_node_fs57 = __toESM(require("fs"), 1);
70638
+ var import_node_fs58 = __toESM(require("fs"), 1);
70545
70639
  var import_node_os23 = __toESM(require("os"), 1);
70546
- var import_node_path63 = __toESM(require("path"), 1);
70640
+ var import_node_path64 = __toESM(require("path"), 1);
70547
70641
  var PROFILE_FILENAME = "profile.json";
70548
70642
  function profilePath(dataDir) {
70549
- return import_node_path63.default.join(dataDir, PROFILE_FILENAME);
70643
+ return import_node_path64.default.join(dataDir, PROFILE_FILENAME);
70550
70644
  }
70551
70645
  function loadOwnerProfile(dataDir) {
70552
70646
  let raw;
70553
70647
  try {
70554
- raw = import_node_fs57.default.readFileSync(profilePath(dataDir), "utf8");
70648
+ raw = import_node_fs58.default.readFileSync(profilePath(dataDir), "utf8");
70555
70649
  } catch {
70556
70650
  return {};
70557
70651
  }
@@ -70567,7 +70661,7 @@ function loadOwnerProfile(dataDir) {
70567
70661
  }
70568
70662
  function patchOwnerProfile(dataDir, patch) {
70569
70663
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
70570
- import_node_fs57.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70664
+ import_node_fs58.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70571
70665
  return merged;
70572
70666
  }
70573
70667
  function loadOwnerDisplayName(dataDir) {
@@ -70583,18 +70677,18 @@ function loadOwnerDisplayName(dataDir) {
70583
70677
  }
70584
70678
 
70585
70679
  // 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);
70680
+ var import_node_fs59 = __toESM(require("fs"), 1);
70681
+ var import_node_path65 = __toESM(require("path"), 1);
70588
70682
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
70589
70683
  var OwnerIdentityStore = class {
70590
70684
  file;
70591
70685
  constructor(dataDir, environment = "production") {
70592
- this.file = import_node_path64.default.join(dataDir, environment === "production" ? OWNER_IDENTITY_FILE_NAME : "owner-identity.integration.json");
70686
+ this.file = import_node_path65.default.join(dataDir, environment === "production" ? OWNER_IDENTITY_FILE_NAME : "owner-identity.integration.json");
70593
70687
  }
70594
70688
  read() {
70595
70689
  let raw;
70596
70690
  try {
70597
- raw = import_node_fs58.default.readFileSync(this.file, "utf8");
70691
+ raw = import_node_fs59.default.readFileSync(this.file, "utf8");
70598
70692
  } catch {
70599
70693
  return null;
70600
70694
  }
@@ -70621,16 +70715,16 @@ var OwnerIdentityStore = class {
70621
70715
  };
70622
70716
  }
70623
70717
  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 });
70718
+ import_node_fs59.default.mkdirSync(import_node_path65.default.dirname(this.file), { recursive: true });
70719
+ import_node_fs59.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
70626
70720
  try {
70627
- import_node_fs58.default.chmodSync(this.file, 384);
70721
+ import_node_fs59.default.chmodSync(this.file, 384);
70628
70722
  } catch {
70629
70723
  }
70630
70724
  }
70631
70725
  clear() {
70632
70726
  try {
70633
- import_node_fs58.default.unlinkSync(this.file);
70727
+ import_node_fs59.default.unlinkSync(this.file);
70634
70728
  } catch (err) {
70635
70729
  const code = err?.code;
70636
70730
  if (code !== "ENOENT") throw err;
@@ -71130,8 +71224,8 @@ function verifyConnectToken(args) {
71130
71224
  }
71131
71225
 
71132
71226
  // src/feishu-auth/server-key.ts
71133
- var fs75 = __toESM(require("fs"), 1);
71134
- var path77 = __toESM(require("path"), 1);
71227
+ var fs76 = __toESM(require("fs"), 1);
71228
+ var path78 = __toESM(require("path"), 1);
71135
71229
  var FILE_NAME2 = "server-signing-key.json";
71136
71230
  var ServerKeyStore = class {
71137
71231
  constructor(dataDir) {
@@ -71139,12 +71233,12 @@ var ServerKeyStore = class {
71139
71233
  }
71140
71234
  dataDir;
71141
71235
  filePath() {
71142
- return path77.join(this.dataDir, FILE_NAME2);
71236
+ return path78.join(this.dataDir, FILE_NAME2);
71143
71237
  }
71144
71238
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
71145
71239
  read() {
71146
71240
  try {
71147
- const raw = fs75.readFileSync(this.filePath(), "utf8");
71241
+ const raw = fs76.readFileSync(this.filePath(), "utf8");
71148
71242
  const parsed = JSON.parse(raw);
71149
71243
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
71150
71244
  return parsed.publicKeyPem;
@@ -71159,12 +71253,12 @@ var ServerKeyStore = class {
71159
71253
  publicKeyPem,
71160
71254
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
71161
71255
  };
71162
- fs75.mkdirSync(this.dataDir, { recursive: true });
71163
- fs75.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
71256
+ fs76.mkdirSync(this.dataDir, { recursive: true });
71257
+ fs76.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
71164
71258
  }
71165
71259
  clear() {
71166
71260
  try {
71167
- fs75.unlinkSync(this.filePath());
71261
+ fs76.unlinkSync(this.filePath());
71168
71262
  } catch {
71169
71263
  }
71170
71264
  }
@@ -71174,19 +71268,19 @@ var ServerKeyStore = class {
71174
71268
  init_protocol();
71175
71269
 
71176
71270
  // src/handlers/index.ts
71177
- var import_node_path81 = __toESM(require("path"), 1);
71271
+ var import_node_path82 = __toESM(require("path"), 1);
71178
71272
 
71179
71273
  // src/handlers/session.ts
71180
71274
  init_protocol();
71181
71275
 
71182
71276
  // src/session/fork.ts
71183
- var import_node_fs59 = __toESM(require("fs"), 1);
71277
+ var import_node_fs60 = __toESM(require("fs"), 1);
71184
71278
  var import_node_os24 = __toESM(require("os"), 1);
71185
- var import_node_path65 = __toESM(require("path"), 1);
71279
+ var import_node_path66 = __toESM(require("path"), 1);
71186
71280
  var import_node_crypto25 = require("crypto");
71187
71281
  init_claude_history();
71188
71282
  function readJsonlEntries(file) {
71189
- const raw = import_node_fs59.default.readFileSync(file, "utf8");
71283
+ const raw = import_node_fs60.default.readFileSync(file, "utf8");
71190
71284
  const out = [];
71191
71285
  for (const line of raw.split("\n")) {
71192
71286
  const t2 = line.trim();
@@ -71199,19 +71293,19 @@ function readJsonlEntries(file) {
71199
71293
  return out;
71200
71294
  }
71201
71295
  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)) {
71296
+ const baseDir = input.baseDir ?? import_node_path66.default.join(import_node_os24.default.homedir(), ".claude");
71297
+ let projectDir = import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
71298
+ let sourceFile = import_node_path66.default.join(projectDir, `${input.toolSessionId}.jsonl`);
71299
+ if (!import_node_fs60.default.existsSync(sourceFile)) {
71206
71300
  const found = findTranscriptByToolSessionId(
71207
- import_node_path65.default.join(baseDir, "projects"),
71301
+ import_node_path66.default.join(baseDir, "projects"),
71208
71302
  input.toolSessionId
71209
71303
  );
71210
71304
  if (!found) {
71211
71305
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
71212
71306
  }
71213
71307
  sourceFile = found;
71214
- projectDir = import_node_path65.default.dirname(found);
71308
+ projectDir = import_node_path66.default.dirname(found);
71215
71309
  }
71216
71310
  const entries = readJsonlEntries(sourceFile);
71217
71311
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -71240,17 +71334,17 @@ function forkSession(input) {
71240
71334
  }
71241
71335
  forkedLines.push(JSON.stringify(forked));
71242
71336
  }
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 });
71337
+ const outDir = input.targetCwd ? import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
71338
+ const forkedFilePath = import_node_path66.default.join(outDir, `${forkedToolSessionId}.jsonl`);
71339
+ import_node_fs60.default.mkdirSync(outDir, { recursive: true });
71340
+ import_node_fs60.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
71247
71341
  return { forkedToolSessionId, forkedFilePath };
71248
71342
  }
71249
71343
 
71250
71344
  // src/tools/codex-fork.ts
71251
71345
  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);
71346
+ var import_node_fs61 = __toESM(require("fs"), 1);
71347
+ var import_node_path67 = __toESM(require("path"), 1);
71254
71348
  function openCodexAppServer(home, cwd) {
71255
71349
  const proc = (0, import_node_child_process18.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
71256
71350
  cwd,
@@ -71270,7 +71364,7 @@ function openCodexAppServer(home, cwd) {
71270
71364
  async function forkCodexThread(input, deps = {}) {
71271
71365
  const source = locateCodexThread(input.roots, input.sourceThreadId);
71272
71366
  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"));
71367
+ const rollout = parseCodexRollout(import_node_fs61.default.readFileSync(source.file, "utf8"));
71274
71368
  if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
71275
71369
  throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
71276
71370
  }
@@ -71305,7 +71399,7 @@ async function forkCodexThread(input, deps = {}) {
71305
71399
  if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
71306
71400
  throw new Error("codex fork: app-server returned no thread id");
71307
71401
  }
71308
- const forked = locateCodexThread([import_node_path66.default.join(owner2.home, "sessions")], forkedToolSessionId);
71402
+ const forked = locateCodexThread([import_node_path67.default.join(owner2.home, "sessions")], forkedToolSessionId);
71309
71403
  if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
71310
71404
  return { forkedToolSessionId, forkedFilePath: forked.file };
71311
71405
  })()]);
@@ -71316,19 +71410,19 @@ async function forkCodexThread(input, deps = {}) {
71316
71410
  }
71317
71411
 
71318
71412
  // src/session/external-scan.ts
71319
- var import_node_fs61 = __toESM(require("fs"), 1);
71413
+ var import_node_fs62 = __toESM(require("fs"), 1);
71320
71414
  var import_promises11 = __toESM(require("fs/promises"), 1);
71321
71415
  var import_node_os25 = __toESM(require("os"), 1);
71322
- var import_node_path67 = __toESM(require("path"), 1);
71416
+ var import_node_path68 = __toESM(require("path"), 1);
71323
71417
  var import_node_module = require("module");
71324
71418
  var import_node_child_process19 = require("child_process");
71325
71419
  var import_meta7 = {};
71326
71420
  function defaultRoots() {
71327
71421
  const home = import_node_os25.default.homedir();
71328
71422
  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")
71423
+ claudeProjectsDir: import_node_path68.default.join(home, ".claude", "projects"),
71424
+ codexDir: import_node_path68.default.join(home, ".codex"),
71425
+ clawdDir: import_node_path68.default.join(home, ".clawd")
71332
71426
  };
71333
71427
  }
71334
71428
  function width(s2) {
@@ -71379,7 +71473,7 @@ function userText(msg) {
71379
71473
  }
71380
71474
  function isDir2(p3) {
71381
71475
  try {
71382
- return import_node_fs61.default.statSync(p3).isDirectory();
71476
+ return import_node_fs62.default.statSync(p3).isDirectory();
71383
71477
  } catch {
71384
71478
  return false;
71385
71479
  }
@@ -71388,7 +71482,7 @@ async function scanClaude(roots) {
71388
71482
  const out = [];
71389
71483
  let dirs;
71390
71484
  try {
71391
- dirs = import_node_fs61.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
71485
+ dirs = import_node_fs62.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
71392
71486
  } catch {
71393
71487
  return out;
71394
71488
  }
@@ -71396,16 +71490,16 @@ async function scanClaude(roots) {
71396
71490
  if (!d2.isDirectory()) continue;
71397
71491
  let files;
71398
71492
  try {
71399
- files = import_node_fs61.default.readdirSync(import_node_path67.default.join(roots.claudeProjectsDir, d2.name));
71493
+ files = import_node_fs62.default.readdirSync(import_node_path68.default.join(roots.claudeProjectsDir, d2.name));
71400
71494
  } catch {
71401
71495
  continue;
71402
71496
  }
71403
71497
  for (const name of files) {
71404
71498
  if (!name.endsWith(".jsonl")) continue;
71405
- const file = import_node_path67.default.join(roots.claudeProjectsDir, d2.name, name);
71499
+ const file = import_node_path68.default.join(roots.claudeProjectsDir, d2.name, name);
71406
71500
  let st2;
71407
71501
  try {
71408
- st2 = import_node_fs61.default.statSync(file);
71502
+ st2 = import_node_fs62.default.statSync(file);
71409
71503
  } catch {
71410
71504
  continue;
71411
71505
  }
@@ -71458,7 +71552,7 @@ async function scanClaude(roots) {
71458
71552
  return out;
71459
71553
  }
71460
71554
  async function countCodexTurns(rolloutPath) {
71461
- if (!rolloutPath || !import_node_fs61.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
71555
+ if (!rolloutPath || !import_node_fs62.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
71462
71556
  let turns = 0;
71463
71557
  let first = "";
71464
71558
  for await (const rec6 of jsonLines(rolloutPath)) {
@@ -71532,7 +71626,7 @@ async function codexFromRows(rows) {
71532
71626
  async function scanCodex(roots) {
71533
71627
  let dbs = [];
71534
71628
  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));
71629
+ 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
71630
  } catch {
71537
71631
  }
71538
71632
  if (!dbs.length) return [];
@@ -71541,14 +71635,14 @@ async function scanCodex(roots) {
71541
71635
  }
71542
71636
  async function scanExternalSessions(rootsIn) {
71543
71637
  const roots = { ...defaultRoots(), ...rootsIn };
71544
- const personaRoot = import_node_path67.default.join(roots.clawdDir, "personas");
71638
+ const personaRoot = import_node_path68.default.join(roots.clawdDir, "personas");
71545
71639
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
71546
71640
  const out = [];
71547
71641
  for (const c2 of all) {
71548
71642
  if (c2.skip) continue;
71549
71643
  if (c2.turns < 1) continue;
71550
71644
  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)) {
71645
+ 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
71646
  continue;
71553
71647
  }
71554
71648
  out.push({
@@ -71565,13 +71659,13 @@ async function scanExternalSessions(rootsIn) {
71565
71659
  }
71566
71660
 
71567
71661
  // src/session/import-ledger.ts
71568
- var import_node_fs62 = __toESM(require("fs"), 1);
71569
- var import_node_path68 = __toESM(require("path"), 1);
71662
+ var import_node_fs63 = __toESM(require("fs"), 1);
71663
+ var import_node_path69 = __toESM(require("path"), 1);
71570
71664
  var LEDGER_FILENAME = "session-import-ledger.json";
71571
71665
  function readImportLedger(dataDir) {
71572
71666
  try {
71573
71667
  const parsed = JSON.parse(
71574
- import_node_fs62.default.readFileSync(import_node_path68.default.join(dataDir, LEDGER_FILENAME), "utf8")
71668
+ import_node_fs63.default.readFileSync(import_node_path69.default.join(dataDir, LEDGER_FILENAME), "utf8")
71575
71669
  );
71576
71670
  return Array.isArray(parsed) ? parsed : [];
71577
71671
  } catch {
@@ -71579,15 +71673,15 @@ function readImportLedger(dataDir) {
71579
71673
  }
71580
71674
  }
71581
71675
  function appendImportLedger(dataDir, entry) {
71582
- const file = import_node_path68.default.join(dataDir, LEDGER_FILENAME);
71676
+ const file = import_node_path69.default.join(dataDir, LEDGER_FILENAME);
71583
71677
  const entries = readImportLedger(dataDir);
71584
71678
  entries.push(entry);
71585
- import_node_fs62.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71679
+ import_node_fs63.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71586
71680
  }
71587
71681
 
71588
71682
  // src/handlers/session.ts
71589
71683
  init_protocol();
71590
- var import_node_path69 = __toESM(require("path"), 1);
71684
+ var import_node_path70 = __toESM(require("path"), 1);
71591
71685
  function canReadSearchHit(ctx, file) {
71592
71686
  if (!ctx || ctx.principal.kind === "owner") return true;
71593
71687
  return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
@@ -71868,7 +71962,7 @@ ${attribution}` } : args;
71868
71962
  `principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
71869
71963
  );
71870
71964
  }
71871
- if (source?.tool === "codex" && args.targetCwd && import_node_path69.default.resolve(args.targetCwd) !== import_node_path69.default.resolve(source.cwd)) {
71965
+ if (source?.tool === "codex" && args.targetCwd && import_node_path70.default.resolve(args.targetCwd) !== import_node_path70.default.resolve(source.cwd)) {
71872
71966
  throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
71873
71967
  }
71874
71968
  }
@@ -72145,7 +72239,7 @@ function buildPermissionHandlers(deps) {
72145
72239
  }
72146
72240
 
72147
72241
  // src/handlers/history.ts
72148
- var path84 = __toESM(require("path"), 1);
72242
+ var path85 = __toESM(require("path"), 1);
72149
72243
  init_protocol();
72150
72244
 
72151
72245
  // src/session/recent-dirs.ts
@@ -72163,7 +72257,7 @@ function listRecentDirs(store, limit = 50) {
72163
72257
  }
72164
72258
 
72165
72259
  // src/permission/persona-paths.ts
72166
- var path83 = __toESM(require("path"), 1);
72260
+ var path84 = __toESM(require("path"), 1);
72167
72261
  function getAllowedPersonaIds(grants, action) {
72168
72262
  const ids = /* @__PURE__ */ new Set();
72169
72263
  for (const g3 of grants) {
@@ -72176,42 +72270,42 @@ function getAllowedPersonaIds(grants, action) {
72176
72270
  return ids;
72177
72271
  }
72178
72272
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
72179
- const target = path83.resolve(absPath);
72273
+ const target = path84.resolve(absPath);
72180
72274
  if (userWorkDir) {
72181
- const u2 = path83.resolve(userWorkDir);
72182
- const usep = u2.endsWith(path83.sep) ? "" : path83.sep;
72275
+ const u2 = path84.resolve(userWorkDir);
72276
+ const usep = u2.endsWith(path84.sep) ? "" : path84.sep;
72183
72277
  if (target === u2 || target.startsWith(u2 + usep)) return true;
72184
72278
  }
72185
- const root = path83.resolve(personaRoot);
72186
- const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
72279
+ const root = path84.resolve(personaRoot);
72280
+ const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
72187
72281
  if (!target.startsWith(root + sep4)) return false;
72188
- const rel = path83.relative(root, target);
72282
+ const rel = path84.relative(root, target);
72189
72283
  if (!rel || rel.startsWith("..")) return false;
72190
- const personaId2 = rel.split(path83.sep)[0];
72284
+ const personaId2 = rel.split(path84.sep)[0];
72191
72285
  if (!personaId2) return false;
72192
72286
  const allowed = getAllowedPersonaIds(grants, action);
72193
72287
  if (allowed === "*") return true;
72194
72288
  return allowed.has(personaId2);
72195
72289
  }
72196
72290
  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;
72291
+ const root = path84.resolve(personaRoot);
72292
+ const target = path84.resolve(absPath);
72293
+ const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
72200
72294
  if (!target.startsWith(root + sep4)) return null;
72201
- const rel = path83.relative(root, target);
72295
+ const rel = path84.relative(root, target);
72202
72296
  if (!rel || rel.startsWith("..")) return null;
72203
- const id = rel.split(path83.sep)[0];
72297
+ const id = rel.split(path84.sep)[0];
72204
72298
  return id || null;
72205
72299
  }
72206
72300
  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;
72301
+ const d2 = path84.resolve(dir);
72302
+ const t2 = path84.resolve(absPath);
72303
+ const sep4 = d2.endsWith(path84.sep) ? "" : path84.sep;
72210
72304
  return t2 === d2 || t2.startsWith(d2 + sep4);
72211
72305
  }
72212
72306
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
72213
72307
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
72214
- return personaIdFromPath(path83.resolve(absPath), personaRoot) === personaId2;
72308
+ return personaIdFromPath(path84.resolve(absPath), personaRoot) === personaId2;
72215
72309
  }
72216
72310
 
72217
72311
  // src/handlers/history.ts
@@ -72265,7 +72359,7 @@ function buildHistoryHandlers(deps) {
72265
72359
  if (!pid) return false;
72266
72360
  return isGuestPathAllowed(
72267
72361
  ctx.grants,
72268
- path84.join(personaRoot, pid),
72362
+ path85.join(personaRoot, pid),
72269
72363
  personaRoot,
72270
72364
  "read",
72271
72365
  userWorkDir
@@ -72277,7 +72371,7 @@ function buildHistoryHandlers(deps) {
72277
72371
  };
72278
72372
  const list = async (frame, _client, ctx) => {
72279
72373
  const args = HistoryListArgs.parse(frame);
72280
- assertGuestPath(ctx, path84.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
72374
+ assertGuestPath(ctx, path85.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
72281
72375
  const sessions = await history.listSessions(args);
72282
72376
  return { response: { type: "history:list", sessions } };
72283
72377
  };
@@ -72369,14 +72463,14 @@ function buildHistoryHandlers(deps) {
72369
72463
  };
72370
72464
  const subagents = async (frame, _client, ctx) => {
72371
72465
  const args = HistorySubagentsArgs.parse(frame);
72372
- assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
72466
+ assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
72373
72467
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
72374
72468
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
72375
72469
  return { response: { type: "history:subagents", subagents: subs } };
72376
72470
  };
72377
72471
  const subagentRead = async (frame, _client, ctx) => {
72378
72472
  const args = HistorySubagentReadArgs.parse(frame);
72379
- assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
72473
+ assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
72380
72474
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
72381
72475
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
72382
72476
  return { response: { type: "history:subagent-read", ...res } };
@@ -72386,7 +72480,7 @@ function buildHistoryHandlers(deps) {
72386
72480
  if (ctx?.principal.kind === "guest" && personaRoot) {
72387
72481
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72388
72482
  const filtered = dirs.filter(
72389
- (d2) => isGuestPathAllowed(ctx.grants, path84.resolve(d2.cwd), personaRoot, "read", userWorkDir)
72483
+ (d2) => isGuestPathAllowed(ctx.grants, path85.resolve(d2.cwd), personaRoot, "read", userWorkDir)
72390
72484
  );
72391
72485
  return { response: { type: "history:recentDirs", dirs: filtered } };
72392
72486
  }
@@ -72403,17 +72497,17 @@ function buildHistoryHandlers(deps) {
72403
72497
  }
72404
72498
 
72405
72499
  // src/handlers/projects.ts
72406
- var fs80 = __toESM(require("fs"), 1);
72500
+ var fs81 = __toESM(require("fs"), 1);
72407
72501
  var os27 = __toESM(require("os"), 1);
72408
- var path85 = __toESM(require("path"), 1);
72502
+ var path86 = __toESM(require("path"), 1);
72409
72503
  var import_node_child_process20 = require("child_process");
72410
72504
  init_protocol();
72411
- var DEFAULT_PROJECTS_ROOT = path85.join(os27.homedir(), "Documents", "ChatGPT");
72505
+ var DEFAULT_PROJECTS_ROOT = path86.join(os27.homedir(), "Documents", "ChatGPT");
72412
72506
  function allocateDir(root, name) {
72413
- let candidate = path85.join(root, name);
72507
+ let candidate = path86.join(root, name);
72414
72508
  let n2 = 2;
72415
- while (fs80.existsSync(candidate)) {
72416
- candidate = path85.join(root, `${name} ${n2}`);
72509
+ while (fs81.existsSync(candidate)) {
72510
+ candidate = path86.join(root, `${name} ${n2}`);
72417
72511
  n2 += 1;
72418
72512
  }
72419
72513
  return candidate;
@@ -72441,7 +72535,7 @@ function buildProjectHandlers(deps) {
72441
72535
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
72442
72536
  }
72443
72537
  try {
72444
- if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72538
+ if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
72445
72539
  } catch {
72446
72540
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72447
72541
  }
@@ -72457,7 +72551,7 @@ function buildProjectHandlers(deps) {
72457
72551
  let target;
72458
72552
  if (args.path) {
72459
72553
  try {
72460
- if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72554
+ if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
72461
72555
  } catch {
72462
72556
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72463
72557
  }
@@ -72465,15 +72559,15 @@ function buildProjectHandlers(deps) {
72465
72559
  } else {
72466
72560
  const name = args.name;
72467
72561
  try {
72468
- fs80.mkdirSync(root, { recursive: true });
72562
+ fs81.mkdirSync(root, { recursive: true });
72469
72563
  target = allocateDir(root, name);
72470
- fs80.mkdirSync(target);
72564
+ fs81.mkdirSync(target);
72471
72565
  } catch (err) {
72472
72566
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
72473
72567
  }
72474
72568
  const git2 = (0, import_node_child_process20.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
72475
72569
  if (git2.status !== 0) {
72476
- fs80.rmSync(target, { recursive: true, force: true });
72570
+ fs81.rmSync(target, { recursive: true, force: true });
72477
72571
  throw new ClawdError(
72478
72572
  ERROR_CODES.INVALID_CWD,
72479
72573
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -72498,7 +72592,7 @@ function buildProjectHandlers(deps) {
72498
72592
  }
72499
72593
 
72500
72594
  // src/handlers/workspace.ts
72501
- var path86 = __toESM(require("path"), 1);
72595
+ var path87 = __toESM(require("path"), 1);
72502
72596
  init_protocol();
72503
72597
  var os28 = __toESM(require("os"), 1);
72504
72598
  init_protocol();
@@ -72541,22 +72635,22 @@ function buildWorkspaceHandlers(deps) {
72541
72635
  const args = WorkspaceListArgs.parse(frame);
72542
72636
  const isGuest = ctx?.principal.kind === "guest";
72543
72637
  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;
72638
+ const resolvedCwd = path87.resolve(args.cwd ?? fallbackCwd);
72639
+ const target = args.path ? path87.resolve(resolvedCwd, args.path) : resolvedCwd;
72546
72640
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
72547
72641
  const res = workspace.list({ ...args, cwd: resolvedCwd });
72548
72642
  return { response: { type: "workspace:list", ...res } };
72549
72643
  };
72550
72644
  const read = async (frame, _client, ctx) => {
72551
72645
  const args = WorkspaceReadArgs.parse(frame);
72552
- const target = path86.isAbsolute(args.path) ? path86.resolve(args.path) : path86.resolve(args.cwd, args.path);
72646
+ const target = path87.isAbsolute(args.path) ? path87.resolve(args.path) : path87.resolve(args.cwd, args.path);
72553
72647
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
72554
72648
  const res = workspace.read(args);
72555
72649
  return { response: { type: "workspace:read", ...res } };
72556
72650
  };
72557
72651
  const skillsList = async (frame, _client, ctx) => {
72558
72652
  const args = SkillsListArgs.parse(frame);
72559
- const cwdAbs = path86.resolve(args.cwd);
72653
+ const cwdAbs = path87.resolve(args.cwd);
72560
72654
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
72561
72655
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
72562
72656
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -72568,7 +72662,7 @@ function buildWorkspaceHandlers(deps) {
72568
72662
  };
72569
72663
  const agentsList = async (frame, _client, ctx) => {
72570
72664
  const args = AgentsListArgs.parse(frame);
72571
- const cwdAbs = path86.resolve(args.cwd);
72665
+ const cwdAbs = path87.resolve(args.cwd);
72572
72666
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
72573
72667
  if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
72574
72668
  return { response: { type: "agents:list", agents: [] } };
@@ -72590,20 +72684,20 @@ function buildWorkspaceHandlers(deps) {
72590
72684
  }
72591
72685
 
72592
72686
  // src/handlers/git.ts
72593
- var path88 = __toESM(require("path"), 1);
72687
+ var path89 = __toESM(require("path"), 1);
72594
72688
  init_protocol();
72595
72689
  init_protocol();
72596
72690
 
72597
72691
  // src/workspace/git.ts
72598
72692
  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);
72693
+ var import_node_fs64 = __toESM(require("fs"), 1);
72694
+ var import_node_path71 = __toESM(require("path"), 1);
72601
72695
  var import_node_util2 = require("util");
72602
72696
  var pexec = (0, import_node_util2.promisify)(import_node_child_process21.execFile);
72603
72697
  function normalizePath(p3) {
72604
- const resolved = import_node_path70.default.resolve(p3);
72698
+ const resolved = import_node_path71.default.resolve(p3);
72605
72699
  try {
72606
- return import_node_fs63.default.realpathSync(resolved);
72700
+ return import_node_fs64.default.realpathSync(resolved);
72607
72701
  } catch {
72608
72702
  return resolved;
72609
72703
  }
@@ -72677,7 +72771,7 @@ async function listGitBranches(cwd) {
72677
72771
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
72678
72772
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
72679
72773
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72680
- if (!isGuestPathAllowed(ctx.grants, path88.resolve(cwd), personaRoot, "read", userWorkDir)) {
72774
+ if (!isGuestPathAllowed(ctx.grants, path89.resolve(cwd), personaRoot, "read", userWorkDir)) {
72681
72775
  throw new ClawdError(
72682
72776
  ERROR_CODES.UNAUTHORIZED,
72683
72777
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -72934,12 +73028,12 @@ async function queryCodexAccount(deps = {}) {
72934
73028
  }
72935
73029
 
72936
73030
  // src/tools/pi-account.ts
72937
- var import_node_fs64 = __toESM(require("fs"), 1);
72938
- var import_node_path71 = __toESM(require("path"), 1);
73031
+ var import_node_fs65 = __toESM(require("fs"), 1);
73032
+ var import_node_path72 = __toESM(require("path"), 1);
72939
73033
  function readPiCredentials(agentDir) {
72940
73034
  let raw;
72941
73035
  try {
72942
- raw = JSON.parse(import_node_fs64.default.readFileSync(import_node_path71.default.join(agentDir, "auth.json"), "utf8"));
73036
+ raw = JSON.parse(import_node_fs65.default.readFileSync(import_node_path72.default.join(agentDir, "auth.json"), "utf8"));
72943
73037
  } catch {
72944
73038
  return {};
72945
73039
  }
@@ -73023,8 +73117,8 @@ function buildEngineHandlers(deps, overrides = {}) {
73023
73117
  }
73024
73118
 
73025
73119
  // src/handlers/channels.ts
73026
- var import_node_fs65 = __toESM(require("fs"), 1);
73027
- var import_node_path72 = __toESM(require("path"), 1);
73120
+ var import_node_fs66 = __toESM(require("fs"), 1);
73121
+ var import_node_path73 = __toESM(require("path"), 1);
73028
73122
  function buildChannelsHandlers(deps) {
73029
73123
  let queue = Promise.resolve();
73030
73124
  const serialized = (fn) => (frame, context) => {
@@ -73038,8 +73132,8 @@ function buildChannelsHandlers(deps) {
73038
73132
  const codexHome = resolveCodexHome2(deps.codexHome);
73039
73133
  const agentDir = resolvePiAgentDir(deps.agentDir);
73040
73134
  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;
73135
+ const restoreCodex = snapshotFile(import_node_path73.default.join(codexHome, "config.toml"));
73136
+ const restorePi = import_node_fs66.default.existsSync(agentDir) ? snapshotFile(import_node_path73.default.join(agentDir, PI_SUBSCRIPTION_FILE)) : null;
73043
73137
  let next;
73044
73138
  try {
73045
73139
  next = mutate();
@@ -74001,21 +74095,21 @@ function computeMethodAccess(args) {
74001
74095
  }
74002
74096
 
74003
74097
  // src/version.ts
74004
- var version = "0.2.644".length > 0 ? "0.2.644" : "dev";
74098
+ var version = "0.2.646".length > 0 ? "0.2.646" : "dev";
74005
74099
 
74006
74100
  // src/cli-probe/probe.ts
74007
- var fs84 = __toESM(require("fs"), 1);
74008
- var path91 = __toESM(require("path"), 1);
74101
+ var fs85 = __toESM(require("fs"), 1);
74102
+ var path92 = __toESM(require("path"), 1);
74009
74103
  var PKG_NAME = "@clawos-dev/clawd";
74010
74104
  var BIN_NAME = "clawd";
74011
74105
  var MAX_PARENT_HOPS = 5;
74012
74106
  function probeGlobalCli(pathEnv) {
74013
74107
  if (!pathEnv) return null;
74014
- for (const dir of pathEnv.split(path91.delimiter)) {
74108
+ for (const dir of pathEnv.split(path92.delimiter)) {
74015
74109
  if (!dir) continue;
74016
74110
  let real;
74017
74111
  try {
74018
- real = fs84.realpathSync(path91.join(dir, BIN_NAME));
74112
+ real = fs85.realpathSync(path92.join(dir, BIN_NAME));
74019
74113
  } catch {
74020
74114
  continue;
74021
74115
  }
@@ -74025,15 +74119,15 @@ function probeGlobalCli(pathEnv) {
74025
74119
  return null;
74026
74120
  }
74027
74121
  function readOwnPackageVersion(entryPath) {
74028
- let dir = path91.dirname(entryPath);
74122
+ let dir = path92.dirname(entryPath);
74029
74123
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
74030
74124
  try {
74031
- const raw = fs84.readFileSync(path91.join(dir, "package.json"), "utf8");
74125
+ const raw = fs85.readFileSync(path92.join(dir, "package.json"), "utf8");
74032
74126
  const pkg = JSON.parse(raw);
74033
74127
  if (pkg.name !== PKG_NAME) return null;
74034
74128
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
74035
74129
  } catch {
74036
- const parent = path91.dirname(dir);
74130
+ const parent = path92.dirname(dir);
74037
74131
  if (parent === dir) return null;
74038
74132
  dir = parent;
74039
74133
  }
@@ -74206,7 +74300,7 @@ function buildPersonaHandlers(deps) {
74206
74300
  }
74207
74301
 
74208
74302
  // src/handlers/attachment.ts
74209
- var import_node_path73 = __toESM(require("path"), 1);
74303
+ var import_node_path74 = __toESM(require("path"), 1);
74210
74304
  init_protocol();
74211
74305
  init_protocol();
74212
74306
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -74285,12 +74379,12 @@ function buildAttachmentHandlers(deps) {
74285
74379
  `session ${args.sessionId} scope unresolved`
74286
74380
  );
74287
74381
  }
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);
74382
+ const cwdAbs = import_node_path74.default.resolve(sessionFile.cwd);
74383
+ 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
74384
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
74291
74385
  const entries = deps.groupFileStore.list(scope, args.sessionId);
74292
74386
  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);
74387
+ 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
74388
  return storedAbs === candidateAbs && !e.stale;
74295
74389
  });
74296
74390
  if (!entry) {
@@ -74314,7 +74408,7 @@ function buildAttachmentHandlers(deps) {
74314
74408
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
74315
74409
  const f2 = deps.sessionStore.read(sessionId);
74316
74410
  if (!f2) return;
74317
- assertGuestAttachmentPath(ctx, import_node_path73.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
74411
+ assertGuestAttachmentPath(ctx, import_node_path74.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
74318
74412
  }
74319
74413
  const groupAdd = async (frame, _client, ctx) => {
74320
74414
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -74329,8 +74423,8 @@ function buildAttachmentHandlers(deps) {
74329
74423
  if (!scope) {
74330
74424
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
74331
74425
  }
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);
74426
+ const cwdAbs = import_node_path74.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
74427
+ 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
74428
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
74335
74429
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
74336
74430
  const size = 0;
@@ -74389,19 +74483,19 @@ function buildAttachmentHandlers(deps) {
74389
74483
 
74390
74484
  // src/handlers/extension.ts
74391
74485
  var import_promises15 = __toESM(require("fs/promises"), 1);
74392
- var import_node_path78 = __toESM(require("path"), 1);
74486
+ var import_node_path79 = __toESM(require("path"), 1);
74393
74487
  init_protocol();
74394
74488
 
74395
74489
  // src/extension/bundle-zip.ts
74396
74490
  var import_promises12 = __toESM(require("fs/promises"), 1);
74397
- var import_node_path74 = __toESM(require("path"), 1);
74491
+ var import_node_path75 = __toESM(require("path"), 1);
74398
74492
  var import_node_crypto26 = __toESM(require("crypto"), 1);
74399
74493
  var import_jszip3 = __toESM(require_lib3(), 1);
74400
74494
  async function bundleExtensionDir(dir) {
74401
74495
  const entries = await listFilesSorted(dir);
74402
74496
  const zip = new import_jszip3.default();
74403
74497
  for (const rel of entries) {
74404
- const abs = import_node_path74.default.join(dir, rel);
74498
+ const abs = import_node_path75.default.join(dir, rel);
74405
74499
  const content = await import_promises12.default.readFile(abs);
74406
74500
  zip.file(rel, content, { date: FIXED_DATE });
74407
74501
  }
@@ -74422,7 +74516,7 @@ async function listFilesSorted(rootDir) {
74422
74516
  return out;
74423
74517
  }
74424
74518
  async function walk(absRoot, relPrefix, out) {
74425
- const dirAbs = import_node_path74.default.join(absRoot, relPrefix);
74519
+ const dirAbs = import_node_path75.default.join(absRoot, relPrefix);
74426
74520
  const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
74427
74521
  for (const e of entries) {
74428
74522
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -74476,25 +74570,25 @@ function computePublishCheck(args) {
74476
74570
 
74477
74571
  // src/extension/install-flow.ts
74478
74572
  var import_promises13 = __toESM(require("fs/promises"), 1);
74479
- var import_node_path76 = __toESM(require("path"), 1);
74573
+ var import_node_path77 = __toESM(require("path"), 1);
74480
74574
  var import_node_os28 = __toESM(require("os"), 1);
74481
74575
  var import_node_crypto27 = __toESM(require("crypto"), 1);
74482
74576
  var import_jszip4 = __toESM(require_lib3(), 1);
74483
74577
 
74484
74578
  // src/extension/paths.ts
74485
74579
  var import_node_os27 = __toESM(require("os"), 1);
74486
- var import_node_path75 = __toESM(require("path"), 1);
74580
+ var import_node_path76 = __toESM(require("path"), 1);
74487
74581
  function clawdHomeRoot(override) {
74488
- return override ?? process.env.CLAWD_HOME ?? import_node_path75.default.join(import_node_os27.default.homedir(), ".clawd");
74582
+ return override ?? process.env.CLAWD_HOME ?? import_node_path76.default.join(import_node_os27.default.homedir(), ".clawd");
74489
74583
  }
74490
74584
  function extensionsRoot(override) {
74491
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions");
74585
+ return import_node_path76.default.join(clawdHomeRoot(override), "extensions");
74492
74586
  }
74493
74587
  function publishedChannelsFile(override) {
74494
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions-published.json");
74588
+ return import_node_path76.default.join(clawdHomeRoot(override), "extensions-published.json");
74495
74589
  }
74496
74590
  function bundleCacheRoot(override) {
74497
- return import_node_path75.default.join(clawdHomeRoot(override), "extension-bundles");
74591
+ return import_node_path76.default.join(clawdHomeRoot(override), "extension-bundles");
74498
74592
  }
74499
74593
 
74500
74594
  // src/extension/install-flow.ts
@@ -74521,7 +74615,7 @@ async function installFromChannel(args, deps) {
74521
74615
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74522
74616
  }
74523
74617
  for (const name of Object.keys(zip.files)) {
74524
- if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74618
+ if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74525
74619
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74526
74620
  }
74527
74621
  }
@@ -74553,7 +74647,7 @@ async function installFromChannel(args, deps) {
74553
74647
  );
74554
74648
  }
74555
74649
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
74556
- const destDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74650
+ const destDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74557
74651
  let destExists = false;
74558
74652
  try {
74559
74653
  await import_promises13.default.access(destDir);
@@ -74567,16 +74661,16 @@ async function installFromChannel(args, deps) {
74567
74661
  );
74568
74662
  }
74569
74663
  const stage = await import_promises13.default.mkdtemp(
74570
- import_node_path76.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74664
+ import_node_path77.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74571
74665
  );
74572
74666
  try {
74573
74667
  for (const [name, entry] of Object.entries(zip.files)) {
74574
- const dest = import_node_path76.default.join(stage, name);
74668
+ const dest = import_node_path77.default.join(stage, name);
74575
74669
  if (entry.dir) {
74576
74670
  await import_promises13.default.mkdir(dest, { recursive: true });
74577
74671
  continue;
74578
74672
  }
74579
- await import_promises13.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74673
+ await import_promises13.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
74580
74674
  if (name === "manifest.json") {
74581
74675
  const rewritten = { ...parsed.data, id: localExtId };
74582
74676
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74597,7 +74691,7 @@ async function installFromChannel(args, deps) {
74597
74691
 
74598
74692
  // src/extension/update-flow.ts
74599
74693
  var import_promises14 = __toESM(require("fs/promises"), 1);
74600
- var import_node_path77 = __toESM(require("path"), 1);
74694
+ var import_node_path78 = __toESM(require("path"), 1);
74601
74695
  var import_node_os29 = __toESM(require("os"), 1);
74602
74696
  var import_node_crypto28 = __toESM(require("crypto"), 1);
74603
74697
  var import_jszip5 = __toESM(require_lib3(), 1);
@@ -74614,11 +74708,11 @@ async function updateFromChannel(args, deps) {
74614
74708
  channelRef.extId,
74615
74709
  channelRef.ownerPrincipalId
74616
74710
  );
74617
- const liveDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74711
+ const liveDir = import_node_path78.default.join(deps.extensionsRoot, localExtId);
74618
74712
  const prevDir = `${liveDir}.prev`;
74619
74713
  let existingVersion;
74620
74714
  try {
74621
- const raw = await import_promises14.default.readFile(import_node_path77.default.join(liveDir, "manifest.json"), "utf8");
74715
+ const raw = await import_promises14.default.readFile(import_node_path78.default.join(liveDir, "manifest.json"), "utf8");
74622
74716
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
74623
74717
  if (!parsed2.success) {
74624
74718
  throw new UpdateError(
@@ -74651,7 +74745,7 @@ async function updateFromChannel(args, deps) {
74651
74745
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74652
74746
  }
74653
74747
  for (const name of Object.keys(zip.files)) {
74654
- if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74748
+ if (name.includes("..") || name.startsWith("/") || import_node_path78.default.isAbsolute(name)) {
74655
74749
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74656
74750
  }
74657
74751
  }
@@ -74686,16 +74780,16 @@ async function updateFromChannel(args, deps) {
74686
74780
  await import_promises14.default.rm(prevDir, { recursive: true, force: true });
74687
74781
  await import_promises14.default.rename(liveDir, prevDir);
74688
74782
  const stage = await import_promises14.default.mkdtemp(
74689
- import_node_path77.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74783
+ import_node_path78.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74690
74784
  );
74691
74785
  try {
74692
74786
  for (const [name, entry] of Object.entries(zip.files)) {
74693
- const dest = import_node_path77.default.join(stage, name);
74787
+ const dest = import_node_path78.default.join(stage, name);
74694
74788
  if (entry.dir) {
74695
74789
  await import_promises14.default.mkdir(dest, { recursive: true });
74696
74790
  continue;
74697
74791
  }
74698
- await import_promises14.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
74792
+ await import_promises14.default.mkdir(import_node_path78.default.dirname(dest), { recursive: true });
74699
74793
  if (name === "manifest.json") {
74700
74794
  const rewritten = { ...parsed.data, id: localExtId };
74701
74795
  await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74762,7 +74856,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74762
74856
  );
74763
74857
  }
74764
74858
  }
74765
- const manifestPath = import_node_path78.default.join(root, extId, "manifest.json");
74859
+ const manifestPath = import_node_path79.default.join(root, extId, "manifest.json");
74766
74860
  const manifest = await readManifest(root, extId);
74767
74861
  const next = { ...manifest, version: newVersion };
74768
74862
  const tmp = `${manifestPath}.tmp`;
@@ -74770,7 +74864,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74770
74864
  await import_promises15.default.rename(tmp, manifestPath);
74771
74865
  }
74772
74866
  async function readManifest(root, extId) {
74773
- const file = import_node_path78.default.join(root, extId, "manifest.json");
74867
+ const file = import_node_path79.default.join(root, extId, "manifest.json");
74774
74868
  let raw;
74775
74869
  try {
74776
74870
  raw = await import_promises15.default.readFile(file, "utf8");
@@ -74854,7 +74948,7 @@ function buildExtensionHandlers(deps) {
74854
74948
  };
74855
74949
  async function buildSnapshotMeta(extId) {
74856
74950
  const manifest = await readManifest(deps.root, extId);
74857
- const { sha256, buffer } = await bundleExtensionDir(import_node_path78.default.join(deps.root, extId));
74951
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path79.default.join(deps.root, extId));
74858
74952
  return { manifest, contentHash: sha256, buffer };
74859
74953
  }
74860
74954
  const publish = async (frame, _client, ctx) => {
@@ -75681,7 +75775,7 @@ function buildVisitorHandlers(deps) {
75681
75775
 
75682
75776
  // src/extension/registry.ts
75683
75777
  var import_promises17 = __toESM(require("fs/promises"), 1);
75684
- var import_node_path79 = __toESM(require("path"), 1);
75778
+ var import_node_path80 = __toESM(require("path"), 1);
75685
75779
  async function loadAll(root) {
75686
75780
  let entries;
75687
75781
  try {
@@ -75694,13 +75788,13 @@ async function loadAll(root) {
75694
75788
  for (const ent of entries) {
75695
75789
  if (!ent.isDirectory()) continue;
75696
75790
  if (ent.name.startsWith(".")) continue;
75697
- records.push(await loadOne(import_node_path79.default.join(root, ent.name), ent.name));
75791
+ records.push(await loadOne(import_node_path80.default.join(root, ent.name), ent.name));
75698
75792
  }
75699
75793
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
75700
75794
  return records;
75701
75795
  }
75702
75796
  async function loadOne(dir, dirName) {
75703
- const manifestPath = import_node_path79.default.join(dir, "manifest.json");
75797
+ const manifestPath = import_node_path80.default.join(dir, "manifest.json");
75704
75798
  let raw;
75705
75799
  try {
75706
75800
  raw = await import_promises17.default.readFile(manifestPath, "utf8");
@@ -75745,7 +75839,7 @@ async function loadOne(dir, dirName) {
75745
75839
 
75746
75840
  // src/extension/uninstall.ts
75747
75841
  var import_promises18 = __toESM(require("fs/promises"), 1);
75748
- var import_node_path80 = __toESM(require("path"), 1);
75842
+ var import_node_path81 = __toESM(require("path"), 1);
75749
75843
  var UninstallError = class extends Error {
75750
75844
  constructor(code, message) {
75751
75845
  super(message);
@@ -75754,7 +75848,7 @@ var UninstallError = class extends Error {
75754
75848
  code;
75755
75849
  };
75756
75850
  async function uninstall(deps) {
75757
- const dir = import_node_path80.default.join(deps.root, deps.extId);
75851
+ const dir = import_node_path81.default.join(deps.root, deps.extId);
75758
75852
  try {
75759
75853
  await import_promises18.default.access(dir);
75760
75854
  } catch {
@@ -75970,7 +76064,7 @@ function buildMethodHandlers(deps) {
75970
76064
  broadcast: deps.broadcastToOwners
75971
76065
  }),
75972
76066
  ...buildMasterHandlers({
75973
- authorityTablePath: import_node_path81.default.join(deps.masterDataDir, "master-authority.json")
76067
+ authorityTablePath: import_node_path82.default.join(deps.masterDataDir, "master-authority.json")
75974
76068
  }),
75975
76069
  ...buildTopicHandlers({
75976
76070
  topicStore: deps.topicStore,
@@ -76112,7 +76206,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
76112
76206
 
76113
76207
  // src/extension/runtime.ts
76114
76208
  var import_node_child_process26 = require("child_process");
76115
- var import_node_path82 = __toESM(require("path"), 1);
76209
+ var import_node_path83 = __toESM(require("path"), 1);
76116
76210
  var import_promises19 = require("timers/promises");
76117
76211
 
76118
76212
  // src/extension/port-allocator.ts
@@ -76213,7 +76307,7 @@ var Runtime = class {
76213
76307
  /\$CLAWOS_EXT_PORT/g,
76214
76308
  String(port)
76215
76309
  );
76216
- const dir = import_node_path82.default.join(this.root, extId);
76310
+ const dir = import_node_path83.default.join(this.root, extId);
76217
76311
  const env = {
76218
76312
  ...process.env,
76219
76313
  CLAWOS_EXT_PORT: String(port),
@@ -76325,7 +76419,7 @@ ${handle.stderrTail}`
76325
76419
 
76326
76420
  // src/extension/published-channels.ts
76327
76421
  var import_promises20 = __toESM(require("fs/promises"), 1);
76328
- var import_node_path83 = __toESM(require("path"), 1);
76422
+ var import_node_path84 = __toESM(require("path"), 1);
76329
76423
  init_zod();
76330
76424
  var PublishedChannelsError = class extends Error {
76331
76425
  constructor(code, message) {
@@ -76422,7 +76516,7 @@ var PublishedChannelStore = class {
76422
76516
  )
76423
76517
  };
76424
76518
  const tmp = `${this.filePath}.tmp`;
76425
- await import_promises20.default.mkdir(import_node_path83.default.dirname(this.filePath), { recursive: true });
76519
+ await import_promises20.default.mkdir(import_node_path84.default.dirname(this.filePath), { recursive: true });
76426
76520
  await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
76427
76521
  await import_promises20.default.rename(tmp, this.filePath);
76428
76522
  }
@@ -76430,7 +76524,7 @@ var PublishedChannelStore = class {
76430
76524
 
76431
76525
  // src/extension/bundle-cache.ts
76432
76526
  var import_promises21 = __toESM(require("fs/promises"), 1);
76433
- var import_node_path84 = __toESM(require("path"), 1);
76527
+ var import_node_path85 = __toESM(require("path"), 1);
76434
76528
  var BundleCache = class {
76435
76529
  constructor(rootDir) {
76436
76530
  this.rootDir = rootDir;
@@ -76439,13 +76533,13 @@ var BundleCache = class {
76439
76533
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
76440
76534
  async write(snapshotHash, buffer) {
76441
76535
  await import_promises21.default.mkdir(this.rootDir, { recursive: true });
76442
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
76536
+ const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
76443
76537
  const tmp = `${file}.tmp`;
76444
76538
  await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
76445
76539
  await import_promises21.default.rename(tmp, file);
76446
76540
  }
76447
76541
  async read(snapshotHash) {
76448
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
76542
+ const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
76449
76543
  try {
76450
76544
  return await import_promises21.default.readFile(file);
76451
76545
  } catch (e) {
@@ -76454,7 +76548,7 @@ var BundleCache = class {
76454
76548
  }
76455
76549
  }
76456
76550
  async delete(snapshotHash) {
76457
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
76551
+ const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
76458
76552
  await import_promises21.default.rm(file, { force: true });
76459
76553
  }
76460
76554
  };
@@ -76477,24 +76571,24 @@ async function startDaemon(config) {
76477
76571
  sampling: logShippingCfg.sampling,
76478
76572
  homeDir: import_node_os31.default.homedir()
76479
76573
  });
76480
- const logDir = import_node_path85.default.join(config.dataDir, "log");
76481
- import_node_fs66.default.mkdirSync(logDir, { recursive: true });
76574
+ const logDir = import_node_path86.default.join(config.dataDir, "log");
76575
+ import_node_fs67.default.mkdirSync(logDir, { recursive: true });
76482
76576
  const logger = createLogger({
76483
76577
  level: config.logLevel,
76484
- file: import_node_path85.default.join(logDir, "clawd.log"),
76578
+ file: import_node_path86.default.join(logDir, "clawd.log"),
76485
76579
  logClient
76486
76580
  });
76487
76581
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
76488
76582
  const screenIdleProbeLogger = createFileOnlyLogger({
76489
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log"),
76583
+ file: import_node_path86.default.join(logDir, "screen-idle-probe.log"),
76490
76584
  level: "debug"
76491
76585
  });
76492
76586
  logger.info("screen-idle probe logger enabled", {
76493
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log")
76587
+ file: import_node_path86.default.join(logDir, "screen-idle-probe.log")
76494
76588
  });
76495
76589
  const CAP_TARGETS = [
76496
- import_node_path85.default.join(logDir, "clawd.log"),
76497
- import_node_path85.default.join(logDir, "screen-idle-probe.log")
76590
+ import_node_path86.default.join(logDir, "clawd.log"),
76591
+ import_node_path86.default.join(logDir, "screen-idle-probe.log")
76498
76592
  ];
76499
76593
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
76500
76594
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -76610,11 +76704,11 @@ async function startDaemon(config) {
76610
76704
  const agents = new AgentsScanner();
76611
76705
  const history = new ClaudeHistoryReader();
76612
76706
  let transport = null;
76613
- const personaStore = new PersonaStore(import_node_path85.default.join(config.dataDir, "personas"));
76707
+ const personaStore = new PersonaStore(import_node_path86.default.join(config.dataDir, "personas"));
76614
76708
  const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
76615
76709
  const activeSubscriptionChannel = subscriptionChannelStore.getActive();
76616
76710
  if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
76617
- const usersRoot = import_node_path85.default.join(config.dataDir, "users");
76711
+ const usersRoot = import_node_path86.default.join(config.dataDir, "users");
76618
76712
  const defaultsRoot = findDefaultsRoot(logger);
76619
76713
  if (defaultsRoot) {
76620
76714
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -76631,7 +76725,7 @@ async function startDaemon(config) {
76631
76725
  retirePersonaBuilder({ store: personaStore, logger });
76632
76726
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
76633
76727
  const dispatchStore = createDispatchStore({
76634
- filePath: import_node_path85.default.join(config.dataDir, "dispatch.json"),
76728
+ filePath: import_node_path86.default.join(config.dataDir, "dispatch.json"),
76635
76729
  now: () => Date.now(),
76636
76730
  onFlushError: (err) => logger.error("dispatch store flush failed", {
76637
76731
  reason: err instanceof Error ? err.message : String(err)
@@ -76640,7 +76734,7 @@ async function startDaemon(config) {
76640
76734
  await dispatchStore.load();
76641
76735
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
76642
76736
  const channelStore = createChannelStore({
76643
- filePath: import_node_path85.default.join(config.dataDir, "channels.json"),
76737
+ filePath: import_node_path86.default.join(config.dataDir, "channels.json"),
76644
76738
  now: () => Date.now(),
76645
76739
  genId: () => `ch-${(0, import_node_crypto30.randomUUID)().slice(0, 8)}`,
76646
76740
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -76649,7 +76743,7 @@ async function startDaemon(config) {
76649
76743
  });
76650
76744
  await channelStore.load();
76651
76745
  const topicStore = createTopicStore({
76652
- filePath: import_node_path85.default.join(config.dataDir, "topics.json"),
76746
+ filePath: import_node_path86.default.join(config.dataDir, "topics.json"),
76653
76747
  now: () => Date.now(),
76654
76748
  genId: () => `tp-${(0, import_node_crypto30.randomUUID)().slice(0, 8)}`,
76655
76749
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -76676,12 +76770,12 @@ async function startDaemon(config) {
76676
76770
  });
76677
76771
  }
76678
76772
  });
76679
- const here = typeof __dirname === "string" ? __dirname : import_node_path85.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76773
+ const here = typeof __dirname === "string" ? __dirname : import_node_path86.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76680
76774
  const mcpConfigs = [];
76681
76775
  const secretsBundleRoot = findSecretsBundleRoot(logger);
76682
- const localSecretsDir = import_node_path85.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76776
+ const localSecretsDir = import_node_path86.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76683
76777
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
76684
- const githubTokenFile = import_node_path85.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76778
+ const githubTokenFile = import_node_path86.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76685
76779
  const githubIdentity = createGithubIdentity({
76686
76780
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
76687
76781
  store: (token) => storeGithubAuth({
@@ -76719,20 +76813,20 @@ async function startDaemon(config) {
76719
76813
  void githubIdentity.refresh();
76720
76814
  return renderPersonaMcpSecrets({
76721
76815
  personaId: personaId2,
76722
- personaDir: import_node_path85.default.join(config.dataDir, "personas", personaId2),
76816
+ personaDir: import_node_path86.default.join(config.dataDir, "personas", personaId2),
76723
76817
  secrets,
76724
- outDir: import_node_path85.default.join(config.dataDir, "persona-mcp"),
76818
+ outDir: import_node_path86.default.join(config.dataDir, "persona-mcp"),
76725
76819
  logger
76726
76820
  });
76727
76821
  };
76728
76822
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
76729
76823
  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")
76824
+ import_node_path86.default.join(here, "dispatch", "mcp-server.cjs"),
76825
+ import_node_path86.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76732
76826
  ];
76733
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76827
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76734
76828
  if (dispatchServerScriptPath) {
76735
- const dispatchLogPath = import_node_path85.default.join(logDir, "dispatch-mcp-server.log");
76829
+ const dispatchLogPath = import_node_path86.default.join(logDir, "dispatch-mcp-server.log");
76736
76830
  const dispatchCfgPath = writeDispatchMcpConfig({
76737
76831
  dataDir: config.dataDir,
76738
76832
  serverScriptPath: dispatchServerScriptPath,
@@ -76752,12 +76846,12 @@ async function startDaemon(config) {
76752
76846
  });
76753
76847
  }
76754
76848
  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")
76849
+ import_node_path86.default.join(here, "ticket", "mcp-server.cjs"),
76850
+ import_node_path86.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
76757
76851
  ];
76758
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76852
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76759
76853
  if (ticketServerScriptPath) {
76760
- const ticketLogPath = import_node_path85.default.join(logDir, "ticket-mcp-server.log");
76854
+ const ticketLogPath = import_node_path86.default.join(logDir, "ticket-mcp-server.log");
76761
76855
  const ticketCfgPath = writeTicketMcpConfig({
76762
76856
  dataDir: config.dataDir,
76763
76857
  serverScriptPath: ticketServerScriptPath,
@@ -76779,12 +76873,12 @@ async function startDaemon(config) {
76779
76873
  });
76780
76874
  }
76781
76875
  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")
76876
+ import_node_path86.default.join(here, "shift", "mcp-server.cjs"),
76877
+ import_node_path86.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
76784
76878
  ];
76785
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76879
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76786
76880
  if (shiftServerScriptPath) {
76787
- const shiftLogPath = import_node_path85.default.join(logDir, "shift-mcp-server.log");
76881
+ const shiftLogPath = import_node_path86.default.join(logDir, "shift-mcp-server.log");
76788
76882
  const shiftCfgPath = await writeShiftMcpConfig({
76789
76883
  dataDir: config.dataDir,
76790
76884
  serverScriptPath: shiftServerScriptPath,
@@ -76805,12 +76899,12 @@ async function startDaemon(config) {
76805
76899
  );
76806
76900
  }
76807
76901
  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")
76902
+ import_node_path86.default.join(here, "inbox", "mcp-server.cjs"),
76903
+ import_node_path86.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
76810
76904
  ];
76811
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76905
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76812
76906
  if (inboxServerScriptPath) {
76813
- const inboxLogPath = import_node_path85.default.join(logDir, "inbox-mcp-server.log");
76907
+ const inboxLogPath = import_node_path86.default.join(logDir, "inbox-mcp-server.log");
76814
76908
  const inboxCfgPath = await writeInboxMcpConfig({
76815
76909
  dataDir: config.dataDir,
76816
76910
  serverScriptPath: inboxServerScriptPath,
@@ -76831,10 +76925,10 @@ async function startDaemon(config) {
76831
76925
  );
76832
76926
  }
76833
76927
  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")
76928
+ import_node_path86.default.join(here, "peer-ops", "mcp-server.cjs"),
76929
+ import_node_path86.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
76836
76930
  ];
76837
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76931
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76838
76932
  if (peerOpsServerScriptPath) {
76839
76933
  const peerOpsCfgPath = writePeerOpsMcpConfig({
76840
76934
  dataDir: config.dataDir,
@@ -76854,12 +76948,12 @@ async function startDaemon(config) {
76854
76948
  );
76855
76949
  }
76856
76950
  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")
76951
+ import_node_path86.default.join(here, "rpc-tool", "mcp-server.cjs"),
76952
+ import_node_path86.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
76859
76953
  ];
76860
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76954
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
76861
76955
  if (rpcToolServerScriptPath) {
76862
- const rpcToolLogPath = import_node_path85.default.join(logDir, "rpc-tool-mcp-server.log");
76956
+ const rpcToolLogPath = import_node_path86.default.join(logDir, "rpc-tool-mcp-server.log");
76863
76957
  const rpcToolCfgPath = writeRpcToolMcpConfig({
76864
76958
  dataDir: config.dataDir,
76865
76959
  serverScriptPath: rpcToolServerScriptPath,
@@ -76880,7 +76974,7 @@ async function startDaemon(config) {
76880
76974
  );
76881
76975
  }
76882
76976
  const shiftStore = createShiftStore({
76883
- filePath: import_node_path85.default.join(config.dataDir, "shift.json"),
76977
+ filePath: import_node_path86.default.join(config.dataDir, "shift.json"),
76884
76978
  ownerIdProvider: () => ownerPrincipalId,
76885
76979
  now: () => Date.now()
76886
76980
  });
@@ -76897,7 +76991,7 @@ async function startDaemon(config) {
76897
76991
  getAdapter,
76898
76992
  historyReader: history,
76899
76993
  dataDir: config.dataDir,
76900
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76994
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
76901
76995
  // Registry defaults are read only after startup, when the later registry binding is initialized.
76902
76996
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
76903
76997
  usersRoot,
@@ -76938,10 +77032,10 @@ async function startDaemon(config) {
76938
77032
  // File edits update the group manifest without making optional stat/manifest failures fail the engine turn.
76939
77033
  attachmentGroup: {
76940
77034
  onFileEdit: (input) => {
76941
- const absPath = import_node_path85.default.isAbsolute(input.relPath) ? input.relPath : import_node_path85.default.join(input.cwd, input.relPath);
77035
+ const absPath = import_node_path86.default.isAbsolute(input.relPath) ? input.relPath : import_node_path86.default.join(input.cwd, input.relPath);
76942
77036
  let size = 0;
76943
77037
  try {
76944
- size = import_node_fs66.default.statSync(absPath).size;
77038
+ size = import_node_fs67.default.statSync(absPath).size;
76945
77039
  } catch (err) {
76946
77040
  logger.warn("attachment.onFileEdit stat failed", {
76947
77041
  sessionId: input.sessionId,
@@ -76982,9 +77076,9 @@ async function startDaemon(config) {
76982
77076
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
76983
77077
  }
76984
77078
  const projectsStore = new ProjectsStore({
76985
- file: import_node_path85.default.join(config.dataDir, "projects.json"),
77079
+ file: import_node_path86.default.join(config.dataDir, "projects.json"),
76986
77080
  clawdDir: config.dataDir,
76987
- codexStateFile: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
77081
+ codexStateFile: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
76988
77082
  logger
76989
77083
  });
76990
77084
  const observer = new SessionObserver({
@@ -77053,13 +77147,13 @@ async function startDaemon(config) {
77053
77147
  runner?.confirmCloudCancelled();
77054
77148
  });
77055
77149
  registerAdapter("claude", claudeAdapter);
77056
- const codexIsolatedHome = import_node_path85.default.join(config.dataDir, "codex-home");
77150
+ const codexIsolatedHome = import_node_path86.default.join(config.dataDir, "codex-home");
77057
77151
  try {
77058
- import_node_fs66.default.mkdirSync(codexIsolatedHome, { recursive: true });
77152
+ import_node_fs67.default.mkdirSync(codexIsolatedHome, { recursive: true });
77059
77153
  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);
77154
+ const link = import_node_path86.default.join(codexIsolatedHome, f2);
77155
+ const target = import_node_path86.default.join(import_node_os31.default.homedir(), ".codex", f2);
77156
+ if (!import_node_fs67.default.existsSync(link) && import_node_fs67.default.existsSync(target)) import_node_fs67.default.symlinkSync(target, link);
77063
77157
  }
77064
77158
  } catch (err) {
77065
77159
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -77070,16 +77164,16 @@ async function startDaemon(config) {
77070
77164
  logger,
77071
77165
  historyReader: new CodexHistoryReader({
77072
77166
  roots: codexRolloutRoots(config.dataDir),
77073
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
77167
+ sharedHome: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex"),
77074
77168
  logger
77075
77169
  }),
77076
77170
  codexHomeFor: (cwd) => resolveCodexHome({
77077
77171
  cwd,
77078
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
77172
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
77079
77173
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
77080
77174
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
77081
77175
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
77082
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
77176
+ sharedHome: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex"),
77083
77177
  isolatedHome: codexIsolatedHome
77084
77178
  }),
77085
77179
  codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
@@ -77109,10 +77203,10 @@ async function startDaemon(config) {
77109
77203
  );
77110
77204
  registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, clientForEnvironment: gatewayForEnvironment, history: cloudHistorySource, logger }));
77111
77205
  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")
77206
+ import_node_path86.default.join(here, "pi-mcp-bridge", "extension.cjs"),
77207
+ import_node_path86.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
77114
77208
  ];
77115
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
77209
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
77116
77210
  if (piMcpBridgePath) {
77117
77211
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
77118
77212
  } else {
@@ -77427,10 +77521,10 @@ async function startDaemon(config) {
77427
77521
  getSignSecret: () => authFile.token,
77428
77522
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
77429
77523
  // Guest attachment paths are guarded against persona and caller work roots.
77430
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
77524
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
77431
77525
  usersRoot
77432
77526
  },
77433
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
77527
+ personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
77434
77528
  usersRoot,
77435
77529
  getOwnerIdentity,
77436
77530
  ownerPrincipalId,
@@ -77717,7 +77811,7 @@ async function startDaemon(config) {
77717
77811
  });
77718
77812
  shiftScheduler.start();
77719
77813
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
77720
- const larkBotStore = createLarkBotBindingStore(import_node_path85.default.join(config.dataDir, "personas"));
77814
+ const larkBotStore = createLarkBotBindingStore(import_node_path86.default.join(config.dataDir, "personas"));
77721
77815
  const larkBotCloud = createLarkBotCloudClient({
77722
77816
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
77723
77817
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -77728,7 +77822,7 @@ async function startDaemon(config) {
77728
77822
  cloud: larkBotCloud,
77729
77823
  store: larkBotStore,
77730
77824
  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"),
77825
+ mediaRootFor: (chatId) => import_node_path86.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
77732
77826
  isShuttingDown: () => larkDraining,
77733
77827
  logger: {
77734
77828
  warn: (msg) => logger.warn(msg),
@@ -78027,8 +78121,8 @@ async function startDaemon(config) {
78027
78121
  const lines = [
78028
78122
  `Tunnel: ${r2.url}`,
78029
78123
  ...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")}`
78124
+ `Frpc config: ${import_node_path86.default.join(config.dataDir, "frpc.toml")}`,
78125
+ `Frpc log: ${import_node_path86.default.join(logDir, "frpc.log")}`
78032
78126
  ];
78033
78127
  const width2 = Math.max(...lines.map((l2) => l2.length));
78034
78128
  const bar = "\u2550".repeat(width2 + 4);
@@ -78041,8 +78135,8 @@ ${bar}
78041
78135
 
78042
78136
  `);
78043
78137
  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 });
78138
+ const connectPath = import_node_path86.default.join(config.dataDir, "connect.txt");
78139
+ import_node_fs67.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
78046
78140
  } catch {
78047
78141
  }
78048
78142
  } catch (err) {
@@ -78140,9 +78234,9 @@ ${bar}
78140
78234
  };
78141
78235
  }
78142
78236
  function migrateDropPersonsDir(dataDir) {
78143
- const dir = import_node_path85.default.join(dataDir, "persons");
78237
+ const dir = import_node_path86.default.join(dataDir, "persons");
78144
78238
  try {
78145
- import_node_fs66.default.rmSync(dir, { recursive: true, force: true });
78239
+ import_node_fs67.default.rmSync(dir, { recursive: true, force: true });
78146
78240
  } catch {
78147
78241
  }
78148
78242
  }