@clawos-dev/clawd 0.2.136-beta.285.b451e3c → 0.2.136-beta.287.97b0d33
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 +314 -385
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -720,8 +720,8 @@ var init_parseUtil = __esm({
|
|
|
720
720
|
init_errors2();
|
|
721
721
|
init_en();
|
|
722
722
|
makeIssue = (params) => {
|
|
723
|
-
const { data, path:
|
|
724
|
-
const fullPath = [...
|
|
723
|
+
const { data, path: path58, errorMaps, issueData } = params;
|
|
724
|
+
const fullPath = [...path58, ...issueData.path || []];
|
|
725
725
|
const fullIssue = {
|
|
726
726
|
...issueData,
|
|
727
727
|
path: fullPath
|
|
@@ -1032,11 +1032,11 @@ var init_types = __esm({
|
|
|
1032
1032
|
init_parseUtil();
|
|
1033
1033
|
init_util();
|
|
1034
1034
|
ParseInputLazyPath = class {
|
|
1035
|
-
constructor(parent, value,
|
|
1035
|
+
constructor(parent, value, path58, key) {
|
|
1036
1036
|
this._cachedPath = [];
|
|
1037
1037
|
this.parent = parent;
|
|
1038
1038
|
this.data = value;
|
|
1039
|
-
this._path =
|
|
1039
|
+
this._path = path58;
|
|
1040
1040
|
this._key = key;
|
|
1041
1041
|
}
|
|
1042
1042
|
get path() {
|
|
@@ -6218,8 +6218,8 @@ var require_req = __commonJS({
|
|
|
6218
6218
|
if (req.originalUrl) {
|
|
6219
6219
|
_req.url = req.originalUrl;
|
|
6220
6220
|
} else {
|
|
6221
|
-
const
|
|
6222
|
-
_req.url = typeof
|
|
6221
|
+
const path58 = req.path;
|
|
6222
|
+
_req.url = typeof path58 === "string" ? path58 : req.url ? req.url.path || req.url : void 0;
|
|
6223
6223
|
}
|
|
6224
6224
|
if (req.query) {
|
|
6225
6225
|
_req.query = req.query;
|
|
@@ -6384,14 +6384,14 @@ var require_redact = __commonJS({
|
|
|
6384
6384
|
}
|
|
6385
6385
|
return obj;
|
|
6386
6386
|
}
|
|
6387
|
-
function parsePath(
|
|
6387
|
+
function parsePath(path58) {
|
|
6388
6388
|
const parts = [];
|
|
6389
6389
|
let current = "";
|
|
6390
6390
|
let inBrackets = false;
|
|
6391
6391
|
let inQuotes = false;
|
|
6392
6392
|
let quoteChar = "";
|
|
6393
|
-
for (let i = 0; i <
|
|
6394
|
-
const char =
|
|
6393
|
+
for (let i = 0; i < path58.length; i++) {
|
|
6394
|
+
const char = path58[i];
|
|
6395
6395
|
if (!inBrackets && char === ".") {
|
|
6396
6396
|
if (current) {
|
|
6397
6397
|
parts.push(current);
|
|
@@ -6522,10 +6522,10 @@ var require_redact = __commonJS({
|
|
|
6522
6522
|
return current;
|
|
6523
6523
|
}
|
|
6524
6524
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6525
|
-
for (const
|
|
6526
|
-
const parts = parsePath(
|
|
6525
|
+
for (const path58 of paths) {
|
|
6526
|
+
const parts = parsePath(path58);
|
|
6527
6527
|
if (parts.includes("*")) {
|
|
6528
|
-
redactWildcardPath(obj, parts, censor,
|
|
6528
|
+
redactWildcardPath(obj, parts, censor, path58, remove);
|
|
6529
6529
|
} else {
|
|
6530
6530
|
if (remove) {
|
|
6531
6531
|
removeKey(obj, parts);
|
|
@@ -6610,8 +6610,8 @@ var require_redact = __commonJS({
|
|
|
6610
6610
|
}
|
|
6611
6611
|
} else {
|
|
6612
6612
|
if (afterWildcard.includes("*")) {
|
|
6613
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6614
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
6613
|
+
const wrappedCensor = typeof censor === "function" ? (value, path58) => {
|
|
6614
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path58];
|
|
6615
6615
|
return censor(value, fullPath);
|
|
6616
6616
|
} : censor;
|
|
6617
6617
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -6646,8 +6646,8 @@ var require_redact = __commonJS({
|
|
|
6646
6646
|
return null;
|
|
6647
6647
|
}
|
|
6648
6648
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
6649
|
-
for (const
|
|
6650
|
-
const parts = parsePath(
|
|
6649
|
+
for (const path58 of pathsToClone) {
|
|
6650
|
+
const parts = parsePath(path58);
|
|
6651
6651
|
let current = pathStructure;
|
|
6652
6652
|
for (let i = 0; i < parts.length; i++) {
|
|
6653
6653
|
const part = parts[i];
|
|
@@ -6699,24 +6699,24 @@ var require_redact = __commonJS({
|
|
|
6699
6699
|
}
|
|
6700
6700
|
return cloneSelectively(obj, pathStructure);
|
|
6701
6701
|
}
|
|
6702
|
-
function validatePath(
|
|
6703
|
-
if (typeof
|
|
6702
|
+
function validatePath(path58) {
|
|
6703
|
+
if (typeof path58 !== "string") {
|
|
6704
6704
|
throw new Error("Paths must be (non-empty) strings");
|
|
6705
6705
|
}
|
|
6706
|
-
if (
|
|
6706
|
+
if (path58 === "") {
|
|
6707
6707
|
throw new Error("Invalid redaction path ()");
|
|
6708
6708
|
}
|
|
6709
|
-
if (
|
|
6710
|
-
throw new Error(`Invalid redaction path (${
|
|
6709
|
+
if (path58.includes("..")) {
|
|
6710
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6711
6711
|
}
|
|
6712
|
-
if (
|
|
6713
|
-
throw new Error(`Invalid redaction path (${
|
|
6712
|
+
if (path58.includes(",")) {
|
|
6713
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6714
6714
|
}
|
|
6715
6715
|
let bracketCount = 0;
|
|
6716
6716
|
let inQuotes = false;
|
|
6717
6717
|
let quoteChar = "";
|
|
6718
|
-
for (let i = 0; i <
|
|
6719
|
-
const char =
|
|
6718
|
+
for (let i = 0; i < path58.length; i++) {
|
|
6719
|
+
const char = path58[i];
|
|
6720
6720
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
6721
6721
|
if (!inQuotes) {
|
|
6722
6722
|
inQuotes = true;
|
|
@@ -6730,20 +6730,20 @@ var require_redact = __commonJS({
|
|
|
6730
6730
|
} else if (char === "]" && !inQuotes) {
|
|
6731
6731
|
bracketCount--;
|
|
6732
6732
|
if (bracketCount < 0) {
|
|
6733
|
-
throw new Error(`Invalid redaction path (${
|
|
6733
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6734
6734
|
}
|
|
6735
6735
|
}
|
|
6736
6736
|
}
|
|
6737
6737
|
if (bracketCount !== 0) {
|
|
6738
|
-
throw new Error(`Invalid redaction path (${
|
|
6738
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6739
6739
|
}
|
|
6740
6740
|
}
|
|
6741
6741
|
function validatePaths(paths) {
|
|
6742
6742
|
if (!Array.isArray(paths)) {
|
|
6743
6743
|
throw new TypeError("paths must be an array");
|
|
6744
6744
|
}
|
|
6745
|
-
for (const
|
|
6746
|
-
validatePath(
|
|
6745
|
+
for (const path58 of paths) {
|
|
6746
|
+
validatePath(path58);
|
|
6747
6747
|
}
|
|
6748
6748
|
}
|
|
6749
6749
|
function slowRedact(options = {}) {
|
|
@@ -6911,8 +6911,8 @@ var require_redaction = __commonJS({
|
|
|
6911
6911
|
if (shape[k2] === null) {
|
|
6912
6912
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
6913
6913
|
} else {
|
|
6914
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6915
|
-
return censor(value, [k2, ...
|
|
6914
|
+
const wrappedCensor = typeof censor === "function" ? (value, path58) => {
|
|
6915
|
+
return censor(value, [k2, ...path58]);
|
|
6916
6916
|
} : censor;
|
|
6917
6917
|
o[k2] = Redact({
|
|
6918
6918
|
paths: shape[k2],
|
|
@@ -7133,7 +7133,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7133
7133
|
var fs51 = require("fs");
|
|
7134
7134
|
var EventEmitter3 = require("events");
|
|
7135
7135
|
var inherits = require("util").inherits;
|
|
7136
|
-
var
|
|
7136
|
+
var path58 = require("path");
|
|
7137
7137
|
var sleep = require_atomic_sleep();
|
|
7138
7138
|
var assert = require("assert");
|
|
7139
7139
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7187,7 +7187,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7187
7187
|
const mode = sonic.mode;
|
|
7188
7188
|
if (sonic.sync) {
|
|
7189
7189
|
try {
|
|
7190
|
-
if (sonic.mkdir) fs51.mkdirSync(
|
|
7190
|
+
if (sonic.mkdir) fs51.mkdirSync(path58.dirname(file), { recursive: true });
|
|
7191
7191
|
const fd = fs51.openSync(file, flags, mode);
|
|
7192
7192
|
fileOpened(null, fd);
|
|
7193
7193
|
} catch (err) {
|
|
@@ -7195,7 +7195,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7195
7195
|
throw err;
|
|
7196
7196
|
}
|
|
7197
7197
|
} else if (sonic.mkdir) {
|
|
7198
|
-
fs51.mkdir(
|
|
7198
|
+
fs51.mkdir(path58.dirname(file), { recursive: true }, (err) => {
|
|
7199
7199
|
if (err) return fileOpened(err);
|
|
7200
7200
|
fs51.open(file, flags, mode, fileOpened);
|
|
7201
7201
|
});
|
|
@@ -10055,7 +10055,7 @@ var require_multistream = __commonJS({
|
|
|
10055
10055
|
var require_pino = __commonJS({
|
|
10056
10056
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
10057
10057
|
"use strict";
|
|
10058
|
-
var
|
|
10058
|
+
var os21 = require("os");
|
|
10059
10059
|
var stdSerializers = require_pino_std_serializers();
|
|
10060
10060
|
var caller = require_caller();
|
|
10061
10061
|
var redaction = require_redaction();
|
|
@@ -10102,7 +10102,7 @@ var require_pino = __commonJS({
|
|
|
10102
10102
|
} = symbols;
|
|
10103
10103
|
var { epochTime, nullTime } = time;
|
|
10104
10104
|
var { pid } = process;
|
|
10105
|
-
var hostname =
|
|
10105
|
+
var hostname = os21.hostname();
|
|
10106
10106
|
var defaultErrorSerializer = stdSerializers.err;
|
|
10107
10107
|
var defaultOptions = {
|
|
10108
10108
|
level: "info",
|
|
@@ -10826,11 +10826,11 @@ var init_lib = __esm({
|
|
|
10826
10826
|
}
|
|
10827
10827
|
}
|
|
10828
10828
|
},
|
|
10829
|
-
addToPath: function addToPath(
|
|
10830
|
-
var last =
|
|
10829
|
+
addToPath: function addToPath(path58, added, removed, oldPosInc, options) {
|
|
10830
|
+
var last = path58.lastComponent;
|
|
10831
10831
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
10832
10832
|
return {
|
|
10833
|
-
oldPos:
|
|
10833
|
+
oldPos: path58.oldPos + oldPosInc,
|
|
10834
10834
|
lastComponent: {
|
|
10835
10835
|
count: last.count + 1,
|
|
10836
10836
|
added,
|
|
@@ -10840,7 +10840,7 @@ var init_lib = __esm({
|
|
|
10840
10840
|
};
|
|
10841
10841
|
} else {
|
|
10842
10842
|
return {
|
|
10843
|
-
oldPos:
|
|
10843
|
+
oldPos: path58.oldPos + oldPosInc,
|
|
10844
10844
|
lastComponent: {
|
|
10845
10845
|
count: 1,
|
|
10846
10846
|
added,
|
|
@@ -11286,10 +11286,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11286
11286
|
const memories = raw.map((m2) => {
|
|
11287
11287
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11288
11288
|
const rec3 = m2;
|
|
11289
|
-
const
|
|
11289
|
+
const path58 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11290
11290
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11291
|
-
if (!
|
|
11292
|
-
const entry = { path:
|
|
11291
|
+
if (!path58 || content == null) return null;
|
|
11292
|
+
const entry = { path: path58, content };
|
|
11293
11293
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11294
11294
|
return entry;
|
|
11295
11295
|
}).filter((m2) => m2 !== null);
|
|
@@ -11754,12 +11754,6 @@ var init_claude_history = __esm({
|
|
|
11754
11754
|
});
|
|
11755
11755
|
|
|
11756
11756
|
// src/tools/claude.ts
|
|
11757
|
-
function macOSDesktopCandidates(home) {
|
|
11758
|
-
return [
|
|
11759
|
-
import_node_path9.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
|
|
11760
|
-
"/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
|
|
11761
|
-
];
|
|
11762
|
-
}
|
|
11763
11757
|
function probeViaWhich() {
|
|
11764
11758
|
try {
|
|
11765
11759
|
const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
|
|
@@ -11768,19 +11762,12 @@ function probeViaWhich() {
|
|
|
11768
11762
|
}
|
|
11769
11763
|
return null;
|
|
11770
11764
|
}
|
|
11771
|
-
async function probeClaude(env = process.env
|
|
11765
|
+
async function probeClaude(env = process.env) {
|
|
11772
11766
|
if (env.CLAUDE_BIN && import_node_fs9.default.existsSync(env.CLAUDE_BIN)) {
|
|
11773
11767
|
return { available: true, path: env.CLAUDE_BIN };
|
|
11774
11768
|
}
|
|
11775
11769
|
const w2 = probeViaWhich();
|
|
11776
11770
|
if (w2) return { available: true, path: w2 };
|
|
11777
|
-
if (process.platform === "darwin") {
|
|
11778
|
-
for (const candidate of macOSDesktopCandidates(home)) {
|
|
11779
|
-
if (import_node_fs9.default.existsSync(candidate)) {
|
|
11780
|
-
return { available: true, path: candidate };
|
|
11781
|
-
}
|
|
11782
|
-
}
|
|
11783
|
-
}
|
|
11784
11771
|
return { available: false };
|
|
11785
11772
|
}
|
|
11786
11773
|
function buildSpawnArgs(ctx) {
|
|
@@ -12101,10 +12088,10 @@ function parseAttachment(obj) {
|
|
|
12101
12088
|
const memories = raw.map((m2) => {
|
|
12102
12089
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12103
12090
|
const rec3 = m2;
|
|
12104
|
-
const
|
|
12091
|
+
const path58 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12105
12092
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12106
|
-
if (!
|
|
12107
|
-
const out = { path:
|
|
12093
|
+
if (!path58 || content == null) return null;
|
|
12094
|
+
const out = { path: path58, content };
|
|
12108
12095
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12109
12096
|
return out;
|
|
12110
12097
|
}).filter((m2) => m2 !== null);
|
|
@@ -12208,15 +12195,13 @@ function encodeClaudeStdin(text) {
|
|
|
12208
12195
|
};
|
|
12209
12196
|
return JSON.stringify(frame) + "\n";
|
|
12210
12197
|
}
|
|
12211
|
-
var import_node_child_process, import_node_child_process2, import_node_fs9,
|
|
12198
|
+
var import_node_child_process, import_node_child_process2, import_node_fs9, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
|
|
12212
12199
|
var init_claude = __esm({
|
|
12213
12200
|
"src/tools/claude.ts"() {
|
|
12214
12201
|
"use strict";
|
|
12215
12202
|
import_node_child_process = require("child_process");
|
|
12216
12203
|
import_node_child_process2 = require("child_process");
|
|
12217
12204
|
import_node_fs9 = __toESM(require("fs"), 1);
|
|
12218
|
-
import_node_os5 = __toESM(require("os"), 1);
|
|
12219
|
-
import_node_path9 = __toESM(require("path"), 1);
|
|
12220
12205
|
init_protocol();
|
|
12221
12206
|
init_claude_history();
|
|
12222
12207
|
init_tool_result_extra();
|
|
@@ -23893,8 +23878,8 @@ var require_utils = __commonJS({
|
|
|
23893
23878
|
var result = transform[inputType][outputType](input);
|
|
23894
23879
|
return result;
|
|
23895
23880
|
};
|
|
23896
|
-
exports2.resolve = function(
|
|
23897
|
-
var parts =
|
|
23881
|
+
exports2.resolve = function(path58) {
|
|
23882
|
+
var parts = path58.split("/");
|
|
23898
23883
|
var result = [];
|
|
23899
23884
|
for (var index = 0; index < parts.length; index++) {
|
|
23900
23885
|
var part = parts[index];
|
|
@@ -29747,18 +29732,18 @@ var require_object = __commonJS({
|
|
|
29747
29732
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
29748
29733
|
this.files[name] = object;
|
|
29749
29734
|
};
|
|
29750
|
-
var parentFolder = function(
|
|
29751
|
-
if (
|
|
29752
|
-
|
|
29735
|
+
var parentFolder = function(path58) {
|
|
29736
|
+
if (path58.slice(-1) === "/") {
|
|
29737
|
+
path58 = path58.substring(0, path58.length - 1);
|
|
29753
29738
|
}
|
|
29754
|
-
var lastSlash =
|
|
29755
|
-
return lastSlash > 0 ?
|
|
29739
|
+
var lastSlash = path58.lastIndexOf("/");
|
|
29740
|
+
return lastSlash > 0 ? path58.substring(0, lastSlash) : "";
|
|
29756
29741
|
};
|
|
29757
|
-
var forceTrailingSlash = function(
|
|
29758
|
-
if (
|
|
29759
|
-
|
|
29742
|
+
var forceTrailingSlash = function(path58) {
|
|
29743
|
+
if (path58.slice(-1) !== "/") {
|
|
29744
|
+
path58 += "/";
|
|
29760
29745
|
}
|
|
29761
|
-
return
|
|
29746
|
+
return path58;
|
|
29762
29747
|
};
|
|
29763
29748
|
var folderAdd = function(name, createFolders) {
|
|
29764
29749
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -30760,7 +30745,7 @@ var require_lib3 = __commonJS({
|
|
|
30760
30745
|
// src/run-case/recorder.ts
|
|
30761
30746
|
function startRunCaseRecorder(opts) {
|
|
30762
30747
|
const now = opts.now ?? Date.now;
|
|
30763
|
-
const dir =
|
|
30748
|
+
const dir = import_node_path46.default.dirname(opts.recordPath);
|
|
30764
30749
|
let stream = null;
|
|
30765
30750
|
let closing = false;
|
|
30766
30751
|
let closedSettled = false;
|
|
@@ -30800,12 +30785,12 @@ function startRunCaseRecorder(opts) {
|
|
|
30800
30785
|
};
|
|
30801
30786
|
return { tap, close, closed };
|
|
30802
30787
|
}
|
|
30803
|
-
var import_node_fs34,
|
|
30788
|
+
var import_node_fs34, import_node_path46;
|
|
30804
30789
|
var init_recorder = __esm({
|
|
30805
30790
|
"src/run-case/recorder.ts"() {
|
|
30806
30791
|
"use strict";
|
|
30807
30792
|
import_node_fs34 = __toESM(require("fs"), 1);
|
|
30808
|
-
|
|
30793
|
+
import_node_path46 = __toESM(require("path"), 1);
|
|
30809
30794
|
}
|
|
30810
30795
|
});
|
|
30811
30796
|
|
|
@@ -30848,7 +30833,7 @@ var init_wire = __esm({
|
|
|
30848
30833
|
// src/run-case/controller.ts
|
|
30849
30834
|
async function runController(opts) {
|
|
30850
30835
|
const now = opts.now ?? Date.now;
|
|
30851
|
-
const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(
|
|
30836
|
+
const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path47.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
|
|
30852
30837
|
const ownsCwd = opts.cwd === void 0;
|
|
30853
30838
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
30854
30839
|
const spawnCtx = { cwd };
|
|
@@ -31015,13 +31000,13 @@ async function runController(opts) {
|
|
|
31015
31000
|
}
|
|
31016
31001
|
return exitCode ?? 0;
|
|
31017
31002
|
}
|
|
31018
|
-
var import_node_fs35,
|
|
31003
|
+
var import_node_fs35, import_node_os19, import_node_path47;
|
|
31019
31004
|
var init_controller = __esm({
|
|
31020
31005
|
"src/run-case/controller.ts"() {
|
|
31021
31006
|
"use strict";
|
|
31022
31007
|
import_node_fs35 = require("fs");
|
|
31023
|
-
|
|
31024
|
-
|
|
31008
|
+
import_node_os19 = __toESM(require("os"), 1);
|
|
31009
|
+
import_node_path47 = __toESM(require("path"), 1);
|
|
31025
31010
|
init_claude();
|
|
31026
31011
|
init_stdout_splitter();
|
|
31027
31012
|
init_permission_stdio();
|
|
@@ -31256,7 +31241,7 @@ Env (advanced):
|
|
|
31256
31241
|
`;
|
|
31257
31242
|
|
|
31258
31243
|
// src/index.ts
|
|
31259
|
-
var
|
|
31244
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
31260
31245
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
31261
31246
|
|
|
31262
31247
|
// src/logger.ts
|
|
@@ -32601,7 +32586,7 @@ var SessionRunner = class {
|
|
|
32601
32586
|
this.input({ kind: "inject-events", events });
|
|
32602
32587
|
}
|
|
32603
32588
|
// session:interrupt 的 SDK 通道分流:codex → AgentSession.interrupt();claude → control_request('interrupt')。
|
|
32604
|
-
// TUI(pty) 路径在 manager.
|
|
32589
|
+
// TUI(pty) 路径在 manager.interrupt() 里先走 stop() SIGKILL,不进这里。
|
|
32605
32590
|
async interrupt() {
|
|
32606
32591
|
if (this.session) {
|
|
32607
32592
|
this.session.interrupt();
|
|
@@ -33079,11 +33064,6 @@ var SessionManager = class {
|
|
|
33079
33064
|
// manager.resizePty 用此映射把 UI 的 session:pty:resize 同步到 surface 内部 buffer,
|
|
33080
33065
|
// 保证 snapshot serialize 时 cursor positioning 与 UI xterm 实际尺寸一致。
|
|
33081
33066
|
surfacesByToolSid = /* @__PURE__ */ new Map();
|
|
33082
|
-
// TUI 模式:sessionId → UI 最近一次上报的 xterm 尺寸。resizePty 入口无条件记录(含 pty
|
|
33083
|
-
// 尚未 spawn / runner 尚未创建的早到 resize),registerPty / registerSurface 时回放——
|
|
33084
|
-
// 修「mount resize 早于 lazy spawn 被丢」与「respawn 回到 120×40 后无人补发」的尺寸错配。
|
|
33085
|
-
// 键用 sessionId 而非 toolSessionId:/clear 会 reassign tsid,sessionId 跨 respawn 稳定
|
|
33086
|
-
lastUiSizeBySessionId = /* @__PURE__ */ new Map();
|
|
33087
33067
|
// 仅 mode='tui' 需要:index.ts 装配阶段在 observer 构造后注入。
|
|
33088
33068
|
// observer.onEvent 要回灌 manager.feedObserverEvents,所以 observer 必须晚于 manager
|
|
33089
33069
|
// 构造;反过来 manager 又要在 mode='tui' 下 spawn session 时 attach observer。setter 解循环
|
|
@@ -33620,7 +33600,6 @@ var SessionManager = class {
|
|
|
33620
33600
|
});
|
|
33621
33601
|
this.runners.delete(args.sessionId);
|
|
33622
33602
|
this.realUuidBySynth.delete(args.sessionId);
|
|
33623
|
-
this.lastUiSizeBySessionId.delete(args.sessionId);
|
|
33624
33603
|
return { response: { sessionId: args.sessionId }, broadcast };
|
|
33625
33604
|
}
|
|
33626
33605
|
this.deleteOwned(args.sessionId);
|
|
@@ -33678,50 +33657,12 @@ var SessionManager = class {
|
|
|
33678
33657
|
return this.stop({ sessionId: args.sessionId });
|
|
33679
33658
|
}
|
|
33680
33659
|
try {
|
|
33681
|
-
await
|
|
33660
|
+
await runner.interrupt();
|
|
33682
33661
|
} catch (err) {
|
|
33683
33662
|
throw new ClawdError(ERROR_CODES.INTERNAL, err.message);
|
|
33684
33663
|
}
|
|
33685
33664
|
return { response: { ok: true }, broadcast: [] };
|
|
33686
33665
|
}
|
|
33687
|
-
// 同时被 interrupt / cancelQuestion 调用:按模式选 interrupt 通道。TUI 优先 pty,
|
|
33688
|
-
// 否则 fallback 到 SDK 的 control_request(包括 mode='tui' 但 pty 未 register 的边角场景)。
|
|
33689
|
-
async dispatchInterrupt(runner) {
|
|
33690
|
-
const sid = runner.getState().file.sessionId;
|
|
33691
|
-
const tsid = runner.getState().file.toolSessionId;
|
|
33692
|
-
const pty = tsid ? this.ptyTransports.get(tsid) : void 0;
|
|
33693
|
-
const stateBefore = runner.getState();
|
|
33694
|
-
this.deps.logger?.info("[BUG-HUNT-INTERRUPT] dispatchInterrupt enter", {
|
|
33695
|
-
sessionId: sid,
|
|
33696
|
-
tsid,
|
|
33697
|
-
ptyHit: Boolean(pty),
|
|
33698
|
-
mode: this.deps.mode,
|
|
33699
|
-
turnOpenBefore: stateBefore.turnOpen,
|
|
33700
|
-
procAlive: stateBefore.procAlive,
|
|
33701
|
-
bufferLen: stateBefore.buffer.length
|
|
33702
|
-
});
|
|
33703
|
-
if (pty) {
|
|
33704
|
-
pty.write("\x1B");
|
|
33705
|
-
this.deps.logger?.info("[BUG-HUNT-INTERRUPT] pty.write ESC done", { sessionId: sid });
|
|
33706
|
-
runner.input({ kind: "inject-events", events: [{ kind: "turn_end" }] });
|
|
33707
|
-
const stateAfter = runner.getState();
|
|
33708
|
-
const lastEvent = stateAfter.buffer[stateAfter.buffer.length - 1];
|
|
33709
|
-
this.deps.logger?.info("[BUG-HUNT-INTERRUPT] after inject turn_end", {
|
|
33710
|
-
sessionId: sid,
|
|
33711
|
-
turnOpenAfter: stateAfter.turnOpen,
|
|
33712
|
-
bufferLen: stateAfter.buffer.length,
|
|
33713
|
-
lastEventKind: lastEvent?.event?.kind,
|
|
33714
|
-
lastEventSeq: lastEvent?.seq
|
|
33715
|
-
});
|
|
33716
|
-
return;
|
|
33717
|
-
}
|
|
33718
|
-
this.deps.logger?.warn("[BUG-HUNT-INTERRUPT] SDK fallback path (pty not registered)", {
|
|
33719
|
-
sessionId: sid,
|
|
33720
|
-
tsid,
|
|
33721
|
-
mode: this.deps.mode
|
|
33722
|
-
});
|
|
33723
|
-
await runner.interrupt();
|
|
33724
|
-
}
|
|
33725
33666
|
// 批量版本:UI 打开 session 时一次性拿到"磁盘和快照有差异"的 user message id 集合,
|
|
33726
33667
|
// 用来在消息流里精准控制 rewind 按钮的显示。session 没 toolSessionId 时返回空
|
|
33727
33668
|
rewindableMessageIds(args) {
|
|
@@ -34136,7 +34077,6 @@ var SessionManager = class {
|
|
|
34136
34077
|
});
|
|
34137
34078
|
this.runners.delete(args.sessionId);
|
|
34138
34079
|
this.realUuidBySynth.delete(args.sessionId);
|
|
34139
|
-
this.lastUiSizeBySessionId.delete(args.sessionId);
|
|
34140
34080
|
return { response: { sessionId: args.sessionId }, broadcast };
|
|
34141
34081
|
}
|
|
34142
34082
|
this.storeFor(args.scope).delete(args.sessionId);
|
|
@@ -34267,7 +34207,7 @@ var SessionManager = class {
|
|
|
34267
34207
|
runner.input({ kind: "cancel-question", toolUseId: args.toolUseId });
|
|
34268
34208
|
});
|
|
34269
34209
|
if (runner.getState().procAlive) {
|
|
34270
|
-
void
|
|
34210
|
+
void runner.interrupt().catch(() => {
|
|
34271
34211
|
});
|
|
34272
34212
|
}
|
|
34273
34213
|
return { response: { ok: true }, broadcast };
|
|
@@ -34302,14 +34242,6 @@ var SessionManager = class {
|
|
|
34302
34242
|
/** ClaudeTuiAdapter.spawn 后调用,让 manager 持有 pty handle 供 handler input/resize 路由 */
|
|
34303
34243
|
registerPty(toolSessionId, pty) {
|
|
34304
34244
|
this.ptyTransports.set(toolSessionId, pty);
|
|
34305
|
-
const sid = this.sessionIdByToolSid(toolSessionId);
|
|
34306
|
-
const size = sid ? this.lastUiSizeBySessionId.get(sid) : void 0;
|
|
34307
|
-
if (size) {
|
|
34308
|
-
try {
|
|
34309
|
-
pty.resize(size.cols, size.rows);
|
|
34310
|
-
} catch {
|
|
34311
|
-
}
|
|
34312
|
-
}
|
|
34313
34245
|
}
|
|
34314
34246
|
/** spawn 进程 exit 时调用,清理映射防止后续 input 写到已死 pty + 释放 replay 闭包 */
|
|
34315
34247
|
unregisterPty(toolSessionId) {
|
|
@@ -34399,9 +34331,6 @@ var SessionManager = class {
|
|
|
34399
34331
|
/** ClaudeTuiAdapter spawn 时注册 surface ref;同一 tsid 重 spawn 会覆盖 */
|
|
34400
34332
|
registerSurface(toolSessionId, surface) {
|
|
34401
34333
|
this.surfacesByToolSid.set(toolSessionId, surface);
|
|
34402
|
-
const sid = this.sessionIdByToolSid(toolSessionId);
|
|
34403
|
-
const size = sid ? this.lastUiSizeBySessionId.get(sid) : void 0;
|
|
34404
|
-
if (size) surface.resize(size.cols, size.rows);
|
|
34405
34334
|
}
|
|
34406
34335
|
/** spawn 进程 exit 时清理 */
|
|
34407
34336
|
unregisterSurface(toolSessionId) {
|
|
@@ -34414,7 +34343,6 @@ var SessionManager = class {
|
|
|
34414
34343
|
* 找不到 runner / toolSessionId / pty 任一缺失 → 返 false,handler 静默给 UI 报 ok=false 不抛错。
|
|
34415
34344
|
*/
|
|
34416
34345
|
resizePty(sessionId, cols, rows) {
|
|
34417
|
-
this.lastUiSizeBySessionId.set(sessionId, { cols, rows });
|
|
34418
34346
|
const runner = this.runners.get(sessionId);
|
|
34419
34347
|
if (!runner) return false;
|
|
34420
34348
|
const tsid = runner.getState().file.toolSessionId;
|
|
@@ -35588,8 +35516,8 @@ function turnStartInput(text) {
|
|
|
35588
35516
|
const items = [];
|
|
35589
35517
|
let leftover = text;
|
|
35590
35518
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
35591
|
-
const [marker, name,
|
|
35592
|
-
items.push({ type: "skill", name, path:
|
|
35519
|
+
const [marker, name, path58] = m2;
|
|
35520
|
+
items.push({ type: "skill", name, path: path58 });
|
|
35593
35521
|
leftover = leftover.replace(marker, "");
|
|
35594
35522
|
}
|
|
35595
35523
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -35648,6 +35576,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
35648
35576
|
]);
|
|
35649
35577
|
return;
|
|
35650
35578
|
}
|
|
35579
|
+
deps.logger?.warn("codex unknown server-request auto-cancelled", { method });
|
|
35651
35580
|
client.respond(id, "cancel");
|
|
35652
35581
|
},
|
|
35653
35582
|
onClose: () => finish(proc.exitCode)
|
|
@@ -35821,8 +35750,8 @@ var CodexAdapter = class {
|
|
|
35821
35750
|
|
|
35822
35751
|
// src/tools/claude-tui.ts
|
|
35823
35752
|
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
35824
|
-
var
|
|
35825
|
-
var
|
|
35753
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
35754
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
35826
35755
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
35827
35756
|
|
|
35828
35757
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -36801,8 +36730,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
36801
36730
|
}
|
|
36802
36731
|
function jsonlExistsForCtx(ctx) {
|
|
36803
36732
|
if (!ctx.toolSessionId) return false;
|
|
36804
|
-
const home =
|
|
36805
|
-
const file =
|
|
36733
|
+
const home = import_node_os5.default.homedir();
|
|
36734
|
+
const file = import_node_path9.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
36806
36735
|
try {
|
|
36807
36736
|
return import_node_fs11.default.statSync(file).isFile();
|
|
36808
36737
|
} catch {
|
|
@@ -36999,13 +36928,13 @@ function mapSkillsListResponse(res) {
|
|
|
36999
36928
|
const r = s ?? {};
|
|
37000
36929
|
const name = str3(r.name);
|
|
37001
36930
|
if (!name) continue;
|
|
37002
|
-
const
|
|
36931
|
+
const path58 = str3(r.path);
|
|
37003
36932
|
const description = str3(r.description);
|
|
37004
36933
|
const isPlugin = name.includes(":");
|
|
37005
36934
|
out.push({
|
|
37006
36935
|
name,
|
|
37007
36936
|
source: isPlugin ? "plugin" : "project",
|
|
37008
|
-
...
|
|
36937
|
+
...path58 ? { path: path58 } : {},
|
|
37009
36938
|
...description ? { description } : {},
|
|
37010
36939
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
37011
36940
|
});
|
|
@@ -37045,15 +36974,15 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
37045
36974
|
|
|
37046
36975
|
// src/workspace/browser.ts
|
|
37047
36976
|
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
37048
|
-
var
|
|
37049
|
-
var
|
|
36977
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
36978
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
37050
36979
|
init_protocol();
|
|
37051
36980
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
37052
36981
|
function resolveInsideCwd(cwd, subpath) {
|
|
37053
|
-
const absCwd =
|
|
37054
|
-
const joined =
|
|
37055
|
-
const rel =
|
|
37056
|
-
if (rel.startsWith("..") ||
|
|
36982
|
+
const absCwd = import_node_path10.default.resolve(cwd);
|
|
36983
|
+
const joined = import_node_path10.default.resolve(absCwd, subpath ?? ".");
|
|
36984
|
+
const rel = import_node_path10.default.relative(absCwd, joined);
|
|
36985
|
+
if (rel.startsWith("..") || import_node_path10.default.isAbsolute(rel)) {
|
|
37057
36986
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
37058
36987
|
}
|
|
37059
36988
|
return joined;
|
|
@@ -37071,7 +37000,7 @@ function ensureCwd(cwd) {
|
|
|
37071
37000
|
}
|
|
37072
37001
|
var WorkspaceBrowser = class {
|
|
37073
37002
|
list(args) {
|
|
37074
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
37003
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
|
|
37075
37004
|
ensureCwd(cwd);
|
|
37076
37005
|
const full = resolveInsideCwd(cwd, args.path);
|
|
37077
37006
|
const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
|
|
@@ -37084,7 +37013,7 @@ var WorkspaceBrowser = class {
|
|
|
37084
37013
|
mtime: ""
|
|
37085
37014
|
};
|
|
37086
37015
|
try {
|
|
37087
|
-
const st = import_node_fs12.default.statSync(
|
|
37016
|
+
const st = import_node_fs12.default.statSync(import_node_path10.default.join(full, d.name));
|
|
37088
37017
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
37089
37018
|
if (d.isFile()) entry.size = st.size;
|
|
37090
37019
|
} catch {
|
|
@@ -37130,8 +37059,8 @@ var WorkspaceBrowser = class {
|
|
|
37130
37059
|
|
|
37131
37060
|
// src/skills/agents-scanner.ts
|
|
37132
37061
|
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
37133
|
-
var
|
|
37134
|
-
var
|
|
37062
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
37063
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
37135
37064
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
37136
37065
|
function isDirLikeSync2(p2) {
|
|
37137
37066
|
try {
|
|
@@ -37169,10 +37098,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
37169
37098
|
}
|
|
37170
37099
|
for (const ent of entries) {
|
|
37171
37100
|
if (!ent.name.endsWith(".md")) continue;
|
|
37172
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
37101
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path11.default.join(dir, ent.name)))) {
|
|
37173
37102
|
continue;
|
|
37174
37103
|
}
|
|
37175
|
-
const filePath =
|
|
37104
|
+
const filePath = import_node_path11.default.join(dir, ent.name);
|
|
37176
37105
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
37177
37106
|
if (seen.has(baseName)) continue;
|
|
37178
37107
|
seen.add(baseName);
|
|
@@ -37195,7 +37124,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
37195
37124
|
return;
|
|
37196
37125
|
}
|
|
37197
37126
|
for (const ent of entries) {
|
|
37198
|
-
const childPath =
|
|
37127
|
+
const childPath = import_node_path11.default.join(dir, ent.name);
|
|
37199
37128
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
37200
37129
|
walk2(childPath, [...namespaces, ent.name]);
|
|
37201
37130
|
continue;
|
|
@@ -37220,9 +37149,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
37220
37149
|
walk2(root, []);
|
|
37221
37150
|
}
|
|
37222
37151
|
function readInstalledPlugins2(home) {
|
|
37223
|
-
const pluginsDir =
|
|
37224
|
-
const v2 =
|
|
37225
|
-
const v1 =
|
|
37152
|
+
const pluginsDir = import_node_path11.default.join(home, ".claude", "plugins");
|
|
37153
|
+
const v2 = import_node_path11.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
37154
|
+
const v1 = import_node_path11.default.join(pluginsDir, "installed_plugins.json");
|
|
37226
37155
|
let raw = null;
|
|
37227
37156
|
for (const candidate of [v2, v1]) {
|
|
37228
37157
|
try {
|
|
@@ -37251,19 +37180,19 @@ function readInstalledPlugins2(home) {
|
|
|
37251
37180
|
return out;
|
|
37252
37181
|
}
|
|
37253
37182
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
37254
|
-
let cur =
|
|
37255
|
-
const fsRoot =
|
|
37183
|
+
let cur = import_node_path11.default.resolve(startCwd);
|
|
37184
|
+
const fsRoot = import_node_path11.default.parse(cur).root;
|
|
37256
37185
|
while (true) {
|
|
37257
|
-
scanAgentsDir(
|
|
37186
|
+
scanAgentsDir(import_node_path11.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
37258
37187
|
let hasGit = false;
|
|
37259
37188
|
try {
|
|
37260
|
-
hasGit = import_node_fs13.default.existsSync(
|
|
37189
|
+
hasGit = import_node_fs13.default.existsSync(import_node_path11.default.join(cur, ".git"));
|
|
37261
37190
|
} catch {
|
|
37262
37191
|
}
|
|
37263
37192
|
if (hasGit) return;
|
|
37264
37193
|
if (cur === home) return;
|
|
37265
37194
|
if (cur === fsRoot) return;
|
|
37266
|
-
const parent =
|
|
37195
|
+
const parent = import_node_path11.default.dirname(cur);
|
|
37267
37196
|
if (parent === cur) return;
|
|
37268
37197
|
cur = parent;
|
|
37269
37198
|
}
|
|
@@ -37273,7 +37202,7 @@ var AgentsScanner = class {
|
|
|
37273
37202
|
extraPluginRoots;
|
|
37274
37203
|
policyDir;
|
|
37275
37204
|
constructor(opts = {}) {
|
|
37276
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
37205
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os7.default.homedir();
|
|
37277
37206
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
37278
37207
|
if (opts.policyDir !== void 0) {
|
|
37279
37208
|
this.policyDir = opts.policyDir;
|
|
@@ -37298,7 +37227,7 @@ var AgentsScanner = class {
|
|
|
37298
37227
|
}
|
|
37299
37228
|
const fsBlock = [];
|
|
37300
37229
|
scanAgentsDir(
|
|
37301
|
-
|
|
37230
|
+
import_node_path11.default.join(this.home, ".claude", "agents"),
|
|
37302
37231
|
"global",
|
|
37303
37232
|
seen,
|
|
37304
37233
|
fsBlock
|
|
@@ -37312,7 +37241,7 @@ var AgentsScanner = class {
|
|
|
37312
37241
|
...this.extraPluginRoots
|
|
37313
37242
|
];
|
|
37314
37243
|
for (const { name, root } of plugins) {
|
|
37315
|
-
const agentsRoot =
|
|
37244
|
+
const agentsRoot = import_node_path11.default.join(root, "agents");
|
|
37316
37245
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
37317
37246
|
}
|
|
37318
37247
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -37321,27 +37250,27 @@ var AgentsScanner = class {
|
|
|
37321
37250
|
|
|
37322
37251
|
// src/observer/session-observer.ts
|
|
37323
37252
|
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
37324
|
-
var
|
|
37325
|
-
var
|
|
37253
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
37254
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
37326
37255
|
init_claude_history();
|
|
37327
37256
|
|
|
37328
37257
|
// src/observer/subagent-meta-observer.ts
|
|
37329
37258
|
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
37330
|
-
var
|
|
37331
|
-
var
|
|
37259
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
37260
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
37332
37261
|
init_claude_history();
|
|
37333
37262
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
37334
37263
|
var SubagentMetaObserver = class {
|
|
37335
37264
|
constructor(opts) {
|
|
37336
37265
|
this.opts = opts;
|
|
37337
|
-
this.home = opts.home ??
|
|
37266
|
+
this.home = opts.home ?? import_node_os8.default.homedir();
|
|
37338
37267
|
}
|
|
37339
37268
|
opts;
|
|
37340
37269
|
home;
|
|
37341
37270
|
watches = /* @__PURE__ */ new Map();
|
|
37342
37271
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
37343
37272
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
37344
|
-
return
|
|
37273
|
+
return import_node_path12.default.join(
|
|
37345
37274
|
this.home,
|
|
37346
37275
|
".claude",
|
|
37347
37276
|
"projects",
|
|
@@ -37397,7 +37326,7 @@ var SubagentMetaObserver = class {
|
|
|
37397
37326
|
if (!m2) return;
|
|
37398
37327
|
const agentId = m2[1];
|
|
37399
37328
|
if (w2.emitted.has(agentId)) return;
|
|
37400
|
-
const file =
|
|
37329
|
+
const file = import_node_path12.default.join(w2.dirPath, name);
|
|
37401
37330
|
let raw;
|
|
37402
37331
|
try {
|
|
37403
37332
|
raw = import_node_fs14.default.readFileSync(file, "utf8");
|
|
@@ -37445,7 +37374,7 @@ var SubagentMetaObserver = class {
|
|
|
37445
37374
|
var SessionObserver = class {
|
|
37446
37375
|
constructor(opts) {
|
|
37447
37376
|
this.opts = opts;
|
|
37448
|
-
this.home = opts.home ??
|
|
37377
|
+
this.home = opts.home ?? import_node_os9.default.homedir();
|
|
37449
37378
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
37450
37379
|
}
|
|
37451
37380
|
opts;
|
|
@@ -37457,7 +37386,7 @@ var SessionObserver = class {
|
|
|
37457
37386
|
metaObserver;
|
|
37458
37387
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
37459
37388
|
if (override) return override;
|
|
37460
|
-
return
|
|
37389
|
+
return import_node_path13.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
37461
37390
|
}
|
|
37462
37391
|
start(args) {
|
|
37463
37392
|
this.stop(args.sessionId);
|
|
@@ -37478,10 +37407,10 @@ var SessionObserver = class {
|
|
|
37478
37407
|
prevIsRejectSentinel: false
|
|
37479
37408
|
};
|
|
37480
37409
|
try {
|
|
37481
|
-
import_node_fs15.default.mkdirSync(
|
|
37410
|
+
import_node_fs15.default.mkdirSync(import_node_path13.default.dirname(filePath), { recursive: true });
|
|
37482
37411
|
} catch {
|
|
37483
37412
|
}
|
|
37484
|
-
w2.watcher = import_node_fs15.default.watch(
|
|
37413
|
+
w2.watcher = import_node_fs15.default.watch(import_node_path13.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
37485
37414
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
37486
37415
|
this.poll(w2);
|
|
37487
37416
|
});
|
|
@@ -38288,7 +38217,7 @@ async function authenticate(token, deps) {
|
|
|
38288
38217
|
|
|
38289
38218
|
// src/permission/capability-store.ts
|
|
38290
38219
|
var fs18 = __toESM(require("fs"), 1);
|
|
38291
|
-
var
|
|
38220
|
+
var path18 = __toESM(require("path"), 1);
|
|
38292
38221
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
38293
38222
|
var FILE_VERSION = 1;
|
|
38294
38223
|
var CapabilityStore = class {
|
|
@@ -38318,7 +38247,7 @@ var CapabilityStore = class {
|
|
|
38318
38247
|
this.flush();
|
|
38319
38248
|
}
|
|
38320
38249
|
filePath() {
|
|
38321
|
-
return
|
|
38250
|
+
return path18.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
38322
38251
|
}
|
|
38323
38252
|
readFromDisk() {
|
|
38324
38253
|
const file = this.filePath();
|
|
@@ -38465,7 +38394,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
38465
38394
|
|
|
38466
38395
|
// src/inbox/inbox-store.ts
|
|
38467
38396
|
var fs20 = __toESM(require("fs"), 1);
|
|
38468
|
-
var
|
|
38397
|
+
var path19 = __toESM(require("path"), 1);
|
|
38469
38398
|
var INBOX_SUBDIR = "inbox";
|
|
38470
38399
|
var InboxStore = class {
|
|
38471
38400
|
constructor(dataDir) {
|
|
@@ -38563,10 +38492,10 @@ var InboxStore = class {
|
|
|
38563
38492
|
}
|
|
38564
38493
|
}
|
|
38565
38494
|
dirPath() {
|
|
38566
|
-
return
|
|
38495
|
+
return path19.join(this.dataDir, INBOX_SUBDIR);
|
|
38567
38496
|
}
|
|
38568
38497
|
filePath(peerDeviceId) {
|
|
38569
|
-
return
|
|
38498
|
+
return path19.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
38570
38499
|
}
|
|
38571
38500
|
};
|
|
38572
38501
|
function parseAllLines(raw) {
|
|
@@ -38654,7 +38583,7 @@ var InboxManager = class {
|
|
|
38654
38583
|
|
|
38655
38584
|
// src/state/contact-store.ts
|
|
38656
38585
|
var fs21 = __toESM(require("fs"), 1);
|
|
38657
|
-
var
|
|
38586
|
+
var path20 = __toESM(require("path"), 1);
|
|
38658
38587
|
var FILE_NAME = "contacts.json";
|
|
38659
38588
|
var ContactStore = class {
|
|
38660
38589
|
constructor(dataDir) {
|
|
@@ -38664,7 +38593,7 @@ var ContactStore = class {
|
|
|
38664
38593
|
contacts = /* @__PURE__ */ new Map();
|
|
38665
38594
|
load() {
|
|
38666
38595
|
this.contacts.clear();
|
|
38667
|
-
const file =
|
|
38596
|
+
const file = path20.join(this.dataDir, FILE_NAME);
|
|
38668
38597
|
let raw;
|
|
38669
38598
|
try {
|
|
38670
38599
|
raw = fs21.readFileSync(file, "utf8");
|
|
@@ -38710,7 +38639,7 @@ var ContactStore = class {
|
|
|
38710
38639
|
return existed;
|
|
38711
38640
|
}
|
|
38712
38641
|
flush() {
|
|
38713
|
-
const file =
|
|
38642
|
+
const file = path20.join(this.dataDir, FILE_NAME);
|
|
38714
38643
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
38715
38644
|
const content = JSON.stringify(
|
|
38716
38645
|
{ contacts: Array.from(this.contacts.values()) },
|
|
@@ -38874,52 +38803,52 @@ async function autoReverseContact(args) {
|
|
|
38874
38803
|
|
|
38875
38804
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
38876
38805
|
var fs22 = __toESM(require("fs"), 1);
|
|
38877
|
-
var
|
|
38806
|
+
var path21 = __toESM(require("path"), 1);
|
|
38878
38807
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
38879
38808
|
function migrateFlattenSessions(opts) {
|
|
38880
38809
|
const dataDir = opts.dataDir;
|
|
38881
38810
|
const now = opts.now ?? Date.now;
|
|
38882
|
-
const sessionsDir =
|
|
38883
|
-
const flagPath =
|
|
38811
|
+
const sessionsDir = path21.join(dataDir, "sessions");
|
|
38812
|
+
const flagPath = path21.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
38884
38813
|
if (existsSync3(flagPath)) {
|
|
38885
38814
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
38886
38815
|
}
|
|
38887
38816
|
let movedBare = 0;
|
|
38888
38817
|
let movedVmOwner = 0;
|
|
38889
38818
|
let archivedListener = 0;
|
|
38890
|
-
const defaultDir =
|
|
38819
|
+
const defaultDir = path21.join(sessionsDir, "default");
|
|
38891
38820
|
if (existsSync3(defaultDir)) {
|
|
38892
38821
|
for (const entry of readdirSafe(defaultDir)) {
|
|
38893
38822
|
if (!entry.endsWith(".json")) continue;
|
|
38894
|
-
const src =
|
|
38895
|
-
const dst =
|
|
38823
|
+
const src = path21.join(defaultDir, entry);
|
|
38824
|
+
const dst = path21.join(sessionsDir, entry);
|
|
38896
38825
|
fs22.renameSync(src, dst);
|
|
38897
38826
|
movedBare += 1;
|
|
38898
38827
|
}
|
|
38899
38828
|
rmdirIfEmpty(defaultDir);
|
|
38900
38829
|
}
|
|
38901
38830
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
38902
|
-
const personaDir =
|
|
38831
|
+
const personaDir = path21.join(sessionsDir, pid);
|
|
38903
38832
|
if (!isDir(personaDir)) continue;
|
|
38904
38833
|
if (pid === "default") continue;
|
|
38905
|
-
const ownerSrc =
|
|
38834
|
+
const ownerSrc = path21.join(personaDir, "owner");
|
|
38906
38835
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
38907
|
-
const ownerDst =
|
|
38836
|
+
const ownerDst = path21.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
38908
38837
|
fs22.mkdirSync(ownerDst, { recursive: true });
|
|
38909
38838
|
for (const file of readdirSafe(ownerSrc)) {
|
|
38910
38839
|
if (!file.endsWith(".json")) continue;
|
|
38911
|
-
fs22.renameSync(
|
|
38840
|
+
fs22.renameSync(path21.join(ownerSrc, file), path21.join(ownerDst, file));
|
|
38912
38841
|
movedVmOwner += 1;
|
|
38913
38842
|
}
|
|
38914
38843
|
rmdirIfEmpty(ownerSrc);
|
|
38915
38844
|
}
|
|
38916
|
-
const listenerSrc =
|
|
38845
|
+
const listenerSrc = path21.join(personaDir, "listener");
|
|
38917
38846
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
38918
|
-
const archiveDst =
|
|
38847
|
+
const archiveDst = path21.join(dataDir, ".legacy", `listener-${pid}`);
|
|
38919
38848
|
fs22.mkdirSync(archiveDst, { recursive: true });
|
|
38920
38849
|
for (const file of readdirSafe(listenerSrc)) {
|
|
38921
38850
|
if (!file.endsWith(".json")) continue;
|
|
38922
|
-
fs22.renameSync(
|
|
38851
|
+
fs22.renameSync(path21.join(listenerSrc, file), path21.join(archiveDst, file));
|
|
38923
38852
|
archivedListener += 1;
|
|
38924
38853
|
}
|
|
38925
38854
|
rmdirIfEmpty(listenerSrc);
|
|
@@ -38967,10 +38896,10 @@ function rmdirIfEmpty(p2) {
|
|
|
38967
38896
|
|
|
38968
38897
|
// src/transport/http-router.ts
|
|
38969
38898
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
38970
|
-
var
|
|
38899
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
38971
38900
|
|
|
38972
38901
|
// src/attachment/mime.ts
|
|
38973
|
-
var
|
|
38902
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
38974
38903
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
38975
38904
|
var EXT_TO_NATIVE_MIME = {
|
|
38976
38905
|
// 图片
|
|
@@ -39077,7 +39006,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
39077
39006
|
".mk"
|
|
39078
39007
|
]);
|
|
39079
39008
|
function lookupMime(filePathOrName) {
|
|
39080
|
-
const ext =
|
|
39009
|
+
const ext = import_node_path14.default.extname(filePathOrName).toLowerCase();
|
|
39081
39010
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
39082
39011
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
39083
39012
|
return "application/octet-stream";
|
|
@@ -39147,7 +39076,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
39147
39076
|
|
|
39148
39077
|
// src/attachment/upload.ts
|
|
39149
39078
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
39150
|
-
var
|
|
39079
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
39151
39080
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
39152
39081
|
var import_promises = require("stream/promises");
|
|
39153
39082
|
var UploadError = class extends Error {
|
|
@@ -39159,14 +39088,14 @@ var UploadError = class extends Error {
|
|
|
39159
39088
|
code;
|
|
39160
39089
|
};
|
|
39161
39090
|
function assertValidFileName(fileName) {
|
|
39162
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
39091
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path15.default.basename(fileName)) {
|
|
39163
39092
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
39164
39093
|
}
|
|
39165
39094
|
}
|
|
39166
39095
|
var HASH_PREFIX_LEN = 16;
|
|
39167
39096
|
async function writeUploadedAttachment(args) {
|
|
39168
39097
|
assertValidFileName(args.fileName);
|
|
39169
|
-
const attachmentsRoot =
|
|
39098
|
+
const attachmentsRoot = import_node_path15.default.join(args.sessionDir, ".attachments");
|
|
39170
39099
|
try {
|
|
39171
39100
|
import_node_fs16.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
39172
39101
|
} catch (err) {
|
|
@@ -39174,7 +39103,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39174
39103
|
}
|
|
39175
39104
|
const hasher = import_node_crypto5.default.createHash("sha256");
|
|
39176
39105
|
let actualSize = 0;
|
|
39177
|
-
const tmpPath =
|
|
39106
|
+
const tmpPath = import_node_path15.default.join(
|
|
39178
39107
|
attachmentsRoot,
|
|
39179
39108
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto5.default.randomBytes(4).toString("hex")}`
|
|
39180
39109
|
);
|
|
@@ -39209,7 +39138,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39209
39138
|
);
|
|
39210
39139
|
}
|
|
39211
39140
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
39212
|
-
const hashDir =
|
|
39141
|
+
const hashDir = import_node_path15.default.join(attachmentsRoot, attachmentId);
|
|
39213
39142
|
let finalFileName;
|
|
39214
39143
|
let hashDirExists = false;
|
|
39215
39144
|
try {
|
|
@@ -39227,7 +39156,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39227
39156
|
try {
|
|
39228
39157
|
import_node_fs16.default.mkdirSync(hashDir, { recursive: true });
|
|
39229
39158
|
finalFileName = args.fileName;
|
|
39230
|
-
import_node_fs16.default.renameSync(tmpPath,
|
|
39159
|
+
import_node_fs16.default.renameSync(tmpPath, import_node_path15.default.join(hashDir, finalFileName));
|
|
39231
39160
|
} catch (err) {
|
|
39232
39161
|
try {
|
|
39233
39162
|
import_node_fs16.default.unlinkSync(tmpPath);
|
|
@@ -39236,8 +39165,8 @@ async function writeUploadedAttachment(args) {
|
|
|
39236
39165
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
39237
39166
|
}
|
|
39238
39167
|
}
|
|
39239
|
-
const absPath =
|
|
39240
|
-
const relPath =
|
|
39168
|
+
const absPath = import_node_path15.default.join(hashDir, finalFileName);
|
|
39169
|
+
const relPath = import_node_path15.default.relative(args.sessionDir, absPath);
|
|
39241
39170
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
39242
39171
|
relPath: absPath,
|
|
39243
39172
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -39251,8 +39180,8 @@ async function writeUploadedAttachment(args) {
|
|
|
39251
39180
|
|
|
39252
39181
|
// src/extension/import.ts
|
|
39253
39182
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
39254
|
-
var
|
|
39255
|
-
var
|
|
39183
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
39184
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
39256
39185
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
39257
39186
|
var ImportError = class extends Error {
|
|
39258
39187
|
constructor(code, message) {
|
|
@@ -39269,7 +39198,7 @@ async function importZip(buf, root) {
|
|
|
39269
39198
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
39270
39199
|
}
|
|
39271
39200
|
for (const name of Object.keys(zip.files)) {
|
|
39272
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
39201
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path16.default.isAbsolute(name)) {
|
|
39273
39202
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
39274
39203
|
}
|
|
39275
39204
|
}
|
|
@@ -39302,7 +39231,7 @@ async function importZip(buf, root) {
|
|
|
39302
39231
|
);
|
|
39303
39232
|
}
|
|
39304
39233
|
}
|
|
39305
|
-
const destDir =
|
|
39234
|
+
const destDir = import_node_path16.default.join(root, manifest.id);
|
|
39306
39235
|
let destExists = false;
|
|
39307
39236
|
try {
|
|
39308
39237
|
await import_promises2.default.access(destDir);
|
|
@@ -39312,15 +39241,15 @@ async function importZip(buf, root) {
|
|
|
39312
39241
|
if (destExists) {
|
|
39313
39242
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
39314
39243
|
}
|
|
39315
|
-
const stage = await import_promises2.default.mkdtemp(
|
|
39244
|
+
const stage = await import_promises2.default.mkdtemp(import_node_path16.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
39316
39245
|
try {
|
|
39317
39246
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
39318
|
-
const dest =
|
|
39247
|
+
const dest = import_node_path16.default.join(stage, name);
|
|
39319
39248
|
if (entry.dir) {
|
|
39320
39249
|
await import_promises2.default.mkdir(dest, { recursive: true });
|
|
39321
39250
|
continue;
|
|
39322
39251
|
}
|
|
39323
|
-
await import_promises2.default.mkdir(
|
|
39252
|
+
await import_promises2.default.mkdir(import_node_path16.default.dirname(dest), { recursive: true });
|
|
39324
39253
|
const content = await entry.async("nodebuffer");
|
|
39325
39254
|
await import_promises2.default.writeFile(dest, content);
|
|
39326
39255
|
}
|
|
@@ -39434,7 +39363,7 @@ function isValidUploadFileName(fileName) {
|
|
|
39434
39363
|
if (fileName === "." || fileName === "..") return false;
|
|
39435
39364
|
if (fileName.startsWith(".")) return false;
|
|
39436
39365
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
39437
|
-
return fileName ===
|
|
39366
|
+
return fileName === import_node_path17.default.basename(fileName);
|
|
39438
39367
|
}
|
|
39439
39368
|
function createHttpRouter(deps) {
|
|
39440
39369
|
return async (req, res) => {
|
|
@@ -39663,7 +39592,7 @@ function createHttpRouter(deps) {
|
|
|
39663
39592
|
return true;
|
|
39664
39593
|
}
|
|
39665
39594
|
let absPath;
|
|
39666
|
-
if (
|
|
39595
|
+
if (import_node_path17.default.isAbsolute(pathParam)) {
|
|
39667
39596
|
absPath = pathParam;
|
|
39668
39597
|
} else if (deps.sessionStore) {
|
|
39669
39598
|
const file = deps.sessionStore.read(sid);
|
|
@@ -39671,7 +39600,7 @@ function createHttpRouter(deps) {
|
|
|
39671
39600
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
39672
39601
|
return true;
|
|
39673
39602
|
}
|
|
39674
|
-
absPath =
|
|
39603
|
+
absPath = import_node_path17.default.join(file.cwd, pathParam);
|
|
39675
39604
|
} else {
|
|
39676
39605
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
39677
39606
|
return true;
|
|
@@ -39769,7 +39698,7 @@ function streamFile(res, absPath, logger) {
|
|
|
39769
39698
|
return;
|
|
39770
39699
|
}
|
|
39771
39700
|
const mime = lookupMime(absPath);
|
|
39772
|
-
const basename =
|
|
39701
|
+
const basename = import_node_path17.default.basename(absPath);
|
|
39773
39702
|
res.writeHead(200, {
|
|
39774
39703
|
"Content-Type": mime,
|
|
39775
39704
|
"Content-Length": String(stat.size),
|
|
@@ -39787,7 +39716,7 @@ function streamFile(res, absPath, logger) {
|
|
|
39787
39716
|
|
|
39788
39717
|
// src/attachment/gc.ts
|
|
39789
39718
|
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
39790
|
-
var
|
|
39719
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
39791
39720
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
39792
39721
|
function runAttachmentGc(args) {
|
|
39793
39722
|
const now = (args.now ?? Date.now)();
|
|
@@ -39796,17 +39725,17 @@ function runAttachmentGc(args) {
|
|
|
39796
39725
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
39797
39726
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
39798
39727
|
if (entry.stale) continue;
|
|
39799
|
-
if (
|
|
39728
|
+
if (import_node_path18.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
39800
39729
|
}
|
|
39801
39730
|
}
|
|
39802
39731
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
39803
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
39732
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path18.default.join(
|
|
39804
39733
|
args.dataDir,
|
|
39805
39734
|
"sessions",
|
|
39806
39735
|
...scopeSubPath(scope).map(safeFileName),
|
|
39807
39736
|
safeFileName(sessionId)
|
|
39808
39737
|
);
|
|
39809
|
-
const attRoot =
|
|
39738
|
+
const attRoot = import_node_path18.default.join(sessionDir, ".attachments");
|
|
39810
39739
|
let hashDirs;
|
|
39811
39740
|
try {
|
|
39812
39741
|
hashDirs = import_node_fs18.default.readdirSync(attRoot);
|
|
@@ -39816,7 +39745,7 @@ function runAttachmentGc(args) {
|
|
|
39816
39745
|
continue;
|
|
39817
39746
|
}
|
|
39818
39747
|
for (const hashDir of hashDirs) {
|
|
39819
|
-
const hashDirAbs =
|
|
39748
|
+
const hashDirAbs = import_node_path18.default.join(attRoot, hashDir);
|
|
39820
39749
|
let files;
|
|
39821
39750
|
try {
|
|
39822
39751
|
files = import_node_fs18.default.readdirSync(hashDirAbs);
|
|
@@ -39824,7 +39753,7 @@ function runAttachmentGc(args) {
|
|
|
39824
39753
|
continue;
|
|
39825
39754
|
}
|
|
39826
39755
|
for (const name of files) {
|
|
39827
|
-
const file =
|
|
39756
|
+
const file = import_node_path18.default.join(hashDirAbs, name);
|
|
39828
39757
|
let stat;
|
|
39829
39758
|
try {
|
|
39830
39759
|
stat = import_node_fs18.default.statSync(file);
|
|
@@ -39855,7 +39784,7 @@ function runAttachmentGc(args) {
|
|
|
39855
39784
|
|
|
39856
39785
|
// src/attachment/group.ts
|
|
39857
39786
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
39858
|
-
var
|
|
39787
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
39859
39788
|
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
39860
39789
|
init_protocol();
|
|
39861
39790
|
var GroupFileStore = class {
|
|
@@ -39867,11 +39796,11 @@ var GroupFileStore = class {
|
|
|
39867
39796
|
this.logger = opts.logger;
|
|
39868
39797
|
}
|
|
39869
39798
|
rootForScope(scope) {
|
|
39870
|
-
return
|
|
39799
|
+
return import_node_path19.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
39871
39800
|
}
|
|
39872
39801
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
39873
39802
|
filePath(scope, sessionId) {
|
|
39874
|
-
return
|
|
39803
|
+
return import_node_path19.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
39875
39804
|
}
|
|
39876
39805
|
cacheKey(scope, sessionId) {
|
|
39877
39806
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -39906,7 +39835,7 @@ var GroupFileStore = class {
|
|
|
39906
39835
|
}
|
|
39907
39836
|
writeFile(scope, sessionId, entries) {
|
|
39908
39837
|
const file = this.filePath(scope, sessionId);
|
|
39909
|
-
import_node_fs19.default.mkdirSync(
|
|
39838
|
+
import_node_fs19.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
|
|
39910
39839
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
39911
39840
|
import_node_fs19.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
39912
39841
|
import_node_fs19.default.renameSync(tmp, file);
|
|
@@ -39996,9 +39925,9 @@ var GroupFileStore = class {
|
|
|
39996
39925
|
|
|
39997
39926
|
// src/discovery/state-file.ts
|
|
39998
39927
|
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
39999
|
-
var
|
|
39928
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
40000
39929
|
function defaultStateFilePath(dataDir) {
|
|
40001
|
-
return
|
|
39930
|
+
return import_node_path20.default.join(dataDir, "state.json");
|
|
40002
39931
|
}
|
|
40003
39932
|
function isPidAlive(pid) {
|
|
40004
39933
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -40034,7 +39963,7 @@ var StateFileManager = class {
|
|
|
40034
39963
|
return { status: "stale", existing };
|
|
40035
39964
|
}
|
|
40036
39965
|
write(state) {
|
|
40037
|
-
import_node_fs20.default.mkdirSync(
|
|
39966
|
+
import_node_fs20.default.mkdirSync(import_node_path20.default.dirname(this.file), { recursive: true });
|
|
40038
39967
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
40039
39968
|
import_node_fs20.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
40040
39969
|
import_node_fs20.default.renameSync(tmp, this.file);
|
|
@@ -40063,13 +39992,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
40063
39992
|
|
|
40064
39993
|
// src/tunnel/tunnel-manager.ts
|
|
40065
39994
|
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
40066
|
-
var
|
|
39995
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
40067
39996
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
40068
39997
|
var import_node_child_process9 = require("child_process");
|
|
40069
39998
|
|
|
40070
39999
|
// src/tunnel/tunnel-store.ts
|
|
40071
40000
|
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
40072
|
-
var
|
|
40001
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
40073
40002
|
var TunnelStore = class {
|
|
40074
40003
|
constructor(filePath) {
|
|
40075
40004
|
this.filePath = filePath;
|
|
@@ -40088,7 +40017,7 @@ var TunnelStore = class {
|
|
|
40088
40017
|
}
|
|
40089
40018
|
}
|
|
40090
40019
|
async set(v2) {
|
|
40091
|
-
const dir =
|
|
40020
|
+
const dir = import_node_path21.default.dirname(this.filePath);
|
|
40092
40021
|
await import_node_fs21.default.promises.mkdir(dir, { recursive: true });
|
|
40093
40022
|
const data = JSON.stringify(v2, null, 2);
|
|
40094
40023
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -40199,8 +40128,8 @@ function escape(v2) {
|
|
|
40199
40128
|
|
|
40200
40129
|
// src/tunnel/frpc-binary.ts
|
|
40201
40130
|
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
40202
|
-
var
|
|
40203
|
-
var
|
|
40131
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
40132
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
40204
40133
|
var import_node_child_process7 = require("child_process");
|
|
40205
40134
|
var import_node_stream2 = require("stream");
|
|
40206
40135
|
var import_promises3 = require("stream/promises");
|
|
@@ -40239,13 +40168,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
40239
40168
|
}
|
|
40240
40169
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
40241
40170
|
const platform = opts.platform ?? detectPlatform();
|
|
40242
|
-
const binDir =
|
|
40171
|
+
const binDir = import_node_path22.default.join(opts.dataDir, "bin");
|
|
40243
40172
|
import_node_fs22.default.mkdirSync(binDir, { recursive: true });
|
|
40244
40173
|
cleanupStaleArtifacts(binDir);
|
|
40245
|
-
const stableBin =
|
|
40174
|
+
const stableBin = import_node_path22.default.join(binDir, "frpc");
|
|
40246
40175
|
if (import_node_fs22.default.existsSync(stableBin)) return stableBin;
|
|
40247
40176
|
const partialBin = `${stableBin}.partial`;
|
|
40248
|
-
const tarballPath =
|
|
40177
|
+
const tarballPath = import_node_path22.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
40249
40178
|
try {
|
|
40250
40179
|
const url = frpcDownloadUrl(version2, platform);
|
|
40251
40180
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -40271,7 +40200,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
40271
40200
|
}
|
|
40272
40201
|
for (const name of entries) {
|
|
40273
40202
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
40274
|
-
const full =
|
|
40203
|
+
const full = import_node_path22.default.join(binDir, name);
|
|
40275
40204
|
try {
|
|
40276
40205
|
import_node_fs22.default.rmSync(full, { recursive: true, force: true });
|
|
40277
40206
|
} catch {
|
|
@@ -40297,7 +40226,7 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
40297
40226
|
await (0, import_promises3.pipeline)(nodeStream, out);
|
|
40298
40227
|
}
|
|
40299
40228
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
40300
|
-
const work =
|
|
40229
|
+
const work = import_node_path22.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
40301
40230
|
import_node_fs22.default.mkdirSync(work, { recursive: true });
|
|
40302
40231
|
try {
|
|
40303
40232
|
await new Promise((resolve6, reject) => {
|
|
@@ -40306,7 +40235,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
40306
40235
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
40307
40236
|
});
|
|
40308
40237
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
40309
|
-
const src =
|
|
40238
|
+
const src = import_node_path22.default.join(work, dirName, "frpc");
|
|
40310
40239
|
if (!import_node_fs22.default.existsSync(src)) {
|
|
40311
40240
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
40312
40241
|
}
|
|
@@ -40318,10 +40247,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
40318
40247
|
|
|
40319
40248
|
// src/tunnel/frpc-process.ts
|
|
40320
40249
|
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
40321
|
-
var
|
|
40250
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
40322
40251
|
var import_node_child_process8 = require("child_process");
|
|
40323
40252
|
function frpcPidFilePath(dataDir) {
|
|
40324
|
-
return
|
|
40253
|
+
return import_node_path23.default.join(dataDir, "frpc.pid");
|
|
40325
40254
|
}
|
|
40326
40255
|
function writeFrpcPid(dataDir, pid) {
|
|
40327
40256
|
try {
|
|
@@ -40363,7 +40292,7 @@ function defaultSleep(ms) {
|
|
|
40363
40292
|
}
|
|
40364
40293
|
async function killStaleFrpc(deps) {
|
|
40365
40294
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
40366
|
-
const tomlPath =
|
|
40295
|
+
const tomlPath = import_node_path23.default.join(deps.dataDir, "frpc.toml");
|
|
40367
40296
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
40368
40297
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
40369
40298
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -40435,7 +40364,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
40435
40364
|
var TunnelManager = class {
|
|
40436
40365
|
constructor(deps) {
|
|
40437
40366
|
this.deps = deps;
|
|
40438
|
-
this.store = deps.store ?? new TunnelStore(
|
|
40367
|
+
this.store = deps.store ?? new TunnelStore(import_node_path24.default.join(deps.dataDir, "tunnel.json"));
|
|
40439
40368
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
40440
40369
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
40441
40370
|
}
|
|
@@ -40562,7 +40491,7 @@ var TunnelManager = class {
|
|
|
40562
40491
|
dataDir: this.deps.dataDir,
|
|
40563
40492
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
40564
40493
|
});
|
|
40565
|
-
const tomlPath =
|
|
40494
|
+
const tomlPath = import_node_path24.default.join(this.deps.dataDir, "frpc.toml");
|
|
40566
40495
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto7.default.randomBytes(3).toString("hex")}`;
|
|
40567
40496
|
const toml = buildFrpcToml({
|
|
40568
40497
|
serverAddr: t.frpsHost,
|
|
@@ -40577,7 +40506,7 @@ var TunnelManager = class {
|
|
|
40577
40506
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
40578
40507
|
stdio: ["ignore", "pipe", "pipe"]
|
|
40579
40508
|
});
|
|
40580
|
-
const logFilePath =
|
|
40509
|
+
const logFilePath = import_node_path24.default.join(this.deps.dataDir, "frpc.log");
|
|
40581
40510
|
const logStream = import_node_fs24.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
40582
40511
|
logStream.on("error", () => {
|
|
40583
40512
|
});
|
|
@@ -40660,16 +40589,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
40660
40589
|
}
|
|
40661
40590
|
|
|
40662
40591
|
// src/tunnel/device-key.ts
|
|
40663
|
-
var
|
|
40664
|
-
var
|
|
40592
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
40593
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
40665
40594
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
40666
40595
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
40667
40596
|
function deriveStableDeviceKey(opts = {}) {
|
|
40668
|
-
const hostname = opts.hostname ??
|
|
40669
|
-
const uid = opts.uid ?? (typeof
|
|
40670
|
-
const home = opts.home ??
|
|
40671
|
-
const defaultDataDir =
|
|
40672
|
-
const normalizedDataDir = opts.dataDir ?
|
|
40597
|
+
const hostname = opts.hostname ?? import_node_os12.default.hostname();
|
|
40598
|
+
const uid = opts.uid ?? (typeof import_node_os12.default.userInfo === "function" ? import_node_os12.default.userInfo().uid : 0);
|
|
40599
|
+
const home = opts.home ?? import_node_os12.default.homedir();
|
|
40600
|
+
const defaultDataDir = import_node_path25.default.resolve(import_node_path25.default.join(home, ".clawd"));
|
|
40601
|
+
const normalizedDataDir = opts.dataDir ? import_node_path25.default.resolve(opts.dataDir) : null;
|
|
40673
40602
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
40674
40603
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
40675
40604
|
return import_node_crypto8.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
@@ -40677,11 +40606,11 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
40677
40606
|
|
|
40678
40607
|
// src/auth-store.ts
|
|
40679
40608
|
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
40680
|
-
var
|
|
40609
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
40681
40610
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
40682
40611
|
var AUTH_FILE_NAME = "auth.json";
|
|
40683
40612
|
function authFilePath(dataDir) {
|
|
40684
|
-
return
|
|
40613
|
+
return import_node_path26.default.join(dataDir, AUTH_FILE_NAME);
|
|
40685
40614
|
}
|
|
40686
40615
|
function loadOrCreateAuthFile(opts) {
|
|
40687
40616
|
const file = authFilePath(opts.dataDir);
|
|
@@ -40734,7 +40663,7 @@ function readAuthFile(file) {
|
|
|
40734
40663
|
}
|
|
40735
40664
|
}
|
|
40736
40665
|
function writeAuthFile(file, content) {
|
|
40737
|
-
import_node_fs25.default.mkdirSync(
|
|
40666
|
+
import_node_fs25.default.mkdirSync(import_node_path26.default.dirname(file), { recursive: true });
|
|
40738
40667
|
import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
40739
40668
|
try {
|
|
40740
40669
|
import_node_fs25.default.chmodSync(file, 384);
|
|
@@ -40744,12 +40673,12 @@ function writeAuthFile(file, content) {
|
|
|
40744
40673
|
|
|
40745
40674
|
// src/owner-profile.ts
|
|
40746
40675
|
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
40747
|
-
var
|
|
40748
|
-
var
|
|
40676
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
40677
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
40749
40678
|
var PROFILE_FILENAME = "profile.json";
|
|
40750
40679
|
function loadOwnerDisplayName(dataDir) {
|
|
40751
|
-
const fallback =
|
|
40752
|
-
const profilePath =
|
|
40680
|
+
const fallback = import_node_os13.default.userInfo().username;
|
|
40681
|
+
const profilePath = import_node_path27.default.join(dataDir, PROFILE_FILENAME);
|
|
40753
40682
|
let raw;
|
|
40754
40683
|
try {
|
|
40755
40684
|
raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
|
|
@@ -40776,12 +40705,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
40776
40705
|
|
|
40777
40706
|
// src/feishu-auth/owner-identity-store.ts
|
|
40778
40707
|
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
40779
|
-
var
|
|
40708
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
40780
40709
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
40781
40710
|
var OwnerIdentityStore = class {
|
|
40782
40711
|
file;
|
|
40783
40712
|
constructor(dataDir) {
|
|
40784
|
-
this.file =
|
|
40713
|
+
this.file = import_node_path28.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
40785
40714
|
}
|
|
40786
40715
|
read() {
|
|
40787
40716
|
let raw;
|
|
@@ -40813,7 +40742,7 @@ var OwnerIdentityStore = class {
|
|
|
40813
40742
|
};
|
|
40814
40743
|
}
|
|
40815
40744
|
write(record) {
|
|
40816
|
-
import_node_fs27.default.mkdirSync(
|
|
40745
|
+
import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(this.file), { recursive: true });
|
|
40817
40746
|
import_node_fs27.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
40818
40747
|
try {
|
|
40819
40748
|
import_node_fs27.default.chmodSync(this.file, 384);
|
|
@@ -40941,9 +40870,9 @@ var CentralClientError = class extends Error {
|
|
|
40941
40870
|
code;
|
|
40942
40871
|
cause;
|
|
40943
40872
|
};
|
|
40944
|
-
async function centralRequest(opts,
|
|
40873
|
+
async function centralRequest(opts, path58, init) {
|
|
40945
40874
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
40946
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
40875
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path58}`;
|
|
40947
40876
|
const ctrl = new AbortController();
|
|
40948
40877
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
40949
40878
|
let res;
|
|
@@ -41086,7 +41015,7 @@ function verifyConnectToken(args) {
|
|
|
41086
41015
|
|
|
41087
41016
|
// src/feishu-auth/server-key.ts
|
|
41088
41017
|
var fs36 = __toESM(require("fs"), 1);
|
|
41089
|
-
var
|
|
41018
|
+
var path37 = __toESM(require("path"), 1);
|
|
41090
41019
|
var FILE_NAME2 = "server-signing-key.json";
|
|
41091
41020
|
var ServerKeyStore = class {
|
|
41092
41021
|
constructor(dataDir) {
|
|
@@ -41094,7 +41023,7 @@ var ServerKeyStore = class {
|
|
|
41094
41023
|
}
|
|
41095
41024
|
dataDir;
|
|
41096
41025
|
filePath() {
|
|
41097
|
-
return
|
|
41026
|
+
return path37.join(this.dataDir, FILE_NAME2);
|
|
41098
41027
|
}
|
|
41099
41028
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
41100
41029
|
read() {
|
|
@@ -41133,8 +41062,8 @@ init_protocol();
|
|
|
41133
41062
|
|
|
41134
41063
|
// src/session/fork.ts
|
|
41135
41064
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
41136
|
-
var
|
|
41137
|
-
var
|
|
41065
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
41066
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
41138
41067
|
init_claude_history();
|
|
41139
41068
|
function readJsonlEntries(file) {
|
|
41140
41069
|
const raw = import_node_fs28.default.readFileSync(file, "utf8");
|
|
@@ -41150,9 +41079,9 @@ function readJsonlEntries(file) {
|
|
|
41150
41079
|
return out;
|
|
41151
41080
|
}
|
|
41152
41081
|
function forkSession(input) {
|
|
41153
|
-
const baseDir = input.baseDir ??
|
|
41154
|
-
const projectDir =
|
|
41155
|
-
const sourceFile =
|
|
41082
|
+
const baseDir = input.baseDir ?? import_node_path29.default.join(import_node_os14.default.homedir(), ".claude");
|
|
41083
|
+
const projectDir = import_node_path29.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
41084
|
+
const sourceFile = import_node_path29.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
41156
41085
|
if (!import_node_fs28.default.existsSync(sourceFile)) {
|
|
41157
41086
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
41158
41087
|
}
|
|
@@ -41183,7 +41112,7 @@ function forkSession(input) {
|
|
|
41183
41112
|
}
|
|
41184
41113
|
forkedLines.push(JSON.stringify(forked));
|
|
41185
41114
|
}
|
|
41186
|
-
const forkedFilePath =
|
|
41115
|
+
const forkedFilePath = import_node_path29.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
41187
41116
|
import_node_fs28.default.mkdirSync(projectDir, { recursive: true });
|
|
41188
41117
|
import_node_fs28.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
41189
41118
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -41561,7 +41490,7 @@ function buildPermissionHandlers(deps) {
|
|
|
41561
41490
|
}
|
|
41562
41491
|
|
|
41563
41492
|
// src/handlers/history.ts
|
|
41564
|
-
var
|
|
41493
|
+
var path40 = __toESM(require("path"), 1);
|
|
41565
41494
|
init_protocol();
|
|
41566
41495
|
|
|
41567
41496
|
// src/session/recent-dirs.ts
|
|
@@ -41579,7 +41508,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
41579
41508
|
}
|
|
41580
41509
|
|
|
41581
41510
|
// src/permission/persona-paths.ts
|
|
41582
|
-
var
|
|
41511
|
+
var path39 = __toESM(require("path"), 1);
|
|
41583
41512
|
function getAllowedPersonaIds(grants, action) {
|
|
41584
41513
|
const ids = /* @__PURE__ */ new Set();
|
|
41585
41514
|
for (const g2 of grants) {
|
|
@@ -41592,31 +41521,31 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
41592
41521
|
return ids;
|
|
41593
41522
|
}
|
|
41594
41523
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
41595
|
-
const target =
|
|
41524
|
+
const target = path39.resolve(absPath);
|
|
41596
41525
|
if (userWorkDir) {
|
|
41597
|
-
const u =
|
|
41598
|
-
const usep = u.endsWith(
|
|
41526
|
+
const u = path39.resolve(userWorkDir);
|
|
41527
|
+
const usep = u.endsWith(path39.sep) ? "" : path39.sep;
|
|
41599
41528
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
41600
41529
|
}
|
|
41601
|
-
const root =
|
|
41602
|
-
const sep2 = root.endsWith(
|
|
41530
|
+
const root = path39.resolve(personaRoot);
|
|
41531
|
+
const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
|
|
41603
41532
|
if (!target.startsWith(root + sep2)) return false;
|
|
41604
|
-
const rel =
|
|
41533
|
+
const rel = path39.relative(root, target);
|
|
41605
41534
|
if (!rel || rel.startsWith("..")) return false;
|
|
41606
|
-
const personaId = rel.split(
|
|
41535
|
+
const personaId = rel.split(path39.sep)[0];
|
|
41607
41536
|
if (!personaId) return false;
|
|
41608
41537
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
41609
41538
|
if (allowed === "*") return true;
|
|
41610
41539
|
return allowed.has(personaId);
|
|
41611
41540
|
}
|
|
41612
41541
|
function personaIdFromPath(absPath, personaRoot) {
|
|
41613
|
-
const root =
|
|
41614
|
-
const target =
|
|
41615
|
-
const sep2 = root.endsWith(
|
|
41542
|
+
const root = path39.resolve(personaRoot);
|
|
41543
|
+
const target = path39.resolve(absPath);
|
|
41544
|
+
const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
|
|
41616
41545
|
if (!target.startsWith(root + sep2)) return null;
|
|
41617
|
-
const rel =
|
|
41546
|
+
const rel = path39.relative(root, target);
|
|
41618
41547
|
if (!rel || rel.startsWith("..")) return null;
|
|
41619
|
-
const id = rel.split(
|
|
41548
|
+
const id = rel.split(path39.sep)[0];
|
|
41620
41549
|
return id || null;
|
|
41621
41550
|
}
|
|
41622
41551
|
|
|
@@ -41643,7 +41572,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41643
41572
|
if (!pid) return false;
|
|
41644
41573
|
return isGuestPathAllowed(
|
|
41645
41574
|
ctx.grants,
|
|
41646
|
-
|
|
41575
|
+
path40.join(personaRoot, pid),
|
|
41647
41576
|
personaRoot,
|
|
41648
41577
|
"read",
|
|
41649
41578
|
userWorkDir
|
|
@@ -41655,7 +41584,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41655
41584
|
};
|
|
41656
41585
|
const list = async (frame, _client, ctx) => {
|
|
41657
41586
|
const args = HistoryListArgs.parse(frame);
|
|
41658
|
-
assertGuestPath(ctx,
|
|
41587
|
+
assertGuestPath(ctx, path40.resolve(args.projectPath), personaRoot, "history:list");
|
|
41659
41588
|
const sessions = await history.listSessions(args);
|
|
41660
41589
|
return { response: { type: "history:list", sessions } };
|
|
41661
41590
|
};
|
|
@@ -41687,13 +41616,13 @@ function buildHistoryHandlers(deps) {
|
|
|
41687
41616
|
};
|
|
41688
41617
|
const subagents = async (frame, _client, ctx) => {
|
|
41689
41618
|
const args = HistorySubagentsArgs.parse(frame);
|
|
41690
|
-
assertGuestPath(ctx,
|
|
41619
|
+
assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
41691
41620
|
const subs = await history.listSubagents(args);
|
|
41692
41621
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
41693
41622
|
};
|
|
41694
41623
|
const subagentRead = async (frame, _client, ctx) => {
|
|
41695
41624
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
41696
|
-
assertGuestPath(ctx,
|
|
41625
|
+
assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
41697
41626
|
const res = await history.readSubagent(args);
|
|
41698
41627
|
return { response: { type: "history:subagent-read", ...res } };
|
|
41699
41628
|
};
|
|
@@ -41702,7 +41631,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41702
41631
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
41703
41632
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
41704
41633
|
const filtered = dirs.filter(
|
|
41705
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
41634
|
+
(d) => isGuestPathAllowed(ctx.grants, path40.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
41706
41635
|
);
|
|
41707
41636
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
41708
41637
|
}
|
|
@@ -41719,8 +41648,8 @@ function buildHistoryHandlers(deps) {
|
|
|
41719
41648
|
}
|
|
41720
41649
|
|
|
41721
41650
|
// src/handlers/workspace.ts
|
|
41722
|
-
var
|
|
41723
|
-
var
|
|
41651
|
+
var path41 = __toESM(require("path"), 1);
|
|
41652
|
+
var os15 = __toESM(require("os"), 1);
|
|
41724
41653
|
init_protocol();
|
|
41725
41654
|
init_protocol();
|
|
41726
41655
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -41760,23 +41689,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41760
41689
|
const list = async (frame, _client, ctx) => {
|
|
41761
41690
|
const args = WorkspaceListArgs.parse(frame);
|
|
41762
41691
|
const isGuest = ctx?.principal.kind === "guest";
|
|
41763
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
41764
|
-
const resolvedCwd =
|
|
41765
|
-
const target = args.path ?
|
|
41692
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
|
|
41693
|
+
const resolvedCwd = path41.resolve(args.cwd ?? fallbackCwd);
|
|
41694
|
+
const target = args.path ? path41.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
41766
41695
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
41767
41696
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
41768
41697
|
return { response: { type: "workspace:list", ...res } };
|
|
41769
41698
|
};
|
|
41770
41699
|
const read = async (frame, _client, ctx) => {
|
|
41771
41700
|
const args = WorkspaceReadArgs.parse(frame);
|
|
41772
|
-
const target =
|
|
41701
|
+
const target = path41.isAbsolute(args.path) ? path41.resolve(args.path) : path41.resolve(args.cwd, args.path);
|
|
41773
41702
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
41774
41703
|
const res = workspace.read(args);
|
|
41775
41704
|
return { response: { type: "workspace:read", ...res } };
|
|
41776
41705
|
};
|
|
41777
41706
|
const skillsList = async (frame, _client, ctx) => {
|
|
41778
41707
|
const args = SkillsListArgs.parse(frame);
|
|
41779
|
-
const cwdAbs =
|
|
41708
|
+
const cwdAbs = path41.resolve(args.cwd);
|
|
41780
41709
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
41781
41710
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
41782
41711
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -41788,7 +41717,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41788
41717
|
};
|
|
41789
41718
|
const agentsList = async (frame, _client, ctx) => {
|
|
41790
41719
|
const args = AgentsListArgs.parse(frame);
|
|
41791
|
-
const cwdAbs =
|
|
41720
|
+
const cwdAbs = path41.resolve(args.cwd);
|
|
41792
41721
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
41793
41722
|
if (args.tool === "codex") {
|
|
41794
41723
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -41810,18 +41739,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41810
41739
|
}
|
|
41811
41740
|
|
|
41812
41741
|
// src/handlers/git.ts
|
|
41813
|
-
var
|
|
41742
|
+
var path43 = __toESM(require("path"), 1);
|
|
41814
41743
|
init_protocol();
|
|
41815
41744
|
init_protocol();
|
|
41816
41745
|
|
|
41817
41746
|
// src/workspace/git.ts
|
|
41818
41747
|
var import_node_child_process10 = require("child_process");
|
|
41819
41748
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
41820
|
-
var
|
|
41749
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
41821
41750
|
var import_node_util = require("util");
|
|
41822
41751
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
41823
41752
|
function normalizePath(p2) {
|
|
41824
|
-
const resolved =
|
|
41753
|
+
const resolved = import_node_path30.default.resolve(p2);
|
|
41825
41754
|
try {
|
|
41826
41755
|
return import_node_fs29.default.realpathSync(resolved);
|
|
41827
41756
|
} catch {
|
|
@@ -41897,7 +41826,7 @@ async function listGitBranches(cwd) {
|
|
|
41897
41826
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
41898
41827
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
41899
41828
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
41900
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
41829
|
+
if (!isGuestPathAllowed(ctx.grants, path43.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
41901
41830
|
throw new ClawdError(
|
|
41902
41831
|
ERROR_CODES.UNAUTHORIZED,
|
|
41903
41832
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -42285,7 +42214,7 @@ function buildDeviceHandlers(deps) {
|
|
|
42285
42214
|
}
|
|
42286
42215
|
|
|
42287
42216
|
// src/handlers/meta.ts
|
|
42288
|
-
var
|
|
42217
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
42289
42218
|
init_protocol();
|
|
42290
42219
|
|
|
42291
42220
|
// src/version.ts
|
|
@@ -42316,7 +42245,7 @@ function buildReadyFrame(deps, client) {
|
|
|
42316
42245
|
return {
|
|
42317
42246
|
version,
|
|
42318
42247
|
protocolVersion: PROTOCOL_VERSION,
|
|
42319
|
-
hostname:
|
|
42248
|
+
hostname: import_node_os15.default.hostname(),
|
|
42320
42249
|
os: process.platform,
|
|
42321
42250
|
tools,
|
|
42322
42251
|
runningSessions: info.runningSessions,
|
|
@@ -42411,7 +42340,7 @@ function buildPersonaHandlers(deps) {
|
|
|
42411
42340
|
}
|
|
42412
42341
|
|
|
42413
42342
|
// src/handlers/attachment.ts
|
|
42414
|
-
var
|
|
42343
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
42415
42344
|
init_protocol();
|
|
42416
42345
|
init_protocol();
|
|
42417
42346
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -42466,12 +42395,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
42466
42395
|
`session ${args.sessionId} scope unresolved`
|
|
42467
42396
|
);
|
|
42468
42397
|
}
|
|
42469
|
-
const cwdAbs =
|
|
42470
|
-
const candidateAbs =
|
|
42398
|
+
const cwdAbs = import_node_path31.default.resolve(sessionFile.cwd);
|
|
42399
|
+
const candidateAbs = import_node_path31.default.isAbsolute(args.relPath) ? import_node_path31.default.resolve(args.relPath) : import_node_path31.default.resolve(cwdAbs, args.relPath);
|
|
42471
42400
|
assertGuestAttachmentPath(ctx, candidateAbs, deps.personaRoot, "attachment.signUrl", deps.usersRoot);
|
|
42472
42401
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
42473
42402
|
const entry = entries.find((e) => {
|
|
42474
|
-
const storedAbs =
|
|
42403
|
+
const storedAbs = import_node_path31.default.isAbsolute(e.relPath) ? import_node_path31.default.resolve(e.relPath) : import_node_path31.default.resolve(cwdAbs, e.relPath);
|
|
42475
42404
|
return storedAbs === candidateAbs && !e.stale;
|
|
42476
42405
|
});
|
|
42477
42406
|
if (!entry) {
|
|
@@ -42495,7 +42424,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
42495
42424
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
42496
42425
|
const f = deps.sessionStore.read(sessionId);
|
|
42497
42426
|
if (!f) return;
|
|
42498
|
-
assertGuestAttachmentPath(ctx,
|
|
42427
|
+
assertGuestAttachmentPath(ctx, import_node_path31.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
42499
42428
|
}
|
|
42500
42429
|
const groupAdd = async (frame, _client, ctx) => {
|
|
42501
42430
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -42567,19 +42496,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
42567
42496
|
|
|
42568
42497
|
// src/handlers/extension.ts
|
|
42569
42498
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
42570
|
-
var
|
|
42499
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
42571
42500
|
init_protocol();
|
|
42572
42501
|
|
|
42573
42502
|
// src/extension/bundle-zip.ts
|
|
42574
42503
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
42575
|
-
var
|
|
42504
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
42576
42505
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
42577
42506
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
42578
42507
|
async function bundleExtensionDir(dir) {
|
|
42579
42508
|
const entries = await listFilesSorted(dir);
|
|
42580
42509
|
const zip = new import_jszip2.default();
|
|
42581
42510
|
for (const rel of entries) {
|
|
42582
|
-
const abs =
|
|
42511
|
+
const abs = import_node_path32.default.join(dir, rel);
|
|
42583
42512
|
const content = await import_promises4.default.readFile(abs);
|
|
42584
42513
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
42585
42514
|
}
|
|
@@ -42600,7 +42529,7 @@ async function listFilesSorted(rootDir) {
|
|
|
42600
42529
|
return out;
|
|
42601
42530
|
}
|
|
42602
42531
|
async function walk(absRoot, relPrefix, out) {
|
|
42603
|
-
const dirAbs =
|
|
42532
|
+
const dirAbs = import_node_path32.default.join(absRoot, relPrefix);
|
|
42604
42533
|
const entries = await import_promises4.default.readdir(dirAbs, { withFileTypes: true });
|
|
42605
42534
|
for (const e of entries) {
|
|
42606
42535
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -42654,25 +42583,25 @@ function computePublishCheck(args) {
|
|
|
42654
42583
|
|
|
42655
42584
|
// src/extension/install-flow.ts
|
|
42656
42585
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
42657
|
-
var
|
|
42658
|
-
var
|
|
42586
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
42587
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
42659
42588
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
42660
42589
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
42661
42590
|
|
|
42662
42591
|
// src/extension/paths.ts
|
|
42663
|
-
var
|
|
42664
|
-
var
|
|
42592
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
42593
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
42665
42594
|
function clawdHomeRoot(override) {
|
|
42666
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
42595
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path33.default.join(import_node_os16.default.homedir(), ".clawd");
|
|
42667
42596
|
}
|
|
42668
42597
|
function extensionsRoot(override) {
|
|
42669
|
-
return
|
|
42598
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extensions");
|
|
42670
42599
|
}
|
|
42671
42600
|
function publishedChannelsFile(override) {
|
|
42672
|
-
return
|
|
42601
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
42673
42602
|
}
|
|
42674
42603
|
function bundleCacheRoot(override) {
|
|
42675
|
-
return
|
|
42604
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
42676
42605
|
}
|
|
42677
42606
|
|
|
42678
42607
|
// src/extension/install-flow.ts
|
|
@@ -42699,7 +42628,7 @@ async function installFromChannel(args, deps) {
|
|
|
42699
42628
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
42700
42629
|
}
|
|
42701
42630
|
for (const name of Object.keys(zip.files)) {
|
|
42702
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
42631
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path34.default.isAbsolute(name)) {
|
|
42703
42632
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
42704
42633
|
}
|
|
42705
42634
|
}
|
|
@@ -42731,7 +42660,7 @@ async function installFromChannel(args, deps) {
|
|
|
42731
42660
|
);
|
|
42732
42661
|
}
|
|
42733
42662
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
42734
|
-
const destDir =
|
|
42663
|
+
const destDir = import_node_path34.default.join(deps.extensionsRoot, localExtId);
|
|
42735
42664
|
let destExists = false;
|
|
42736
42665
|
try {
|
|
42737
42666
|
await import_promises5.default.access(destDir);
|
|
@@ -42745,16 +42674,16 @@ async function installFromChannel(args, deps) {
|
|
|
42745
42674
|
);
|
|
42746
42675
|
}
|
|
42747
42676
|
const stage = await import_promises5.default.mkdtemp(
|
|
42748
|
-
|
|
42677
|
+
import_node_path34.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
42749
42678
|
);
|
|
42750
42679
|
try {
|
|
42751
42680
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
42752
|
-
const dest =
|
|
42681
|
+
const dest = import_node_path34.default.join(stage, name);
|
|
42753
42682
|
if (entry.dir) {
|
|
42754
42683
|
await import_promises5.default.mkdir(dest, { recursive: true });
|
|
42755
42684
|
continue;
|
|
42756
42685
|
}
|
|
42757
|
-
await import_promises5.default.mkdir(
|
|
42686
|
+
await import_promises5.default.mkdir(import_node_path34.default.dirname(dest), { recursive: true });
|
|
42758
42687
|
if (name === "manifest.json") {
|
|
42759
42688
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
42760
42689
|
await import_promises5.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -42775,8 +42704,8 @@ async function installFromChannel(args, deps) {
|
|
|
42775
42704
|
|
|
42776
42705
|
// src/extension/update-flow.ts
|
|
42777
42706
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
42778
|
-
var
|
|
42779
|
-
var
|
|
42707
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
42708
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
42780
42709
|
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
42781
42710
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
42782
42711
|
var UpdateError = class extends Error {
|
|
@@ -42792,11 +42721,11 @@ async function updateFromChannel(args, deps) {
|
|
|
42792
42721
|
channelRef.extId,
|
|
42793
42722
|
channelRef.ownerPrincipalId
|
|
42794
42723
|
);
|
|
42795
|
-
const liveDir =
|
|
42724
|
+
const liveDir = import_node_path35.default.join(deps.extensionsRoot, localExtId);
|
|
42796
42725
|
const prevDir = `${liveDir}.prev`;
|
|
42797
42726
|
let existingVersion;
|
|
42798
42727
|
try {
|
|
42799
|
-
const raw = await import_promises6.default.readFile(
|
|
42728
|
+
const raw = await import_promises6.default.readFile(import_node_path35.default.join(liveDir, "manifest.json"), "utf8");
|
|
42800
42729
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
42801
42730
|
if (!parsed2.success) {
|
|
42802
42731
|
throw new UpdateError(
|
|
@@ -42829,7 +42758,7 @@ async function updateFromChannel(args, deps) {
|
|
|
42829
42758
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
42830
42759
|
}
|
|
42831
42760
|
for (const name of Object.keys(zip.files)) {
|
|
42832
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
42761
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path35.default.isAbsolute(name)) {
|
|
42833
42762
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
42834
42763
|
}
|
|
42835
42764
|
}
|
|
@@ -42864,16 +42793,16 @@ async function updateFromChannel(args, deps) {
|
|
|
42864
42793
|
await import_promises6.default.rm(prevDir, { recursive: true, force: true });
|
|
42865
42794
|
await import_promises6.default.rename(liveDir, prevDir);
|
|
42866
42795
|
const stage = await import_promises6.default.mkdtemp(
|
|
42867
|
-
|
|
42796
|
+
import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
42868
42797
|
);
|
|
42869
42798
|
try {
|
|
42870
42799
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
42871
|
-
const dest =
|
|
42800
|
+
const dest = import_node_path35.default.join(stage, name);
|
|
42872
42801
|
if (entry.dir) {
|
|
42873
42802
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
42874
42803
|
continue;
|
|
42875
42804
|
}
|
|
42876
|
-
await import_promises6.default.mkdir(
|
|
42805
|
+
await import_promises6.default.mkdir(import_node_path35.default.dirname(dest), { recursive: true });
|
|
42877
42806
|
if (name === "manifest.json") {
|
|
42878
42807
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
42879
42808
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -42966,7 +42895,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
42966
42895
|
);
|
|
42967
42896
|
}
|
|
42968
42897
|
}
|
|
42969
|
-
const manifestPath =
|
|
42898
|
+
const manifestPath = import_node_path36.default.join(root, extId, "manifest.json");
|
|
42970
42899
|
const manifest = await readManifest(root, extId);
|
|
42971
42900
|
const next = { ...manifest, version: newVersion };
|
|
42972
42901
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -42974,7 +42903,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
42974
42903
|
await import_promises7.default.rename(tmp, manifestPath);
|
|
42975
42904
|
}
|
|
42976
42905
|
async function readManifest(root, extId) {
|
|
42977
|
-
const file =
|
|
42906
|
+
const file = import_node_path36.default.join(root, extId, "manifest.json");
|
|
42978
42907
|
let raw;
|
|
42979
42908
|
try {
|
|
42980
42909
|
raw = await import_promises7.default.readFile(file, "utf8");
|
|
@@ -43065,7 +42994,7 @@ function buildExtensionHandlers(deps) {
|
|
|
43065
42994
|
};
|
|
43066
42995
|
async function buildSnapshotMeta(extId) {
|
|
43067
42996
|
const manifest = await readManifest(deps.root, extId);
|
|
43068
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
42997
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path36.default.join(deps.root, extId));
|
|
43069
42998
|
return { manifest, contentHash: sha256, buffer };
|
|
43070
42999
|
}
|
|
43071
43000
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -43362,7 +43291,7 @@ var PublishJobRegistry = class {
|
|
|
43362
43291
|
// src/app-builder/publish-job-runner.ts
|
|
43363
43292
|
var import_node_child_process12 = require("child_process");
|
|
43364
43293
|
var import_node_fs30 = require("fs");
|
|
43365
|
-
var
|
|
43294
|
+
var import_node_path37 = require("path");
|
|
43366
43295
|
|
|
43367
43296
|
// src/app-builder/publish-stage-parser.ts
|
|
43368
43297
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -43394,7 +43323,7 @@ async function startPublishJob(deps, args) {
|
|
|
43394
43323
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
43395
43324
|
}
|
|
43396
43325
|
const projDir = projectDir(args.name);
|
|
43397
|
-
const logPath = (0,
|
|
43326
|
+
const logPath = (0, import_node_path37.join)(projDir, ".publish.log");
|
|
43398
43327
|
let logStream = null;
|
|
43399
43328
|
try {
|
|
43400
43329
|
logStream = (0, import_node_fs30.createWriteStream)(logPath, { flags: "w" });
|
|
@@ -43654,7 +43583,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
43654
43583
|
|
|
43655
43584
|
// src/handlers/app-builder.ts
|
|
43656
43585
|
init_protocol();
|
|
43657
|
-
var
|
|
43586
|
+
var import_node_path38 = require("path");
|
|
43658
43587
|
var import_node_fs31 = require("fs");
|
|
43659
43588
|
var APP_BUILDER_PERSONAS = ["persona-app-builder"];
|
|
43660
43589
|
var PUBLISH_SCRIPT_REL = "extension-kit/scripts/publish.sh";
|
|
@@ -44031,7 +43960,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
44031
43960
|
});
|
|
44032
43961
|
await userStore.clearPublishJob(args.name);
|
|
44033
43962
|
}
|
|
44034
|
-
const scriptPath = (0,
|
|
43963
|
+
const scriptPath = (0, import_node_path38.join)(deps.personaRoot, PUBLISH_SCRIPT_REL);
|
|
44035
43964
|
deps.logger?.info("app-builder.publish.start", {
|
|
44036
43965
|
name: args.name,
|
|
44037
43966
|
sessionId: boundSession.sessionId,
|
|
@@ -44125,7 +44054,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
44125
44054
|
|
|
44126
44055
|
// src/extension/registry.ts
|
|
44127
44056
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
44128
|
-
var
|
|
44057
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
44129
44058
|
async function loadAll(root) {
|
|
44130
44059
|
let entries;
|
|
44131
44060
|
try {
|
|
@@ -44138,13 +44067,13 @@ async function loadAll(root) {
|
|
|
44138
44067
|
for (const ent of entries) {
|
|
44139
44068
|
if (!ent.isDirectory()) continue;
|
|
44140
44069
|
if (ent.name.startsWith(".")) continue;
|
|
44141
|
-
records.push(await loadOne(
|
|
44070
|
+
records.push(await loadOne(import_node_path39.default.join(root, ent.name), ent.name));
|
|
44142
44071
|
}
|
|
44143
44072
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
44144
44073
|
return records;
|
|
44145
44074
|
}
|
|
44146
44075
|
async function loadOne(dir, dirName) {
|
|
44147
|
-
const manifestPath =
|
|
44076
|
+
const manifestPath = import_node_path39.default.join(dir, "manifest.json");
|
|
44148
44077
|
let raw;
|
|
44149
44078
|
try {
|
|
44150
44079
|
raw = await import_promises8.default.readFile(manifestPath, "utf8");
|
|
@@ -44189,7 +44118,7 @@ async function loadOne(dir, dirName) {
|
|
|
44189
44118
|
|
|
44190
44119
|
// src/extension/uninstall.ts
|
|
44191
44120
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
44192
|
-
var
|
|
44121
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
44193
44122
|
var UninstallError = class extends Error {
|
|
44194
44123
|
constructor(code, message) {
|
|
44195
44124
|
super(message);
|
|
@@ -44198,7 +44127,7 @@ var UninstallError = class extends Error {
|
|
|
44198
44127
|
code;
|
|
44199
44128
|
};
|
|
44200
44129
|
async function uninstall(deps) {
|
|
44201
|
-
const dir =
|
|
44130
|
+
const dir = import_node_path40.default.join(deps.root, deps.extId);
|
|
44202
44131
|
try {
|
|
44203
44132
|
await import_promises9.default.access(dir);
|
|
44204
44133
|
} catch {
|
|
@@ -44279,7 +44208,7 @@ function buildMethodHandlers(deps) {
|
|
|
44279
44208
|
// src/app-builder/project-store.ts
|
|
44280
44209
|
var import_node_fs32 = require("fs");
|
|
44281
44210
|
var import_node_child_process13 = require("child_process");
|
|
44282
|
-
var
|
|
44211
|
+
var import_node_path41 = require("path");
|
|
44283
44212
|
init_protocol();
|
|
44284
44213
|
var PROJECTS_DIR = "projects";
|
|
44285
44214
|
var META_FILE = ".clawd-project.json";
|
|
@@ -44294,14 +44223,14 @@ var ProjectStore = class {
|
|
|
44294
44223
|
root;
|
|
44295
44224
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
44296
44225
|
metaPath(name) {
|
|
44297
|
-
return (0,
|
|
44226
|
+
return (0, import_node_path41.join)(this.projectsRoot(), name, META_FILE);
|
|
44298
44227
|
}
|
|
44299
44228
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
44300
44229
|
projectDir(name) {
|
|
44301
|
-
return (0,
|
|
44230
|
+
return (0, import_node_path41.join)(this.projectsRoot(), name);
|
|
44302
44231
|
}
|
|
44303
44232
|
projectsRoot() {
|
|
44304
|
-
return (0,
|
|
44233
|
+
return (0, import_node_path41.join)(this.root, PROJECTS_DIR);
|
|
44305
44234
|
}
|
|
44306
44235
|
async list() {
|
|
44307
44236
|
let entries;
|
|
@@ -44382,7 +44311,7 @@ var ProjectStore = class {
|
|
|
44382
44311
|
* 代码再参考"。assistant 进 project 时目录已是完整模板,直接 pnpm install 即可。
|
|
44383
44312
|
*/
|
|
44384
44313
|
async scaffold(name, template = DEFAULT_TEMPLATE, personaRoot = this.root) {
|
|
44385
|
-
const scriptPath = (0,
|
|
44314
|
+
const scriptPath = (0, import_node_path41.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
|
|
44386
44315
|
const destDir = this.projectDir(name);
|
|
44387
44316
|
return await new Promise((resolve6, reject) => {
|
|
44388
44317
|
const child = (0, import_node_child_process13.spawn)("bash", [scriptPath, name, template, destDir], {
|
|
@@ -44920,7 +44849,7 @@ function computeGrantForFrame(method, frame) {
|
|
|
44920
44849
|
|
|
44921
44850
|
// src/extension/runtime.ts
|
|
44922
44851
|
var import_node_child_process15 = require("child_process");
|
|
44923
|
-
var
|
|
44852
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
44924
44853
|
var import_promises10 = require("timers/promises");
|
|
44925
44854
|
|
|
44926
44855
|
// src/extension/port-allocator.ts
|
|
@@ -45021,7 +44950,7 @@ var Runtime = class {
|
|
|
45021
44950
|
/\$CLAWOS_EXT_PORT/g,
|
|
45022
44951
|
String(port)
|
|
45023
44952
|
);
|
|
45024
|
-
const dir =
|
|
44953
|
+
const dir = import_node_path42.default.join(this.root, extId);
|
|
45025
44954
|
const env = {
|
|
45026
44955
|
...process.env,
|
|
45027
44956
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -45133,7 +45062,7 @@ ${handle.stderrTail}`
|
|
|
45133
45062
|
|
|
45134
45063
|
// src/extension/published-channels.ts
|
|
45135
45064
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
45136
|
-
var
|
|
45065
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
45137
45066
|
init_zod();
|
|
45138
45067
|
var PublishedChannelsError = class extends Error {
|
|
45139
45068
|
constructor(code, message) {
|
|
@@ -45232,7 +45161,7 @@ var PublishedChannelStore = class {
|
|
|
45232
45161
|
)
|
|
45233
45162
|
};
|
|
45234
45163
|
const tmp = `${this.filePath}.tmp`;
|
|
45235
|
-
await import_promises11.default.mkdir(
|
|
45164
|
+
await import_promises11.default.mkdir(import_node_path43.default.dirname(this.filePath), { recursive: true });
|
|
45236
45165
|
await import_promises11.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
45237
45166
|
await import_promises11.default.rename(tmp, this.filePath);
|
|
45238
45167
|
}
|
|
@@ -45240,7 +45169,7 @@ var PublishedChannelStore = class {
|
|
|
45240
45169
|
|
|
45241
45170
|
// src/extension/bundle-cache.ts
|
|
45242
45171
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
45243
|
-
var
|
|
45172
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
45244
45173
|
var BundleCache = class {
|
|
45245
45174
|
constructor(rootDir) {
|
|
45246
45175
|
this.rootDir = rootDir;
|
|
@@ -45249,14 +45178,14 @@ var BundleCache = class {
|
|
|
45249
45178
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
45250
45179
|
async write(snapshotHash, buffer) {
|
|
45251
45180
|
await import_promises12.default.mkdir(this.rootDir, { recursive: true });
|
|
45252
|
-
const file =
|
|
45181
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45253
45182
|
const tmp = `${file}.tmp`;
|
|
45254
45183
|
await import_promises12.default.writeFile(tmp, buffer, { mode: 384 });
|
|
45255
45184
|
await import_promises12.default.rename(tmp, file);
|
|
45256
45185
|
}
|
|
45257
45186
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
45258
45187
|
async read(snapshotHash) {
|
|
45259
|
-
const file =
|
|
45188
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45260
45189
|
try {
|
|
45261
45190
|
return await import_promises12.default.readFile(file);
|
|
45262
45191
|
} catch (e) {
|
|
@@ -45266,7 +45195,7 @@ var BundleCache = class {
|
|
|
45266
45195
|
}
|
|
45267
45196
|
/** Idempotent — missing file is not an error. */
|
|
45268
45197
|
async delete(snapshotHash) {
|
|
45269
|
-
const file =
|
|
45198
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45270
45199
|
await import_promises12.default.rm(file, { force: true });
|
|
45271
45200
|
}
|
|
45272
45201
|
};
|
|
@@ -45275,7 +45204,7 @@ var BundleCache = class {
|
|
|
45275
45204
|
async function startDaemon(config) {
|
|
45276
45205
|
const logger = createLogger({
|
|
45277
45206
|
level: config.logLevel,
|
|
45278
|
-
file:
|
|
45207
|
+
file: import_node_path45.default.join(config.dataDir, "clawd.log")
|
|
45279
45208
|
});
|
|
45280
45209
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
45281
45210
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
@@ -45411,8 +45340,8 @@ async function startDaemon(config) {
|
|
|
45411
45340
|
const agents = new AgentsScanner();
|
|
45412
45341
|
const history = new ClaudeHistoryReader();
|
|
45413
45342
|
let transport = null;
|
|
45414
|
-
const personaStore = new PersonaStore(
|
|
45415
|
-
const usersRoot =
|
|
45343
|
+
const personaStore = new PersonaStore(import_node_path45.default.join(config.dataDir, "personas"));
|
|
45344
|
+
const usersRoot = import_node_path45.default.join(config.dataDir, "users");
|
|
45416
45345
|
const defaultsRoot = findDefaultsRoot();
|
|
45417
45346
|
if (defaultsRoot) {
|
|
45418
45347
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -45432,7 +45361,7 @@ async function startDaemon(config) {
|
|
|
45432
45361
|
getAdapter,
|
|
45433
45362
|
historyReader: history,
|
|
45434
45363
|
dataDir: config.dataDir,
|
|
45435
|
-
personaRoot:
|
|
45364
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45436
45365
|
usersRoot,
|
|
45437
45366
|
personaStore,
|
|
45438
45367
|
ownerDisplayName,
|
|
@@ -45462,7 +45391,7 @@ async function startDaemon(config) {
|
|
|
45462
45391
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
45463
45392
|
attachmentGroup: {
|
|
45464
45393
|
onFileEdit: (input) => {
|
|
45465
|
-
const absPath =
|
|
45394
|
+
const absPath = import_node_path45.default.isAbsolute(input.relPath) ? input.relPath : import_node_path45.default.join(input.cwd, input.relPath);
|
|
45466
45395
|
let size = 0;
|
|
45467
45396
|
try {
|
|
45468
45397
|
size = import_node_fs33.default.statSync(absPath).size;
|
|
@@ -45651,11 +45580,11 @@ async function startDaemon(config) {
|
|
|
45651
45580
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
45652
45581
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
45653
45582
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
45654
|
-
personaRoot:
|
|
45583
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45655
45584
|
usersRoot
|
|
45656
45585
|
},
|
|
45657
45586
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
45658
|
-
personaRoot:
|
|
45587
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45659
45588
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
45660
45589
|
usersRoot,
|
|
45661
45590
|
// capability:list / delete handler 依赖
|
|
@@ -45744,7 +45673,7 @@ async function startDaemon(config) {
|
|
|
45744
45673
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
45745
45674
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
45746
45675
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
45747
|
-
appBuilderPersonaRoot:
|
|
45676
|
+
appBuilderPersonaRoot: import_node_path45.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
45748
45677
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
45749
45678
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
45750
45679
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -45993,8 +45922,8 @@ async function startDaemon(config) {
|
|
|
45993
45922
|
const lines = [
|
|
45994
45923
|
`Tunnel: ${r.url}`,
|
|
45995
45924
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
45996
|
-
`Frpc config: ${
|
|
45997
|
-
`Frpc log: ${
|
|
45925
|
+
`Frpc config: ${import_node_path45.default.join(config.dataDir, "frpc.toml")}`,
|
|
45926
|
+
`Frpc log: ${import_node_path45.default.join(config.dataDir, "frpc.log")}`
|
|
45998
45927
|
];
|
|
45999
45928
|
const width = Math.max(...lines.map((l) => l.length));
|
|
46000
45929
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -46007,7 +45936,7 @@ ${bar}
|
|
|
46007
45936
|
|
|
46008
45937
|
`);
|
|
46009
45938
|
try {
|
|
46010
|
-
const connectPath =
|
|
45939
|
+
const connectPath = import_node_path45.default.join(config.dataDir, "connect.txt");
|
|
46011
45940
|
import_node_fs33.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
46012
45941
|
} catch {
|
|
46013
45942
|
}
|
|
@@ -46079,7 +46008,7 @@ ${bar}
|
|
|
46079
46008
|
};
|
|
46080
46009
|
}
|
|
46081
46010
|
function migrateDropPersonsDir(dataDir) {
|
|
46082
|
-
const dir =
|
|
46011
|
+
const dir = import_node_path45.default.join(dataDir, "persons");
|
|
46083
46012
|
try {
|
|
46084
46013
|
import_node_fs33.default.rmSync(dir, { recursive: true, force: true });
|
|
46085
46014
|
} catch {
|