@clawos-dev/clawd 0.2.33-beta.48.5d86147 → 0.2.34-beta.49.e300ede
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 +274 -510
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1208,7 +1208,7 @@ var require_atomic_sleep = __commonJS({
|
|
|
1208
1208
|
var require_sonic_boom = __commonJS({
|
|
1209
1209
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
1210
1210
|
"use strict";
|
|
1211
|
-
var
|
|
1211
|
+
var fs21 = require("fs");
|
|
1212
1212
|
var EventEmitter = require("events");
|
|
1213
1213
|
var inherits = require("util").inherits;
|
|
1214
1214
|
var path22 = require("path");
|
|
@@ -1265,20 +1265,20 @@ var require_sonic_boom = __commonJS({
|
|
|
1265
1265
|
const mode = sonic.mode;
|
|
1266
1266
|
if (sonic.sync) {
|
|
1267
1267
|
try {
|
|
1268
|
-
if (sonic.mkdir)
|
|
1269
|
-
const fd =
|
|
1268
|
+
if (sonic.mkdir) fs21.mkdirSync(path22.dirname(file), { recursive: true });
|
|
1269
|
+
const fd = fs21.openSync(file, flags, mode);
|
|
1270
1270
|
fileOpened(null, fd);
|
|
1271
1271
|
} catch (err) {
|
|
1272
1272
|
fileOpened(err);
|
|
1273
1273
|
throw err;
|
|
1274
1274
|
}
|
|
1275
1275
|
} else if (sonic.mkdir) {
|
|
1276
|
-
|
|
1276
|
+
fs21.mkdir(path22.dirname(file), { recursive: true }, (err) => {
|
|
1277
1277
|
if (err) return fileOpened(err);
|
|
1278
|
-
|
|
1278
|
+
fs21.open(file, flags, mode, fileOpened);
|
|
1279
1279
|
});
|
|
1280
1280
|
} else {
|
|
1281
|
-
|
|
1281
|
+
fs21.open(file, flags, mode, fileOpened);
|
|
1282
1282
|
}
|
|
1283
1283
|
}
|
|
1284
1284
|
function SonicBoom(opts) {
|
|
@@ -1319,8 +1319,8 @@ var require_sonic_boom = __commonJS({
|
|
|
1319
1319
|
this.flush = flushBuffer;
|
|
1320
1320
|
this.flushSync = flushBufferSync;
|
|
1321
1321
|
this._actualWrite = actualWriteBuffer;
|
|
1322
|
-
fsWriteSync = () =>
|
|
1323
|
-
fsWrite = () =>
|
|
1322
|
+
fsWriteSync = () => fs21.writeSync(this.fd, this._writingBuf);
|
|
1323
|
+
fsWrite = () => fs21.write(this.fd, this._writingBuf, this.release);
|
|
1324
1324
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
1325
1325
|
this._writingBuf = "";
|
|
1326
1326
|
this.write = write;
|
|
@@ -1329,15 +1329,15 @@ var require_sonic_boom = __commonJS({
|
|
|
1329
1329
|
this._actualWrite = actualWrite;
|
|
1330
1330
|
fsWriteSync = () => {
|
|
1331
1331
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
1332
|
-
return
|
|
1332
|
+
return fs21.writeSync(this.fd, this._writingBuf);
|
|
1333
1333
|
}
|
|
1334
|
-
return
|
|
1334
|
+
return fs21.writeSync(this.fd, this._writingBuf, "utf8");
|
|
1335
1335
|
};
|
|
1336
1336
|
fsWrite = () => {
|
|
1337
1337
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
1338
|
-
return
|
|
1338
|
+
return fs21.write(this.fd, this._writingBuf, this.release);
|
|
1339
1339
|
}
|
|
1340
|
-
return
|
|
1340
|
+
return fs21.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
1341
1341
|
};
|
|
1342
1342
|
} else {
|
|
1343
1343
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -1394,7 +1394,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1394
1394
|
}
|
|
1395
1395
|
}
|
|
1396
1396
|
if (this._fsync) {
|
|
1397
|
-
|
|
1397
|
+
fs21.fsyncSync(this.fd);
|
|
1398
1398
|
}
|
|
1399
1399
|
const len = this._len;
|
|
1400
1400
|
if (this._reopening) {
|
|
@@ -1508,7 +1508,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1508
1508
|
const onDrain = () => {
|
|
1509
1509
|
if (!this._fsync) {
|
|
1510
1510
|
try {
|
|
1511
|
-
|
|
1511
|
+
fs21.fsync(this.fd, (err) => {
|
|
1512
1512
|
this._flushPending = false;
|
|
1513
1513
|
cb(err);
|
|
1514
1514
|
});
|
|
@@ -1610,7 +1610,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1610
1610
|
const fd = this.fd;
|
|
1611
1611
|
this.once("ready", () => {
|
|
1612
1612
|
if (fd !== this.fd) {
|
|
1613
|
-
|
|
1613
|
+
fs21.close(fd, (err) => {
|
|
1614
1614
|
if (err) {
|
|
1615
1615
|
return this.emit("error", err);
|
|
1616
1616
|
}
|
|
@@ -1659,7 +1659,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1659
1659
|
buf = this._bufs[0];
|
|
1660
1660
|
}
|
|
1661
1661
|
try {
|
|
1662
|
-
const n = Buffer.isBuffer(buf) ?
|
|
1662
|
+
const n = Buffer.isBuffer(buf) ? fs21.writeSync(this.fd, buf) : fs21.writeSync(this.fd, buf, "utf8");
|
|
1663
1663
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
1664
1664
|
buf = releasedBufObj.writingBuf;
|
|
1665
1665
|
this._len = releasedBufObj.len;
|
|
@@ -1675,7 +1675,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1675
1675
|
}
|
|
1676
1676
|
}
|
|
1677
1677
|
try {
|
|
1678
|
-
|
|
1678
|
+
fs21.fsyncSync(this.fd);
|
|
1679
1679
|
} catch {
|
|
1680
1680
|
}
|
|
1681
1681
|
}
|
|
@@ -1696,7 +1696,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1696
1696
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
1697
1697
|
}
|
|
1698
1698
|
try {
|
|
1699
|
-
const n =
|
|
1699
|
+
const n = fs21.writeSync(this.fd, buf);
|
|
1700
1700
|
buf = buf.subarray(n);
|
|
1701
1701
|
this._len = Math.max(this._len - n, 0);
|
|
1702
1702
|
if (buf.length <= 0) {
|
|
@@ -1724,13 +1724,13 @@ var require_sonic_boom = __commonJS({
|
|
|
1724
1724
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
1725
1725
|
if (this.sync) {
|
|
1726
1726
|
try {
|
|
1727
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
1727
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs21.writeSync(this.fd, this._writingBuf) : fs21.writeSync(this.fd, this._writingBuf, "utf8");
|
|
1728
1728
|
release(null, written);
|
|
1729
1729
|
} catch (err) {
|
|
1730
1730
|
release(err);
|
|
1731
1731
|
}
|
|
1732
1732
|
} else {
|
|
1733
|
-
|
|
1733
|
+
fs21.write(this.fd, this._writingBuf, release);
|
|
1734
1734
|
}
|
|
1735
1735
|
}
|
|
1736
1736
|
function actualWriteBuffer() {
|
|
@@ -1739,7 +1739,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1739
1739
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
1740
1740
|
if (this.sync) {
|
|
1741
1741
|
try {
|
|
1742
|
-
const written =
|
|
1742
|
+
const written = fs21.writeSync(this.fd, this._writingBuf);
|
|
1743
1743
|
release(null, written);
|
|
1744
1744
|
} catch (err) {
|
|
1745
1745
|
release(err);
|
|
@@ -1748,7 +1748,7 @@ var require_sonic_boom = __commonJS({
|
|
|
1748
1748
|
if (kCopyBuffer) {
|
|
1749
1749
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
1750
1750
|
}
|
|
1751
|
-
|
|
1751
|
+
fs21.write(this.fd, this._writingBuf, release);
|
|
1752
1752
|
}
|
|
1753
1753
|
}
|
|
1754
1754
|
function actualClose(sonic) {
|
|
@@ -1764,12 +1764,12 @@ var require_sonic_boom = __commonJS({
|
|
|
1764
1764
|
sonic._lens = [];
|
|
1765
1765
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
1766
1766
|
try {
|
|
1767
|
-
|
|
1767
|
+
fs21.fsync(sonic.fd, closeWrapped);
|
|
1768
1768
|
} catch {
|
|
1769
1769
|
}
|
|
1770
1770
|
function closeWrapped() {
|
|
1771
1771
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
1772
|
-
|
|
1772
|
+
fs21.close(sonic.fd, done);
|
|
1773
1773
|
} else {
|
|
1774
1774
|
done();
|
|
1775
1775
|
}
|
|
@@ -4133,7 +4133,7 @@ var require_multistream = __commonJS({
|
|
|
4133
4133
|
var require_pino = __commonJS({
|
|
4134
4134
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
4135
4135
|
"use strict";
|
|
4136
|
-
var
|
|
4136
|
+
var os13 = require("os");
|
|
4137
4137
|
var stdSerializers = require_pino_std_serializers();
|
|
4138
4138
|
var caller = require_caller();
|
|
4139
4139
|
var redaction = require_redaction();
|
|
@@ -4180,7 +4180,7 @@ var require_pino = __commonJS({
|
|
|
4180
4180
|
} = symbols;
|
|
4181
4181
|
var { epochTime, nullTime } = time;
|
|
4182
4182
|
var { pid } = process;
|
|
4183
|
-
var hostname =
|
|
4183
|
+
var hostname = os13.hostname();
|
|
4184
4184
|
var defaultErrorSerializer = stdSerializers.err;
|
|
4185
4185
|
var defaultOptions = {
|
|
4186
4186
|
level: "info",
|
|
@@ -4384,7 +4384,6 @@ var init_methods = __esm({
|
|
|
4384
4384
|
"workspace:list",
|
|
4385
4385
|
"workspace:read",
|
|
4386
4386
|
"skills:list",
|
|
4387
|
-
"agents:list",
|
|
4388
4387
|
"git:root",
|
|
4389
4388
|
"git:branch",
|
|
4390
4389
|
"git:branches",
|
|
@@ -4409,7 +4408,7 @@ var init_methods = __esm({
|
|
|
4409
4408
|
});
|
|
4410
4409
|
|
|
4411
4410
|
// ../protocol/src/events.ts
|
|
4412
|
-
var SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES,
|
|
4411
|
+
var SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, ASK_USER_QUESTION_TOOL_NAME;
|
|
4413
4412
|
var init_events = __esm({
|
|
4414
4413
|
"../protocol/src/events.ts"() {
|
|
4415
4414
|
"use strict";
|
|
@@ -4430,14 +4429,6 @@ var init_events = __esm({
|
|
|
4430
4429
|
"attachment-skills",
|
|
4431
4430
|
"attachment-deferred-tools"
|
|
4432
4431
|
];
|
|
4433
|
-
SKILL_SOURCE_VALUES = ["builtin", "global", "project", "plugin"];
|
|
4434
|
-
AGENT_SOURCE_VALUES = [
|
|
4435
|
-
"builtin",
|
|
4436
|
-
"global",
|
|
4437
|
-
"project",
|
|
4438
|
-
"policy",
|
|
4439
|
-
"plugin"
|
|
4440
|
-
];
|
|
4441
4432
|
ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
|
|
4442
4433
|
}
|
|
4443
4434
|
});
|
|
@@ -8646,7 +8637,7 @@ var init_persona_schemas = __esm({
|
|
|
8646
8637
|
});
|
|
8647
8638
|
|
|
8648
8639
|
// ../protocol/src/schemas.ts
|
|
8649
|
-
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,
|
|
8640
|
+
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, SessionSubscribeArgs, SessionPinArgs, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, GitWorktreePrefixArgs, GitWorktreePrefixResponseSchema, GitWorktreeCreateArgs, GitWorktreeCreateResponseSchema, GitWorktreeRemoveArgs, GitWorktreeRemoveResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelExitedEventSchema, InfoRunningSessionSchema, InfoResponseSchema;
|
|
8650
8641
|
var init_schemas = __esm({
|
|
8651
8642
|
"../protocol/src/schemas.ts"() {
|
|
8652
8643
|
"use strict";
|
|
@@ -8741,6 +8732,9 @@ var init_schemas = __esm({
|
|
|
8741
8732
|
// 由 session:fork 派生的 session 在 create 时记录源 transcript 的 toolSessionId;
|
|
8742
8733
|
// sidebar 据此挂 fork 图标。非 fork session 该字段缺省
|
|
8743
8734
|
forkedFromToolSessionId: external_exports.string().min(1).optional(),
|
|
8735
|
+
// owner-mode persona session 身份标识;UI 用它在 SessionList 过滤 + jump,
|
|
8736
|
+
// daemon 用它做 idempotent dedupe + spawn 时派生 ctx.personaMode='owner'
|
|
8737
|
+
ownerPersonaId: external_exports.string().min(1).optional(),
|
|
8744
8738
|
createdAt: external_exports.string().min(1),
|
|
8745
8739
|
updatedAt: external_exports.string().min(1)
|
|
8746
8740
|
});
|
|
@@ -8940,7 +8934,8 @@ var init_schemas = __esm({
|
|
|
8940
8934
|
})
|
|
8941
8935
|
]);
|
|
8942
8936
|
SessionCreateArgs = external_exports.object({
|
|
8943
|
-
cwd
|
|
8937
|
+
// 当 ownerPersonaId 存在时 cwd 由 daemon 派生,UI 可不传
|
|
8938
|
+
cwd: external_exports.string().min(1).optional(),
|
|
8944
8939
|
tool: external_exports.string().optional(),
|
|
8945
8940
|
label: external_exports.string().optional(),
|
|
8946
8941
|
model: external_exports.string().optional(),
|
|
@@ -8952,7 +8947,12 @@ var init_schemas = __esm({
|
|
|
8952
8947
|
worktreeRoot: external_exports.string().min(1).optional(),
|
|
8953
8948
|
worktreeBranch: external_exports.string().min(1).optional(),
|
|
8954
8949
|
// session:fork 派生 session 时由 UI 传入,daemon 写到 SessionFile.forkedFromToolSessionId
|
|
8955
|
-
forkedFromToolSessionId: external_exports.string().min(1).optional()
|
|
8950
|
+
forkedFromToolSessionId: external_exports.string().min(1).optional(),
|
|
8951
|
+
// owner-mode persona session:传此字段时 daemon 自行派生 cwd 和启动参数,
|
|
8952
|
+
// 且按 ownerPersonaId 做 idempotent dedupe(每 persona 永远只有一个 owner session)
|
|
8953
|
+
ownerPersonaId: external_exports.string().min(1).optional()
|
|
8954
|
+
}).refine((args) => args.cwd != null || args.ownerPersonaId != null, {
|
|
8955
|
+
message: "cwd \u4E0E ownerPersonaId \u81F3\u5C11\u4F20\u4E00\u4E2A"
|
|
8956
8956
|
});
|
|
8957
8957
|
SessionIdArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
|
|
8958
8958
|
SessionUpdateArgs = external_exports.object({
|
|
@@ -9069,25 +9069,6 @@ var init_schemas = __esm({
|
|
|
9069
9069
|
path: external_exports.string().min(1)
|
|
9070
9070
|
});
|
|
9071
9071
|
SkillsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
|
|
9072
|
-
SkillEntrySchema = external_exports.object({
|
|
9073
|
-
name: external_exports.string().min(1),
|
|
9074
|
-
source: external_exports.enum(SKILL_SOURCE_VALUES),
|
|
9075
|
-
path: external_exports.string().optional(),
|
|
9076
|
-
description: external_exports.string().optional(),
|
|
9077
|
-
plugin: external_exports.string().optional()
|
|
9078
|
-
});
|
|
9079
|
-
AgentEntrySchema = external_exports.object({
|
|
9080
|
-
name: external_exports.string().min(1),
|
|
9081
|
-
source: external_exports.enum(AGENT_SOURCE_VALUES),
|
|
9082
|
-
path: external_exports.string().optional(),
|
|
9083
|
-
description: external_exports.string().optional(),
|
|
9084
|
-
whenToUse: external_exports.string().optional(),
|
|
9085
|
-
plugin: external_exports.string().optional()
|
|
9086
|
-
});
|
|
9087
|
-
AgentsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
|
|
9088
|
-
AgentsListResponseSchema = external_exports.object({
|
|
9089
|
-
agents: external_exports.array(AgentEntrySchema)
|
|
9090
|
-
});
|
|
9091
9072
|
SessionSubscribeArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
|
|
9092
9073
|
SessionPinArgs = external_exports.object({
|
|
9093
9074
|
sessionId: external_exports.string().min(1),
|
|
@@ -9202,6 +9183,13 @@ var init_frames = __esm({
|
|
|
9202
9183
|
}
|
|
9203
9184
|
});
|
|
9204
9185
|
|
|
9186
|
+
// ../protocol/src/persona-mode.ts
|
|
9187
|
+
var init_persona_mode = __esm({
|
|
9188
|
+
"../protocol/src/persona-mode.ts"() {
|
|
9189
|
+
"use strict";
|
|
9190
|
+
}
|
|
9191
|
+
});
|
|
9192
|
+
|
|
9205
9193
|
// ../protocol/src/runtime.ts
|
|
9206
9194
|
var init_runtime = __esm({
|
|
9207
9195
|
"../protocol/src/runtime.ts"() {
|
|
@@ -9212,6 +9200,7 @@ var init_runtime = __esm({
|
|
|
9212
9200
|
init_schemas();
|
|
9213
9201
|
init_frames();
|
|
9214
9202
|
init_persona_schemas();
|
|
9203
|
+
init_persona_mode();
|
|
9215
9204
|
}
|
|
9216
9205
|
});
|
|
9217
9206
|
|
|
@@ -10273,7 +10262,7 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
10273
10262
|
if (backupFileName === null) return null;
|
|
10274
10263
|
try {
|
|
10275
10264
|
return import_node_fs6.default.readFileSync(
|
|
10276
|
-
|
|
10265
|
+
import_node_path6.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
10277
10266
|
"utf8"
|
|
10278
10267
|
);
|
|
10279
10268
|
} catch {
|
|
@@ -10288,13 +10277,13 @@ function readCurrentContent(filePath) {
|
|
|
10288
10277
|
return null;
|
|
10289
10278
|
}
|
|
10290
10279
|
}
|
|
10291
|
-
var import_node_fs6, import_node_os2,
|
|
10280
|
+
var import_node_fs6, import_node_os2, import_node_path6, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
|
|
10292
10281
|
var init_claude_history = __esm({
|
|
10293
10282
|
"src/tools/claude-history.ts"() {
|
|
10294
10283
|
"use strict";
|
|
10295
10284
|
import_node_fs6 = __toESM(require("fs"), 1);
|
|
10296
10285
|
import_node_os2 = __toESM(require("os"), 1);
|
|
10297
|
-
|
|
10286
|
+
import_node_path6 = __toESM(require("path"), 1);
|
|
10298
10287
|
init_lib();
|
|
10299
10288
|
init_tool_result_extra();
|
|
10300
10289
|
TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
|
|
@@ -10318,9 +10307,9 @@ var init_claude_history = __esm({
|
|
|
10318
10307
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
10319
10308
|
fileHistoryRoot;
|
|
10320
10309
|
constructor(opts = {}) {
|
|
10321
|
-
const base = opts.baseDir ??
|
|
10322
|
-
this.projectsRoot =
|
|
10323
|
-
this.fileHistoryRoot =
|
|
10310
|
+
const base = opts.baseDir ?? import_node_path6.default.join(import_node_os2.default.homedir(), ".claude");
|
|
10311
|
+
this.projectsRoot = import_node_path6.default.join(base, "projects");
|
|
10312
|
+
this.fileHistoryRoot = import_node_path6.default.join(base, "file-history");
|
|
10324
10313
|
}
|
|
10325
10314
|
async listProjects() {
|
|
10326
10315
|
let entries;
|
|
@@ -10333,9 +10322,9 @@ var init_claude_history = __esm({
|
|
|
10333
10322
|
const out = [];
|
|
10334
10323
|
for (const ent of entries) {
|
|
10335
10324
|
if (!ent.isDirectory()) continue;
|
|
10336
|
-
const dir =
|
|
10325
|
+
const dir = import_node_path6.default.join(this.projectsRoot, ent.name);
|
|
10337
10326
|
const files = import_node_fs6.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
10338
|
-
const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(
|
|
10327
|
+
const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(import_node_path6.default.join(dir, f))), 0);
|
|
10339
10328
|
out.push({
|
|
10340
10329
|
projectPath: hashDirToCwd(ent.name),
|
|
10341
10330
|
hashDir: ent.name,
|
|
@@ -10347,7 +10336,7 @@ var init_claude_history = __esm({
|
|
|
10347
10336
|
return out;
|
|
10348
10337
|
}
|
|
10349
10338
|
async listSessions(args) {
|
|
10350
|
-
const dir =
|
|
10339
|
+
const dir = import_node_path6.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
10351
10340
|
let files;
|
|
10352
10341
|
try {
|
|
10353
10342
|
files = import_node_fs6.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
@@ -10357,7 +10346,7 @@ var init_claude_history = __esm({
|
|
|
10357
10346
|
}
|
|
10358
10347
|
const out = [];
|
|
10359
10348
|
for (const f of files) {
|
|
10360
|
-
const full =
|
|
10349
|
+
const full = import_node_path6.default.join(dir, f);
|
|
10361
10350
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
10362
10351
|
const lines = readJsonlLines(full);
|
|
10363
10352
|
let summary = "";
|
|
@@ -10412,7 +10401,7 @@ var init_claude_history = __esm({
|
|
|
10412
10401
|
return out;
|
|
10413
10402
|
}
|
|
10414
10403
|
async read(args) {
|
|
10415
|
-
const file =
|
|
10404
|
+
const file = import_node_path6.default.join(
|
|
10416
10405
|
this.projectsRoot,
|
|
10417
10406
|
cwdToHashDir(args.cwd),
|
|
10418
10407
|
`${args.toolSessionId}.jsonl`
|
|
@@ -10445,7 +10434,7 @@ var init_claude_history = __esm({
|
|
|
10445
10434
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
10446
10435
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
10447
10436
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
10448
|
-
const dir =
|
|
10437
|
+
const dir = import_node_path6.default.join(
|
|
10449
10438
|
this.projectsRoot,
|
|
10450
10439
|
cwdToHashDir(cwd),
|
|
10451
10440
|
toolSessionId,
|
|
@@ -10463,7 +10452,7 @@ var init_claude_history = __esm({
|
|
|
10463
10452
|
if (!e.isFile()) continue;
|
|
10464
10453
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
10465
10454
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
10466
|
-
const filePath =
|
|
10455
|
+
const filePath = import_node_path6.default.join(dir, e.name);
|
|
10467
10456
|
const lines = readJsonlLines(filePath);
|
|
10468
10457
|
let firstText = "";
|
|
10469
10458
|
let messageCount = 0;
|
|
@@ -10480,7 +10469,7 @@ var init_claude_history = __esm({
|
|
|
10480
10469
|
return out;
|
|
10481
10470
|
}
|
|
10482
10471
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
10483
|
-
const file =
|
|
10472
|
+
const file = import_node_path6.default.join(
|
|
10484
10473
|
this.projectsRoot,
|
|
10485
10474
|
cwdToHashDir(cwd),
|
|
10486
10475
|
`${toolSessionId}.jsonl`
|
|
@@ -10515,7 +10504,7 @@ var init_claude_history = __esm({
|
|
|
10515
10504
|
}
|
|
10516
10505
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
10517
10506
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
10518
|
-
const file =
|
|
10507
|
+
const file = import_node_path6.default.join(
|
|
10519
10508
|
this.projectsRoot,
|
|
10520
10509
|
cwdToHashDir(cwd),
|
|
10521
10510
|
toolSessionId,
|
|
@@ -10543,7 +10532,7 @@ var init_claude_history = __esm({
|
|
|
10543
10532
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
10544
10533
|
*/
|
|
10545
10534
|
readFileHistorySnapshots(args) {
|
|
10546
|
-
const file =
|
|
10535
|
+
const file = import_node_path6.default.join(
|
|
10547
10536
|
this.projectsRoot,
|
|
10548
10537
|
cwdToHashDir(args.cwd),
|
|
10549
10538
|
`${args.toolSessionId}.jsonl`
|
|
@@ -10588,7 +10577,7 @@ var init_claude_history = __esm({
|
|
|
10588
10577
|
for (const [anchorId, target] of snapshots) {
|
|
10589
10578
|
let hasAny = false;
|
|
10590
10579
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
10591
|
-
const absPath =
|
|
10580
|
+
const absPath = import_node_path6.default.isAbsolute(rawPath) ? rawPath : import_node_path6.default.join(args.cwd, rawPath);
|
|
10592
10581
|
const backupContent = readBackupContent(
|
|
10593
10582
|
this.fileHistoryRoot,
|
|
10594
10583
|
args.toolSessionId,
|
|
@@ -10628,7 +10617,7 @@ var init_claude_history = __esm({
|
|
|
10628
10617
|
let totalInsertions = 0;
|
|
10629
10618
|
let totalDeletions = 0;
|
|
10630
10619
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
10631
|
-
const absPath =
|
|
10620
|
+
const absPath = import_node_path6.default.isAbsolute(rawPath) ? rawPath : import_node_path6.default.join(args.cwd, rawPath);
|
|
10632
10621
|
const backupContent = readBackupContent(
|
|
10633
10622
|
this.fileHistoryRoot,
|
|
10634
10623
|
args.toolSessionId,
|
|
@@ -10675,7 +10664,7 @@ var init_claude_history = __esm({
|
|
|
10675
10664
|
};
|
|
10676
10665
|
}
|
|
10677
10666
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
10678
|
-
const file =
|
|
10667
|
+
const file = import_node_path6.default.join(
|
|
10679
10668
|
this.projectsRoot,
|
|
10680
10669
|
cwdToHashDir(cwd),
|
|
10681
10670
|
`${toolSessionId}.jsonl`
|
|
@@ -10699,7 +10688,7 @@ var init_claude_history = __esm({
|
|
|
10699
10688
|
// src/tools/claude.ts
|
|
10700
10689
|
function macOSDesktopCandidates(home) {
|
|
10701
10690
|
return [
|
|
10702
|
-
|
|
10691
|
+
import_node_path7.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
|
|
10703
10692
|
"/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
|
|
10704
10693
|
];
|
|
10705
10694
|
}
|
|
@@ -10744,10 +10733,21 @@ function buildSpawnArgs(ctx) {
|
|
|
10744
10733
|
"--verbose"
|
|
10745
10734
|
];
|
|
10746
10735
|
if (ctx.model) args.push("--model", ctx.model);
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10736
|
+
switch (ctx.personaMode) {
|
|
10737
|
+
case "listener":
|
|
10738
|
+
args.push("--setting-sources", "project,local");
|
|
10739
|
+
break;
|
|
10740
|
+
case "owner":
|
|
10741
|
+
args.push("--setting-sources", "user");
|
|
10742
|
+
args.push("--permission-mode", "bypassPermissions");
|
|
10743
|
+
break;
|
|
10744
|
+
case void 0:
|
|
10745
|
+
if (ctx.permissionMode) args.push("--permission-mode", ctx.permissionMode);
|
|
10746
|
+
break;
|
|
10747
|
+
default: {
|
|
10748
|
+
const _exhaustive = ctx.personaMode;
|
|
10749
|
+
throw new Error(`unexpected personaMode: ${String(_exhaustive)}`);
|
|
10750
|
+
}
|
|
10751
10751
|
}
|
|
10752
10752
|
if (ctx.effort) args.push("--effort", ctx.effort);
|
|
10753
10753
|
if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
|
|
@@ -11134,7 +11134,7 @@ function encodeClaudeStdin(text) {
|
|
|
11134
11134
|
};
|
|
11135
11135
|
return JSON.stringify(frame) + "\n";
|
|
11136
11136
|
}
|
|
11137
|
-
var import_node_child_process, import_node_child_process2, import_node_fs7, import_node_os3,
|
|
11137
|
+
var import_node_child_process, import_node_child_process2, import_node_fs7, import_node_os3, import_node_path7, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
|
|
11138
11138
|
var init_claude = __esm({
|
|
11139
11139
|
"src/tools/claude.ts"() {
|
|
11140
11140
|
"use strict";
|
|
@@ -11142,7 +11142,7 @@ var init_claude = __esm({
|
|
|
11142
11142
|
import_node_child_process2 = require("child_process");
|
|
11143
11143
|
import_node_fs7 = __toESM(require("fs"), 1);
|
|
11144
11144
|
import_node_os3 = __toESM(require("os"), 1);
|
|
11145
|
-
|
|
11145
|
+
import_node_path7 = __toESM(require("path"), 1);
|
|
11146
11146
|
init_protocol();
|
|
11147
11147
|
init_claude_history();
|
|
11148
11148
|
init_tool_result_extra();
|
|
@@ -14911,8 +14911,8 @@ function startRunCaseRecorder(opts) {
|
|
|
14911
14911
|
});
|
|
14912
14912
|
const ensureStream = () => {
|
|
14913
14913
|
if (stream) return stream;
|
|
14914
|
-
|
|
14915
|
-
stream =
|
|
14914
|
+
import_node_fs19.default.mkdirSync(dir, { recursive: true });
|
|
14915
|
+
stream = import_node_fs19.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
14916
14916
|
stream.on("close", () => closedResolve());
|
|
14917
14917
|
return stream;
|
|
14918
14918
|
};
|
|
@@ -14937,11 +14937,11 @@ function startRunCaseRecorder(opts) {
|
|
|
14937
14937
|
};
|
|
14938
14938
|
return { tap, close, closed };
|
|
14939
14939
|
}
|
|
14940
|
-
var
|
|
14940
|
+
var import_node_fs19, import_node_path19;
|
|
14941
14941
|
var init_recorder = __esm({
|
|
14942
14942
|
"src/run-case/recorder.ts"() {
|
|
14943
14943
|
"use strict";
|
|
14944
|
-
|
|
14944
|
+
import_node_fs19 = __toESM(require("fs"), 1);
|
|
14945
14945
|
import_node_path19 = __toESM(require("path"), 1);
|
|
14946
14946
|
}
|
|
14947
14947
|
});
|
|
@@ -14985,7 +14985,7 @@ var init_wire = __esm({
|
|
|
14985
14985
|
// src/run-case/controller.ts
|
|
14986
14986
|
async function runController(opts) {
|
|
14987
14987
|
const now = opts.now ?? Date.now;
|
|
14988
|
-
const cwd = opts.cwd ?? (0,
|
|
14988
|
+
const cwd = opts.cwd ?? (0, import_node_fs20.mkdtempSync)(import_node_path20.default.join(import_node_os12.default.tmpdir(), "clawd-runcase-"));
|
|
14989
14989
|
const ownsCwd = opts.cwd === void 0;
|
|
14990
14990
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
14991
14991
|
const spawnCtx = { cwd };
|
|
@@ -15146,18 +15146,18 @@ async function runController(opts) {
|
|
|
15146
15146
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
15147
15147
|
if (ownsCwd) {
|
|
15148
15148
|
try {
|
|
15149
|
-
(0,
|
|
15149
|
+
(0, import_node_fs20.rmSync)(cwd, { recursive: true, force: true });
|
|
15150
15150
|
} catch {
|
|
15151
15151
|
}
|
|
15152
15152
|
}
|
|
15153
15153
|
return exitCode ?? 0;
|
|
15154
15154
|
}
|
|
15155
|
-
var
|
|
15155
|
+
var import_node_fs20, import_node_os12, import_node_path20;
|
|
15156
15156
|
var init_controller = __esm({
|
|
15157
15157
|
"src/run-case/controller.ts"() {
|
|
15158
15158
|
"use strict";
|
|
15159
|
-
|
|
15160
|
-
|
|
15159
|
+
import_node_fs20 = require("fs");
|
|
15160
|
+
import_node_os12 = __toESM(require("os"), 1);
|
|
15161
15161
|
import_node_path20 = __toESM(require("path"), 1);
|
|
15162
15162
|
init_claude();
|
|
15163
15163
|
init_stdout_splitter();
|
|
@@ -15384,7 +15384,7 @@ Env (advanced):
|
|
|
15384
15384
|
|
|
15385
15385
|
// src/index.ts
|
|
15386
15386
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
15387
|
-
var
|
|
15387
|
+
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
15388
15388
|
|
|
15389
15389
|
// src/logger.ts
|
|
15390
15390
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
@@ -15514,6 +15514,7 @@ var SessionStore = class {
|
|
|
15514
15514
|
|
|
15515
15515
|
// src/session/manager.ts
|
|
15516
15516
|
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
15517
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
15517
15518
|
|
|
15518
15519
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
15519
15520
|
var byteToHex = [];
|
|
@@ -15660,7 +15661,7 @@ function buildSpawnContext(state) {
|
|
|
15660
15661
|
};
|
|
15661
15662
|
const meta = state.subSessionMeta;
|
|
15662
15663
|
if (meta?.personaMode) {
|
|
15663
|
-
ctx.personaMode =
|
|
15664
|
+
ctx.personaMode = meta.personaMode;
|
|
15664
15665
|
}
|
|
15665
15666
|
return ctx;
|
|
15666
15667
|
}
|
|
@@ -16642,10 +16643,22 @@ var SessionManager = class {
|
|
|
16642
16643
|
this.capabilitiesCache.set(tool, caps);
|
|
16643
16644
|
return caps;
|
|
16644
16645
|
}
|
|
16646
|
+
// 按优先级解析 SubSessionMeta:subSessionMetaBySid 缓存(内存,首次 create/registerSubSession 写入)
|
|
16647
|
+
// → SessionFile.ownerPersonaId 派生(持久化兜底,daemon 重启后 subSessionMetaBySid 丢失时生效)
|
|
16648
|
+
// → undefined(普通 session)
|
|
16649
|
+
resolveSubSessionMeta(file) {
|
|
16650
|
+
const cached = this.subSessionMetaBySid.get(file.sessionId);
|
|
16651
|
+
if (cached) return cached;
|
|
16652
|
+
if (file.ownerPersonaId) {
|
|
16653
|
+
return { idleKillEnabled: false, personaMode: "owner" };
|
|
16654
|
+
}
|
|
16655
|
+
return void 0;
|
|
16656
|
+
}
|
|
16645
16657
|
// 创建 runner 时包一层 broadcast hook:所有外出 frame 统一走 routeFromRunner,
|
|
16646
16658
|
// 经过 compressFrameForWire 后决定是 push collector 还是走 deps.broadcastFrame
|
|
16647
16659
|
// store:默认 deps.store;persona sub-session 路径下传该 personaId 对应的 SessionStore
|
|
16648
|
-
// subSessionMeta:
|
|
16660
|
+
// subSessionMeta:listener 传 { idleKillEnabled: true, personaMode: 'listener' };
|
|
16661
|
+
// owner 传 { idleKillEnabled: false, personaMode: 'owner' };普通 session 不传
|
|
16649
16662
|
newRunner(file, opts = {}) {
|
|
16650
16663
|
const adapter = this.deps.getAdapter(file.tool ?? "claude");
|
|
16651
16664
|
const store = opts.store ?? this.deps.store;
|
|
@@ -16703,18 +16716,34 @@ var SessionManager = class {
|
|
|
16703
16716
|
}
|
|
16704
16717
|
// ---- 命令方法:均返回 { response, broadcast[] },由 dispatcher 聚合 ----
|
|
16705
16718
|
create(args) {
|
|
16719
|
+
if (args.ownerPersonaId) {
|
|
16720
|
+
const existing = this.deps.store.list().find((s) => s.ownerPersonaId === args.ownerPersonaId);
|
|
16721
|
+
if (existing) {
|
|
16722
|
+
return { response: existing, broadcast: [] };
|
|
16723
|
+
}
|
|
16724
|
+
}
|
|
16725
|
+
let cwd = args.cwd;
|
|
16726
|
+
if (args.ownerPersonaId && !cwd) {
|
|
16727
|
+
if (!this.deps.personaRoot) {
|
|
16728
|
+
throw new Error("personaRoot required to derive cwd from ownerPersonaId");
|
|
16729
|
+
}
|
|
16730
|
+
cwd = import_node_path5.default.join(this.deps.personaRoot, safeFileName(args.ownerPersonaId));
|
|
16731
|
+
}
|
|
16732
|
+
if (!cwd) {
|
|
16733
|
+
throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
|
|
16734
|
+
}
|
|
16706
16735
|
try {
|
|
16707
|
-
const stat = import_node_fs5.default.statSync(
|
|
16736
|
+
const stat = import_node_fs5.default.statSync(cwd);
|
|
16708
16737
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
16709
16738
|
} catch {
|
|
16710
|
-
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${
|
|
16739
|
+
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
|
|
16711
16740
|
}
|
|
16712
16741
|
const tool = args.tool ?? "claude";
|
|
16713
16742
|
this.deps.getAdapter(tool);
|
|
16714
16743
|
const iso = nowIso2(this.deps);
|
|
16715
16744
|
const file = {
|
|
16716
16745
|
sessionId: newSessionId(),
|
|
16717
|
-
cwd
|
|
16746
|
+
cwd,
|
|
16718
16747
|
tool,
|
|
16719
16748
|
label: args.label,
|
|
16720
16749
|
model: args.model,
|
|
@@ -16724,10 +16753,17 @@ var SessionManager = class {
|
|
|
16724
16753
|
worktreeRoot: args.worktreeRoot,
|
|
16725
16754
|
worktreeBranch: args.worktreeBranch,
|
|
16726
16755
|
forkedFromToolSessionId: args.forkedFromToolSessionId,
|
|
16756
|
+
ownerPersonaId: args.ownerPersonaId,
|
|
16727
16757
|
createdAt: iso,
|
|
16728
16758
|
updatedAt: iso
|
|
16729
16759
|
};
|
|
16730
16760
|
const written = this.deps.store.write(file);
|
|
16761
|
+
if (args.ownerPersonaId) {
|
|
16762
|
+
this.subSessionMetaBySid.set(written.sessionId, {
|
|
16763
|
+
idleKillEnabled: false,
|
|
16764
|
+
personaMode: "owner"
|
|
16765
|
+
});
|
|
16766
|
+
}
|
|
16731
16767
|
return { response: written, broadcast: [] };
|
|
16732
16768
|
}
|
|
16733
16769
|
pin(args) {
|
|
@@ -16887,7 +16923,8 @@ var SessionManager = class {
|
|
|
16887
16923
|
const existing = this.getFile(args.sessionId);
|
|
16888
16924
|
let runner = this.runners.get(args.sessionId);
|
|
16889
16925
|
if (!runner) {
|
|
16890
|
-
|
|
16926
|
+
const subSessionMeta = this.resolveSubSessionMeta(existing);
|
|
16927
|
+
runner = this.newRunner(existing, { subSessionMeta });
|
|
16891
16928
|
this.runners.set(args.sessionId, runner);
|
|
16892
16929
|
}
|
|
16893
16930
|
const { broadcast } = this.withCollector(() => {
|
|
@@ -16981,7 +17018,8 @@ var SessionManager = class {
|
|
|
16981
17018
|
const file = this.getFile(args.sessionId);
|
|
16982
17019
|
let runner = this.runners.get(args.sessionId);
|
|
16983
17020
|
if (!runner) {
|
|
16984
|
-
|
|
17021
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17022
|
+
runner = this.newRunner(file, { subSessionMeta });
|
|
16985
17023
|
this.runners.set(args.sessionId, runner);
|
|
16986
17024
|
}
|
|
16987
17025
|
if (!runner.getState().procAlive) {
|
|
@@ -17139,7 +17177,7 @@ var SessionManager = class {
|
|
|
17139
17177
|
ensureSession(file) {
|
|
17140
17178
|
let r = this.runners.get(file.sessionId);
|
|
17141
17179
|
if (r) return r;
|
|
17142
|
-
const subSessionMeta = this.
|
|
17180
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17143
17181
|
r = this.newRunner(file, { subSessionMeta });
|
|
17144
17182
|
this.runners.set(file.sessionId, r);
|
|
17145
17183
|
return r;
|
|
@@ -17315,7 +17353,7 @@ var SessionManager = class {
|
|
|
17315
17353
|
const existing = this.runners.get(file.sessionId);
|
|
17316
17354
|
if (existing) return existing;
|
|
17317
17355
|
const store = this.storeFor(agentId);
|
|
17318
|
-
const subSessionMeta = this.
|
|
17356
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17319
17357
|
const runner = this.newRunner(file, { store, subSessionMeta });
|
|
17320
17358
|
this.runners.set(file.sessionId, runner);
|
|
17321
17359
|
return runner;
|
|
@@ -17337,7 +17375,7 @@ var SessionManager = class {
|
|
|
17337
17375
|
}
|
|
17338
17376
|
let runner = this.runners.get(args.sessionId);
|
|
17339
17377
|
if (!runner) {
|
|
17340
|
-
const subSessionMeta = this.
|
|
17378
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17341
17379
|
runner = this.newRunner(file, { store, subSessionMeta });
|
|
17342
17380
|
this.runners.set(args.sessionId, runner);
|
|
17343
17381
|
}
|
|
@@ -17409,7 +17447,7 @@ var SessionManager = class {
|
|
|
17409
17447
|
|
|
17410
17448
|
// src/persona/store.ts
|
|
17411
17449
|
var fs6 = __toESM(require("fs"), 1);
|
|
17412
|
-
var
|
|
17450
|
+
var path6 = __toESM(require("path"), 1);
|
|
17413
17451
|
init_protocol();
|
|
17414
17452
|
var DEFAULT_SETTINGS = {
|
|
17415
17453
|
permissions: {
|
|
@@ -17438,21 +17476,21 @@ var PersonaStore = class {
|
|
|
17438
17476
|
}
|
|
17439
17477
|
root;
|
|
17440
17478
|
personaDir(personaId) {
|
|
17441
|
-
return
|
|
17479
|
+
return path6.join(this.root, safeFileName(personaId));
|
|
17442
17480
|
}
|
|
17443
17481
|
metaPath(personaId) {
|
|
17444
|
-
return
|
|
17482
|
+
return path6.join(this.personaDir(personaId), ".clawd", "persona.json");
|
|
17445
17483
|
}
|
|
17446
17484
|
claudeMdPath(personaId) {
|
|
17447
|
-
return
|
|
17485
|
+
return path6.join(this.personaDir(personaId), "CLAUDE.md");
|
|
17448
17486
|
}
|
|
17449
17487
|
settingsPath(personaId) {
|
|
17450
|
-
return
|
|
17488
|
+
return path6.join(this.personaDir(personaId), ".claude", "settings.json");
|
|
17451
17489
|
}
|
|
17452
17490
|
write(persona, personality) {
|
|
17453
17491
|
const dir = this.personaDir(persona.personaId);
|
|
17454
|
-
fs6.mkdirSync(
|
|
17455
|
-
fs6.mkdirSync(
|
|
17492
|
+
fs6.mkdirSync(path6.join(dir, ".claude"), { recursive: true });
|
|
17493
|
+
fs6.mkdirSync(path6.join(dir, ".clawd"), { recursive: true });
|
|
17456
17494
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
17457
17495
|
this.atomicWrite(this.settingsPath(persona.personaId), JSON.stringify(DEFAULT_SETTINGS, null, 2));
|
|
17458
17496
|
this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
|
|
@@ -17477,7 +17515,7 @@ var PersonaStore = class {
|
|
|
17477
17515
|
list() {
|
|
17478
17516
|
if (!fs6.existsSync(this.root)) return [];
|
|
17479
17517
|
return fs6.readdirSync(this.root).filter((name) => {
|
|
17480
|
-
return fs6.existsSync(
|
|
17518
|
+
return fs6.existsSync(path6.join(this.root, name, ".clawd", "persona.json"));
|
|
17481
17519
|
});
|
|
17482
17520
|
}
|
|
17483
17521
|
remove(personaId) {
|
|
@@ -17642,7 +17680,7 @@ var PersonaManager = class {
|
|
|
17642
17680
|
tool: "claude",
|
|
17643
17681
|
label: subLabel,
|
|
17644
17682
|
model: persona.model,
|
|
17645
|
-
subSessionMeta: { idleKillEnabled: true, personaMode:
|
|
17683
|
+
subSessionMeta: { idleKillEnabled: true, personaMode: "listener" }
|
|
17646
17684
|
});
|
|
17647
17685
|
return { sessionFile, isNew: true };
|
|
17648
17686
|
}
|
|
@@ -17678,14 +17716,14 @@ init_claude_history();
|
|
|
17678
17716
|
// src/workspace/browser.ts
|
|
17679
17717
|
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
17680
17718
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
17681
|
-
var
|
|
17719
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
17682
17720
|
init_protocol();
|
|
17683
17721
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
17684
17722
|
function resolveInsideCwd(cwd, subpath) {
|
|
17685
|
-
const absCwd =
|
|
17686
|
-
const joined =
|
|
17687
|
-
const rel =
|
|
17688
|
-
if (rel.startsWith("..") ||
|
|
17723
|
+
const absCwd = import_node_path8.default.resolve(cwd);
|
|
17724
|
+
const joined = import_node_path8.default.resolve(absCwd, subpath ?? ".");
|
|
17725
|
+
const rel = import_node_path8.default.relative(absCwd, joined);
|
|
17726
|
+
if (rel.startsWith("..") || import_node_path8.default.isAbsolute(rel)) {
|
|
17689
17727
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
17690
17728
|
}
|
|
17691
17729
|
return joined;
|
|
@@ -17716,7 +17754,7 @@ var WorkspaceBrowser = class {
|
|
|
17716
17754
|
mtime: ""
|
|
17717
17755
|
};
|
|
17718
17756
|
try {
|
|
17719
|
-
const st = import_node_fs8.default.statSync(
|
|
17757
|
+
const st = import_node_fs8.default.statSync(import_node_path8.default.join(full, d.name));
|
|
17720
17758
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
17721
17759
|
if (d.isFile()) entry.size = st.size;
|
|
17722
17760
|
} catch {
|
|
@@ -17763,25 +17801,21 @@ var WorkspaceBrowser = class {
|
|
|
17763
17801
|
// src/skills/scanner.ts
|
|
17764
17802
|
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
17765
17803
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
17766
|
-
var
|
|
17767
|
-
|
|
17768
|
-
|
|
17769
|
-
var STRIP_QUOTES = /^["']|["']$/g;
|
|
17770
|
-
function strip(s) {
|
|
17771
|
-
return s.trim().replace(STRIP_QUOTES, "");
|
|
17772
|
-
}
|
|
17773
|
-
function parseFrontmatter(content, keys) {
|
|
17774
|
-
const out = {};
|
|
17775
|
-
if (!content.startsWith("---")) return out;
|
|
17804
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
17805
|
+
function parseFrontmatter(content) {
|
|
17806
|
+
if (!content.startsWith("---")) return { name: "", description: "" };
|
|
17776
17807
|
const end = content.indexOf("---", 3);
|
|
17777
|
-
if (end === -1) return
|
|
17808
|
+
if (end === -1) return { name: "", description: "" };
|
|
17778
17809
|
const lines = content.slice(3, end).split("\n");
|
|
17810
|
+
const strip = (s) => s.trim().replace(/^["']|["']$/g, "");
|
|
17811
|
+
let name = "";
|
|
17812
|
+
let description = "";
|
|
17779
17813
|
for (let i = 0; i < lines.length; i++) {
|
|
17780
17814
|
const trimmed = lines[i].trim();
|
|
17781
|
-
|
|
17782
|
-
|
|
17783
|
-
|
|
17784
|
-
const rest = trimmed.slice(
|
|
17815
|
+
if (trimmed.startsWith("name:")) {
|
|
17816
|
+
name = strip(trimmed.slice(5));
|
|
17817
|
+
} else if (trimmed.startsWith("description:")) {
|
|
17818
|
+
const rest = trimmed.slice(12).trim();
|
|
17785
17819
|
if (rest === "|" || rest === ">" || rest === "|-" || rest === ">-") {
|
|
17786
17820
|
const parts = [];
|
|
17787
17821
|
for (let j = i + 1; j < lines.length; j++) {
|
|
@@ -17793,82 +17827,13 @@ function parseFrontmatter(content, keys) {
|
|
|
17793
17827
|
if (!/^\s/.test(next)) break;
|
|
17794
17828
|
parts.push(next.replace(/^\s+/, ""));
|
|
17795
17829
|
}
|
|
17796
|
-
|
|
17797
|
-
if (value) out[key] = value;
|
|
17830
|
+
description = parts.filter(Boolean).join(" ").trim();
|
|
17798
17831
|
} else {
|
|
17799
|
-
|
|
17800
|
-
if (value) out[key] = value;
|
|
17832
|
+
description = strip(rest);
|
|
17801
17833
|
}
|
|
17802
|
-
break;
|
|
17803
17834
|
}
|
|
17804
17835
|
}
|
|
17805
|
-
return
|
|
17806
|
-
}
|
|
17807
|
-
|
|
17808
|
-
// src/skills/builtin-cc-resources.ts
|
|
17809
|
-
var BUILTIN_SKILLS = [
|
|
17810
|
-
{ name: "update-config", source: "builtin", description: "Update Claude Code configuration." },
|
|
17811
|
-
{ name: "keybindings-help", source: "builtin", description: "Show available keybindings." },
|
|
17812
|
-
{ name: "verify", source: "builtin", description: "Verify the implementation." },
|
|
17813
|
-
{ name: "debug", source: "builtin", description: "Debug current issue." },
|
|
17814
|
-
{ name: "lorem-ipsum", source: "builtin", description: "Generate lorem ipsum placeholder text." },
|
|
17815
|
-
{ name: "skillify", source: "builtin", description: "Convert a process into a reusable skill." },
|
|
17816
|
-
{ name: "remember", source: "builtin", description: "Remember context for later use." },
|
|
17817
|
-
{ name: "simplify", source: "builtin", description: "Simplify the code or message." },
|
|
17818
|
-
{ name: "batch", source: "builtin", description: "Run a batch of similar operations." },
|
|
17819
|
-
{ name: "stuck", source: "builtin", description: "Help unstick a stalled task." },
|
|
17820
|
-
{ name: "loop", source: "builtin", description: "Loop a task until a condition is met." },
|
|
17821
|
-
{ name: "cron-list", source: "builtin", description: "List scheduled cron tasks." },
|
|
17822
|
-
{ name: "cron-delete", source: "builtin", description: "Delete a scheduled cron task." },
|
|
17823
|
-
{ name: "dream", source: "builtin", description: "Brainstorm freely without constraints." },
|
|
17824
|
-
{ name: "hunter", source: "builtin", description: "Hunt down a bug or root cause." },
|
|
17825
|
-
{ name: "schedule", source: "builtin", description: "Schedule a task to run later." },
|
|
17826
|
-
{ name: "claude-api", source: "builtin", description: "Use the Claude API directly." },
|
|
17827
|
-
{ name: "claude-in-chrome", source: "builtin", description: "Drive Claude inside Chrome via the Chrome extension." }
|
|
17828
|
-
];
|
|
17829
|
-
var BUILTIN_AGENTS = [
|
|
17830
|
-
{
|
|
17831
|
-
name: "general-purpose",
|
|
17832
|
-
source: "builtin",
|
|
17833
|
-
description: "General-purpose agent for researching complex questions and executing multi-step tasks.",
|
|
17834
|
-
whenToUse: "When you are searching for a keyword or file and are not confident you will find the right match in the first few tries."
|
|
17835
|
-
},
|
|
17836
|
-
{
|
|
17837
|
-
name: "statusline-setup",
|
|
17838
|
-
source: "builtin",
|
|
17839
|
-
description: "Configure the user's Claude Code status line setting.",
|
|
17840
|
-
whenToUse: "When the user is setting up or changing their status line configuration."
|
|
17841
|
-
},
|
|
17842
|
-
{
|
|
17843
|
-
name: "Explore",
|
|
17844
|
-
source: "builtin",
|
|
17845
|
-
description: "Explore the codebase to gather context.",
|
|
17846
|
-
whenToUse: "Before making changes that require understanding the surrounding code."
|
|
17847
|
-
},
|
|
17848
|
-
{
|
|
17849
|
-
name: "Plan",
|
|
17850
|
-
source: "builtin",
|
|
17851
|
-
description: "Produce an implementation plan before writing code.",
|
|
17852
|
-
whenToUse: "When the task is non-trivial and would benefit from an explicit plan."
|
|
17853
|
-
},
|
|
17854
|
-
{
|
|
17855
|
-
name: "claude-code-guide",
|
|
17856
|
-
source: "builtin",
|
|
17857
|
-
description: "Guide the user through Claude Code features.",
|
|
17858
|
-
whenToUse: "When the user needs help understanding what Claude Code can do."
|
|
17859
|
-
},
|
|
17860
|
-
{
|
|
17861
|
-
name: "verification",
|
|
17862
|
-
source: "builtin",
|
|
17863
|
-
description: "Verify that a change works as intended.",
|
|
17864
|
-
whenToUse: "After implementing a change, before declaring it done."
|
|
17865
|
-
}
|
|
17866
|
-
];
|
|
17867
|
-
|
|
17868
|
-
// src/skills/scanner.ts
|
|
17869
|
-
function parseDescription(content) {
|
|
17870
|
-
const fields = parseFrontmatter(content, ["description"]);
|
|
17871
|
-
return { description: fields.description ?? "" };
|
|
17836
|
+
return { name, description };
|
|
17872
17837
|
}
|
|
17873
17838
|
function isDirLikeSync(p) {
|
|
17874
17839
|
try {
|
|
@@ -17885,19 +17850,19 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
|
17885
17850
|
return;
|
|
17886
17851
|
}
|
|
17887
17852
|
for (const ent of entries) {
|
|
17888
|
-
const entryPath =
|
|
17853
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
17889
17854
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
17890
17855
|
let content;
|
|
17891
17856
|
try {
|
|
17892
|
-
content = import_node_fs9.default.readFileSync(
|
|
17857
|
+
content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
|
|
17893
17858
|
} catch {
|
|
17894
17859
|
try {
|
|
17895
|
-
content = import_node_fs9.default.readFileSync(
|
|
17860
|
+
content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
|
|
17896
17861
|
} catch {
|
|
17897
17862
|
continue;
|
|
17898
17863
|
}
|
|
17899
17864
|
}
|
|
17900
|
-
const { description } =
|
|
17865
|
+
const { description } = parseFrontmatter(content);
|
|
17901
17866
|
const baseName = ent.name;
|
|
17902
17867
|
const name = pluginName ? `${pluginName}:${baseName}` : baseName;
|
|
17903
17868
|
if (seen.has(name)) continue;
|
|
@@ -17915,7 +17880,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17915
17880
|
return;
|
|
17916
17881
|
}
|
|
17917
17882
|
for (const ent of entries) {
|
|
17918
|
-
const entryPath =
|
|
17883
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
17919
17884
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
17920
17885
|
const ns = ent.name;
|
|
17921
17886
|
let subEntries;
|
|
@@ -17926,7 +17891,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17926
17891
|
}
|
|
17927
17892
|
for (const se of subEntries) {
|
|
17928
17893
|
if (!se.name.endsWith(".md")) continue;
|
|
17929
|
-
const sePath =
|
|
17894
|
+
const sePath = import_node_path9.default.join(entryPath, se.name);
|
|
17930
17895
|
let content;
|
|
17931
17896
|
try {
|
|
17932
17897
|
content = import_node_fs9.default.readFileSync(sePath, "utf8");
|
|
@@ -17934,7 +17899,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17934
17899
|
continue;
|
|
17935
17900
|
}
|
|
17936
17901
|
const cmd = se.name.replace(/\.md$/, "");
|
|
17937
|
-
const { description } =
|
|
17902
|
+
const { description } = parseFrontmatter(content);
|
|
17938
17903
|
const qualified = `${ns}:${cmd}`;
|
|
17939
17904
|
const name = pluginName ? `${pluginName}:${qualified}` : qualified;
|
|
17940
17905
|
if (seen.has(name)) continue;
|
|
@@ -17951,7 +17916,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17951
17916
|
continue;
|
|
17952
17917
|
}
|
|
17953
17918
|
const cmd = ent.name.replace(/\.md$/, "");
|
|
17954
|
-
const { description } =
|
|
17919
|
+
const { description } = parseFrontmatter(content);
|
|
17955
17920
|
const name = pluginName ? `${pluginName}:${cmd}` : cmd;
|
|
17956
17921
|
if (seen.has(name)) continue;
|
|
17957
17922
|
seen.add(name);
|
|
@@ -17962,7 +17927,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17962
17927
|
}
|
|
17963
17928
|
}
|
|
17964
17929
|
function readInstalledPlugins(home) {
|
|
17965
|
-
const file =
|
|
17930
|
+
const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
17966
17931
|
let raw;
|
|
17967
17932
|
try {
|
|
17968
17933
|
raw = import_node_fs9.default.readFileSync(file, "utf8");
|
|
@@ -18002,231 +17967,30 @@ var SkillsScanner = class {
|
|
|
18002
17967
|
*/
|
|
18003
17968
|
list(args) {
|
|
18004
17969
|
const seen = /* @__PURE__ */ new Set();
|
|
18005
|
-
const
|
|
18006
|
-
|
|
18007
|
-
|
|
18008
|
-
|
|
18009
|
-
|
|
18010
|
-
name: b.name,
|
|
18011
|
-
source: "builtin",
|
|
18012
|
-
description: b.description
|
|
18013
|
-
});
|
|
18014
|
-
}
|
|
18015
|
-
const fsBlock = [];
|
|
18016
|
-
scanSkillDir(import_node_path8.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
|
|
18017
|
-
scanCommandDir(import_node_path8.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
|
|
18018
|
-
scanSkillDir(import_node_path8.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
|
|
18019
|
-
scanCommandDir(import_node_path8.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
|
|
17970
|
+
const out = [];
|
|
17971
|
+
scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, out);
|
|
17972
|
+
scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, out);
|
|
17973
|
+
scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, out);
|
|
17974
|
+
scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, out);
|
|
18020
17975
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
18021
17976
|
for (const { name, root } of plugins) {
|
|
18022
|
-
scanSkillDir(
|
|
18023
|
-
scanCommandDir(
|
|
17977
|
+
scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, out, name);
|
|
17978
|
+
scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, out, name);
|
|
18024
17979
|
}
|
|
18025
|
-
|
|
18026
|
-
return
|
|
17980
|
+
out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
17981
|
+
return out;
|
|
18027
17982
|
}
|
|
18028
17983
|
};
|
|
18029
17984
|
|
|
18030
|
-
// src/
|
|
17985
|
+
// src/observer/session-observer.ts
|
|
18031
17986
|
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
18032
17987
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
18033
|
-
var import_node_path9 = __toESM(require("path"), 1);
|
|
18034
|
-
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
18035
|
-
function isDirLikeSync2(p) {
|
|
18036
|
-
try {
|
|
18037
|
-
return import_node_fs10.default.statSync(p).isDirectory();
|
|
18038
|
-
} catch {
|
|
18039
|
-
return false;
|
|
18040
|
-
}
|
|
18041
|
-
}
|
|
18042
|
-
function fileExistsSync(p) {
|
|
18043
|
-
try {
|
|
18044
|
-
return import_node_fs10.default.statSync(p).isFile();
|
|
18045
|
-
} catch {
|
|
18046
|
-
return false;
|
|
18047
|
-
}
|
|
18048
|
-
}
|
|
18049
|
-
function parseAgentFile(filePath) {
|
|
18050
|
-
let content;
|
|
18051
|
-
try {
|
|
18052
|
-
content = import_node_fs10.default.readFileSync(filePath, "utf8");
|
|
18053
|
-
} catch {
|
|
18054
|
-
return {};
|
|
18055
|
-
}
|
|
18056
|
-
const fm = parseFrontmatter(content, ["description", "whenToUse"]);
|
|
18057
|
-
return {
|
|
18058
|
-
description: fm.description,
|
|
18059
|
-
whenToUse: fm.whenToUse
|
|
18060
|
-
};
|
|
18061
|
-
}
|
|
18062
|
-
function scanAgentsDir(dir, source, seen, out) {
|
|
18063
|
-
let entries;
|
|
18064
|
-
try {
|
|
18065
|
-
entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
|
|
18066
|
-
} catch {
|
|
18067
|
-
return;
|
|
18068
|
-
}
|
|
18069
|
-
for (const ent of entries) {
|
|
18070
|
-
if (!ent.name.endsWith(".md")) continue;
|
|
18071
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path9.default.join(dir, ent.name)))) {
|
|
18072
|
-
continue;
|
|
18073
|
-
}
|
|
18074
|
-
const filePath = import_node_path9.default.join(dir, ent.name);
|
|
18075
|
-
const baseName = ent.name.replace(/\.md$/, "");
|
|
18076
|
-
if (seen.has(baseName)) continue;
|
|
18077
|
-
seen.add(baseName);
|
|
18078
|
-
const { description, whenToUse } = parseAgentFile(filePath);
|
|
18079
|
-
out.push({
|
|
18080
|
-
name: baseName,
|
|
18081
|
-
source,
|
|
18082
|
-
path: filePath,
|
|
18083
|
-
...description ? { description } : {},
|
|
18084
|
-
...whenToUse ? { whenToUse } : {}
|
|
18085
|
-
});
|
|
18086
|
-
}
|
|
18087
|
-
}
|
|
18088
|
-
function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
18089
|
-
function walk(dir, namespaces) {
|
|
18090
|
-
let entries;
|
|
18091
|
-
try {
|
|
18092
|
-
entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
|
|
18093
|
-
} catch {
|
|
18094
|
-
return;
|
|
18095
|
-
}
|
|
18096
|
-
for (const ent of entries) {
|
|
18097
|
-
const childPath = import_node_path9.default.join(dir, ent.name);
|
|
18098
|
-
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
18099
|
-
walk(childPath, [...namespaces, ent.name]);
|
|
18100
|
-
continue;
|
|
18101
|
-
}
|
|
18102
|
-
if (!ent.name.endsWith(".md")) continue;
|
|
18103
|
-
const baseName = ent.name.replace(/\.md$/, "");
|
|
18104
|
-
const nameParts = [pluginName, ...namespaces, baseName];
|
|
18105
|
-
const name = nameParts.join(":");
|
|
18106
|
-
if (seen.has(name)) continue;
|
|
18107
|
-
seen.add(name);
|
|
18108
|
-
const { description, whenToUse } = parseAgentFile(childPath);
|
|
18109
|
-
out.push({
|
|
18110
|
-
name,
|
|
18111
|
-
source: "plugin",
|
|
18112
|
-
path: childPath,
|
|
18113
|
-
plugin: pluginName,
|
|
18114
|
-
...description ? { description } : {},
|
|
18115
|
-
...whenToUse ? { whenToUse } : {}
|
|
18116
|
-
});
|
|
18117
|
-
}
|
|
18118
|
-
}
|
|
18119
|
-
walk(root, []);
|
|
18120
|
-
}
|
|
18121
|
-
function readInstalledPlugins2(home) {
|
|
18122
|
-
const pluginsDir = import_node_path9.default.join(home, ".claude", "plugins");
|
|
18123
|
-
const v2 = import_node_path9.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
18124
|
-
const v1 = import_node_path9.default.join(pluginsDir, "installed_plugins.json");
|
|
18125
|
-
let raw = null;
|
|
18126
|
-
for (const candidate of [v2, v1]) {
|
|
18127
|
-
try {
|
|
18128
|
-
raw = import_node_fs10.default.readFileSync(candidate, "utf8");
|
|
18129
|
-
break;
|
|
18130
|
-
} catch {
|
|
18131
|
-
}
|
|
18132
|
-
}
|
|
18133
|
-
if (!raw) return [];
|
|
18134
|
-
let parsed;
|
|
18135
|
-
try {
|
|
18136
|
-
parsed = JSON.parse(raw);
|
|
18137
|
-
} catch {
|
|
18138
|
-
return [];
|
|
18139
|
-
}
|
|
18140
|
-
const out = [];
|
|
18141
|
-
for (const [key, entries] of Object.entries(parsed.plugins ?? {})) {
|
|
18142
|
-
if (!Array.isArray(entries) || entries.length === 0) continue;
|
|
18143
|
-
const entry = entries[0];
|
|
18144
|
-
if (!entry?.installPath) continue;
|
|
18145
|
-
if (entry.enabled === false) continue;
|
|
18146
|
-
const pluginName = key.includes("@") ? key.slice(0, key.indexOf("@")) : key;
|
|
18147
|
-
if (!pluginName) continue;
|
|
18148
|
-
out.push({ name: pluginName, root: entry.installPath });
|
|
18149
|
-
}
|
|
18150
|
-
return out;
|
|
18151
|
-
}
|
|
18152
|
-
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
18153
|
-
let cur = import_node_path9.default.resolve(startCwd);
|
|
18154
|
-
const fsRoot = import_node_path9.default.parse(cur).root;
|
|
18155
|
-
while (true) {
|
|
18156
|
-
scanAgentsDir(import_node_path9.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
18157
|
-
let hasGit = false;
|
|
18158
|
-
try {
|
|
18159
|
-
hasGit = import_node_fs10.default.existsSync(import_node_path9.default.join(cur, ".git"));
|
|
18160
|
-
} catch {
|
|
18161
|
-
}
|
|
18162
|
-
if (hasGit) return;
|
|
18163
|
-
if (cur === home) return;
|
|
18164
|
-
if (cur === fsRoot) return;
|
|
18165
|
-
const parent = import_node_path9.default.dirname(cur);
|
|
18166
|
-
if (parent === cur) return;
|
|
18167
|
-
cur = parent;
|
|
18168
|
-
}
|
|
18169
|
-
}
|
|
18170
|
-
var AgentsScanner = class {
|
|
18171
|
-
home;
|
|
18172
|
-
extraPluginRoots;
|
|
18173
|
-
policyDir;
|
|
18174
|
-
constructor(opts = {}) {
|
|
18175
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os6.default.homedir();
|
|
18176
|
-
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
18177
|
-
if (opts.policyDir !== void 0) {
|
|
18178
|
-
this.policyDir = opts.policyDir;
|
|
18179
|
-
} else if (process.platform === "darwin") {
|
|
18180
|
-
this.policyDir = DEFAULT_POLICY_DIR_DARWIN;
|
|
18181
|
-
} else {
|
|
18182
|
-
this.policyDir = null;
|
|
18183
|
-
}
|
|
18184
|
-
}
|
|
18185
|
-
list(args) {
|
|
18186
|
-
const seen = /* @__PURE__ */ new Set();
|
|
18187
|
-
const builtinBlock = [];
|
|
18188
|
-
for (const b of BUILTIN_AGENTS) {
|
|
18189
|
-
if (seen.has(b.name)) continue;
|
|
18190
|
-
seen.add(b.name);
|
|
18191
|
-
builtinBlock.push({
|
|
18192
|
-
name: b.name,
|
|
18193
|
-
source: "builtin",
|
|
18194
|
-
...b.description ? { description: b.description } : {},
|
|
18195
|
-
...b.whenToUse ? { whenToUse: b.whenToUse } : {}
|
|
18196
|
-
});
|
|
18197
|
-
}
|
|
18198
|
-
const fsBlock = [];
|
|
18199
|
-
scanAgentsDir(
|
|
18200
|
-
import_node_path9.default.join(this.home, ".claude", "agents"),
|
|
18201
|
-
"global",
|
|
18202
|
-
seen,
|
|
18203
|
-
fsBlock
|
|
18204
|
-
);
|
|
18205
|
-
walkUpProjectAgentsDirs(args.cwd, this.home, seen, fsBlock);
|
|
18206
|
-
if (this.policyDir) {
|
|
18207
|
-
scanAgentsDir(this.policyDir, "policy", seen, fsBlock);
|
|
18208
|
-
}
|
|
18209
|
-
const plugins = [
|
|
18210
|
-
...readInstalledPlugins2(this.home),
|
|
18211
|
-
...this.extraPluginRoots
|
|
18212
|
-
];
|
|
18213
|
-
for (const { name, root } of plugins) {
|
|
18214
|
-
const agentsRoot = import_node_path9.default.join(root, "agents");
|
|
18215
|
-
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
18216
|
-
}
|
|
18217
|
-
return [...builtinBlock, ...fsBlock];
|
|
18218
|
-
}
|
|
18219
|
-
};
|
|
18220
|
-
|
|
18221
|
-
// src/observer/session-observer.ts
|
|
18222
|
-
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
18223
|
-
var import_node_os7 = __toESM(require("os"), 1);
|
|
18224
17988
|
var import_node_path10 = __toESM(require("path"), 1);
|
|
18225
17989
|
init_claude_history();
|
|
18226
17990
|
var SessionObserver = class {
|
|
18227
17991
|
constructor(opts) {
|
|
18228
17992
|
this.opts = opts;
|
|
18229
|
-
this.home = opts.home ??
|
|
17993
|
+
this.home = opts.home ?? import_node_os6.default.homedir();
|
|
18230
17994
|
}
|
|
18231
17995
|
opts;
|
|
18232
17996
|
home;
|
|
@@ -18240,7 +18004,7 @@ var SessionObserver = class {
|
|
|
18240
18004
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
18241
18005
|
let size = 0;
|
|
18242
18006
|
try {
|
|
18243
|
-
size =
|
|
18007
|
+
size = import_node_fs10.default.statSync(filePath).size;
|
|
18244
18008
|
} catch {
|
|
18245
18009
|
}
|
|
18246
18010
|
const w = {
|
|
@@ -18253,10 +18017,10 @@ var SessionObserver = class {
|
|
|
18253
18017
|
adapter: args.adapter
|
|
18254
18018
|
};
|
|
18255
18019
|
try {
|
|
18256
|
-
|
|
18020
|
+
import_node_fs10.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
|
|
18257
18021
|
} catch {
|
|
18258
18022
|
}
|
|
18259
|
-
w.watcher =
|
|
18023
|
+
w.watcher = import_node_fs10.default.watch(import_node_path10.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
18260
18024
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
18261
18025
|
this.poll(w);
|
|
18262
18026
|
});
|
|
@@ -18271,7 +18035,7 @@ var SessionObserver = class {
|
|
|
18271
18035
|
// reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
|
|
18272
18036
|
hydrateMetaTail(w, maxLines = 200) {
|
|
18273
18037
|
try {
|
|
18274
|
-
const raw =
|
|
18038
|
+
const raw = import_node_fs10.default.readFileSync(w.filePath, "utf8");
|
|
18275
18039
|
if (!raw) return;
|
|
18276
18040
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
18277
18041
|
if (allLines.length === 0) return;
|
|
@@ -18292,7 +18056,7 @@ var SessionObserver = class {
|
|
|
18292
18056
|
poll(w) {
|
|
18293
18057
|
let size = 0;
|
|
18294
18058
|
try {
|
|
18295
|
-
size =
|
|
18059
|
+
size = import_node_fs10.default.statSync(w.filePath).size;
|
|
18296
18060
|
} catch {
|
|
18297
18061
|
return;
|
|
18298
18062
|
}
|
|
@@ -18301,11 +18065,11 @@ var SessionObserver = class {
|
|
|
18301
18065
|
w.buf = "";
|
|
18302
18066
|
}
|
|
18303
18067
|
if (size === w.lastSize) return;
|
|
18304
|
-
const fd =
|
|
18068
|
+
const fd = import_node_fs10.default.openSync(w.filePath, "r");
|
|
18305
18069
|
try {
|
|
18306
18070
|
const len = size - w.lastSize;
|
|
18307
18071
|
const buf = Buffer.alloc(len);
|
|
18308
|
-
|
|
18072
|
+
import_node_fs10.default.readSync(fd, buf, 0, len, w.lastSize);
|
|
18309
18073
|
w.lastSize = size;
|
|
18310
18074
|
w.buf += buf.toString("utf8");
|
|
18311
18075
|
let newlineIndex;
|
|
@@ -18319,7 +18083,7 @@ var SessionObserver = class {
|
|
|
18319
18083
|
this.maybeReportUserMessage(w.sessionId, line);
|
|
18320
18084
|
}
|
|
18321
18085
|
} finally {
|
|
18322
|
-
|
|
18086
|
+
import_node_fs10.default.closeSync(fd);
|
|
18323
18087
|
}
|
|
18324
18088
|
}
|
|
18325
18089
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -18971,7 +18735,7 @@ function isLocalhost(addr) {
|
|
|
18971
18735
|
}
|
|
18972
18736
|
|
|
18973
18737
|
// src/discovery/state-file.ts
|
|
18974
|
-
var
|
|
18738
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
18975
18739
|
var import_node_path11 = __toESM(require("path"), 1);
|
|
18976
18740
|
function defaultStateFilePath(dataDir) {
|
|
18977
18741
|
return import_node_path11.default.join(dataDir, "state.json");
|
|
@@ -18996,7 +18760,7 @@ var StateFileManager = class {
|
|
|
18996
18760
|
}
|
|
18997
18761
|
read() {
|
|
18998
18762
|
try {
|
|
18999
|
-
const raw =
|
|
18763
|
+
const raw = import_node_fs11.default.readFileSync(this.file, "utf8");
|
|
19000
18764
|
const parsed = JSON.parse(raw);
|
|
19001
18765
|
return parsed;
|
|
19002
18766
|
} catch {
|
|
@@ -19010,33 +18774,33 @@ var StateFileManager = class {
|
|
|
19010
18774
|
return { status: "stale", existing };
|
|
19011
18775
|
}
|
|
19012
18776
|
write(state) {
|
|
19013
|
-
|
|
18777
|
+
import_node_fs11.default.mkdirSync(import_node_path11.default.dirname(this.file), { recursive: true });
|
|
19014
18778
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
19015
|
-
|
|
19016
|
-
|
|
18779
|
+
import_node_fs11.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
18780
|
+
import_node_fs11.default.renameSync(tmp, this.file);
|
|
19017
18781
|
if (process.platform !== "win32") {
|
|
19018
18782
|
try {
|
|
19019
|
-
|
|
18783
|
+
import_node_fs11.default.chmodSync(this.file, 384);
|
|
19020
18784
|
} catch {
|
|
19021
18785
|
}
|
|
19022
18786
|
}
|
|
19023
18787
|
}
|
|
19024
18788
|
delete() {
|
|
19025
18789
|
try {
|
|
19026
|
-
|
|
18790
|
+
import_node_fs11.default.unlinkSync(this.file);
|
|
19027
18791
|
} catch {
|
|
19028
18792
|
}
|
|
19029
18793
|
}
|
|
19030
18794
|
};
|
|
19031
18795
|
|
|
19032
18796
|
// src/tunnel/tunnel-manager.ts
|
|
19033
|
-
var
|
|
18797
|
+
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
19034
18798
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
19035
18799
|
var import_node_crypto4 = __toESM(require("crypto"), 1);
|
|
19036
18800
|
var import_node_child_process4 = require("child_process");
|
|
19037
18801
|
|
|
19038
18802
|
// src/tunnel/tunnel-store.ts
|
|
19039
|
-
var
|
|
18803
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
19040
18804
|
var import_node_path12 = __toESM(require("path"), 1);
|
|
19041
18805
|
var TunnelStore = class {
|
|
19042
18806
|
constructor(filePath) {
|
|
@@ -19045,7 +18809,7 @@ var TunnelStore = class {
|
|
|
19045
18809
|
filePath;
|
|
19046
18810
|
async get() {
|
|
19047
18811
|
try {
|
|
19048
|
-
const raw = await
|
|
18812
|
+
const raw = await import_node_fs12.default.promises.readFile(this.filePath, "utf8");
|
|
19049
18813
|
const obj = JSON.parse(raw);
|
|
19050
18814
|
if (!isPersistedTunnel(obj)) return null;
|
|
19051
18815
|
return obj;
|
|
@@ -19057,21 +18821,21 @@ var TunnelStore = class {
|
|
|
19057
18821
|
}
|
|
19058
18822
|
async set(v) {
|
|
19059
18823
|
const dir = import_node_path12.default.dirname(this.filePath);
|
|
19060
|
-
await
|
|
18824
|
+
await import_node_fs12.default.promises.mkdir(dir, { recursive: true });
|
|
19061
18825
|
const data = JSON.stringify(v, null, 2);
|
|
19062
18826
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
19063
|
-
await
|
|
18827
|
+
await import_node_fs12.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
19064
18828
|
if (process.platform !== "win32") {
|
|
19065
18829
|
try {
|
|
19066
|
-
await
|
|
18830
|
+
await import_node_fs12.default.promises.chmod(tmp, 384);
|
|
19067
18831
|
} catch {
|
|
19068
18832
|
}
|
|
19069
18833
|
}
|
|
19070
|
-
await
|
|
18834
|
+
await import_node_fs12.default.promises.rename(tmp, this.filePath);
|
|
19071
18835
|
}
|
|
19072
18836
|
async clear() {
|
|
19073
18837
|
try {
|
|
19074
|
-
await
|
|
18838
|
+
await import_node_fs12.default.promises.unlink(this.filePath);
|
|
19075
18839
|
} catch (err) {
|
|
19076
18840
|
const code = err?.code;
|
|
19077
18841
|
if (code !== "ENOENT") throw err;
|
|
@@ -19166,8 +18930,8 @@ function escape(v) {
|
|
|
19166
18930
|
}
|
|
19167
18931
|
|
|
19168
18932
|
// src/tunnel/frpc-binary.ts
|
|
19169
|
-
var
|
|
19170
|
-
var
|
|
18933
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
18934
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
19171
18935
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
19172
18936
|
var import_node_child_process3 = require("child_process");
|
|
19173
18937
|
var import_node_stream = require("stream");
|
|
@@ -19200,7 +18964,7 @@ function frpcDownloadUrl(version2, p) {
|
|
|
19200
18964
|
}
|
|
19201
18965
|
async function ensureFrpcBinary(opts) {
|
|
19202
18966
|
if (opts.override) {
|
|
19203
|
-
if (!
|
|
18967
|
+
if (!import_node_fs13.default.existsSync(opts.override)) {
|
|
19204
18968
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
19205
18969
|
}
|
|
19206
18970
|
return opts.override;
|
|
@@ -19208,10 +18972,10 @@ async function ensureFrpcBinary(opts) {
|
|
|
19208
18972
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
19209
18973
|
const platform = opts.platform ?? detectPlatform();
|
|
19210
18974
|
const binDir = import_node_path13.default.join(opts.dataDir, "bin");
|
|
19211
|
-
|
|
18975
|
+
import_node_fs13.default.mkdirSync(binDir, { recursive: true });
|
|
19212
18976
|
cleanupStaleArtifacts(binDir);
|
|
19213
18977
|
const stableBin = import_node_path13.default.join(binDir, "frpc");
|
|
19214
|
-
if (
|
|
18978
|
+
if (import_node_fs13.default.existsSync(stableBin)) return stableBin;
|
|
19215
18979
|
const partialBin = `${stableBin}.partial`;
|
|
19216
18980
|
const tarballPath = import_node_path13.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
19217
18981
|
try {
|
|
@@ -19222,8 +18986,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
19222
18986
|
} else {
|
|
19223
18987
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
19224
18988
|
}
|
|
19225
|
-
|
|
19226
|
-
|
|
18989
|
+
import_node_fs13.default.chmodSync(partialBin, 493);
|
|
18990
|
+
import_node_fs13.default.renameSync(partialBin, stableBin);
|
|
19227
18991
|
} finally {
|
|
19228
18992
|
safeUnlink(tarballPath);
|
|
19229
18993
|
safeUnlink(partialBin);
|
|
@@ -19233,7 +18997,7 @@ async function ensureFrpcBinary(opts) {
|
|
|
19233
18997
|
function cleanupStaleArtifacts(binDir) {
|
|
19234
18998
|
let entries;
|
|
19235
18999
|
try {
|
|
19236
|
-
entries =
|
|
19000
|
+
entries = import_node_fs13.default.readdirSync(binDir);
|
|
19237
19001
|
} catch {
|
|
19238
19002
|
return;
|
|
19239
19003
|
}
|
|
@@ -19241,7 +19005,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
19241
19005
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
19242
19006
|
const full = import_node_path13.default.join(binDir, name);
|
|
19243
19007
|
try {
|
|
19244
|
-
|
|
19008
|
+
import_node_fs13.default.rmSync(full, { recursive: true, force: true });
|
|
19245
19009
|
} catch {
|
|
19246
19010
|
}
|
|
19247
19011
|
}
|
|
@@ -19249,7 +19013,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
19249
19013
|
}
|
|
19250
19014
|
function safeUnlink(p) {
|
|
19251
19015
|
try {
|
|
19252
|
-
|
|
19016
|
+
import_node_fs13.default.unlinkSync(p);
|
|
19253
19017
|
} catch {
|
|
19254
19018
|
}
|
|
19255
19019
|
}
|
|
@@ -19260,13 +19024,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
19260
19024
|
if (!res.ok || !res.body) {
|
|
19261
19025
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
19262
19026
|
}
|
|
19263
|
-
const out =
|
|
19027
|
+
const out = import_node_fs13.default.createWriteStream(dest);
|
|
19264
19028
|
const nodeStream = import_node_stream.Readable.fromWeb(res.body);
|
|
19265
19029
|
await (0, import_promises.pipeline)(nodeStream, out);
|
|
19266
19030
|
}
|
|
19267
19031
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
19268
19032
|
const work = import_node_path13.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
19269
|
-
|
|
19033
|
+
import_node_fs13.default.mkdirSync(work, { recursive: true });
|
|
19270
19034
|
try {
|
|
19271
19035
|
await new Promise((resolve, reject) => {
|
|
19272
19036
|
const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -19275,12 +19039,12 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
19275
19039
|
});
|
|
19276
19040
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
19277
19041
|
const src = import_node_path13.default.join(work, dirName, "frpc");
|
|
19278
|
-
if (!
|
|
19042
|
+
if (!import_node_fs13.default.existsSync(src)) {
|
|
19279
19043
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
19280
19044
|
}
|
|
19281
|
-
|
|
19045
|
+
import_node_fs13.default.copyFileSync(src, destBin);
|
|
19282
19046
|
} finally {
|
|
19283
|
-
|
|
19047
|
+
import_node_fs13.default.rmSync(work, { recursive: true, force: true });
|
|
19284
19048
|
}
|
|
19285
19049
|
}
|
|
19286
19050
|
|
|
@@ -19417,12 +19181,12 @@ var TunnelManager = class {
|
|
|
19417
19181
|
localPort,
|
|
19418
19182
|
logLevel: "info"
|
|
19419
19183
|
});
|
|
19420
|
-
await
|
|
19184
|
+
await import_node_fs14.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
19421
19185
|
const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
|
|
19422
19186
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19423
19187
|
});
|
|
19424
19188
|
const logFilePath = import_node_path14.default.join(this.deps.dataDir, "frpc.log");
|
|
19425
|
-
const logStream =
|
|
19189
|
+
const logStream = import_node_fs14.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
19426
19190
|
logStream.on("error", () => {
|
|
19427
19191
|
});
|
|
19428
19192
|
const tee = (chunk) => {
|
|
@@ -19503,18 +19267,18 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
19503
19267
|
}
|
|
19504
19268
|
|
|
19505
19269
|
// src/tunnel/device-key.ts
|
|
19506
|
-
var
|
|
19270
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
19507
19271
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
19508
19272
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
19509
19273
|
function deriveStableDeviceKey(opts = {}) {
|
|
19510
|
-
const hostname = opts.hostname ??
|
|
19511
|
-
const uid = opts.uid ?? (typeof
|
|
19274
|
+
const hostname = opts.hostname ?? import_node_os8.default.hostname();
|
|
19275
|
+
const uid = opts.uid ?? (typeof import_node_os8.default.userInfo === "function" ? import_node_os8.default.userInfo().uid : 0);
|
|
19512
19276
|
const input = `${hostname}::${uid}`;
|
|
19513
19277
|
return import_node_crypto5.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
19514
19278
|
}
|
|
19515
19279
|
|
|
19516
19280
|
// src/auth-store.ts
|
|
19517
|
-
var
|
|
19281
|
+
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
19518
19282
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
19519
19283
|
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
19520
19284
|
var AUTH_FILE_NAME = "auth.json";
|
|
@@ -19535,7 +19299,7 @@ function defaultGenerate() {
|
|
|
19535
19299
|
}
|
|
19536
19300
|
function readAuthFile(file) {
|
|
19537
19301
|
try {
|
|
19538
|
-
const raw =
|
|
19302
|
+
const raw = import_node_fs15.default.readFileSync(file, "utf8");
|
|
19539
19303
|
const parsed = JSON.parse(raw);
|
|
19540
19304
|
if (typeof parsed?.token === "string" && parsed.token.length > 0) {
|
|
19541
19305
|
return {
|
|
@@ -19551,10 +19315,10 @@ function readAuthFile(file) {
|
|
|
19551
19315
|
}
|
|
19552
19316
|
}
|
|
19553
19317
|
function writeAuthFile(file, content) {
|
|
19554
|
-
|
|
19555
|
-
|
|
19318
|
+
import_node_fs15.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true });
|
|
19319
|
+
import_node_fs15.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
19556
19320
|
try {
|
|
19557
|
-
|
|
19321
|
+
import_node_fs15.default.chmodSync(file, 384);
|
|
19558
19322
|
} catch {
|
|
19559
19323
|
}
|
|
19560
19324
|
}
|
|
@@ -19566,12 +19330,12 @@ init_protocol();
|
|
|
19566
19330
|
init_protocol();
|
|
19567
19331
|
|
|
19568
19332
|
// src/session/fork.ts
|
|
19569
|
-
var
|
|
19570
|
-
var
|
|
19333
|
+
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
19334
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
19571
19335
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
19572
19336
|
init_claude_history();
|
|
19573
19337
|
function readJsonlEntries(file) {
|
|
19574
|
-
const raw =
|
|
19338
|
+
const raw = import_node_fs16.default.readFileSync(file, "utf8");
|
|
19575
19339
|
const out = [];
|
|
19576
19340
|
for (const line of raw.split("\n")) {
|
|
19577
19341
|
const t = line.trim();
|
|
@@ -19584,10 +19348,10 @@ function readJsonlEntries(file) {
|
|
|
19584
19348
|
return out;
|
|
19585
19349
|
}
|
|
19586
19350
|
function forkSession(input) {
|
|
19587
|
-
const baseDir = input.baseDir ?? import_node_path16.default.join(
|
|
19351
|
+
const baseDir = input.baseDir ?? import_node_path16.default.join(import_node_os9.default.homedir(), ".claude");
|
|
19588
19352
|
const projectDir = import_node_path16.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
19589
19353
|
const sourceFile = import_node_path16.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
19590
|
-
if (!
|
|
19354
|
+
if (!import_node_fs16.default.existsSync(sourceFile)) {
|
|
19591
19355
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
19592
19356
|
}
|
|
19593
19357
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -19618,8 +19382,8 @@ function forkSession(input) {
|
|
|
19618
19382
|
forkedLines.push(JSON.stringify(forked));
|
|
19619
19383
|
}
|
|
19620
19384
|
const forkedFilePath = import_node_path16.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
19621
|
-
|
|
19622
|
-
|
|
19385
|
+
import_node_fs16.default.mkdirSync(projectDir, { recursive: true });
|
|
19386
|
+
import_node_fs16.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
19623
19387
|
return { forkedToolSessionId, forkedFilePath };
|
|
19624
19388
|
}
|
|
19625
19389
|
|
|
@@ -19628,6 +19392,12 @@ function buildSessionHandlers(deps) {
|
|
|
19628
19392
|
const { manager, observer, getAdapter: getAdapter2 } = deps;
|
|
19629
19393
|
const create = async (frame) => {
|
|
19630
19394
|
const args = SessionCreateArgs.parse(frame);
|
|
19395
|
+
if (args.ownerPersonaId) {
|
|
19396
|
+
const persona = deps.personaRegistry.get(args.ownerPersonaId);
|
|
19397
|
+
if (!persona) {
|
|
19398
|
+
throw new Error(`persona not found: ${args.ownerPersonaId}`);
|
|
19399
|
+
}
|
|
19400
|
+
}
|
|
19631
19401
|
const { response, broadcast } = manager.create(args);
|
|
19632
19402
|
return { response: { type: "session:info", ...response }, broadcast };
|
|
19633
19403
|
};
|
|
@@ -19861,7 +19631,7 @@ function buildHistoryHandlers(deps) {
|
|
|
19861
19631
|
// src/handlers/workspace.ts
|
|
19862
19632
|
init_protocol();
|
|
19863
19633
|
function buildWorkspaceHandlers(deps) {
|
|
19864
|
-
const { workspace, skills
|
|
19634
|
+
const { workspace, skills } = deps;
|
|
19865
19635
|
const list = async (frame) => {
|
|
19866
19636
|
const args = WorkspaceListArgs.parse(frame);
|
|
19867
19637
|
const res = workspace.list(args);
|
|
@@ -19877,16 +19647,10 @@ function buildWorkspaceHandlers(deps) {
|
|
|
19877
19647
|
const list2 = skills.list(args);
|
|
19878
19648
|
return { response: { type: "skills:list", skills: list2 } };
|
|
19879
19649
|
};
|
|
19880
|
-
const agentsList = async (frame) => {
|
|
19881
|
-
const args = AgentsListArgs.parse(frame);
|
|
19882
|
-
const list2 = agents.list(args);
|
|
19883
|
-
return { response: { type: "agents:list", agents: list2 } };
|
|
19884
|
-
};
|
|
19885
19650
|
return {
|
|
19886
19651
|
"workspace:list": list,
|
|
19887
19652
|
"workspace:read": read,
|
|
19888
|
-
"skills:list": skillsList
|
|
19889
|
-
"agents:list": agentsList
|
|
19653
|
+
"skills:list": skillsList
|
|
19890
19654
|
};
|
|
19891
19655
|
}
|
|
19892
19656
|
|
|
@@ -19895,8 +19659,8 @@ init_protocol();
|
|
|
19895
19659
|
|
|
19896
19660
|
// src/workspace/git.ts
|
|
19897
19661
|
var import_node_child_process5 = require("child_process");
|
|
19898
|
-
var
|
|
19899
|
-
var
|
|
19662
|
+
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
19663
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
19900
19664
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
19901
19665
|
var import_node_util = require("util");
|
|
19902
19666
|
var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
|
|
@@ -19914,7 +19678,7 @@ function formatChildProcessError(err) {
|
|
|
19914
19678
|
function normalizePath(p) {
|
|
19915
19679
|
const resolved = import_node_path17.default.resolve(p);
|
|
19916
19680
|
try {
|
|
19917
|
-
return
|
|
19681
|
+
return import_node_fs17.default.realpathSync(resolved);
|
|
19918
19682
|
} catch {
|
|
19919
19683
|
return resolved;
|
|
19920
19684
|
}
|
|
@@ -20001,7 +19765,7 @@ function sanitizeLabel(raw) {
|
|
|
20001
19765
|
function computePrefix() {
|
|
20002
19766
|
let username;
|
|
20003
19767
|
try {
|
|
20004
|
-
username =
|
|
19768
|
+
username = import_node_os10.default.userInfo().username;
|
|
20005
19769
|
} catch {
|
|
20006
19770
|
username = void 0;
|
|
20007
19771
|
}
|
|
@@ -20017,10 +19781,10 @@ function encodeClaudeProjectDir(absPath) {
|
|
|
20017
19781
|
if (!absPath || typeof absPath !== "string") return "";
|
|
20018
19782
|
let canonical = import_node_path17.default.resolve(absPath);
|
|
20019
19783
|
try {
|
|
20020
|
-
canonical =
|
|
19784
|
+
canonical = import_node_fs17.default.realpathSync(canonical);
|
|
20021
19785
|
} catch {
|
|
20022
19786
|
try {
|
|
20023
|
-
const parent =
|
|
19787
|
+
const parent = import_node_fs17.default.realpathSync(import_node_path17.default.dirname(canonical));
|
|
20024
19788
|
canonical = import_node_path17.default.join(parent, import_node_path17.default.basename(canonical));
|
|
20025
19789
|
} catch {
|
|
20026
19790
|
}
|
|
@@ -20051,11 +19815,13 @@ async function createWorktree(input) {
|
|
|
20051
19815
|
}
|
|
20052
19816
|
const worktreeRoot = import_node_path17.default.join(parent, dirName);
|
|
20053
19817
|
try {
|
|
20054
|
-
await pexec("git", ["-C", cwd, "
|
|
20055
|
-
timeout:
|
|
19818
|
+
await pexec("git", ["-C", cwd, "fetch", "origin", baseBranch, "--no-tags"], {
|
|
19819
|
+
timeout: 3e4
|
|
20056
19820
|
});
|
|
20057
|
-
} catch {
|
|
20058
|
-
throw new Error(
|
|
19821
|
+
} catch (err) {
|
|
19822
|
+
throw new Error(
|
|
19823
|
+
`\u57FA\u51C6\u5206\u652F ${baseBranch} \u4E0D\u5B58\u5728\u6216 fetch \u8FDC\u7AEF\u5931\u8D25\uFF1A${formatChildProcessError(err)}`
|
|
19824
|
+
);
|
|
20059
19825
|
}
|
|
20060
19826
|
try {
|
|
20061
19827
|
await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${branch}`], {
|
|
@@ -20066,13 +19832,13 @@ async function createWorktree(input) {
|
|
|
20066
19832
|
const msg = err.message;
|
|
20067
19833
|
if (msg.startsWith("\u5206\u652F ")) throw err;
|
|
20068
19834
|
}
|
|
20069
|
-
if (
|
|
19835
|
+
if (import_node_fs17.default.existsSync(worktreeRoot)) {
|
|
20070
19836
|
throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
|
|
20071
19837
|
}
|
|
20072
19838
|
try {
|
|
20073
19839
|
await pexec(
|
|
20074
19840
|
"git",
|
|
20075
|
-
["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, baseBranch],
|
|
19841
|
+
["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, `origin/${baseBranch}`],
|
|
20076
19842
|
{ timeout: 15e3 }
|
|
20077
19843
|
);
|
|
20078
19844
|
} catch (err) {
|
|
@@ -20107,7 +19873,7 @@ async function removeWorktree(input) {
|
|
|
20107
19873
|
} catch (err) {
|
|
20108
19874
|
const stderr = err.stderr ?? "";
|
|
20109
19875
|
const lower = stderr.toLowerCase();
|
|
20110
|
-
const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !
|
|
19876
|
+
const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs17.default.existsSync(worktreeRoot);
|
|
20111
19877
|
if (!vanished) {
|
|
20112
19878
|
throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
|
|
20113
19879
|
}
|
|
@@ -20126,10 +19892,10 @@ async function removeWorktree(input) {
|
|
|
20126
19892
|
try {
|
|
20127
19893
|
const encoded = encodeClaudeProjectDir(worktreeRoot);
|
|
20128
19894
|
if (encoded) {
|
|
20129
|
-
const projectsRoot = import_node_path17.default.join(
|
|
19895
|
+
const projectsRoot = import_node_path17.default.join(import_node_os10.default.homedir(), ".claude", "projects");
|
|
20130
19896
|
const target = import_node_path17.default.resolve(projectsRoot, encoded);
|
|
20131
19897
|
if (target.startsWith(projectsRoot + import_node_path17.default.sep) && target !== projectsRoot) {
|
|
20132
|
-
|
|
19898
|
+
import_node_fs17.default.rmSync(target, { recursive: true, force: true });
|
|
20133
19899
|
}
|
|
20134
19900
|
}
|
|
20135
19901
|
} catch {
|
|
@@ -20201,7 +19967,7 @@ function buildCapabilitiesHandlers(deps) {
|
|
|
20201
19967
|
}
|
|
20202
19968
|
|
|
20203
19969
|
// src/handlers/meta.ts
|
|
20204
|
-
var
|
|
19970
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
20205
19971
|
init_protocol();
|
|
20206
19972
|
|
|
20207
19973
|
// src/version.ts
|
|
@@ -20223,7 +19989,7 @@ function buildReadyFrame(deps) {
|
|
|
20223
19989
|
return {
|
|
20224
19990
|
version,
|
|
20225
19991
|
protocolVersion: PROTOCOL_VERSION,
|
|
20226
|
-
hostname:
|
|
19992
|
+
hostname: import_node_os11.default.hostname(),
|
|
20227
19993
|
os: process.platform,
|
|
20228
19994
|
tools,
|
|
20229
19995
|
runningSessions: info.runningSessions,
|
|
@@ -20374,7 +20140,6 @@ async function startDaemon(config) {
|
|
|
20374
20140
|
const store = new SessionStore({ dataDir: config.dataDir });
|
|
20375
20141
|
const workspace = new WorkspaceBrowser();
|
|
20376
20142
|
const skills = new SkillsScanner();
|
|
20377
|
-
const agents = new AgentsScanner();
|
|
20378
20143
|
const history = new ClaudeHistoryReader();
|
|
20379
20144
|
let transport = null;
|
|
20380
20145
|
const manager = new SessionManager({
|
|
@@ -20435,7 +20200,6 @@ async function startDaemon(config) {
|
|
|
20435
20200
|
manager,
|
|
20436
20201
|
workspace,
|
|
20437
20202
|
skills,
|
|
20438
|
-
agents,
|
|
20439
20203
|
history,
|
|
20440
20204
|
observer,
|
|
20441
20205
|
getAdapter,
|
|
@@ -20571,7 +20335,7 @@ ${bar}
|
|
|
20571
20335
|
`);
|
|
20572
20336
|
try {
|
|
20573
20337
|
const connectPath = import_node_path18.default.join(config.dataDir, "connect.txt");
|
|
20574
|
-
|
|
20338
|
+
import_node_fs18.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
20575
20339
|
} catch {
|
|
20576
20340
|
}
|
|
20577
20341
|
} catch (err) {
|