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