@clawos-dev/clawd 0.2.136 → 0.2.137
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +314 -366
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -720,8 +720,8 @@ var init_parseUtil = __esm({
|
|
|
720
720
|
init_errors2();
|
|
721
721
|
init_en();
|
|
722
722
|
makeIssue = (params) => {
|
|
723
|
-
const { data, path:
|
|
724
|
-
const fullPath = [...
|
|
723
|
+
const { data, path: path58, errorMaps, issueData } = params;
|
|
724
|
+
const fullPath = [...path58, ...issueData.path || []];
|
|
725
725
|
const fullIssue = {
|
|
726
726
|
...issueData,
|
|
727
727
|
path: fullPath
|
|
@@ -1032,11 +1032,11 @@ var init_types = __esm({
|
|
|
1032
1032
|
init_parseUtil();
|
|
1033
1033
|
init_util();
|
|
1034
1034
|
ParseInputLazyPath = class {
|
|
1035
|
-
constructor(parent, value,
|
|
1035
|
+
constructor(parent, value, path58, key) {
|
|
1036
1036
|
this._cachedPath = [];
|
|
1037
1037
|
this.parent = parent;
|
|
1038
1038
|
this.data = value;
|
|
1039
|
-
this._path =
|
|
1039
|
+
this._path = path58;
|
|
1040
1040
|
this._key = key;
|
|
1041
1041
|
}
|
|
1042
1042
|
get path() {
|
|
@@ -6218,8 +6218,8 @@ var require_req = __commonJS({
|
|
|
6218
6218
|
if (req.originalUrl) {
|
|
6219
6219
|
_req.url = req.originalUrl;
|
|
6220
6220
|
} else {
|
|
6221
|
-
const
|
|
6222
|
-
_req.url = typeof
|
|
6221
|
+
const path58 = req.path;
|
|
6222
|
+
_req.url = typeof path58 === "string" ? path58 : req.url ? req.url.path || req.url : void 0;
|
|
6223
6223
|
}
|
|
6224
6224
|
if (req.query) {
|
|
6225
6225
|
_req.query = req.query;
|
|
@@ -6384,14 +6384,14 @@ var require_redact = __commonJS({
|
|
|
6384
6384
|
}
|
|
6385
6385
|
return obj;
|
|
6386
6386
|
}
|
|
6387
|
-
function parsePath(
|
|
6387
|
+
function parsePath(path58) {
|
|
6388
6388
|
const parts = [];
|
|
6389
6389
|
let current = "";
|
|
6390
6390
|
let inBrackets = false;
|
|
6391
6391
|
let inQuotes = false;
|
|
6392
6392
|
let quoteChar = "";
|
|
6393
|
-
for (let i = 0; i <
|
|
6394
|
-
const char =
|
|
6393
|
+
for (let i = 0; i < path58.length; i++) {
|
|
6394
|
+
const char = path58[i];
|
|
6395
6395
|
if (!inBrackets && char === ".") {
|
|
6396
6396
|
if (current) {
|
|
6397
6397
|
parts.push(current);
|
|
@@ -6522,10 +6522,10 @@ var require_redact = __commonJS({
|
|
|
6522
6522
|
return current;
|
|
6523
6523
|
}
|
|
6524
6524
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6525
|
-
for (const
|
|
6526
|
-
const parts = parsePath(
|
|
6525
|
+
for (const path58 of paths) {
|
|
6526
|
+
const parts = parsePath(path58);
|
|
6527
6527
|
if (parts.includes("*")) {
|
|
6528
|
-
redactWildcardPath(obj, parts, censor,
|
|
6528
|
+
redactWildcardPath(obj, parts, censor, path58, remove);
|
|
6529
6529
|
} else {
|
|
6530
6530
|
if (remove) {
|
|
6531
6531
|
removeKey(obj, parts);
|
|
@@ -6610,8 +6610,8 @@ var require_redact = __commonJS({
|
|
|
6610
6610
|
}
|
|
6611
6611
|
} else {
|
|
6612
6612
|
if (afterWildcard.includes("*")) {
|
|
6613
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6614
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
6613
|
+
const wrappedCensor = typeof censor === "function" ? (value, path58) => {
|
|
6614
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path58];
|
|
6615
6615
|
return censor(value, fullPath);
|
|
6616
6616
|
} : censor;
|
|
6617
6617
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -6646,8 +6646,8 @@ var require_redact = __commonJS({
|
|
|
6646
6646
|
return null;
|
|
6647
6647
|
}
|
|
6648
6648
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
6649
|
-
for (const
|
|
6650
|
-
const parts = parsePath(
|
|
6649
|
+
for (const path58 of pathsToClone) {
|
|
6650
|
+
const parts = parsePath(path58);
|
|
6651
6651
|
let current = pathStructure;
|
|
6652
6652
|
for (let i = 0; i < parts.length; i++) {
|
|
6653
6653
|
const part = parts[i];
|
|
@@ -6699,24 +6699,24 @@ var require_redact = __commonJS({
|
|
|
6699
6699
|
}
|
|
6700
6700
|
return cloneSelectively(obj, pathStructure);
|
|
6701
6701
|
}
|
|
6702
|
-
function validatePath(
|
|
6703
|
-
if (typeof
|
|
6702
|
+
function validatePath(path58) {
|
|
6703
|
+
if (typeof path58 !== "string") {
|
|
6704
6704
|
throw new Error("Paths must be (non-empty) strings");
|
|
6705
6705
|
}
|
|
6706
|
-
if (
|
|
6706
|
+
if (path58 === "") {
|
|
6707
6707
|
throw new Error("Invalid redaction path ()");
|
|
6708
6708
|
}
|
|
6709
|
-
if (
|
|
6710
|
-
throw new Error(`Invalid redaction path (${
|
|
6709
|
+
if (path58.includes("..")) {
|
|
6710
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6711
6711
|
}
|
|
6712
|
-
if (
|
|
6713
|
-
throw new Error(`Invalid redaction path (${
|
|
6712
|
+
if (path58.includes(",")) {
|
|
6713
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6714
6714
|
}
|
|
6715
6715
|
let bracketCount = 0;
|
|
6716
6716
|
let inQuotes = false;
|
|
6717
6717
|
let quoteChar = "";
|
|
6718
|
-
for (let i = 0; i <
|
|
6719
|
-
const char =
|
|
6718
|
+
for (let i = 0; i < path58.length; i++) {
|
|
6719
|
+
const char = path58[i];
|
|
6720
6720
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
6721
6721
|
if (!inQuotes) {
|
|
6722
6722
|
inQuotes = true;
|
|
@@ -6730,20 +6730,20 @@ var require_redact = __commonJS({
|
|
|
6730
6730
|
} else if (char === "]" && !inQuotes) {
|
|
6731
6731
|
bracketCount--;
|
|
6732
6732
|
if (bracketCount < 0) {
|
|
6733
|
-
throw new Error(`Invalid redaction path (${
|
|
6733
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6734
6734
|
}
|
|
6735
6735
|
}
|
|
6736
6736
|
}
|
|
6737
6737
|
if (bracketCount !== 0) {
|
|
6738
|
-
throw new Error(`Invalid redaction path (${
|
|
6738
|
+
throw new Error(`Invalid redaction path (${path58})`);
|
|
6739
6739
|
}
|
|
6740
6740
|
}
|
|
6741
6741
|
function validatePaths(paths) {
|
|
6742
6742
|
if (!Array.isArray(paths)) {
|
|
6743
6743
|
throw new TypeError("paths must be an array");
|
|
6744
6744
|
}
|
|
6745
|
-
for (const
|
|
6746
|
-
validatePath(
|
|
6745
|
+
for (const path58 of paths) {
|
|
6746
|
+
validatePath(path58);
|
|
6747
6747
|
}
|
|
6748
6748
|
}
|
|
6749
6749
|
function slowRedact(options = {}) {
|
|
@@ -6911,8 +6911,8 @@ var require_redaction = __commonJS({
|
|
|
6911
6911
|
if (shape[k2] === null) {
|
|
6912
6912
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
6913
6913
|
} else {
|
|
6914
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6915
|
-
return censor(value, [k2, ...
|
|
6914
|
+
const wrappedCensor = typeof censor === "function" ? (value, path58) => {
|
|
6915
|
+
return censor(value, [k2, ...path58]);
|
|
6916
6916
|
} : censor;
|
|
6917
6917
|
o[k2] = Redact({
|
|
6918
6918
|
paths: shape[k2],
|
|
@@ -7133,7 +7133,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7133
7133
|
var fs51 = require("fs");
|
|
7134
7134
|
var EventEmitter3 = require("events");
|
|
7135
7135
|
var inherits = require("util").inherits;
|
|
7136
|
-
var
|
|
7136
|
+
var path58 = require("path");
|
|
7137
7137
|
var sleep = require_atomic_sleep();
|
|
7138
7138
|
var assert = require("assert");
|
|
7139
7139
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7187,7 +7187,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7187
7187
|
const mode = sonic.mode;
|
|
7188
7188
|
if (sonic.sync) {
|
|
7189
7189
|
try {
|
|
7190
|
-
if (sonic.mkdir) fs51.mkdirSync(
|
|
7190
|
+
if (sonic.mkdir) fs51.mkdirSync(path58.dirname(file), { recursive: true });
|
|
7191
7191
|
const fd = fs51.openSync(file, flags, mode);
|
|
7192
7192
|
fileOpened(null, fd);
|
|
7193
7193
|
} catch (err) {
|
|
@@ -7195,7 +7195,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7195
7195
|
throw err;
|
|
7196
7196
|
}
|
|
7197
7197
|
} else if (sonic.mkdir) {
|
|
7198
|
-
fs51.mkdir(
|
|
7198
|
+
fs51.mkdir(path58.dirname(file), { recursive: true }, (err) => {
|
|
7199
7199
|
if (err) return fileOpened(err);
|
|
7200
7200
|
fs51.open(file, flags, mode, fileOpened);
|
|
7201
7201
|
});
|
|
@@ -10055,7 +10055,7 @@ var require_multistream = __commonJS({
|
|
|
10055
10055
|
var require_pino = __commonJS({
|
|
10056
10056
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
10057
10057
|
"use strict";
|
|
10058
|
-
var
|
|
10058
|
+
var os21 = require("os");
|
|
10059
10059
|
var stdSerializers = require_pino_std_serializers();
|
|
10060
10060
|
var caller = require_caller();
|
|
10061
10061
|
var redaction = require_redaction();
|
|
@@ -10102,7 +10102,7 @@ var require_pino = __commonJS({
|
|
|
10102
10102
|
} = symbols;
|
|
10103
10103
|
var { epochTime, nullTime } = time;
|
|
10104
10104
|
var { pid } = process;
|
|
10105
|
-
var hostname =
|
|
10105
|
+
var hostname = os21.hostname();
|
|
10106
10106
|
var defaultErrorSerializer = stdSerializers.err;
|
|
10107
10107
|
var defaultOptions = {
|
|
10108
10108
|
level: "info",
|
|
@@ -10826,11 +10826,11 @@ var init_lib = __esm({
|
|
|
10826
10826
|
}
|
|
10827
10827
|
}
|
|
10828
10828
|
},
|
|
10829
|
-
addToPath: function addToPath(
|
|
10830
|
-
var last =
|
|
10829
|
+
addToPath: function addToPath(path58, added, removed, oldPosInc, options) {
|
|
10830
|
+
var last = path58.lastComponent;
|
|
10831
10831
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
10832
10832
|
return {
|
|
10833
|
-
oldPos:
|
|
10833
|
+
oldPos: path58.oldPos + oldPosInc,
|
|
10834
10834
|
lastComponent: {
|
|
10835
10835
|
count: last.count + 1,
|
|
10836
10836
|
added,
|
|
@@ -10840,7 +10840,7 @@ var init_lib = __esm({
|
|
|
10840
10840
|
};
|
|
10841
10841
|
} else {
|
|
10842
10842
|
return {
|
|
10843
|
-
oldPos:
|
|
10843
|
+
oldPos: path58.oldPos + oldPosInc,
|
|
10844
10844
|
lastComponent: {
|
|
10845
10845
|
count: 1,
|
|
10846
10846
|
added,
|
|
@@ -11286,10 +11286,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11286
11286
|
const memories = raw.map((m2) => {
|
|
11287
11287
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11288
11288
|
const rec3 = m2;
|
|
11289
|
-
const
|
|
11289
|
+
const path58 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11290
11290
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11291
|
-
if (!
|
|
11292
|
-
const entry = { path:
|
|
11291
|
+
if (!path58 || content == null) return null;
|
|
11292
|
+
const entry = { path: path58, content };
|
|
11293
11293
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11294
11294
|
return entry;
|
|
11295
11295
|
}).filter((m2) => m2 !== null);
|
|
@@ -11754,12 +11754,6 @@ var init_claude_history = __esm({
|
|
|
11754
11754
|
});
|
|
11755
11755
|
|
|
11756
11756
|
// src/tools/claude.ts
|
|
11757
|
-
function macOSDesktopCandidates(home) {
|
|
11758
|
-
return [
|
|
11759
|
-
import_node_path9.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
|
|
11760
|
-
"/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
|
|
11761
|
-
];
|
|
11762
|
-
}
|
|
11763
11757
|
function probeViaWhich() {
|
|
11764
11758
|
try {
|
|
11765
11759
|
const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
|
|
@@ -11768,19 +11762,12 @@ function probeViaWhich() {
|
|
|
11768
11762
|
}
|
|
11769
11763
|
return null;
|
|
11770
11764
|
}
|
|
11771
|
-
async function probeClaude(env = process.env
|
|
11765
|
+
async function probeClaude(env = process.env) {
|
|
11772
11766
|
if (env.CLAUDE_BIN && import_node_fs9.default.existsSync(env.CLAUDE_BIN)) {
|
|
11773
11767
|
return { available: true, path: env.CLAUDE_BIN };
|
|
11774
11768
|
}
|
|
11775
11769
|
const w2 = probeViaWhich();
|
|
11776
11770
|
if (w2) return { available: true, path: w2 };
|
|
11777
|
-
if (process.platform === "darwin") {
|
|
11778
|
-
for (const candidate of macOSDesktopCandidates(home)) {
|
|
11779
|
-
if (import_node_fs9.default.existsSync(candidate)) {
|
|
11780
|
-
return { available: true, path: candidate };
|
|
11781
|
-
}
|
|
11782
|
-
}
|
|
11783
|
-
}
|
|
11784
11771
|
return { available: false };
|
|
11785
11772
|
}
|
|
11786
11773
|
function buildSpawnArgs(ctx) {
|
|
@@ -12101,10 +12088,10 @@ function parseAttachment(obj) {
|
|
|
12101
12088
|
const memories = raw.map((m2) => {
|
|
12102
12089
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12103
12090
|
const rec3 = m2;
|
|
12104
|
-
const
|
|
12091
|
+
const path58 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12105
12092
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12106
|
-
if (!
|
|
12107
|
-
const out = { path:
|
|
12093
|
+
if (!path58 || content == null) return null;
|
|
12094
|
+
const out = { path: path58, content };
|
|
12108
12095
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12109
12096
|
return out;
|
|
12110
12097
|
}).filter((m2) => m2 !== null);
|
|
@@ -12208,15 +12195,13 @@ function encodeClaudeStdin(text) {
|
|
|
12208
12195
|
};
|
|
12209
12196
|
return JSON.stringify(frame) + "\n";
|
|
12210
12197
|
}
|
|
12211
|
-
var import_node_child_process, import_node_child_process2, import_node_fs9,
|
|
12198
|
+
var import_node_child_process, import_node_child_process2, import_node_fs9, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
|
|
12212
12199
|
var init_claude = __esm({
|
|
12213
12200
|
"src/tools/claude.ts"() {
|
|
12214
12201
|
"use strict";
|
|
12215
12202
|
import_node_child_process = require("child_process");
|
|
12216
12203
|
import_node_child_process2 = require("child_process");
|
|
12217
12204
|
import_node_fs9 = __toESM(require("fs"), 1);
|
|
12218
|
-
import_node_os5 = __toESM(require("os"), 1);
|
|
12219
|
-
import_node_path9 = __toESM(require("path"), 1);
|
|
12220
12205
|
init_protocol();
|
|
12221
12206
|
init_claude_history();
|
|
12222
12207
|
init_tool_result_extra();
|
|
@@ -23893,8 +23878,8 @@ var require_utils = __commonJS({
|
|
|
23893
23878
|
var result = transform[inputType][outputType](input);
|
|
23894
23879
|
return result;
|
|
23895
23880
|
};
|
|
23896
|
-
exports2.resolve = function(
|
|
23897
|
-
var parts =
|
|
23881
|
+
exports2.resolve = function(path58) {
|
|
23882
|
+
var parts = path58.split("/");
|
|
23898
23883
|
var result = [];
|
|
23899
23884
|
for (var index = 0; index < parts.length; index++) {
|
|
23900
23885
|
var part = parts[index];
|
|
@@ -29747,18 +29732,18 @@ var require_object = __commonJS({
|
|
|
29747
29732
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
29748
29733
|
this.files[name] = object;
|
|
29749
29734
|
};
|
|
29750
|
-
var parentFolder = function(
|
|
29751
|
-
if (
|
|
29752
|
-
|
|
29735
|
+
var parentFolder = function(path58) {
|
|
29736
|
+
if (path58.slice(-1) === "/") {
|
|
29737
|
+
path58 = path58.substring(0, path58.length - 1);
|
|
29753
29738
|
}
|
|
29754
|
-
var lastSlash =
|
|
29755
|
-
return lastSlash > 0 ?
|
|
29739
|
+
var lastSlash = path58.lastIndexOf("/");
|
|
29740
|
+
return lastSlash > 0 ? path58.substring(0, lastSlash) : "";
|
|
29756
29741
|
};
|
|
29757
|
-
var forceTrailingSlash = function(
|
|
29758
|
-
if (
|
|
29759
|
-
|
|
29742
|
+
var forceTrailingSlash = function(path58) {
|
|
29743
|
+
if (path58.slice(-1) !== "/") {
|
|
29744
|
+
path58 += "/";
|
|
29760
29745
|
}
|
|
29761
|
-
return
|
|
29746
|
+
return path58;
|
|
29762
29747
|
};
|
|
29763
29748
|
var folderAdd = function(name, createFolders) {
|
|
29764
29749
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -30760,7 +30745,7 @@ var require_lib3 = __commonJS({
|
|
|
30760
30745
|
// src/run-case/recorder.ts
|
|
30761
30746
|
function startRunCaseRecorder(opts) {
|
|
30762
30747
|
const now = opts.now ?? Date.now;
|
|
30763
|
-
const dir =
|
|
30748
|
+
const dir = import_node_path46.default.dirname(opts.recordPath);
|
|
30764
30749
|
let stream = null;
|
|
30765
30750
|
let closing = false;
|
|
30766
30751
|
let closedSettled = false;
|
|
@@ -30800,12 +30785,12 @@ function startRunCaseRecorder(opts) {
|
|
|
30800
30785
|
};
|
|
30801
30786
|
return { tap, close, closed };
|
|
30802
30787
|
}
|
|
30803
|
-
var import_node_fs34,
|
|
30788
|
+
var import_node_fs34, import_node_path46;
|
|
30804
30789
|
var init_recorder = __esm({
|
|
30805
30790
|
"src/run-case/recorder.ts"() {
|
|
30806
30791
|
"use strict";
|
|
30807
30792
|
import_node_fs34 = __toESM(require("fs"), 1);
|
|
30808
|
-
|
|
30793
|
+
import_node_path46 = __toESM(require("path"), 1);
|
|
30809
30794
|
}
|
|
30810
30795
|
});
|
|
30811
30796
|
|
|
@@ -30848,7 +30833,7 @@ var init_wire = __esm({
|
|
|
30848
30833
|
// src/run-case/controller.ts
|
|
30849
30834
|
async function runController(opts) {
|
|
30850
30835
|
const now = opts.now ?? Date.now;
|
|
30851
|
-
const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(
|
|
30836
|
+
const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path47.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
|
|
30852
30837
|
const ownsCwd = opts.cwd === void 0;
|
|
30853
30838
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
30854
30839
|
const spawnCtx = { cwd };
|
|
@@ -31015,13 +31000,13 @@ async function runController(opts) {
|
|
|
31015
31000
|
}
|
|
31016
31001
|
return exitCode ?? 0;
|
|
31017
31002
|
}
|
|
31018
|
-
var import_node_fs35,
|
|
31003
|
+
var import_node_fs35, import_node_os19, import_node_path47;
|
|
31019
31004
|
var init_controller = __esm({
|
|
31020
31005
|
"src/run-case/controller.ts"() {
|
|
31021
31006
|
"use strict";
|
|
31022
31007
|
import_node_fs35 = require("fs");
|
|
31023
|
-
|
|
31024
|
-
|
|
31008
|
+
import_node_os19 = __toESM(require("os"), 1);
|
|
31009
|
+
import_node_path47 = __toESM(require("path"), 1);
|
|
31025
31010
|
init_claude();
|
|
31026
31011
|
init_stdout_splitter();
|
|
31027
31012
|
init_permission_stdio();
|
|
@@ -31256,7 +31241,7 @@ Env (advanced):
|
|
|
31256
31241
|
`;
|
|
31257
31242
|
|
|
31258
31243
|
// src/index.ts
|
|
31259
|
-
var
|
|
31244
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
31260
31245
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
31261
31246
|
|
|
31262
31247
|
// src/logger.ts
|
|
@@ -32601,7 +32586,7 @@ var SessionRunner = class {
|
|
|
32601
32586
|
this.input({ kind: "inject-events", events });
|
|
32602
32587
|
}
|
|
32603
32588
|
// session:interrupt 的 SDK 通道分流:codex → AgentSession.interrupt();claude → control_request('interrupt')。
|
|
32604
|
-
// TUI(pty) 路径在 manager.
|
|
32589
|
+
// TUI(pty) 路径在 manager.interrupt() 里先走 stop() SIGKILL,不进这里。
|
|
32605
32590
|
async interrupt() {
|
|
32606
32591
|
if (this.session) {
|
|
32607
32592
|
this.session.interrupt();
|
|
@@ -33678,50 +33663,12 @@ var SessionManager = class {
|
|
|
33678
33663
|
return this.stop({ sessionId: args.sessionId });
|
|
33679
33664
|
}
|
|
33680
33665
|
try {
|
|
33681
|
-
await
|
|
33666
|
+
await runner.interrupt();
|
|
33682
33667
|
} catch (err) {
|
|
33683
33668
|
throw new ClawdError(ERROR_CODES.INTERNAL, err.message);
|
|
33684
33669
|
}
|
|
33685
33670
|
return { response: { ok: true }, broadcast: [] };
|
|
33686
33671
|
}
|
|
33687
|
-
// 同时被 interrupt / cancelQuestion 调用:按模式选 interrupt 通道。TUI 优先 pty,
|
|
33688
|
-
// 否则 fallback 到 SDK 的 control_request(包括 mode='tui' 但 pty 未 register 的边角场景)。
|
|
33689
|
-
async dispatchInterrupt(runner) {
|
|
33690
|
-
const sid = runner.getState().file.sessionId;
|
|
33691
|
-
const tsid = runner.getState().file.toolSessionId;
|
|
33692
|
-
const pty = tsid ? this.ptyTransports.get(tsid) : void 0;
|
|
33693
|
-
const stateBefore = runner.getState();
|
|
33694
|
-
this.deps.logger?.info("[BUG-HUNT-INTERRUPT] dispatchInterrupt enter", {
|
|
33695
|
-
sessionId: sid,
|
|
33696
|
-
tsid,
|
|
33697
|
-
ptyHit: Boolean(pty),
|
|
33698
|
-
mode: this.deps.mode,
|
|
33699
|
-
turnOpenBefore: stateBefore.turnOpen,
|
|
33700
|
-
procAlive: stateBefore.procAlive,
|
|
33701
|
-
bufferLen: stateBefore.buffer.length
|
|
33702
|
-
});
|
|
33703
|
-
if (pty) {
|
|
33704
|
-
pty.write("\x1B");
|
|
33705
|
-
this.deps.logger?.info("[BUG-HUNT-INTERRUPT] pty.write ESC done", { sessionId: sid });
|
|
33706
|
-
runner.input({ kind: "inject-events", events: [{ kind: "turn_end" }] });
|
|
33707
|
-
const stateAfter = runner.getState();
|
|
33708
|
-
const lastEvent = stateAfter.buffer[stateAfter.buffer.length - 1];
|
|
33709
|
-
this.deps.logger?.info("[BUG-HUNT-INTERRUPT] after inject turn_end", {
|
|
33710
|
-
sessionId: sid,
|
|
33711
|
-
turnOpenAfter: stateAfter.turnOpen,
|
|
33712
|
-
bufferLen: stateAfter.buffer.length,
|
|
33713
|
-
lastEventKind: lastEvent?.event?.kind,
|
|
33714
|
-
lastEventSeq: lastEvent?.seq
|
|
33715
|
-
});
|
|
33716
|
-
return;
|
|
33717
|
-
}
|
|
33718
|
-
this.deps.logger?.warn("[BUG-HUNT-INTERRUPT] SDK fallback path (pty not registered)", {
|
|
33719
|
-
sessionId: sid,
|
|
33720
|
-
tsid,
|
|
33721
|
-
mode: this.deps.mode
|
|
33722
|
-
});
|
|
33723
|
-
await runner.interrupt();
|
|
33724
|
-
}
|
|
33725
33672
|
// 批量版本:UI 打开 session 时一次性拿到"磁盘和快照有差异"的 user message id 集合,
|
|
33726
33673
|
// 用来在消息流里精准控制 rewind 按钮的显示。session 没 toolSessionId 时返回空
|
|
33727
33674
|
rewindableMessageIds(args) {
|
|
@@ -34267,7 +34214,7 @@ var SessionManager = class {
|
|
|
34267
34214
|
runner.input({ kind: "cancel-question", toolUseId: args.toolUseId });
|
|
34268
34215
|
});
|
|
34269
34216
|
if (runner.getState().procAlive) {
|
|
34270
|
-
void
|
|
34217
|
+
void runner.interrupt().catch(() => {
|
|
34271
34218
|
});
|
|
34272
34219
|
}
|
|
34273
34220
|
return { response: { ok: true }, broadcast };
|
|
@@ -35588,8 +35535,8 @@ function turnStartInput(text) {
|
|
|
35588
35535
|
const items = [];
|
|
35589
35536
|
let leftover = text;
|
|
35590
35537
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
35591
|
-
const [marker, name,
|
|
35592
|
-
items.push({ type: "skill", name, path:
|
|
35538
|
+
const [marker, name, path58] = m2;
|
|
35539
|
+
items.push({ type: "skill", name, path: path58 });
|
|
35593
35540
|
leftover = leftover.replace(marker, "");
|
|
35594
35541
|
}
|
|
35595
35542
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -35648,6 +35595,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
35648
35595
|
]);
|
|
35649
35596
|
return;
|
|
35650
35597
|
}
|
|
35598
|
+
deps.logger?.warn("codex unknown server-request auto-cancelled", { method });
|
|
35651
35599
|
client.respond(id, "cancel");
|
|
35652
35600
|
},
|
|
35653
35601
|
onClose: () => finish(proc.exitCode)
|
|
@@ -35821,8 +35769,8 @@ var CodexAdapter = class {
|
|
|
35821
35769
|
|
|
35822
35770
|
// src/tools/claude-tui.ts
|
|
35823
35771
|
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
35824
|
-
var
|
|
35825
|
-
var
|
|
35772
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
35773
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
35826
35774
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
35827
35775
|
|
|
35828
35776
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -36801,8 +36749,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
36801
36749
|
}
|
|
36802
36750
|
function jsonlExistsForCtx(ctx) {
|
|
36803
36751
|
if (!ctx.toolSessionId) return false;
|
|
36804
|
-
const home =
|
|
36805
|
-
const file =
|
|
36752
|
+
const home = import_node_os5.default.homedir();
|
|
36753
|
+
const file = import_node_path9.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
36806
36754
|
try {
|
|
36807
36755
|
return import_node_fs11.default.statSync(file).isFile();
|
|
36808
36756
|
} catch {
|
|
@@ -36999,13 +36947,13 @@ function mapSkillsListResponse(res) {
|
|
|
36999
36947
|
const r = s ?? {};
|
|
37000
36948
|
const name = str3(r.name);
|
|
37001
36949
|
if (!name) continue;
|
|
37002
|
-
const
|
|
36950
|
+
const path58 = str3(r.path);
|
|
37003
36951
|
const description = str3(r.description);
|
|
37004
36952
|
const isPlugin = name.includes(":");
|
|
37005
36953
|
out.push({
|
|
37006
36954
|
name,
|
|
37007
36955
|
source: isPlugin ? "plugin" : "project",
|
|
37008
|
-
...
|
|
36956
|
+
...path58 ? { path: path58 } : {},
|
|
37009
36957
|
...description ? { description } : {},
|
|
37010
36958
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
37011
36959
|
});
|
|
@@ -37045,15 +36993,15 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
37045
36993
|
|
|
37046
36994
|
// src/workspace/browser.ts
|
|
37047
36995
|
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
37048
|
-
var
|
|
37049
|
-
var
|
|
36996
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
36997
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
37050
36998
|
init_protocol();
|
|
37051
36999
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
37052
37000
|
function resolveInsideCwd(cwd, subpath) {
|
|
37053
|
-
const absCwd =
|
|
37054
|
-
const joined =
|
|
37055
|
-
const rel =
|
|
37056
|
-
if (rel.startsWith("..") ||
|
|
37001
|
+
const absCwd = import_node_path10.default.resolve(cwd);
|
|
37002
|
+
const joined = import_node_path10.default.resolve(absCwd, subpath ?? ".");
|
|
37003
|
+
const rel = import_node_path10.default.relative(absCwd, joined);
|
|
37004
|
+
if (rel.startsWith("..") || import_node_path10.default.isAbsolute(rel)) {
|
|
37057
37005
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
37058
37006
|
}
|
|
37059
37007
|
return joined;
|
|
@@ -37071,7 +37019,7 @@ function ensureCwd(cwd) {
|
|
|
37071
37019
|
}
|
|
37072
37020
|
var WorkspaceBrowser = class {
|
|
37073
37021
|
list(args) {
|
|
37074
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
37022
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
|
|
37075
37023
|
ensureCwd(cwd);
|
|
37076
37024
|
const full = resolveInsideCwd(cwd, args.path);
|
|
37077
37025
|
const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
|
|
@@ -37084,7 +37032,7 @@ var WorkspaceBrowser = class {
|
|
|
37084
37032
|
mtime: ""
|
|
37085
37033
|
};
|
|
37086
37034
|
try {
|
|
37087
|
-
const st = import_node_fs12.default.statSync(
|
|
37035
|
+
const st = import_node_fs12.default.statSync(import_node_path10.default.join(full, d.name));
|
|
37088
37036
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
37089
37037
|
if (d.isFile()) entry.size = st.size;
|
|
37090
37038
|
} catch {
|
|
@@ -37130,8 +37078,8 @@ var WorkspaceBrowser = class {
|
|
|
37130
37078
|
|
|
37131
37079
|
// src/skills/agents-scanner.ts
|
|
37132
37080
|
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
37133
|
-
var
|
|
37134
|
-
var
|
|
37081
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
37082
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
37135
37083
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
37136
37084
|
function isDirLikeSync2(p2) {
|
|
37137
37085
|
try {
|
|
@@ -37169,10 +37117,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
37169
37117
|
}
|
|
37170
37118
|
for (const ent of entries) {
|
|
37171
37119
|
if (!ent.name.endsWith(".md")) continue;
|
|
37172
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
37120
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path11.default.join(dir, ent.name)))) {
|
|
37173
37121
|
continue;
|
|
37174
37122
|
}
|
|
37175
|
-
const filePath =
|
|
37123
|
+
const filePath = import_node_path11.default.join(dir, ent.name);
|
|
37176
37124
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
37177
37125
|
if (seen.has(baseName)) continue;
|
|
37178
37126
|
seen.add(baseName);
|
|
@@ -37195,7 +37143,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
37195
37143
|
return;
|
|
37196
37144
|
}
|
|
37197
37145
|
for (const ent of entries) {
|
|
37198
|
-
const childPath =
|
|
37146
|
+
const childPath = import_node_path11.default.join(dir, ent.name);
|
|
37199
37147
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
37200
37148
|
walk2(childPath, [...namespaces, ent.name]);
|
|
37201
37149
|
continue;
|
|
@@ -37220,9 +37168,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
37220
37168
|
walk2(root, []);
|
|
37221
37169
|
}
|
|
37222
37170
|
function readInstalledPlugins2(home) {
|
|
37223
|
-
const pluginsDir =
|
|
37224
|
-
const v2 =
|
|
37225
|
-
const v1 =
|
|
37171
|
+
const pluginsDir = import_node_path11.default.join(home, ".claude", "plugins");
|
|
37172
|
+
const v2 = import_node_path11.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
37173
|
+
const v1 = import_node_path11.default.join(pluginsDir, "installed_plugins.json");
|
|
37226
37174
|
let raw = null;
|
|
37227
37175
|
for (const candidate of [v2, v1]) {
|
|
37228
37176
|
try {
|
|
@@ -37251,19 +37199,19 @@ function readInstalledPlugins2(home) {
|
|
|
37251
37199
|
return out;
|
|
37252
37200
|
}
|
|
37253
37201
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
37254
|
-
let cur =
|
|
37255
|
-
const fsRoot =
|
|
37202
|
+
let cur = import_node_path11.default.resolve(startCwd);
|
|
37203
|
+
const fsRoot = import_node_path11.default.parse(cur).root;
|
|
37256
37204
|
while (true) {
|
|
37257
|
-
scanAgentsDir(
|
|
37205
|
+
scanAgentsDir(import_node_path11.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
37258
37206
|
let hasGit = false;
|
|
37259
37207
|
try {
|
|
37260
|
-
hasGit = import_node_fs13.default.existsSync(
|
|
37208
|
+
hasGit = import_node_fs13.default.existsSync(import_node_path11.default.join(cur, ".git"));
|
|
37261
37209
|
} catch {
|
|
37262
37210
|
}
|
|
37263
37211
|
if (hasGit) return;
|
|
37264
37212
|
if (cur === home) return;
|
|
37265
37213
|
if (cur === fsRoot) return;
|
|
37266
|
-
const parent =
|
|
37214
|
+
const parent = import_node_path11.default.dirname(cur);
|
|
37267
37215
|
if (parent === cur) return;
|
|
37268
37216
|
cur = parent;
|
|
37269
37217
|
}
|
|
@@ -37273,7 +37221,7 @@ var AgentsScanner = class {
|
|
|
37273
37221
|
extraPluginRoots;
|
|
37274
37222
|
policyDir;
|
|
37275
37223
|
constructor(opts = {}) {
|
|
37276
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
37224
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os7.default.homedir();
|
|
37277
37225
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
37278
37226
|
if (opts.policyDir !== void 0) {
|
|
37279
37227
|
this.policyDir = opts.policyDir;
|
|
@@ -37298,7 +37246,7 @@ var AgentsScanner = class {
|
|
|
37298
37246
|
}
|
|
37299
37247
|
const fsBlock = [];
|
|
37300
37248
|
scanAgentsDir(
|
|
37301
|
-
|
|
37249
|
+
import_node_path11.default.join(this.home, ".claude", "agents"),
|
|
37302
37250
|
"global",
|
|
37303
37251
|
seen,
|
|
37304
37252
|
fsBlock
|
|
@@ -37312,7 +37260,7 @@ var AgentsScanner = class {
|
|
|
37312
37260
|
...this.extraPluginRoots
|
|
37313
37261
|
];
|
|
37314
37262
|
for (const { name, root } of plugins) {
|
|
37315
|
-
const agentsRoot =
|
|
37263
|
+
const agentsRoot = import_node_path11.default.join(root, "agents");
|
|
37316
37264
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
37317
37265
|
}
|
|
37318
37266
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -37321,27 +37269,27 @@ var AgentsScanner = class {
|
|
|
37321
37269
|
|
|
37322
37270
|
// src/observer/session-observer.ts
|
|
37323
37271
|
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
37324
|
-
var
|
|
37325
|
-
var
|
|
37272
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
37273
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
37326
37274
|
init_claude_history();
|
|
37327
37275
|
|
|
37328
37276
|
// src/observer/subagent-meta-observer.ts
|
|
37329
37277
|
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
37330
|
-
var
|
|
37331
|
-
var
|
|
37278
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
37279
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
37332
37280
|
init_claude_history();
|
|
37333
37281
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
37334
37282
|
var SubagentMetaObserver = class {
|
|
37335
37283
|
constructor(opts) {
|
|
37336
37284
|
this.opts = opts;
|
|
37337
|
-
this.home = opts.home ??
|
|
37285
|
+
this.home = opts.home ?? import_node_os8.default.homedir();
|
|
37338
37286
|
}
|
|
37339
37287
|
opts;
|
|
37340
37288
|
home;
|
|
37341
37289
|
watches = /* @__PURE__ */ new Map();
|
|
37342
37290
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
37343
37291
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
37344
|
-
return
|
|
37292
|
+
return import_node_path12.default.join(
|
|
37345
37293
|
this.home,
|
|
37346
37294
|
".claude",
|
|
37347
37295
|
"projects",
|
|
@@ -37397,7 +37345,7 @@ var SubagentMetaObserver = class {
|
|
|
37397
37345
|
if (!m2) return;
|
|
37398
37346
|
const agentId = m2[1];
|
|
37399
37347
|
if (w2.emitted.has(agentId)) return;
|
|
37400
|
-
const file =
|
|
37348
|
+
const file = import_node_path12.default.join(w2.dirPath, name);
|
|
37401
37349
|
let raw;
|
|
37402
37350
|
try {
|
|
37403
37351
|
raw = import_node_fs14.default.readFileSync(file, "utf8");
|
|
@@ -37445,7 +37393,7 @@ var SubagentMetaObserver = class {
|
|
|
37445
37393
|
var SessionObserver = class {
|
|
37446
37394
|
constructor(opts) {
|
|
37447
37395
|
this.opts = opts;
|
|
37448
|
-
this.home = opts.home ??
|
|
37396
|
+
this.home = opts.home ?? import_node_os9.default.homedir();
|
|
37449
37397
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
37450
37398
|
}
|
|
37451
37399
|
opts;
|
|
@@ -37457,7 +37405,7 @@ var SessionObserver = class {
|
|
|
37457
37405
|
metaObserver;
|
|
37458
37406
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
37459
37407
|
if (override) return override;
|
|
37460
|
-
return
|
|
37408
|
+
return import_node_path13.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
37461
37409
|
}
|
|
37462
37410
|
start(args) {
|
|
37463
37411
|
this.stop(args.sessionId);
|
|
@@ -37478,10 +37426,10 @@ var SessionObserver = class {
|
|
|
37478
37426
|
prevIsRejectSentinel: false
|
|
37479
37427
|
};
|
|
37480
37428
|
try {
|
|
37481
|
-
import_node_fs15.default.mkdirSync(
|
|
37429
|
+
import_node_fs15.default.mkdirSync(import_node_path13.default.dirname(filePath), { recursive: true });
|
|
37482
37430
|
} catch {
|
|
37483
37431
|
}
|
|
37484
|
-
w2.watcher = import_node_fs15.default.watch(
|
|
37432
|
+
w2.watcher = import_node_fs15.default.watch(import_node_path13.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
37485
37433
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
37486
37434
|
this.poll(w2);
|
|
37487
37435
|
});
|
|
@@ -38288,7 +38236,7 @@ async function authenticate(token, deps) {
|
|
|
38288
38236
|
|
|
38289
38237
|
// src/permission/capability-store.ts
|
|
38290
38238
|
var fs18 = __toESM(require("fs"), 1);
|
|
38291
|
-
var
|
|
38239
|
+
var path18 = __toESM(require("path"), 1);
|
|
38292
38240
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
38293
38241
|
var FILE_VERSION = 1;
|
|
38294
38242
|
var CapabilityStore = class {
|
|
@@ -38318,7 +38266,7 @@ var CapabilityStore = class {
|
|
|
38318
38266
|
this.flush();
|
|
38319
38267
|
}
|
|
38320
38268
|
filePath() {
|
|
38321
|
-
return
|
|
38269
|
+
return path18.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
38322
38270
|
}
|
|
38323
38271
|
readFromDisk() {
|
|
38324
38272
|
const file = this.filePath();
|
|
@@ -38465,7 +38413,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
38465
38413
|
|
|
38466
38414
|
// src/inbox/inbox-store.ts
|
|
38467
38415
|
var fs20 = __toESM(require("fs"), 1);
|
|
38468
|
-
var
|
|
38416
|
+
var path19 = __toESM(require("path"), 1);
|
|
38469
38417
|
var INBOX_SUBDIR = "inbox";
|
|
38470
38418
|
var InboxStore = class {
|
|
38471
38419
|
constructor(dataDir) {
|
|
@@ -38563,10 +38511,10 @@ var InboxStore = class {
|
|
|
38563
38511
|
}
|
|
38564
38512
|
}
|
|
38565
38513
|
dirPath() {
|
|
38566
|
-
return
|
|
38514
|
+
return path19.join(this.dataDir, INBOX_SUBDIR);
|
|
38567
38515
|
}
|
|
38568
38516
|
filePath(peerDeviceId) {
|
|
38569
|
-
return
|
|
38517
|
+
return path19.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
38570
38518
|
}
|
|
38571
38519
|
};
|
|
38572
38520
|
function parseAllLines(raw) {
|
|
@@ -38654,7 +38602,7 @@ var InboxManager = class {
|
|
|
38654
38602
|
|
|
38655
38603
|
// src/state/contact-store.ts
|
|
38656
38604
|
var fs21 = __toESM(require("fs"), 1);
|
|
38657
|
-
var
|
|
38605
|
+
var path20 = __toESM(require("path"), 1);
|
|
38658
38606
|
var FILE_NAME = "contacts.json";
|
|
38659
38607
|
var ContactStore = class {
|
|
38660
38608
|
constructor(dataDir) {
|
|
@@ -38664,7 +38612,7 @@ var ContactStore = class {
|
|
|
38664
38612
|
contacts = /* @__PURE__ */ new Map();
|
|
38665
38613
|
load() {
|
|
38666
38614
|
this.contacts.clear();
|
|
38667
|
-
const file =
|
|
38615
|
+
const file = path20.join(this.dataDir, FILE_NAME);
|
|
38668
38616
|
let raw;
|
|
38669
38617
|
try {
|
|
38670
38618
|
raw = fs21.readFileSync(file, "utf8");
|
|
@@ -38710,7 +38658,7 @@ var ContactStore = class {
|
|
|
38710
38658
|
return existed;
|
|
38711
38659
|
}
|
|
38712
38660
|
flush() {
|
|
38713
|
-
const file =
|
|
38661
|
+
const file = path20.join(this.dataDir, FILE_NAME);
|
|
38714
38662
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
38715
38663
|
const content = JSON.stringify(
|
|
38716
38664
|
{ contacts: Array.from(this.contacts.values()) },
|
|
@@ -38874,52 +38822,52 @@ async function autoReverseContact(args) {
|
|
|
38874
38822
|
|
|
38875
38823
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
38876
38824
|
var fs22 = __toESM(require("fs"), 1);
|
|
38877
|
-
var
|
|
38825
|
+
var path21 = __toESM(require("path"), 1);
|
|
38878
38826
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
38879
38827
|
function migrateFlattenSessions(opts) {
|
|
38880
38828
|
const dataDir = opts.dataDir;
|
|
38881
38829
|
const now = opts.now ?? Date.now;
|
|
38882
|
-
const sessionsDir =
|
|
38883
|
-
const flagPath =
|
|
38830
|
+
const sessionsDir = path21.join(dataDir, "sessions");
|
|
38831
|
+
const flagPath = path21.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
38884
38832
|
if (existsSync3(flagPath)) {
|
|
38885
38833
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
38886
38834
|
}
|
|
38887
38835
|
let movedBare = 0;
|
|
38888
38836
|
let movedVmOwner = 0;
|
|
38889
38837
|
let archivedListener = 0;
|
|
38890
|
-
const defaultDir =
|
|
38838
|
+
const defaultDir = path21.join(sessionsDir, "default");
|
|
38891
38839
|
if (existsSync3(defaultDir)) {
|
|
38892
38840
|
for (const entry of readdirSafe(defaultDir)) {
|
|
38893
38841
|
if (!entry.endsWith(".json")) continue;
|
|
38894
|
-
const src =
|
|
38895
|
-
const dst =
|
|
38842
|
+
const src = path21.join(defaultDir, entry);
|
|
38843
|
+
const dst = path21.join(sessionsDir, entry);
|
|
38896
38844
|
fs22.renameSync(src, dst);
|
|
38897
38845
|
movedBare += 1;
|
|
38898
38846
|
}
|
|
38899
38847
|
rmdirIfEmpty(defaultDir);
|
|
38900
38848
|
}
|
|
38901
38849
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
38902
|
-
const personaDir =
|
|
38850
|
+
const personaDir = path21.join(sessionsDir, pid);
|
|
38903
38851
|
if (!isDir(personaDir)) continue;
|
|
38904
38852
|
if (pid === "default") continue;
|
|
38905
|
-
const ownerSrc =
|
|
38853
|
+
const ownerSrc = path21.join(personaDir, "owner");
|
|
38906
38854
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
38907
|
-
const ownerDst =
|
|
38855
|
+
const ownerDst = path21.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
38908
38856
|
fs22.mkdirSync(ownerDst, { recursive: true });
|
|
38909
38857
|
for (const file of readdirSafe(ownerSrc)) {
|
|
38910
38858
|
if (!file.endsWith(".json")) continue;
|
|
38911
|
-
fs22.renameSync(
|
|
38859
|
+
fs22.renameSync(path21.join(ownerSrc, file), path21.join(ownerDst, file));
|
|
38912
38860
|
movedVmOwner += 1;
|
|
38913
38861
|
}
|
|
38914
38862
|
rmdirIfEmpty(ownerSrc);
|
|
38915
38863
|
}
|
|
38916
|
-
const listenerSrc =
|
|
38864
|
+
const listenerSrc = path21.join(personaDir, "listener");
|
|
38917
38865
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
38918
|
-
const archiveDst =
|
|
38866
|
+
const archiveDst = path21.join(dataDir, ".legacy", `listener-${pid}`);
|
|
38919
38867
|
fs22.mkdirSync(archiveDst, { recursive: true });
|
|
38920
38868
|
for (const file of readdirSafe(listenerSrc)) {
|
|
38921
38869
|
if (!file.endsWith(".json")) continue;
|
|
38922
|
-
fs22.renameSync(
|
|
38870
|
+
fs22.renameSync(path21.join(listenerSrc, file), path21.join(archiveDst, file));
|
|
38923
38871
|
archivedListener += 1;
|
|
38924
38872
|
}
|
|
38925
38873
|
rmdirIfEmpty(listenerSrc);
|
|
@@ -38967,10 +38915,10 @@ function rmdirIfEmpty(p2) {
|
|
|
38967
38915
|
|
|
38968
38916
|
// src/transport/http-router.ts
|
|
38969
38917
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
38970
|
-
var
|
|
38918
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
38971
38919
|
|
|
38972
38920
|
// src/attachment/mime.ts
|
|
38973
|
-
var
|
|
38921
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
38974
38922
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
38975
38923
|
var EXT_TO_NATIVE_MIME = {
|
|
38976
38924
|
// 图片
|
|
@@ -39077,7 +39025,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
39077
39025
|
".mk"
|
|
39078
39026
|
]);
|
|
39079
39027
|
function lookupMime(filePathOrName) {
|
|
39080
|
-
const ext =
|
|
39028
|
+
const ext = import_node_path14.default.extname(filePathOrName).toLowerCase();
|
|
39081
39029
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
39082
39030
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
39083
39031
|
return "application/octet-stream";
|
|
@@ -39147,7 +39095,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
39147
39095
|
|
|
39148
39096
|
// src/attachment/upload.ts
|
|
39149
39097
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
39150
|
-
var
|
|
39098
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
39151
39099
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
39152
39100
|
var import_promises = require("stream/promises");
|
|
39153
39101
|
var UploadError = class extends Error {
|
|
@@ -39159,14 +39107,14 @@ var UploadError = class extends Error {
|
|
|
39159
39107
|
code;
|
|
39160
39108
|
};
|
|
39161
39109
|
function assertValidFileName(fileName) {
|
|
39162
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
39110
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path15.default.basename(fileName)) {
|
|
39163
39111
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
39164
39112
|
}
|
|
39165
39113
|
}
|
|
39166
39114
|
var HASH_PREFIX_LEN = 16;
|
|
39167
39115
|
async function writeUploadedAttachment(args) {
|
|
39168
39116
|
assertValidFileName(args.fileName);
|
|
39169
|
-
const attachmentsRoot =
|
|
39117
|
+
const attachmentsRoot = import_node_path15.default.join(args.sessionDir, ".attachments");
|
|
39170
39118
|
try {
|
|
39171
39119
|
import_node_fs16.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
39172
39120
|
} catch (err) {
|
|
@@ -39174,7 +39122,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39174
39122
|
}
|
|
39175
39123
|
const hasher = import_node_crypto5.default.createHash("sha256");
|
|
39176
39124
|
let actualSize = 0;
|
|
39177
|
-
const tmpPath =
|
|
39125
|
+
const tmpPath = import_node_path15.default.join(
|
|
39178
39126
|
attachmentsRoot,
|
|
39179
39127
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto5.default.randomBytes(4).toString("hex")}`
|
|
39180
39128
|
);
|
|
@@ -39209,7 +39157,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39209
39157
|
);
|
|
39210
39158
|
}
|
|
39211
39159
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
39212
|
-
const hashDir =
|
|
39160
|
+
const hashDir = import_node_path15.default.join(attachmentsRoot, attachmentId);
|
|
39213
39161
|
let finalFileName;
|
|
39214
39162
|
let hashDirExists = false;
|
|
39215
39163
|
try {
|
|
@@ -39227,7 +39175,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39227
39175
|
try {
|
|
39228
39176
|
import_node_fs16.default.mkdirSync(hashDir, { recursive: true });
|
|
39229
39177
|
finalFileName = args.fileName;
|
|
39230
|
-
import_node_fs16.default.renameSync(tmpPath,
|
|
39178
|
+
import_node_fs16.default.renameSync(tmpPath, import_node_path15.default.join(hashDir, finalFileName));
|
|
39231
39179
|
} catch (err) {
|
|
39232
39180
|
try {
|
|
39233
39181
|
import_node_fs16.default.unlinkSync(tmpPath);
|
|
@@ -39236,8 +39184,8 @@ async function writeUploadedAttachment(args) {
|
|
|
39236
39184
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
39237
39185
|
}
|
|
39238
39186
|
}
|
|
39239
|
-
const absPath =
|
|
39240
|
-
const relPath =
|
|
39187
|
+
const absPath = import_node_path15.default.join(hashDir, finalFileName);
|
|
39188
|
+
const relPath = import_node_path15.default.relative(args.sessionDir, absPath);
|
|
39241
39189
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
39242
39190
|
relPath: absPath,
|
|
39243
39191
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -39251,8 +39199,8 @@ async function writeUploadedAttachment(args) {
|
|
|
39251
39199
|
|
|
39252
39200
|
// src/extension/import.ts
|
|
39253
39201
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
39254
|
-
var
|
|
39255
|
-
var
|
|
39202
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
39203
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
39256
39204
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
39257
39205
|
var ImportError = class extends Error {
|
|
39258
39206
|
constructor(code, message) {
|
|
@@ -39269,7 +39217,7 @@ async function importZip(buf, root) {
|
|
|
39269
39217
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
39270
39218
|
}
|
|
39271
39219
|
for (const name of Object.keys(zip.files)) {
|
|
39272
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
39220
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path16.default.isAbsolute(name)) {
|
|
39273
39221
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
39274
39222
|
}
|
|
39275
39223
|
}
|
|
@@ -39302,7 +39250,7 @@ async function importZip(buf, root) {
|
|
|
39302
39250
|
);
|
|
39303
39251
|
}
|
|
39304
39252
|
}
|
|
39305
|
-
const destDir =
|
|
39253
|
+
const destDir = import_node_path16.default.join(root, manifest.id);
|
|
39306
39254
|
let destExists = false;
|
|
39307
39255
|
try {
|
|
39308
39256
|
await import_promises2.default.access(destDir);
|
|
@@ -39312,15 +39260,15 @@ async function importZip(buf, root) {
|
|
|
39312
39260
|
if (destExists) {
|
|
39313
39261
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
39314
39262
|
}
|
|
39315
|
-
const stage = await import_promises2.default.mkdtemp(
|
|
39263
|
+
const stage = await import_promises2.default.mkdtemp(import_node_path16.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
39316
39264
|
try {
|
|
39317
39265
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
39318
|
-
const dest =
|
|
39266
|
+
const dest = import_node_path16.default.join(stage, name);
|
|
39319
39267
|
if (entry.dir) {
|
|
39320
39268
|
await import_promises2.default.mkdir(dest, { recursive: true });
|
|
39321
39269
|
continue;
|
|
39322
39270
|
}
|
|
39323
|
-
await import_promises2.default.mkdir(
|
|
39271
|
+
await import_promises2.default.mkdir(import_node_path16.default.dirname(dest), { recursive: true });
|
|
39324
39272
|
const content = await entry.async("nodebuffer");
|
|
39325
39273
|
await import_promises2.default.writeFile(dest, content);
|
|
39326
39274
|
}
|
|
@@ -39434,7 +39382,7 @@ function isValidUploadFileName(fileName) {
|
|
|
39434
39382
|
if (fileName === "." || fileName === "..") return false;
|
|
39435
39383
|
if (fileName.startsWith(".")) return false;
|
|
39436
39384
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
39437
|
-
return fileName ===
|
|
39385
|
+
return fileName === import_node_path17.default.basename(fileName);
|
|
39438
39386
|
}
|
|
39439
39387
|
function createHttpRouter(deps) {
|
|
39440
39388
|
return async (req, res) => {
|
|
@@ -39663,7 +39611,7 @@ function createHttpRouter(deps) {
|
|
|
39663
39611
|
return true;
|
|
39664
39612
|
}
|
|
39665
39613
|
let absPath;
|
|
39666
|
-
if (
|
|
39614
|
+
if (import_node_path17.default.isAbsolute(pathParam)) {
|
|
39667
39615
|
absPath = pathParam;
|
|
39668
39616
|
} else if (deps.sessionStore) {
|
|
39669
39617
|
const file = deps.sessionStore.read(sid);
|
|
@@ -39671,7 +39619,7 @@ function createHttpRouter(deps) {
|
|
|
39671
39619
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
39672
39620
|
return true;
|
|
39673
39621
|
}
|
|
39674
|
-
absPath =
|
|
39622
|
+
absPath = import_node_path17.default.join(file.cwd, pathParam);
|
|
39675
39623
|
} else {
|
|
39676
39624
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
39677
39625
|
return true;
|
|
@@ -39769,7 +39717,7 @@ function streamFile(res, absPath, logger) {
|
|
|
39769
39717
|
return;
|
|
39770
39718
|
}
|
|
39771
39719
|
const mime = lookupMime(absPath);
|
|
39772
|
-
const basename =
|
|
39720
|
+
const basename = import_node_path17.default.basename(absPath);
|
|
39773
39721
|
res.writeHead(200, {
|
|
39774
39722
|
"Content-Type": mime,
|
|
39775
39723
|
"Content-Length": String(stat.size),
|
|
@@ -39787,7 +39735,7 @@ function streamFile(res, absPath, logger) {
|
|
|
39787
39735
|
|
|
39788
39736
|
// src/attachment/gc.ts
|
|
39789
39737
|
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
39790
|
-
var
|
|
39738
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
39791
39739
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
39792
39740
|
function runAttachmentGc(args) {
|
|
39793
39741
|
const now = (args.now ?? Date.now)();
|
|
@@ -39796,17 +39744,17 @@ function runAttachmentGc(args) {
|
|
|
39796
39744
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
39797
39745
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
39798
39746
|
if (entry.stale) continue;
|
|
39799
|
-
if (
|
|
39747
|
+
if (import_node_path18.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
39800
39748
|
}
|
|
39801
39749
|
}
|
|
39802
39750
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
39803
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
39751
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path18.default.join(
|
|
39804
39752
|
args.dataDir,
|
|
39805
39753
|
"sessions",
|
|
39806
39754
|
...scopeSubPath(scope).map(safeFileName),
|
|
39807
39755
|
safeFileName(sessionId)
|
|
39808
39756
|
);
|
|
39809
|
-
const attRoot =
|
|
39757
|
+
const attRoot = import_node_path18.default.join(sessionDir, ".attachments");
|
|
39810
39758
|
let hashDirs;
|
|
39811
39759
|
try {
|
|
39812
39760
|
hashDirs = import_node_fs18.default.readdirSync(attRoot);
|
|
@@ -39816,7 +39764,7 @@ function runAttachmentGc(args) {
|
|
|
39816
39764
|
continue;
|
|
39817
39765
|
}
|
|
39818
39766
|
for (const hashDir of hashDirs) {
|
|
39819
|
-
const hashDirAbs =
|
|
39767
|
+
const hashDirAbs = import_node_path18.default.join(attRoot, hashDir);
|
|
39820
39768
|
let files;
|
|
39821
39769
|
try {
|
|
39822
39770
|
files = import_node_fs18.default.readdirSync(hashDirAbs);
|
|
@@ -39824,7 +39772,7 @@ function runAttachmentGc(args) {
|
|
|
39824
39772
|
continue;
|
|
39825
39773
|
}
|
|
39826
39774
|
for (const name of files) {
|
|
39827
|
-
const file =
|
|
39775
|
+
const file = import_node_path18.default.join(hashDirAbs, name);
|
|
39828
39776
|
let stat;
|
|
39829
39777
|
try {
|
|
39830
39778
|
stat = import_node_fs18.default.statSync(file);
|
|
@@ -39855,7 +39803,7 @@ function runAttachmentGc(args) {
|
|
|
39855
39803
|
|
|
39856
39804
|
// src/attachment/group.ts
|
|
39857
39805
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
39858
|
-
var
|
|
39806
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
39859
39807
|
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
39860
39808
|
init_protocol();
|
|
39861
39809
|
var GroupFileStore = class {
|
|
@@ -39867,11 +39815,11 @@ var GroupFileStore = class {
|
|
|
39867
39815
|
this.logger = opts.logger;
|
|
39868
39816
|
}
|
|
39869
39817
|
rootForScope(scope) {
|
|
39870
|
-
return
|
|
39818
|
+
return import_node_path19.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
39871
39819
|
}
|
|
39872
39820
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
39873
39821
|
filePath(scope, sessionId) {
|
|
39874
|
-
return
|
|
39822
|
+
return import_node_path19.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
39875
39823
|
}
|
|
39876
39824
|
cacheKey(scope, sessionId) {
|
|
39877
39825
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -39906,7 +39854,7 @@ var GroupFileStore = class {
|
|
|
39906
39854
|
}
|
|
39907
39855
|
writeFile(scope, sessionId, entries) {
|
|
39908
39856
|
const file = this.filePath(scope, sessionId);
|
|
39909
|
-
import_node_fs19.default.mkdirSync(
|
|
39857
|
+
import_node_fs19.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
|
|
39910
39858
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
39911
39859
|
import_node_fs19.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
39912
39860
|
import_node_fs19.default.renameSync(tmp, file);
|
|
@@ -39996,9 +39944,9 @@ var GroupFileStore = class {
|
|
|
39996
39944
|
|
|
39997
39945
|
// src/discovery/state-file.ts
|
|
39998
39946
|
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
39999
|
-
var
|
|
39947
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
40000
39948
|
function defaultStateFilePath(dataDir) {
|
|
40001
|
-
return
|
|
39949
|
+
return import_node_path20.default.join(dataDir, "state.json");
|
|
40002
39950
|
}
|
|
40003
39951
|
function isPidAlive(pid) {
|
|
40004
39952
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -40034,7 +39982,7 @@ var StateFileManager = class {
|
|
|
40034
39982
|
return { status: "stale", existing };
|
|
40035
39983
|
}
|
|
40036
39984
|
write(state) {
|
|
40037
|
-
import_node_fs20.default.mkdirSync(
|
|
39985
|
+
import_node_fs20.default.mkdirSync(import_node_path20.default.dirname(this.file), { recursive: true });
|
|
40038
39986
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
40039
39987
|
import_node_fs20.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
40040
39988
|
import_node_fs20.default.renameSync(tmp, this.file);
|
|
@@ -40063,13 +40011,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
40063
40011
|
|
|
40064
40012
|
// src/tunnel/tunnel-manager.ts
|
|
40065
40013
|
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
40066
|
-
var
|
|
40014
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
40067
40015
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
40068
40016
|
var import_node_child_process9 = require("child_process");
|
|
40069
40017
|
|
|
40070
40018
|
// src/tunnel/tunnel-store.ts
|
|
40071
40019
|
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
40072
|
-
var
|
|
40020
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
40073
40021
|
var TunnelStore = class {
|
|
40074
40022
|
constructor(filePath) {
|
|
40075
40023
|
this.filePath = filePath;
|
|
@@ -40088,7 +40036,7 @@ var TunnelStore = class {
|
|
|
40088
40036
|
}
|
|
40089
40037
|
}
|
|
40090
40038
|
async set(v2) {
|
|
40091
|
-
const dir =
|
|
40039
|
+
const dir = import_node_path21.default.dirname(this.filePath);
|
|
40092
40040
|
await import_node_fs21.default.promises.mkdir(dir, { recursive: true });
|
|
40093
40041
|
const data = JSON.stringify(v2, null, 2);
|
|
40094
40042
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -40199,8 +40147,8 @@ function escape(v2) {
|
|
|
40199
40147
|
|
|
40200
40148
|
// src/tunnel/frpc-binary.ts
|
|
40201
40149
|
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
40202
|
-
var
|
|
40203
|
-
var
|
|
40150
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
40151
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
40204
40152
|
var import_node_child_process7 = require("child_process");
|
|
40205
40153
|
var import_node_stream2 = require("stream");
|
|
40206
40154
|
var import_promises3 = require("stream/promises");
|
|
@@ -40239,13 +40187,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
40239
40187
|
}
|
|
40240
40188
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
40241
40189
|
const platform = opts.platform ?? detectPlatform();
|
|
40242
|
-
const binDir =
|
|
40190
|
+
const binDir = import_node_path22.default.join(opts.dataDir, "bin");
|
|
40243
40191
|
import_node_fs22.default.mkdirSync(binDir, { recursive: true });
|
|
40244
40192
|
cleanupStaleArtifacts(binDir);
|
|
40245
|
-
const stableBin =
|
|
40193
|
+
const stableBin = import_node_path22.default.join(binDir, "frpc");
|
|
40246
40194
|
if (import_node_fs22.default.existsSync(stableBin)) return stableBin;
|
|
40247
40195
|
const partialBin = `${stableBin}.partial`;
|
|
40248
|
-
const tarballPath =
|
|
40196
|
+
const tarballPath = import_node_path22.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
40249
40197
|
try {
|
|
40250
40198
|
const url = frpcDownloadUrl(version2, platform);
|
|
40251
40199
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -40271,7 +40219,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
40271
40219
|
}
|
|
40272
40220
|
for (const name of entries) {
|
|
40273
40221
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
40274
|
-
const full =
|
|
40222
|
+
const full = import_node_path22.default.join(binDir, name);
|
|
40275
40223
|
try {
|
|
40276
40224
|
import_node_fs22.default.rmSync(full, { recursive: true, force: true });
|
|
40277
40225
|
} catch {
|
|
@@ -40297,7 +40245,7 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
40297
40245
|
await (0, import_promises3.pipeline)(nodeStream, out);
|
|
40298
40246
|
}
|
|
40299
40247
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
40300
|
-
const work =
|
|
40248
|
+
const work = import_node_path22.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
40301
40249
|
import_node_fs22.default.mkdirSync(work, { recursive: true });
|
|
40302
40250
|
try {
|
|
40303
40251
|
await new Promise((resolve6, reject) => {
|
|
@@ -40306,7 +40254,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
40306
40254
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
40307
40255
|
});
|
|
40308
40256
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
40309
|
-
const src =
|
|
40257
|
+
const src = import_node_path22.default.join(work, dirName, "frpc");
|
|
40310
40258
|
if (!import_node_fs22.default.existsSync(src)) {
|
|
40311
40259
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
40312
40260
|
}
|
|
@@ -40318,10 +40266,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
40318
40266
|
|
|
40319
40267
|
// src/tunnel/frpc-process.ts
|
|
40320
40268
|
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
40321
|
-
var
|
|
40269
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
40322
40270
|
var import_node_child_process8 = require("child_process");
|
|
40323
40271
|
function frpcPidFilePath(dataDir) {
|
|
40324
|
-
return
|
|
40272
|
+
return import_node_path23.default.join(dataDir, "frpc.pid");
|
|
40325
40273
|
}
|
|
40326
40274
|
function writeFrpcPid(dataDir, pid) {
|
|
40327
40275
|
try {
|
|
@@ -40363,7 +40311,7 @@ function defaultSleep(ms) {
|
|
|
40363
40311
|
}
|
|
40364
40312
|
async function killStaleFrpc(deps) {
|
|
40365
40313
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
40366
|
-
const tomlPath =
|
|
40314
|
+
const tomlPath = import_node_path23.default.join(deps.dataDir, "frpc.toml");
|
|
40367
40315
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
40368
40316
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
40369
40317
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -40435,7 +40383,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
40435
40383
|
var TunnelManager = class {
|
|
40436
40384
|
constructor(deps) {
|
|
40437
40385
|
this.deps = deps;
|
|
40438
|
-
this.store = deps.store ?? new TunnelStore(
|
|
40386
|
+
this.store = deps.store ?? new TunnelStore(import_node_path24.default.join(deps.dataDir, "tunnel.json"));
|
|
40439
40387
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
40440
40388
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
40441
40389
|
}
|
|
@@ -40562,7 +40510,7 @@ var TunnelManager = class {
|
|
|
40562
40510
|
dataDir: this.deps.dataDir,
|
|
40563
40511
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
40564
40512
|
});
|
|
40565
|
-
const tomlPath =
|
|
40513
|
+
const tomlPath = import_node_path24.default.join(this.deps.dataDir, "frpc.toml");
|
|
40566
40514
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto7.default.randomBytes(3).toString("hex")}`;
|
|
40567
40515
|
const toml = buildFrpcToml({
|
|
40568
40516
|
serverAddr: t.frpsHost,
|
|
@@ -40577,7 +40525,7 @@ var TunnelManager = class {
|
|
|
40577
40525
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
40578
40526
|
stdio: ["ignore", "pipe", "pipe"]
|
|
40579
40527
|
});
|
|
40580
|
-
const logFilePath =
|
|
40528
|
+
const logFilePath = import_node_path24.default.join(this.deps.dataDir, "frpc.log");
|
|
40581
40529
|
const logStream = import_node_fs24.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
40582
40530
|
logStream.on("error", () => {
|
|
40583
40531
|
});
|
|
@@ -40660,16 +40608,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
40660
40608
|
}
|
|
40661
40609
|
|
|
40662
40610
|
// src/tunnel/device-key.ts
|
|
40663
|
-
var
|
|
40664
|
-
var
|
|
40611
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
40612
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
40665
40613
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
40666
40614
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
40667
40615
|
function deriveStableDeviceKey(opts = {}) {
|
|
40668
|
-
const hostname = opts.hostname ??
|
|
40669
|
-
const uid = opts.uid ?? (typeof
|
|
40670
|
-
const home = opts.home ??
|
|
40671
|
-
const defaultDataDir =
|
|
40672
|
-
const normalizedDataDir = opts.dataDir ?
|
|
40616
|
+
const hostname = opts.hostname ?? import_node_os12.default.hostname();
|
|
40617
|
+
const uid = opts.uid ?? (typeof import_node_os12.default.userInfo === "function" ? import_node_os12.default.userInfo().uid : 0);
|
|
40618
|
+
const home = opts.home ?? import_node_os12.default.homedir();
|
|
40619
|
+
const defaultDataDir = import_node_path25.default.resolve(import_node_path25.default.join(home, ".clawd"));
|
|
40620
|
+
const normalizedDataDir = opts.dataDir ? import_node_path25.default.resolve(opts.dataDir) : null;
|
|
40673
40621
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
40674
40622
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
40675
40623
|
return import_node_crypto8.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
@@ -40677,11 +40625,11 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
40677
40625
|
|
|
40678
40626
|
// src/auth-store.ts
|
|
40679
40627
|
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
40680
|
-
var
|
|
40628
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
40681
40629
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
40682
40630
|
var AUTH_FILE_NAME = "auth.json";
|
|
40683
40631
|
function authFilePath(dataDir) {
|
|
40684
|
-
return
|
|
40632
|
+
return import_node_path26.default.join(dataDir, AUTH_FILE_NAME);
|
|
40685
40633
|
}
|
|
40686
40634
|
function loadOrCreateAuthFile(opts) {
|
|
40687
40635
|
const file = authFilePath(opts.dataDir);
|
|
@@ -40734,7 +40682,7 @@ function readAuthFile(file) {
|
|
|
40734
40682
|
}
|
|
40735
40683
|
}
|
|
40736
40684
|
function writeAuthFile(file, content) {
|
|
40737
|
-
import_node_fs25.default.mkdirSync(
|
|
40685
|
+
import_node_fs25.default.mkdirSync(import_node_path26.default.dirname(file), { recursive: true });
|
|
40738
40686
|
import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
40739
40687
|
try {
|
|
40740
40688
|
import_node_fs25.default.chmodSync(file, 384);
|
|
@@ -40744,12 +40692,12 @@ function writeAuthFile(file, content) {
|
|
|
40744
40692
|
|
|
40745
40693
|
// src/owner-profile.ts
|
|
40746
40694
|
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
40747
|
-
var
|
|
40748
|
-
var
|
|
40695
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
40696
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
40749
40697
|
var PROFILE_FILENAME = "profile.json";
|
|
40750
40698
|
function loadOwnerDisplayName(dataDir) {
|
|
40751
|
-
const fallback =
|
|
40752
|
-
const profilePath =
|
|
40699
|
+
const fallback = import_node_os13.default.userInfo().username;
|
|
40700
|
+
const profilePath = import_node_path27.default.join(dataDir, PROFILE_FILENAME);
|
|
40753
40701
|
let raw;
|
|
40754
40702
|
try {
|
|
40755
40703
|
raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
|
|
@@ -40776,12 +40724,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
40776
40724
|
|
|
40777
40725
|
// src/feishu-auth/owner-identity-store.ts
|
|
40778
40726
|
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
40779
|
-
var
|
|
40727
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
40780
40728
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
40781
40729
|
var OwnerIdentityStore = class {
|
|
40782
40730
|
file;
|
|
40783
40731
|
constructor(dataDir) {
|
|
40784
|
-
this.file =
|
|
40732
|
+
this.file = import_node_path28.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
40785
40733
|
}
|
|
40786
40734
|
read() {
|
|
40787
40735
|
let raw;
|
|
@@ -40813,7 +40761,7 @@ var OwnerIdentityStore = class {
|
|
|
40813
40761
|
};
|
|
40814
40762
|
}
|
|
40815
40763
|
write(record) {
|
|
40816
|
-
import_node_fs27.default.mkdirSync(
|
|
40764
|
+
import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(this.file), { recursive: true });
|
|
40817
40765
|
import_node_fs27.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
40818
40766
|
try {
|
|
40819
40767
|
import_node_fs27.default.chmodSync(this.file, 384);
|
|
@@ -40941,9 +40889,9 @@ var CentralClientError = class extends Error {
|
|
|
40941
40889
|
code;
|
|
40942
40890
|
cause;
|
|
40943
40891
|
};
|
|
40944
|
-
async function centralRequest(opts,
|
|
40892
|
+
async function centralRequest(opts, path58, init) {
|
|
40945
40893
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
40946
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
40894
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path58}`;
|
|
40947
40895
|
const ctrl = new AbortController();
|
|
40948
40896
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
40949
40897
|
let res;
|
|
@@ -41086,7 +41034,7 @@ function verifyConnectToken(args) {
|
|
|
41086
41034
|
|
|
41087
41035
|
// src/feishu-auth/server-key.ts
|
|
41088
41036
|
var fs36 = __toESM(require("fs"), 1);
|
|
41089
|
-
var
|
|
41037
|
+
var path37 = __toESM(require("path"), 1);
|
|
41090
41038
|
var FILE_NAME2 = "server-signing-key.json";
|
|
41091
41039
|
var ServerKeyStore = class {
|
|
41092
41040
|
constructor(dataDir) {
|
|
@@ -41094,7 +41042,7 @@ var ServerKeyStore = class {
|
|
|
41094
41042
|
}
|
|
41095
41043
|
dataDir;
|
|
41096
41044
|
filePath() {
|
|
41097
|
-
return
|
|
41045
|
+
return path37.join(this.dataDir, FILE_NAME2);
|
|
41098
41046
|
}
|
|
41099
41047
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
41100
41048
|
read() {
|
|
@@ -41133,8 +41081,8 @@ init_protocol();
|
|
|
41133
41081
|
|
|
41134
41082
|
// src/session/fork.ts
|
|
41135
41083
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
41136
|
-
var
|
|
41137
|
-
var
|
|
41084
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
41085
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
41138
41086
|
init_claude_history();
|
|
41139
41087
|
function readJsonlEntries(file) {
|
|
41140
41088
|
const raw = import_node_fs28.default.readFileSync(file, "utf8");
|
|
@@ -41150,9 +41098,9 @@ function readJsonlEntries(file) {
|
|
|
41150
41098
|
return out;
|
|
41151
41099
|
}
|
|
41152
41100
|
function forkSession(input) {
|
|
41153
|
-
const baseDir = input.baseDir ??
|
|
41154
|
-
const projectDir =
|
|
41155
|
-
const sourceFile =
|
|
41101
|
+
const baseDir = input.baseDir ?? import_node_path29.default.join(import_node_os14.default.homedir(), ".claude");
|
|
41102
|
+
const projectDir = import_node_path29.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
41103
|
+
const sourceFile = import_node_path29.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
41156
41104
|
if (!import_node_fs28.default.existsSync(sourceFile)) {
|
|
41157
41105
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
41158
41106
|
}
|
|
@@ -41183,7 +41131,7 @@ function forkSession(input) {
|
|
|
41183
41131
|
}
|
|
41184
41132
|
forkedLines.push(JSON.stringify(forked));
|
|
41185
41133
|
}
|
|
41186
|
-
const forkedFilePath =
|
|
41134
|
+
const forkedFilePath = import_node_path29.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
41187
41135
|
import_node_fs28.default.mkdirSync(projectDir, { recursive: true });
|
|
41188
41136
|
import_node_fs28.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
41189
41137
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -41561,7 +41509,7 @@ function buildPermissionHandlers(deps) {
|
|
|
41561
41509
|
}
|
|
41562
41510
|
|
|
41563
41511
|
// src/handlers/history.ts
|
|
41564
|
-
var
|
|
41512
|
+
var path40 = __toESM(require("path"), 1);
|
|
41565
41513
|
init_protocol();
|
|
41566
41514
|
|
|
41567
41515
|
// src/session/recent-dirs.ts
|
|
@@ -41579,7 +41527,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
41579
41527
|
}
|
|
41580
41528
|
|
|
41581
41529
|
// src/permission/persona-paths.ts
|
|
41582
|
-
var
|
|
41530
|
+
var path39 = __toESM(require("path"), 1);
|
|
41583
41531
|
function getAllowedPersonaIds(grants, action) {
|
|
41584
41532
|
const ids = /* @__PURE__ */ new Set();
|
|
41585
41533
|
for (const g2 of grants) {
|
|
@@ -41592,31 +41540,31 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
41592
41540
|
return ids;
|
|
41593
41541
|
}
|
|
41594
41542
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
41595
|
-
const target =
|
|
41543
|
+
const target = path39.resolve(absPath);
|
|
41596
41544
|
if (userWorkDir) {
|
|
41597
|
-
const u =
|
|
41598
|
-
const usep = u.endsWith(
|
|
41545
|
+
const u = path39.resolve(userWorkDir);
|
|
41546
|
+
const usep = u.endsWith(path39.sep) ? "" : path39.sep;
|
|
41599
41547
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
41600
41548
|
}
|
|
41601
|
-
const root =
|
|
41602
|
-
const sep2 = root.endsWith(
|
|
41549
|
+
const root = path39.resolve(personaRoot);
|
|
41550
|
+
const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
|
|
41603
41551
|
if (!target.startsWith(root + sep2)) return false;
|
|
41604
|
-
const rel =
|
|
41552
|
+
const rel = path39.relative(root, target);
|
|
41605
41553
|
if (!rel || rel.startsWith("..")) return false;
|
|
41606
|
-
const personaId = rel.split(
|
|
41554
|
+
const personaId = rel.split(path39.sep)[0];
|
|
41607
41555
|
if (!personaId) return false;
|
|
41608
41556
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
41609
41557
|
if (allowed === "*") return true;
|
|
41610
41558
|
return allowed.has(personaId);
|
|
41611
41559
|
}
|
|
41612
41560
|
function personaIdFromPath(absPath, personaRoot) {
|
|
41613
|
-
const root =
|
|
41614
|
-
const target =
|
|
41615
|
-
const sep2 = root.endsWith(
|
|
41561
|
+
const root = path39.resolve(personaRoot);
|
|
41562
|
+
const target = path39.resolve(absPath);
|
|
41563
|
+
const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
|
|
41616
41564
|
if (!target.startsWith(root + sep2)) return null;
|
|
41617
|
-
const rel =
|
|
41565
|
+
const rel = path39.relative(root, target);
|
|
41618
41566
|
if (!rel || rel.startsWith("..")) return null;
|
|
41619
|
-
const id = rel.split(
|
|
41567
|
+
const id = rel.split(path39.sep)[0];
|
|
41620
41568
|
return id || null;
|
|
41621
41569
|
}
|
|
41622
41570
|
|
|
@@ -41643,7 +41591,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41643
41591
|
if (!pid) return false;
|
|
41644
41592
|
return isGuestPathAllowed(
|
|
41645
41593
|
ctx.grants,
|
|
41646
|
-
|
|
41594
|
+
path40.join(personaRoot, pid),
|
|
41647
41595
|
personaRoot,
|
|
41648
41596
|
"read",
|
|
41649
41597
|
userWorkDir
|
|
@@ -41655,7 +41603,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41655
41603
|
};
|
|
41656
41604
|
const list = async (frame, _client, ctx) => {
|
|
41657
41605
|
const args = HistoryListArgs.parse(frame);
|
|
41658
|
-
assertGuestPath(ctx,
|
|
41606
|
+
assertGuestPath(ctx, path40.resolve(args.projectPath), personaRoot, "history:list");
|
|
41659
41607
|
const sessions = await history.listSessions(args);
|
|
41660
41608
|
return { response: { type: "history:list", sessions } };
|
|
41661
41609
|
};
|
|
@@ -41687,13 +41635,13 @@ function buildHistoryHandlers(deps) {
|
|
|
41687
41635
|
};
|
|
41688
41636
|
const subagents = async (frame, _client, ctx) => {
|
|
41689
41637
|
const args = HistorySubagentsArgs.parse(frame);
|
|
41690
|
-
assertGuestPath(ctx,
|
|
41638
|
+
assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
41691
41639
|
const subs = await history.listSubagents(args);
|
|
41692
41640
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
41693
41641
|
};
|
|
41694
41642
|
const subagentRead = async (frame, _client, ctx) => {
|
|
41695
41643
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
41696
|
-
assertGuestPath(ctx,
|
|
41644
|
+
assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
41697
41645
|
const res = await history.readSubagent(args);
|
|
41698
41646
|
return { response: { type: "history:subagent-read", ...res } };
|
|
41699
41647
|
};
|
|
@@ -41702,7 +41650,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41702
41650
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
41703
41651
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
41704
41652
|
const filtered = dirs.filter(
|
|
41705
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
41653
|
+
(d) => isGuestPathAllowed(ctx.grants, path40.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
41706
41654
|
);
|
|
41707
41655
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
41708
41656
|
}
|
|
@@ -41719,8 +41667,8 @@ function buildHistoryHandlers(deps) {
|
|
|
41719
41667
|
}
|
|
41720
41668
|
|
|
41721
41669
|
// src/handlers/workspace.ts
|
|
41722
|
-
var
|
|
41723
|
-
var
|
|
41670
|
+
var path41 = __toESM(require("path"), 1);
|
|
41671
|
+
var os15 = __toESM(require("os"), 1);
|
|
41724
41672
|
init_protocol();
|
|
41725
41673
|
init_protocol();
|
|
41726
41674
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -41760,23 +41708,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41760
41708
|
const list = async (frame, _client, ctx) => {
|
|
41761
41709
|
const args = WorkspaceListArgs.parse(frame);
|
|
41762
41710
|
const isGuest = ctx?.principal.kind === "guest";
|
|
41763
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
41764
|
-
const resolvedCwd =
|
|
41765
|
-
const target = args.path ?
|
|
41711
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
|
|
41712
|
+
const resolvedCwd = path41.resolve(args.cwd ?? fallbackCwd);
|
|
41713
|
+
const target = args.path ? path41.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
41766
41714
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
41767
41715
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
41768
41716
|
return { response: { type: "workspace:list", ...res } };
|
|
41769
41717
|
};
|
|
41770
41718
|
const read = async (frame, _client, ctx) => {
|
|
41771
41719
|
const args = WorkspaceReadArgs.parse(frame);
|
|
41772
|
-
const target =
|
|
41720
|
+
const target = path41.isAbsolute(args.path) ? path41.resolve(args.path) : path41.resolve(args.cwd, args.path);
|
|
41773
41721
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
41774
41722
|
const res = workspace.read(args);
|
|
41775
41723
|
return { response: { type: "workspace:read", ...res } };
|
|
41776
41724
|
};
|
|
41777
41725
|
const skillsList = async (frame, _client, ctx) => {
|
|
41778
41726
|
const args = SkillsListArgs.parse(frame);
|
|
41779
|
-
const cwdAbs =
|
|
41727
|
+
const cwdAbs = path41.resolve(args.cwd);
|
|
41780
41728
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
41781
41729
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
41782
41730
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -41788,7 +41736,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41788
41736
|
};
|
|
41789
41737
|
const agentsList = async (frame, _client, ctx) => {
|
|
41790
41738
|
const args = AgentsListArgs.parse(frame);
|
|
41791
|
-
const cwdAbs =
|
|
41739
|
+
const cwdAbs = path41.resolve(args.cwd);
|
|
41792
41740
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
41793
41741
|
if (args.tool === "codex") {
|
|
41794
41742
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -41810,18 +41758,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41810
41758
|
}
|
|
41811
41759
|
|
|
41812
41760
|
// src/handlers/git.ts
|
|
41813
|
-
var
|
|
41761
|
+
var path43 = __toESM(require("path"), 1);
|
|
41814
41762
|
init_protocol();
|
|
41815
41763
|
init_protocol();
|
|
41816
41764
|
|
|
41817
41765
|
// src/workspace/git.ts
|
|
41818
41766
|
var import_node_child_process10 = require("child_process");
|
|
41819
41767
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
41820
|
-
var
|
|
41768
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
41821
41769
|
var import_node_util = require("util");
|
|
41822
41770
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
41823
41771
|
function normalizePath(p2) {
|
|
41824
|
-
const resolved =
|
|
41772
|
+
const resolved = import_node_path30.default.resolve(p2);
|
|
41825
41773
|
try {
|
|
41826
41774
|
return import_node_fs29.default.realpathSync(resolved);
|
|
41827
41775
|
} catch {
|
|
@@ -41897,7 +41845,7 @@ async function listGitBranches(cwd) {
|
|
|
41897
41845
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
41898
41846
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
41899
41847
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
41900
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
41848
|
+
if (!isGuestPathAllowed(ctx.grants, path43.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
41901
41849
|
throw new ClawdError(
|
|
41902
41850
|
ERROR_CODES.UNAUTHORIZED,
|
|
41903
41851
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -42285,7 +42233,7 @@ function buildDeviceHandlers(deps) {
|
|
|
42285
42233
|
}
|
|
42286
42234
|
|
|
42287
42235
|
// src/handlers/meta.ts
|
|
42288
|
-
var
|
|
42236
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
42289
42237
|
init_protocol();
|
|
42290
42238
|
|
|
42291
42239
|
// src/version.ts
|
|
@@ -42316,7 +42264,7 @@ function buildReadyFrame(deps, client) {
|
|
|
42316
42264
|
return {
|
|
42317
42265
|
version,
|
|
42318
42266
|
protocolVersion: PROTOCOL_VERSION,
|
|
42319
|
-
hostname:
|
|
42267
|
+
hostname: import_node_os15.default.hostname(),
|
|
42320
42268
|
os: process.platform,
|
|
42321
42269
|
tools,
|
|
42322
42270
|
runningSessions: info.runningSessions,
|
|
@@ -42411,7 +42359,7 @@ function buildPersonaHandlers(deps) {
|
|
|
42411
42359
|
}
|
|
42412
42360
|
|
|
42413
42361
|
// src/handlers/attachment.ts
|
|
42414
|
-
var
|
|
42362
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
42415
42363
|
init_protocol();
|
|
42416
42364
|
init_protocol();
|
|
42417
42365
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -42466,12 +42414,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
42466
42414
|
`session ${args.sessionId} scope unresolved`
|
|
42467
42415
|
);
|
|
42468
42416
|
}
|
|
42469
|
-
const cwdAbs =
|
|
42470
|
-
const candidateAbs =
|
|
42417
|
+
const cwdAbs = import_node_path31.default.resolve(sessionFile.cwd);
|
|
42418
|
+
const candidateAbs = import_node_path31.default.isAbsolute(args.relPath) ? import_node_path31.default.resolve(args.relPath) : import_node_path31.default.resolve(cwdAbs, args.relPath);
|
|
42471
42419
|
assertGuestAttachmentPath(ctx, candidateAbs, deps.personaRoot, "attachment.signUrl", deps.usersRoot);
|
|
42472
42420
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
42473
42421
|
const entry = entries.find((e) => {
|
|
42474
|
-
const storedAbs =
|
|
42422
|
+
const storedAbs = import_node_path31.default.isAbsolute(e.relPath) ? import_node_path31.default.resolve(e.relPath) : import_node_path31.default.resolve(cwdAbs, e.relPath);
|
|
42475
42423
|
return storedAbs === candidateAbs && !e.stale;
|
|
42476
42424
|
});
|
|
42477
42425
|
if (!entry) {
|
|
@@ -42495,7 +42443,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
42495
42443
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
42496
42444
|
const f = deps.sessionStore.read(sessionId);
|
|
42497
42445
|
if (!f) return;
|
|
42498
|
-
assertGuestAttachmentPath(ctx,
|
|
42446
|
+
assertGuestAttachmentPath(ctx, import_node_path31.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
42499
42447
|
}
|
|
42500
42448
|
const groupAdd = async (frame, _client, ctx) => {
|
|
42501
42449
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -42567,19 +42515,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
42567
42515
|
|
|
42568
42516
|
// src/handlers/extension.ts
|
|
42569
42517
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
42570
|
-
var
|
|
42518
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
42571
42519
|
init_protocol();
|
|
42572
42520
|
|
|
42573
42521
|
// src/extension/bundle-zip.ts
|
|
42574
42522
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
42575
|
-
var
|
|
42523
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
42576
42524
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
42577
42525
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
42578
42526
|
async function bundleExtensionDir(dir) {
|
|
42579
42527
|
const entries = await listFilesSorted(dir);
|
|
42580
42528
|
const zip = new import_jszip2.default();
|
|
42581
42529
|
for (const rel of entries) {
|
|
42582
|
-
const abs =
|
|
42530
|
+
const abs = import_node_path32.default.join(dir, rel);
|
|
42583
42531
|
const content = await import_promises4.default.readFile(abs);
|
|
42584
42532
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
42585
42533
|
}
|
|
@@ -42600,7 +42548,7 @@ async function listFilesSorted(rootDir) {
|
|
|
42600
42548
|
return out;
|
|
42601
42549
|
}
|
|
42602
42550
|
async function walk(absRoot, relPrefix, out) {
|
|
42603
|
-
const dirAbs =
|
|
42551
|
+
const dirAbs = import_node_path32.default.join(absRoot, relPrefix);
|
|
42604
42552
|
const entries = await import_promises4.default.readdir(dirAbs, { withFileTypes: true });
|
|
42605
42553
|
for (const e of entries) {
|
|
42606
42554
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -42654,25 +42602,25 @@ function computePublishCheck(args) {
|
|
|
42654
42602
|
|
|
42655
42603
|
// src/extension/install-flow.ts
|
|
42656
42604
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
42657
|
-
var
|
|
42658
|
-
var
|
|
42605
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
42606
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
42659
42607
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
42660
42608
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
42661
42609
|
|
|
42662
42610
|
// src/extension/paths.ts
|
|
42663
|
-
var
|
|
42664
|
-
var
|
|
42611
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
42612
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
42665
42613
|
function clawdHomeRoot(override) {
|
|
42666
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
42614
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path33.default.join(import_node_os16.default.homedir(), ".clawd");
|
|
42667
42615
|
}
|
|
42668
42616
|
function extensionsRoot(override) {
|
|
42669
|
-
return
|
|
42617
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extensions");
|
|
42670
42618
|
}
|
|
42671
42619
|
function publishedChannelsFile(override) {
|
|
42672
|
-
return
|
|
42620
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
42673
42621
|
}
|
|
42674
42622
|
function bundleCacheRoot(override) {
|
|
42675
|
-
return
|
|
42623
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
42676
42624
|
}
|
|
42677
42625
|
|
|
42678
42626
|
// src/extension/install-flow.ts
|
|
@@ -42699,7 +42647,7 @@ async function installFromChannel(args, deps) {
|
|
|
42699
42647
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
42700
42648
|
}
|
|
42701
42649
|
for (const name of Object.keys(zip.files)) {
|
|
42702
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
42650
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path34.default.isAbsolute(name)) {
|
|
42703
42651
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
42704
42652
|
}
|
|
42705
42653
|
}
|
|
@@ -42731,7 +42679,7 @@ async function installFromChannel(args, deps) {
|
|
|
42731
42679
|
);
|
|
42732
42680
|
}
|
|
42733
42681
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
42734
|
-
const destDir =
|
|
42682
|
+
const destDir = import_node_path34.default.join(deps.extensionsRoot, localExtId);
|
|
42735
42683
|
let destExists = false;
|
|
42736
42684
|
try {
|
|
42737
42685
|
await import_promises5.default.access(destDir);
|
|
@@ -42745,16 +42693,16 @@ async function installFromChannel(args, deps) {
|
|
|
42745
42693
|
);
|
|
42746
42694
|
}
|
|
42747
42695
|
const stage = await import_promises5.default.mkdtemp(
|
|
42748
|
-
|
|
42696
|
+
import_node_path34.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
42749
42697
|
);
|
|
42750
42698
|
try {
|
|
42751
42699
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
42752
|
-
const dest =
|
|
42700
|
+
const dest = import_node_path34.default.join(stage, name);
|
|
42753
42701
|
if (entry.dir) {
|
|
42754
42702
|
await import_promises5.default.mkdir(dest, { recursive: true });
|
|
42755
42703
|
continue;
|
|
42756
42704
|
}
|
|
42757
|
-
await import_promises5.default.mkdir(
|
|
42705
|
+
await import_promises5.default.mkdir(import_node_path34.default.dirname(dest), { recursive: true });
|
|
42758
42706
|
if (name === "manifest.json") {
|
|
42759
42707
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
42760
42708
|
await import_promises5.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -42775,8 +42723,8 @@ async function installFromChannel(args, deps) {
|
|
|
42775
42723
|
|
|
42776
42724
|
// src/extension/update-flow.ts
|
|
42777
42725
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
42778
|
-
var
|
|
42779
|
-
var
|
|
42726
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
42727
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
42780
42728
|
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
42781
42729
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
42782
42730
|
var UpdateError = class extends Error {
|
|
@@ -42792,11 +42740,11 @@ async function updateFromChannel(args, deps) {
|
|
|
42792
42740
|
channelRef.extId,
|
|
42793
42741
|
channelRef.ownerPrincipalId
|
|
42794
42742
|
);
|
|
42795
|
-
const liveDir =
|
|
42743
|
+
const liveDir = import_node_path35.default.join(deps.extensionsRoot, localExtId);
|
|
42796
42744
|
const prevDir = `${liveDir}.prev`;
|
|
42797
42745
|
let existingVersion;
|
|
42798
42746
|
try {
|
|
42799
|
-
const raw = await import_promises6.default.readFile(
|
|
42747
|
+
const raw = await import_promises6.default.readFile(import_node_path35.default.join(liveDir, "manifest.json"), "utf8");
|
|
42800
42748
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
42801
42749
|
if (!parsed2.success) {
|
|
42802
42750
|
throw new UpdateError(
|
|
@@ -42829,7 +42777,7 @@ async function updateFromChannel(args, deps) {
|
|
|
42829
42777
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
42830
42778
|
}
|
|
42831
42779
|
for (const name of Object.keys(zip.files)) {
|
|
42832
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
42780
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path35.default.isAbsolute(name)) {
|
|
42833
42781
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
42834
42782
|
}
|
|
42835
42783
|
}
|
|
@@ -42864,16 +42812,16 @@ async function updateFromChannel(args, deps) {
|
|
|
42864
42812
|
await import_promises6.default.rm(prevDir, { recursive: true, force: true });
|
|
42865
42813
|
await import_promises6.default.rename(liveDir, prevDir);
|
|
42866
42814
|
const stage = await import_promises6.default.mkdtemp(
|
|
42867
|
-
|
|
42815
|
+
import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
42868
42816
|
);
|
|
42869
42817
|
try {
|
|
42870
42818
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
42871
|
-
const dest =
|
|
42819
|
+
const dest = import_node_path35.default.join(stage, name);
|
|
42872
42820
|
if (entry.dir) {
|
|
42873
42821
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
42874
42822
|
continue;
|
|
42875
42823
|
}
|
|
42876
|
-
await import_promises6.default.mkdir(
|
|
42824
|
+
await import_promises6.default.mkdir(import_node_path35.default.dirname(dest), { recursive: true });
|
|
42877
42825
|
if (name === "manifest.json") {
|
|
42878
42826
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
42879
42827
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -42966,7 +42914,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
42966
42914
|
);
|
|
42967
42915
|
}
|
|
42968
42916
|
}
|
|
42969
|
-
const manifestPath =
|
|
42917
|
+
const manifestPath = import_node_path36.default.join(root, extId, "manifest.json");
|
|
42970
42918
|
const manifest = await readManifest(root, extId);
|
|
42971
42919
|
const next = { ...manifest, version: newVersion };
|
|
42972
42920
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -42974,7 +42922,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
42974
42922
|
await import_promises7.default.rename(tmp, manifestPath);
|
|
42975
42923
|
}
|
|
42976
42924
|
async function readManifest(root, extId) {
|
|
42977
|
-
const file =
|
|
42925
|
+
const file = import_node_path36.default.join(root, extId, "manifest.json");
|
|
42978
42926
|
let raw;
|
|
42979
42927
|
try {
|
|
42980
42928
|
raw = await import_promises7.default.readFile(file, "utf8");
|
|
@@ -43065,7 +43013,7 @@ function buildExtensionHandlers(deps) {
|
|
|
43065
43013
|
};
|
|
43066
43014
|
async function buildSnapshotMeta(extId) {
|
|
43067
43015
|
const manifest = await readManifest(deps.root, extId);
|
|
43068
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
43016
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path36.default.join(deps.root, extId));
|
|
43069
43017
|
return { manifest, contentHash: sha256, buffer };
|
|
43070
43018
|
}
|
|
43071
43019
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -43362,7 +43310,7 @@ var PublishJobRegistry = class {
|
|
|
43362
43310
|
// src/app-builder/publish-job-runner.ts
|
|
43363
43311
|
var import_node_child_process12 = require("child_process");
|
|
43364
43312
|
var import_node_fs30 = require("fs");
|
|
43365
|
-
var
|
|
43313
|
+
var import_node_path37 = require("path");
|
|
43366
43314
|
|
|
43367
43315
|
// src/app-builder/publish-stage-parser.ts
|
|
43368
43316
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -43394,7 +43342,7 @@ async function startPublishJob(deps, args) {
|
|
|
43394
43342
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
43395
43343
|
}
|
|
43396
43344
|
const projDir = projectDir(args.name);
|
|
43397
|
-
const logPath = (0,
|
|
43345
|
+
const logPath = (0, import_node_path37.join)(projDir, ".publish.log");
|
|
43398
43346
|
let logStream = null;
|
|
43399
43347
|
try {
|
|
43400
43348
|
logStream = (0, import_node_fs30.createWriteStream)(logPath, { flags: "w" });
|
|
@@ -43654,7 +43602,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
43654
43602
|
|
|
43655
43603
|
// src/handlers/app-builder.ts
|
|
43656
43604
|
init_protocol();
|
|
43657
|
-
var
|
|
43605
|
+
var import_node_path38 = require("path");
|
|
43658
43606
|
var import_node_fs31 = require("fs");
|
|
43659
43607
|
var APP_BUILDER_PERSONAS = ["persona-app-builder"];
|
|
43660
43608
|
var PUBLISH_SCRIPT_REL = "extension-kit/scripts/publish.sh";
|
|
@@ -44031,7 +43979,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
44031
43979
|
});
|
|
44032
43980
|
await userStore.clearPublishJob(args.name);
|
|
44033
43981
|
}
|
|
44034
|
-
const scriptPath = (0,
|
|
43982
|
+
const scriptPath = (0, import_node_path38.join)(deps.personaRoot, PUBLISH_SCRIPT_REL);
|
|
44035
43983
|
deps.logger?.info("app-builder.publish.start", {
|
|
44036
43984
|
name: args.name,
|
|
44037
43985
|
sessionId: boundSession.sessionId,
|
|
@@ -44125,7 +44073,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
44125
44073
|
|
|
44126
44074
|
// src/extension/registry.ts
|
|
44127
44075
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
44128
|
-
var
|
|
44076
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
44129
44077
|
async function loadAll(root) {
|
|
44130
44078
|
let entries;
|
|
44131
44079
|
try {
|
|
@@ -44138,13 +44086,13 @@ async function loadAll(root) {
|
|
|
44138
44086
|
for (const ent of entries) {
|
|
44139
44087
|
if (!ent.isDirectory()) continue;
|
|
44140
44088
|
if (ent.name.startsWith(".")) continue;
|
|
44141
|
-
records.push(await loadOne(
|
|
44089
|
+
records.push(await loadOne(import_node_path39.default.join(root, ent.name), ent.name));
|
|
44142
44090
|
}
|
|
44143
44091
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
44144
44092
|
return records;
|
|
44145
44093
|
}
|
|
44146
44094
|
async function loadOne(dir, dirName) {
|
|
44147
|
-
const manifestPath =
|
|
44095
|
+
const manifestPath = import_node_path39.default.join(dir, "manifest.json");
|
|
44148
44096
|
let raw;
|
|
44149
44097
|
try {
|
|
44150
44098
|
raw = await import_promises8.default.readFile(manifestPath, "utf8");
|
|
@@ -44189,7 +44137,7 @@ async function loadOne(dir, dirName) {
|
|
|
44189
44137
|
|
|
44190
44138
|
// src/extension/uninstall.ts
|
|
44191
44139
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
44192
|
-
var
|
|
44140
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
44193
44141
|
var UninstallError = class extends Error {
|
|
44194
44142
|
constructor(code, message) {
|
|
44195
44143
|
super(message);
|
|
@@ -44198,7 +44146,7 @@ var UninstallError = class extends Error {
|
|
|
44198
44146
|
code;
|
|
44199
44147
|
};
|
|
44200
44148
|
async function uninstall(deps) {
|
|
44201
|
-
const dir =
|
|
44149
|
+
const dir = import_node_path40.default.join(deps.root, deps.extId);
|
|
44202
44150
|
try {
|
|
44203
44151
|
await import_promises9.default.access(dir);
|
|
44204
44152
|
} catch {
|
|
@@ -44279,7 +44227,7 @@ function buildMethodHandlers(deps) {
|
|
|
44279
44227
|
// src/app-builder/project-store.ts
|
|
44280
44228
|
var import_node_fs32 = require("fs");
|
|
44281
44229
|
var import_node_child_process13 = require("child_process");
|
|
44282
|
-
var
|
|
44230
|
+
var import_node_path41 = require("path");
|
|
44283
44231
|
init_protocol();
|
|
44284
44232
|
var PROJECTS_DIR = "projects";
|
|
44285
44233
|
var META_FILE = ".clawd-project.json";
|
|
@@ -44294,14 +44242,14 @@ var ProjectStore = class {
|
|
|
44294
44242
|
root;
|
|
44295
44243
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
44296
44244
|
metaPath(name) {
|
|
44297
|
-
return (0,
|
|
44245
|
+
return (0, import_node_path41.join)(this.projectsRoot(), name, META_FILE);
|
|
44298
44246
|
}
|
|
44299
44247
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
44300
44248
|
projectDir(name) {
|
|
44301
|
-
return (0,
|
|
44249
|
+
return (0, import_node_path41.join)(this.projectsRoot(), name);
|
|
44302
44250
|
}
|
|
44303
44251
|
projectsRoot() {
|
|
44304
|
-
return (0,
|
|
44252
|
+
return (0, import_node_path41.join)(this.root, PROJECTS_DIR);
|
|
44305
44253
|
}
|
|
44306
44254
|
async list() {
|
|
44307
44255
|
let entries;
|
|
@@ -44382,7 +44330,7 @@ var ProjectStore = class {
|
|
|
44382
44330
|
* 代码再参考"。assistant 进 project 时目录已是完整模板,直接 pnpm install 即可。
|
|
44383
44331
|
*/
|
|
44384
44332
|
async scaffold(name, template = DEFAULT_TEMPLATE, personaRoot = this.root) {
|
|
44385
|
-
const scriptPath = (0,
|
|
44333
|
+
const scriptPath = (0, import_node_path41.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
|
|
44386
44334
|
const destDir = this.projectDir(name);
|
|
44387
44335
|
return await new Promise((resolve6, reject) => {
|
|
44388
44336
|
const child = (0, import_node_child_process13.spawn)("bash", [scriptPath, name, template, destDir], {
|
|
@@ -44920,7 +44868,7 @@ function computeGrantForFrame(method, frame) {
|
|
|
44920
44868
|
|
|
44921
44869
|
// src/extension/runtime.ts
|
|
44922
44870
|
var import_node_child_process15 = require("child_process");
|
|
44923
|
-
var
|
|
44871
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
44924
44872
|
var import_promises10 = require("timers/promises");
|
|
44925
44873
|
|
|
44926
44874
|
// src/extension/port-allocator.ts
|
|
@@ -45021,7 +44969,7 @@ var Runtime = class {
|
|
|
45021
44969
|
/\$CLAWOS_EXT_PORT/g,
|
|
45022
44970
|
String(port)
|
|
45023
44971
|
);
|
|
45024
|
-
const dir =
|
|
44972
|
+
const dir = import_node_path42.default.join(this.root, extId);
|
|
45025
44973
|
const env = {
|
|
45026
44974
|
...process.env,
|
|
45027
44975
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -45133,7 +45081,7 @@ ${handle.stderrTail}`
|
|
|
45133
45081
|
|
|
45134
45082
|
// src/extension/published-channels.ts
|
|
45135
45083
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
45136
|
-
var
|
|
45084
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
45137
45085
|
init_zod();
|
|
45138
45086
|
var PublishedChannelsError = class extends Error {
|
|
45139
45087
|
constructor(code, message) {
|
|
@@ -45232,7 +45180,7 @@ var PublishedChannelStore = class {
|
|
|
45232
45180
|
)
|
|
45233
45181
|
};
|
|
45234
45182
|
const tmp = `${this.filePath}.tmp`;
|
|
45235
|
-
await import_promises11.default.mkdir(
|
|
45183
|
+
await import_promises11.default.mkdir(import_node_path43.default.dirname(this.filePath), { recursive: true });
|
|
45236
45184
|
await import_promises11.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
45237
45185
|
await import_promises11.default.rename(tmp, this.filePath);
|
|
45238
45186
|
}
|
|
@@ -45240,7 +45188,7 @@ var PublishedChannelStore = class {
|
|
|
45240
45188
|
|
|
45241
45189
|
// src/extension/bundle-cache.ts
|
|
45242
45190
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
45243
|
-
var
|
|
45191
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
45244
45192
|
var BundleCache = class {
|
|
45245
45193
|
constructor(rootDir) {
|
|
45246
45194
|
this.rootDir = rootDir;
|
|
@@ -45249,14 +45197,14 @@ var BundleCache = class {
|
|
|
45249
45197
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
45250
45198
|
async write(snapshotHash, buffer) {
|
|
45251
45199
|
await import_promises12.default.mkdir(this.rootDir, { recursive: true });
|
|
45252
|
-
const file =
|
|
45200
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45253
45201
|
const tmp = `${file}.tmp`;
|
|
45254
45202
|
await import_promises12.default.writeFile(tmp, buffer, { mode: 384 });
|
|
45255
45203
|
await import_promises12.default.rename(tmp, file);
|
|
45256
45204
|
}
|
|
45257
45205
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
45258
45206
|
async read(snapshotHash) {
|
|
45259
|
-
const file =
|
|
45207
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45260
45208
|
try {
|
|
45261
45209
|
return await import_promises12.default.readFile(file);
|
|
45262
45210
|
} catch (e) {
|
|
@@ -45266,7 +45214,7 @@ var BundleCache = class {
|
|
|
45266
45214
|
}
|
|
45267
45215
|
/** Idempotent — missing file is not an error. */
|
|
45268
45216
|
async delete(snapshotHash) {
|
|
45269
|
-
const file =
|
|
45217
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45270
45218
|
await import_promises12.default.rm(file, { force: true });
|
|
45271
45219
|
}
|
|
45272
45220
|
};
|
|
@@ -45275,7 +45223,7 @@ var BundleCache = class {
|
|
|
45275
45223
|
async function startDaemon(config) {
|
|
45276
45224
|
const logger = createLogger({
|
|
45277
45225
|
level: config.logLevel,
|
|
45278
|
-
file:
|
|
45226
|
+
file: import_node_path45.default.join(config.dataDir, "clawd.log")
|
|
45279
45227
|
});
|
|
45280
45228
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
45281
45229
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
@@ -45411,8 +45359,8 @@ async function startDaemon(config) {
|
|
|
45411
45359
|
const agents = new AgentsScanner();
|
|
45412
45360
|
const history = new ClaudeHistoryReader();
|
|
45413
45361
|
let transport = null;
|
|
45414
|
-
const personaStore = new PersonaStore(
|
|
45415
|
-
const usersRoot =
|
|
45362
|
+
const personaStore = new PersonaStore(import_node_path45.default.join(config.dataDir, "personas"));
|
|
45363
|
+
const usersRoot = import_node_path45.default.join(config.dataDir, "users");
|
|
45416
45364
|
const defaultsRoot = findDefaultsRoot();
|
|
45417
45365
|
if (defaultsRoot) {
|
|
45418
45366
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -45432,7 +45380,7 @@ async function startDaemon(config) {
|
|
|
45432
45380
|
getAdapter,
|
|
45433
45381
|
historyReader: history,
|
|
45434
45382
|
dataDir: config.dataDir,
|
|
45435
|
-
personaRoot:
|
|
45383
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45436
45384
|
usersRoot,
|
|
45437
45385
|
personaStore,
|
|
45438
45386
|
ownerDisplayName,
|
|
@@ -45462,7 +45410,7 @@ async function startDaemon(config) {
|
|
|
45462
45410
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
45463
45411
|
attachmentGroup: {
|
|
45464
45412
|
onFileEdit: (input) => {
|
|
45465
|
-
const absPath =
|
|
45413
|
+
const absPath = import_node_path45.default.isAbsolute(input.relPath) ? input.relPath : import_node_path45.default.join(input.cwd, input.relPath);
|
|
45466
45414
|
let size = 0;
|
|
45467
45415
|
try {
|
|
45468
45416
|
size = import_node_fs33.default.statSync(absPath).size;
|
|
@@ -45651,11 +45599,11 @@ async function startDaemon(config) {
|
|
|
45651
45599
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
45652
45600
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
45653
45601
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
45654
|
-
personaRoot:
|
|
45602
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45655
45603
|
usersRoot
|
|
45656
45604
|
},
|
|
45657
45605
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
45658
|
-
personaRoot:
|
|
45606
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45659
45607
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
45660
45608
|
usersRoot,
|
|
45661
45609
|
// capability:list / delete handler 依赖
|
|
@@ -45744,7 +45692,7 @@ async function startDaemon(config) {
|
|
|
45744
45692
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
45745
45693
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
45746
45694
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
45747
|
-
appBuilderPersonaRoot:
|
|
45695
|
+
appBuilderPersonaRoot: import_node_path45.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
45748
45696
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
45749
45697
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
45750
45698
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -45993,8 +45941,8 @@ async function startDaemon(config) {
|
|
|
45993
45941
|
const lines = [
|
|
45994
45942
|
`Tunnel: ${r.url}`,
|
|
45995
45943
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
45996
|
-
`Frpc config: ${
|
|
45997
|
-
`Frpc log: ${
|
|
45944
|
+
`Frpc config: ${import_node_path45.default.join(config.dataDir, "frpc.toml")}`,
|
|
45945
|
+
`Frpc log: ${import_node_path45.default.join(config.dataDir, "frpc.log")}`
|
|
45998
45946
|
];
|
|
45999
45947
|
const width = Math.max(...lines.map((l) => l.length));
|
|
46000
45948
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -46007,7 +45955,7 @@ ${bar}
|
|
|
46007
45955
|
|
|
46008
45956
|
`);
|
|
46009
45957
|
try {
|
|
46010
|
-
const connectPath =
|
|
45958
|
+
const connectPath = import_node_path45.default.join(config.dataDir, "connect.txt");
|
|
46011
45959
|
import_node_fs33.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
46012
45960
|
} catch {
|
|
46013
45961
|
}
|
|
@@ -46079,7 +46027,7 @@ ${bar}
|
|
|
46079
46027
|
};
|
|
46080
46028
|
}
|
|
46081
46029
|
function migrateDropPersonsDir(dataDir) {
|
|
46082
|
-
const dir =
|
|
46030
|
+
const dir = import_node_path45.default.join(dataDir, "persons");
|
|
46083
46031
|
try {
|
|
46084
46032
|
import_node_fs33.default.rmSync(dir, { recursive: true, force: true });
|
|
46085
46033
|
} catch {
|