@clawos-dev/clawd 0.2.136 → 0.2.138
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 +335 -368
- 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
|
|
@@ -36794,15 +36742,34 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
36794
36742
|
args.push(isResume ? "--resume" : "--session-id", ctx.toolSessionId);
|
|
36795
36743
|
}
|
|
36796
36744
|
if (ctx.model) args.push("--model", ctx.model);
|
|
36797
|
-
|
|
36798
|
-
|
|
36745
|
+
switch (ctx.personaMode) {
|
|
36746
|
+
case "guest":
|
|
36747
|
+
args.push("--setting-sources", "project,local");
|
|
36748
|
+
break;
|
|
36749
|
+
case "owner":
|
|
36750
|
+
args.push("--setting-sources", "user,project,local");
|
|
36751
|
+
args.push("--permission-mode", "bypassPermissions");
|
|
36752
|
+
break;
|
|
36753
|
+
case void 0:
|
|
36754
|
+
args.push("--permission-mode", ctx.permissionMode || "bypassPermissions");
|
|
36755
|
+
break;
|
|
36756
|
+
default: {
|
|
36757
|
+
const _exhaustive = ctx.personaMode;
|
|
36758
|
+
throw new Error(`unexpected personaMode: ${String(_exhaustive)}`);
|
|
36759
|
+
}
|
|
36760
|
+
}
|
|
36799
36761
|
if (ctx.extraSettings) args.push("--settings", ctx.extraSettings);
|
|
36762
|
+
if (ctx.extraSystemPrompt) args.push("--append-system-prompt", ctx.extraSystemPrompt);
|
|
36763
|
+
if (ctx.addDirs) {
|
|
36764
|
+
for (const dir of ctx.addDirs) args.push("--add-dir", dir);
|
|
36765
|
+
}
|
|
36766
|
+
if (ctx.effort) args.push("--effort", ctx.effort);
|
|
36800
36767
|
return args;
|
|
36801
36768
|
}
|
|
36802
36769
|
function jsonlExistsForCtx(ctx) {
|
|
36803
36770
|
if (!ctx.toolSessionId) return false;
|
|
36804
|
-
const home =
|
|
36805
|
-
const file =
|
|
36771
|
+
const home = import_node_os5.default.homedir();
|
|
36772
|
+
const file = import_node_path9.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
36806
36773
|
try {
|
|
36807
36774
|
return import_node_fs11.default.statSync(file).isFile();
|
|
36808
36775
|
} catch {
|
|
@@ -36999,13 +36966,13 @@ function mapSkillsListResponse(res) {
|
|
|
36999
36966
|
const r = s ?? {};
|
|
37000
36967
|
const name = str3(r.name);
|
|
37001
36968
|
if (!name) continue;
|
|
37002
|
-
const
|
|
36969
|
+
const path58 = str3(r.path);
|
|
37003
36970
|
const description = str3(r.description);
|
|
37004
36971
|
const isPlugin = name.includes(":");
|
|
37005
36972
|
out.push({
|
|
37006
36973
|
name,
|
|
37007
36974
|
source: isPlugin ? "plugin" : "project",
|
|
37008
|
-
...
|
|
36975
|
+
...path58 ? { path: path58 } : {},
|
|
37009
36976
|
...description ? { description } : {},
|
|
37010
36977
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
37011
36978
|
});
|
|
@@ -37045,15 +37012,15 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
37045
37012
|
|
|
37046
37013
|
// src/workspace/browser.ts
|
|
37047
37014
|
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
37048
|
-
var
|
|
37049
|
-
var
|
|
37015
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
37016
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
37050
37017
|
init_protocol();
|
|
37051
37018
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
37052
37019
|
function resolveInsideCwd(cwd, subpath) {
|
|
37053
|
-
const absCwd =
|
|
37054
|
-
const joined =
|
|
37055
|
-
const rel =
|
|
37056
|
-
if (rel.startsWith("..") ||
|
|
37020
|
+
const absCwd = import_node_path10.default.resolve(cwd);
|
|
37021
|
+
const joined = import_node_path10.default.resolve(absCwd, subpath ?? ".");
|
|
37022
|
+
const rel = import_node_path10.default.relative(absCwd, joined);
|
|
37023
|
+
if (rel.startsWith("..") || import_node_path10.default.isAbsolute(rel)) {
|
|
37057
37024
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
37058
37025
|
}
|
|
37059
37026
|
return joined;
|
|
@@ -37071,7 +37038,7 @@ function ensureCwd(cwd) {
|
|
|
37071
37038
|
}
|
|
37072
37039
|
var WorkspaceBrowser = class {
|
|
37073
37040
|
list(args) {
|
|
37074
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
37041
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
|
|
37075
37042
|
ensureCwd(cwd);
|
|
37076
37043
|
const full = resolveInsideCwd(cwd, args.path);
|
|
37077
37044
|
const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
|
|
@@ -37084,7 +37051,7 @@ var WorkspaceBrowser = class {
|
|
|
37084
37051
|
mtime: ""
|
|
37085
37052
|
};
|
|
37086
37053
|
try {
|
|
37087
|
-
const st = import_node_fs12.default.statSync(
|
|
37054
|
+
const st = import_node_fs12.default.statSync(import_node_path10.default.join(full, d.name));
|
|
37088
37055
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
37089
37056
|
if (d.isFile()) entry.size = st.size;
|
|
37090
37057
|
} catch {
|
|
@@ -37130,8 +37097,8 @@ var WorkspaceBrowser = class {
|
|
|
37130
37097
|
|
|
37131
37098
|
// src/skills/agents-scanner.ts
|
|
37132
37099
|
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
37133
|
-
var
|
|
37134
|
-
var
|
|
37100
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
37101
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
37135
37102
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
37136
37103
|
function isDirLikeSync2(p2) {
|
|
37137
37104
|
try {
|
|
@@ -37169,10 +37136,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
37169
37136
|
}
|
|
37170
37137
|
for (const ent of entries) {
|
|
37171
37138
|
if (!ent.name.endsWith(".md")) continue;
|
|
37172
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
37139
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path11.default.join(dir, ent.name)))) {
|
|
37173
37140
|
continue;
|
|
37174
37141
|
}
|
|
37175
|
-
const filePath =
|
|
37142
|
+
const filePath = import_node_path11.default.join(dir, ent.name);
|
|
37176
37143
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
37177
37144
|
if (seen.has(baseName)) continue;
|
|
37178
37145
|
seen.add(baseName);
|
|
@@ -37195,7 +37162,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
37195
37162
|
return;
|
|
37196
37163
|
}
|
|
37197
37164
|
for (const ent of entries) {
|
|
37198
|
-
const childPath =
|
|
37165
|
+
const childPath = import_node_path11.default.join(dir, ent.name);
|
|
37199
37166
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
37200
37167
|
walk2(childPath, [...namespaces, ent.name]);
|
|
37201
37168
|
continue;
|
|
@@ -37220,9 +37187,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
37220
37187
|
walk2(root, []);
|
|
37221
37188
|
}
|
|
37222
37189
|
function readInstalledPlugins2(home) {
|
|
37223
|
-
const pluginsDir =
|
|
37224
|
-
const v2 =
|
|
37225
|
-
const v1 =
|
|
37190
|
+
const pluginsDir = import_node_path11.default.join(home, ".claude", "plugins");
|
|
37191
|
+
const v2 = import_node_path11.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
37192
|
+
const v1 = import_node_path11.default.join(pluginsDir, "installed_plugins.json");
|
|
37226
37193
|
let raw = null;
|
|
37227
37194
|
for (const candidate of [v2, v1]) {
|
|
37228
37195
|
try {
|
|
@@ -37251,19 +37218,19 @@ function readInstalledPlugins2(home) {
|
|
|
37251
37218
|
return out;
|
|
37252
37219
|
}
|
|
37253
37220
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
37254
|
-
let cur =
|
|
37255
|
-
const fsRoot =
|
|
37221
|
+
let cur = import_node_path11.default.resolve(startCwd);
|
|
37222
|
+
const fsRoot = import_node_path11.default.parse(cur).root;
|
|
37256
37223
|
while (true) {
|
|
37257
|
-
scanAgentsDir(
|
|
37224
|
+
scanAgentsDir(import_node_path11.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
37258
37225
|
let hasGit = false;
|
|
37259
37226
|
try {
|
|
37260
|
-
hasGit = import_node_fs13.default.existsSync(
|
|
37227
|
+
hasGit = import_node_fs13.default.existsSync(import_node_path11.default.join(cur, ".git"));
|
|
37261
37228
|
} catch {
|
|
37262
37229
|
}
|
|
37263
37230
|
if (hasGit) return;
|
|
37264
37231
|
if (cur === home) return;
|
|
37265
37232
|
if (cur === fsRoot) return;
|
|
37266
|
-
const parent =
|
|
37233
|
+
const parent = import_node_path11.default.dirname(cur);
|
|
37267
37234
|
if (parent === cur) return;
|
|
37268
37235
|
cur = parent;
|
|
37269
37236
|
}
|
|
@@ -37273,7 +37240,7 @@ var AgentsScanner = class {
|
|
|
37273
37240
|
extraPluginRoots;
|
|
37274
37241
|
policyDir;
|
|
37275
37242
|
constructor(opts = {}) {
|
|
37276
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
37243
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os7.default.homedir();
|
|
37277
37244
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
37278
37245
|
if (opts.policyDir !== void 0) {
|
|
37279
37246
|
this.policyDir = opts.policyDir;
|
|
@@ -37298,7 +37265,7 @@ var AgentsScanner = class {
|
|
|
37298
37265
|
}
|
|
37299
37266
|
const fsBlock = [];
|
|
37300
37267
|
scanAgentsDir(
|
|
37301
|
-
|
|
37268
|
+
import_node_path11.default.join(this.home, ".claude", "agents"),
|
|
37302
37269
|
"global",
|
|
37303
37270
|
seen,
|
|
37304
37271
|
fsBlock
|
|
@@ -37312,7 +37279,7 @@ var AgentsScanner = class {
|
|
|
37312
37279
|
...this.extraPluginRoots
|
|
37313
37280
|
];
|
|
37314
37281
|
for (const { name, root } of plugins) {
|
|
37315
|
-
const agentsRoot =
|
|
37282
|
+
const agentsRoot = import_node_path11.default.join(root, "agents");
|
|
37316
37283
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
37317
37284
|
}
|
|
37318
37285
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -37321,27 +37288,27 @@ var AgentsScanner = class {
|
|
|
37321
37288
|
|
|
37322
37289
|
// src/observer/session-observer.ts
|
|
37323
37290
|
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
37324
|
-
var
|
|
37325
|
-
var
|
|
37291
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
37292
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
37326
37293
|
init_claude_history();
|
|
37327
37294
|
|
|
37328
37295
|
// src/observer/subagent-meta-observer.ts
|
|
37329
37296
|
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
37330
|
-
var
|
|
37331
|
-
var
|
|
37297
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
37298
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
37332
37299
|
init_claude_history();
|
|
37333
37300
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
37334
37301
|
var SubagentMetaObserver = class {
|
|
37335
37302
|
constructor(opts) {
|
|
37336
37303
|
this.opts = opts;
|
|
37337
|
-
this.home = opts.home ??
|
|
37304
|
+
this.home = opts.home ?? import_node_os8.default.homedir();
|
|
37338
37305
|
}
|
|
37339
37306
|
opts;
|
|
37340
37307
|
home;
|
|
37341
37308
|
watches = /* @__PURE__ */ new Map();
|
|
37342
37309
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
37343
37310
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
37344
|
-
return
|
|
37311
|
+
return import_node_path12.default.join(
|
|
37345
37312
|
this.home,
|
|
37346
37313
|
".claude",
|
|
37347
37314
|
"projects",
|
|
@@ -37397,7 +37364,7 @@ var SubagentMetaObserver = class {
|
|
|
37397
37364
|
if (!m2) return;
|
|
37398
37365
|
const agentId = m2[1];
|
|
37399
37366
|
if (w2.emitted.has(agentId)) return;
|
|
37400
|
-
const file =
|
|
37367
|
+
const file = import_node_path12.default.join(w2.dirPath, name);
|
|
37401
37368
|
let raw;
|
|
37402
37369
|
try {
|
|
37403
37370
|
raw = import_node_fs14.default.readFileSync(file, "utf8");
|
|
@@ -37445,7 +37412,7 @@ var SubagentMetaObserver = class {
|
|
|
37445
37412
|
var SessionObserver = class {
|
|
37446
37413
|
constructor(opts) {
|
|
37447
37414
|
this.opts = opts;
|
|
37448
|
-
this.home = opts.home ??
|
|
37415
|
+
this.home = opts.home ?? import_node_os9.default.homedir();
|
|
37449
37416
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
37450
37417
|
}
|
|
37451
37418
|
opts;
|
|
@@ -37457,7 +37424,7 @@ var SessionObserver = class {
|
|
|
37457
37424
|
metaObserver;
|
|
37458
37425
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
37459
37426
|
if (override) return override;
|
|
37460
|
-
return
|
|
37427
|
+
return import_node_path13.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
37461
37428
|
}
|
|
37462
37429
|
start(args) {
|
|
37463
37430
|
this.stop(args.sessionId);
|
|
@@ -37478,10 +37445,10 @@ var SessionObserver = class {
|
|
|
37478
37445
|
prevIsRejectSentinel: false
|
|
37479
37446
|
};
|
|
37480
37447
|
try {
|
|
37481
|
-
import_node_fs15.default.mkdirSync(
|
|
37448
|
+
import_node_fs15.default.mkdirSync(import_node_path13.default.dirname(filePath), { recursive: true });
|
|
37482
37449
|
} catch {
|
|
37483
37450
|
}
|
|
37484
|
-
w2.watcher = import_node_fs15.default.watch(
|
|
37451
|
+
w2.watcher = import_node_fs15.default.watch(import_node_path13.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
37485
37452
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
37486
37453
|
this.poll(w2);
|
|
37487
37454
|
});
|
|
@@ -38288,7 +38255,7 @@ async function authenticate(token, deps) {
|
|
|
38288
38255
|
|
|
38289
38256
|
// src/permission/capability-store.ts
|
|
38290
38257
|
var fs18 = __toESM(require("fs"), 1);
|
|
38291
|
-
var
|
|
38258
|
+
var path18 = __toESM(require("path"), 1);
|
|
38292
38259
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
38293
38260
|
var FILE_VERSION = 1;
|
|
38294
38261
|
var CapabilityStore = class {
|
|
@@ -38318,7 +38285,7 @@ var CapabilityStore = class {
|
|
|
38318
38285
|
this.flush();
|
|
38319
38286
|
}
|
|
38320
38287
|
filePath() {
|
|
38321
|
-
return
|
|
38288
|
+
return path18.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
38322
38289
|
}
|
|
38323
38290
|
readFromDisk() {
|
|
38324
38291
|
const file = this.filePath();
|
|
@@ -38465,7 +38432,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
38465
38432
|
|
|
38466
38433
|
// src/inbox/inbox-store.ts
|
|
38467
38434
|
var fs20 = __toESM(require("fs"), 1);
|
|
38468
|
-
var
|
|
38435
|
+
var path19 = __toESM(require("path"), 1);
|
|
38469
38436
|
var INBOX_SUBDIR = "inbox";
|
|
38470
38437
|
var InboxStore = class {
|
|
38471
38438
|
constructor(dataDir) {
|
|
@@ -38563,10 +38530,10 @@ var InboxStore = class {
|
|
|
38563
38530
|
}
|
|
38564
38531
|
}
|
|
38565
38532
|
dirPath() {
|
|
38566
|
-
return
|
|
38533
|
+
return path19.join(this.dataDir, INBOX_SUBDIR);
|
|
38567
38534
|
}
|
|
38568
38535
|
filePath(peerDeviceId) {
|
|
38569
|
-
return
|
|
38536
|
+
return path19.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
38570
38537
|
}
|
|
38571
38538
|
};
|
|
38572
38539
|
function parseAllLines(raw) {
|
|
@@ -38654,7 +38621,7 @@ var InboxManager = class {
|
|
|
38654
38621
|
|
|
38655
38622
|
// src/state/contact-store.ts
|
|
38656
38623
|
var fs21 = __toESM(require("fs"), 1);
|
|
38657
|
-
var
|
|
38624
|
+
var path20 = __toESM(require("path"), 1);
|
|
38658
38625
|
var FILE_NAME = "contacts.json";
|
|
38659
38626
|
var ContactStore = class {
|
|
38660
38627
|
constructor(dataDir) {
|
|
@@ -38664,7 +38631,7 @@ var ContactStore = class {
|
|
|
38664
38631
|
contacts = /* @__PURE__ */ new Map();
|
|
38665
38632
|
load() {
|
|
38666
38633
|
this.contacts.clear();
|
|
38667
|
-
const file =
|
|
38634
|
+
const file = path20.join(this.dataDir, FILE_NAME);
|
|
38668
38635
|
let raw;
|
|
38669
38636
|
try {
|
|
38670
38637
|
raw = fs21.readFileSync(file, "utf8");
|
|
@@ -38710,7 +38677,7 @@ var ContactStore = class {
|
|
|
38710
38677
|
return existed;
|
|
38711
38678
|
}
|
|
38712
38679
|
flush() {
|
|
38713
|
-
const file =
|
|
38680
|
+
const file = path20.join(this.dataDir, FILE_NAME);
|
|
38714
38681
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
38715
38682
|
const content = JSON.stringify(
|
|
38716
38683
|
{ contacts: Array.from(this.contacts.values()) },
|
|
@@ -38874,52 +38841,52 @@ async function autoReverseContact(args) {
|
|
|
38874
38841
|
|
|
38875
38842
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
38876
38843
|
var fs22 = __toESM(require("fs"), 1);
|
|
38877
|
-
var
|
|
38844
|
+
var path21 = __toESM(require("path"), 1);
|
|
38878
38845
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
38879
38846
|
function migrateFlattenSessions(opts) {
|
|
38880
38847
|
const dataDir = opts.dataDir;
|
|
38881
38848
|
const now = opts.now ?? Date.now;
|
|
38882
|
-
const sessionsDir =
|
|
38883
|
-
const flagPath =
|
|
38849
|
+
const sessionsDir = path21.join(dataDir, "sessions");
|
|
38850
|
+
const flagPath = path21.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
38884
38851
|
if (existsSync3(flagPath)) {
|
|
38885
38852
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
38886
38853
|
}
|
|
38887
38854
|
let movedBare = 0;
|
|
38888
38855
|
let movedVmOwner = 0;
|
|
38889
38856
|
let archivedListener = 0;
|
|
38890
|
-
const defaultDir =
|
|
38857
|
+
const defaultDir = path21.join(sessionsDir, "default");
|
|
38891
38858
|
if (existsSync3(defaultDir)) {
|
|
38892
38859
|
for (const entry of readdirSafe(defaultDir)) {
|
|
38893
38860
|
if (!entry.endsWith(".json")) continue;
|
|
38894
|
-
const src =
|
|
38895
|
-
const dst =
|
|
38861
|
+
const src = path21.join(defaultDir, entry);
|
|
38862
|
+
const dst = path21.join(sessionsDir, entry);
|
|
38896
38863
|
fs22.renameSync(src, dst);
|
|
38897
38864
|
movedBare += 1;
|
|
38898
38865
|
}
|
|
38899
38866
|
rmdirIfEmpty(defaultDir);
|
|
38900
38867
|
}
|
|
38901
38868
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
38902
|
-
const personaDir =
|
|
38869
|
+
const personaDir = path21.join(sessionsDir, pid);
|
|
38903
38870
|
if (!isDir(personaDir)) continue;
|
|
38904
38871
|
if (pid === "default") continue;
|
|
38905
|
-
const ownerSrc =
|
|
38872
|
+
const ownerSrc = path21.join(personaDir, "owner");
|
|
38906
38873
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
38907
|
-
const ownerDst =
|
|
38874
|
+
const ownerDst = path21.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
38908
38875
|
fs22.mkdirSync(ownerDst, { recursive: true });
|
|
38909
38876
|
for (const file of readdirSafe(ownerSrc)) {
|
|
38910
38877
|
if (!file.endsWith(".json")) continue;
|
|
38911
|
-
fs22.renameSync(
|
|
38878
|
+
fs22.renameSync(path21.join(ownerSrc, file), path21.join(ownerDst, file));
|
|
38912
38879
|
movedVmOwner += 1;
|
|
38913
38880
|
}
|
|
38914
38881
|
rmdirIfEmpty(ownerSrc);
|
|
38915
38882
|
}
|
|
38916
|
-
const listenerSrc =
|
|
38883
|
+
const listenerSrc = path21.join(personaDir, "listener");
|
|
38917
38884
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
38918
|
-
const archiveDst =
|
|
38885
|
+
const archiveDst = path21.join(dataDir, ".legacy", `listener-${pid}`);
|
|
38919
38886
|
fs22.mkdirSync(archiveDst, { recursive: true });
|
|
38920
38887
|
for (const file of readdirSafe(listenerSrc)) {
|
|
38921
38888
|
if (!file.endsWith(".json")) continue;
|
|
38922
|
-
fs22.renameSync(
|
|
38889
|
+
fs22.renameSync(path21.join(listenerSrc, file), path21.join(archiveDst, file));
|
|
38923
38890
|
archivedListener += 1;
|
|
38924
38891
|
}
|
|
38925
38892
|
rmdirIfEmpty(listenerSrc);
|
|
@@ -38967,10 +38934,10 @@ function rmdirIfEmpty(p2) {
|
|
|
38967
38934
|
|
|
38968
38935
|
// src/transport/http-router.ts
|
|
38969
38936
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
38970
|
-
var
|
|
38937
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
38971
38938
|
|
|
38972
38939
|
// src/attachment/mime.ts
|
|
38973
|
-
var
|
|
38940
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
38974
38941
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
38975
38942
|
var EXT_TO_NATIVE_MIME = {
|
|
38976
38943
|
// 图片
|
|
@@ -39077,7 +39044,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
39077
39044
|
".mk"
|
|
39078
39045
|
]);
|
|
39079
39046
|
function lookupMime(filePathOrName) {
|
|
39080
|
-
const ext =
|
|
39047
|
+
const ext = import_node_path14.default.extname(filePathOrName).toLowerCase();
|
|
39081
39048
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
39082
39049
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
39083
39050
|
return "application/octet-stream";
|
|
@@ -39147,7 +39114,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
39147
39114
|
|
|
39148
39115
|
// src/attachment/upload.ts
|
|
39149
39116
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
39150
|
-
var
|
|
39117
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
39151
39118
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
39152
39119
|
var import_promises = require("stream/promises");
|
|
39153
39120
|
var UploadError = class extends Error {
|
|
@@ -39159,14 +39126,14 @@ var UploadError = class extends Error {
|
|
|
39159
39126
|
code;
|
|
39160
39127
|
};
|
|
39161
39128
|
function assertValidFileName(fileName) {
|
|
39162
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
39129
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path15.default.basename(fileName)) {
|
|
39163
39130
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
39164
39131
|
}
|
|
39165
39132
|
}
|
|
39166
39133
|
var HASH_PREFIX_LEN = 16;
|
|
39167
39134
|
async function writeUploadedAttachment(args) {
|
|
39168
39135
|
assertValidFileName(args.fileName);
|
|
39169
|
-
const attachmentsRoot =
|
|
39136
|
+
const attachmentsRoot = import_node_path15.default.join(args.sessionDir, ".attachments");
|
|
39170
39137
|
try {
|
|
39171
39138
|
import_node_fs16.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
39172
39139
|
} catch (err) {
|
|
@@ -39174,7 +39141,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39174
39141
|
}
|
|
39175
39142
|
const hasher = import_node_crypto5.default.createHash("sha256");
|
|
39176
39143
|
let actualSize = 0;
|
|
39177
|
-
const tmpPath =
|
|
39144
|
+
const tmpPath = import_node_path15.default.join(
|
|
39178
39145
|
attachmentsRoot,
|
|
39179
39146
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto5.default.randomBytes(4).toString("hex")}`
|
|
39180
39147
|
);
|
|
@@ -39209,7 +39176,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39209
39176
|
);
|
|
39210
39177
|
}
|
|
39211
39178
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
39212
|
-
const hashDir =
|
|
39179
|
+
const hashDir = import_node_path15.default.join(attachmentsRoot, attachmentId);
|
|
39213
39180
|
let finalFileName;
|
|
39214
39181
|
let hashDirExists = false;
|
|
39215
39182
|
try {
|
|
@@ -39227,7 +39194,7 @@ async function writeUploadedAttachment(args) {
|
|
|
39227
39194
|
try {
|
|
39228
39195
|
import_node_fs16.default.mkdirSync(hashDir, { recursive: true });
|
|
39229
39196
|
finalFileName = args.fileName;
|
|
39230
|
-
import_node_fs16.default.renameSync(tmpPath,
|
|
39197
|
+
import_node_fs16.default.renameSync(tmpPath, import_node_path15.default.join(hashDir, finalFileName));
|
|
39231
39198
|
} catch (err) {
|
|
39232
39199
|
try {
|
|
39233
39200
|
import_node_fs16.default.unlinkSync(tmpPath);
|
|
@@ -39236,8 +39203,8 @@ async function writeUploadedAttachment(args) {
|
|
|
39236
39203
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
39237
39204
|
}
|
|
39238
39205
|
}
|
|
39239
|
-
const absPath =
|
|
39240
|
-
const relPath =
|
|
39206
|
+
const absPath = import_node_path15.default.join(hashDir, finalFileName);
|
|
39207
|
+
const relPath = import_node_path15.default.relative(args.sessionDir, absPath);
|
|
39241
39208
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
39242
39209
|
relPath: absPath,
|
|
39243
39210
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -39251,8 +39218,8 @@ async function writeUploadedAttachment(args) {
|
|
|
39251
39218
|
|
|
39252
39219
|
// src/extension/import.ts
|
|
39253
39220
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
39254
|
-
var
|
|
39255
|
-
var
|
|
39221
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
39222
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
39256
39223
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
39257
39224
|
var ImportError = class extends Error {
|
|
39258
39225
|
constructor(code, message) {
|
|
@@ -39269,7 +39236,7 @@ async function importZip(buf, root) {
|
|
|
39269
39236
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
39270
39237
|
}
|
|
39271
39238
|
for (const name of Object.keys(zip.files)) {
|
|
39272
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
39239
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path16.default.isAbsolute(name)) {
|
|
39273
39240
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
39274
39241
|
}
|
|
39275
39242
|
}
|
|
@@ -39302,7 +39269,7 @@ async function importZip(buf, root) {
|
|
|
39302
39269
|
);
|
|
39303
39270
|
}
|
|
39304
39271
|
}
|
|
39305
|
-
const destDir =
|
|
39272
|
+
const destDir = import_node_path16.default.join(root, manifest.id);
|
|
39306
39273
|
let destExists = false;
|
|
39307
39274
|
try {
|
|
39308
39275
|
await import_promises2.default.access(destDir);
|
|
@@ -39312,15 +39279,15 @@ async function importZip(buf, root) {
|
|
|
39312
39279
|
if (destExists) {
|
|
39313
39280
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
39314
39281
|
}
|
|
39315
|
-
const stage = await import_promises2.default.mkdtemp(
|
|
39282
|
+
const stage = await import_promises2.default.mkdtemp(import_node_path16.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
39316
39283
|
try {
|
|
39317
39284
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
39318
|
-
const dest =
|
|
39285
|
+
const dest = import_node_path16.default.join(stage, name);
|
|
39319
39286
|
if (entry.dir) {
|
|
39320
39287
|
await import_promises2.default.mkdir(dest, { recursive: true });
|
|
39321
39288
|
continue;
|
|
39322
39289
|
}
|
|
39323
|
-
await import_promises2.default.mkdir(
|
|
39290
|
+
await import_promises2.default.mkdir(import_node_path16.default.dirname(dest), { recursive: true });
|
|
39324
39291
|
const content = await entry.async("nodebuffer");
|
|
39325
39292
|
await import_promises2.default.writeFile(dest, content);
|
|
39326
39293
|
}
|
|
@@ -39434,7 +39401,7 @@ function isValidUploadFileName(fileName) {
|
|
|
39434
39401
|
if (fileName === "." || fileName === "..") return false;
|
|
39435
39402
|
if (fileName.startsWith(".")) return false;
|
|
39436
39403
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
39437
|
-
return fileName ===
|
|
39404
|
+
return fileName === import_node_path17.default.basename(fileName);
|
|
39438
39405
|
}
|
|
39439
39406
|
function createHttpRouter(deps) {
|
|
39440
39407
|
return async (req, res) => {
|
|
@@ -39663,7 +39630,7 @@ function createHttpRouter(deps) {
|
|
|
39663
39630
|
return true;
|
|
39664
39631
|
}
|
|
39665
39632
|
let absPath;
|
|
39666
|
-
if (
|
|
39633
|
+
if (import_node_path17.default.isAbsolute(pathParam)) {
|
|
39667
39634
|
absPath = pathParam;
|
|
39668
39635
|
} else if (deps.sessionStore) {
|
|
39669
39636
|
const file = deps.sessionStore.read(sid);
|
|
@@ -39671,7 +39638,7 @@ function createHttpRouter(deps) {
|
|
|
39671
39638
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
39672
39639
|
return true;
|
|
39673
39640
|
}
|
|
39674
|
-
absPath =
|
|
39641
|
+
absPath = import_node_path17.default.join(file.cwd, pathParam);
|
|
39675
39642
|
} else {
|
|
39676
39643
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
39677
39644
|
return true;
|
|
@@ -39769,7 +39736,7 @@ function streamFile(res, absPath, logger) {
|
|
|
39769
39736
|
return;
|
|
39770
39737
|
}
|
|
39771
39738
|
const mime = lookupMime(absPath);
|
|
39772
|
-
const basename =
|
|
39739
|
+
const basename = import_node_path17.default.basename(absPath);
|
|
39773
39740
|
res.writeHead(200, {
|
|
39774
39741
|
"Content-Type": mime,
|
|
39775
39742
|
"Content-Length": String(stat.size),
|
|
@@ -39787,7 +39754,7 @@ function streamFile(res, absPath, logger) {
|
|
|
39787
39754
|
|
|
39788
39755
|
// src/attachment/gc.ts
|
|
39789
39756
|
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
39790
|
-
var
|
|
39757
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
39791
39758
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
39792
39759
|
function runAttachmentGc(args) {
|
|
39793
39760
|
const now = (args.now ?? Date.now)();
|
|
@@ -39796,17 +39763,17 @@ function runAttachmentGc(args) {
|
|
|
39796
39763
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
39797
39764
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
39798
39765
|
if (entry.stale) continue;
|
|
39799
|
-
if (
|
|
39766
|
+
if (import_node_path18.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
39800
39767
|
}
|
|
39801
39768
|
}
|
|
39802
39769
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
39803
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
39770
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path18.default.join(
|
|
39804
39771
|
args.dataDir,
|
|
39805
39772
|
"sessions",
|
|
39806
39773
|
...scopeSubPath(scope).map(safeFileName),
|
|
39807
39774
|
safeFileName(sessionId)
|
|
39808
39775
|
);
|
|
39809
|
-
const attRoot =
|
|
39776
|
+
const attRoot = import_node_path18.default.join(sessionDir, ".attachments");
|
|
39810
39777
|
let hashDirs;
|
|
39811
39778
|
try {
|
|
39812
39779
|
hashDirs = import_node_fs18.default.readdirSync(attRoot);
|
|
@@ -39816,7 +39783,7 @@ function runAttachmentGc(args) {
|
|
|
39816
39783
|
continue;
|
|
39817
39784
|
}
|
|
39818
39785
|
for (const hashDir of hashDirs) {
|
|
39819
|
-
const hashDirAbs =
|
|
39786
|
+
const hashDirAbs = import_node_path18.default.join(attRoot, hashDir);
|
|
39820
39787
|
let files;
|
|
39821
39788
|
try {
|
|
39822
39789
|
files = import_node_fs18.default.readdirSync(hashDirAbs);
|
|
@@ -39824,7 +39791,7 @@ function runAttachmentGc(args) {
|
|
|
39824
39791
|
continue;
|
|
39825
39792
|
}
|
|
39826
39793
|
for (const name of files) {
|
|
39827
|
-
const file =
|
|
39794
|
+
const file = import_node_path18.default.join(hashDirAbs, name);
|
|
39828
39795
|
let stat;
|
|
39829
39796
|
try {
|
|
39830
39797
|
stat = import_node_fs18.default.statSync(file);
|
|
@@ -39855,7 +39822,7 @@ function runAttachmentGc(args) {
|
|
|
39855
39822
|
|
|
39856
39823
|
// src/attachment/group.ts
|
|
39857
39824
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
39858
|
-
var
|
|
39825
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
39859
39826
|
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
39860
39827
|
init_protocol();
|
|
39861
39828
|
var GroupFileStore = class {
|
|
@@ -39867,11 +39834,11 @@ var GroupFileStore = class {
|
|
|
39867
39834
|
this.logger = opts.logger;
|
|
39868
39835
|
}
|
|
39869
39836
|
rootForScope(scope) {
|
|
39870
|
-
return
|
|
39837
|
+
return import_node_path19.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
39871
39838
|
}
|
|
39872
39839
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
39873
39840
|
filePath(scope, sessionId) {
|
|
39874
|
-
return
|
|
39841
|
+
return import_node_path19.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
39875
39842
|
}
|
|
39876
39843
|
cacheKey(scope, sessionId) {
|
|
39877
39844
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -39906,7 +39873,7 @@ var GroupFileStore = class {
|
|
|
39906
39873
|
}
|
|
39907
39874
|
writeFile(scope, sessionId, entries) {
|
|
39908
39875
|
const file = this.filePath(scope, sessionId);
|
|
39909
|
-
import_node_fs19.default.mkdirSync(
|
|
39876
|
+
import_node_fs19.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
|
|
39910
39877
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
39911
39878
|
import_node_fs19.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
39912
39879
|
import_node_fs19.default.renameSync(tmp, file);
|
|
@@ -39996,9 +39963,9 @@ var GroupFileStore = class {
|
|
|
39996
39963
|
|
|
39997
39964
|
// src/discovery/state-file.ts
|
|
39998
39965
|
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
39999
|
-
var
|
|
39966
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
40000
39967
|
function defaultStateFilePath(dataDir) {
|
|
40001
|
-
return
|
|
39968
|
+
return import_node_path20.default.join(dataDir, "state.json");
|
|
40002
39969
|
}
|
|
40003
39970
|
function isPidAlive(pid) {
|
|
40004
39971
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -40034,7 +40001,7 @@ var StateFileManager = class {
|
|
|
40034
40001
|
return { status: "stale", existing };
|
|
40035
40002
|
}
|
|
40036
40003
|
write(state) {
|
|
40037
|
-
import_node_fs20.default.mkdirSync(
|
|
40004
|
+
import_node_fs20.default.mkdirSync(import_node_path20.default.dirname(this.file), { recursive: true });
|
|
40038
40005
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
40039
40006
|
import_node_fs20.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
40040
40007
|
import_node_fs20.default.renameSync(tmp, this.file);
|
|
@@ -40063,13 +40030,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
40063
40030
|
|
|
40064
40031
|
// src/tunnel/tunnel-manager.ts
|
|
40065
40032
|
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
40066
|
-
var
|
|
40033
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
40067
40034
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
40068
40035
|
var import_node_child_process9 = require("child_process");
|
|
40069
40036
|
|
|
40070
40037
|
// src/tunnel/tunnel-store.ts
|
|
40071
40038
|
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
40072
|
-
var
|
|
40039
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
40073
40040
|
var TunnelStore = class {
|
|
40074
40041
|
constructor(filePath) {
|
|
40075
40042
|
this.filePath = filePath;
|
|
@@ -40088,7 +40055,7 @@ var TunnelStore = class {
|
|
|
40088
40055
|
}
|
|
40089
40056
|
}
|
|
40090
40057
|
async set(v2) {
|
|
40091
|
-
const dir =
|
|
40058
|
+
const dir = import_node_path21.default.dirname(this.filePath);
|
|
40092
40059
|
await import_node_fs21.default.promises.mkdir(dir, { recursive: true });
|
|
40093
40060
|
const data = JSON.stringify(v2, null, 2);
|
|
40094
40061
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -40199,8 +40166,8 @@ function escape(v2) {
|
|
|
40199
40166
|
|
|
40200
40167
|
// src/tunnel/frpc-binary.ts
|
|
40201
40168
|
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
40202
|
-
var
|
|
40203
|
-
var
|
|
40169
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
40170
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
40204
40171
|
var import_node_child_process7 = require("child_process");
|
|
40205
40172
|
var import_node_stream2 = require("stream");
|
|
40206
40173
|
var import_promises3 = require("stream/promises");
|
|
@@ -40239,13 +40206,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
40239
40206
|
}
|
|
40240
40207
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
40241
40208
|
const platform = opts.platform ?? detectPlatform();
|
|
40242
|
-
const binDir =
|
|
40209
|
+
const binDir = import_node_path22.default.join(opts.dataDir, "bin");
|
|
40243
40210
|
import_node_fs22.default.mkdirSync(binDir, { recursive: true });
|
|
40244
40211
|
cleanupStaleArtifacts(binDir);
|
|
40245
|
-
const stableBin =
|
|
40212
|
+
const stableBin = import_node_path22.default.join(binDir, "frpc");
|
|
40246
40213
|
if (import_node_fs22.default.existsSync(stableBin)) return stableBin;
|
|
40247
40214
|
const partialBin = `${stableBin}.partial`;
|
|
40248
|
-
const tarballPath =
|
|
40215
|
+
const tarballPath = import_node_path22.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
40249
40216
|
try {
|
|
40250
40217
|
const url = frpcDownloadUrl(version2, platform);
|
|
40251
40218
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -40271,7 +40238,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
40271
40238
|
}
|
|
40272
40239
|
for (const name of entries) {
|
|
40273
40240
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
40274
|
-
const full =
|
|
40241
|
+
const full = import_node_path22.default.join(binDir, name);
|
|
40275
40242
|
try {
|
|
40276
40243
|
import_node_fs22.default.rmSync(full, { recursive: true, force: true });
|
|
40277
40244
|
} catch {
|
|
@@ -40297,7 +40264,7 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
40297
40264
|
await (0, import_promises3.pipeline)(nodeStream, out);
|
|
40298
40265
|
}
|
|
40299
40266
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
40300
|
-
const work =
|
|
40267
|
+
const work = import_node_path22.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
40301
40268
|
import_node_fs22.default.mkdirSync(work, { recursive: true });
|
|
40302
40269
|
try {
|
|
40303
40270
|
await new Promise((resolve6, reject) => {
|
|
@@ -40306,7 +40273,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
40306
40273
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
40307
40274
|
});
|
|
40308
40275
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
40309
|
-
const src =
|
|
40276
|
+
const src = import_node_path22.default.join(work, dirName, "frpc");
|
|
40310
40277
|
if (!import_node_fs22.default.existsSync(src)) {
|
|
40311
40278
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
40312
40279
|
}
|
|
@@ -40318,10 +40285,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
40318
40285
|
|
|
40319
40286
|
// src/tunnel/frpc-process.ts
|
|
40320
40287
|
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
40321
|
-
var
|
|
40288
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
40322
40289
|
var import_node_child_process8 = require("child_process");
|
|
40323
40290
|
function frpcPidFilePath(dataDir) {
|
|
40324
|
-
return
|
|
40291
|
+
return import_node_path23.default.join(dataDir, "frpc.pid");
|
|
40325
40292
|
}
|
|
40326
40293
|
function writeFrpcPid(dataDir, pid) {
|
|
40327
40294
|
try {
|
|
@@ -40363,7 +40330,7 @@ function defaultSleep(ms) {
|
|
|
40363
40330
|
}
|
|
40364
40331
|
async function killStaleFrpc(deps) {
|
|
40365
40332
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
40366
|
-
const tomlPath =
|
|
40333
|
+
const tomlPath = import_node_path23.default.join(deps.dataDir, "frpc.toml");
|
|
40367
40334
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
40368
40335
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
40369
40336
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -40435,7 +40402,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
40435
40402
|
var TunnelManager = class {
|
|
40436
40403
|
constructor(deps) {
|
|
40437
40404
|
this.deps = deps;
|
|
40438
|
-
this.store = deps.store ?? new TunnelStore(
|
|
40405
|
+
this.store = deps.store ?? new TunnelStore(import_node_path24.default.join(deps.dataDir, "tunnel.json"));
|
|
40439
40406
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
40440
40407
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
40441
40408
|
}
|
|
@@ -40562,7 +40529,7 @@ var TunnelManager = class {
|
|
|
40562
40529
|
dataDir: this.deps.dataDir,
|
|
40563
40530
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
40564
40531
|
});
|
|
40565
|
-
const tomlPath =
|
|
40532
|
+
const tomlPath = import_node_path24.default.join(this.deps.dataDir, "frpc.toml");
|
|
40566
40533
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto7.default.randomBytes(3).toString("hex")}`;
|
|
40567
40534
|
const toml = buildFrpcToml({
|
|
40568
40535
|
serverAddr: t.frpsHost,
|
|
@@ -40577,7 +40544,7 @@ var TunnelManager = class {
|
|
|
40577
40544
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
40578
40545
|
stdio: ["ignore", "pipe", "pipe"]
|
|
40579
40546
|
});
|
|
40580
|
-
const logFilePath =
|
|
40547
|
+
const logFilePath = import_node_path24.default.join(this.deps.dataDir, "frpc.log");
|
|
40581
40548
|
const logStream = import_node_fs24.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
40582
40549
|
logStream.on("error", () => {
|
|
40583
40550
|
});
|
|
@@ -40660,16 +40627,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
40660
40627
|
}
|
|
40661
40628
|
|
|
40662
40629
|
// src/tunnel/device-key.ts
|
|
40663
|
-
var
|
|
40664
|
-
var
|
|
40630
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
40631
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
40665
40632
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
40666
40633
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
40667
40634
|
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 ?
|
|
40635
|
+
const hostname = opts.hostname ?? import_node_os12.default.hostname();
|
|
40636
|
+
const uid = opts.uid ?? (typeof import_node_os12.default.userInfo === "function" ? import_node_os12.default.userInfo().uid : 0);
|
|
40637
|
+
const home = opts.home ?? import_node_os12.default.homedir();
|
|
40638
|
+
const defaultDataDir = import_node_path25.default.resolve(import_node_path25.default.join(home, ".clawd"));
|
|
40639
|
+
const normalizedDataDir = opts.dataDir ? import_node_path25.default.resolve(opts.dataDir) : null;
|
|
40673
40640
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
40674
40641
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
40675
40642
|
return import_node_crypto8.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
@@ -40677,11 +40644,11 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
40677
40644
|
|
|
40678
40645
|
// src/auth-store.ts
|
|
40679
40646
|
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
40680
|
-
var
|
|
40647
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
40681
40648
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
40682
40649
|
var AUTH_FILE_NAME = "auth.json";
|
|
40683
40650
|
function authFilePath(dataDir) {
|
|
40684
|
-
return
|
|
40651
|
+
return import_node_path26.default.join(dataDir, AUTH_FILE_NAME);
|
|
40685
40652
|
}
|
|
40686
40653
|
function loadOrCreateAuthFile(opts) {
|
|
40687
40654
|
const file = authFilePath(opts.dataDir);
|
|
@@ -40734,7 +40701,7 @@ function readAuthFile(file) {
|
|
|
40734
40701
|
}
|
|
40735
40702
|
}
|
|
40736
40703
|
function writeAuthFile(file, content) {
|
|
40737
|
-
import_node_fs25.default.mkdirSync(
|
|
40704
|
+
import_node_fs25.default.mkdirSync(import_node_path26.default.dirname(file), { recursive: true });
|
|
40738
40705
|
import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
40739
40706
|
try {
|
|
40740
40707
|
import_node_fs25.default.chmodSync(file, 384);
|
|
@@ -40744,12 +40711,12 @@ function writeAuthFile(file, content) {
|
|
|
40744
40711
|
|
|
40745
40712
|
// src/owner-profile.ts
|
|
40746
40713
|
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
40747
|
-
var
|
|
40748
|
-
var
|
|
40714
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
40715
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
40749
40716
|
var PROFILE_FILENAME = "profile.json";
|
|
40750
40717
|
function loadOwnerDisplayName(dataDir) {
|
|
40751
|
-
const fallback =
|
|
40752
|
-
const profilePath =
|
|
40718
|
+
const fallback = import_node_os13.default.userInfo().username;
|
|
40719
|
+
const profilePath = import_node_path27.default.join(dataDir, PROFILE_FILENAME);
|
|
40753
40720
|
let raw;
|
|
40754
40721
|
try {
|
|
40755
40722
|
raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
|
|
@@ -40776,12 +40743,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
40776
40743
|
|
|
40777
40744
|
// src/feishu-auth/owner-identity-store.ts
|
|
40778
40745
|
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
40779
|
-
var
|
|
40746
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
40780
40747
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
40781
40748
|
var OwnerIdentityStore = class {
|
|
40782
40749
|
file;
|
|
40783
40750
|
constructor(dataDir) {
|
|
40784
|
-
this.file =
|
|
40751
|
+
this.file = import_node_path28.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
40785
40752
|
}
|
|
40786
40753
|
read() {
|
|
40787
40754
|
let raw;
|
|
@@ -40813,7 +40780,7 @@ var OwnerIdentityStore = class {
|
|
|
40813
40780
|
};
|
|
40814
40781
|
}
|
|
40815
40782
|
write(record) {
|
|
40816
|
-
import_node_fs27.default.mkdirSync(
|
|
40783
|
+
import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(this.file), { recursive: true });
|
|
40817
40784
|
import_node_fs27.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
40818
40785
|
try {
|
|
40819
40786
|
import_node_fs27.default.chmodSync(this.file, 384);
|
|
@@ -40941,9 +40908,9 @@ var CentralClientError = class extends Error {
|
|
|
40941
40908
|
code;
|
|
40942
40909
|
cause;
|
|
40943
40910
|
};
|
|
40944
|
-
async function centralRequest(opts,
|
|
40911
|
+
async function centralRequest(opts, path58, init) {
|
|
40945
40912
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
40946
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
40913
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path58}`;
|
|
40947
40914
|
const ctrl = new AbortController();
|
|
40948
40915
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
40949
40916
|
let res;
|
|
@@ -41086,7 +41053,7 @@ function verifyConnectToken(args) {
|
|
|
41086
41053
|
|
|
41087
41054
|
// src/feishu-auth/server-key.ts
|
|
41088
41055
|
var fs36 = __toESM(require("fs"), 1);
|
|
41089
|
-
var
|
|
41056
|
+
var path37 = __toESM(require("path"), 1);
|
|
41090
41057
|
var FILE_NAME2 = "server-signing-key.json";
|
|
41091
41058
|
var ServerKeyStore = class {
|
|
41092
41059
|
constructor(dataDir) {
|
|
@@ -41094,7 +41061,7 @@ var ServerKeyStore = class {
|
|
|
41094
41061
|
}
|
|
41095
41062
|
dataDir;
|
|
41096
41063
|
filePath() {
|
|
41097
|
-
return
|
|
41064
|
+
return path37.join(this.dataDir, FILE_NAME2);
|
|
41098
41065
|
}
|
|
41099
41066
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
41100
41067
|
read() {
|
|
@@ -41133,8 +41100,8 @@ init_protocol();
|
|
|
41133
41100
|
|
|
41134
41101
|
// src/session/fork.ts
|
|
41135
41102
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
41136
|
-
var
|
|
41137
|
-
var
|
|
41103
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
41104
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
41138
41105
|
init_claude_history();
|
|
41139
41106
|
function readJsonlEntries(file) {
|
|
41140
41107
|
const raw = import_node_fs28.default.readFileSync(file, "utf8");
|
|
@@ -41150,9 +41117,9 @@ function readJsonlEntries(file) {
|
|
|
41150
41117
|
return out;
|
|
41151
41118
|
}
|
|
41152
41119
|
function forkSession(input) {
|
|
41153
|
-
const baseDir = input.baseDir ??
|
|
41154
|
-
const projectDir =
|
|
41155
|
-
const sourceFile =
|
|
41120
|
+
const baseDir = input.baseDir ?? import_node_path29.default.join(import_node_os14.default.homedir(), ".claude");
|
|
41121
|
+
const projectDir = import_node_path29.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
41122
|
+
const sourceFile = import_node_path29.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
41156
41123
|
if (!import_node_fs28.default.existsSync(sourceFile)) {
|
|
41157
41124
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
41158
41125
|
}
|
|
@@ -41183,7 +41150,7 @@ function forkSession(input) {
|
|
|
41183
41150
|
}
|
|
41184
41151
|
forkedLines.push(JSON.stringify(forked));
|
|
41185
41152
|
}
|
|
41186
|
-
const forkedFilePath =
|
|
41153
|
+
const forkedFilePath = import_node_path29.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
41187
41154
|
import_node_fs28.default.mkdirSync(projectDir, { recursive: true });
|
|
41188
41155
|
import_node_fs28.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
41189
41156
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -41561,7 +41528,7 @@ function buildPermissionHandlers(deps) {
|
|
|
41561
41528
|
}
|
|
41562
41529
|
|
|
41563
41530
|
// src/handlers/history.ts
|
|
41564
|
-
var
|
|
41531
|
+
var path40 = __toESM(require("path"), 1);
|
|
41565
41532
|
init_protocol();
|
|
41566
41533
|
|
|
41567
41534
|
// src/session/recent-dirs.ts
|
|
@@ -41579,7 +41546,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
41579
41546
|
}
|
|
41580
41547
|
|
|
41581
41548
|
// src/permission/persona-paths.ts
|
|
41582
|
-
var
|
|
41549
|
+
var path39 = __toESM(require("path"), 1);
|
|
41583
41550
|
function getAllowedPersonaIds(grants, action) {
|
|
41584
41551
|
const ids = /* @__PURE__ */ new Set();
|
|
41585
41552
|
for (const g2 of grants) {
|
|
@@ -41592,31 +41559,31 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
41592
41559
|
return ids;
|
|
41593
41560
|
}
|
|
41594
41561
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
41595
|
-
const target =
|
|
41562
|
+
const target = path39.resolve(absPath);
|
|
41596
41563
|
if (userWorkDir) {
|
|
41597
|
-
const u =
|
|
41598
|
-
const usep = u.endsWith(
|
|
41564
|
+
const u = path39.resolve(userWorkDir);
|
|
41565
|
+
const usep = u.endsWith(path39.sep) ? "" : path39.sep;
|
|
41599
41566
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
41600
41567
|
}
|
|
41601
|
-
const root =
|
|
41602
|
-
const sep2 = root.endsWith(
|
|
41568
|
+
const root = path39.resolve(personaRoot);
|
|
41569
|
+
const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
|
|
41603
41570
|
if (!target.startsWith(root + sep2)) return false;
|
|
41604
|
-
const rel =
|
|
41571
|
+
const rel = path39.relative(root, target);
|
|
41605
41572
|
if (!rel || rel.startsWith("..")) return false;
|
|
41606
|
-
const personaId = rel.split(
|
|
41573
|
+
const personaId = rel.split(path39.sep)[0];
|
|
41607
41574
|
if (!personaId) return false;
|
|
41608
41575
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
41609
41576
|
if (allowed === "*") return true;
|
|
41610
41577
|
return allowed.has(personaId);
|
|
41611
41578
|
}
|
|
41612
41579
|
function personaIdFromPath(absPath, personaRoot) {
|
|
41613
|
-
const root =
|
|
41614
|
-
const target =
|
|
41615
|
-
const sep2 = root.endsWith(
|
|
41580
|
+
const root = path39.resolve(personaRoot);
|
|
41581
|
+
const target = path39.resolve(absPath);
|
|
41582
|
+
const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
|
|
41616
41583
|
if (!target.startsWith(root + sep2)) return null;
|
|
41617
|
-
const rel =
|
|
41584
|
+
const rel = path39.relative(root, target);
|
|
41618
41585
|
if (!rel || rel.startsWith("..")) return null;
|
|
41619
|
-
const id = rel.split(
|
|
41586
|
+
const id = rel.split(path39.sep)[0];
|
|
41620
41587
|
return id || null;
|
|
41621
41588
|
}
|
|
41622
41589
|
|
|
@@ -41643,7 +41610,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41643
41610
|
if (!pid) return false;
|
|
41644
41611
|
return isGuestPathAllowed(
|
|
41645
41612
|
ctx.grants,
|
|
41646
|
-
|
|
41613
|
+
path40.join(personaRoot, pid),
|
|
41647
41614
|
personaRoot,
|
|
41648
41615
|
"read",
|
|
41649
41616
|
userWorkDir
|
|
@@ -41655,7 +41622,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41655
41622
|
};
|
|
41656
41623
|
const list = async (frame, _client, ctx) => {
|
|
41657
41624
|
const args = HistoryListArgs.parse(frame);
|
|
41658
|
-
assertGuestPath(ctx,
|
|
41625
|
+
assertGuestPath(ctx, path40.resolve(args.projectPath), personaRoot, "history:list");
|
|
41659
41626
|
const sessions = await history.listSessions(args);
|
|
41660
41627
|
return { response: { type: "history:list", sessions } };
|
|
41661
41628
|
};
|
|
@@ -41687,13 +41654,13 @@ function buildHistoryHandlers(deps) {
|
|
|
41687
41654
|
};
|
|
41688
41655
|
const subagents = async (frame, _client, ctx) => {
|
|
41689
41656
|
const args = HistorySubagentsArgs.parse(frame);
|
|
41690
|
-
assertGuestPath(ctx,
|
|
41657
|
+
assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
41691
41658
|
const subs = await history.listSubagents(args);
|
|
41692
41659
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
41693
41660
|
};
|
|
41694
41661
|
const subagentRead = async (frame, _client, ctx) => {
|
|
41695
41662
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
41696
|
-
assertGuestPath(ctx,
|
|
41663
|
+
assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
41697
41664
|
const res = await history.readSubagent(args);
|
|
41698
41665
|
return { response: { type: "history:subagent-read", ...res } };
|
|
41699
41666
|
};
|
|
@@ -41702,7 +41669,7 @@ function buildHistoryHandlers(deps) {
|
|
|
41702
41669
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
41703
41670
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
41704
41671
|
const filtered = dirs.filter(
|
|
41705
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
41672
|
+
(d) => isGuestPathAllowed(ctx.grants, path40.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
41706
41673
|
);
|
|
41707
41674
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
41708
41675
|
}
|
|
@@ -41719,8 +41686,8 @@ function buildHistoryHandlers(deps) {
|
|
|
41719
41686
|
}
|
|
41720
41687
|
|
|
41721
41688
|
// src/handlers/workspace.ts
|
|
41722
|
-
var
|
|
41723
|
-
var
|
|
41689
|
+
var path41 = __toESM(require("path"), 1);
|
|
41690
|
+
var os15 = __toESM(require("os"), 1);
|
|
41724
41691
|
init_protocol();
|
|
41725
41692
|
init_protocol();
|
|
41726
41693
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -41760,23 +41727,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41760
41727
|
const list = async (frame, _client, ctx) => {
|
|
41761
41728
|
const args = WorkspaceListArgs.parse(frame);
|
|
41762
41729
|
const isGuest = ctx?.principal.kind === "guest";
|
|
41763
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
41764
|
-
const resolvedCwd =
|
|
41765
|
-
const target = args.path ?
|
|
41730
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
|
|
41731
|
+
const resolvedCwd = path41.resolve(args.cwd ?? fallbackCwd);
|
|
41732
|
+
const target = args.path ? path41.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
41766
41733
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
41767
41734
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
41768
41735
|
return { response: { type: "workspace:list", ...res } };
|
|
41769
41736
|
};
|
|
41770
41737
|
const read = async (frame, _client, ctx) => {
|
|
41771
41738
|
const args = WorkspaceReadArgs.parse(frame);
|
|
41772
|
-
const target =
|
|
41739
|
+
const target = path41.isAbsolute(args.path) ? path41.resolve(args.path) : path41.resolve(args.cwd, args.path);
|
|
41773
41740
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
41774
41741
|
const res = workspace.read(args);
|
|
41775
41742
|
return { response: { type: "workspace:read", ...res } };
|
|
41776
41743
|
};
|
|
41777
41744
|
const skillsList = async (frame, _client, ctx) => {
|
|
41778
41745
|
const args = SkillsListArgs.parse(frame);
|
|
41779
|
-
const cwdAbs =
|
|
41746
|
+
const cwdAbs = path41.resolve(args.cwd);
|
|
41780
41747
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
41781
41748
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
41782
41749
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -41788,7 +41755,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41788
41755
|
};
|
|
41789
41756
|
const agentsList = async (frame, _client, ctx) => {
|
|
41790
41757
|
const args = AgentsListArgs.parse(frame);
|
|
41791
|
-
const cwdAbs =
|
|
41758
|
+
const cwdAbs = path41.resolve(args.cwd);
|
|
41792
41759
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
41793
41760
|
if (args.tool === "codex") {
|
|
41794
41761
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -41810,18 +41777,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
41810
41777
|
}
|
|
41811
41778
|
|
|
41812
41779
|
// src/handlers/git.ts
|
|
41813
|
-
var
|
|
41780
|
+
var path43 = __toESM(require("path"), 1);
|
|
41814
41781
|
init_protocol();
|
|
41815
41782
|
init_protocol();
|
|
41816
41783
|
|
|
41817
41784
|
// src/workspace/git.ts
|
|
41818
41785
|
var import_node_child_process10 = require("child_process");
|
|
41819
41786
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
41820
|
-
var
|
|
41787
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
41821
41788
|
var import_node_util = require("util");
|
|
41822
41789
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
41823
41790
|
function normalizePath(p2) {
|
|
41824
|
-
const resolved =
|
|
41791
|
+
const resolved = import_node_path30.default.resolve(p2);
|
|
41825
41792
|
try {
|
|
41826
41793
|
return import_node_fs29.default.realpathSync(resolved);
|
|
41827
41794
|
} catch {
|
|
@@ -41897,7 +41864,7 @@ async function listGitBranches(cwd) {
|
|
|
41897
41864
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
41898
41865
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
41899
41866
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
41900
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
41867
|
+
if (!isGuestPathAllowed(ctx.grants, path43.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
41901
41868
|
throw new ClawdError(
|
|
41902
41869
|
ERROR_CODES.UNAUTHORIZED,
|
|
41903
41870
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -42285,7 +42252,7 @@ function buildDeviceHandlers(deps) {
|
|
|
42285
42252
|
}
|
|
42286
42253
|
|
|
42287
42254
|
// src/handlers/meta.ts
|
|
42288
|
-
var
|
|
42255
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
42289
42256
|
init_protocol();
|
|
42290
42257
|
|
|
42291
42258
|
// src/version.ts
|
|
@@ -42316,7 +42283,7 @@ function buildReadyFrame(deps, client) {
|
|
|
42316
42283
|
return {
|
|
42317
42284
|
version,
|
|
42318
42285
|
protocolVersion: PROTOCOL_VERSION,
|
|
42319
|
-
hostname:
|
|
42286
|
+
hostname: import_node_os15.default.hostname(),
|
|
42320
42287
|
os: process.platform,
|
|
42321
42288
|
tools,
|
|
42322
42289
|
runningSessions: info.runningSessions,
|
|
@@ -42411,7 +42378,7 @@ function buildPersonaHandlers(deps) {
|
|
|
42411
42378
|
}
|
|
42412
42379
|
|
|
42413
42380
|
// src/handlers/attachment.ts
|
|
42414
|
-
var
|
|
42381
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
42415
42382
|
init_protocol();
|
|
42416
42383
|
init_protocol();
|
|
42417
42384
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -42466,12 +42433,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
42466
42433
|
`session ${args.sessionId} scope unresolved`
|
|
42467
42434
|
);
|
|
42468
42435
|
}
|
|
42469
|
-
const cwdAbs =
|
|
42470
|
-
const candidateAbs =
|
|
42436
|
+
const cwdAbs = import_node_path31.default.resolve(sessionFile.cwd);
|
|
42437
|
+
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
42438
|
assertGuestAttachmentPath(ctx, candidateAbs, deps.personaRoot, "attachment.signUrl", deps.usersRoot);
|
|
42472
42439
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
42473
42440
|
const entry = entries.find((e) => {
|
|
42474
|
-
const storedAbs =
|
|
42441
|
+
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
42442
|
return storedAbs === candidateAbs && !e.stale;
|
|
42476
42443
|
});
|
|
42477
42444
|
if (!entry) {
|
|
@@ -42495,7 +42462,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
42495
42462
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
42496
42463
|
const f = deps.sessionStore.read(sessionId);
|
|
42497
42464
|
if (!f) return;
|
|
42498
|
-
assertGuestAttachmentPath(ctx,
|
|
42465
|
+
assertGuestAttachmentPath(ctx, import_node_path31.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
42499
42466
|
}
|
|
42500
42467
|
const groupAdd = async (frame, _client, ctx) => {
|
|
42501
42468
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -42567,19 +42534,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
42567
42534
|
|
|
42568
42535
|
// src/handlers/extension.ts
|
|
42569
42536
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
42570
|
-
var
|
|
42537
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
42571
42538
|
init_protocol();
|
|
42572
42539
|
|
|
42573
42540
|
// src/extension/bundle-zip.ts
|
|
42574
42541
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
42575
|
-
var
|
|
42542
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
42576
42543
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
42577
42544
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
42578
42545
|
async function bundleExtensionDir(dir) {
|
|
42579
42546
|
const entries = await listFilesSorted(dir);
|
|
42580
42547
|
const zip = new import_jszip2.default();
|
|
42581
42548
|
for (const rel of entries) {
|
|
42582
|
-
const abs =
|
|
42549
|
+
const abs = import_node_path32.default.join(dir, rel);
|
|
42583
42550
|
const content = await import_promises4.default.readFile(abs);
|
|
42584
42551
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
42585
42552
|
}
|
|
@@ -42600,7 +42567,7 @@ async function listFilesSorted(rootDir) {
|
|
|
42600
42567
|
return out;
|
|
42601
42568
|
}
|
|
42602
42569
|
async function walk(absRoot, relPrefix, out) {
|
|
42603
|
-
const dirAbs =
|
|
42570
|
+
const dirAbs = import_node_path32.default.join(absRoot, relPrefix);
|
|
42604
42571
|
const entries = await import_promises4.default.readdir(dirAbs, { withFileTypes: true });
|
|
42605
42572
|
for (const e of entries) {
|
|
42606
42573
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -42654,25 +42621,25 @@ function computePublishCheck(args) {
|
|
|
42654
42621
|
|
|
42655
42622
|
// src/extension/install-flow.ts
|
|
42656
42623
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
42657
|
-
var
|
|
42658
|
-
var
|
|
42624
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
42625
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
42659
42626
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
42660
42627
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
42661
42628
|
|
|
42662
42629
|
// src/extension/paths.ts
|
|
42663
|
-
var
|
|
42664
|
-
var
|
|
42630
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
42631
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
42665
42632
|
function clawdHomeRoot(override) {
|
|
42666
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
42633
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path33.default.join(import_node_os16.default.homedir(), ".clawd");
|
|
42667
42634
|
}
|
|
42668
42635
|
function extensionsRoot(override) {
|
|
42669
|
-
return
|
|
42636
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extensions");
|
|
42670
42637
|
}
|
|
42671
42638
|
function publishedChannelsFile(override) {
|
|
42672
|
-
return
|
|
42639
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
42673
42640
|
}
|
|
42674
42641
|
function bundleCacheRoot(override) {
|
|
42675
|
-
return
|
|
42642
|
+
return import_node_path33.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
42676
42643
|
}
|
|
42677
42644
|
|
|
42678
42645
|
// src/extension/install-flow.ts
|
|
@@ -42699,7 +42666,7 @@ async function installFromChannel(args, deps) {
|
|
|
42699
42666
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
42700
42667
|
}
|
|
42701
42668
|
for (const name of Object.keys(zip.files)) {
|
|
42702
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
42669
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path34.default.isAbsolute(name)) {
|
|
42703
42670
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
42704
42671
|
}
|
|
42705
42672
|
}
|
|
@@ -42731,7 +42698,7 @@ async function installFromChannel(args, deps) {
|
|
|
42731
42698
|
);
|
|
42732
42699
|
}
|
|
42733
42700
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
42734
|
-
const destDir =
|
|
42701
|
+
const destDir = import_node_path34.default.join(deps.extensionsRoot, localExtId);
|
|
42735
42702
|
let destExists = false;
|
|
42736
42703
|
try {
|
|
42737
42704
|
await import_promises5.default.access(destDir);
|
|
@@ -42745,16 +42712,16 @@ async function installFromChannel(args, deps) {
|
|
|
42745
42712
|
);
|
|
42746
42713
|
}
|
|
42747
42714
|
const stage = await import_promises5.default.mkdtemp(
|
|
42748
|
-
|
|
42715
|
+
import_node_path34.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
42749
42716
|
);
|
|
42750
42717
|
try {
|
|
42751
42718
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
42752
|
-
const dest =
|
|
42719
|
+
const dest = import_node_path34.default.join(stage, name);
|
|
42753
42720
|
if (entry.dir) {
|
|
42754
42721
|
await import_promises5.default.mkdir(dest, { recursive: true });
|
|
42755
42722
|
continue;
|
|
42756
42723
|
}
|
|
42757
|
-
await import_promises5.default.mkdir(
|
|
42724
|
+
await import_promises5.default.mkdir(import_node_path34.default.dirname(dest), { recursive: true });
|
|
42758
42725
|
if (name === "manifest.json") {
|
|
42759
42726
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
42760
42727
|
await import_promises5.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -42775,8 +42742,8 @@ async function installFromChannel(args, deps) {
|
|
|
42775
42742
|
|
|
42776
42743
|
// src/extension/update-flow.ts
|
|
42777
42744
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
42778
|
-
var
|
|
42779
|
-
var
|
|
42745
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
42746
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
42780
42747
|
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
42781
42748
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
42782
42749
|
var UpdateError = class extends Error {
|
|
@@ -42792,11 +42759,11 @@ async function updateFromChannel(args, deps) {
|
|
|
42792
42759
|
channelRef.extId,
|
|
42793
42760
|
channelRef.ownerPrincipalId
|
|
42794
42761
|
);
|
|
42795
|
-
const liveDir =
|
|
42762
|
+
const liveDir = import_node_path35.default.join(deps.extensionsRoot, localExtId);
|
|
42796
42763
|
const prevDir = `${liveDir}.prev`;
|
|
42797
42764
|
let existingVersion;
|
|
42798
42765
|
try {
|
|
42799
|
-
const raw = await import_promises6.default.readFile(
|
|
42766
|
+
const raw = await import_promises6.default.readFile(import_node_path35.default.join(liveDir, "manifest.json"), "utf8");
|
|
42800
42767
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
42801
42768
|
if (!parsed2.success) {
|
|
42802
42769
|
throw new UpdateError(
|
|
@@ -42829,7 +42796,7 @@ async function updateFromChannel(args, deps) {
|
|
|
42829
42796
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
42830
42797
|
}
|
|
42831
42798
|
for (const name of Object.keys(zip.files)) {
|
|
42832
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
42799
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path35.default.isAbsolute(name)) {
|
|
42833
42800
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
42834
42801
|
}
|
|
42835
42802
|
}
|
|
@@ -42864,16 +42831,16 @@ async function updateFromChannel(args, deps) {
|
|
|
42864
42831
|
await import_promises6.default.rm(prevDir, { recursive: true, force: true });
|
|
42865
42832
|
await import_promises6.default.rename(liveDir, prevDir);
|
|
42866
42833
|
const stage = await import_promises6.default.mkdtemp(
|
|
42867
|
-
|
|
42834
|
+
import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
42868
42835
|
);
|
|
42869
42836
|
try {
|
|
42870
42837
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
42871
|
-
const dest =
|
|
42838
|
+
const dest = import_node_path35.default.join(stage, name);
|
|
42872
42839
|
if (entry.dir) {
|
|
42873
42840
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
42874
42841
|
continue;
|
|
42875
42842
|
}
|
|
42876
|
-
await import_promises6.default.mkdir(
|
|
42843
|
+
await import_promises6.default.mkdir(import_node_path35.default.dirname(dest), { recursive: true });
|
|
42877
42844
|
if (name === "manifest.json") {
|
|
42878
42845
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
42879
42846
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -42966,7 +42933,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
42966
42933
|
);
|
|
42967
42934
|
}
|
|
42968
42935
|
}
|
|
42969
|
-
const manifestPath =
|
|
42936
|
+
const manifestPath = import_node_path36.default.join(root, extId, "manifest.json");
|
|
42970
42937
|
const manifest = await readManifest(root, extId);
|
|
42971
42938
|
const next = { ...manifest, version: newVersion };
|
|
42972
42939
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -42974,7 +42941,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
42974
42941
|
await import_promises7.default.rename(tmp, manifestPath);
|
|
42975
42942
|
}
|
|
42976
42943
|
async function readManifest(root, extId) {
|
|
42977
|
-
const file =
|
|
42944
|
+
const file = import_node_path36.default.join(root, extId, "manifest.json");
|
|
42978
42945
|
let raw;
|
|
42979
42946
|
try {
|
|
42980
42947
|
raw = await import_promises7.default.readFile(file, "utf8");
|
|
@@ -43065,7 +43032,7 @@ function buildExtensionHandlers(deps) {
|
|
|
43065
43032
|
};
|
|
43066
43033
|
async function buildSnapshotMeta(extId) {
|
|
43067
43034
|
const manifest = await readManifest(deps.root, extId);
|
|
43068
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
43035
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path36.default.join(deps.root, extId));
|
|
43069
43036
|
return { manifest, contentHash: sha256, buffer };
|
|
43070
43037
|
}
|
|
43071
43038
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -43362,7 +43329,7 @@ var PublishJobRegistry = class {
|
|
|
43362
43329
|
// src/app-builder/publish-job-runner.ts
|
|
43363
43330
|
var import_node_child_process12 = require("child_process");
|
|
43364
43331
|
var import_node_fs30 = require("fs");
|
|
43365
|
-
var
|
|
43332
|
+
var import_node_path37 = require("path");
|
|
43366
43333
|
|
|
43367
43334
|
// src/app-builder/publish-stage-parser.ts
|
|
43368
43335
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -43394,7 +43361,7 @@ async function startPublishJob(deps, args) {
|
|
|
43394
43361
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
43395
43362
|
}
|
|
43396
43363
|
const projDir = projectDir(args.name);
|
|
43397
|
-
const logPath = (0,
|
|
43364
|
+
const logPath = (0, import_node_path37.join)(projDir, ".publish.log");
|
|
43398
43365
|
let logStream = null;
|
|
43399
43366
|
try {
|
|
43400
43367
|
logStream = (0, import_node_fs30.createWriteStream)(logPath, { flags: "w" });
|
|
@@ -43654,7 +43621,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
43654
43621
|
|
|
43655
43622
|
// src/handlers/app-builder.ts
|
|
43656
43623
|
init_protocol();
|
|
43657
|
-
var
|
|
43624
|
+
var import_node_path38 = require("path");
|
|
43658
43625
|
var import_node_fs31 = require("fs");
|
|
43659
43626
|
var APP_BUILDER_PERSONAS = ["persona-app-builder"];
|
|
43660
43627
|
var PUBLISH_SCRIPT_REL = "extension-kit/scripts/publish.sh";
|
|
@@ -44031,7 +43998,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
44031
43998
|
});
|
|
44032
43999
|
await userStore.clearPublishJob(args.name);
|
|
44033
44000
|
}
|
|
44034
|
-
const scriptPath = (0,
|
|
44001
|
+
const scriptPath = (0, import_node_path38.join)(deps.personaRoot, PUBLISH_SCRIPT_REL);
|
|
44035
44002
|
deps.logger?.info("app-builder.publish.start", {
|
|
44036
44003
|
name: args.name,
|
|
44037
44004
|
sessionId: boundSession.sessionId,
|
|
@@ -44125,7 +44092,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
44125
44092
|
|
|
44126
44093
|
// src/extension/registry.ts
|
|
44127
44094
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
44128
|
-
var
|
|
44095
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
44129
44096
|
async function loadAll(root) {
|
|
44130
44097
|
let entries;
|
|
44131
44098
|
try {
|
|
@@ -44138,13 +44105,13 @@ async function loadAll(root) {
|
|
|
44138
44105
|
for (const ent of entries) {
|
|
44139
44106
|
if (!ent.isDirectory()) continue;
|
|
44140
44107
|
if (ent.name.startsWith(".")) continue;
|
|
44141
|
-
records.push(await loadOne(
|
|
44108
|
+
records.push(await loadOne(import_node_path39.default.join(root, ent.name), ent.name));
|
|
44142
44109
|
}
|
|
44143
44110
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
44144
44111
|
return records;
|
|
44145
44112
|
}
|
|
44146
44113
|
async function loadOne(dir, dirName) {
|
|
44147
|
-
const manifestPath =
|
|
44114
|
+
const manifestPath = import_node_path39.default.join(dir, "manifest.json");
|
|
44148
44115
|
let raw;
|
|
44149
44116
|
try {
|
|
44150
44117
|
raw = await import_promises8.default.readFile(manifestPath, "utf8");
|
|
@@ -44189,7 +44156,7 @@ async function loadOne(dir, dirName) {
|
|
|
44189
44156
|
|
|
44190
44157
|
// src/extension/uninstall.ts
|
|
44191
44158
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
44192
|
-
var
|
|
44159
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
44193
44160
|
var UninstallError = class extends Error {
|
|
44194
44161
|
constructor(code, message) {
|
|
44195
44162
|
super(message);
|
|
@@ -44198,7 +44165,7 @@ var UninstallError = class extends Error {
|
|
|
44198
44165
|
code;
|
|
44199
44166
|
};
|
|
44200
44167
|
async function uninstall(deps) {
|
|
44201
|
-
const dir =
|
|
44168
|
+
const dir = import_node_path40.default.join(deps.root, deps.extId);
|
|
44202
44169
|
try {
|
|
44203
44170
|
await import_promises9.default.access(dir);
|
|
44204
44171
|
} catch {
|
|
@@ -44279,7 +44246,7 @@ function buildMethodHandlers(deps) {
|
|
|
44279
44246
|
// src/app-builder/project-store.ts
|
|
44280
44247
|
var import_node_fs32 = require("fs");
|
|
44281
44248
|
var import_node_child_process13 = require("child_process");
|
|
44282
|
-
var
|
|
44249
|
+
var import_node_path41 = require("path");
|
|
44283
44250
|
init_protocol();
|
|
44284
44251
|
var PROJECTS_DIR = "projects";
|
|
44285
44252
|
var META_FILE = ".clawd-project.json";
|
|
@@ -44294,14 +44261,14 @@ var ProjectStore = class {
|
|
|
44294
44261
|
root;
|
|
44295
44262
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
44296
44263
|
metaPath(name) {
|
|
44297
|
-
return (0,
|
|
44264
|
+
return (0, import_node_path41.join)(this.projectsRoot(), name, META_FILE);
|
|
44298
44265
|
}
|
|
44299
44266
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
44300
44267
|
projectDir(name) {
|
|
44301
|
-
return (0,
|
|
44268
|
+
return (0, import_node_path41.join)(this.projectsRoot(), name);
|
|
44302
44269
|
}
|
|
44303
44270
|
projectsRoot() {
|
|
44304
|
-
return (0,
|
|
44271
|
+
return (0, import_node_path41.join)(this.root, PROJECTS_DIR);
|
|
44305
44272
|
}
|
|
44306
44273
|
async list() {
|
|
44307
44274
|
let entries;
|
|
@@ -44382,7 +44349,7 @@ var ProjectStore = class {
|
|
|
44382
44349
|
* 代码再参考"。assistant 进 project 时目录已是完整模板,直接 pnpm install 即可。
|
|
44383
44350
|
*/
|
|
44384
44351
|
async scaffold(name, template = DEFAULT_TEMPLATE, personaRoot = this.root) {
|
|
44385
|
-
const scriptPath = (0,
|
|
44352
|
+
const scriptPath = (0, import_node_path41.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
|
|
44386
44353
|
const destDir = this.projectDir(name);
|
|
44387
44354
|
return await new Promise((resolve6, reject) => {
|
|
44388
44355
|
const child = (0, import_node_child_process13.spawn)("bash", [scriptPath, name, template, destDir], {
|
|
@@ -44920,7 +44887,7 @@ function computeGrantForFrame(method, frame) {
|
|
|
44920
44887
|
|
|
44921
44888
|
// src/extension/runtime.ts
|
|
44922
44889
|
var import_node_child_process15 = require("child_process");
|
|
44923
|
-
var
|
|
44890
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
44924
44891
|
var import_promises10 = require("timers/promises");
|
|
44925
44892
|
|
|
44926
44893
|
// src/extension/port-allocator.ts
|
|
@@ -45021,7 +44988,7 @@ var Runtime = class {
|
|
|
45021
44988
|
/\$CLAWOS_EXT_PORT/g,
|
|
45022
44989
|
String(port)
|
|
45023
44990
|
);
|
|
45024
|
-
const dir =
|
|
44991
|
+
const dir = import_node_path42.default.join(this.root, extId);
|
|
45025
44992
|
const env = {
|
|
45026
44993
|
...process.env,
|
|
45027
44994
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -45133,7 +45100,7 @@ ${handle.stderrTail}`
|
|
|
45133
45100
|
|
|
45134
45101
|
// src/extension/published-channels.ts
|
|
45135
45102
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
45136
|
-
var
|
|
45103
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
45137
45104
|
init_zod();
|
|
45138
45105
|
var PublishedChannelsError = class extends Error {
|
|
45139
45106
|
constructor(code, message) {
|
|
@@ -45232,7 +45199,7 @@ var PublishedChannelStore = class {
|
|
|
45232
45199
|
)
|
|
45233
45200
|
};
|
|
45234
45201
|
const tmp = `${this.filePath}.tmp`;
|
|
45235
|
-
await import_promises11.default.mkdir(
|
|
45202
|
+
await import_promises11.default.mkdir(import_node_path43.default.dirname(this.filePath), { recursive: true });
|
|
45236
45203
|
await import_promises11.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
45237
45204
|
await import_promises11.default.rename(tmp, this.filePath);
|
|
45238
45205
|
}
|
|
@@ -45240,7 +45207,7 @@ var PublishedChannelStore = class {
|
|
|
45240
45207
|
|
|
45241
45208
|
// src/extension/bundle-cache.ts
|
|
45242
45209
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
45243
|
-
var
|
|
45210
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
45244
45211
|
var BundleCache = class {
|
|
45245
45212
|
constructor(rootDir) {
|
|
45246
45213
|
this.rootDir = rootDir;
|
|
@@ -45249,14 +45216,14 @@ var BundleCache = class {
|
|
|
45249
45216
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
45250
45217
|
async write(snapshotHash, buffer) {
|
|
45251
45218
|
await import_promises12.default.mkdir(this.rootDir, { recursive: true });
|
|
45252
|
-
const file =
|
|
45219
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45253
45220
|
const tmp = `${file}.tmp`;
|
|
45254
45221
|
await import_promises12.default.writeFile(tmp, buffer, { mode: 384 });
|
|
45255
45222
|
await import_promises12.default.rename(tmp, file);
|
|
45256
45223
|
}
|
|
45257
45224
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
45258
45225
|
async read(snapshotHash) {
|
|
45259
|
-
const file =
|
|
45226
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45260
45227
|
try {
|
|
45261
45228
|
return await import_promises12.default.readFile(file);
|
|
45262
45229
|
} catch (e) {
|
|
@@ -45266,7 +45233,7 @@ var BundleCache = class {
|
|
|
45266
45233
|
}
|
|
45267
45234
|
/** Idempotent — missing file is not an error. */
|
|
45268
45235
|
async delete(snapshotHash) {
|
|
45269
|
-
const file =
|
|
45236
|
+
const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
45270
45237
|
await import_promises12.default.rm(file, { force: true });
|
|
45271
45238
|
}
|
|
45272
45239
|
};
|
|
@@ -45275,7 +45242,7 @@ var BundleCache = class {
|
|
|
45275
45242
|
async function startDaemon(config) {
|
|
45276
45243
|
const logger = createLogger({
|
|
45277
45244
|
level: config.logLevel,
|
|
45278
|
-
file:
|
|
45245
|
+
file: import_node_path45.default.join(config.dataDir, "clawd.log")
|
|
45279
45246
|
});
|
|
45280
45247
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
45281
45248
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
@@ -45411,8 +45378,8 @@ async function startDaemon(config) {
|
|
|
45411
45378
|
const agents = new AgentsScanner();
|
|
45412
45379
|
const history = new ClaudeHistoryReader();
|
|
45413
45380
|
let transport = null;
|
|
45414
|
-
const personaStore = new PersonaStore(
|
|
45415
|
-
const usersRoot =
|
|
45381
|
+
const personaStore = new PersonaStore(import_node_path45.default.join(config.dataDir, "personas"));
|
|
45382
|
+
const usersRoot = import_node_path45.default.join(config.dataDir, "users");
|
|
45416
45383
|
const defaultsRoot = findDefaultsRoot();
|
|
45417
45384
|
if (defaultsRoot) {
|
|
45418
45385
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -45432,7 +45399,7 @@ async function startDaemon(config) {
|
|
|
45432
45399
|
getAdapter,
|
|
45433
45400
|
historyReader: history,
|
|
45434
45401
|
dataDir: config.dataDir,
|
|
45435
|
-
personaRoot:
|
|
45402
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45436
45403
|
usersRoot,
|
|
45437
45404
|
personaStore,
|
|
45438
45405
|
ownerDisplayName,
|
|
@@ -45462,7 +45429,7 @@ async function startDaemon(config) {
|
|
|
45462
45429
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
45463
45430
|
attachmentGroup: {
|
|
45464
45431
|
onFileEdit: (input) => {
|
|
45465
|
-
const absPath =
|
|
45432
|
+
const absPath = import_node_path45.default.isAbsolute(input.relPath) ? input.relPath : import_node_path45.default.join(input.cwd, input.relPath);
|
|
45466
45433
|
let size = 0;
|
|
45467
45434
|
try {
|
|
45468
45435
|
size = import_node_fs33.default.statSync(absPath).size;
|
|
@@ -45651,11 +45618,11 @@ async function startDaemon(config) {
|
|
|
45651
45618
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
45652
45619
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
45653
45620
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
45654
|
-
personaRoot:
|
|
45621
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45655
45622
|
usersRoot
|
|
45656
45623
|
},
|
|
45657
45624
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
45658
|
-
personaRoot:
|
|
45625
|
+
personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
|
|
45659
45626
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
45660
45627
|
usersRoot,
|
|
45661
45628
|
// capability:list / delete handler 依赖
|
|
@@ -45744,7 +45711,7 @@ async function startDaemon(config) {
|
|
|
45744
45711
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
45745
45712
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
45746
45713
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
45747
|
-
appBuilderPersonaRoot:
|
|
45714
|
+
appBuilderPersonaRoot: import_node_path45.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
45748
45715
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
45749
45716
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
45750
45717
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -45993,8 +45960,8 @@ async function startDaemon(config) {
|
|
|
45993
45960
|
const lines = [
|
|
45994
45961
|
`Tunnel: ${r.url}`,
|
|
45995
45962
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
45996
|
-
`Frpc config: ${
|
|
45997
|
-
`Frpc log: ${
|
|
45963
|
+
`Frpc config: ${import_node_path45.default.join(config.dataDir, "frpc.toml")}`,
|
|
45964
|
+
`Frpc log: ${import_node_path45.default.join(config.dataDir, "frpc.log")}`
|
|
45998
45965
|
];
|
|
45999
45966
|
const width = Math.max(...lines.map((l) => l.length));
|
|
46000
45967
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -46007,7 +45974,7 @@ ${bar}
|
|
|
46007
45974
|
|
|
46008
45975
|
`);
|
|
46009
45976
|
try {
|
|
46010
|
-
const connectPath =
|
|
45977
|
+
const connectPath = import_node_path45.default.join(config.dataDir, "connect.txt");
|
|
46011
45978
|
import_node_fs33.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
46012
45979
|
} catch {
|
|
46013
45980
|
}
|
|
@@ -46079,7 +46046,7 @@ ${bar}
|
|
|
46079
46046
|
};
|
|
46080
46047
|
}
|
|
46081
46048
|
function migrateDropPersonsDir(dataDir) {
|
|
46082
|
-
const dir =
|
|
46049
|
+
const dir = import_node_path45.default.join(dataDir, "persons");
|
|
46083
46050
|
try {
|
|
46084
46051
|
import_node_fs33.default.rmSync(dir, { recursive: true, force: true });
|
|
46085
46052
|
} catch {
|