@clawos-dev/clawd 0.2.23-beta.33.3955675 → 0.2.23-beta.34.136a698
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 +293 -306
- 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,6 +8144,7 @@ var METHOD_NAMES = [
|
|
|
8144
8144
|
"session:subscribe",
|
|
8145
8145
|
"session:unsubscribe",
|
|
8146
8146
|
"session:pin",
|
|
8147
|
+
"session:reorderPins",
|
|
8147
8148
|
"permission:respond",
|
|
8148
8149
|
// AskUserQuestion 表单回写:UI 答完所有 question 后调用,daemon 把答案合并进 updated_input
|
|
8149
8150
|
// 写一条 control_response 到 CC stdin(详见 events.ts session:question JSDoc)
|
|
@@ -8686,8 +8687,8 @@ function getErrorMap() {
|
|
|
8686
8687
|
|
|
8687
8688
|
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
8688
8689
|
var makeIssue = (params) => {
|
|
8689
|
-
const { data, path:
|
|
8690
|
-
const fullPath = [...
|
|
8690
|
+
const { data, path: path17, errorMaps, issueData } = params;
|
|
8691
|
+
const fullPath = [...path17, ...issueData.path || []];
|
|
8691
8692
|
const fullIssue = {
|
|
8692
8693
|
...issueData,
|
|
8693
8694
|
path: fullPath
|
|
@@ -8803,11 +8804,11 @@ var errorUtil;
|
|
|
8803
8804
|
|
|
8804
8805
|
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
8805
8806
|
var ParseInputLazyPath = class {
|
|
8806
|
-
constructor(parent, value,
|
|
8807
|
+
constructor(parent, value, path17, key) {
|
|
8807
8808
|
this._cachedPath = [];
|
|
8808
8809
|
this.parent = parent;
|
|
8809
8810
|
this.data = value;
|
|
8810
|
-
this._path =
|
|
8811
|
+
this._path = path17;
|
|
8811
8812
|
this._key = key;
|
|
8812
8813
|
}
|
|
8813
8814
|
get path() {
|
|
@@ -12326,6 +12327,9 @@ var SessionFileSchema = external_exports.object({
|
|
|
12326
12327
|
permissionRules: external_exports.array(AllowRuleSchema).optional(),
|
|
12327
12328
|
// Sidebar 置顶时间戳;null/undefined 表示未置顶
|
|
12328
12329
|
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(),
|
|
12329
12333
|
// 用户在 NewSessionDialog 或 Edit modal 选择的 icon 标识;UI 端做 enum 兜底
|
|
12330
12334
|
iconKey: external_exports.string().optional(),
|
|
12331
12335
|
// NewSessionDialog 勾选 worktree 创建的 session 才会持久化这两个字段
|
|
@@ -12657,6 +12661,9 @@ var SessionPinArgs = external_exports.object({
|
|
|
12657
12661
|
sessionId: external_exports.string().min(1),
|
|
12658
12662
|
pinned: external_exports.boolean()
|
|
12659
12663
|
});
|
|
12664
|
+
var SessionReorderPinsArgs = external_exports.object({
|
|
12665
|
+
orderedIds: external_exports.array(external_exports.string().min(1)).min(1)
|
|
12666
|
+
});
|
|
12660
12667
|
var GitRootArgs = external_exports.object({ cwd: external_exports.string().min(1) });
|
|
12661
12668
|
var GitRootResponseSchema = external_exports.object({
|
|
12662
12669
|
isGitRoot: external_exports.boolean(),
|
|
@@ -12812,7 +12819,7 @@ var SessionStore = class {
|
|
|
12812
12819
|
};
|
|
12813
12820
|
|
|
12814
12821
|
// src/session/manager.ts
|
|
12815
|
-
var
|
|
12822
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
12816
12823
|
|
|
12817
12824
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
12818
12825
|
var byteToHex = [];
|
|
@@ -13401,58 +13408,6 @@ function reduceSession(state, input, deps) {
|
|
|
13401
13408
|
}
|
|
13402
13409
|
}
|
|
13403
13410
|
|
|
13404
|
-
// src/ipc-recorder.ts
|
|
13405
|
-
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
13406
|
-
var import_node_path4 = __toESM(require("path"), 1);
|
|
13407
|
-
function tsForFilename(ms) {
|
|
13408
|
-
return new Date(ms).toISOString().replace(/[:.]/g, "-");
|
|
13409
|
-
}
|
|
13410
|
-
function startRecorder(opts) {
|
|
13411
|
-
if (opts.env.CLAWD_RECORD_IPC !== "1") return null;
|
|
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;
|
|
13415
|
-
}
|
|
13416
|
-
const now = opts.now ?? Date.now;
|
|
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
|
-
};
|
|
13454
|
-
}
|
|
13455
|
-
|
|
13456
13411
|
// src/session/runner.ts
|
|
13457
13412
|
var DEFAULT_CONTROL_REQUEST_TIMEOUT_MS = 1e4;
|
|
13458
13413
|
function encodeAllowWithInputControlResponse(requestId, updatedInput) {
|
|
@@ -13483,8 +13438,6 @@ var SessionRunner = class {
|
|
|
13483
13438
|
pendingControlRequests = /* @__PURE__ */ new Map();
|
|
13484
13439
|
// waitUntilStopped 排队的 resolve 回调;reducer 把 procAlive 翻成 false 后批量触发
|
|
13485
13440
|
stopWaiters = [];
|
|
13486
|
-
// IPC recorder(CLAWD_RECORD_IPC=1 时启用);null 表示当前 spawn 未启用 / 已退出
|
|
13487
|
-
recorder = null;
|
|
13488
13441
|
getState() {
|
|
13489
13442
|
return this.state;
|
|
13490
13443
|
}
|
|
@@ -13574,7 +13527,6 @@ var SessionRunner = class {
|
|
|
13574
13527
|
this.pendingControlRequests.set(requestId, { resolve, reject, timer });
|
|
13575
13528
|
try {
|
|
13576
13529
|
proc.stdin?.write(payload);
|
|
13577
|
-
this.recorder?.tapStdinWrite(payload);
|
|
13578
13530
|
} catch (err) {
|
|
13579
13531
|
clearTimeout(timer);
|
|
13580
13532
|
this.pendingControlRequests.delete(requestId);
|
|
@@ -13630,14 +13582,10 @@ var SessionRunner = class {
|
|
|
13630
13582
|
break;
|
|
13631
13583
|
case "write-stdin":
|
|
13632
13584
|
this.proc?.stdin?.write(effect.payload);
|
|
13633
|
-
this.recorder?.tapStdinWrite(effect.payload);
|
|
13634
13585
|
break;
|
|
13635
|
-
case "send-control-response-allow-with-input":
|
|
13636
|
-
|
|
13637
|
-
this.proc?.stdin?.write(payload);
|
|
13638
|
-
this.recorder?.tapStdinWrite(payload);
|
|
13586
|
+
case "send-control-response-allow-with-input":
|
|
13587
|
+
this.proc?.stdin?.write(encodeAllowWithInputControlResponse(effect.requestId, effect.updatedInput));
|
|
13639
13588
|
break;
|
|
13640
|
-
}
|
|
13641
13589
|
case "persist-file":
|
|
13642
13590
|
try {
|
|
13643
13591
|
this.hooks.store.write(effect.file);
|
|
@@ -13667,13 +13615,6 @@ var SessionRunner = class {
|
|
|
13667
13615
|
const proc = this.hooks.spawnOverride ? this.hooks.spawnOverride(ctx) : this.hooks.adapter.spawn(ctx);
|
|
13668
13616
|
this.proc = proc;
|
|
13669
13617
|
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
13618
|
proc.stdout?.on("data", (chunk) => {
|
|
13678
13619
|
this.stdoutBuf += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
13679
13620
|
let idx;
|
|
@@ -13690,7 +13631,6 @@ var SessionRunner = class {
|
|
|
13690
13631
|
});
|
|
13691
13632
|
proc.on("exit", (code) => {
|
|
13692
13633
|
this.proc = null;
|
|
13693
|
-
this.recorder = null;
|
|
13694
13634
|
this.rejectAllPending(new Error("session gone"));
|
|
13695
13635
|
this.input({ kind: "proc-exit", code });
|
|
13696
13636
|
});
|
|
@@ -13817,8 +13757,7 @@ var SessionManager = class {
|
|
|
13817
13757
|
now: this.deps.now,
|
|
13818
13758
|
bufferCap: this.deps.bufferCap,
|
|
13819
13759
|
// adapter 自己持有模型表 + 兜底逻辑(contains / opus-1M / [1m] 等),manager 不再 cache 转发
|
|
13820
|
-
resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId)
|
|
13821
|
-
dataDir: this.deps.dataDir
|
|
13760
|
+
resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId)
|
|
13822
13761
|
});
|
|
13823
13762
|
return runner;
|
|
13824
13763
|
}
|
|
@@ -13849,7 +13788,7 @@ var SessionManager = class {
|
|
|
13849
13788
|
// ---- 命令方法:均返回 { response, broadcast[] },由 dispatcher 聚合 ----
|
|
13850
13789
|
create(args) {
|
|
13851
13790
|
try {
|
|
13852
|
-
const stat =
|
|
13791
|
+
const stat = import_node_fs4.default.statSync(args.cwd);
|
|
13853
13792
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
13854
13793
|
} catch {
|
|
13855
13794
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -13890,6 +13829,49 @@ var SessionManager = class {
|
|
|
13890
13829
|
this.deps.store.write(updated);
|
|
13891
13830
|
return { response: updated, broadcast: [] };
|
|
13892
13831
|
}
|
|
13832
|
+
// sidebar 拖拽完成 → 整体重写 pinned root 的 pinSortOrder(按 orderedIds 下标 0,1,2...)
|
|
13833
|
+
// orderedIds 必须正好覆盖所有当前 pinned root(既不能漏,也不能含 unpinned id)
|
|
13834
|
+
reorderPins(args) {
|
|
13835
|
+
const all = this.deps.store.list();
|
|
13836
|
+
const currentPinnedIds = new Set(
|
|
13837
|
+
all.filter((f) => typeof f.pinnedAt === "number").map((f) => f.sessionId)
|
|
13838
|
+
);
|
|
13839
|
+
const incoming = new Set(args.orderedIds);
|
|
13840
|
+
if (incoming.size !== args.orderedIds.length) {
|
|
13841
|
+
throw new Error("reorderPins: orderedIds contains duplicate ids");
|
|
13842
|
+
}
|
|
13843
|
+
if (currentPinnedIds.size !== incoming.size || [...currentPinnedIds].some((id) => !incoming.has(id))) {
|
|
13844
|
+
throw new Error(
|
|
13845
|
+
"reorderPins: orderedIds must cover exactly the current pinned root set"
|
|
13846
|
+
);
|
|
13847
|
+
}
|
|
13848
|
+
const broadcast = [];
|
|
13849
|
+
const updatedFiles = [];
|
|
13850
|
+
args.orderedIds.forEach((sessionId, index) => {
|
|
13851
|
+
const runner = this.runners.get(sessionId);
|
|
13852
|
+
if (runner) {
|
|
13853
|
+
const { value, broadcast: b } = this.withCollector(() => {
|
|
13854
|
+
runner.input({
|
|
13855
|
+
kind: "command",
|
|
13856
|
+
command: { kind: "update", patch: { pinSortOrder: index } }
|
|
13857
|
+
});
|
|
13858
|
+
return runner.getState().file;
|
|
13859
|
+
});
|
|
13860
|
+
updatedFiles.push(value);
|
|
13861
|
+
broadcast.push(...b);
|
|
13862
|
+
} else {
|
|
13863
|
+
const existing = this.getFile(sessionId);
|
|
13864
|
+
const updated = {
|
|
13865
|
+
...existing,
|
|
13866
|
+
pinSortOrder: index,
|
|
13867
|
+
updatedAt: nowIso2(this.deps)
|
|
13868
|
+
};
|
|
13869
|
+
this.deps.store.write(updated);
|
|
13870
|
+
updatedFiles.push(updated);
|
|
13871
|
+
}
|
|
13872
|
+
});
|
|
13873
|
+
return { response: { sessions: updatedFiles }, broadcast };
|
|
13874
|
+
}
|
|
13893
13875
|
list() {
|
|
13894
13876
|
return { response: { sessions: this.deps.store.list() }, broadcast: [] };
|
|
13895
13877
|
}
|
|
@@ -14295,14 +14277,14 @@ var SessionManager = class {
|
|
|
14295
14277
|
// src/tools/claude.ts
|
|
14296
14278
|
var import_node_child_process = require("child_process");
|
|
14297
14279
|
var import_node_child_process2 = require("child_process");
|
|
14298
|
-
var
|
|
14280
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
14299
14281
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
14300
|
-
var
|
|
14282
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
14301
14283
|
|
|
14302
14284
|
// src/tools/claude-history.ts
|
|
14303
|
-
var
|
|
14285
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
14304
14286
|
var import_node_os2 = __toESM(require("os"), 1);
|
|
14305
|
-
var
|
|
14287
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
14306
14288
|
|
|
14307
14289
|
// ../node_modules/.pnpm/diff@7.0.0/node_modules/diff/lib/index.mjs
|
|
14308
14290
|
function Diff() {
|
|
@@ -14406,11 +14388,11 @@ Diff.prototype = {
|
|
|
14406
14388
|
}
|
|
14407
14389
|
}
|
|
14408
14390
|
},
|
|
14409
|
-
addToPath: function addToPath(
|
|
14410
|
-
var last =
|
|
14391
|
+
addToPath: function addToPath(path17, added, removed, oldPosInc, options) {
|
|
14392
|
+
var last = path17.lastComponent;
|
|
14411
14393
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14412
14394
|
return {
|
|
14413
|
-
oldPos:
|
|
14395
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
14414
14396
|
lastComponent: {
|
|
14415
14397
|
count: last.count + 1,
|
|
14416
14398
|
added,
|
|
@@ -14420,7 +14402,7 @@ Diff.prototype = {
|
|
|
14420
14402
|
};
|
|
14421
14403
|
} else {
|
|
14422
14404
|
return {
|
|
14423
|
-
oldPos:
|
|
14405
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
14424
14406
|
lastComponent: {
|
|
14425
14407
|
count: 1,
|
|
14426
14408
|
added,
|
|
@@ -15079,7 +15061,7 @@ function hashDirToCwd(hash) {
|
|
|
15079
15061
|
}
|
|
15080
15062
|
function safeStatMtime(p) {
|
|
15081
15063
|
try {
|
|
15082
|
-
return
|
|
15064
|
+
return import_node_fs5.default.statSync(p).mtimeMs;
|
|
15083
15065
|
} catch {
|
|
15084
15066
|
return 0;
|
|
15085
15067
|
}
|
|
@@ -15087,7 +15069,7 @@ function safeStatMtime(p) {
|
|
|
15087
15069
|
function readJsonlLines(file) {
|
|
15088
15070
|
let raw;
|
|
15089
15071
|
try {
|
|
15090
|
-
raw =
|
|
15072
|
+
raw = import_node_fs5.default.readFileSync(file, "utf8");
|
|
15091
15073
|
} catch (err) {
|
|
15092
15074
|
if (err.code === "ENOENT") return [];
|
|
15093
15075
|
throw err;
|
|
@@ -15279,10 +15261,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
15279
15261
|
const memories = raw.map((m) => {
|
|
15280
15262
|
if (!m || typeof m !== "object") return null;
|
|
15281
15263
|
const rec = m;
|
|
15282
|
-
const
|
|
15264
|
+
const path17 = typeof rec.path === "string" ? rec.path : null;
|
|
15283
15265
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
15284
|
-
if (!
|
|
15285
|
-
const entry = { path:
|
|
15266
|
+
if (!path17 || content == null) return null;
|
|
15267
|
+
const entry = { path: path17, content };
|
|
15286
15268
|
if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
|
|
15287
15269
|
return entry;
|
|
15288
15270
|
}).filter((m) => m !== null);
|
|
@@ -15318,8 +15300,8 @@ function attachmentDeferredToolsText(a) {
|
|
|
15318
15300
|
function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
15319
15301
|
if (backupFileName === null) return null;
|
|
15320
15302
|
try {
|
|
15321
|
-
return
|
|
15322
|
-
|
|
15303
|
+
return import_node_fs5.default.readFileSync(
|
|
15304
|
+
import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
15323
15305
|
"utf8"
|
|
15324
15306
|
);
|
|
15325
15307
|
} catch {
|
|
@@ -15328,7 +15310,7 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
15328
15310
|
}
|
|
15329
15311
|
function readCurrentContent(filePath) {
|
|
15330
15312
|
try {
|
|
15331
|
-
return
|
|
15313
|
+
return import_node_fs5.default.readFileSync(filePath, "utf8");
|
|
15332
15314
|
} catch (err) {
|
|
15333
15315
|
if (err.code === "ENOENT") return null;
|
|
15334
15316
|
return null;
|
|
@@ -15340,14 +15322,14 @@ var ClaudeHistoryReader = class {
|
|
|
15340
15322
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
15341
15323
|
fileHistoryRoot;
|
|
15342
15324
|
constructor(opts = {}) {
|
|
15343
|
-
const base = opts.baseDir ??
|
|
15344
|
-
this.projectsRoot =
|
|
15345
|
-
this.fileHistoryRoot =
|
|
15325
|
+
const base = opts.baseDir ?? import_node_path4.default.join(import_node_os2.default.homedir(), ".claude");
|
|
15326
|
+
this.projectsRoot = import_node_path4.default.join(base, "projects");
|
|
15327
|
+
this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
|
|
15346
15328
|
}
|
|
15347
15329
|
async listProjects() {
|
|
15348
15330
|
let entries;
|
|
15349
15331
|
try {
|
|
15350
|
-
entries =
|
|
15332
|
+
entries = import_node_fs5.default.readdirSync(this.projectsRoot, { withFileTypes: true });
|
|
15351
15333
|
} catch (err) {
|
|
15352
15334
|
if (err.code === "ENOENT") return [];
|
|
15353
15335
|
throw err;
|
|
@@ -15355,9 +15337,9 @@ var ClaudeHistoryReader = class {
|
|
|
15355
15337
|
const out = [];
|
|
15356
15338
|
for (const ent of entries) {
|
|
15357
15339
|
if (!ent.isDirectory()) continue;
|
|
15358
|
-
const dir =
|
|
15359
|
-
const files =
|
|
15360
|
-
const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(
|
|
15340
|
+
const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
|
|
15341
|
+
const files = import_node_fs5.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
15342
|
+
const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
|
|
15361
15343
|
out.push({
|
|
15362
15344
|
projectPath: hashDirToCwd(ent.name),
|
|
15363
15345
|
hashDir: ent.name,
|
|
@@ -15369,17 +15351,17 @@ var ClaudeHistoryReader = class {
|
|
|
15369
15351
|
return out;
|
|
15370
15352
|
}
|
|
15371
15353
|
async listSessions(args) {
|
|
15372
|
-
const dir =
|
|
15354
|
+
const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
15373
15355
|
let files;
|
|
15374
15356
|
try {
|
|
15375
|
-
files =
|
|
15357
|
+
files = import_node_fs5.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
15376
15358
|
} catch (err) {
|
|
15377
15359
|
if (err.code === "ENOENT") return [];
|
|
15378
15360
|
throw err;
|
|
15379
15361
|
}
|
|
15380
15362
|
const out = [];
|
|
15381
15363
|
for (const f of files) {
|
|
15382
|
-
const full =
|
|
15364
|
+
const full = import_node_path4.default.join(dir, f);
|
|
15383
15365
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
15384
15366
|
const lines = readJsonlLines(full);
|
|
15385
15367
|
let summary = "";
|
|
@@ -15434,7 +15416,7 @@ var ClaudeHistoryReader = class {
|
|
|
15434
15416
|
return out;
|
|
15435
15417
|
}
|
|
15436
15418
|
async read(args) {
|
|
15437
|
-
const file =
|
|
15419
|
+
const file = import_node_path4.default.join(
|
|
15438
15420
|
this.projectsRoot,
|
|
15439
15421
|
cwdToHashDir(args.cwd),
|
|
15440
15422
|
`${args.toolSessionId}.jsonl`
|
|
@@ -15467,7 +15449,7 @@ var ClaudeHistoryReader = class {
|
|
|
15467
15449
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
15468
15450
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
15469
15451
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
15470
|
-
const dir =
|
|
15452
|
+
const dir = import_node_path4.default.join(
|
|
15471
15453
|
this.projectsRoot,
|
|
15472
15454
|
cwdToHashDir(cwd),
|
|
15473
15455
|
toolSessionId,
|
|
@@ -15475,7 +15457,7 @@ var ClaudeHistoryReader = class {
|
|
|
15475
15457
|
);
|
|
15476
15458
|
let entries;
|
|
15477
15459
|
try {
|
|
15478
|
-
entries =
|
|
15460
|
+
entries = import_node_fs5.default.readdirSync(dir, { withFileTypes: true });
|
|
15479
15461
|
} catch (err) {
|
|
15480
15462
|
if (err.code === "ENOENT") return null;
|
|
15481
15463
|
return null;
|
|
@@ -15485,7 +15467,7 @@ var ClaudeHistoryReader = class {
|
|
|
15485
15467
|
if (!e.isFile()) continue;
|
|
15486
15468
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
15487
15469
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
15488
|
-
const filePath =
|
|
15470
|
+
const filePath = import_node_path4.default.join(dir, e.name);
|
|
15489
15471
|
const lines = readJsonlLines(filePath);
|
|
15490
15472
|
let firstText = "";
|
|
15491
15473
|
let messageCount = 0;
|
|
@@ -15502,7 +15484,7 @@ var ClaudeHistoryReader = class {
|
|
|
15502
15484
|
return out;
|
|
15503
15485
|
}
|
|
15504
15486
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
15505
|
-
const file =
|
|
15487
|
+
const file = import_node_path4.default.join(
|
|
15506
15488
|
this.projectsRoot,
|
|
15507
15489
|
cwdToHashDir(cwd),
|
|
15508
15490
|
`${toolSessionId}.jsonl`
|
|
@@ -15537,7 +15519,7 @@ var ClaudeHistoryReader = class {
|
|
|
15537
15519
|
}
|
|
15538
15520
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
15539
15521
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
15540
|
-
const file =
|
|
15522
|
+
const file = import_node_path4.default.join(
|
|
15541
15523
|
this.projectsRoot,
|
|
15542
15524
|
cwdToHashDir(cwd),
|
|
15543
15525
|
toolSessionId,
|
|
@@ -15546,7 +15528,7 @@ var ClaudeHistoryReader = class {
|
|
|
15546
15528
|
);
|
|
15547
15529
|
let exists = false;
|
|
15548
15530
|
try {
|
|
15549
|
-
exists =
|
|
15531
|
+
exists = import_node_fs5.default.statSync(file).isFile();
|
|
15550
15532
|
} catch {
|
|
15551
15533
|
return null;
|
|
15552
15534
|
}
|
|
@@ -15565,7 +15547,7 @@ var ClaudeHistoryReader = class {
|
|
|
15565
15547
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
15566
15548
|
*/
|
|
15567
15549
|
readFileHistorySnapshots(args) {
|
|
15568
|
-
const file =
|
|
15550
|
+
const file = import_node_path4.default.join(
|
|
15569
15551
|
this.projectsRoot,
|
|
15570
15552
|
cwdToHashDir(args.cwd),
|
|
15571
15553
|
`${args.toolSessionId}.jsonl`
|
|
@@ -15610,7 +15592,7 @@ var ClaudeHistoryReader = class {
|
|
|
15610
15592
|
for (const [anchorId, target] of snapshots) {
|
|
15611
15593
|
let hasAny = false;
|
|
15612
15594
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
15613
|
-
const absPath =
|
|
15595
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
15614
15596
|
const backupContent = readBackupContent(
|
|
15615
15597
|
this.fileHistoryRoot,
|
|
15616
15598
|
args.toolSessionId,
|
|
@@ -15650,7 +15632,7 @@ var ClaudeHistoryReader = class {
|
|
|
15650
15632
|
let totalInsertions = 0;
|
|
15651
15633
|
let totalDeletions = 0;
|
|
15652
15634
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
15653
|
-
const absPath =
|
|
15635
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
15654
15636
|
const backupContent = readBackupContent(
|
|
15655
15637
|
this.fileHistoryRoot,
|
|
15656
15638
|
args.toolSessionId,
|
|
@@ -15697,7 +15679,7 @@ var ClaudeHistoryReader = class {
|
|
|
15697
15679
|
};
|
|
15698
15680
|
}
|
|
15699
15681
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
15700
|
-
const file =
|
|
15682
|
+
const file = import_node_path4.default.join(
|
|
15701
15683
|
this.projectsRoot,
|
|
15702
15684
|
cwdToHashDir(cwd),
|
|
15703
15685
|
`${toolSessionId}.jsonl`
|
|
@@ -15719,27 +15701,27 @@ var ClaudeHistoryReader = class {
|
|
|
15719
15701
|
// src/tools/claude.ts
|
|
15720
15702
|
function macOSDesktopCandidates(home) {
|
|
15721
15703
|
return [
|
|
15722
|
-
|
|
15704
|
+
import_node_path5.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
|
|
15723
15705
|
"/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
|
|
15724
15706
|
];
|
|
15725
15707
|
}
|
|
15726
15708
|
function probeViaWhich() {
|
|
15727
15709
|
try {
|
|
15728
15710
|
const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
|
|
15729
|
-
if (out &&
|
|
15711
|
+
if (out && import_node_fs6.default.existsSync(out)) return out;
|
|
15730
15712
|
} catch {
|
|
15731
15713
|
}
|
|
15732
15714
|
return null;
|
|
15733
15715
|
}
|
|
15734
15716
|
async function probeClaude(env = process.env, home = import_node_os3.default.homedir()) {
|
|
15735
|
-
if (env.CLAUDE_BIN &&
|
|
15717
|
+
if (env.CLAUDE_BIN && import_node_fs6.default.existsSync(env.CLAUDE_BIN)) {
|
|
15736
15718
|
return { available: true, path: env.CLAUDE_BIN };
|
|
15737
15719
|
}
|
|
15738
15720
|
const w = probeViaWhich();
|
|
15739
15721
|
if (w) return { available: true, path: w };
|
|
15740
15722
|
if (process.platform === "darwin") {
|
|
15741
15723
|
for (const candidate of macOSDesktopCandidates(home)) {
|
|
15742
|
-
if (
|
|
15724
|
+
if (import_node_fs6.default.existsSync(candidate)) {
|
|
15743
15725
|
return { available: true, path: candidate };
|
|
15744
15726
|
}
|
|
15745
15727
|
}
|
|
@@ -16050,10 +16032,10 @@ function parseAttachment(obj) {
|
|
|
16050
16032
|
const memories = raw.map((m) => {
|
|
16051
16033
|
if (!m || typeof m !== "object") return null;
|
|
16052
16034
|
const rec = m;
|
|
16053
|
-
const
|
|
16035
|
+
const path17 = typeof rec.path === "string" ? rec.path : null;
|
|
16054
16036
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
16055
|
-
if (!
|
|
16056
|
-
const out = { path:
|
|
16037
|
+
if (!path17 || content == null) return null;
|
|
16038
|
+
const out = { path: path17, content };
|
|
16057
16039
|
if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
|
|
16058
16040
|
return out;
|
|
16059
16041
|
}).filter((m) => m !== null);
|
|
@@ -16281,22 +16263,22 @@ var ClaudeAdapter = class {
|
|
|
16281
16263
|
};
|
|
16282
16264
|
|
|
16283
16265
|
// src/workspace/browser.ts
|
|
16284
|
-
var
|
|
16266
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
16285
16267
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
16286
|
-
var
|
|
16268
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
16287
16269
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
16288
16270
|
function resolveInsideCwd(cwd, subpath) {
|
|
16289
|
-
const absCwd =
|
|
16290
|
-
const joined =
|
|
16291
|
-
const rel =
|
|
16292
|
-
if (rel.startsWith("..") ||
|
|
16271
|
+
const absCwd = import_node_path6.default.resolve(cwd);
|
|
16272
|
+
const joined = import_node_path6.default.resolve(absCwd, subpath ?? ".");
|
|
16273
|
+
const rel = import_node_path6.default.relative(absCwd, joined);
|
|
16274
|
+
if (rel.startsWith("..") || import_node_path6.default.isAbsolute(rel)) {
|
|
16293
16275
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
16294
16276
|
}
|
|
16295
16277
|
return joined;
|
|
16296
16278
|
}
|
|
16297
16279
|
function ensureCwd(cwd) {
|
|
16298
16280
|
try {
|
|
16299
|
-
const stat =
|
|
16281
|
+
const stat = import_node_fs7.default.statSync(cwd);
|
|
16300
16282
|
if (!stat.isDirectory()) {
|
|
16301
16283
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
16302
16284
|
}
|
|
@@ -16310,7 +16292,7 @@ var WorkspaceBrowser = class {
|
|
|
16310
16292
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os4.default.homedir();
|
|
16311
16293
|
ensureCwd(cwd);
|
|
16312
16294
|
const full = resolveInsideCwd(cwd, args.path);
|
|
16313
|
-
const dirents =
|
|
16295
|
+
const dirents = import_node_fs7.default.readdirSync(full, { withFileTypes: true });
|
|
16314
16296
|
const entries = [];
|
|
16315
16297
|
for (const d of dirents) {
|
|
16316
16298
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -16320,7 +16302,7 @@ var WorkspaceBrowser = class {
|
|
|
16320
16302
|
mtime: ""
|
|
16321
16303
|
};
|
|
16322
16304
|
try {
|
|
16323
|
-
const st =
|
|
16305
|
+
const st = import_node_fs7.default.statSync(import_node_path6.default.join(full, d.name));
|
|
16324
16306
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
16325
16307
|
if (d.isFile()) entry.size = st.size;
|
|
16326
16308
|
} catch {
|
|
@@ -16336,14 +16318,14 @@ var WorkspaceBrowser = class {
|
|
|
16336
16318
|
read(args) {
|
|
16337
16319
|
ensureCwd(args.cwd);
|
|
16338
16320
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
16339
|
-
const st =
|
|
16321
|
+
const st = import_node_fs7.default.statSync(full);
|
|
16340
16322
|
if (!st.isFile()) {
|
|
16341
16323
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
16342
16324
|
}
|
|
16343
16325
|
if (st.size > MAX_FILE_BYTES) {
|
|
16344
16326
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
16345
16327
|
}
|
|
16346
|
-
const buf =
|
|
16328
|
+
const buf = import_node_fs7.default.readFileSync(full);
|
|
16347
16329
|
const isBinary = buf.includes(0);
|
|
16348
16330
|
if (isBinary) {
|
|
16349
16331
|
return {
|
|
@@ -16365,9 +16347,9 @@ var WorkspaceBrowser = class {
|
|
|
16365
16347
|
};
|
|
16366
16348
|
|
|
16367
16349
|
// src/skills/scanner.ts
|
|
16368
|
-
var
|
|
16350
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
16369
16351
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
16370
|
-
var
|
|
16352
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
16371
16353
|
function parseFrontmatter(content) {
|
|
16372
16354
|
if (!content.startsWith("---")) return { name: "", description: "" };
|
|
16373
16355
|
const end = content.indexOf("---", 3);
|
|
@@ -16403,7 +16385,7 @@ function parseFrontmatter(content) {
|
|
|
16403
16385
|
}
|
|
16404
16386
|
function isDirLikeSync(p) {
|
|
16405
16387
|
try {
|
|
16406
|
-
return
|
|
16388
|
+
return import_node_fs8.default.statSync(p).isDirectory();
|
|
16407
16389
|
} catch {
|
|
16408
16390
|
return false;
|
|
16409
16391
|
}
|
|
@@ -16411,19 +16393,19 @@ function isDirLikeSync(p) {
|
|
|
16411
16393
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
16412
16394
|
let entries;
|
|
16413
16395
|
try {
|
|
16414
|
-
entries =
|
|
16396
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
16415
16397
|
} catch {
|
|
16416
16398
|
return;
|
|
16417
16399
|
}
|
|
16418
16400
|
for (const ent of entries) {
|
|
16419
|
-
const entryPath =
|
|
16401
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
16420
16402
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
16421
16403
|
let content;
|
|
16422
16404
|
try {
|
|
16423
|
-
content =
|
|
16405
|
+
content = import_node_fs8.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
|
|
16424
16406
|
} catch {
|
|
16425
16407
|
try {
|
|
16426
|
-
content =
|
|
16408
|
+
content = import_node_fs8.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
|
|
16427
16409
|
} catch {
|
|
16428
16410
|
continue;
|
|
16429
16411
|
}
|
|
@@ -16441,26 +16423,26 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
|
16441
16423
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
16442
16424
|
let entries;
|
|
16443
16425
|
try {
|
|
16444
|
-
entries =
|
|
16426
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
16445
16427
|
} catch {
|
|
16446
16428
|
return;
|
|
16447
16429
|
}
|
|
16448
16430
|
for (const ent of entries) {
|
|
16449
|
-
const entryPath =
|
|
16431
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
16450
16432
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
16451
16433
|
const ns = ent.name;
|
|
16452
16434
|
let subEntries;
|
|
16453
16435
|
try {
|
|
16454
|
-
subEntries =
|
|
16436
|
+
subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
|
|
16455
16437
|
} catch {
|
|
16456
16438
|
continue;
|
|
16457
16439
|
}
|
|
16458
16440
|
for (const se of subEntries) {
|
|
16459
16441
|
if (!se.name.endsWith(".md")) continue;
|
|
16460
|
-
const sePath =
|
|
16442
|
+
const sePath = import_node_path7.default.join(entryPath, se.name);
|
|
16461
16443
|
let content;
|
|
16462
16444
|
try {
|
|
16463
|
-
content =
|
|
16445
|
+
content = import_node_fs8.default.readFileSync(sePath, "utf8");
|
|
16464
16446
|
} catch {
|
|
16465
16447
|
continue;
|
|
16466
16448
|
}
|
|
@@ -16477,7 +16459,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
16477
16459
|
} else if (ent.name.endsWith(".md")) {
|
|
16478
16460
|
let content;
|
|
16479
16461
|
try {
|
|
16480
|
-
content =
|
|
16462
|
+
content = import_node_fs8.default.readFileSync(entryPath, "utf8");
|
|
16481
16463
|
} catch {
|
|
16482
16464
|
continue;
|
|
16483
16465
|
}
|
|
@@ -16493,10 +16475,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
16493
16475
|
}
|
|
16494
16476
|
}
|
|
16495
16477
|
function readInstalledPlugins(home) {
|
|
16496
|
-
const file =
|
|
16478
|
+
const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
16497
16479
|
let raw;
|
|
16498
16480
|
try {
|
|
16499
|
-
raw =
|
|
16481
|
+
raw = import_node_fs8.default.readFileSync(file, "utf8");
|
|
16500
16482
|
} catch {
|
|
16501
16483
|
return [];
|
|
16502
16484
|
}
|
|
@@ -16534,14 +16516,14 @@ var SkillsScanner = class {
|
|
|
16534
16516
|
list(args) {
|
|
16535
16517
|
const seen = /* @__PURE__ */ new Set();
|
|
16536
16518
|
const out = [];
|
|
16537
|
-
scanSkillDir(
|
|
16538
|
-
scanCommandDir(
|
|
16539
|
-
scanSkillDir(
|
|
16540
|
-
scanCommandDir(
|
|
16519
|
+
scanSkillDir(import_node_path7.default.join(this.home, ".claude", "skills"), "global", seen, out);
|
|
16520
|
+
scanCommandDir(import_node_path7.default.join(this.home, ".claude", "commands"), "global", seen, out);
|
|
16521
|
+
scanSkillDir(import_node_path7.default.join(args.cwd, ".claude", "skills"), "project", seen, out);
|
|
16522
|
+
scanCommandDir(import_node_path7.default.join(args.cwd, ".claude", "commands"), "project", seen, out);
|
|
16541
16523
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
16542
16524
|
for (const { name, root } of plugins) {
|
|
16543
|
-
scanSkillDir(
|
|
16544
|
-
scanCommandDir(
|
|
16525
|
+
scanSkillDir(import_node_path7.default.join(root, "skills"), "plugin", seen, out, name);
|
|
16526
|
+
scanCommandDir(import_node_path7.default.join(root, "commands"), "plugin", seen, out, name);
|
|
16545
16527
|
}
|
|
16546
16528
|
out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
16547
16529
|
return out;
|
|
@@ -16549,9 +16531,9 @@ var SkillsScanner = class {
|
|
|
16549
16531
|
};
|
|
16550
16532
|
|
|
16551
16533
|
// src/observer/session-observer.ts
|
|
16552
|
-
var
|
|
16534
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
16553
16535
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
16554
|
-
var
|
|
16536
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
16555
16537
|
var SessionObserver = class {
|
|
16556
16538
|
constructor(opts) {
|
|
16557
16539
|
this.opts = opts;
|
|
@@ -16562,14 +16544,14 @@ var SessionObserver = class {
|
|
|
16562
16544
|
watches = /* @__PURE__ */ new Map();
|
|
16563
16545
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
16564
16546
|
if (override) return override;
|
|
16565
|
-
return
|
|
16547
|
+
return import_node_path8.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
16566
16548
|
}
|
|
16567
16549
|
start(args) {
|
|
16568
16550
|
this.stop(args.sessionId);
|
|
16569
16551
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
16570
16552
|
let size = 0;
|
|
16571
16553
|
try {
|
|
16572
|
-
size =
|
|
16554
|
+
size = import_node_fs9.default.statSync(filePath).size;
|
|
16573
16555
|
} catch {
|
|
16574
16556
|
}
|
|
16575
16557
|
const w = {
|
|
@@ -16582,10 +16564,10 @@ var SessionObserver = class {
|
|
|
16582
16564
|
adapter: args.adapter
|
|
16583
16565
|
};
|
|
16584
16566
|
try {
|
|
16585
|
-
|
|
16567
|
+
import_node_fs9.default.mkdirSync(import_node_path8.default.dirname(filePath), { recursive: true });
|
|
16586
16568
|
} catch {
|
|
16587
16569
|
}
|
|
16588
|
-
w.watcher =
|
|
16570
|
+
w.watcher = import_node_fs9.default.watch(import_node_path8.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
16589
16571
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
16590
16572
|
this.poll(w);
|
|
16591
16573
|
});
|
|
@@ -16600,7 +16582,7 @@ var SessionObserver = class {
|
|
|
16600
16582
|
// reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
|
|
16601
16583
|
hydrateMetaTail(w, maxLines = 200) {
|
|
16602
16584
|
try {
|
|
16603
|
-
const raw =
|
|
16585
|
+
const raw = import_node_fs9.default.readFileSync(w.filePath, "utf8");
|
|
16604
16586
|
if (!raw) return;
|
|
16605
16587
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
16606
16588
|
if (allLines.length === 0) return;
|
|
@@ -16621,7 +16603,7 @@ var SessionObserver = class {
|
|
|
16621
16603
|
poll(w) {
|
|
16622
16604
|
let size = 0;
|
|
16623
16605
|
try {
|
|
16624
|
-
size =
|
|
16606
|
+
size = import_node_fs9.default.statSync(w.filePath).size;
|
|
16625
16607
|
} catch {
|
|
16626
16608
|
return;
|
|
16627
16609
|
}
|
|
@@ -16630,11 +16612,11 @@ var SessionObserver = class {
|
|
|
16630
16612
|
w.buf = "";
|
|
16631
16613
|
}
|
|
16632
16614
|
if (size === w.lastSize) return;
|
|
16633
|
-
const fd =
|
|
16615
|
+
const fd = import_node_fs9.default.openSync(w.filePath, "r");
|
|
16634
16616
|
try {
|
|
16635
16617
|
const len = size - w.lastSize;
|
|
16636
16618
|
const buf = Buffer.alloc(len);
|
|
16637
|
-
|
|
16619
|
+
import_node_fs9.default.readSync(fd, buf, 0, len, w.lastSize);
|
|
16638
16620
|
w.lastSize = size;
|
|
16639
16621
|
w.buf += buf.toString("utf8");
|
|
16640
16622
|
let newlineIndex;
|
|
@@ -16648,7 +16630,7 @@ var SessionObserver = class {
|
|
|
16648
16630
|
this.maybeReportUserMessage(w.sessionId, line);
|
|
16649
16631
|
}
|
|
16650
16632
|
} finally {
|
|
16651
|
-
|
|
16633
|
+
import_node_fs9.default.closeSync(fd);
|
|
16652
16634
|
}
|
|
16653
16635
|
}
|
|
16654
16636
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -17063,10 +17045,10 @@ function isLocalhost(addr) {
|
|
|
17063
17045
|
}
|
|
17064
17046
|
|
|
17065
17047
|
// src/discovery/state-file.ts
|
|
17066
|
-
var
|
|
17067
|
-
var
|
|
17048
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
17049
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
17068
17050
|
function defaultStateFilePath(dataDir) {
|
|
17069
|
-
return
|
|
17051
|
+
return import_node_path9.default.join(dataDir, "state.json");
|
|
17070
17052
|
}
|
|
17071
17053
|
function isPidAlive(pid) {
|
|
17072
17054
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -17088,7 +17070,7 @@ var StateFileManager = class {
|
|
|
17088
17070
|
}
|
|
17089
17071
|
read() {
|
|
17090
17072
|
try {
|
|
17091
|
-
const raw =
|
|
17073
|
+
const raw = import_node_fs10.default.readFileSync(this.file, "utf8");
|
|
17092
17074
|
const parsed = JSON.parse(raw);
|
|
17093
17075
|
return parsed;
|
|
17094
17076
|
} catch {
|
|
@@ -17102,34 +17084,34 @@ var StateFileManager = class {
|
|
|
17102
17084
|
return { status: "stale", existing };
|
|
17103
17085
|
}
|
|
17104
17086
|
write(state) {
|
|
17105
|
-
|
|
17087
|
+
import_node_fs10.default.mkdirSync(import_node_path9.default.dirname(this.file), { recursive: true });
|
|
17106
17088
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
17107
|
-
|
|
17108
|
-
|
|
17089
|
+
import_node_fs10.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
17090
|
+
import_node_fs10.default.renameSync(tmp, this.file);
|
|
17109
17091
|
if (process.platform !== "win32") {
|
|
17110
17092
|
try {
|
|
17111
|
-
|
|
17093
|
+
import_node_fs10.default.chmodSync(this.file, 384);
|
|
17112
17094
|
} catch {
|
|
17113
17095
|
}
|
|
17114
17096
|
}
|
|
17115
17097
|
}
|
|
17116
17098
|
delete() {
|
|
17117
17099
|
try {
|
|
17118
|
-
|
|
17100
|
+
import_node_fs10.default.unlinkSync(this.file);
|
|
17119
17101
|
} catch {
|
|
17120
17102
|
}
|
|
17121
17103
|
}
|
|
17122
17104
|
};
|
|
17123
17105
|
|
|
17124
17106
|
// src/tunnel/tunnel-manager.ts
|
|
17125
|
-
var
|
|
17126
|
-
var
|
|
17107
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
17108
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
17127
17109
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
17128
17110
|
var import_node_child_process4 = require("child_process");
|
|
17129
17111
|
|
|
17130
17112
|
// src/tunnel/tunnel-store.ts
|
|
17131
|
-
var
|
|
17132
|
-
var
|
|
17113
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
17114
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
17133
17115
|
var TunnelStore = class {
|
|
17134
17116
|
constructor(filePath) {
|
|
17135
17117
|
this.filePath = filePath;
|
|
@@ -17137,7 +17119,7 @@ var TunnelStore = class {
|
|
|
17137
17119
|
filePath;
|
|
17138
17120
|
async get() {
|
|
17139
17121
|
try {
|
|
17140
|
-
const raw = await
|
|
17122
|
+
const raw = await import_node_fs11.default.promises.readFile(this.filePath, "utf8");
|
|
17141
17123
|
const obj = JSON.parse(raw);
|
|
17142
17124
|
if (!isPersistedTunnel(obj)) return null;
|
|
17143
17125
|
return obj;
|
|
@@ -17148,22 +17130,22 @@ var TunnelStore = class {
|
|
|
17148
17130
|
}
|
|
17149
17131
|
}
|
|
17150
17132
|
async set(v) {
|
|
17151
|
-
const dir =
|
|
17152
|
-
await
|
|
17133
|
+
const dir = import_node_path10.default.dirname(this.filePath);
|
|
17134
|
+
await import_node_fs11.default.promises.mkdir(dir, { recursive: true });
|
|
17153
17135
|
const data = JSON.stringify(v, null, 2);
|
|
17154
17136
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
17155
|
-
await
|
|
17137
|
+
await import_node_fs11.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
17156
17138
|
if (process.platform !== "win32") {
|
|
17157
17139
|
try {
|
|
17158
|
-
await
|
|
17140
|
+
await import_node_fs11.default.promises.chmod(tmp, 384);
|
|
17159
17141
|
} catch {
|
|
17160
17142
|
}
|
|
17161
17143
|
}
|
|
17162
|
-
await
|
|
17144
|
+
await import_node_fs11.default.promises.rename(tmp, this.filePath);
|
|
17163
17145
|
}
|
|
17164
17146
|
async clear() {
|
|
17165
17147
|
try {
|
|
17166
|
-
await
|
|
17148
|
+
await import_node_fs11.default.promises.unlink(this.filePath);
|
|
17167
17149
|
} catch (err) {
|
|
17168
17150
|
const code = err?.code;
|
|
17169
17151
|
if (code !== "ENOENT") throw err;
|
|
@@ -17258,9 +17240,9 @@ function escape(v) {
|
|
|
17258
17240
|
}
|
|
17259
17241
|
|
|
17260
17242
|
// src/tunnel/frpc-binary.ts
|
|
17261
|
-
var
|
|
17243
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
17262
17244
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
17263
|
-
var
|
|
17245
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
17264
17246
|
var import_node_child_process3 = require("child_process");
|
|
17265
17247
|
var import_node_stream = require("stream");
|
|
17266
17248
|
var import_promises = require("stream/promises");
|
|
@@ -17292,20 +17274,20 @@ function frpcDownloadUrl(version2, p) {
|
|
|
17292
17274
|
}
|
|
17293
17275
|
async function ensureFrpcBinary(opts) {
|
|
17294
17276
|
if (opts.override) {
|
|
17295
|
-
if (!
|
|
17277
|
+
if (!import_node_fs12.default.existsSync(opts.override)) {
|
|
17296
17278
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
17297
17279
|
}
|
|
17298
17280
|
return opts.override;
|
|
17299
17281
|
}
|
|
17300
17282
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
17301
17283
|
const platform = opts.platform ?? detectPlatform();
|
|
17302
|
-
const binDir =
|
|
17303
|
-
|
|
17284
|
+
const binDir = import_node_path11.default.join(opts.dataDir, "bin");
|
|
17285
|
+
import_node_fs12.default.mkdirSync(binDir, { recursive: true });
|
|
17304
17286
|
cleanupStaleArtifacts(binDir);
|
|
17305
|
-
const stableBin =
|
|
17306
|
-
if (
|
|
17287
|
+
const stableBin = import_node_path11.default.join(binDir, "frpc");
|
|
17288
|
+
if (import_node_fs12.default.existsSync(stableBin)) return stableBin;
|
|
17307
17289
|
const partialBin = `${stableBin}.partial`;
|
|
17308
|
-
const tarballPath =
|
|
17290
|
+
const tarballPath = import_node_path11.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
17309
17291
|
try {
|
|
17310
17292
|
const url = frpcDownloadUrl(version2, platform);
|
|
17311
17293
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -17314,8 +17296,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
17314
17296
|
} else {
|
|
17315
17297
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
17316
17298
|
}
|
|
17317
|
-
|
|
17318
|
-
|
|
17299
|
+
import_node_fs12.default.chmodSync(partialBin, 493);
|
|
17300
|
+
import_node_fs12.default.renameSync(partialBin, stableBin);
|
|
17319
17301
|
} finally {
|
|
17320
17302
|
safeUnlink(tarballPath);
|
|
17321
17303
|
safeUnlink(partialBin);
|
|
@@ -17325,15 +17307,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
17325
17307
|
function cleanupStaleArtifacts(binDir) {
|
|
17326
17308
|
let entries;
|
|
17327
17309
|
try {
|
|
17328
|
-
entries =
|
|
17310
|
+
entries = import_node_fs12.default.readdirSync(binDir);
|
|
17329
17311
|
} catch {
|
|
17330
17312
|
return;
|
|
17331
17313
|
}
|
|
17332
17314
|
for (const name of entries) {
|
|
17333
17315
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
17334
|
-
const full =
|
|
17316
|
+
const full = import_node_path11.default.join(binDir, name);
|
|
17335
17317
|
try {
|
|
17336
|
-
|
|
17318
|
+
import_node_fs12.default.rmSync(full, { recursive: true, force: true });
|
|
17337
17319
|
} catch {
|
|
17338
17320
|
}
|
|
17339
17321
|
}
|
|
@@ -17341,7 +17323,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
17341
17323
|
}
|
|
17342
17324
|
function safeUnlink(p) {
|
|
17343
17325
|
try {
|
|
17344
|
-
|
|
17326
|
+
import_node_fs12.default.unlinkSync(p);
|
|
17345
17327
|
} catch {
|
|
17346
17328
|
}
|
|
17347
17329
|
}
|
|
@@ -17352,13 +17334,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
17352
17334
|
if (!res.ok || !res.body) {
|
|
17353
17335
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
17354
17336
|
}
|
|
17355
|
-
const out =
|
|
17337
|
+
const out = import_node_fs12.default.createWriteStream(dest);
|
|
17356
17338
|
const nodeStream = import_node_stream.Readable.fromWeb(res.body);
|
|
17357
17339
|
await (0, import_promises.pipeline)(nodeStream, out);
|
|
17358
17340
|
}
|
|
17359
17341
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
17360
|
-
const work =
|
|
17361
|
-
|
|
17342
|
+
const work = import_node_path11.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
17343
|
+
import_node_fs12.default.mkdirSync(work, { recursive: true });
|
|
17362
17344
|
try {
|
|
17363
17345
|
await new Promise((resolve, reject) => {
|
|
17364
17346
|
const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -17366,13 +17348,13 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
17366
17348
|
proc.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`tar exited ${code}`)));
|
|
17367
17349
|
});
|
|
17368
17350
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
17369
|
-
const src =
|
|
17370
|
-
if (!
|
|
17351
|
+
const src = import_node_path11.default.join(work, dirName, "frpc");
|
|
17352
|
+
if (!import_node_fs12.default.existsSync(src)) {
|
|
17371
17353
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
17372
17354
|
}
|
|
17373
|
-
|
|
17355
|
+
import_node_fs12.default.copyFileSync(src, destBin);
|
|
17374
17356
|
} finally {
|
|
17375
|
-
|
|
17357
|
+
import_node_fs12.default.rmSync(work, { recursive: true, force: true });
|
|
17376
17358
|
}
|
|
17377
17359
|
}
|
|
17378
17360
|
|
|
@@ -17381,7 +17363,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
17381
17363
|
var TunnelManager = class {
|
|
17382
17364
|
constructor(deps) {
|
|
17383
17365
|
this.deps = deps;
|
|
17384
|
-
this.store = deps.store ?? new TunnelStore(
|
|
17366
|
+
this.store = deps.store ?? new TunnelStore(import_node_path12.default.join(deps.dataDir, "tunnel.json"));
|
|
17385
17367
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
17386
17368
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
17387
17369
|
}
|
|
@@ -17498,7 +17480,7 @@ var TunnelManager = class {
|
|
|
17498
17480
|
dataDir: this.deps.dataDir,
|
|
17499
17481
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
17500
17482
|
});
|
|
17501
|
-
const tomlPath =
|
|
17483
|
+
const tomlPath = import_node_path12.default.join(this.deps.dataDir, "frpc.toml");
|
|
17502
17484
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto3.default.randomBytes(3).toString("hex")}`;
|
|
17503
17485
|
const toml = buildFrpcToml({
|
|
17504
17486
|
serverAddr: t.frpsHost,
|
|
@@ -17509,12 +17491,12 @@ var TunnelManager = class {
|
|
|
17509
17491
|
localPort,
|
|
17510
17492
|
logLevel: "info"
|
|
17511
17493
|
});
|
|
17512
|
-
await
|
|
17494
|
+
await import_node_fs13.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
17513
17495
|
const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
|
|
17514
17496
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17515
17497
|
});
|
|
17516
|
-
const logFilePath =
|
|
17517
|
-
const logStream =
|
|
17498
|
+
const logFilePath = import_node_path12.default.join(this.deps.dataDir, "frpc.log");
|
|
17499
|
+
const logStream = import_node_fs13.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
17518
17500
|
logStream.on("error", () => {
|
|
17519
17501
|
});
|
|
17520
17502
|
const tee = (chunk) => {
|
|
@@ -17606,12 +17588,12 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
17606
17588
|
}
|
|
17607
17589
|
|
|
17608
17590
|
// src/auth-store.ts
|
|
17609
|
-
var
|
|
17610
|
-
var
|
|
17591
|
+
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
17592
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
17611
17593
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
17612
17594
|
var AUTH_FILE_NAME = "auth.json";
|
|
17613
17595
|
function authFilePath(dataDir) {
|
|
17614
|
-
return
|
|
17596
|
+
return import_node_path13.default.join(dataDir, AUTH_FILE_NAME);
|
|
17615
17597
|
}
|
|
17616
17598
|
function loadOrCreateAuthToken(opts) {
|
|
17617
17599
|
const file = authFilePath(opts.dataDir);
|
|
@@ -17627,7 +17609,7 @@ function defaultGenerate() {
|
|
|
17627
17609
|
}
|
|
17628
17610
|
function readAuthFile(file) {
|
|
17629
17611
|
try {
|
|
17630
|
-
const raw =
|
|
17612
|
+
const raw = import_node_fs14.default.readFileSync(file, "utf8");
|
|
17631
17613
|
const parsed = JSON.parse(raw);
|
|
17632
17614
|
if (typeof parsed?.token === "string" && parsed.token.length > 0) {
|
|
17633
17615
|
return {
|
|
@@ -17643,20 +17625,20 @@ function readAuthFile(file) {
|
|
|
17643
17625
|
}
|
|
17644
17626
|
}
|
|
17645
17627
|
function writeAuthFile(file, content) {
|
|
17646
|
-
|
|
17647
|
-
|
|
17628
|
+
import_node_fs14.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
|
|
17629
|
+
import_node_fs14.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
17648
17630
|
try {
|
|
17649
|
-
|
|
17631
|
+
import_node_fs14.default.chmodSync(file, 384);
|
|
17650
17632
|
} catch {
|
|
17651
17633
|
}
|
|
17652
17634
|
}
|
|
17653
17635
|
|
|
17654
17636
|
// src/session/fork.ts
|
|
17655
|
-
var
|
|
17637
|
+
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
17656
17638
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
17657
|
-
var
|
|
17639
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
17658
17640
|
function readJsonlEntries(file) {
|
|
17659
|
-
const raw =
|
|
17641
|
+
const raw = import_node_fs15.default.readFileSync(file, "utf8");
|
|
17660
17642
|
const out = [];
|
|
17661
17643
|
for (const line of raw.split("\n")) {
|
|
17662
17644
|
const t = line.trim();
|
|
@@ -17669,10 +17651,10 @@ function readJsonlEntries(file) {
|
|
|
17669
17651
|
return out;
|
|
17670
17652
|
}
|
|
17671
17653
|
function forkSession(input) {
|
|
17672
|
-
const baseDir = input.baseDir ??
|
|
17673
|
-
const projectDir =
|
|
17674
|
-
const sourceFile =
|
|
17675
|
-
if (!
|
|
17654
|
+
const baseDir = input.baseDir ?? import_node_path14.default.join(import_node_os9.default.homedir(), ".claude");
|
|
17655
|
+
const projectDir = import_node_path14.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
17656
|
+
const sourceFile = import_node_path14.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
17657
|
+
if (!import_node_fs15.default.existsSync(sourceFile)) {
|
|
17676
17658
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
17677
17659
|
}
|
|
17678
17660
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -17702,9 +17684,9 @@ function forkSession(input) {
|
|
|
17702
17684
|
}
|
|
17703
17685
|
forkedLines.push(JSON.stringify(forked));
|
|
17704
17686
|
}
|
|
17705
|
-
const forkedFilePath =
|
|
17706
|
-
|
|
17707
|
-
|
|
17687
|
+
const forkedFilePath = import_node_path14.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
17688
|
+
import_node_fs15.default.mkdirSync(projectDir, { recursive: true });
|
|
17689
|
+
import_node_fs15.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
17708
17690
|
return { forkedToolSessionId, forkedFilePath };
|
|
17709
17691
|
}
|
|
17710
17692
|
|
|
@@ -17825,6 +17807,11 @@ function buildSessionHandlers(deps) {
|
|
|
17825
17807
|
const { response, broadcast } = manager.pin(args);
|
|
17826
17808
|
return { response: { type: "session:info", ...response }, broadcast };
|
|
17827
17809
|
};
|
|
17810
|
+
const reorderPins = async (frame) => {
|
|
17811
|
+
const args = SessionReorderPinsArgs.parse(frame);
|
|
17812
|
+
const { response, broadcast } = manager.reorderPins(args);
|
|
17813
|
+
return { response: { type: "session:reorderPins", ...response }, broadcast };
|
|
17814
|
+
};
|
|
17828
17815
|
const answerQuestion = async (frame) => {
|
|
17829
17816
|
const args = AnswerQuestionArgs.parse(frame);
|
|
17830
17817
|
const { response, broadcast } = manager.answerQuestion(args);
|
|
@@ -17850,6 +17837,7 @@ function buildSessionHandlers(deps) {
|
|
|
17850
17837
|
"session:subscribe": subscribe,
|
|
17851
17838
|
"session:unsubscribe": unsubscribe,
|
|
17852
17839
|
"session:pin": pin,
|
|
17840
|
+
"session:reorderPins": reorderPins,
|
|
17853
17841
|
"session:answerQuestion": answerQuestion
|
|
17854
17842
|
};
|
|
17855
17843
|
}
|
|
@@ -17960,9 +17948,9 @@ function buildWorkspaceHandlers(deps) {
|
|
|
17960
17948
|
|
|
17961
17949
|
// src/workspace/git.ts
|
|
17962
17950
|
var import_node_child_process5 = require("child_process");
|
|
17963
|
-
var
|
|
17951
|
+
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
17964
17952
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
17965
|
-
var
|
|
17953
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
17966
17954
|
var import_node_util = require("util");
|
|
17967
17955
|
var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
|
|
17968
17956
|
function formatChildProcessError(err) {
|
|
@@ -17977,9 +17965,9 @@ function formatChildProcessError(err) {
|
|
|
17977
17965
|
return e.message ?? "unknown error";
|
|
17978
17966
|
}
|
|
17979
17967
|
function normalizePath(p) {
|
|
17980
|
-
const resolved =
|
|
17968
|
+
const resolved = import_node_path15.default.resolve(p);
|
|
17981
17969
|
try {
|
|
17982
|
-
return
|
|
17970
|
+
return import_node_fs16.default.realpathSync(resolved);
|
|
17983
17971
|
} catch {
|
|
17984
17972
|
return resolved;
|
|
17985
17973
|
}
|
|
@@ -18080,13 +18068,13 @@ function flattenToDirName(branch) {
|
|
|
18080
18068
|
}
|
|
18081
18069
|
function encodeClaudeProjectDir(absPath) {
|
|
18082
18070
|
if (!absPath || typeof absPath !== "string") return "";
|
|
18083
|
-
let canonical =
|
|
18071
|
+
let canonical = import_node_path15.default.resolve(absPath);
|
|
18084
18072
|
try {
|
|
18085
|
-
canonical =
|
|
18073
|
+
canonical = import_node_fs16.default.realpathSync(canonical);
|
|
18086
18074
|
} catch {
|
|
18087
18075
|
try {
|
|
18088
|
-
const parent =
|
|
18089
|
-
canonical =
|
|
18076
|
+
const parent = import_node_fs16.default.realpathSync(import_node_path15.default.dirname(canonical));
|
|
18077
|
+
canonical = import_node_path15.default.join(parent, import_node_path15.default.basename(canonical));
|
|
18090
18078
|
} catch {
|
|
18091
18079
|
}
|
|
18092
18080
|
}
|
|
@@ -18110,11 +18098,11 @@ async function createWorktree(input) {
|
|
|
18110
18098
|
if (!isGitRoot) {
|
|
18111
18099
|
throw new Error(`\u76EE\u5F55 ${cwd} \u4E0D\u662F git repo \u6839`);
|
|
18112
18100
|
}
|
|
18113
|
-
const parent =
|
|
18114
|
-
if (parent === "/" || parent ===
|
|
18101
|
+
const parent = import_node_path15.default.dirname(import_node_path15.default.resolve(cwd));
|
|
18102
|
+
if (parent === "/" || parent === import_node_path15.default.resolve(cwd)) {
|
|
18115
18103
|
throw new Error("repo \u5728\u78C1\u76D8\u6839\u76EE\u5F55\uFF0C\u65E0\u6CD5\u5728\u540C\u7EA7\u521B\u5EFA worktree");
|
|
18116
18104
|
}
|
|
18117
|
-
const worktreeRoot =
|
|
18105
|
+
const worktreeRoot = import_node_path15.default.join(parent, dirName);
|
|
18118
18106
|
try {
|
|
18119
18107
|
await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${baseBranch}`], {
|
|
18120
18108
|
timeout: 3e3
|
|
@@ -18131,7 +18119,7 @@ async function createWorktree(input) {
|
|
|
18131
18119
|
const msg = err.message;
|
|
18132
18120
|
if (msg.startsWith("\u5206\u652F ")) throw err;
|
|
18133
18121
|
}
|
|
18134
|
-
if (
|
|
18122
|
+
if (import_node_fs16.default.existsSync(worktreeRoot)) {
|
|
18135
18123
|
throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
|
|
18136
18124
|
}
|
|
18137
18125
|
try {
|
|
@@ -18159,8 +18147,8 @@ async function removeWorktree(input) {
|
|
|
18159
18147
|
);
|
|
18160
18148
|
const gitCommonDir = stdout.trim();
|
|
18161
18149
|
if (!gitCommonDir) throw new Error("empty git-common-dir");
|
|
18162
|
-
const absGitCommon =
|
|
18163
|
-
repoRoot =
|
|
18150
|
+
const absGitCommon = import_node_path15.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path15.default.resolve(worktreeRoot, gitCommonDir);
|
|
18151
|
+
repoRoot = import_node_path15.default.dirname(absGitCommon);
|
|
18164
18152
|
} catch {
|
|
18165
18153
|
repoRoot = null;
|
|
18166
18154
|
}
|
|
@@ -18172,7 +18160,7 @@ async function removeWorktree(input) {
|
|
|
18172
18160
|
} catch (err) {
|
|
18173
18161
|
const stderr = err.stderr ?? "";
|
|
18174
18162
|
const lower = stderr.toLowerCase();
|
|
18175
|
-
const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !
|
|
18163
|
+
const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs16.default.existsSync(worktreeRoot);
|
|
18176
18164
|
if (!vanished) {
|
|
18177
18165
|
throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
|
|
18178
18166
|
}
|
|
@@ -18191,10 +18179,10 @@ async function removeWorktree(input) {
|
|
|
18191
18179
|
try {
|
|
18192
18180
|
const encoded = encodeClaudeProjectDir(worktreeRoot);
|
|
18193
18181
|
if (encoded) {
|
|
18194
|
-
const projectsRoot =
|
|
18195
|
-
const target =
|
|
18196
|
-
if (target.startsWith(projectsRoot +
|
|
18197
|
-
|
|
18182
|
+
const projectsRoot = import_node_path15.default.join(import_node_os10.default.homedir(), ".claude", "projects");
|
|
18183
|
+
const target = import_node_path15.default.resolve(projectsRoot, encoded);
|
|
18184
|
+
if (target.startsWith(projectsRoot + import_node_path15.default.sep) && target !== projectsRoot) {
|
|
18185
|
+
import_node_fs16.default.rmSync(target, { recursive: true, force: true });
|
|
18198
18186
|
}
|
|
18199
18187
|
}
|
|
18200
18188
|
} catch {
|
|
@@ -18321,7 +18309,7 @@ function buildMethodHandlers(deps) {
|
|
|
18321
18309
|
async function startDaemon(config) {
|
|
18322
18310
|
const logger = createLogger({
|
|
18323
18311
|
level: config.logLevel,
|
|
18324
|
-
file:
|
|
18312
|
+
file: import_node_path16.default.join(config.dataDir, "clawd.log")
|
|
18325
18313
|
});
|
|
18326
18314
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
18327
18315
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
@@ -18361,7 +18349,6 @@ async function startDaemon(config) {
|
|
|
18361
18349
|
logger,
|
|
18362
18350
|
getAdapter,
|
|
18363
18351
|
historyReader: history,
|
|
18364
|
-
dataDir: config.dataDir,
|
|
18365
18352
|
broadcastFrame: (frame, target) => {
|
|
18366
18353
|
if (target === "all") {
|
|
18367
18354
|
transport?.broadcastAll(frame);
|
|
@@ -18484,8 +18471,8 @@ async function startDaemon(config) {
|
|
|
18484
18471
|
const lines = [
|
|
18485
18472
|
`Tunnel: ${r.url}`,
|
|
18486
18473
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
18487
|
-
`Frpc config: ${
|
|
18488
|
-
`Frpc log: ${
|
|
18474
|
+
`Frpc config: ${import_node_path16.default.join(config.dataDir, "frpc.toml")}`,
|
|
18475
|
+
`Frpc log: ${import_node_path16.default.join(config.dataDir, "frpc.log")}`
|
|
18489
18476
|
];
|
|
18490
18477
|
const width = Math.max(...lines.map((l) => l.length));
|
|
18491
18478
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -18498,8 +18485,8 @@ ${bar}
|
|
|
18498
18485
|
|
|
18499
18486
|
`);
|
|
18500
18487
|
try {
|
|
18501
|
-
const connectPath =
|
|
18502
|
-
|
|
18488
|
+
const connectPath = import_node_path16.default.join(config.dataDir, "connect.txt");
|
|
18489
|
+
import_node_fs17.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
18503
18490
|
} catch {
|
|
18504
18491
|
}
|
|
18505
18492
|
} catch (err) {
|