@clawos-dev/clawd 0.2.23 → 0.2.25-beta.35.0347a17
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 +249 -308
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -293,8 +293,8 @@ var require_req = __commonJS({
|
|
|
293
293
|
if (req.originalUrl) {
|
|
294
294
|
_req.url = req.originalUrl;
|
|
295
295
|
} else {
|
|
296
|
-
const
|
|
297
|
-
_req.url = typeof
|
|
296
|
+
const path17 = req.path;
|
|
297
|
+
_req.url = typeof path17 === "string" ? path17 : req.url ? req.url.path || req.url : void 0;
|
|
298
298
|
}
|
|
299
299
|
if (req.query) {
|
|
300
300
|
_req.query = req.query;
|
|
@@ -459,14 +459,14 @@ var require_redact = __commonJS({
|
|
|
459
459
|
}
|
|
460
460
|
return obj;
|
|
461
461
|
}
|
|
462
|
-
function parsePath(
|
|
462
|
+
function parsePath(path17) {
|
|
463
463
|
const parts = [];
|
|
464
464
|
let current = "";
|
|
465
465
|
let inBrackets = false;
|
|
466
466
|
let inQuotes = false;
|
|
467
467
|
let quoteChar = "";
|
|
468
|
-
for (let i = 0; i <
|
|
469
|
-
const char =
|
|
468
|
+
for (let i = 0; i < path17.length; i++) {
|
|
469
|
+
const char = path17[i];
|
|
470
470
|
if (!inBrackets && char === ".") {
|
|
471
471
|
if (current) {
|
|
472
472
|
parts.push(current);
|
|
@@ -597,10 +597,10 @@ var require_redact = __commonJS({
|
|
|
597
597
|
return current;
|
|
598
598
|
}
|
|
599
599
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
600
|
-
for (const
|
|
601
|
-
const parts = parsePath(
|
|
600
|
+
for (const path17 of paths) {
|
|
601
|
+
const parts = parsePath(path17);
|
|
602
602
|
if (parts.includes("*")) {
|
|
603
|
-
redactWildcardPath(obj, parts, censor,
|
|
603
|
+
redactWildcardPath(obj, parts, censor, path17, remove);
|
|
604
604
|
} else {
|
|
605
605
|
if (remove) {
|
|
606
606
|
removeKey(obj, parts);
|
|
@@ -685,8 +685,8 @@ var require_redact = __commonJS({
|
|
|
685
685
|
}
|
|
686
686
|
} else {
|
|
687
687
|
if (afterWildcard.includes("*")) {
|
|
688
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
689
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
688
|
+
const wrappedCensor = typeof censor === "function" ? (value, path17) => {
|
|
689
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path17];
|
|
690
690
|
return censor(value, fullPath);
|
|
691
691
|
} : censor;
|
|
692
692
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -721,8 +721,8 @@ var require_redact = __commonJS({
|
|
|
721
721
|
return null;
|
|
722
722
|
}
|
|
723
723
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
724
|
-
for (const
|
|
725
|
-
const parts = parsePath(
|
|
724
|
+
for (const path17 of pathsToClone) {
|
|
725
|
+
const parts = parsePath(path17);
|
|
726
726
|
let current = pathStructure;
|
|
727
727
|
for (let i = 0; i < parts.length; i++) {
|
|
728
728
|
const part = parts[i];
|
|
@@ -774,24 +774,24 @@ var require_redact = __commonJS({
|
|
|
774
774
|
}
|
|
775
775
|
return cloneSelectively(obj, pathStructure);
|
|
776
776
|
}
|
|
777
|
-
function validatePath(
|
|
778
|
-
if (typeof
|
|
777
|
+
function validatePath(path17) {
|
|
778
|
+
if (typeof path17 !== "string") {
|
|
779
779
|
throw new Error("Paths must be (non-empty) strings");
|
|
780
780
|
}
|
|
781
|
-
if (
|
|
781
|
+
if (path17 === "") {
|
|
782
782
|
throw new Error("Invalid redaction path ()");
|
|
783
783
|
}
|
|
784
|
-
if (
|
|
785
|
-
throw new Error(`Invalid redaction path (${
|
|
784
|
+
if (path17.includes("..")) {
|
|
785
|
+
throw new Error(`Invalid redaction path (${path17})`);
|
|
786
786
|
}
|
|
787
|
-
if (
|
|
788
|
-
throw new Error(`Invalid redaction path (${
|
|
787
|
+
if (path17.includes(",")) {
|
|
788
|
+
throw new Error(`Invalid redaction path (${path17})`);
|
|
789
789
|
}
|
|
790
790
|
let bracketCount = 0;
|
|
791
791
|
let inQuotes = false;
|
|
792
792
|
let quoteChar = "";
|
|
793
|
-
for (let i = 0; i <
|
|
794
|
-
const char =
|
|
793
|
+
for (let i = 0; i < path17.length; i++) {
|
|
794
|
+
const char = path17[i];
|
|
795
795
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
796
796
|
if (!inQuotes) {
|
|
797
797
|
inQuotes = true;
|
|
@@ -805,20 +805,20 @@ var require_redact = __commonJS({
|
|
|
805
805
|
} else if (char === "]" && !inQuotes) {
|
|
806
806
|
bracketCount--;
|
|
807
807
|
if (bracketCount < 0) {
|
|
808
|
-
throw new Error(`Invalid redaction path (${
|
|
808
|
+
throw new Error(`Invalid redaction path (${path17})`);
|
|
809
809
|
}
|
|
810
810
|
}
|
|
811
811
|
}
|
|
812
812
|
if (bracketCount !== 0) {
|
|
813
|
-
throw new Error(`Invalid redaction path (${
|
|
813
|
+
throw new Error(`Invalid redaction path (${path17})`);
|
|
814
814
|
}
|
|
815
815
|
}
|
|
816
816
|
function validatePaths(paths) {
|
|
817
817
|
if (!Array.isArray(paths)) {
|
|
818
818
|
throw new TypeError("paths must be an array");
|
|
819
819
|
}
|
|
820
|
-
for (const
|
|
821
|
-
validatePath(
|
|
820
|
+
for (const path17 of paths) {
|
|
821
|
+
validatePath(path17);
|
|
822
822
|
}
|
|
823
823
|
}
|
|
824
824
|
function slowRedact(options = {}) {
|
|
@@ -986,8 +986,8 @@ var require_redaction = __commonJS({
|
|
|
986
986
|
if (shape[k] === null) {
|
|
987
987
|
o[k] = (value) => topCensor(value, [k]);
|
|
988
988
|
} else {
|
|
989
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
990
|
-
return censor(value, [k, ...
|
|
989
|
+
const wrappedCensor = typeof censor === "function" ? (value, path17) => {
|
|
990
|
+
return censor(value, [k, ...path17]);
|
|
991
991
|
} : censor;
|
|
992
992
|
o[k] = Redact({
|
|
993
993
|
paths: shape[k],
|
|
@@ -1205,10 +1205,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
1205
1205
|
var require_sonic_boom = __commonJS({
|
|
1206
1206
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
1207
1207
|
"use strict";
|
|
1208
|
-
var
|
|
1208
|
+
var fs18 = require("fs");
|
|
1209
1209
|
var EventEmitter = require("events");
|
|
1210
1210
|
var inherits = require("util").inherits;
|
|
1211
|
-
var
|
|
1211
|
+
var path17 = require("path");
|
|
1212
1212
|
var sleep = require_atomic_sleep();
|
|
1213
1213
|
var assert = require("assert");
|
|
1214
1214
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -1262,20 +1262,20 @@ var require_sonic_boom = __commonJS({
|
|
|
1262
1262
|
const mode = sonic.mode;
|
|
1263
1263
|
if (sonic.sync) {
|
|
1264
1264
|
try {
|
|
1265
|
-
if (sonic.mkdir)
|
|
1266
|
-
const fd =
|
|
1265
|
+
if (sonic.mkdir) fs18.mkdirSync(path17.dirname(file), { recursive: true });
|
|
1266
|
+
const fd = fs18.openSync(file, flags, mode);
|
|
1267
1267
|
fileOpened(null, fd);
|
|
1268
1268
|
} catch (err) {
|
|
1269
1269
|
fileOpened(err);
|
|
1270
1270
|
throw err;
|
|
1271
1271
|
}
|
|
1272
1272
|
} else if (sonic.mkdir) {
|
|
1273
|
-
|
|
1273
|
+
fs18.mkdir(path17.dirname(file), { recursive: true }, (err) => {
|
|
1274
1274
|
if (err) return fileOpened(err);
|
|
1275
|
-
|
|
1275
|
+
fs18.open(file, flags, mode, fileOpened);
|
|
1276
1276
|
});
|
|
1277
1277
|
} else {
|
|
1278
|
-
|
|
1278
|
+
fs18.open(file, flags, mode, fileOpened);
|
|
1279
1279
|
}
|
|
1280
1280
|
}
|
|
1281
1281
|
function SonicBoom(opts) {
|
|
@@ -1316,8 +1316,8 @@ var require_sonic_boom = __commonJS({
|
|
|
1316
1316
|
this.flush = flushBuffer;
|
|
1317
1317
|
this.flushSync = flushBufferSync;
|
|
1318
1318
|
this._actualWrite = actualWriteBuffer;
|
|
1319
|
-
fsWriteSync = () =>
|
|
1320
|
-
fsWrite = () =>
|
|
1319
|
+
fsWriteSync = () => fs18.writeSync(this.fd, this._writingBuf);
|
|
1320
|
+
fsWrite = () => fs18.write(this.fd, this._writingBuf, this.release);
|
|
1321
1321
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
1322
1322
|
this._writingBuf = "";
|
|
1323
1323
|
this.write = write;
|
|
@@ -1326,15 +1326,15 @@ var require_sonic_boom = __commonJS({
|
|
|
1326
1326
|
this._actualWrite = actualWrite;
|
|
1327
1327
|
fsWriteSync = () => {
|
|
1328
1328
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
1329
|
-
return
|
|
1329
|
+
return fs18.writeSync(this.fd, this._writingBuf);
|
|
1330
1330
|
}
|
|
1331
|
-
return
|
|
1331
|
+
return fs18.writeSync(this.fd, this._writingBuf, "utf8");
|
|
1332
1332
|
};
|
|
1333
1333
|
fsWrite = () => {
|
|
1334
1334
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
1335
|
-
return
|
|
1335
|
+
return fs18.write(this.fd, this._writingBuf, this.release);
|
|
1336
1336
|
}
|
|
1337
|
-
return
|
|
1337
|
+
return fs18.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
1338
1338
|
};
|
|
1339
1339
|
} else {
|
|
1340
1340
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -1391,7 +1391,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
1393
1393
|
if (this._fsync) {
|
|
1394
|
-
|
|
1394
|
+
fs18.fsyncSync(this.fd);
|
|
1395
1395
|
}
|
|
1396
1396
|
const len = this._len;
|
|
1397
1397
|
if (this._reopening) {
|
|
@@ -1505,7 +1505,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1505
1505
|
const onDrain = () => {
|
|
1506
1506
|
if (!this._fsync) {
|
|
1507
1507
|
try {
|
|
1508
|
-
|
|
1508
|
+
fs18.fsync(this.fd, (err) => {
|
|
1509
1509
|
this._flushPending = false;
|
|
1510
1510
|
cb(err);
|
|
1511
1511
|
});
|
|
@@ -1607,7 +1607,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1607
1607
|
const fd = this.fd;
|
|
1608
1608
|
this.once("ready", () => {
|
|
1609
1609
|
if (fd !== this.fd) {
|
|
1610
|
-
|
|
1610
|
+
fs18.close(fd, (err) => {
|
|
1611
1611
|
if (err) {
|
|
1612
1612
|
return this.emit("error", err);
|
|
1613
1613
|
}
|
|
@@ -1656,7 +1656,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1656
1656
|
buf = this._bufs[0];
|
|
1657
1657
|
}
|
|
1658
1658
|
try {
|
|
1659
|
-
const n = Buffer.isBuffer(buf) ?
|
|
1659
|
+
const n = Buffer.isBuffer(buf) ? fs18.writeSync(this.fd, buf) : fs18.writeSync(this.fd, buf, "utf8");
|
|
1660
1660
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
1661
1661
|
buf = releasedBufObj.writingBuf;
|
|
1662
1662
|
this._len = releasedBufObj.len;
|
|
@@ -1672,7 +1672,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1672
1672
|
}
|
|
1673
1673
|
}
|
|
1674
1674
|
try {
|
|
1675
|
-
|
|
1675
|
+
fs18.fsyncSync(this.fd);
|
|
1676
1676
|
} catch {
|
|
1677
1677
|
}
|
|
1678
1678
|
}
|
|
@@ -1693,7 +1693,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1693
1693
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
1694
1694
|
}
|
|
1695
1695
|
try {
|
|
1696
|
-
const n =
|
|
1696
|
+
const n = fs18.writeSync(this.fd, buf);
|
|
1697
1697
|
buf = buf.subarray(n);
|
|
1698
1698
|
this._len = Math.max(this._len - n, 0);
|
|
1699
1699
|
if (buf.length <= 0) {
|
|
@@ -1721,13 +1721,13 @@ var require_sonic_boom = __commonJS({
|
|
|
1721
1721
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
1722
1722
|
if (this.sync) {
|
|
1723
1723
|
try {
|
|
1724
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
1724
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs18.writeSync(this.fd, this._writingBuf) : fs18.writeSync(this.fd, this._writingBuf, "utf8");
|
|
1725
1725
|
release(null, written);
|
|
1726
1726
|
} catch (err) {
|
|
1727
1727
|
release(err);
|
|
1728
1728
|
}
|
|
1729
1729
|
} else {
|
|
1730
|
-
|
|
1730
|
+
fs18.write(this.fd, this._writingBuf, release);
|
|
1731
1731
|
}
|
|
1732
1732
|
}
|
|
1733
1733
|
function actualWriteBuffer() {
|
|
@@ -1736,7 +1736,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1736
1736
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
1737
1737
|
if (this.sync) {
|
|
1738
1738
|
try {
|
|
1739
|
-
const written =
|
|
1739
|
+
const written = fs18.writeSync(this.fd, this._writingBuf);
|
|
1740
1740
|
release(null, written);
|
|
1741
1741
|
} catch (err) {
|
|
1742
1742
|
release(err);
|
|
@@ -1745,7 +1745,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1745
1745
|
if (kCopyBuffer) {
|
|
1746
1746
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
1747
1747
|
}
|
|
1748
|
-
|
|
1748
|
+
fs18.write(this.fd, this._writingBuf, release);
|
|
1749
1749
|
}
|
|
1750
1750
|
}
|
|
1751
1751
|
function actualClose(sonic) {
|
|
@@ -1761,12 +1761,12 @@ var require_sonic_boom = __commonJS({
|
|
|
1761
1761
|
sonic._lens = [];
|
|
1762
1762
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
1763
1763
|
try {
|
|
1764
|
-
|
|
1764
|
+
fs18.fsync(sonic.fd, closeWrapped);
|
|
1765
1765
|
} catch {
|
|
1766
1766
|
}
|
|
1767
1767
|
function closeWrapped() {
|
|
1768
1768
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
1769
|
-
|
|
1769
|
+
fs18.close(sonic.fd, done);
|
|
1770
1770
|
} else {
|
|
1771
1771
|
done();
|
|
1772
1772
|
}
|
|
@@ -8075,8 +8075,8 @@ Env (advanced):
|
|
|
8075
8075
|
`;
|
|
8076
8076
|
|
|
8077
8077
|
// src/index.ts
|
|
8078
|
-
var
|
|
8079
|
-
var
|
|
8078
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
8079
|
+
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
8080
8080
|
|
|
8081
8081
|
// src/logger.ts
|
|
8082
8082
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
@@ -8686,8 +8686,8 @@ function getErrorMap() {
|
|
|
8686
8686
|
|
|
8687
8687
|
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
8688
8688
|
var makeIssue = (params) => {
|
|
8689
|
-
const { data, path:
|
|
8690
|
-
const fullPath = [...
|
|
8689
|
+
const { data, path: path17, errorMaps, issueData } = params;
|
|
8690
|
+
const fullPath = [...path17, ...issueData.path || []];
|
|
8691
8691
|
const fullIssue = {
|
|
8692
8692
|
...issueData,
|
|
8693
8693
|
path: fullPath
|
|
@@ -8803,11 +8803,11 @@ var errorUtil;
|
|
|
8803
8803
|
|
|
8804
8804
|
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
8805
8805
|
var ParseInputLazyPath = class {
|
|
8806
|
-
constructor(parent, value,
|
|
8806
|
+
constructor(parent, value, path17, key) {
|
|
8807
8807
|
this._cachedPath = [];
|
|
8808
8808
|
this.parent = parent;
|
|
8809
8809
|
this.data = value;
|
|
8810
|
-
this._path =
|
|
8810
|
+
this._path = path17;
|
|
8811
8811
|
this._key = key;
|
|
8812
8812
|
}
|
|
8813
8813
|
get path() {
|
|
@@ -12812,7 +12812,7 @@ var SessionStore = class {
|
|
|
12812
12812
|
};
|
|
12813
12813
|
|
|
12814
12814
|
// src/session/manager.ts
|
|
12815
|
-
var
|
|
12815
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
12816
12816
|
|
|
12817
12817
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
12818
12818
|
var byteToHex = [];
|
|
@@ -13401,56 +13401,16 @@ function reduceSession(state, input, deps) {
|
|
|
13401
13401
|
}
|
|
13402
13402
|
}
|
|
13403
13403
|
|
|
13404
|
-
// src/
|
|
13405
|
-
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
|
|
13409
|
-
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
if (!opts.dataDir) return null;
|
|
13413
|
-
if (!opts.sessionId || opts.sessionId.includes("..") || opts.sessionId.includes("/") || opts.sessionId.includes("\\") || opts.sessionId.startsWith(".")) {
|
|
13414
|
-
return null;
|
|
13404
|
+
// src/session/stdout-splitter.ts
|
|
13405
|
+
function splitStdoutChunk(buf, chunk) {
|
|
13406
|
+
let next = buf + (typeof chunk === "string" ? chunk : chunk.toString("utf8"));
|
|
13407
|
+
const lines = [];
|
|
13408
|
+
let idx;
|
|
13409
|
+
while ((idx = next.indexOf("\n")) >= 0) {
|
|
13410
|
+
lines.push(next.slice(0, idx));
|
|
13411
|
+
next = next.slice(idx + 1);
|
|
13415
13412
|
}
|
|
13416
|
-
|
|
13417
|
-
const dir = import_node_path4.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
|
|
13418
|
-
const filePath = import_node_path4.default.join(dir, `${tsForFilename(now())}.jsonl`);
|
|
13419
|
-
let stream = null;
|
|
13420
|
-
let closedResolve;
|
|
13421
|
-
const closed = new Promise((resolve) => {
|
|
13422
|
-
closedResolve = resolve;
|
|
13423
|
-
});
|
|
13424
|
-
let exited = false;
|
|
13425
|
-
const ensureStream = () => {
|
|
13426
|
-
if (stream) return stream;
|
|
13427
|
-
import_node_fs4.default.mkdirSync(dir, { recursive: true });
|
|
13428
|
-
stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
|
|
13429
|
-
stream.on("close", () => closedResolve());
|
|
13430
|
-
return stream;
|
|
13431
|
-
};
|
|
13432
|
-
const writeLine = (s, chunk) => {
|
|
13433
|
-
if (exited) return;
|
|
13434
|
-
const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
13435
|
-
const line = JSON.stringify({ ts: now(), stream: s, chunk: text }) + "\n";
|
|
13436
|
-
ensureStream().write(line);
|
|
13437
|
-
};
|
|
13438
|
-
opts.proc.stdout?.on("data", (chunk) => writeLine("stdout", chunk));
|
|
13439
|
-
opts.proc.stderr?.on("data", (chunk) => writeLine("stderr", chunk));
|
|
13440
|
-
opts.proc.on("exit", () => {
|
|
13441
|
-
exited = true;
|
|
13442
|
-
if (stream) {
|
|
13443
|
-
stream.end();
|
|
13444
|
-
} else {
|
|
13445
|
-
closedResolve();
|
|
13446
|
-
}
|
|
13447
|
-
});
|
|
13448
|
-
return {
|
|
13449
|
-
tapStdinWrite(chunk) {
|
|
13450
|
-
writeLine("stdin", chunk);
|
|
13451
|
-
},
|
|
13452
|
-
closed
|
|
13453
|
-
};
|
|
13413
|
+
return { newBuf: next, lines };
|
|
13454
13414
|
}
|
|
13455
13415
|
|
|
13456
13416
|
// src/session/runner.ts
|
|
@@ -13483,8 +13443,6 @@ var SessionRunner = class {
|
|
|
13483
13443
|
pendingControlRequests = /* @__PURE__ */ new Map();
|
|
13484
13444
|
// waitUntilStopped 排队的 resolve 回调;reducer 把 procAlive 翻成 false 后批量触发
|
|
13485
13445
|
stopWaiters = [];
|
|
13486
|
-
// IPC recorder(CLAWD_RECORD_IPC=1 时启用);null 表示当前 spawn 未启用 / 已退出
|
|
13487
|
-
recorder = null;
|
|
13488
13446
|
getState() {
|
|
13489
13447
|
return this.state;
|
|
13490
13448
|
}
|
|
@@ -13574,7 +13532,6 @@ var SessionRunner = class {
|
|
|
13574
13532
|
this.pendingControlRequests.set(requestId, { resolve, reject, timer });
|
|
13575
13533
|
try {
|
|
13576
13534
|
proc.stdin?.write(payload);
|
|
13577
|
-
this.recorder?.tapStdinWrite(payload);
|
|
13578
13535
|
} catch (err) {
|
|
13579
13536
|
clearTimeout(timer);
|
|
13580
13537
|
this.pendingControlRequests.delete(requestId);
|
|
@@ -13630,14 +13587,10 @@ var SessionRunner = class {
|
|
|
13630
13587
|
break;
|
|
13631
13588
|
case "write-stdin":
|
|
13632
13589
|
this.proc?.stdin?.write(effect.payload);
|
|
13633
|
-
this.recorder?.tapStdinWrite(effect.payload);
|
|
13634
13590
|
break;
|
|
13635
|
-
case "send-control-response-allow-with-input":
|
|
13636
|
-
|
|
13637
|
-
this.proc?.stdin?.write(payload);
|
|
13638
|
-
this.recorder?.tapStdinWrite(payload);
|
|
13591
|
+
case "send-control-response-allow-with-input":
|
|
13592
|
+
this.proc?.stdin?.write(encodeAllowWithInputControlResponse(effect.requestId, effect.updatedInput));
|
|
13639
13593
|
break;
|
|
13640
|
-
}
|
|
13641
13594
|
case "persist-file":
|
|
13642
13595
|
try {
|
|
13643
13596
|
this.hooks.store.write(effect.file);
|
|
@@ -13667,19 +13620,10 @@ var SessionRunner = class {
|
|
|
13667
13620
|
const proc = this.hooks.spawnOverride ? this.hooks.spawnOverride(ctx) : this.hooks.adapter.spawn(ctx);
|
|
13668
13621
|
this.proc = proc;
|
|
13669
13622
|
this.stdoutBuf = "";
|
|
13670
|
-
this.recorder = startRecorder({
|
|
13671
|
-
proc,
|
|
13672
|
-
sessionId: this.state.file.sessionId,
|
|
13673
|
-
dataDir: this.hooks.dataDir,
|
|
13674
|
-
env: this.hooks.recordEnv ?? process.env,
|
|
13675
|
-
now: this.hooks.now
|
|
13676
|
-
});
|
|
13677
13623
|
proc.stdout?.on("data", (chunk) => {
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
|
|
13681
|
-
const line = this.stdoutBuf.slice(0, idx);
|
|
13682
|
-
this.stdoutBuf = this.stdoutBuf.slice(idx + 1);
|
|
13624
|
+
const { newBuf, lines } = splitStdoutChunk(this.stdoutBuf, chunk);
|
|
13625
|
+
this.stdoutBuf = newBuf;
|
|
13626
|
+
for (const line of lines) {
|
|
13683
13627
|
if (this.tryHandleControlResponse(line)) continue;
|
|
13684
13628
|
this.input({ kind: "stdout-line", line });
|
|
13685
13629
|
}
|
|
@@ -13690,7 +13634,6 @@ var SessionRunner = class {
|
|
|
13690
13634
|
});
|
|
13691
13635
|
proc.on("exit", (code) => {
|
|
13692
13636
|
this.proc = null;
|
|
13693
|
-
this.recorder = null;
|
|
13694
13637
|
this.rejectAllPending(new Error("session gone"));
|
|
13695
13638
|
this.input({ kind: "proc-exit", code });
|
|
13696
13639
|
});
|
|
@@ -13817,8 +13760,7 @@ var SessionManager = class {
|
|
|
13817
13760
|
now: this.deps.now,
|
|
13818
13761
|
bufferCap: this.deps.bufferCap,
|
|
13819
13762
|
// adapter 自己持有模型表 + 兜底逻辑(contains / opus-1M / [1m] 等),manager 不再 cache 转发
|
|
13820
|
-
resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId)
|
|
13821
|
-
dataDir: this.deps.dataDir
|
|
13763
|
+
resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId)
|
|
13822
13764
|
});
|
|
13823
13765
|
return runner;
|
|
13824
13766
|
}
|
|
@@ -13849,7 +13791,7 @@ var SessionManager = class {
|
|
|
13849
13791
|
// ---- 命令方法:均返回 { response, broadcast[] },由 dispatcher 聚合 ----
|
|
13850
13792
|
create(args) {
|
|
13851
13793
|
try {
|
|
13852
|
-
const stat =
|
|
13794
|
+
const stat = import_node_fs4.default.statSync(args.cwd);
|
|
13853
13795
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
13854
13796
|
} catch {
|
|
13855
13797
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -14295,14 +14237,14 @@ var SessionManager = class {
|
|
|
14295
14237
|
// src/tools/claude.ts
|
|
14296
14238
|
var import_node_child_process = require("child_process");
|
|
14297
14239
|
var import_node_child_process2 = require("child_process");
|
|
14298
|
-
var
|
|
14240
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
14299
14241
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
14300
|
-
var
|
|
14242
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
14301
14243
|
|
|
14302
14244
|
// src/tools/claude-history.ts
|
|
14303
|
-
var
|
|
14245
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
14304
14246
|
var import_node_os2 = __toESM(require("os"), 1);
|
|
14305
|
-
var
|
|
14247
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
14306
14248
|
|
|
14307
14249
|
// ../node_modules/.pnpm/diff@7.0.0/node_modules/diff/lib/index.mjs
|
|
14308
14250
|
function Diff() {
|
|
@@ -14406,11 +14348,11 @@ Diff.prototype = {
|
|
|
14406
14348
|
}
|
|
14407
14349
|
}
|
|
14408
14350
|
},
|
|
14409
|
-
addToPath: function addToPath(
|
|
14410
|
-
var last =
|
|
14351
|
+
addToPath: function addToPath(path17, added, removed, oldPosInc, options) {
|
|
14352
|
+
var last = path17.lastComponent;
|
|
14411
14353
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14412
14354
|
return {
|
|
14413
|
-
oldPos:
|
|
14355
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
14414
14356
|
lastComponent: {
|
|
14415
14357
|
count: last.count + 1,
|
|
14416
14358
|
added,
|
|
@@ -14420,7 +14362,7 @@ Diff.prototype = {
|
|
|
14420
14362
|
};
|
|
14421
14363
|
} else {
|
|
14422
14364
|
return {
|
|
14423
|
-
oldPos:
|
|
14365
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
14424
14366
|
lastComponent: {
|
|
14425
14367
|
count: 1,
|
|
14426
14368
|
added,
|
|
@@ -15079,7 +15021,7 @@ function hashDirToCwd(hash) {
|
|
|
15079
15021
|
}
|
|
15080
15022
|
function safeStatMtime(p) {
|
|
15081
15023
|
try {
|
|
15082
|
-
return
|
|
15024
|
+
return import_node_fs5.default.statSync(p).mtimeMs;
|
|
15083
15025
|
} catch {
|
|
15084
15026
|
return 0;
|
|
15085
15027
|
}
|
|
@@ -15087,7 +15029,7 @@ function safeStatMtime(p) {
|
|
|
15087
15029
|
function readJsonlLines(file) {
|
|
15088
15030
|
let raw;
|
|
15089
15031
|
try {
|
|
15090
|
-
raw =
|
|
15032
|
+
raw = import_node_fs5.default.readFileSync(file, "utf8");
|
|
15091
15033
|
} catch (err) {
|
|
15092
15034
|
if (err.code === "ENOENT") return [];
|
|
15093
15035
|
throw err;
|
|
@@ -15279,10 +15221,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
15279
15221
|
const memories = raw.map((m) => {
|
|
15280
15222
|
if (!m || typeof m !== "object") return null;
|
|
15281
15223
|
const rec = m;
|
|
15282
|
-
const
|
|
15224
|
+
const path17 = typeof rec.path === "string" ? rec.path : null;
|
|
15283
15225
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
15284
|
-
if (!
|
|
15285
|
-
const entry = { path:
|
|
15226
|
+
if (!path17 || content == null) return null;
|
|
15227
|
+
const entry = { path: path17, content };
|
|
15286
15228
|
if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
|
|
15287
15229
|
return entry;
|
|
15288
15230
|
}).filter((m) => m !== null);
|
|
@@ -15318,8 +15260,8 @@ function attachmentDeferredToolsText(a) {
|
|
|
15318
15260
|
function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
15319
15261
|
if (backupFileName === null) return null;
|
|
15320
15262
|
try {
|
|
15321
|
-
return
|
|
15322
|
-
|
|
15263
|
+
return import_node_fs5.default.readFileSync(
|
|
15264
|
+
import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
15323
15265
|
"utf8"
|
|
15324
15266
|
);
|
|
15325
15267
|
} catch {
|
|
@@ -15328,7 +15270,7 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
15328
15270
|
}
|
|
15329
15271
|
function readCurrentContent(filePath) {
|
|
15330
15272
|
try {
|
|
15331
|
-
return
|
|
15273
|
+
return import_node_fs5.default.readFileSync(filePath, "utf8");
|
|
15332
15274
|
} catch (err) {
|
|
15333
15275
|
if (err.code === "ENOENT") return null;
|
|
15334
15276
|
return null;
|
|
@@ -15340,14 +15282,14 @@ var ClaudeHistoryReader = class {
|
|
|
15340
15282
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
15341
15283
|
fileHistoryRoot;
|
|
15342
15284
|
constructor(opts = {}) {
|
|
15343
|
-
const base = opts.baseDir ??
|
|
15344
|
-
this.projectsRoot =
|
|
15345
|
-
this.fileHistoryRoot =
|
|
15285
|
+
const base = opts.baseDir ?? import_node_path4.default.join(import_node_os2.default.homedir(), ".claude");
|
|
15286
|
+
this.projectsRoot = import_node_path4.default.join(base, "projects");
|
|
15287
|
+
this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
|
|
15346
15288
|
}
|
|
15347
15289
|
async listProjects() {
|
|
15348
15290
|
let entries;
|
|
15349
15291
|
try {
|
|
15350
|
-
entries =
|
|
15292
|
+
entries = import_node_fs5.default.readdirSync(this.projectsRoot, { withFileTypes: true });
|
|
15351
15293
|
} catch (err) {
|
|
15352
15294
|
if (err.code === "ENOENT") return [];
|
|
15353
15295
|
throw err;
|
|
@@ -15355,9 +15297,9 @@ var ClaudeHistoryReader = class {
|
|
|
15355
15297
|
const out = [];
|
|
15356
15298
|
for (const ent of entries) {
|
|
15357
15299
|
if (!ent.isDirectory()) continue;
|
|
15358
|
-
const dir =
|
|
15359
|
-
const files =
|
|
15360
|
-
const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(
|
|
15300
|
+
const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
|
|
15301
|
+
const files = import_node_fs5.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
15302
|
+
const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
|
|
15361
15303
|
out.push({
|
|
15362
15304
|
projectPath: hashDirToCwd(ent.name),
|
|
15363
15305
|
hashDir: ent.name,
|
|
@@ -15369,17 +15311,17 @@ var ClaudeHistoryReader = class {
|
|
|
15369
15311
|
return out;
|
|
15370
15312
|
}
|
|
15371
15313
|
async listSessions(args) {
|
|
15372
|
-
const dir =
|
|
15314
|
+
const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
15373
15315
|
let files;
|
|
15374
15316
|
try {
|
|
15375
|
-
files =
|
|
15317
|
+
files = import_node_fs5.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
15376
15318
|
} catch (err) {
|
|
15377
15319
|
if (err.code === "ENOENT") return [];
|
|
15378
15320
|
throw err;
|
|
15379
15321
|
}
|
|
15380
15322
|
const out = [];
|
|
15381
15323
|
for (const f of files) {
|
|
15382
|
-
const full =
|
|
15324
|
+
const full = import_node_path4.default.join(dir, f);
|
|
15383
15325
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
15384
15326
|
const lines = readJsonlLines(full);
|
|
15385
15327
|
let summary = "";
|
|
@@ -15434,7 +15376,7 @@ var ClaudeHistoryReader = class {
|
|
|
15434
15376
|
return out;
|
|
15435
15377
|
}
|
|
15436
15378
|
async read(args) {
|
|
15437
|
-
const file =
|
|
15379
|
+
const file = import_node_path4.default.join(
|
|
15438
15380
|
this.projectsRoot,
|
|
15439
15381
|
cwdToHashDir(args.cwd),
|
|
15440
15382
|
`${args.toolSessionId}.jsonl`
|
|
@@ -15467,7 +15409,7 @@ var ClaudeHistoryReader = class {
|
|
|
15467
15409
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
15468
15410
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
15469
15411
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
15470
|
-
const dir =
|
|
15412
|
+
const dir = import_node_path4.default.join(
|
|
15471
15413
|
this.projectsRoot,
|
|
15472
15414
|
cwdToHashDir(cwd),
|
|
15473
15415
|
toolSessionId,
|
|
@@ -15475,7 +15417,7 @@ var ClaudeHistoryReader = class {
|
|
|
15475
15417
|
);
|
|
15476
15418
|
let entries;
|
|
15477
15419
|
try {
|
|
15478
|
-
entries =
|
|
15420
|
+
entries = import_node_fs5.default.readdirSync(dir, { withFileTypes: true });
|
|
15479
15421
|
} catch (err) {
|
|
15480
15422
|
if (err.code === "ENOENT") return null;
|
|
15481
15423
|
return null;
|
|
@@ -15485,7 +15427,7 @@ var ClaudeHistoryReader = class {
|
|
|
15485
15427
|
if (!e.isFile()) continue;
|
|
15486
15428
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
15487
15429
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
15488
|
-
const filePath =
|
|
15430
|
+
const filePath = import_node_path4.default.join(dir, e.name);
|
|
15489
15431
|
const lines = readJsonlLines(filePath);
|
|
15490
15432
|
let firstText = "";
|
|
15491
15433
|
let messageCount = 0;
|
|
@@ -15502,7 +15444,7 @@ var ClaudeHistoryReader = class {
|
|
|
15502
15444
|
return out;
|
|
15503
15445
|
}
|
|
15504
15446
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
15505
|
-
const file =
|
|
15447
|
+
const file = import_node_path4.default.join(
|
|
15506
15448
|
this.projectsRoot,
|
|
15507
15449
|
cwdToHashDir(cwd),
|
|
15508
15450
|
`${toolSessionId}.jsonl`
|
|
@@ -15537,7 +15479,7 @@ var ClaudeHistoryReader = class {
|
|
|
15537
15479
|
}
|
|
15538
15480
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
15539
15481
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
15540
|
-
const file =
|
|
15482
|
+
const file = import_node_path4.default.join(
|
|
15541
15483
|
this.projectsRoot,
|
|
15542
15484
|
cwdToHashDir(cwd),
|
|
15543
15485
|
toolSessionId,
|
|
@@ -15546,7 +15488,7 @@ var ClaudeHistoryReader = class {
|
|
|
15546
15488
|
);
|
|
15547
15489
|
let exists = false;
|
|
15548
15490
|
try {
|
|
15549
|
-
exists =
|
|
15491
|
+
exists = import_node_fs5.default.statSync(file).isFile();
|
|
15550
15492
|
} catch {
|
|
15551
15493
|
return null;
|
|
15552
15494
|
}
|
|
@@ -15565,7 +15507,7 @@ var ClaudeHistoryReader = class {
|
|
|
15565
15507
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
15566
15508
|
*/
|
|
15567
15509
|
readFileHistorySnapshots(args) {
|
|
15568
|
-
const file =
|
|
15510
|
+
const file = import_node_path4.default.join(
|
|
15569
15511
|
this.projectsRoot,
|
|
15570
15512
|
cwdToHashDir(args.cwd),
|
|
15571
15513
|
`${args.toolSessionId}.jsonl`
|
|
@@ -15610,7 +15552,7 @@ var ClaudeHistoryReader = class {
|
|
|
15610
15552
|
for (const [anchorId, target] of snapshots) {
|
|
15611
15553
|
let hasAny = false;
|
|
15612
15554
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
15613
|
-
const absPath =
|
|
15555
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
15614
15556
|
const backupContent = readBackupContent(
|
|
15615
15557
|
this.fileHistoryRoot,
|
|
15616
15558
|
args.toolSessionId,
|
|
@@ -15650,7 +15592,7 @@ var ClaudeHistoryReader = class {
|
|
|
15650
15592
|
let totalInsertions = 0;
|
|
15651
15593
|
let totalDeletions = 0;
|
|
15652
15594
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
15653
|
-
const absPath =
|
|
15595
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
15654
15596
|
const backupContent = readBackupContent(
|
|
15655
15597
|
this.fileHistoryRoot,
|
|
15656
15598
|
args.toolSessionId,
|
|
@@ -15697,7 +15639,7 @@ var ClaudeHistoryReader = class {
|
|
|
15697
15639
|
};
|
|
15698
15640
|
}
|
|
15699
15641
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
15700
|
-
const file =
|
|
15642
|
+
const file = import_node_path4.default.join(
|
|
15701
15643
|
this.projectsRoot,
|
|
15702
15644
|
cwdToHashDir(cwd),
|
|
15703
15645
|
`${toolSessionId}.jsonl`
|
|
@@ -15719,27 +15661,27 @@ var ClaudeHistoryReader = class {
|
|
|
15719
15661
|
// src/tools/claude.ts
|
|
15720
15662
|
function macOSDesktopCandidates(home) {
|
|
15721
15663
|
return [
|
|
15722
|
-
|
|
15664
|
+
import_node_path5.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
|
|
15723
15665
|
"/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
|
|
15724
15666
|
];
|
|
15725
15667
|
}
|
|
15726
15668
|
function probeViaWhich() {
|
|
15727
15669
|
try {
|
|
15728
15670
|
const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
|
|
15729
|
-
if (out &&
|
|
15671
|
+
if (out && import_node_fs6.default.existsSync(out)) return out;
|
|
15730
15672
|
} catch {
|
|
15731
15673
|
}
|
|
15732
15674
|
return null;
|
|
15733
15675
|
}
|
|
15734
15676
|
async function probeClaude(env = process.env, home = import_node_os3.default.homedir()) {
|
|
15735
|
-
if (env.CLAUDE_BIN &&
|
|
15677
|
+
if (env.CLAUDE_BIN && import_node_fs6.default.existsSync(env.CLAUDE_BIN)) {
|
|
15736
15678
|
return { available: true, path: env.CLAUDE_BIN };
|
|
15737
15679
|
}
|
|
15738
15680
|
const w = probeViaWhich();
|
|
15739
15681
|
if (w) return { available: true, path: w };
|
|
15740
15682
|
if (process.platform === "darwin") {
|
|
15741
15683
|
for (const candidate of macOSDesktopCandidates(home)) {
|
|
15742
|
-
if (
|
|
15684
|
+
if (import_node_fs6.default.existsSync(candidate)) {
|
|
15743
15685
|
return { available: true, path: candidate };
|
|
15744
15686
|
}
|
|
15745
15687
|
}
|
|
@@ -16050,10 +15992,10 @@ function parseAttachment(obj) {
|
|
|
16050
15992
|
const memories = raw.map((m) => {
|
|
16051
15993
|
if (!m || typeof m !== "object") return null;
|
|
16052
15994
|
const rec = m;
|
|
16053
|
-
const
|
|
15995
|
+
const path17 = typeof rec.path === "string" ? rec.path : null;
|
|
16054
15996
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
16055
|
-
if (!
|
|
16056
|
-
const out = { path:
|
|
15997
|
+
if (!path17 || content == null) return null;
|
|
15998
|
+
const out = { path: path17, content };
|
|
16057
15999
|
if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
|
|
16058
16000
|
return out;
|
|
16059
16001
|
}).filter((m) => m !== null);
|
|
@@ -16281,22 +16223,22 @@ var ClaudeAdapter = class {
|
|
|
16281
16223
|
};
|
|
16282
16224
|
|
|
16283
16225
|
// src/workspace/browser.ts
|
|
16284
|
-
var
|
|
16226
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
16285
16227
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
16286
|
-
var
|
|
16228
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
16287
16229
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
16288
16230
|
function resolveInsideCwd(cwd, subpath) {
|
|
16289
|
-
const absCwd =
|
|
16290
|
-
const joined =
|
|
16291
|
-
const rel =
|
|
16292
|
-
if (rel.startsWith("..") ||
|
|
16231
|
+
const absCwd = import_node_path6.default.resolve(cwd);
|
|
16232
|
+
const joined = import_node_path6.default.resolve(absCwd, subpath ?? ".");
|
|
16233
|
+
const rel = import_node_path6.default.relative(absCwd, joined);
|
|
16234
|
+
if (rel.startsWith("..") || import_node_path6.default.isAbsolute(rel)) {
|
|
16293
16235
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
16294
16236
|
}
|
|
16295
16237
|
return joined;
|
|
16296
16238
|
}
|
|
16297
16239
|
function ensureCwd(cwd) {
|
|
16298
16240
|
try {
|
|
16299
|
-
const stat =
|
|
16241
|
+
const stat = import_node_fs7.default.statSync(cwd);
|
|
16300
16242
|
if (!stat.isDirectory()) {
|
|
16301
16243
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
16302
16244
|
}
|
|
@@ -16310,7 +16252,7 @@ var WorkspaceBrowser = class {
|
|
|
16310
16252
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os4.default.homedir();
|
|
16311
16253
|
ensureCwd(cwd);
|
|
16312
16254
|
const full = resolveInsideCwd(cwd, args.path);
|
|
16313
|
-
const dirents =
|
|
16255
|
+
const dirents = import_node_fs7.default.readdirSync(full, { withFileTypes: true });
|
|
16314
16256
|
const entries = [];
|
|
16315
16257
|
for (const d of dirents) {
|
|
16316
16258
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -16320,7 +16262,7 @@ var WorkspaceBrowser = class {
|
|
|
16320
16262
|
mtime: ""
|
|
16321
16263
|
};
|
|
16322
16264
|
try {
|
|
16323
|
-
const st =
|
|
16265
|
+
const st = import_node_fs7.default.statSync(import_node_path6.default.join(full, d.name));
|
|
16324
16266
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
16325
16267
|
if (d.isFile()) entry.size = st.size;
|
|
16326
16268
|
} catch {
|
|
@@ -16336,14 +16278,14 @@ var WorkspaceBrowser = class {
|
|
|
16336
16278
|
read(args) {
|
|
16337
16279
|
ensureCwd(args.cwd);
|
|
16338
16280
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
16339
|
-
const st =
|
|
16281
|
+
const st = import_node_fs7.default.statSync(full);
|
|
16340
16282
|
if (!st.isFile()) {
|
|
16341
16283
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
16342
16284
|
}
|
|
16343
16285
|
if (st.size > MAX_FILE_BYTES) {
|
|
16344
16286
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
16345
16287
|
}
|
|
16346
|
-
const buf =
|
|
16288
|
+
const buf = import_node_fs7.default.readFileSync(full);
|
|
16347
16289
|
const isBinary = buf.includes(0);
|
|
16348
16290
|
if (isBinary) {
|
|
16349
16291
|
return {
|
|
@@ -16365,9 +16307,9 @@ var WorkspaceBrowser = class {
|
|
|
16365
16307
|
};
|
|
16366
16308
|
|
|
16367
16309
|
// src/skills/scanner.ts
|
|
16368
|
-
var
|
|
16310
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
16369
16311
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
16370
|
-
var
|
|
16312
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
16371
16313
|
function parseFrontmatter(content) {
|
|
16372
16314
|
if (!content.startsWith("---")) return { name: "", description: "" };
|
|
16373
16315
|
const end = content.indexOf("---", 3);
|
|
@@ -16403,7 +16345,7 @@ function parseFrontmatter(content) {
|
|
|
16403
16345
|
}
|
|
16404
16346
|
function isDirLikeSync(p) {
|
|
16405
16347
|
try {
|
|
16406
|
-
return
|
|
16348
|
+
return import_node_fs8.default.statSync(p).isDirectory();
|
|
16407
16349
|
} catch {
|
|
16408
16350
|
return false;
|
|
16409
16351
|
}
|
|
@@ -16411,19 +16353,19 @@ function isDirLikeSync(p) {
|
|
|
16411
16353
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
16412
16354
|
let entries;
|
|
16413
16355
|
try {
|
|
16414
|
-
entries =
|
|
16356
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
16415
16357
|
} catch {
|
|
16416
16358
|
return;
|
|
16417
16359
|
}
|
|
16418
16360
|
for (const ent of entries) {
|
|
16419
|
-
const entryPath =
|
|
16361
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
16420
16362
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
16421
16363
|
let content;
|
|
16422
16364
|
try {
|
|
16423
|
-
content =
|
|
16365
|
+
content = import_node_fs8.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
|
|
16424
16366
|
} catch {
|
|
16425
16367
|
try {
|
|
16426
|
-
content =
|
|
16368
|
+
content = import_node_fs8.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
|
|
16427
16369
|
} catch {
|
|
16428
16370
|
continue;
|
|
16429
16371
|
}
|
|
@@ -16441,26 +16383,26 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
|
16441
16383
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
16442
16384
|
let entries;
|
|
16443
16385
|
try {
|
|
16444
|
-
entries =
|
|
16386
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
16445
16387
|
} catch {
|
|
16446
16388
|
return;
|
|
16447
16389
|
}
|
|
16448
16390
|
for (const ent of entries) {
|
|
16449
|
-
const entryPath =
|
|
16391
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
16450
16392
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
16451
16393
|
const ns = ent.name;
|
|
16452
16394
|
let subEntries;
|
|
16453
16395
|
try {
|
|
16454
|
-
subEntries =
|
|
16396
|
+
subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
|
|
16455
16397
|
} catch {
|
|
16456
16398
|
continue;
|
|
16457
16399
|
}
|
|
16458
16400
|
for (const se of subEntries) {
|
|
16459
16401
|
if (!se.name.endsWith(".md")) continue;
|
|
16460
|
-
const sePath =
|
|
16402
|
+
const sePath = import_node_path7.default.join(entryPath, se.name);
|
|
16461
16403
|
let content;
|
|
16462
16404
|
try {
|
|
16463
|
-
content =
|
|
16405
|
+
content = import_node_fs8.default.readFileSync(sePath, "utf8");
|
|
16464
16406
|
} catch {
|
|
16465
16407
|
continue;
|
|
16466
16408
|
}
|
|
@@ -16477,7 +16419,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
16477
16419
|
} else if (ent.name.endsWith(".md")) {
|
|
16478
16420
|
let content;
|
|
16479
16421
|
try {
|
|
16480
|
-
content =
|
|
16422
|
+
content = import_node_fs8.default.readFileSync(entryPath, "utf8");
|
|
16481
16423
|
} catch {
|
|
16482
16424
|
continue;
|
|
16483
16425
|
}
|
|
@@ -16493,10 +16435,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
16493
16435
|
}
|
|
16494
16436
|
}
|
|
16495
16437
|
function readInstalledPlugins(home) {
|
|
16496
|
-
const file =
|
|
16438
|
+
const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
16497
16439
|
let raw;
|
|
16498
16440
|
try {
|
|
16499
|
-
raw =
|
|
16441
|
+
raw = import_node_fs8.default.readFileSync(file, "utf8");
|
|
16500
16442
|
} catch {
|
|
16501
16443
|
return [];
|
|
16502
16444
|
}
|
|
@@ -16534,14 +16476,14 @@ var SkillsScanner = class {
|
|
|
16534
16476
|
list(args) {
|
|
16535
16477
|
const seen = /* @__PURE__ */ new Set();
|
|
16536
16478
|
const out = [];
|
|
16537
|
-
scanSkillDir(
|
|
16538
|
-
scanCommandDir(
|
|
16539
|
-
scanSkillDir(
|
|
16540
|
-
scanCommandDir(
|
|
16479
|
+
scanSkillDir(import_node_path7.default.join(this.home, ".claude", "skills"), "global", seen, out);
|
|
16480
|
+
scanCommandDir(import_node_path7.default.join(this.home, ".claude", "commands"), "global", seen, out);
|
|
16481
|
+
scanSkillDir(import_node_path7.default.join(args.cwd, ".claude", "skills"), "project", seen, out);
|
|
16482
|
+
scanCommandDir(import_node_path7.default.join(args.cwd, ".claude", "commands"), "project", seen, out);
|
|
16541
16483
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
16542
16484
|
for (const { name, root } of plugins) {
|
|
16543
|
-
scanSkillDir(
|
|
16544
|
-
scanCommandDir(
|
|
16485
|
+
scanSkillDir(import_node_path7.default.join(root, "skills"), "plugin", seen, out, name);
|
|
16486
|
+
scanCommandDir(import_node_path7.default.join(root, "commands"), "plugin", seen, out, name);
|
|
16545
16487
|
}
|
|
16546
16488
|
out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
16547
16489
|
return out;
|
|
@@ -16549,9 +16491,9 @@ var SkillsScanner = class {
|
|
|
16549
16491
|
};
|
|
16550
16492
|
|
|
16551
16493
|
// src/observer/session-observer.ts
|
|
16552
|
-
var
|
|
16494
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
16553
16495
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
16554
|
-
var
|
|
16496
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
16555
16497
|
var SessionObserver = class {
|
|
16556
16498
|
constructor(opts) {
|
|
16557
16499
|
this.opts = opts;
|
|
@@ -16562,14 +16504,14 @@ var SessionObserver = class {
|
|
|
16562
16504
|
watches = /* @__PURE__ */ new Map();
|
|
16563
16505
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
16564
16506
|
if (override) return override;
|
|
16565
|
-
return
|
|
16507
|
+
return import_node_path8.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
16566
16508
|
}
|
|
16567
16509
|
start(args) {
|
|
16568
16510
|
this.stop(args.sessionId);
|
|
16569
16511
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
16570
16512
|
let size = 0;
|
|
16571
16513
|
try {
|
|
16572
|
-
size =
|
|
16514
|
+
size = import_node_fs9.default.statSync(filePath).size;
|
|
16573
16515
|
} catch {
|
|
16574
16516
|
}
|
|
16575
16517
|
const w = {
|
|
@@ -16582,10 +16524,10 @@ var SessionObserver = class {
|
|
|
16582
16524
|
adapter: args.adapter
|
|
16583
16525
|
};
|
|
16584
16526
|
try {
|
|
16585
|
-
|
|
16527
|
+
import_node_fs9.default.mkdirSync(import_node_path8.default.dirname(filePath), { recursive: true });
|
|
16586
16528
|
} catch {
|
|
16587
16529
|
}
|
|
16588
|
-
w.watcher =
|
|
16530
|
+
w.watcher = import_node_fs9.default.watch(import_node_path8.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
16589
16531
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
16590
16532
|
this.poll(w);
|
|
16591
16533
|
});
|
|
@@ -16600,7 +16542,7 @@ var SessionObserver = class {
|
|
|
16600
16542
|
// reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
|
|
16601
16543
|
hydrateMetaTail(w, maxLines = 200) {
|
|
16602
16544
|
try {
|
|
16603
|
-
const raw =
|
|
16545
|
+
const raw = import_node_fs9.default.readFileSync(w.filePath, "utf8");
|
|
16604
16546
|
if (!raw) return;
|
|
16605
16547
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
16606
16548
|
if (allLines.length === 0) return;
|
|
@@ -16621,7 +16563,7 @@ var SessionObserver = class {
|
|
|
16621
16563
|
poll(w) {
|
|
16622
16564
|
let size = 0;
|
|
16623
16565
|
try {
|
|
16624
|
-
size =
|
|
16566
|
+
size = import_node_fs9.default.statSync(w.filePath).size;
|
|
16625
16567
|
} catch {
|
|
16626
16568
|
return;
|
|
16627
16569
|
}
|
|
@@ -16630,11 +16572,11 @@ var SessionObserver = class {
|
|
|
16630
16572
|
w.buf = "";
|
|
16631
16573
|
}
|
|
16632
16574
|
if (size === w.lastSize) return;
|
|
16633
|
-
const fd =
|
|
16575
|
+
const fd = import_node_fs9.default.openSync(w.filePath, "r");
|
|
16634
16576
|
try {
|
|
16635
16577
|
const len = size - w.lastSize;
|
|
16636
16578
|
const buf = Buffer.alloc(len);
|
|
16637
|
-
|
|
16579
|
+
import_node_fs9.default.readSync(fd, buf, 0, len, w.lastSize);
|
|
16638
16580
|
w.lastSize = size;
|
|
16639
16581
|
w.buf += buf.toString("utf8");
|
|
16640
16582
|
let newlineIndex;
|
|
@@ -16648,7 +16590,7 @@ var SessionObserver = class {
|
|
|
16648
16590
|
this.maybeReportUserMessage(w.sessionId, line);
|
|
16649
16591
|
}
|
|
16650
16592
|
} finally {
|
|
16651
|
-
|
|
16593
|
+
import_node_fs9.default.closeSync(fd);
|
|
16652
16594
|
}
|
|
16653
16595
|
}
|
|
16654
16596
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -17063,10 +17005,10 @@ function isLocalhost(addr) {
|
|
|
17063
17005
|
}
|
|
17064
17006
|
|
|
17065
17007
|
// src/discovery/state-file.ts
|
|
17066
|
-
var
|
|
17067
|
-
var
|
|
17008
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
17009
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
17068
17010
|
function defaultStateFilePath(dataDir) {
|
|
17069
|
-
return
|
|
17011
|
+
return import_node_path9.default.join(dataDir, "state.json");
|
|
17070
17012
|
}
|
|
17071
17013
|
function isPidAlive(pid) {
|
|
17072
17014
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -17088,7 +17030,7 @@ var StateFileManager = class {
|
|
|
17088
17030
|
}
|
|
17089
17031
|
read() {
|
|
17090
17032
|
try {
|
|
17091
|
-
const raw =
|
|
17033
|
+
const raw = import_node_fs10.default.readFileSync(this.file, "utf8");
|
|
17092
17034
|
const parsed = JSON.parse(raw);
|
|
17093
17035
|
return parsed;
|
|
17094
17036
|
} catch {
|
|
@@ -17102,34 +17044,34 @@ var StateFileManager = class {
|
|
|
17102
17044
|
return { status: "stale", existing };
|
|
17103
17045
|
}
|
|
17104
17046
|
write(state) {
|
|
17105
|
-
|
|
17047
|
+
import_node_fs10.default.mkdirSync(import_node_path9.default.dirname(this.file), { recursive: true });
|
|
17106
17048
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
17107
|
-
|
|
17108
|
-
|
|
17049
|
+
import_node_fs10.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
17050
|
+
import_node_fs10.default.renameSync(tmp, this.file);
|
|
17109
17051
|
if (process.platform !== "win32") {
|
|
17110
17052
|
try {
|
|
17111
|
-
|
|
17053
|
+
import_node_fs10.default.chmodSync(this.file, 384);
|
|
17112
17054
|
} catch {
|
|
17113
17055
|
}
|
|
17114
17056
|
}
|
|
17115
17057
|
}
|
|
17116
17058
|
delete() {
|
|
17117
17059
|
try {
|
|
17118
|
-
|
|
17060
|
+
import_node_fs10.default.unlinkSync(this.file);
|
|
17119
17061
|
} catch {
|
|
17120
17062
|
}
|
|
17121
17063
|
}
|
|
17122
17064
|
};
|
|
17123
17065
|
|
|
17124
17066
|
// src/tunnel/tunnel-manager.ts
|
|
17125
|
-
var
|
|
17126
|
-
var
|
|
17067
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
17068
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
17127
17069
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
17128
17070
|
var import_node_child_process4 = require("child_process");
|
|
17129
17071
|
|
|
17130
17072
|
// src/tunnel/tunnel-store.ts
|
|
17131
|
-
var
|
|
17132
|
-
var
|
|
17073
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
17074
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
17133
17075
|
var TunnelStore = class {
|
|
17134
17076
|
constructor(filePath) {
|
|
17135
17077
|
this.filePath = filePath;
|
|
@@ -17137,7 +17079,7 @@ var TunnelStore = class {
|
|
|
17137
17079
|
filePath;
|
|
17138
17080
|
async get() {
|
|
17139
17081
|
try {
|
|
17140
|
-
const raw = await
|
|
17082
|
+
const raw = await import_node_fs11.default.promises.readFile(this.filePath, "utf8");
|
|
17141
17083
|
const obj = JSON.parse(raw);
|
|
17142
17084
|
if (!isPersistedTunnel(obj)) return null;
|
|
17143
17085
|
return obj;
|
|
@@ -17148,22 +17090,22 @@ var TunnelStore = class {
|
|
|
17148
17090
|
}
|
|
17149
17091
|
}
|
|
17150
17092
|
async set(v) {
|
|
17151
|
-
const dir =
|
|
17152
|
-
await
|
|
17093
|
+
const dir = import_node_path10.default.dirname(this.filePath);
|
|
17094
|
+
await import_node_fs11.default.promises.mkdir(dir, { recursive: true });
|
|
17153
17095
|
const data = JSON.stringify(v, null, 2);
|
|
17154
17096
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
17155
|
-
await
|
|
17097
|
+
await import_node_fs11.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
17156
17098
|
if (process.platform !== "win32") {
|
|
17157
17099
|
try {
|
|
17158
|
-
await
|
|
17100
|
+
await import_node_fs11.default.promises.chmod(tmp, 384);
|
|
17159
17101
|
} catch {
|
|
17160
17102
|
}
|
|
17161
17103
|
}
|
|
17162
|
-
await
|
|
17104
|
+
await import_node_fs11.default.promises.rename(tmp, this.filePath);
|
|
17163
17105
|
}
|
|
17164
17106
|
async clear() {
|
|
17165
17107
|
try {
|
|
17166
|
-
await
|
|
17108
|
+
await import_node_fs11.default.promises.unlink(this.filePath);
|
|
17167
17109
|
} catch (err) {
|
|
17168
17110
|
const code = err?.code;
|
|
17169
17111
|
if (code !== "ENOENT") throw err;
|
|
@@ -17258,9 +17200,9 @@ function escape(v) {
|
|
|
17258
17200
|
}
|
|
17259
17201
|
|
|
17260
17202
|
// src/tunnel/frpc-binary.ts
|
|
17261
|
-
var
|
|
17203
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
17262
17204
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
17263
|
-
var
|
|
17205
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
17264
17206
|
var import_node_child_process3 = require("child_process");
|
|
17265
17207
|
var import_node_stream = require("stream");
|
|
17266
17208
|
var import_promises = require("stream/promises");
|
|
@@ -17292,20 +17234,20 @@ function frpcDownloadUrl(version2, p) {
|
|
|
17292
17234
|
}
|
|
17293
17235
|
async function ensureFrpcBinary(opts) {
|
|
17294
17236
|
if (opts.override) {
|
|
17295
|
-
if (!
|
|
17237
|
+
if (!import_node_fs12.default.existsSync(opts.override)) {
|
|
17296
17238
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
17297
17239
|
}
|
|
17298
17240
|
return opts.override;
|
|
17299
17241
|
}
|
|
17300
17242
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
17301
17243
|
const platform = opts.platform ?? detectPlatform();
|
|
17302
|
-
const binDir =
|
|
17303
|
-
|
|
17244
|
+
const binDir = import_node_path11.default.join(opts.dataDir, "bin");
|
|
17245
|
+
import_node_fs12.default.mkdirSync(binDir, { recursive: true });
|
|
17304
17246
|
cleanupStaleArtifacts(binDir);
|
|
17305
|
-
const stableBin =
|
|
17306
|
-
if (
|
|
17247
|
+
const stableBin = import_node_path11.default.join(binDir, "frpc");
|
|
17248
|
+
if (import_node_fs12.default.existsSync(stableBin)) return stableBin;
|
|
17307
17249
|
const partialBin = `${stableBin}.partial`;
|
|
17308
|
-
const tarballPath =
|
|
17250
|
+
const tarballPath = import_node_path11.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
17309
17251
|
try {
|
|
17310
17252
|
const url = frpcDownloadUrl(version2, platform);
|
|
17311
17253
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -17314,8 +17256,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
17314
17256
|
} else {
|
|
17315
17257
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
17316
17258
|
}
|
|
17317
|
-
|
|
17318
|
-
|
|
17259
|
+
import_node_fs12.default.chmodSync(partialBin, 493);
|
|
17260
|
+
import_node_fs12.default.renameSync(partialBin, stableBin);
|
|
17319
17261
|
} finally {
|
|
17320
17262
|
safeUnlink(tarballPath);
|
|
17321
17263
|
safeUnlink(partialBin);
|
|
@@ -17325,15 +17267,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
17325
17267
|
function cleanupStaleArtifacts(binDir) {
|
|
17326
17268
|
let entries;
|
|
17327
17269
|
try {
|
|
17328
|
-
entries =
|
|
17270
|
+
entries = import_node_fs12.default.readdirSync(binDir);
|
|
17329
17271
|
} catch {
|
|
17330
17272
|
return;
|
|
17331
17273
|
}
|
|
17332
17274
|
for (const name of entries) {
|
|
17333
17275
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
17334
|
-
const full =
|
|
17276
|
+
const full = import_node_path11.default.join(binDir, name);
|
|
17335
17277
|
try {
|
|
17336
|
-
|
|
17278
|
+
import_node_fs12.default.rmSync(full, { recursive: true, force: true });
|
|
17337
17279
|
} catch {
|
|
17338
17280
|
}
|
|
17339
17281
|
}
|
|
@@ -17341,7 +17283,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
17341
17283
|
}
|
|
17342
17284
|
function safeUnlink(p) {
|
|
17343
17285
|
try {
|
|
17344
|
-
|
|
17286
|
+
import_node_fs12.default.unlinkSync(p);
|
|
17345
17287
|
} catch {
|
|
17346
17288
|
}
|
|
17347
17289
|
}
|
|
@@ -17352,13 +17294,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
17352
17294
|
if (!res.ok || !res.body) {
|
|
17353
17295
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
17354
17296
|
}
|
|
17355
|
-
const out =
|
|
17297
|
+
const out = import_node_fs12.default.createWriteStream(dest);
|
|
17356
17298
|
const nodeStream = import_node_stream.Readable.fromWeb(res.body);
|
|
17357
17299
|
await (0, import_promises.pipeline)(nodeStream, out);
|
|
17358
17300
|
}
|
|
17359
17301
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
17360
|
-
const work =
|
|
17361
|
-
|
|
17302
|
+
const work = import_node_path11.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
17303
|
+
import_node_fs12.default.mkdirSync(work, { recursive: true });
|
|
17362
17304
|
try {
|
|
17363
17305
|
await new Promise((resolve, reject) => {
|
|
17364
17306
|
const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -17366,13 +17308,13 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
17366
17308
|
proc.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`tar exited ${code}`)));
|
|
17367
17309
|
});
|
|
17368
17310
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
17369
|
-
const src =
|
|
17370
|
-
if (!
|
|
17311
|
+
const src = import_node_path11.default.join(work, dirName, "frpc");
|
|
17312
|
+
if (!import_node_fs12.default.existsSync(src)) {
|
|
17371
17313
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
17372
17314
|
}
|
|
17373
|
-
|
|
17315
|
+
import_node_fs12.default.copyFileSync(src, destBin);
|
|
17374
17316
|
} finally {
|
|
17375
|
-
|
|
17317
|
+
import_node_fs12.default.rmSync(work, { recursive: true, force: true });
|
|
17376
17318
|
}
|
|
17377
17319
|
}
|
|
17378
17320
|
|
|
@@ -17381,7 +17323,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
17381
17323
|
var TunnelManager = class {
|
|
17382
17324
|
constructor(deps) {
|
|
17383
17325
|
this.deps = deps;
|
|
17384
|
-
this.store = deps.store ?? new TunnelStore(
|
|
17326
|
+
this.store = deps.store ?? new TunnelStore(import_node_path12.default.join(deps.dataDir, "tunnel.json"));
|
|
17385
17327
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
17386
17328
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
17387
17329
|
}
|
|
@@ -17498,7 +17440,7 @@ var TunnelManager = class {
|
|
|
17498
17440
|
dataDir: this.deps.dataDir,
|
|
17499
17441
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
17500
17442
|
});
|
|
17501
|
-
const tomlPath =
|
|
17443
|
+
const tomlPath = import_node_path12.default.join(this.deps.dataDir, "frpc.toml");
|
|
17502
17444
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto3.default.randomBytes(3).toString("hex")}`;
|
|
17503
17445
|
const toml = buildFrpcToml({
|
|
17504
17446
|
serverAddr: t.frpsHost,
|
|
@@ -17509,12 +17451,12 @@ var TunnelManager = class {
|
|
|
17509
17451
|
localPort,
|
|
17510
17452
|
logLevel: "info"
|
|
17511
17453
|
});
|
|
17512
|
-
await
|
|
17454
|
+
await import_node_fs13.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
17513
17455
|
const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
|
|
17514
17456
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17515
17457
|
});
|
|
17516
|
-
const logFilePath =
|
|
17517
|
-
const logStream =
|
|
17458
|
+
const logFilePath = import_node_path12.default.join(this.deps.dataDir, "frpc.log");
|
|
17459
|
+
const logStream = import_node_fs13.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
17518
17460
|
logStream.on("error", () => {
|
|
17519
17461
|
});
|
|
17520
17462
|
const tee = (chunk) => {
|
|
@@ -17606,12 +17548,12 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
17606
17548
|
}
|
|
17607
17549
|
|
|
17608
17550
|
// src/auth-store.ts
|
|
17609
|
-
var
|
|
17610
|
-
var
|
|
17551
|
+
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
17552
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
17611
17553
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
17612
17554
|
var AUTH_FILE_NAME = "auth.json";
|
|
17613
17555
|
function authFilePath(dataDir) {
|
|
17614
|
-
return
|
|
17556
|
+
return import_node_path13.default.join(dataDir, AUTH_FILE_NAME);
|
|
17615
17557
|
}
|
|
17616
17558
|
function loadOrCreateAuthToken(opts) {
|
|
17617
17559
|
const file = authFilePath(opts.dataDir);
|
|
@@ -17627,7 +17569,7 @@ function defaultGenerate() {
|
|
|
17627
17569
|
}
|
|
17628
17570
|
function readAuthFile(file) {
|
|
17629
17571
|
try {
|
|
17630
|
-
const raw =
|
|
17572
|
+
const raw = import_node_fs14.default.readFileSync(file, "utf8");
|
|
17631
17573
|
const parsed = JSON.parse(raw);
|
|
17632
17574
|
if (typeof parsed?.token === "string" && parsed.token.length > 0) {
|
|
17633
17575
|
return {
|
|
@@ -17643,20 +17585,20 @@ function readAuthFile(file) {
|
|
|
17643
17585
|
}
|
|
17644
17586
|
}
|
|
17645
17587
|
function writeAuthFile(file, content) {
|
|
17646
|
-
|
|
17647
|
-
|
|
17588
|
+
import_node_fs14.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
|
|
17589
|
+
import_node_fs14.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
17648
17590
|
try {
|
|
17649
|
-
|
|
17591
|
+
import_node_fs14.default.chmodSync(file, 384);
|
|
17650
17592
|
} catch {
|
|
17651
17593
|
}
|
|
17652
17594
|
}
|
|
17653
17595
|
|
|
17654
17596
|
// src/session/fork.ts
|
|
17655
|
-
var
|
|
17597
|
+
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
17656
17598
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
17657
|
-
var
|
|
17599
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
17658
17600
|
function readJsonlEntries(file) {
|
|
17659
|
-
const raw =
|
|
17601
|
+
const raw = import_node_fs15.default.readFileSync(file, "utf8");
|
|
17660
17602
|
const out = [];
|
|
17661
17603
|
for (const line of raw.split("\n")) {
|
|
17662
17604
|
const t = line.trim();
|
|
@@ -17669,10 +17611,10 @@ function readJsonlEntries(file) {
|
|
|
17669
17611
|
return out;
|
|
17670
17612
|
}
|
|
17671
17613
|
function forkSession(input) {
|
|
17672
|
-
const baseDir = input.baseDir ??
|
|
17673
|
-
const projectDir =
|
|
17674
|
-
const sourceFile =
|
|
17675
|
-
if (!
|
|
17614
|
+
const baseDir = input.baseDir ?? import_node_path14.default.join(import_node_os9.default.homedir(), ".claude");
|
|
17615
|
+
const projectDir = import_node_path14.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
17616
|
+
const sourceFile = import_node_path14.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
17617
|
+
if (!import_node_fs15.default.existsSync(sourceFile)) {
|
|
17676
17618
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
17677
17619
|
}
|
|
17678
17620
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -17702,9 +17644,9 @@ function forkSession(input) {
|
|
|
17702
17644
|
}
|
|
17703
17645
|
forkedLines.push(JSON.stringify(forked));
|
|
17704
17646
|
}
|
|
17705
|
-
const forkedFilePath =
|
|
17706
|
-
|
|
17707
|
-
|
|
17647
|
+
const forkedFilePath = import_node_path14.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
17648
|
+
import_node_fs15.default.mkdirSync(projectDir, { recursive: true });
|
|
17649
|
+
import_node_fs15.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
17708
17650
|
return { forkedToolSessionId, forkedFilePath };
|
|
17709
17651
|
}
|
|
17710
17652
|
|
|
@@ -17960,9 +17902,9 @@ function buildWorkspaceHandlers(deps) {
|
|
|
17960
17902
|
|
|
17961
17903
|
// src/workspace/git.ts
|
|
17962
17904
|
var import_node_child_process5 = require("child_process");
|
|
17963
|
-
var
|
|
17905
|
+
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
17964
17906
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
17965
|
-
var
|
|
17907
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
17966
17908
|
var import_node_util = require("util");
|
|
17967
17909
|
var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
|
|
17968
17910
|
function formatChildProcessError(err) {
|
|
@@ -17977,9 +17919,9 @@ function formatChildProcessError(err) {
|
|
|
17977
17919
|
return e.message ?? "unknown error";
|
|
17978
17920
|
}
|
|
17979
17921
|
function normalizePath(p) {
|
|
17980
|
-
const resolved =
|
|
17922
|
+
const resolved = import_node_path15.default.resolve(p);
|
|
17981
17923
|
try {
|
|
17982
|
-
return
|
|
17924
|
+
return import_node_fs16.default.realpathSync(resolved);
|
|
17983
17925
|
} catch {
|
|
17984
17926
|
return resolved;
|
|
17985
17927
|
}
|
|
@@ -18080,13 +18022,13 @@ function flattenToDirName(branch) {
|
|
|
18080
18022
|
}
|
|
18081
18023
|
function encodeClaudeProjectDir(absPath) {
|
|
18082
18024
|
if (!absPath || typeof absPath !== "string") return "";
|
|
18083
|
-
let canonical =
|
|
18025
|
+
let canonical = import_node_path15.default.resolve(absPath);
|
|
18084
18026
|
try {
|
|
18085
|
-
canonical =
|
|
18027
|
+
canonical = import_node_fs16.default.realpathSync(canonical);
|
|
18086
18028
|
} catch {
|
|
18087
18029
|
try {
|
|
18088
|
-
const parent =
|
|
18089
|
-
canonical =
|
|
18030
|
+
const parent = import_node_fs16.default.realpathSync(import_node_path15.default.dirname(canonical));
|
|
18031
|
+
canonical = import_node_path15.default.join(parent, import_node_path15.default.basename(canonical));
|
|
18090
18032
|
} catch {
|
|
18091
18033
|
}
|
|
18092
18034
|
}
|
|
@@ -18110,11 +18052,11 @@ async function createWorktree(input) {
|
|
|
18110
18052
|
if (!isGitRoot) {
|
|
18111
18053
|
throw new Error(`\u76EE\u5F55 ${cwd} \u4E0D\u662F git repo \u6839`);
|
|
18112
18054
|
}
|
|
18113
|
-
const parent =
|
|
18114
|
-
if (parent === "/" || parent ===
|
|
18055
|
+
const parent = import_node_path15.default.dirname(import_node_path15.default.resolve(cwd));
|
|
18056
|
+
if (parent === "/" || parent === import_node_path15.default.resolve(cwd)) {
|
|
18115
18057
|
throw new Error("repo \u5728\u78C1\u76D8\u6839\u76EE\u5F55\uFF0C\u65E0\u6CD5\u5728\u540C\u7EA7\u521B\u5EFA worktree");
|
|
18116
18058
|
}
|
|
18117
|
-
const worktreeRoot =
|
|
18059
|
+
const worktreeRoot = import_node_path15.default.join(parent, dirName);
|
|
18118
18060
|
try {
|
|
18119
18061
|
await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${baseBranch}`], {
|
|
18120
18062
|
timeout: 3e3
|
|
@@ -18131,7 +18073,7 @@ async function createWorktree(input) {
|
|
|
18131
18073
|
const msg = err.message;
|
|
18132
18074
|
if (msg.startsWith("\u5206\u652F ")) throw err;
|
|
18133
18075
|
}
|
|
18134
|
-
if (
|
|
18076
|
+
if (import_node_fs16.default.existsSync(worktreeRoot)) {
|
|
18135
18077
|
throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
|
|
18136
18078
|
}
|
|
18137
18079
|
try {
|
|
@@ -18159,8 +18101,8 @@ async function removeWorktree(input) {
|
|
|
18159
18101
|
);
|
|
18160
18102
|
const gitCommonDir = stdout.trim();
|
|
18161
18103
|
if (!gitCommonDir) throw new Error("empty git-common-dir");
|
|
18162
|
-
const absGitCommon =
|
|
18163
|
-
repoRoot =
|
|
18104
|
+
const absGitCommon = import_node_path15.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path15.default.resolve(worktreeRoot, gitCommonDir);
|
|
18105
|
+
repoRoot = import_node_path15.default.dirname(absGitCommon);
|
|
18164
18106
|
} catch {
|
|
18165
18107
|
repoRoot = null;
|
|
18166
18108
|
}
|
|
@@ -18172,7 +18114,7 @@ async function removeWorktree(input) {
|
|
|
18172
18114
|
} catch (err) {
|
|
18173
18115
|
const stderr = err.stderr ?? "";
|
|
18174
18116
|
const lower = stderr.toLowerCase();
|
|
18175
|
-
const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !
|
|
18117
|
+
const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs16.default.existsSync(worktreeRoot);
|
|
18176
18118
|
if (!vanished) {
|
|
18177
18119
|
throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
|
|
18178
18120
|
}
|
|
@@ -18191,10 +18133,10 @@ async function removeWorktree(input) {
|
|
|
18191
18133
|
try {
|
|
18192
18134
|
const encoded = encodeClaudeProjectDir(worktreeRoot);
|
|
18193
18135
|
if (encoded) {
|
|
18194
|
-
const projectsRoot =
|
|
18195
|
-
const target =
|
|
18196
|
-
if (target.startsWith(projectsRoot +
|
|
18197
|
-
|
|
18136
|
+
const projectsRoot = import_node_path15.default.join(import_node_os10.default.homedir(), ".claude", "projects");
|
|
18137
|
+
const target = import_node_path15.default.resolve(projectsRoot, encoded);
|
|
18138
|
+
if (target.startsWith(projectsRoot + import_node_path15.default.sep) && target !== projectsRoot) {
|
|
18139
|
+
import_node_fs16.default.rmSync(target, { recursive: true, force: true });
|
|
18198
18140
|
}
|
|
18199
18141
|
}
|
|
18200
18142
|
} catch {
|
|
@@ -18321,7 +18263,7 @@ function buildMethodHandlers(deps) {
|
|
|
18321
18263
|
async function startDaemon(config) {
|
|
18322
18264
|
const logger = createLogger({
|
|
18323
18265
|
level: config.logLevel,
|
|
18324
|
-
file:
|
|
18266
|
+
file: import_node_path16.default.join(config.dataDir, "clawd.log")
|
|
18325
18267
|
});
|
|
18326
18268
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
18327
18269
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
@@ -18361,7 +18303,6 @@ async function startDaemon(config) {
|
|
|
18361
18303
|
logger,
|
|
18362
18304
|
getAdapter,
|
|
18363
18305
|
historyReader: history,
|
|
18364
|
-
dataDir: config.dataDir,
|
|
18365
18306
|
broadcastFrame: (frame, target) => {
|
|
18366
18307
|
if (target === "all") {
|
|
18367
18308
|
transport?.broadcastAll(frame);
|
|
@@ -18484,8 +18425,8 @@ async function startDaemon(config) {
|
|
|
18484
18425
|
const lines = [
|
|
18485
18426
|
`Tunnel: ${r.url}`,
|
|
18486
18427
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
18487
|
-
`Frpc config: ${
|
|
18488
|
-
`Frpc log: ${
|
|
18428
|
+
`Frpc config: ${import_node_path16.default.join(config.dataDir, "frpc.toml")}`,
|
|
18429
|
+
`Frpc log: ${import_node_path16.default.join(config.dataDir, "frpc.log")}`
|
|
18489
18430
|
];
|
|
18490
18431
|
const width = Math.max(...lines.map((l) => l.length));
|
|
18491
18432
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -18498,8 +18439,8 @@ ${bar}
|
|
|
18498
18439
|
|
|
18499
18440
|
`);
|
|
18500
18441
|
try {
|
|
18501
|
-
const connectPath =
|
|
18502
|
-
|
|
18442
|
+
const connectPath = import_node_path16.default.join(config.dataDir, "connect.txt");
|
|
18443
|
+
import_node_fs17.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
18503
18444
|
} catch {
|
|
18504
18445
|
}
|
|
18505
18446
|
} catch (err) {
|