@clawos-dev/clawd 0.2.24 → 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 -364
- 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);
|
|
@@ -8144,7 +8144,6 @@ var METHOD_NAMES = [
|
|
|
8144
8144
|
"session:subscribe",
|
|
8145
8145
|
"session:unsubscribe",
|
|
8146
8146
|
"session:pin",
|
|
8147
|
-
"session:reorderPins",
|
|
8148
8147
|
"permission:respond",
|
|
8149
8148
|
// AskUserQuestion 表单回写:UI 答完所有 question 后调用,daemon 把答案合并进 updated_input
|
|
8150
8149
|
// 写一条 control_response 到 CC stdin(详见 events.ts session:question JSDoc)
|
|
@@ -8687,8 +8686,8 @@ function getErrorMap() {
|
|
|
8687
8686
|
|
|
8688
8687
|
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
8689
8688
|
var makeIssue = (params) => {
|
|
8690
|
-
const { data, path:
|
|
8691
|
-
const fullPath = [...
|
|
8689
|
+
const { data, path: path17, errorMaps, issueData } = params;
|
|
8690
|
+
const fullPath = [...path17, ...issueData.path || []];
|
|
8692
8691
|
const fullIssue = {
|
|
8693
8692
|
...issueData,
|
|
8694
8693
|
path: fullPath
|
|
@@ -8804,11 +8803,11 @@ var errorUtil;
|
|
|
8804
8803
|
|
|
8805
8804
|
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
8806
8805
|
var ParseInputLazyPath = class {
|
|
8807
|
-
constructor(parent, value,
|
|
8806
|
+
constructor(parent, value, path17, key) {
|
|
8808
8807
|
this._cachedPath = [];
|
|
8809
8808
|
this.parent = parent;
|
|
8810
8809
|
this.data = value;
|
|
8811
|
-
this._path =
|
|
8810
|
+
this._path = path17;
|
|
8812
8811
|
this._key = key;
|
|
8813
8812
|
}
|
|
8814
8813
|
get path() {
|
|
@@ -12327,9 +12326,6 @@ var SessionFileSchema = external_exports.object({
|
|
|
12327
12326
|
permissionRules: external_exports.array(AllowRuleSchema).optional(),
|
|
12328
12327
|
// Sidebar 置顶时间戳;null/undefined 表示未置顶
|
|
12329
12328
|
pinnedAt: external_exports.number().int().nonnegative().nullable().optional(),
|
|
12330
|
-
// pinned 行手动拖拽顺序;越小越靠前。session:reorderPins 整体重写所有 pinned 的此字段。
|
|
12331
|
-
// 缺失时 view-state 排序回退到 pinnedAt desc(旧数据兼容)
|
|
12332
|
-
pinSortOrder: external_exports.number().int().nullable().optional(),
|
|
12333
12329
|
// 用户在 NewSessionDialog 或 Edit modal 选择的 icon 标识;UI 端做 enum 兜底
|
|
12334
12330
|
iconKey: external_exports.string().optional(),
|
|
12335
12331
|
// NewSessionDialog 勾选 worktree 创建的 session 才会持久化这两个字段
|
|
@@ -12661,9 +12657,6 @@ var SessionPinArgs = external_exports.object({
|
|
|
12661
12657
|
sessionId: external_exports.string().min(1),
|
|
12662
12658
|
pinned: external_exports.boolean()
|
|
12663
12659
|
});
|
|
12664
|
-
var SessionReorderPinsArgs = external_exports.object({
|
|
12665
|
-
orderedIds: external_exports.array(external_exports.string().min(1)).min(1)
|
|
12666
|
-
});
|
|
12667
12660
|
var GitRootArgs = external_exports.object({ cwd: external_exports.string().min(1) });
|
|
12668
12661
|
var GitRootResponseSchema = external_exports.object({
|
|
12669
12662
|
isGitRoot: external_exports.boolean(),
|
|
@@ -12819,7 +12812,7 @@ var SessionStore = class {
|
|
|
12819
12812
|
};
|
|
12820
12813
|
|
|
12821
12814
|
// src/session/manager.ts
|
|
12822
|
-
var
|
|
12815
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
12823
12816
|
|
|
12824
12817
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
12825
12818
|
var byteToHex = [];
|
|
@@ -13408,56 +13401,16 @@ function reduceSession(state, input, deps) {
|
|
|
13408
13401
|
}
|
|
13409
13402
|
}
|
|
13410
13403
|
|
|
13411
|
-
// src/
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
|
|
13419
|
-
if (!opts.dataDir) return null;
|
|
13420
|
-
if (!opts.sessionId || opts.sessionId.includes("..") || opts.sessionId.includes("/") || opts.sessionId.includes("\\") || opts.sessionId.startsWith(".")) {
|
|
13421
|
-
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);
|
|
13422
13412
|
}
|
|
13423
|
-
|
|
13424
|
-
const dir = import_node_path4.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
|
|
13425
|
-
const filePath = import_node_path4.default.join(dir, `${tsForFilename(now())}.jsonl`);
|
|
13426
|
-
let stream = null;
|
|
13427
|
-
let closedResolve;
|
|
13428
|
-
const closed = new Promise((resolve) => {
|
|
13429
|
-
closedResolve = resolve;
|
|
13430
|
-
});
|
|
13431
|
-
let exited = false;
|
|
13432
|
-
const ensureStream = () => {
|
|
13433
|
-
if (stream) return stream;
|
|
13434
|
-
import_node_fs4.default.mkdirSync(dir, { recursive: true });
|
|
13435
|
-
stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
|
|
13436
|
-
stream.on("close", () => closedResolve());
|
|
13437
|
-
return stream;
|
|
13438
|
-
};
|
|
13439
|
-
const writeLine = (s, chunk) => {
|
|
13440
|
-
if (exited) return;
|
|
13441
|
-
const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
13442
|
-
const line = JSON.stringify({ ts: now(), stream: s, chunk: text }) + "\n";
|
|
13443
|
-
ensureStream().write(line);
|
|
13444
|
-
};
|
|
13445
|
-
opts.proc.stdout?.on("data", (chunk) => writeLine("stdout", chunk));
|
|
13446
|
-
opts.proc.stderr?.on("data", (chunk) => writeLine("stderr", chunk));
|
|
13447
|
-
opts.proc.on("exit", () => {
|
|
13448
|
-
exited = true;
|
|
13449
|
-
if (stream) {
|
|
13450
|
-
stream.end();
|
|
13451
|
-
} else {
|
|
13452
|
-
closedResolve();
|
|
13453
|
-
}
|
|
13454
|
-
});
|
|
13455
|
-
return {
|
|
13456
|
-
tapStdinWrite(chunk) {
|
|
13457
|
-
writeLine("stdin", chunk);
|
|
13458
|
-
},
|
|
13459
|
-
closed
|
|
13460
|
-
};
|
|
13413
|
+
return { newBuf: next, lines };
|
|
13461
13414
|
}
|
|
13462
13415
|
|
|
13463
13416
|
// src/session/runner.ts
|
|
@@ -13490,8 +13443,6 @@ var SessionRunner = class {
|
|
|
13490
13443
|
pendingControlRequests = /* @__PURE__ */ new Map();
|
|
13491
13444
|
// waitUntilStopped 排队的 resolve 回调;reducer 把 procAlive 翻成 false 后批量触发
|
|
13492
13445
|
stopWaiters = [];
|
|
13493
|
-
// IPC recorder(CLAWD_RECORD_IPC=1 时启用);null 表示当前 spawn 未启用 / 已退出
|
|
13494
|
-
recorder = null;
|
|
13495
13446
|
getState() {
|
|
13496
13447
|
return this.state;
|
|
13497
13448
|
}
|
|
@@ -13581,7 +13532,6 @@ var SessionRunner = class {
|
|
|
13581
13532
|
this.pendingControlRequests.set(requestId, { resolve, reject, timer });
|
|
13582
13533
|
try {
|
|
13583
13534
|
proc.stdin?.write(payload);
|
|
13584
|
-
this.recorder?.tapStdinWrite(payload);
|
|
13585
13535
|
} catch (err) {
|
|
13586
13536
|
clearTimeout(timer);
|
|
13587
13537
|
this.pendingControlRequests.delete(requestId);
|
|
@@ -13637,14 +13587,10 @@ var SessionRunner = class {
|
|
|
13637
13587
|
break;
|
|
13638
13588
|
case "write-stdin":
|
|
13639
13589
|
this.proc?.stdin?.write(effect.payload);
|
|
13640
|
-
this.recorder?.tapStdinWrite(effect.payload);
|
|
13641
13590
|
break;
|
|
13642
|
-
case "send-control-response-allow-with-input":
|
|
13643
|
-
|
|
13644
|
-
this.proc?.stdin?.write(payload);
|
|
13645
|
-
this.recorder?.tapStdinWrite(payload);
|
|
13591
|
+
case "send-control-response-allow-with-input":
|
|
13592
|
+
this.proc?.stdin?.write(encodeAllowWithInputControlResponse(effect.requestId, effect.updatedInput));
|
|
13646
13593
|
break;
|
|
13647
|
-
}
|
|
13648
13594
|
case "persist-file":
|
|
13649
13595
|
try {
|
|
13650
13596
|
this.hooks.store.write(effect.file);
|
|
@@ -13674,19 +13620,10 @@ var SessionRunner = class {
|
|
|
13674
13620
|
const proc = this.hooks.spawnOverride ? this.hooks.spawnOverride(ctx) : this.hooks.adapter.spawn(ctx);
|
|
13675
13621
|
this.proc = proc;
|
|
13676
13622
|
this.stdoutBuf = "";
|
|
13677
|
-
this.recorder = startRecorder({
|
|
13678
|
-
proc,
|
|
13679
|
-
sessionId: this.state.file.sessionId,
|
|
13680
|
-
dataDir: this.hooks.dataDir,
|
|
13681
|
-
env: this.hooks.recordEnv ?? process.env,
|
|
13682
|
-
now: this.hooks.now
|
|
13683
|
-
});
|
|
13684
13623
|
proc.stdout?.on("data", (chunk) => {
|
|
13685
|
-
|
|
13686
|
-
|
|
13687
|
-
|
|
13688
|
-
const line = this.stdoutBuf.slice(0, idx);
|
|
13689
|
-
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) {
|
|
13690
13627
|
if (this.tryHandleControlResponse(line)) continue;
|
|
13691
13628
|
this.input({ kind: "stdout-line", line });
|
|
13692
13629
|
}
|
|
@@ -13697,7 +13634,6 @@ var SessionRunner = class {
|
|
|
13697
13634
|
});
|
|
13698
13635
|
proc.on("exit", (code) => {
|
|
13699
13636
|
this.proc = null;
|
|
13700
|
-
this.recorder = null;
|
|
13701
13637
|
this.rejectAllPending(new Error("session gone"));
|
|
13702
13638
|
this.input({ kind: "proc-exit", code });
|
|
13703
13639
|
});
|
|
@@ -13824,8 +13760,7 @@ var SessionManager = class {
|
|
|
13824
13760
|
now: this.deps.now,
|
|
13825
13761
|
bufferCap: this.deps.bufferCap,
|
|
13826
13762
|
// adapter 自己持有模型表 + 兜底逻辑(contains / opus-1M / [1m] 等),manager 不再 cache 转发
|
|
13827
|
-
resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId)
|
|
13828
|
-
dataDir: this.deps.dataDir
|
|
13763
|
+
resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId)
|
|
13829
13764
|
});
|
|
13830
13765
|
return runner;
|
|
13831
13766
|
}
|
|
@@ -13856,7 +13791,7 @@ var SessionManager = class {
|
|
|
13856
13791
|
// ---- 命令方法:均返回 { response, broadcast[] },由 dispatcher 聚合 ----
|
|
13857
13792
|
create(args) {
|
|
13858
13793
|
try {
|
|
13859
|
-
const stat =
|
|
13794
|
+
const stat = import_node_fs4.default.statSync(args.cwd);
|
|
13860
13795
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
13861
13796
|
} catch {
|
|
13862
13797
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -13897,49 +13832,6 @@ var SessionManager = class {
|
|
|
13897
13832
|
this.deps.store.write(updated);
|
|
13898
13833
|
return { response: updated, broadcast: [] };
|
|
13899
13834
|
}
|
|
13900
|
-
// sidebar 拖拽完成 → 整体重写 pinned root 的 pinSortOrder(按 orderedIds 下标 0,1,2...)
|
|
13901
|
-
// orderedIds 必须正好覆盖所有当前 pinned root(既不能漏,也不能含 unpinned id)
|
|
13902
|
-
reorderPins(args) {
|
|
13903
|
-
const all = this.deps.store.list();
|
|
13904
|
-
const currentPinnedIds = new Set(
|
|
13905
|
-
all.filter((f) => typeof f.pinnedAt === "number").map((f) => f.sessionId)
|
|
13906
|
-
);
|
|
13907
|
-
const incoming = new Set(args.orderedIds);
|
|
13908
|
-
if (incoming.size !== args.orderedIds.length) {
|
|
13909
|
-
throw new Error("reorderPins: orderedIds contains duplicate ids");
|
|
13910
|
-
}
|
|
13911
|
-
if (currentPinnedIds.size !== incoming.size || [...currentPinnedIds].some((id) => !incoming.has(id))) {
|
|
13912
|
-
throw new Error(
|
|
13913
|
-
"reorderPins: orderedIds must cover exactly the current pinned root set"
|
|
13914
|
-
);
|
|
13915
|
-
}
|
|
13916
|
-
const broadcast = [];
|
|
13917
|
-
const updatedFiles = [];
|
|
13918
|
-
args.orderedIds.forEach((sessionId, index) => {
|
|
13919
|
-
const runner = this.runners.get(sessionId);
|
|
13920
|
-
if (runner) {
|
|
13921
|
-
const { value, broadcast: b } = this.withCollector(() => {
|
|
13922
|
-
runner.input({
|
|
13923
|
-
kind: "command",
|
|
13924
|
-
command: { kind: "update", patch: { pinSortOrder: index } }
|
|
13925
|
-
});
|
|
13926
|
-
return runner.getState().file;
|
|
13927
|
-
});
|
|
13928
|
-
updatedFiles.push(value);
|
|
13929
|
-
broadcast.push(...b);
|
|
13930
|
-
} else {
|
|
13931
|
-
const existing = this.getFile(sessionId);
|
|
13932
|
-
const updated = {
|
|
13933
|
-
...existing,
|
|
13934
|
-
pinSortOrder: index,
|
|
13935
|
-
updatedAt: nowIso2(this.deps)
|
|
13936
|
-
};
|
|
13937
|
-
this.deps.store.write(updated);
|
|
13938
|
-
updatedFiles.push(updated);
|
|
13939
|
-
}
|
|
13940
|
-
});
|
|
13941
|
-
return { response: { sessions: updatedFiles }, broadcast };
|
|
13942
|
-
}
|
|
13943
13835
|
list() {
|
|
13944
13836
|
return { response: { sessions: this.deps.store.list() }, broadcast: [] };
|
|
13945
13837
|
}
|
|
@@ -14345,14 +14237,14 @@ var SessionManager = class {
|
|
|
14345
14237
|
// src/tools/claude.ts
|
|
14346
14238
|
var import_node_child_process = require("child_process");
|
|
14347
14239
|
var import_node_child_process2 = require("child_process");
|
|
14348
|
-
var
|
|
14240
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
14349
14241
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
14350
|
-
var
|
|
14242
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
14351
14243
|
|
|
14352
14244
|
// src/tools/claude-history.ts
|
|
14353
|
-
var
|
|
14245
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
14354
14246
|
var import_node_os2 = __toESM(require("os"), 1);
|
|
14355
|
-
var
|
|
14247
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
14356
14248
|
|
|
14357
14249
|
// ../node_modules/.pnpm/diff@7.0.0/node_modules/diff/lib/index.mjs
|
|
14358
14250
|
function Diff() {
|
|
@@ -14456,11 +14348,11 @@ Diff.prototype = {
|
|
|
14456
14348
|
}
|
|
14457
14349
|
}
|
|
14458
14350
|
},
|
|
14459
|
-
addToPath: function addToPath(
|
|
14460
|
-
var last =
|
|
14351
|
+
addToPath: function addToPath(path17, added, removed, oldPosInc, options) {
|
|
14352
|
+
var last = path17.lastComponent;
|
|
14461
14353
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14462
14354
|
return {
|
|
14463
|
-
oldPos:
|
|
14355
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
14464
14356
|
lastComponent: {
|
|
14465
14357
|
count: last.count + 1,
|
|
14466
14358
|
added,
|
|
@@ -14470,7 +14362,7 @@ Diff.prototype = {
|
|
|
14470
14362
|
};
|
|
14471
14363
|
} else {
|
|
14472
14364
|
return {
|
|
14473
|
-
oldPos:
|
|
14365
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
14474
14366
|
lastComponent: {
|
|
14475
14367
|
count: 1,
|
|
14476
14368
|
added,
|
|
@@ -15129,7 +15021,7 @@ function hashDirToCwd(hash) {
|
|
|
15129
15021
|
}
|
|
15130
15022
|
function safeStatMtime(p) {
|
|
15131
15023
|
try {
|
|
15132
|
-
return
|
|
15024
|
+
return import_node_fs5.default.statSync(p).mtimeMs;
|
|
15133
15025
|
} catch {
|
|
15134
15026
|
return 0;
|
|
15135
15027
|
}
|
|
@@ -15137,7 +15029,7 @@ function safeStatMtime(p) {
|
|
|
15137
15029
|
function readJsonlLines(file) {
|
|
15138
15030
|
let raw;
|
|
15139
15031
|
try {
|
|
15140
|
-
raw =
|
|
15032
|
+
raw = import_node_fs5.default.readFileSync(file, "utf8");
|
|
15141
15033
|
} catch (err) {
|
|
15142
15034
|
if (err.code === "ENOENT") return [];
|
|
15143
15035
|
throw err;
|
|
@@ -15329,10 +15221,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
15329
15221
|
const memories = raw.map((m) => {
|
|
15330
15222
|
if (!m || typeof m !== "object") return null;
|
|
15331
15223
|
const rec = m;
|
|
15332
|
-
const
|
|
15224
|
+
const path17 = typeof rec.path === "string" ? rec.path : null;
|
|
15333
15225
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
15334
|
-
if (!
|
|
15335
|
-
const entry = { path:
|
|
15226
|
+
if (!path17 || content == null) return null;
|
|
15227
|
+
const entry = { path: path17, content };
|
|
15336
15228
|
if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
|
|
15337
15229
|
return entry;
|
|
15338
15230
|
}).filter((m) => m !== null);
|
|
@@ -15368,8 +15260,8 @@ function attachmentDeferredToolsText(a) {
|
|
|
15368
15260
|
function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
15369
15261
|
if (backupFileName === null) return null;
|
|
15370
15262
|
try {
|
|
15371
|
-
return
|
|
15372
|
-
|
|
15263
|
+
return import_node_fs5.default.readFileSync(
|
|
15264
|
+
import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
15373
15265
|
"utf8"
|
|
15374
15266
|
);
|
|
15375
15267
|
} catch {
|
|
@@ -15378,7 +15270,7 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
15378
15270
|
}
|
|
15379
15271
|
function readCurrentContent(filePath) {
|
|
15380
15272
|
try {
|
|
15381
|
-
return
|
|
15273
|
+
return import_node_fs5.default.readFileSync(filePath, "utf8");
|
|
15382
15274
|
} catch (err) {
|
|
15383
15275
|
if (err.code === "ENOENT") return null;
|
|
15384
15276
|
return null;
|
|
@@ -15390,14 +15282,14 @@ var ClaudeHistoryReader = class {
|
|
|
15390
15282
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
15391
15283
|
fileHistoryRoot;
|
|
15392
15284
|
constructor(opts = {}) {
|
|
15393
|
-
const base = opts.baseDir ??
|
|
15394
|
-
this.projectsRoot =
|
|
15395
|
-
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");
|
|
15396
15288
|
}
|
|
15397
15289
|
async listProjects() {
|
|
15398
15290
|
let entries;
|
|
15399
15291
|
try {
|
|
15400
|
-
entries =
|
|
15292
|
+
entries = import_node_fs5.default.readdirSync(this.projectsRoot, { withFileTypes: true });
|
|
15401
15293
|
} catch (err) {
|
|
15402
15294
|
if (err.code === "ENOENT") return [];
|
|
15403
15295
|
throw err;
|
|
@@ -15405,9 +15297,9 @@ var ClaudeHistoryReader = class {
|
|
|
15405
15297
|
const out = [];
|
|
15406
15298
|
for (const ent of entries) {
|
|
15407
15299
|
if (!ent.isDirectory()) continue;
|
|
15408
|
-
const dir =
|
|
15409
|
-
const files =
|
|
15410
|
-
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);
|
|
15411
15303
|
out.push({
|
|
15412
15304
|
projectPath: hashDirToCwd(ent.name),
|
|
15413
15305
|
hashDir: ent.name,
|
|
@@ -15419,17 +15311,17 @@ var ClaudeHistoryReader = class {
|
|
|
15419
15311
|
return out;
|
|
15420
15312
|
}
|
|
15421
15313
|
async listSessions(args) {
|
|
15422
|
-
const dir =
|
|
15314
|
+
const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
15423
15315
|
let files;
|
|
15424
15316
|
try {
|
|
15425
|
-
files =
|
|
15317
|
+
files = import_node_fs5.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
15426
15318
|
} catch (err) {
|
|
15427
15319
|
if (err.code === "ENOENT") return [];
|
|
15428
15320
|
throw err;
|
|
15429
15321
|
}
|
|
15430
15322
|
const out = [];
|
|
15431
15323
|
for (const f of files) {
|
|
15432
|
-
const full =
|
|
15324
|
+
const full = import_node_path4.default.join(dir, f);
|
|
15433
15325
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
15434
15326
|
const lines = readJsonlLines(full);
|
|
15435
15327
|
let summary = "";
|
|
@@ -15484,7 +15376,7 @@ var ClaudeHistoryReader = class {
|
|
|
15484
15376
|
return out;
|
|
15485
15377
|
}
|
|
15486
15378
|
async read(args) {
|
|
15487
|
-
const file =
|
|
15379
|
+
const file = import_node_path4.default.join(
|
|
15488
15380
|
this.projectsRoot,
|
|
15489
15381
|
cwdToHashDir(args.cwd),
|
|
15490
15382
|
`${args.toolSessionId}.jsonl`
|
|
@@ -15517,7 +15409,7 @@ var ClaudeHistoryReader = class {
|
|
|
15517
15409
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
15518
15410
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
15519
15411
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
15520
|
-
const dir =
|
|
15412
|
+
const dir = import_node_path4.default.join(
|
|
15521
15413
|
this.projectsRoot,
|
|
15522
15414
|
cwdToHashDir(cwd),
|
|
15523
15415
|
toolSessionId,
|
|
@@ -15525,7 +15417,7 @@ var ClaudeHistoryReader = class {
|
|
|
15525
15417
|
);
|
|
15526
15418
|
let entries;
|
|
15527
15419
|
try {
|
|
15528
|
-
entries =
|
|
15420
|
+
entries = import_node_fs5.default.readdirSync(dir, { withFileTypes: true });
|
|
15529
15421
|
} catch (err) {
|
|
15530
15422
|
if (err.code === "ENOENT") return null;
|
|
15531
15423
|
return null;
|
|
@@ -15535,7 +15427,7 @@ var ClaudeHistoryReader = class {
|
|
|
15535
15427
|
if (!e.isFile()) continue;
|
|
15536
15428
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
15537
15429
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
15538
|
-
const filePath =
|
|
15430
|
+
const filePath = import_node_path4.default.join(dir, e.name);
|
|
15539
15431
|
const lines = readJsonlLines(filePath);
|
|
15540
15432
|
let firstText = "";
|
|
15541
15433
|
let messageCount = 0;
|
|
@@ -15552,7 +15444,7 @@ var ClaudeHistoryReader = class {
|
|
|
15552
15444
|
return out;
|
|
15553
15445
|
}
|
|
15554
15446
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
15555
|
-
const file =
|
|
15447
|
+
const file = import_node_path4.default.join(
|
|
15556
15448
|
this.projectsRoot,
|
|
15557
15449
|
cwdToHashDir(cwd),
|
|
15558
15450
|
`${toolSessionId}.jsonl`
|
|
@@ -15587,7 +15479,7 @@ var ClaudeHistoryReader = class {
|
|
|
15587
15479
|
}
|
|
15588
15480
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
15589
15481
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
15590
|
-
const file =
|
|
15482
|
+
const file = import_node_path4.default.join(
|
|
15591
15483
|
this.projectsRoot,
|
|
15592
15484
|
cwdToHashDir(cwd),
|
|
15593
15485
|
toolSessionId,
|
|
@@ -15596,7 +15488,7 @@ var ClaudeHistoryReader = class {
|
|
|
15596
15488
|
);
|
|
15597
15489
|
let exists = false;
|
|
15598
15490
|
try {
|
|
15599
|
-
exists =
|
|
15491
|
+
exists = import_node_fs5.default.statSync(file).isFile();
|
|
15600
15492
|
} catch {
|
|
15601
15493
|
return null;
|
|
15602
15494
|
}
|
|
@@ -15615,7 +15507,7 @@ var ClaudeHistoryReader = class {
|
|
|
15615
15507
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
15616
15508
|
*/
|
|
15617
15509
|
readFileHistorySnapshots(args) {
|
|
15618
|
-
const file =
|
|
15510
|
+
const file = import_node_path4.default.join(
|
|
15619
15511
|
this.projectsRoot,
|
|
15620
15512
|
cwdToHashDir(args.cwd),
|
|
15621
15513
|
`${args.toolSessionId}.jsonl`
|
|
@@ -15660,7 +15552,7 @@ var ClaudeHistoryReader = class {
|
|
|
15660
15552
|
for (const [anchorId, target] of snapshots) {
|
|
15661
15553
|
let hasAny = false;
|
|
15662
15554
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
15663
|
-
const absPath =
|
|
15555
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
15664
15556
|
const backupContent = readBackupContent(
|
|
15665
15557
|
this.fileHistoryRoot,
|
|
15666
15558
|
args.toolSessionId,
|
|
@@ -15700,7 +15592,7 @@ var ClaudeHistoryReader = class {
|
|
|
15700
15592
|
let totalInsertions = 0;
|
|
15701
15593
|
let totalDeletions = 0;
|
|
15702
15594
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
15703
|
-
const absPath =
|
|
15595
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
15704
15596
|
const backupContent = readBackupContent(
|
|
15705
15597
|
this.fileHistoryRoot,
|
|
15706
15598
|
args.toolSessionId,
|
|
@@ -15747,7 +15639,7 @@ var ClaudeHistoryReader = class {
|
|
|
15747
15639
|
};
|
|
15748
15640
|
}
|
|
15749
15641
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
15750
|
-
const file =
|
|
15642
|
+
const file = import_node_path4.default.join(
|
|
15751
15643
|
this.projectsRoot,
|
|
15752
15644
|
cwdToHashDir(cwd),
|
|
15753
15645
|
`${toolSessionId}.jsonl`
|
|
@@ -15769,27 +15661,27 @@ var ClaudeHistoryReader = class {
|
|
|
15769
15661
|
// src/tools/claude.ts
|
|
15770
15662
|
function macOSDesktopCandidates(home) {
|
|
15771
15663
|
return [
|
|
15772
|
-
|
|
15664
|
+
import_node_path5.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
|
|
15773
15665
|
"/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
|
|
15774
15666
|
];
|
|
15775
15667
|
}
|
|
15776
15668
|
function probeViaWhich() {
|
|
15777
15669
|
try {
|
|
15778
15670
|
const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
|
|
15779
|
-
if (out &&
|
|
15671
|
+
if (out && import_node_fs6.default.existsSync(out)) return out;
|
|
15780
15672
|
} catch {
|
|
15781
15673
|
}
|
|
15782
15674
|
return null;
|
|
15783
15675
|
}
|
|
15784
15676
|
async function probeClaude(env = process.env, home = import_node_os3.default.homedir()) {
|
|
15785
|
-
if (env.CLAUDE_BIN &&
|
|
15677
|
+
if (env.CLAUDE_BIN && import_node_fs6.default.existsSync(env.CLAUDE_BIN)) {
|
|
15786
15678
|
return { available: true, path: env.CLAUDE_BIN };
|
|
15787
15679
|
}
|
|
15788
15680
|
const w = probeViaWhich();
|
|
15789
15681
|
if (w) return { available: true, path: w };
|
|
15790
15682
|
if (process.platform === "darwin") {
|
|
15791
15683
|
for (const candidate of macOSDesktopCandidates(home)) {
|
|
15792
|
-
if (
|
|
15684
|
+
if (import_node_fs6.default.existsSync(candidate)) {
|
|
15793
15685
|
return { available: true, path: candidate };
|
|
15794
15686
|
}
|
|
15795
15687
|
}
|
|
@@ -16100,10 +15992,10 @@ function parseAttachment(obj) {
|
|
|
16100
15992
|
const memories = raw.map((m) => {
|
|
16101
15993
|
if (!m || typeof m !== "object") return null;
|
|
16102
15994
|
const rec = m;
|
|
16103
|
-
const
|
|
15995
|
+
const path17 = typeof rec.path === "string" ? rec.path : null;
|
|
16104
15996
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
16105
|
-
if (!
|
|
16106
|
-
const out = { path:
|
|
15997
|
+
if (!path17 || content == null) return null;
|
|
15998
|
+
const out = { path: path17, content };
|
|
16107
15999
|
if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
|
|
16108
16000
|
return out;
|
|
16109
16001
|
}).filter((m) => m !== null);
|
|
@@ -16331,22 +16223,22 @@ var ClaudeAdapter = class {
|
|
|
16331
16223
|
};
|
|
16332
16224
|
|
|
16333
16225
|
// src/workspace/browser.ts
|
|
16334
|
-
var
|
|
16226
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
16335
16227
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
16336
|
-
var
|
|
16228
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
16337
16229
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
16338
16230
|
function resolveInsideCwd(cwd, subpath) {
|
|
16339
|
-
const absCwd =
|
|
16340
|
-
const joined =
|
|
16341
|
-
const rel =
|
|
16342
|
-
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)) {
|
|
16343
16235
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
16344
16236
|
}
|
|
16345
16237
|
return joined;
|
|
16346
16238
|
}
|
|
16347
16239
|
function ensureCwd(cwd) {
|
|
16348
16240
|
try {
|
|
16349
|
-
const stat =
|
|
16241
|
+
const stat = import_node_fs7.default.statSync(cwd);
|
|
16350
16242
|
if (!stat.isDirectory()) {
|
|
16351
16243
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
16352
16244
|
}
|
|
@@ -16360,7 +16252,7 @@ var WorkspaceBrowser = class {
|
|
|
16360
16252
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os4.default.homedir();
|
|
16361
16253
|
ensureCwd(cwd);
|
|
16362
16254
|
const full = resolveInsideCwd(cwd, args.path);
|
|
16363
|
-
const dirents =
|
|
16255
|
+
const dirents = import_node_fs7.default.readdirSync(full, { withFileTypes: true });
|
|
16364
16256
|
const entries = [];
|
|
16365
16257
|
for (const d of dirents) {
|
|
16366
16258
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -16370,7 +16262,7 @@ var WorkspaceBrowser = class {
|
|
|
16370
16262
|
mtime: ""
|
|
16371
16263
|
};
|
|
16372
16264
|
try {
|
|
16373
|
-
const st =
|
|
16265
|
+
const st = import_node_fs7.default.statSync(import_node_path6.default.join(full, d.name));
|
|
16374
16266
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
16375
16267
|
if (d.isFile()) entry.size = st.size;
|
|
16376
16268
|
} catch {
|
|
@@ -16386,14 +16278,14 @@ var WorkspaceBrowser = class {
|
|
|
16386
16278
|
read(args) {
|
|
16387
16279
|
ensureCwd(args.cwd);
|
|
16388
16280
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
16389
|
-
const st =
|
|
16281
|
+
const st = import_node_fs7.default.statSync(full);
|
|
16390
16282
|
if (!st.isFile()) {
|
|
16391
16283
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
16392
16284
|
}
|
|
16393
16285
|
if (st.size > MAX_FILE_BYTES) {
|
|
16394
16286
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
16395
16287
|
}
|
|
16396
|
-
const buf =
|
|
16288
|
+
const buf = import_node_fs7.default.readFileSync(full);
|
|
16397
16289
|
const isBinary = buf.includes(0);
|
|
16398
16290
|
if (isBinary) {
|
|
16399
16291
|
return {
|
|
@@ -16415,9 +16307,9 @@ var WorkspaceBrowser = class {
|
|
|
16415
16307
|
};
|
|
16416
16308
|
|
|
16417
16309
|
// src/skills/scanner.ts
|
|
16418
|
-
var
|
|
16310
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
16419
16311
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
16420
|
-
var
|
|
16312
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
16421
16313
|
function parseFrontmatter(content) {
|
|
16422
16314
|
if (!content.startsWith("---")) return { name: "", description: "" };
|
|
16423
16315
|
const end = content.indexOf("---", 3);
|
|
@@ -16453,7 +16345,7 @@ function parseFrontmatter(content) {
|
|
|
16453
16345
|
}
|
|
16454
16346
|
function isDirLikeSync(p) {
|
|
16455
16347
|
try {
|
|
16456
|
-
return
|
|
16348
|
+
return import_node_fs8.default.statSync(p).isDirectory();
|
|
16457
16349
|
} catch {
|
|
16458
16350
|
return false;
|
|
16459
16351
|
}
|
|
@@ -16461,19 +16353,19 @@ function isDirLikeSync(p) {
|
|
|
16461
16353
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
16462
16354
|
let entries;
|
|
16463
16355
|
try {
|
|
16464
|
-
entries =
|
|
16356
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
16465
16357
|
} catch {
|
|
16466
16358
|
return;
|
|
16467
16359
|
}
|
|
16468
16360
|
for (const ent of entries) {
|
|
16469
|
-
const entryPath =
|
|
16361
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
16470
16362
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
16471
16363
|
let content;
|
|
16472
16364
|
try {
|
|
16473
|
-
content =
|
|
16365
|
+
content = import_node_fs8.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
|
|
16474
16366
|
} catch {
|
|
16475
16367
|
try {
|
|
16476
|
-
content =
|
|
16368
|
+
content = import_node_fs8.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
|
|
16477
16369
|
} catch {
|
|
16478
16370
|
continue;
|
|
16479
16371
|
}
|
|
@@ -16491,26 +16383,26 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
|
16491
16383
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
16492
16384
|
let entries;
|
|
16493
16385
|
try {
|
|
16494
|
-
entries =
|
|
16386
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
16495
16387
|
} catch {
|
|
16496
16388
|
return;
|
|
16497
16389
|
}
|
|
16498
16390
|
for (const ent of entries) {
|
|
16499
|
-
const entryPath =
|
|
16391
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
16500
16392
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
16501
16393
|
const ns = ent.name;
|
|
16502
16394
|
let subEntries;
|
|
16503
16395
|
try {
|
|
16504
|
-
subEntries =
|
|
16396
|
+
subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
|
|
16505
16397
|
} catch {
|
|
16506
16398
|
continue;
|
|
16507
16399
|
}
|
|
16508
16400
|
for (const se of subEntries) {
|
|
16509
16401
|
if (!se.name.endsWith(".md")) continue;
|
|
16510
|
-
const sePath =
|
|
16402
|
+
const sePath = import_node_path7.default.join(entryPath, se.name);
|
|
16511
16403
|
let content;
|
|
16512
16404
|
try {
|
|
16513
|
-
content =
|
|
16405
|
+
content = import_node_fs8.default.readFileSync(sePath, "utf8");
|
|
16514
16406
|
} catch {
|
|
16515
16407
|
continue;
|
|
16516
16408
|
}
|
|
@@ -16527,7 +16419,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
16527
16419
|
} else if (ent.name.endsWith(".md")) {
|
|
16528
16420
|
let content;
|
|
16529
16421
|
try {
|
|
16530
|
-
content =
|
|
16422
|
+
content = import_node_fs8.default.readFileSync(entryPath, "utf8");
|
|
16531
16423
|
} catch {
|
|
16532
16424
|
continue;
|
|
16533
16425
|
}
|
|
@@ -16543,10 +16435,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
16543
16435
|
}
|
|
16544
16436
|
}
|
|
16545
16437
|
function readInstalledPlugins(home) {
|
|
16546
|
-
const file =
|
|
16438
|
+
const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
16547
16439
|
let raw;
|
|
16548
16440
|
try {
|
|
16549
|
-
raw =
|
|
16441
|
+
raw = import_node_fs8.default.readFileSync(file, "utf8");
|
|
16550
16442
|
} catch {
|
|
16551
16443
|
return [];
|
|
16552
16444
|
}
|
|
@@ -16584,14 +16476,14 @@ var SkillsScanner = class {
|
|
|
16584
16476
|
list(args) {
|
|
16585
16477
|
const seen = /* @__PURE__ */ new Set();
|
|
16586
16478
|
const out = [];
|
|
16587
|
-
scanSkillDir(
|
|
16588
|
-
scanCommandDir(
|
|
16589
|
-
scanSkillDir(
|
|
16590
|
-
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);
|
|
16591
16483
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
16592
16484
|
for (const { name, root } of plugins) {
|
|
16593
|
-
scanSkillDir(
|
|
16594
|
-
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);
|
|
16595
16487
|
}
|
|
16596
16488
|
out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
16597
16489
|
return out;
|
|
@@ -16599,9 +16491,9 @@ var SkillsScanner = class {
|
|
|
16599
16491
|
};
|
|
16600
16492
|
|
|
16601
16493
|
// src/observer/session-observer.ts
|
|
16602
|
-
var
|
|
16494
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
16603
16495
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
16604
|
-
var
|
|
16496
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
16605
16497
|
var SessionObserver = class {
|
|
16606
16498
|
constructor(opts) {
|
|
16607
16499
|
this.opts = opts;
|
|
@@ -16612,14 +16504,14 @@ var SessionObserver = class {
|
|
|
16612
16504
|
watches = /* @__PURE__ */ new Map();
|
|
16613
16505
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
16614
16506
|
if (override) return override;
|
|
16615
|
-
return
|
|
16507
|
+
return import_node_path8.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
16616
16508
|
}
|
|
16617
16509
|
start(args) {
|
|
16618
16510
|
this.stop(args.sessionId);
|
|
16619
16511
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
16620
16512
|
let size = 0;
|
|
16621
16513
|
try {
|
|
16622
|
-
size =
|
|
16514
|
+
size = import_node_fs9.default.statSync(filePath).size;
|
|
16623
16515
|
} catch {
|
|
16624
16516
|
}
|
|
16625
16517
|
const w = {
|
|
@@ -16632,10 +16524,10 @@ var SessionObserver = class {
|
|
|
16632
16524
|
adapter: args.adapter
|
|
16633
16525
|
};
|
|
16634
16526
|
try {
|
|
16635
|
-
|
|
16527
|
+
import_node_fs9.default.mkdirSync(import_node_path8.default.dirname(filePath), { recursive: true });
|
|
16636
16528
|
} catch {
|
|
16637
16529
|
}
|
|
16638
|
-
w.watcher =
|
|
16530
|
+
w.watcher = import_node_fs9.default.watch(import_node_path8.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
16639
16531
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
16640
16532
|
this.poll(w);
|
|
16641
16533
|
});
|
|
@@ -16650,7 +16542,7 @@ var SessionObserver = class {
|
|
|
16650
16542
|
// reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
|
|
16651
16543
|
hydrateMetaTail(w, maxLines = 200) {
|
|
16652
16544
|
try {
|
|
16653
|
-
const raw =
|
|
16545
|
+
const raw = import_node_fs9.default.readFileSync(w.filePath, "utf8");
|
|
16654
16546
|
if (!raw) return;
|
|
16655
16547
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
16656
16548
|
if (allLines.length === 0) return;
|
|
@@ -16671,7 +16563,7 @@ var SessionObserver = class {
|
|
|
16671
16563
|
poll(w) {
|
|
16672
16564
|
let size = 0;
|
|
16673
16565
|
try {
|
|
16674
|
-
size =
|
|
16566
|
+
size = import_node_fs9.default.statSync(w.filePath).size;
|
|
16675
16567
|
} catch {
|
|
16676
16568
|
return;
|
|
16677
16569
|
}
|
|
@@ -16680,11 +16572,11 @@ var SessionObserver = class {
|
|
|
16680
16572
|
w.buf = "";
|
|
16681
16573
|
}
|
|
16682
16574
|
if (size === w.lastSize) return;
|
|
16683
|
-
const fd =
|
|
16575
|
+
const fd = import_node_fs9.default.openSync(w.filePath, "r");
|
|
16684
16576
|
try {
|
|
16685
16577
|
const len = size - w.lastSize;
|
|
16686
16578
|
const buf = Buffer.alloc(len);
|
|
16687
|
-
|
|
16579
|
+
import_node_fs9.default.readSync(fd, buf, 0, len, w.lastSize);
|
|
16688
16580
|
w.lastSize = size;
|
|
16689
16581
|
w.buf += buf.toString("utf8");
|
|
16690
16582
|
let newlineIndex;
|
|
@@ -16698,7 +16590,7 @@ var SessionObserver = class {
|
|
|
16698
16590
|
this.maybeReportUserMessage(w.sessionId, line);
|
|
16699
16591
|
}
|
|
16700
16592
|
} finally {
|
|
16701
|
-
|
|
16593
|
+
import_node_fs9.default.closeSync(fd);
|
|
16702
16594
|
}
|
|
16703
16595
|
}
|
|
16704
16596
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -17113,10 +17005,10 @@ function isLocalhost(addr) {
|
|
|
17113
17005
|
}
|
|
17114
17006
|
|
|
17115
17007
|
// src/discovery/state-file.ts
|
|
17116
|
-
var
|
|
17117
|
-
var
|
|
17008
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
17009
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
17118
17010
|
function defaultStateFilePath(dataDir) {
|
|
17119
|
-
return
|
|
17011
|
+
return import_node_path9.default.join(dataDir, "state.json");
|
|
17120
17012
|
}
|
|
17121
17013
|
function isPidAlive(pid) {
|
|
17122
17014
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -17138,7 +17030,7 @@ var StateFileManager = class {
|
|
|
17138
17030
|
}
|
|
17139
17031
|
read() {
|
|
17140
17032
|
try {
|
|
17141
|
-
const raw =
|
|
17033
|
+
const raw = import_node_fs10.default.readFileSync(this.file, "utf8");
|
|
17142
17034
|
const parsed = JSON.parse(raw);
|
|
17143
17035
|
return parsed;
|
|
17144
17036
|
} catch {
|
|
@@ -17152,34 +17044,34 @@ var StateFileManager = class {
|
|
|
17152
17044
|
return { status: "stale", existing };
|
|
17153
17045
|
}
|
|
17154
17046
|
write(state) {
|
|
17155
|
-
|
|
17047
|
+
import_node_fs10.default.mkdirSync(import_node_path9.default.dirname(this.file), { recursive: true });
|
|
17156
17048
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
17157
|
-
|
|
17158
|
-
|
|
17049
|
+
import_node_fs10.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
17050
|
+
import_node_fs10.default.renameSync(tmp, this.file);
|
|
17159
17051
|
if (process.platform !== "win32") {
|
|
17160
17052
|
try {
|
|
17161
|
-
|
|
17053
|
+
import_node_fs10.default.chmodSync(this.file, 384);
|
|
17162
17054
|
} catch {
|
|
17163
17055
|
}
|
|
17164
17056
|
}
|
|
17165
17057
|
}
|
|
17166
17058
|
delete() {
|
|
17167
17059
|
try {
|
|
17168
|
-
|
|
17060
|
+
import_node_fs10.default.unlinkSync(this.file);
|
|
17169
17061
|
} catch {
|
|
17170
17062
|
}
|
|
17171
17063
|
}
|
|
17172
17064
|
};
|
|
17173
17065
|
|
|
17174
17066
|
// src/tunnel/tunnel-manager.ts
|
|
17175
|
-
var
|
|
17176
|
-
var
|
|
17067
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
17068
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
17177
17069
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
17178
17070
|
var import_node_child_process4 = require("child_process");
|
|
17179
17071
|
|
|
17180
17072
|
// src/tunnel/tunnel-store.ts
|
|
17181
|
-
var
|
|
17182
|
-
var
|
|
17073
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
17074
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
17183
17075
|
var TunnelStore = class {
|
|
17184
17076
|
constructor(filePath) {
|
|
17185
17077
|
this.filePath = filePath;
|
|
@@ -17187,7 +17079,7 @@ var TunnelStore = class {
|
|
|
17187
17079
|
filePath;
|
|
17188
17080
|
async get() {
|
|
17189
17081
|
try {
|
|
17190
|
-
const raw = await
|
|
17082
|
+
const raw = await import_node_fs11.default.promises.readFile(this.filePath, "utf8");
|
|
17191
17083
|
const obj = JSON.parse(raw);
|
|
17192
17084
|
if (!isPersistedTunnel(obj)) return null;
|
|
17193
17085
|
return obj;
|
|
@@ -17198,22 +17090,22 @@ var TunnelStore = class {
|
|
|
17198
17090
|
}
|
|
17199
17091
|
}
|
|
17200
17092
|
async set(v) {
|
|
17201
|
-
const dir =
|
|
17202
|
-
await
|
|
17093
|
+
const dir = import_node_path10.default.dirname(this.filePath);
|
|
17094
|
+
await import_node_fs11.default.promises.mkdir(dir, { recursive: true });
|
|
17203
17095
|
const data = JSON.stringify(v, null, 2);
|
|
17204
17096
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
17205
|
-
await
|
|
17097
|
+
await import_node_fs11.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
17206
17098
|
if (process.platform !== "win32") {
|
|
17207
17099
|
try {
|
|
17208
|
-
await
|
|
17100
|
+
await import_node_fs11.default.promises.chmod(tmp, 384);
|
|
17209
17101
|
} catch {
|
|
17210
17102
|
}
|
|
17211
17103
|
}
|
|
17212
|
-
await
|
|
17104
|
+
await import_node_fs11.default.promises.rename(tmp, this.filePath);
|
|
17213
17105
|
}
|
|
17214
17106
|
async clear() {
|
|
17215
17107
|
try {
|
|
17216
|
-
await
|
|
17108
|
+
await import_node_fs11.default.promises.unlink(this.filePath);
|
|
17217
17109
|
} catch (err) {
|
|
17218
17110
|
const code = err?.code;
|
|
17219
17111
|
if (code !== "ENOENT") throw err;
|
|
@@ -17308,9 +17200,9 @@ function escape(v) {
|
|
|
17308
17200
|
}
|
|
17309
17201
|
|
|
17310
17202
|
// src/tunnel/frpc-binary.ts
|
|
17311
|
-
var
|
|
17203
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
17312
17204
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
17313
|
-
var
|
|
17205
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
17314
17206
|
var import_node_child_process3 = require("child_process");
|
|
17315
17207
|
var import_node_stream = require("stream");
|
|
17316
17208
|
var import_promises = require("stream/promises");
|
|
@@ -17342,20 +17234,20 @@ function frpcDownloadUrl(version2, p) {
|
|
|
17342
17234
|
}
|
|
17343
17235
|
async function ensureFrpcBinary(opts) {
|
|
17344
17236
|
if (opts.override) {
|
|
17345
|
-
if (!
|
|
17237
|
+
if (!import_node_fs12.default.existsSync(opts.override)) {
|
|
17346
17238
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
17347
17239
|
}
|
|
17348
17240
|
return opts.override;
|
|
17349
17241
|
}
|
|
17350
17242
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
17351
17243
|
const platform = opts.platform ?? detectPlatform();
|
|
17352
|
-
const binDir =
|
|
17353
|
-
|
|
17244
|
+
const binDir = import_node_path11.default.join(opts.dataDir, "bin");
|
|
17245
|
+
import_node_fs12.default.mkdirSync(binDir, { recursive: true });
|
|
17354
17246
|
cleanupStaleArtifacts(binDir);
|
|
17355
|
-
const stableBin =
|
|
17356
|
-
if (
|
|
17247
|
+
const stableBin = import_node_path11.default.join(binDir, "frpc");
|
|
17248
|
+
if (import_node_fs12.default.existsSync(stableBin)) return stableBin;
|
|
17357
17249
|
const partialBin = `${stableBin}.partial`;
|
|
17358
|
-
const tarballPath =
|
|
17250
|
+
const tarballPath = import_node_path11.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
17359
17251
|
try {
|
|
17360
17252
|
const url = frpcDownloadUrl(version2, platform);
|
|
17361
17253
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -17364,8 +17256,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
17364
17256
|
} else {
|
|
17365
17257
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
17366
17258
|
}
|
|
17367
|
-
|
|
17368
|
-
|
|
17259
|
+
import_node_fs12.default.chmodSync(partialBin, 493);
|
|
17260
|
+
import_node_fs12.default.renameSync(partialBin, stableBin);
|
|
17369
17261
|
} finally {
|
|
17370
17262
|
safeUnlink(tarballPath);
|
|
17371
17263
|
safeUnlink(partialBin);
|
|
@@ -17375,15 +17267,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
17375
17267
|
function cleanupStaleArtifacts(binDir) {
|
|
17376
17268
|
let entries;
|
|
17377
17269
|
try {
|
|
17378
|
-
entries =
|
|
17270
|
+
entries = import_node_fs12.default.readdirSync(binDir);
|
|
17379
17271
|
} catch {
|
|
17380
17272
|
return;
|
|
17381
17273
|
}
|
|
17382
17274
|
for (const name of entries) {
|
|
17383
17275
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
17384
|
-
const full =
|
|
17276
|
+
const full = import_node_path11.default.join(binDir, name);
|
|
17385
17277
|
try {
|
|
17386
|
-
|
|
17278
|
+
import_node_fs12.default.rmSync(full, { recursive: true, force: true });
|
|
17387
17279
|
} catch {
|
|
17388
17280
|
}
|
|
17389
17281
|
}
|
|
@@ -17391,7 +17283,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
17391
17283
|
}
|
|
17392
17284
|
function safeUnlink(p) {
|
|
17393
17285
|
try {
|
|
17394
|
-
|
|
17286
|
+
import_node_fs12.default.unlinkSync(p);
|
|
17395
17287
|
} catch {
|
|
17396
17288
|
}
|
|
17397
17289
|
}
|
|
@@ -17402,13 +17294,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
17402
17294
|
if (!res.ok || !res.body) {
|
|
17403
17295
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
17404
17296
|
}
|
|
17405
|
-
const out =
|
|
17297
|
+
const out = import_node_fs12.default.createWriteStream(dest);
|
|
17406
17298
|
const nodeStream = import_node_stream.Readable.fromWeb(res.body);
|
|
17407
17299
|
await (0, import_promises.pipeline)(nodeStream, out);
|
|
17408
17300
|
}
|
|
17409
17301
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
17410
|
-
const work =
|
|
17411
|
-
|
|
17302
|
+
const work = import_node_path11.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
17303
|
+
import_node_fs12.default.mkdirSync(work, { recursive: true });
|
|
17412
17304
|
try {
|
|
17413
17305
|
await new Promise((resolve, reject) => {
|
|
17414
17306
|
const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -17416,13 +17308,13 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
17416
17308
|
proc.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`tar exited ${code}`)));
|
|
17417
17309
|
});
|
|
17418
17310
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
17419
|
-
const src =
|
|
17420
|
-
if (!
|
|
17311
|
+
const src = import_node_path11.default.join(work, dirName, "frpc");
|
|
17312
|
+
if (!import_node_fs12.default.existsSync(src)) {
|
|
17421
17313
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
17422
17314
|
}
|
|
17423
|
-
|
|
17315
|
+
import_node_fs12.default.copyFileSync(src, destBin);
|
|
17424
17316
|
} finally {
|
|
17425
|
-
|
|
17317
|
+
import_node_fs12.default.rmSync(work, { recursive: true, force: true });
|
|
17426
17318
|
}
|
|
17427
17319
|
}
|
|
17428
17320
|
|
|
@@ -17431,7 +17323,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
17431
17323
|
var TunnelManager = class {
|
|
17432
17324
|
constructor(deps) {
|
|
17433
17325
|
this.deps = deps;
|
|
17434
|
-
this.store = deps.store ?? new TunnelStore(
|
|
17326
|
+
this.store = deps.store ?? new TunnelStore(import_node_path12.default.join(deps.dataDir, "tunnel.json"));
|
|
17435
17327
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
17436
17328
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
17437
17329
|
}
|
|
@@ -17548,7 +17440,7 @@ var TunnelManager = class {
|
|
|
17548
17440
|
dataDir: this.deps.dataDir,
|
|
17549
17441
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
17550
17442
|
});
|
|
17551
|
-
const tomlPath =
|
|
17443
|
+
const tomlPath = import_node_path12.default.join(this.deps.dataDir, "frpc.toml");
|
|
17552
17444
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto3.default.randomBytes(3).toString("hex")}`;
|
|
17553
17445
|
const toml = buildFrpcToml({
|
|
17554
17446
|
serverAddr: t.frpsHost,
|
|
@@ -17559,12 +17451,12 @@ var TunnelManager = class {
|
|
|
17559
17451
|
localPort,
|
|
17560
17452
|
logLevel: "info"
|
|
17561
17453
|
});
|
|
17562
|
-
await
|
|
17454
|
+
await import_node_fs13.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
17563
17455
|
const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
|
|
17564
17456
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17565
17457
|
});
|
|
17566
|
-
const logFilePath =
|
|
17567
|
-
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 });
|
|
17568
17460
|
logStream.on("error", () => {
|
|
17569
17461
|
});
|
|
17570
17462
|
const tee = (chunk) => {
|
|
@@ -17656,12 +17548,12 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
17656
17548
|
}
|
|
17657
17549
|
|
|
17658
17550
|
// src/auth-store.ts
|
|
17659
|
-
var
|
|
17660
|
-
var
|
|
17551
|
+
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
17552
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
17661
17553
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
17662
17554
|
var AUTH_FILE_NAME = "auth.json";
|
|
17663
17555
|
function authFilePath(dataDir) {
|
|
17664
|
-
return
|
|
17556
|
+
return import_node_path13.default.join(dataDir, AUTH_FILE_NAME);
|
|
17665
17557
|
}
|
|
17666
17558
|
function loadOrCreateAuthToken(opts) {
|
|
17667
17559
|
const file = authFilePath(opts.dataDir);
|
|
@@ -17677,7 +17569,7 @@ function defaultGenerate() {
|
|
|
17677
17569
|
}
|
|
17678
17570
|
function readAuthFile(file) {
|
|
17679
17571
|
try {
|
|
17680
|
-
const raw =
|
|
17572
|
+
const raw = import_node_fs14.default.readFileSync(file, "utf8");
|
|
17681
17573
|
const parsed = JSON.parse(raw);
|
|
17682
17574
|
if (typeof parsed?.token === "string" && parsed.token.length > 0) {
|
|
17683
17575
|
return {
|
|
@@ -17693,20 +17585,20 @@ function readAuthFile(file) {
|
|
|
17693
17585
|
}
|
|
17694
17586
|
}
|
|
17695
17587
|
function writeAuthFile(file, content) {
|
|
17696
|
-
|
|
17697
|
-
|
|
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 });
|
|
17698
17590
|
try {
|
|
17699
|
-
|
|
17591
|
+
import_node_fs14.default.chmodSync(file, 384);
|
|
17700
17592
|
} catch {
|
|
17701
17593
|
}
|
|
17702
17594
|
}
|
|
17703
17595
|
|
|
17704
17596
|
// src/session/fork.ts
|
|
17705
|
-
var
|
|
17597
|
+
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
17706
17598
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
17707
|
-
var
|
|
17599
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
17708
17600
|
function readJsonlEntries(file) {
|
|
17709
|
-
const raw =
|
|
17601
|
+
const raw = import_node_fs15.default.readFileSync(file, "utf8");
|
|
17710
17602
|
const out = [];
|
|
17711
17603
|
for (const line of raw.split("\n")) {
|
|
17712
17604
|
const t = line.trim();
|
|
@@ -17719,10 +17611,10 @@ function readJsonlEntries(file) {
|
|
|
17719
17611
|
return out;
|
|
17720
17612
|
}
|
|
17721
17613
|
function forkSession(input) {
|
|
17722
|
-
const baseDir = input.baseDir ??
|
|
17723
|
-
const projectDir =
|
|
17724
|
-
const sourceFile =
|
|
17725
|
-
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)) {
|
|
17726
17618
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
17727
17619
|
}
|
|
17728
17620
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -17752,9 +17644,9 @@ function forkSession(input) {
|
|
|
17752
17644
|
}
|
|
17753
17645
|
forkedLines.push(JSON.stringify(forked));
|
|
17754
17646
|
}
|
|
17755
|
-
const forkedFilePath =
|
|
17756
|
-
|
|
17757
|
-
|
|
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 });
|
|
17758
17650
|
return { forkedToolSessionId, forkedFilePath };
|
|
17759
17651
|
}
|
|
17760
17652
|
|
|
@@ -17875,11 +17767,6 @@ function buildSessionHandlers(deps) {
|
|
|
17875
17767
|
const { response, broadcast } = manager.pin(args);
|
|
17876
17768
|
return { response: { type: "session:info", ...response }, broadcast };
|
|
17877
17769
|
};
|
|
17878
|
-
const reorderPins = async (frame) => {
|
|
17879
|
-
const args = SessionReorderPinsArgs.parse(frame);
|
|
17880
|
-
const { response, broadcast } = manager.reorderPins(args);
|
|
17881
|
-
return { response: { type: "session:reorderPins", ...response }, broadcast };
|
|
17882
|
-
};
|
|
17883
17770
|
const answerQuestion = async (frame) => {
|
|
17884
17771
|
const args = AnswerQuestionArgs.parse(frame);
|
|
17885
17772
|
const { response, broadcast } = manager.answerQuestion(args);
|
|
@@ -17905,7 +17792,6 @@ function buildSessionHandlers(deps) {
|
|
|
17905
17792
|
"session:subscribe": subscribe,
|
|
17906
17793
|
"session:unsubscribe": unsubscribe,
|
|
17907
17794
|
"session:pin": pin,
|
|
17908
|
-
"session:reorderPins": reorderPins,
|
|
17909
17795
|
"session:answerQuestion": answerQuestion
|
|
17910
17796
|
};
|
|
17911
17797
|
}
|
|
@@ -18016,9 +17902,9 @@ function buildWorkspaceHandlers(deps) {
|
|
|
18016
17902
|
|
|
18017
17903
|
// src/workspace/git.ts
|
|
18018
17904
|
var import_node_child_process5 = require("child_process");
|
|
18019
|
-
var
|
|
17905
|
+
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
18020
17906
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
18021
|
-
var
|
|
17907
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
18022
17908
|
var import_node_util = require("util");
|
|
18023
17909
|
var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
|
|
18024
17910
|
function formatChildProcessError(err) {
|
|
@@ -18033,9 +17919,9 @@ function formatChildProcessError(err) {
|
|
|
18033
17919
|
return e.message ?? "unknown error";
|
|
18034
17920
|
}
|
|
18035
17921
|
function normalizePath(p) {
|
|
18036
|
-
const resolved =
|
|
17922
|
+
const resolved = import_node_path15.default.resolve(p);
|
|
18037
17923
|
try {
|
|
18038
|
-
return
|
|
17924
|
+
return import_node_fs16.default.realpathSync(resolved);
|
|
18039
17925
|
} catch {
|
|
18040
17926
|
return resolved;
|
|
18041
17927
|
}
|
|
@@ -18136,13 +18022,13 @@ function flattenToDirName(branch) {
|
|
|
18136
18022
|
}
|
|
18137
18023
|
function encodeClaudeProjectDir(absPath) {
|
|
18138
18024
|
if (!absPath || typeof absPath !== "string") return "";
|
|
18139
|
-
let canonical =
|
|
18025
|
+
let canonical = import_node_path15.default.resolve(absPath);
|
|
18140
18026
|
try {
|
|
18141
|
-
canonical =
|
|
18027
|
+
canonical = import_node_fs16.default.realpathSync(canonical);
|
|
18142
18028
|
} catch {
|
|
18143
18029
|
try {
|
|
18144
|
-
const parent =
|
|
18145
|
-
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));
|
|
18146
18032
|
} catch {
|
|
18147
18033
|
}
|
|
18148
18034
|
}
|
|
@@ -18166,11 +18052,11 @@ async function createWorktree(input) {
|
|
|
18166
18052
|
if (!isGitRoot) {
|
|
18167
18053
|
throw new Error(`\u76EE\u5F55 ${cwd} \u4E0D\u662F git repo \u6839`);
|
|
18168
18054
|
}
|
|
18169
|
-
const parent =
|
|
18170
|
-
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)) {
|
|
18171
18057
|
throw new Error("repo \u5728\u78C1\u76D8\u6839\u76EE\u5F55\uFF0C\u65E0\u6CD5\u5728\u540C\u7EA7\u521B\u5EFA worktree");
|
|
18172
18058
|
}
|
|
18173
|
-
const worktreeRoot =
|
|
18059
|
+
const worktreeRoot = import_node_path15.default.join(parent, dirName);
|
|
18174
18060
|
try {
|
|
18175
18061
|
await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${baseBranch}`], {
|
|
18176
18062
|
timeout: 3e3
|
|
@@ -18187,7 +18073,7 @@ async function createWorktree(input) {
|
|
|
18187
18073
|
const msg = err.message;
|
|
18188
18074
|
if (msg.startsWith("\u5206\u652F ")) throw err;
|
|
18189
18075
|
}
|
|
18190
|
-
if (
|
|
18076
|
+
if (import_node_fs16.default.existsSync(worktreeRoot)) {
|
|
18191
18077
|
throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
|
|
18192
18078
|
}
|
|
18193
18079
|
try {
|
|
@@ -18215,8 +18101,8 @@ async function removeWorktree(input) {
|
|
|
18215
18101
|
);
|
|
18216
18102
|
const gitCommonDir = stdout.trim();
|
|
18217
18103
|
if (!gitCommonDir) throw new Error("empty git-common-dir");
|
|
18218
|
-
const absGitCommon =
|
|
18219
|
-
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);
|
|
18220
18106
|
} catch {
|
|
18221
18107
|
repoRoot = null;
|
|
18222
18108
|
}
|
|
@@ -18228,7 +18114,7 @@ async function removeWorktree(input) {
|
|
|
18228
18114
|
} catch (err) {
|
|
18229
18115
|
const stderr = err.stderr ?? "";
|
|
18230
18116
|
const lower = stderr.toLowerCase();
|
|
18231
|
-
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);
|
|
18232
18118
|
if (!vanished) {
|
|
18233
18119
|
throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
|
|
18234
18120
|
}
|
|
@@ -18247,10 +18133,10 @@ async function removeWorktree(input) {
|
|
|
18247
18133
|
try {
|
|
18248
18134
|
const encoded = encodeClaudeProjectDir(worktreeRoot);
|
|
18249
18135
|
if (encoded) {
|
|
18250
|
-
const projectsRoot =
|
|
18251
|
-
const target =
|
|
18252
|
-
if (target.startsWith(projectsRoot +
|
|
18253
|
-
|
|
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 });
|
|
18254
18140
|
}
|
|
18255
18141
|
}
|
|
18256
18142
|
} catch {
|
|
@@ -18377,7 +18263,7 @@ function buildMethodHandlers(deps) {
|
|
|
18377
18263
|
async function startDaemon(config) {
|
|
18378
18264
|
const logger = createLogger({
|
|
18379
18265
|
level: config.logLevel,
|
|
18380
|
-
file:
|
|
18266
|
+
file: import_node_path16.default.join(config.dataDir, "clawd.log")
|
|
18381
18267
|
});
|
|
18382
18268
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
18383
18269
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
@@ -18417,7 +18303,6 @@ async function startDaemon(config) {
|
|
|
18417
18303
|
logger,
|
|
18418
18304
|
getAdapter,
|
|
18419
18305
|
historyReader: history,
|
|
18420
|
-
dataDir: config.dataDir,
|
|
18421
18306
|
broadcastFrame: (frame, target) => {
|
|
18422
18307
|
if (target === "all") {
|
|
18423
18308
|
transport?.broadcastAll(frame);
|
|
@@ -18540,8 +18425,8 @@ async function startDaemon(config) {
|
|
|
18540
18425
|
const lines = [
|
|
18541
18426
|
`Tunnel: ${r.url}`,
|
|
18542
18427
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
18543
|
-
`Frpc config: ${
|
|
18544
|
-
`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")}`
|
|
18545
18430
|
];
|
|
18546
18431
|
const width = Math.max(...lines.map((l) => l.length));
|
|
18547
18432
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -18554,8 +18439,8 @@ ${bar}
|
|
|
18554
18439
|
|
|
18555
18440
|
`);
|
|
18556
18441
|
try {
|
|
18557
|
-
const connectPath =
|
|
18558
|
-
|
|
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 });
|
|
18559
18444
|
} catch {
|
|
18560
18445
|
}
|
|
18561
18446
|
} catch (err) {
|