@clawos-dev/clawd 0.2.67 → 0.2.69-beta.120.2a41cd5
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 +102 -153
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -605,8 +605,8 @@ var init_parseUtil = __esm({
|
|
|
605
605
|
init_errors2();
|
|
606
606
|
init_en();
|
|
607
607
|
makeIssue = (params) => {
|
|
608
|
-
const { data, path:
|
|
609
|
-
const fullPath = [...
|
|
608
|
+
const { data, path: path31, errorMaps, issueData } = params;
|
|
609
|
+
const fullPath = [...path31, ...issueData.path || []];
|
|
610
610
|
const fullIssue = {
|
|
611
611
|
...issueData,
|
|
612
612
|
path: fullPath
|
|
@@ -917,11 +917,11 @@ var init_types = __esm({
|
|
|
917
917
|
init_parseUtil();
|
|
918
918
|
init_util();
|
|
919
919
|
ParseInputLazyPath = class {
|
|
920
|
-
constructor(parent, value,
|
|
920
|
+
constructor(parent, value, path31, key) {
|
|
921
921
|
this._cachedPath = [];
|
|
922
922
|
this.parent = parent;
|
|
923
923
|
this.data = value;
|
|
924
|
-
this._path =
|
|
924
|
+
this._path = path31;
|
|
925
925
|
this._key = key;
|
|
926
926
|
}
|
|
927
927
|
get path() {
|
|
@@ -4331,11 +4331,9 @@ var init_attachment_schemas = __esm({
|
|
|
4331
4331
|
stale: external_exports.boolean().optional()
|
|
4332
4332
|
});
|
|
4333
4333
|
AttachmentSignUrlArgs = external_exports.object({
|
|
4334
|
-
/**
|
|
4335
|
-
|
|
4336
|
-
/**
|
|
4337
|
-
relPath: external_exports.string().min(1),
|
|
4338
|
-
/** TTL 秒数;缺省 24h;null 走永久 URL(不带 exp 字段) */
|
|
4334
|
+
/** 要分享的绝对路径;签名只关心 absPath,不区分 persona/session */
|
|
4335
|
+
absPath: external_exports.string().min(1),
|
|
4336
|
+
/** TTL 秒数;缺省 24h;'never' 走 null 不带 exp 字段(永久有效) */
|
|
4339
4337
|
ttlSeconds: external_exports.number().int().positive().nullable().optional()
|
|
4340
4338
|
});
|
|
4341
4339
|
AttachmentSignUrlResponseSchema = external_exports.object({
|
|
@@ -4470,7 +4468,7 @@ var init_persona_schemas = __esm({
|
|
|
4470
4468
|
});
|
|
4471
4469
|
|
|
4472
4470
|
// ../protocol/src/schemas.ts
|
|
4473
|
-
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelExitedEventSchema, InfoRunningSessionSchema, InfoResponseSchema;
|
|
4471
|
+
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema;
|
|
4474
4472
|
var init_schemas = __esm({
|
|
4475
4473
|
"../protocol/src/schemas.ts"() {
|
|
4476
4474
|
"use strict";
|
|
@@ -4994,6 +4992,11 @@ var init_schemas = __esm({
|
|
|
4994
4992
|
subdomain: external_exports.string().nullable(),
|
|
4995
4993
|
url: external_exports.string().nullable()
|
|
4996
4994
|
});
|
|
4995
|
+
TunnelUnavailableEventSchema = external_exports.object({
|
|
4996
|
+
type: external_exports.literal("tunnel:unavailable"),
|
|
4997
|
+
reason: external_exports.string().min(1),
|
|
4998
|
+
failedAt: external_exports.string().min(1)
|
|
4999
|
+
});
|
|
4997
5000
|
InfoRunningSessionSchema = external_exports.object({
|
|
4998
5001
|
sessionId: external_exports.string().min(1),
|
|
4999
5002
|
status: SessionStatusSchema,
|
|
@@ -5330,8 +5333,8 @@ var require_req = __commonJS({
|
|
|
5330
5333
|
if (req.originalUrl) {
|
|
5331
5334
|
_req.url = req.originalUrl;
|
|
5332
5335
|
} else {
|
|
5333
|
-
const
|
|
5334
|
-
_req.url = typeof
|
|
5336
|
+
const path31 = req.path;
|
|
5337
|
+
_req.url = typeof path31 === "string" ? path31 : req.url ? req.url.path || req.url : void 0;
|
|
5335
5338
|
}
|
|
5336
5339
|
if (req.query) {
|
|
5337
5340
|
_req.query = req.query;
|
|
@@ -5496,14 +5499,14 @@ var require_redact = __commonJS({
|
|
|
5496
5499
|
}
|
|
5497
5500
|
return obj;
|
|
5498
5501
|
}
|
|
5499
|
-
function parsePath(
|
|
5502
|
+
function parsePath(path31) {
|
|
5500
5503
|
const parts = [];
|
|
5501
5504
|
let current = "";
|
|
5502
5505
|
let inBrackets = false;
|
|
5503
5506
|
let inQuotes = false;
|
|
5504
5507
|
let quoteChar = "";
|
|
5505
|
-
for (let i = 0; i <
|
|
5506
|
-
const char =
|
|
5508
|
+
for (let i = 0; i < path31.length; i++) {
|
|
5509
|
+
const char = path31[i];
|
|
5507
5510
|
if (!inBrackets && char === ".") {
|
|
5508
5511
|
if (current) {
|
|
5509
5512
|
parts.push(current);
|
|
@@ -5634,10 +5637,10 @@ var require_redact = __commonJS({
|
|
|
5634
5637
|
return current;
|
|
5635
5638
|
}
|
|
5636
5639
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
5637
|
-
for (const
|
|
5638
|
-
const parts = parsePath(
|
|
5640
|
+
for (const path31 of paths) {
|
|
5641
|
+
const parts = parsePath(path31);
|
|
5639
5642
|
if (parts.includes("*")) {
|
|
5640
|
-
redactWildcardPath(obj, parts, censor,
|
|
5643
|
+
redactWildcardPath(obj, parts, censor, path31, remove);
|
|
5641
5644
|
} else {
|
|
5642
5645
|
if (remove) {
|
|
5643
5646
|
removeKey(obj, parts);
|
|
@@ -5722,8 +5725,8 @@ var require_redact = __commonJS({
|
|
|
5722
5725
|
}
|
|
5723
5726
|
} else {
|
|
5724
5727
|
if (afterWildcard.includes("*")) {
|
|
5725
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
5726
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
5728
|
+
const wrappedCensor = typeof censor === "function" ? (value, path31) => {
|
|
5729
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path31];
|
|
5727
5730
|
return censor(value, fullPath);
|
|
5728
5731
|
} : censor;
|
|
5729
5732
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -5758,8 +5761,8 @@ var require_redact = __commonJS({
|
|
|
5758
5761
|
return null;
|
|
5759
5762
|
}
|
|
5760
5763
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
5761
|
-
for (const
|
|
5762
|
-
const parts = parsePath(
|
|
5764
|
+
for (const path31 of pathsToClone) {
|
|
5765
|
+
const parts = parsePath(path31);
|
|
5763
5766
|
let current = pathStructure;
|
|
5764
5767
|
for (let i = 0; i < parts.length; i++) {
|
|
5765
5768
|
const part = parts[i];
|
|
@@ -5811,24 +5814,24 @@ var require_redact = __commonJS({
|
|
|
5811
5814
|
}
|
|
5812
5815
|
return cloneSelectively(obj, pathStructure);
|
|
5813
5816
|
}
|
|
5814
|
-
function validatePath(
|
|
5815
|
-
if (typeof
|
|
5817
|
+
function validatePath(path31) {
|
|
5818
|
+
if (typeof path31 !== "string") {
|
|
5816
5819
|
throw new Error("Paths must be (non-empty) strings");
|
|
5817
5820
|
}
|
|
5818
|
-
if (
|
|
5821
|
+
if (path31 === "") {
|
|
5819
5822
|
throw new Error("Invalid redaction path ()");
|
|
5820
5823
|
}
|
|
5821
|
-
if (
|
|
5822
|
-
throw new Error(`Invalid redaction path (${
|
|
5824
|
+
if (path31.includes("..")) {
|
|
5825
|
+
throw new Error(`Invalid redaction path (${path31})`);
|
|
5823
5826
|
}
|
|
5824
|
-
if (
|
|
5825
|
-
throw new Error(`Invalid redaction path (${
|
|
5827
|
+
if (path31.includes(",")) {
|
|
5828
|
+
throw new Error(`Invalid redaction path (${path31})`);
|
|
5826
5829
|
}
|
|
5827
5830
|
let bracketCount = 0;
|
|
5828
5831
|
let inQuotes = false;
|
|
5829
5832
|
let quoteChar = "";
|
|
5830
|
-
for (let i = 0; i <
|
|
5831
|
-
const char =
|
|
5833
|
+
for (let i = 0; i < path31.length; i++) {
|
|
5834
|
+
const char = path31[i];
|
|
5832
5835
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
5833
5836
|
if (!inQuotes) {
|
|
5834
5837
|
inQuotes = true;
|
|
@@ -5842,20 +5845,20 @@ var require_redact = __commonJS({
|
|
|
5842
5845
|
} else if (char === "]" && !inQuotes) {
|
|
5843
5846
|
bracketCount--;
|
|
5844
5847
|
if (bracketCount < 0) {
|
|
5845
|
-
throw new Error(`Invalid redaction path (${
|
|
5848
|
+
throw new Error(`Invalid redaction path (${path31})`);
|
|
5846
5849
|
}
|
|
5847
5850
|
}
|
|
5848
5851
|
}
|
|
5849
5852
|
if (bracketCount !== 0) {
|
|
5850
|
-
throw new Error(`Invalid redaction path (${
|
|
5853
|
+
throw new Error(`Invalid redaction path (${path31})`);
|
|
5851
5854
|
}
|
|
5852
5855
|
}
|
|
5853
5856
|
function validatePaths(paths) {
|
|
5854
5857
|
if (!Array.isArray(paths)) {
|
|
5855
5858
|
throw new TypeError("paths must be an array");
|
|
5856
5859
|
}
|
|
5857
|
-
for (const
|
|
5858
|
-
validatePath(
|
|
5860
|
+
for (const path31 of paths) {
|
|
5861
|
+
validatePath(path31);
|
|
5859
5862
|
}
|
|
5860
5863
|
}
|
|
5861
5864
|
function slowRedact(options = {}) {
|
|
@@ -6023,8 +6026,8 @@ var require_redaction = __commonJS({
|
|
|
6023
6026
|
if (shape[k2] === null) {
|
|
6024
6027
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
6025
6028
|
} else {
|
|
6026
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6027
|
-
return censor(value, [k2, ...
|
|
6029
|
+
const wrappedCensor = typeof censor === "function" ? (value, path31) => {
|
|
6030
|
+
return censor(value, [k2, ...path31]);
|
|
6028
6031
|
} : censor;
|
|
6029
6032
|
o[k2] = Redact({
|
|
6030
6033
|
paths: shape[k2],
|
|
@@ -6245,7 +6248,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6245
6248
|
var fs28 = require("fs");
|
|
6246
6249
|
var EventEmitter2 = require("events");
|
|
6247
6250
|
var inherits = require("util").inherits;
|
|
6248
|
-
var
|
|
6251
|
+
var path31 = require("path");
|
|
6249
6252
|
var sleep = require_atomic_sleep();
|
|
6250
6253
|
var assert = require("assert");
|
|
6251
6254
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -6299,7 +6302,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6299
6302
|
const mode = sonic.mode;
|
|
6300
6303
|
if (sonic.sync) {
|
|
6301
6304
|
try {
|
|
6302
|
-
if (sonic.mkdir) fs28.mkdirSync(
|
|
6305
|
+
if (sonic.mkdir) fs28.mkdirSync(path31.dirname(file), { recursive: true });
|
|
6303
6306
|
const fd = fs28.openSync(file, flags, mode);
|
|
6304
6307
|
fileOpened(null, fd);
|
|
6305
6308
|
} catch (err) {
|
|
@@ -6307,7 +6310,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6307
6310
|
throw err;
|
|
6308
6311
|
}
|
|
6309
6312
|
} else if (sonic.mkdir) {
|
|
6310
|
-
fs28.mkdir(
|
|
6313
|
+
fs28.mkdir(path31.dirname(file), { recursive: true }, (err) => {
|
|
6311
6314
|
if (err) return fileOpened(err);
|
|
6312
6315
|
fs28.open(file, flags, mode, fileOpened);
|
|
6313
6316
|
});
|
|
@@ -9938,11 +9941,11 @@ var init_lib = __esm({
|
|
|
9938
9941
|
}
|
|
9939
9942
|
}
|
|
9940
9943
|
},
|
|
9941
|
-
addToPath: function addToPath(
|
|
9942
|
-
var last =
|
|
9944
|
+
addToPath: function addToPath(path31, added, removed, oldPosInc, options) {
|
|
9945
|
+
var last = path31.lastComponent;
|
|
9943
9946
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
9944
9947
|
return {
|
|
9945
|
-
oldPos:
|
|
9948
|
+
oldPos: path31.oldPos + oldPosInc,
|
|
9946
9949
|
lastComponent: {
|
|
9947
9950
|
count: last.count + 1,
|
|
9948
9951
|
added,
|
|
@@ -9952,7 +9955,7 @@ var init_lib = __esm({
|
|
|
9952
9955
|
};
|
|
9953
9956
|
} else {
|
|
9954
9957
|
return {
|
|
9955
|
-
oldPos:
|
|
9958
|
+
oldPos: path31.oldPos + oldPosInc,
|
|
9956
9959
|
lastComponent: {
|
|
9957
9960
|
count: 1,
|
|
9958
9961
|
added,
|
|
@@ -10383,10 +10386,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
10383
10386
|
const memories = raw.map((m2) => {
|
|
10384
10387
|
if (!m2 || typeof m2 !== "object") return null;
|
|
10385
10388
|
const rec = m2;
|
|
10386
|
-
const
|
|
10389
|
+
const path31 = typeof rec.path === "string" ? rec.path : null;
|
|
10387
10390
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
10388
|
-
if (!
|
|
10389
|
-
const entry = { path:
|
|
10391
|
+
if (!path31 || content == null) return null;
|
|
10392
|
+
const entry = { path: path31, content };
|
|
10390
10393
|
if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
|
|
10391
10394
|
return entry;
|
|
10392
10395
|
}).filter((m2) => m2 !== null);
|
|
@@ -11190,10 +11193,10 @@ function parseAttachment(obj) {
|
|
|
11190
11193
|
const memories = raw.map((m2) => {
|
|
11191
11194
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11192
11195
|
const rec = m2;
|
|
11193
|
-
const
|
|
11196
|
+
const path31 = typeof rec.path === "string" ? rec.path : null;
|
|
11194
11197
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
11195
|
-
if (!
|
|
11196
|
-
const out = { path:
|
|
11198
|
+
if (!path31 || content == null) return null;
|
|
11199
|
+
const out = { path: path31, content };
|
|
11197
11200
|
if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
|
|
11198
11201
|
return out;
|
|
11199
11202
|
}).filter((m2) => m2 !== null);
|
|
@@ -20107,7 +20110,7 @@ var require_websocket_server = __commonJS({
|
|
|
20107
20110
|
// src/run-case/recorder.ts
|
|
20108
20111
|
function startRunCaseRecorder(opts) {
|
|
20109
20112
|
const now = opts.now ?? Date.now;
|
|
20110
|
-
const dir =
|
|
20113
|
+
const dir = import_node_path27.default.dirname(opts.recordPath);
|
|
20111
20114
|
let stream = null;
|
|
20112
20115
|
let closing = false;
|
|
20113
20116
|
let closedSettled = false;
|
|
@@ -20147,12 +20150,12 @@ function startRunCaseRecorder(opts) {
|
|
|
20147
20150
|
};
|
|
20148
20151
|
return { tap, close, closed };
|
|
20149
20152
|
}
|
|
20150
|
-
var import_node_fs25,
|
|
20153
|
+
var import_node_fs25, import_node_path27;
|
|
20151
20154
|
var init_recorder = __esm({
|
|
20152
20155
|
"src/run-case/recorder.ts"() {
|
|
20153
20156
|
"use strict";
|
|
20154
20157
|
import_node_fs25 = __toESM(require("fs"), 1);
|
|
20155
|
-
|
|
20158
|
+
import_node_path27 = __toESM(require("path"), 1);
|
|
20156
20159
|
}
|
|
20157
20160
|
});
|
|
20158
20161
|
|
|
@@ -20195,7 +20198,7 @@ var init_wire = __esm({
|
|
|
20195
20198
|
// src/run-case/controller.ts
|
|
20196
20199
|
async function runController(opts) {
|
|
20197
20200
|
const now = opts.now ?? Date.now;
|
|
20198
|
-
const cwd = opts.cwd ?? (0, import_node_fs26.mkdtempSync)(
|
|
20201
|
+
const cwd = opts.cwd ?? (0, import_node_fs26.mkdtempSync)(import_node_path28.default.join(import_node_os14.default.tmpdir(), "clawd-runcase-"));
|
|
20199
20202
|
const ownsCwd = opts.cwd === void 0;
|
|
20200
20203
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
20201
20204
|
const spawnCtx = { cwd };
|
|
@@ -20362,13 +20365,13 @@ async function runController(opts) {
|
|
|
20362
20365
|
}
|
|
20363
20366
|
return exitCode ?? 0;
|
|
20364
20367
|
}
|
|
20365
|
-
var import_node_fs26, import_node_os14,
|
|
20368
|
+
var import_node_fs26, import_node_os14, import_node_path28;
|
|
20366
20369
|
var init_controller = __esm({
|
|
20367
20370
|
"src/run-case/controller.ts"() {
|
|
20368
20371
|
"use strict";
|
|
20369
20372
|
import_node_fs26 = require("fs");
|
|
20370
20373
|
import_node_os14 = __toESM(require("os"), 1);
|
|
20371
|
-
|
|
20374
|
+
import_node_path28 = __toESM(require("path"), 1);
|
|
20372
20375
|
init_claude();
|
|
20373
20376
|
init_stdout_splitter();
|
|
20374
20377
|
init_permission_stdio();
|
|
@@ -20600,7 +20603,7 @@ Env (advanced):
|
|
|
20600
20603
|
`;
|
|
20601
20604
|
|
|
20602
20605
|
// src/index.ts
|
|
20603
|
-
var
|
|
20606
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
20604
20607
|
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
20605
20608
|
|
|
20606
20609
|
// src/logger.ts
|
|
@@ -26847,24 +26850,14 @@ var AUTH_FILE_NAME = "auth.json";
|
|
|
26847
26850
|
function authFilePath(dataDir) {
|
|
26848
26851
|
return import_node_path22.default.join(dataDir, AUTH_FILE_NAME);
|
|
26849
26852
|
}
|
|
26850
|
-
function
|
|
26853
|
+
function loadOrCreateAuthToken(opts) {
|
|
26851
26854
|
const file = authFilePath(opts.dataDir);
|
|
26852
|
-
const generate = opts.generate ?? defaultGenerate;
|
|
26853
|
-
const now = opts.now ?? (() => /* @__PURE__ */ new Date());
|
|
26854
26855
|
const existing = readAuthFile(file);
|
|
26855
|
-
if (existing && existing.token
|
|
26856
|
-
|
|
26857
|
-
|
|
26858
|
-
|
|
26859
|
-
|
|
26860
|
-
};
|
|
26861
|
-
}
|
|
26862
|
-
const token = existing?.token || generate();
|
|
26863
|
-
const signSecret = existing?.signSecret || generate();
|
|
26864
|
-
const createdAt = existing?.createdAt || now().toISOString();
|
|
26865
|
-
const next = { token, signSecret, createdAt };
|
|
26866
|
-
writeAuthFile(file, next);
|
|
26867
|
-
return next;
|
|
26856
|
+
if (existing && existing.token) return existing.token;
|
|
26857
|
+
const token = (opts.generate ?? defaultGenerate)();
|
|
26858
|
+
const now = (opts.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
26859
|
+
writeAuthFile(file, { token, createdAt: now.toISOString() });
|
|
26860
|
+
return token;
|
|
26868
26861
|
}
|
|
26869
26862
|
function defaultGenerate() {
|
|
26870
26863
|
return import_node_crypto8.default.randomBytes(32).toString("base64url");
|
|
@@ -26873,14 +26866,13 @@ function readAuthFile(file) {
|
|
|
26873
26866
|
try {
|
|
26874
26867
|
const raw = import_node_fs20.default.readFileSync(file, "utf8");
|
|
26875
26868
|
const parsed = JSON.parse(raw);
|
|
26876
|
-
if (typeof parsed?.token
|
|
26877
|
-
return
|
|
26869
|
+
if (typeof parsed?.token === "string" && parsed.token.length > 0) {
|
|
26870
|
+
return {
|
|
26871
|
+
token: parsed.token,
|
|
26872
|
+
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : (/* @__PURE__ */ new Date(0)).toISOString()
|
|
26873
|
+
};
|
|
26878
26874
|
}
|
|
26879
|
-
return
|
|
26880
|
-
token: parsed.token,
|
|
26881
|
-
signSecret: typeof parsed.signSecret === "string" && parsed.signSecret.length > 0 ? parsed.signSecret : void 0,
|
|
26882
|
-
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : void 0
|
|
26883
|
-
};
|
|
26875
|
+
return null;
|
|
26884
26876
|
} catch (err) {
|
|
26885
26877
|
const code = err?.code;
|
|
26886
26878
|
if (code === "ENOENT") return null;
|
|
@@ -27549,7 +27541,6 @@ function buildPersonaHandlers(deps) {
|
|
|
27549
27541
|
}
|
|
27550
27542
|
|
|
27551
27543
|
// src/handlers/attachment.ts
|
|
27552
|
-
var import_node_path26 = __toESM(require("path"), 1);
|
|
27553
27544
|
init_protocol();
|
|
27554
27545
|
init_protocol();
|
|
27555
27546
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -27574,51 +27565,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
27574
27565
|
"httpBaseUrl unavailable (daemon HTTP not ready)"
|
|
27575
27566
|
);
|
|
27576
27567
|
}
|
|
27577
|
-
if (!deps.sessionStore || !deps.getSessionScope || !deps.groupFileStore) {
|
|
27578
|
-
throw new ClawdError(
|
|
27579
|
-
ERROR_CODES.METHOD_NOT_IMPLEMENTED,
|
|
27580
|
-
"signUrl requires session/group stores"
|
|
27581
|
-
);
|
|
27582
|
-
}
|
|
27583
|
-
const sessionFile = deps.sessionStore.read(args.sessionId);
|
|
27584
|
-
if (!sessionFile) {
|
|
27585
|
-
throw new ClawdError(
|
|
27586
|
-
ERROR_CODES.VALIDATION_ERROR,
|
|
27587
|
-
`session ${args.sessionId} not found`
|
|
27588
|
-
);
|
|
27589
|
-
}
|
|
27590
|
-
const scope = deps.getSessionScope(args.sessionId);
|
|
27591
|
-
if (!scope) {
|
|
27592
|
-
throw new ClawdError(
|
|
27593
|
-
ERROR_CODES.VALIDATION_ERROR,
|
|
27594
|
-
`session ${args.sessionId} scope unresolved`
|
|
27595
|
-
);
|
|
27596
|
-
}
|
|
27597
|
-
const cwdAbs = import_node_path26.default.resolve(sessionFile.cwd);
|
|
27598
|
-
const candidateAbs = import_node_path26.default.isAbsolute(args.relPath) ? import_node_path26.default.resolve(args.relPath) : import_node_path26.default.resolve(cwdAbs, args.relPath);
|
|
27599
|
-
if (!isContainedIn2(candidateAbs, cwdAbs)) {
|
|
27600
|
-
throw new ClawdError(
|
|
27601
|
-
ERROR_CODES.VALIDATION_ERROR,
|
|
27602
|
-
"relPath escapes session cwd"
|
|
27603
|
-
);
|
|
27604
|
-
}
|
|
27605
|
-
const relPath = import_node_path26.default.relative(cwdAbs, candidateAbs);
|
|
27606
|
-
if (relPath === "" || relPath.startsWith("..")) {
|
|
27607
|
-
throw new ClawdError(
|
|
27608
|
-
ERROR_CODES.VALIDATION_ERROR,
|
|
27609
|
-
"relPath escapes session cwd"
|
|
27610
|
-
);
|
|
27611
|
-
}
|
|
27612
|
-
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
27613
|
-
const entry = entries.find((e) => e.relPath === relPath && !e.stale);
|
|
27614
|
-
if (!entry) {
|
|
27615
|
-
throw new ClawdError(
|
|
27616
|
-
ERROR_CODES.VALIDATION_ERROR,
|
|
27617
|
-
`relPath not in session group files or stale: ${relPath}`
|
|
27618
|
-
);
|
|
27619
|
-
}
|
|
27620
27568
|
const ttl = args.ttlSeconds === null ? null : args.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
27621
|
-
const parts = signUrlParts(secret,
|
|
27569
|
+
const parts = signUrlParts(secret, args.absPath, ttl);
|
|
27622
27570
|
const url = buildSignedFileUrl(httpBaseUrl, parts);
|
|
27623
27571
|
return {
|
|
27624
27572
|
response: {
|
|
@@ -27704,12 +27652,6 @@ function buildAttachmentHandlers(deps) {
|
|
|
27704
27652
|
"attachment.groupListPersona": groupListPersona
|
|
27705
27653
|
};
|
|
27706
27654
|
}
|
|
27707
|
-
function isContainedIn2(abs, root) {
|
|
27708
|
-
const normalized = import_node_path26.default.resolve(abs);
|
|
27709
|
-
const normalizedRoot = import_node_path26.default.resolve(root);
|
|
27710
|
-
if (normalized === normalizedRoot) return true;
|
|
27711
|
-
return normalized.startsWith(normalizedRoot + import_node_path26.default.sep);
|
|
27712
|
-
}
|
|
27713
27655
|
|
|
27714
27656
|
// src/handlers/index.ts
|
|
27715
27657
|
function buildMethodHandlers(deps) {
|
|
@@ -27733,7 +27675,7 @@ function buildMethodHandlers(deps) {
|
|
|
27733
27675
|
async function startDaemon(config) {
|
|
27734
27676
|
const logger = createLogger({
|
|
27735
27677
|
level: config.logLevel,
|
|
27736
|
-
file:
|
|
27678
|
+
file: import_node_path26.default.join(config.dataDir, "clawd.log")
|
|
27737
27679
|
});
|
|
27738
27680
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
27739
27681
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
@@ -27745,12 +27687,10 @@ async function startDaemon(config) {
|
|
|
27745
27687
|
logger.warn("stale state file detected, overwriting", { pid: pre.existing.pid });
|
|
27746
27688
|
}
|
|
27747
27689
|
let resolvedAuthToken = null;
|
|
27748
|
-
let authFile = null;
|
|
27749
27690
|
if (config.authToken && config.authToken.trim()) {
|
|
27750
27691
|
resolvedAuthToken = config.authToken.trim();
|
|
27751
27692
|
} else if (config.tunnel) {
|
|
27752
|
-
|
|
27753
|
-
resolvedAuthToken = authFile.token;
|
|
27693
|
+
resolvedAuthToken = loadOrCreateAuthToken({ dataDir: config.dataDir });
|
|
27754
27694
|
}
|
|
27755
27695
|
const authMode = resolvedAuthToken == null ? "none" : "first-message";
|
|
27756
27696
|
let wsServer = null;
|
|
@@ -27767,7 +27707,7 @@ async function startDaemon(config) {
|
|
|
27767
27707
|
const agents = new AgentsScanner();
|
|
27768
27708
|
const history = new ClaudeHistoryReader();
|
|
27769
27709
|
let transport = null;
|
|
27770
|
-
const personaStore = new PersonaStore(
|
|
27710
|
+
const personaStore = new PersonaStore(import_node_path26.default.join(config.dataDir, "personas"));
|
|
27771
27711
|
const defaultsRoot = findDefaultsRoot();
|
|
27772
27712
|
if (defaultsRoot) {
|
|
27773
27713
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -27782,7 +27722,7 @@ async function startDaemon(config) {
|
|
|
27782
27722
|
getAdapter,
|
|
27783
27723
|
historyReader: history,
|
|
27784
27724
|
dataDir: config.dataDir,
|
|
27785
|
-
personaRoot:
|
|
27725
|
+
personaRoot: import_node_path26.default.join(config.dataDir, "personas"),
|
|
27786
27726
|
personaStore,
|
|
27787
27727
|
ownerDisplayName,
|
|
27788
27728
|
mode: config.mode,
|
|
@@ -27805,7 +27745,7 @@ async function startDaemon(config) {
|
|
|
27805
27745
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
27806
27746
|
attachmentGroup: {
|
|
27807
27747
|
onFileEdit: (input) => {
|
|
27808
|
-
const absPath =
|
|
27748
|
+
const absPath = import_node_path26.default.isAbsolute(input.relPath) ? input.relPath : import_node_path26.default.join(input.cwd, input.relPath);
|
|
27809
27749
|
let size = 0;
|
|
27810
27750
|
try {
|
|
27811
27751
|
size = import_node_fs24.default.statSync(absPath).size;
|
|
@@ -27906,12 +27846,11 @@ async function startDaemon(config) {
|
|
|
27906
27846
|
// 根据 sessionId 反查 scope 写盘。
|
|
27907
27847
|
attachment: {
|
|
27908
27848
|
groupFileStore,
|
|
27909
|
-
sessionStore: store,
|
|
27910
27849
|
getHttpBaseUrl,
|
|
27911
|
-
// HMAC sign secret
|
|
27912
|
-
//
|
|
27913
|
-
getSignSecret: () =>
|
|
27914
|
-
// group RPC
|
|
27850
|
+
// HMAC sign secret:复用 ~/.clawd/auth.json owner token(持久跨重启)。
|
|
27851
|
+
// noAuth 模式 resolvedAuthToken 为 null → handler 自己返 NOT_IMPLEMENTED。
|
|
27852
|
+
getSignSecret: () => resolvedAuthToken ?? "",
|
|
27853
|
+
// group RPC:根据 sessionId 反查 scope;owner-mode persona session 走
|
|
27915
27854
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
27916
27855
|
getSessionScope: (sessionId) => {
|
|
27917
27856
|
const file = store.read(sessionId);
|
|
@@ -27934,9 +27873,8 @@ async function startDaemon(config) {
|
|
|
27934
27873
|
personaStore,
|
|
27935
27874
|
groupFileStore,
|
|
27936
27875
|
sessionStore: store,
|
|
27937
|
-
// /files HMAC verify
|
|
27938
|
-
|
|
27939
|
-
getSignSecret: () => authFile?.signSecret ?? null
|
|
27876
|
+
// /files HMAC verify 用同一份 owner token 做 secret(与 attachment.signUrl 同源)
|
|
27877
|
+
getSignSecret: () => resolvedAuthToken ?? null
|
|
27940
27878
|
});
|
|
27941
27879
|
wsServer = new LocalWsServer({
|
|
27942
27880
|
host: config.host,
|
|
@@ -28067,15 +28005,15 @@ async function startDaemon(config) {
|
|
|
28067
28005
|
});
|
|
28068
28006
|
try {
|
|
28069
28007
|
const r = await tunnelMgr.start({ localPort: config.port });
|
|
28070
|
-
stateSnapshot = { ...stateSnapshot, tunnelUrl: r.url };
|
|
28008
|
+
stateSnapshot = { ...stateSnapshot, tunnelUrl: r.url, tunnelError: void 0 };
|
|
28071
28009
|
stateMgr.write(stateSnapshot);
|
|
28072
28010
|
currentTunnelUrl = r.url;
|
|
28073
28011
|
const connectUrl = resolvedAuthToken ? `${r.url}#token=${resolvedAuthToken}` : r.url;
|
|
28074
28012
|
const lines = [
|
|
28075
28013
|
`Tunnel: ${r.url}`,
|
|
28076
28014
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
28077
|
-
`Frpc config: ${
|
|
28078
|
-
`Frpc log: ${
|
|
28015
|
+
`Frpc config: ${import_node_path26.default.join(config.dataDir, "frpc.toml")}`,
|
|
28016
|
+
`Frpc log: ${import_node_path26.default.join(config.dataDir, "frpc.log")}`
|
|
28079
28017
|
];
|
|
28080
28018
|
const width = Math.max(...lines.map((l) => l.length));
|
|
28081
28019
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -28088,19 +28026,30 @@ ${bar}
|
|
|
28088
28026
|
|
|
28089
28027
|
`);
|
|
28090
28028
|
try {
|
|
28091
|
-
const connectPath =
|
|
28029
|
+
const connectPath = import_node_path26.default.join(config.dataDir, "connect.txt");
|
|
28092
28030
|
import_node_fs24.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
28093
28031
|
} catch {
|
|
28094
28032
|
}
|
|
28095
28033
|
} catch (err) {
|
|
28034
|
+
const tunnelError = err?.message ?? String(err);
|
|
28096
28035
|
try {
|
|
28097
28036
|
await tunnelMgr.stop();
|
|
28098
28037
|
} catch {
|
|
28099
28038
|
}
|
|
28100
28039
|
tunnelMgr = null;
|
|
28101
|
-
|
|
28102
|
-
|
|
28103
|
-
|
|
28040
|
+
stateSnapshot = { ...stateSnapshot, tunnelUrl: void 0, tunnelError };
|
|
28041
|
+
try {
|
|
28042
|
+
stateMgr.write(stateSnapshot);
|
|
28043
|
+
} catch {
|
|
28044
|
+
}
|
|
28045
|
+
wss.broadcastAll({
|
|
28046
|
+
type: "tunnel:unavailable",
|
|
28047
|
+
reason: tunnelError,
|
|
28048
|
+
failedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
28049
|
+
});
|
|
28050
|
+
process.stdout.write(`Tunnel: unavailable (local mode) \u2014 ${tunnelError}
|
|
28051
|
+
`);
|
|
28052
|
+
logger.warn("tunnel unavailable, degraded to local mode", { reason: tunnelError });
|
|
28104
28053
|
}
|
|
28105
28054
|
}
|
|
28106
28055
|
const shutdown = async () => {
|
package/package.json
CHANGED