@clawos-dev/clawd 0.2.33 → 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 +282 -529
- 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
|
}
|
|
@@ -15686,7 +15687,7 @@ function applyMetaUpdate(state, patch, deps) {
|
|
|
15686
15687
|
if (shallowEqMeta(next.file, merged)) {
|
|
15687
15688
|
return { state: next, effects: [] };
|
|
15688
15689
|
}
|
|
15689
|
-
next.file = merged;
|
|
15690
|
+
next.file = { ...merged, updatedAt: nowIso(deps) };
|
|
15690
15691
|
return {
|
|
15691
15692
|
state: next,
|
|
15692
15693
|
effects: [
|
|
@@ -15788,7 +15789,6 @@ function pushEventToBuffer(state, event, deps) {
|
|
|
15788
15789
|
next.nextSeq = seq + 1;
|
|
15789
15790
|
if (newBuffer.length === 1) next.bufferStartSeq = seq;
|
|
15790
15791
|
const isTurnEnd = withSeq.kind === "turn_end";
|
|
15791
|
-
const isUserText = withSeq.kind === "user_text";
|
|
15792
15792
|
if (isTurnEnd) next.turnOpen = false;
|
|
15793
15793
|
else if (!next.turnOpen) next.turnOpen = true;
|
|
15794
15794
|
if (!next.turnOpen && next.buffer.length > deps.bufferCap) {
|
|
@@ -15799,11 +15799,6 @@ function pushEventToBuffer(state, event, deps) {
|
|
|
15799
15799
|
}
|
|
15800
15800
|
if (next.freshSpawn) next.freshSpawn = false;
|
|
15801
15801
|
const effects = [emitSessionEvent(next.file.sessionId, withSeq)];
|
|
15802
|
-
if (isUserText || isTurnEnd) {
|
|
15803
|
-
next.file = { ...next.file, updatedAt: nowIso(deps) };
|
|
15804
|
-
effects.push({ kind: "persist-file", file: next.file });
|
|
15805
|
-
effects.push(sessionInfoFrame(next.file));
|
|
15806
|
-
}
|
|
15807
15802
|
if (isTurnEnd && next.subSessionMeta?.idleKillEnabled && next.procAlive && (next.status === "running" || next.status === "spawning")) {
|
|
15808
15803
|
next.status = "running-idle";
|
|
15809
15804
|
effects.push({
|
|
@@ -15820,14 +15815,6 @@ var RUNTIME_PATCH_KEYS = [
|
|
|
15820
15815
|
"effort",
|
|
15821
15816
|
"cwd"
|
|
15822
15817
|
];
|
|
15823
|
-
var MARKER_PATCH_KEYS = ["pinnedAt", "pinSortOrder"];
|
|
15824
|
-
function isMarkerOnlyPatch(patch) {
|
|
15825
|
-
const keys = Object.keys(patch).filter(
|
|
15826
|
-
(k) => patch[k] !== void 0
|
|
15827
|
-
);
|
|
15828
|
-
if (keys.length === 0) return false;
|
|
15829
|
-
return keys.every((k) => MARKER_PATCH_KEYS.includes(k));
|
|
15830
|
-
}
|
|
15831
15818
|
function applyCommand(state, command, deps) {
|
|
15832
15819
|
const next = cloneState(state);
|
|
15833
15820
|
const effects = [];
|
|
@@ -15934,8 +15921,7 @@ function applyCommand(state, command, deps) {
|
|
|
15934
15921
|
const runtimePatch = RUNTIME_PATCH_KEYS.some(
|
|
15935
15922
|
(k) => patch[k] !== void 0
|
|
15936
15923
|
);
|
|
15937
|
-
|
|
15938
|
-
next.file = markerOnly ? { ...next.file, ...patch } : { ...next.file, ...patch, updatedAt: nowIso(deps) };
|
|
15924
|
+
next.file = { ...next.file, ...patch, updatedAt: nowIso(deps) };
|
|
15939
15925
|
effects.push({ kind: "persist-file", file: next.file });
|
|
15940
15926
|
effects.push(sessionInfoFrame(next.file));
|
|
15941
15927
|
if (runtimePatch && next.procAlive) {
|
|
@@ -16657,10 +16643,22 @@ var SessionManager = class {
|
|
|
16657
16643
|
this.capabilitiesCache.set(tool, caps);
|
|
16658
16644
|
return caps;
|
|
16659
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
|
+
}
|
|
16660
16657
|
// 创建 runner 时包一层 broadcast hook:所有外出 frame 统一走 routeFromRunner,
|
|
16661
16658
|
// 经过 compressFrameForWire 后决定是 push collector 还是走 deps.broadcastFrame
|
|
16662
16659
|
// store:默认 deps.store;persona sub-session 路径下传该 personaId 对应的 SessionStore
|
|
16663
|
-
// subSessionMeta:
|
|
16660
|
+
// subSessionMeta:listener 传 { idleKillEnabled: true, personaMode: 'listener' };
|
|
16661
|
+
// owner 传 { idleKillEnabled: false, personaMode: 'owner' };普通 session 不传
|
|
16664
16662
|
newRunner(file, opts = {}) {
|
|
16665
16663
|
const adapter = this.deps.getAdapter(file.tool ?? "claude");
|
|
16666
16664
|
const store = opts.store ?? this.deps.store;
|
|
@@ -16718,18 +16716,34 @@ var SessionManager = class {
|
|
|
16718
16716
|
}
|
|
16719
16717
|
// ---- 命令方法:均返回 { response, broadcast[] },由 dispatcher 聚合 ----
|
|
16720
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
|
+
}
|
|
16721
16735
|
try {
|
|
16722
|
-
const stat = import_node_fs5.default.statSync(
|
|
16736
|
+
const stat = import_node_fs5.default.statSync(cwd);
|
|
16723
16737
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
16724
16738
|
} catch {
|
|
16725
|
-
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${
|
|
16739
|
+
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
|
|
16726
16740
|
}
|
|
16727
16741
|
const tool = args.tool ?? "claude";
|
|
16728
16742
|
this.deps.getAdapter(tool);
|
|
16729
16743
|
const iso = nowIso2(this.deps);
|
|
16730
16744
|
const file = {
|
|
16731
16745
|
sessionId: newSessionId(),
|
|
16732
|
-
cwd
|
|
16746
|
+
cwd,
|
|
16733
16747
|
tool,
|
|
16734
16748
|
label: args.label,
|
|
16735
16749
|
model: args.model,
|
|
@@ -16739,10 +16753,17 @@ var SessionManager = class {
|
|
|
16739
16753
|
worktreeRoot: args.worktreeRoot,
|
|
16740
16754
|
worktreeBranch: args.worktreeBranch,
|
|
16741
16755
|
forkedFromToolSessionId: args.forkedFromToolSessionId,
|
|
16756
|
+
ownerPersonaId: args.ownerPersonaId,
|
|
16742
16757
|
createdAt: iso,
|
|
16743
16758
|
updatedAt: iso
|
|
16744
16759
|
};
|
|
16745
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
|
+
}
|
|
16746
16767
|
return { response: written, broadcast: [] };
|
|
16747
16768
|
}
|
|
16748
16769
|
pin(args) {
|
|
@@ -16756,7 +16777,7 @@ var SessionManager = class {
|
|
|
16756
16777
|
});
|
|
16757
16778
|
return { response: value, broadcast };
|
|
16758
16779
|
}
|
|
16759
|
-
const updated = { ...existing, pinnedAt };
|
|
16780
|
+
const updated = { ...existing, pinnedAt, updatedAt: nowIso2(this.deps) };
|
|
16760
16781
|
this.deps.store.write(updated);
|
|
16761
16782
|
return { response: updated, broadcast: [] };
|
|
16762
16783
|
}
|
|
@@ -16792,7 +16813,11 @@ var SessionManager = class {
|
|
|
16792
16813
|
broadcast.push(...b);
|
|
16793
16814
|
} else {
|
|
16794
16815
|
const existing = this.getFile(sessionId);
|
|
16795
|
-
const updated = {
|
|
16816
|
+
const updated = {
|
|
16817
|
+
...existing,
|
|
16818
|
+
pinSortOrder: index,
|
|
16819
|
+
updatedAt: nowIso2(this.deps)
|
|
16820
|
+
};
|
|
16796
16821
|
this.deps.store.write(updated);
|
|
16797
16822
|
updatedFiles.push(updated);
|
|
16798
16823
|
}
|
|
@@ -16898,7 +16923,8 @@ var SessionManager = class {
|
|
|
16898
16923
|
const existing = this.getFile(args.sessionId);
|
|
16899
16924
|
let runner = this.runners.get(args.sessionId);
|
|
16900
16925
|
if (!runner) {
|
|
16901
|
-
|
|
16926
|
+
const subSessionMeta = this.resolveSubSessionMeta(existing);
|
|
16927
|
+
runner = this.newRunner(existing, { subSessionMeta });
|
|
16902
16928
|
this.runners.set(args.sessionId, runner);
|
|
16903
16929
|
}
|
|
16904
16930
|
const { broadcast } = this.withCollector(() => {
|
|
@@ -16992,7 +17018,8 @@ var SessionManager = class {
|
|
|
16992
17018
|
const file = this.getFile(args.sessionId);
|
|
16993
17019
|
let runner = this.runners.get(args.sessionId);
|
|
16994
17020
|
if (!runner) {
|
|
16995
|
-
|
|
17021
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17022
|
+
runner = this.newRunner(file, { subSessionMeta });
|
|
16996
17023
|
this.runners.set(args.sessionId, runner);
|
|
16997
17024
|
}
|
|
16998
17025
|
if (!runner.getState().procAlive) {
|
|
@@ -17150,7 +17177,7 @@ var SessionManager = class {
|
|
|
17150
17177
|
ensureSession(file) {
|
|
17151
17178
|
let r = this.runners.get(file.sessionId);
|
|
17152
17179
|
if (r) return r;
|
|
17153
|
-
const subSessionMeta = this.
|
|
17180
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17154
17181
|
r = this.newRunner(file, { subSessionMeta });
|
|
17155
17182
|
this.runners.set(file.sessionId, r);
|
|
17156
17183
|
return r;
|
|
@@ -17326,7 +17353,7 @@ var SessionManager = class {
|
|
|
17326
17353
|
const existing = this.runners.get(file.sessionId);
|
|
17327
17354
|
if (existing) return existing;
|
|
17328
17355
|
const store = this.storeFor(agentId);
|
|
17329
|
-
const subSessionMeta = this.
|
|
17356
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17330
17357
|
const runner = this.newRunner(file, { store, subSessionMeta });
|
|
17331
17358
|
this.runners.set(file.sessionId, runner);
|
|
17332
17359
|
return runner;
|
|
@@ -17348,7 +17375,7 @@ var SessionManager = class {
|
|
|
17348
17375
|
}
|
|
17349
17376
|
let runner = this.runners.get(args.sessionId);
|
|
17350
17377
|
if (!runner) {
|
|
17351
|
-
const subSessionMeta = this.
|
|
17378
|
+
const subSessionMeta = this.resolveSubSessionMeta(file);
|
|
17352
17379
|
runner = this.newRunner(file, { store, subSessionMeta });
|
|
17353
17380
|
this.runners.set(args.sessionId, runner);
|
|
17354
17381
|
}
|
|
@@ -17420,7 +17447,7 @@ var SessionManager = class {
|
|
|
17420
17447
|
|
|
17421
17448
|
// src/persona/store.ts
|
|
17422
17449
|
var fs6 = __toESM(require("fs"), 1);
|
|
17423
|
-
var
|
|
17450
|
+
var path6 = __toESM(require("path"), 1);
|
|
17424
17451
|
init_protocol();
|
|
17425
17452
|
var DEFAULT_SETTINGS = {
|
|
17426
17453
|
permissions: {
|
|
@@ -17449,21 +17476,21 @@ var PersonaStore = class {
|
|
|
17449
17476
|
}
|
|
17450
17477
|
root;
|
|
17451
17478
|
personaDir(personaId) {
|
|
17452
|
-
return
|
|
17479
|
+
return path6.join(this.root, safeFileName(personaId));
|
|
17453
17480
|
}
|
|
17454
17481
|
metaPath(personaId) {
|
|
17455
|
-
return
|
|
17482
|
+
return path6.join(this.personaDir(personaId), ".clawd", "persona.json");
|
|
17456
17483
|
}
|
|
17457
17484
|
claudeMdPath(personaId) {
|
|
17458
|
-
return
|
|
17485
|
+
return path6.join(this.personaDir(personaId), "CLAUDE.md");
|
|
17459
17486
|
}
|
|
17460
17487
|
settingsPath(personaId) {
|
|
17461
|
-
return
|
|
17488
|
+
return path6.join(this.personaDir(personaId), ".claude", "settings.json");
|
|
17462
17489
|
}
|
|
17463
17490
|
write(persona, personality) {
|
|
17464
17491
|
const dir = this.personaDir(persona.personaId);
|
|
17465
|
-
fs6.mkdirSync(
|
|
17466
|
-
fs6.mkdirSync(
|
|
17492
|
+
fs6.mkdirSync(path6.join(dir, ".claude"), { recursive: true });
|
|
17493
|
+
fs6.mkdirSync(path6.join(dir, ".clawd"), { recursive: true });
|
|
17467
17494
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
17468
17495
|
this.atomicWrite(this.settingsPath(persona.personaId), JSON.stringify(DEFAULT_SETTINGS, null, 2));
|
|
17469
17496
|
this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
|
|
@@ -17488,7 +17515,7 @@ var PersonaStore = class {
|
|
|
17488
17515
|
list() {
|
|
17489
17516
|
if (!fs6.existsSync(this.root)) return [];
|
|
17490
17517
|
return fs6.readdirSync(this.root).filter((name) => {
|
|
17491
|
-
return fs6.existsSync(
|
|
17518
|
+
return fs6.existsSync(path6.join(this.root, name, ".clawd", "persona.json"));
|
|
17492
17519
|
});
|
|
17493
17520
|
}
|
|
17494
17521
|
remove(personaId) {
|
|
@@ -17653,7 +17680,7 @@ var PersonaManager = class {
|
|
|
17653
17680
|
tool: "claude",
|
|
17654
17681
|
label: subLabel,
|
|
17655
17682
|
model: persona.model,
|
|
17656
|
-
subSessionMeta: { idleKillEnabled: true, personaMode:
|
|
17683
|
+
subSessionMeta: { idleKillEnabled: true, personaMode: "listener" }
|
|
17657
17684
|
});
|
|
17658
17685
|
return { sessionFile, isNew: true };
|
|
17659
17686
|
}
|
|
@@ -17689,14 +17716,14 @@ init_claude_history();
|
|
|
17689
17716
|
// src/workspace/browser.ts
|
|
17690
17717
|
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
17691
17718
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
17692
|
-
var
|
|
17719
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
17693
17720
|
init_protocol();
|
|
17694
17721
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
17695
17722
|
function resolveInsideCwd(cwd, subpath) {
|
|
17696
|
-
const absCwd =
|
|
17697
|
-
const joined =
|
|
17698
|
-
const rel =
|
|
17699
|
-
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)) {
|
|
17700
17727
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
17701
17728
|
}
|
|
17702
17729
|
return joined;
|
|
@@ -17727,7 +17754,7 @@ var WorkspaceBrowser = class {
|
|
|
17727
17754
|
mtime: ""
|
|
17728
17755
|
};
|
|
17729
17756
|
try {
|
|
17730
|
-
const st = import_node_fs8.default.statSync(
|
|
17757
|
+
const st = import_node_fs8.default.statSync(import_node_path8.default.join(full, d.name));
|
|
17731
17758
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
17732
17759
|
if (d.isFile()) entry.size = st.size;
|
|
17733
17760
|
} catch {
|
|
@@ -17774,25 +17801,21 @@ var WorkspaceBrowser = class {
|
|
|
17774
17801
|
// src/skills/scanner.ts
|
|
17775
17802
|
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
17776
17803
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
17777
|
-
var
|
|
17778
|
-
|
|
17779
|
-
|
|
17780
|
-
var STRIP_QUOTES = /^["']|["']$/g;
|
|
17781
|
-
function strip(s) {
|
|
17782
|
-
return s.trim().replace(STRIP_QUOTES, "");
|
|
17783
|
-
}
|
|
17784
|
-
function parseFrontmatter(content, keys) {
|
|
17785
|
-
const out = {};
|
|
17786
|
-
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: "" };
|
|
17787
17807
|
const end = content.indexOf("---", 3);
|
|
17788
|
-
if (end === -1) return
|
|
17808
|
+
if (end === -1) return { name: "", description: "" };
|
|
17789
17809
|
const lines = content.slice(3, end).split("\n");
|
|
17810
|
+
const strip = (s) => s.trim().replace(/^["']|["']$/g, "");
|
|
17811
|
+
let name = "";
|
|
17812
|
+
let description = "";
|
|
17790
17813
|
for (let i = 0; i < lines.length; i++) {
|
|
17791
17814
|
const trimmed = lines[i].trim();
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
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();
|
|
17796
17819
|
if (rest === "|" || rest === ">" || rest === "|-" || rest === ">-") {
|
|
17797
17820
|
const parts = [];
|
|
17798
17821
|
for (let j = i + 1; j < lines.length; j++) {
|
|
@@ -17804,82 +17827,13 @@ function parseFrontmatter(content, keys) {
|
|
|
17804
17827
|
if (!/^\s/.test(next)) break;
|
|
17805
17828
|
parts.push(next.replace(/^\s+/, ""));
|
|
17806
17829
|
}
|
|
17807
|
-
|
|
17808
|
-
if (value) out[key] = value;
|
|
17830
|
+
description = parts.filter(Boolean).join(" ").trim();
|
|
17809
17831
|
} else {
|
|
17810
|
-
|
|
17811
|
-
if (value) out[key] = value;
|
|
17832
|
+
description = strip(rest);
|
|
17812
17833
|
}
|
|
17813
|
-
break;
|
|
17814
17834
|
}
|
|
17815
17835
|
}
|
|
17816
|
-
return
|
|
17817
|
-
}
|
|
17818
|
-
|
|
17819
|
-
// src/skills/builtin-cc-resources.ts
|
|
17820
|
-
var BUILTIN_SKILLS = [
|
|
17821
|
-
{ name: "update-config", source: "builtin", description: "Update Claude Code configuration." },
|
|
17822
|
-
{ name: "keybindings-help", source: "builtin", description: "Show available keybindings." },
|
|
17823
|
-
{ name: "verify", source: "builtin", description: "Verify the implementation." },
|
|
17824
|
-
{ name: "debug", source: "builtin", description: "Debug current issue." },
|
|
17825
|
-
{ name: "lorem-ipsum", source: "builtin", description: "Generate lorem ipsum placeholder text." },
|
|
17826
|
-
{ name: "skillify", source: "builtin", description: "Convert a process into a reusable skill." },
|
|
17827
|
-
{ name: "remember", source: "builtin", description: "Remember context for later use." },
|
|
17828
|
-
{ name: "simplify", source: "builtin", description: "Simplify the code or message." },
|
|
17829
|
-
{ name: "batch", source: "builtin", description: "Run a batch of similar operations." },
|
|
17830
|
-
{ name: "stuck", source: "builtin", description: "Help unstick a stalled task." },
|
|
17831
|
-
{ name: "loop", source: "builtin", description: "Loop a task until a condition is met." },
|
|
17832
|
-
{ name: "cron-list", source: "builtin", description: "List scheduled cron tasks." },
|
|
17833
|
-
{ name: "cron-delete", source: "builtin", description: "Delete a scheduled cron task." },
|
|
17834
|
-
{ name: "dream", source: "builtin", description: "Brainstorm freely without constraints." },
|
|
17835
|
-
{ name: "hunter", source: "builtin", description: "Hunt down a bug or root cause." },
|
|
17836
|
-
{ name: "schedule", source: "builtin", description: "Schedule a task to run later." },
|
|
17837
|
-
{ name: "claude-api", source: "builtin", description: "Use the Claude API directly." },
|
|
17838
|
-
{ name: "claude-in-chrome", source: "builtin", description: "Drive Claude inside Chrome via the Chrome extension." }
|
|
17839
|
-
];
|
|
17840
|
-
var BUILTIN_AGENTS = [
|
|
17841
|
-
{
|
|
17842
|
-
name: "general-purpose",
|
|
17843
|
-
source: "builtin",
|
|
17844
|
-
description: "General-purpose agent for researching complex questions and executing multi-step tasks.",
|
|
17845
|
-
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."
|
|
17846
|
-
},
|
|
17847
|
-
{
|
|
17848
|
-
name: "statusline-setup",
|
|
17849
|
-
source: "builtin",
|
|
17850
|
-
description: "Configure the user's Claude Code status line setting.",
|
|
17851
|
-
whenToUse: "When the user is setting up or changing their status line configuration."
|
|
17852
|
-
},
|
|
17853
|
-
{
|
|
17854
|
-
name: "Explore",
|
|
17855
|
-
source: "builtin",
|
|
17856
|
-
description: "Explore the codebase to gather context.",
|
|
17857
|
-
whenToUse: "Before making changes that require understanding the surrounding code."
|
|
17858
|
-
},
|
|
17859
|
-
{
|
|
17860
|
-
name: "Plan",
|
|
17861
|
-
source: "builtin",
|
|
17862
|
-
description: "Produce an implementation plan before writing code.",
|
|
17863
|
-
whenToUse: "When the task is non-trivial and would benefit from an explicit plan."
|
|
17864
|
-
},
|
|
17865
|
-
{
|
|
17866
|
-
name: "claude-code-guide",
|
|
17867
|
-
source: "builtin",
|
|
17868
|
-
description: "Guide the user through Claude Code features.",
|
|
17869
|
-
whenToUse: "When the user needs help understanding what Claude Code can do."
|
|
17870
|
-
},
|
|
17871
|
-
{
|
|
17872
|
-
name: "verification",
|
|
17873
|
-
source: "builtin",
|
|
17874
|
-
description: "Verify that a change works as intended.",
|
|
17875
|
-
whenToUse: "After implementing a change, before declaring it done."
|
|
17876
|
-
}
|
|
17877
|
-
];
|
|
17878
|
-
|
|
17879
|
-
// src/skills/scanner.ts
|
|
17880
|
-
function parseDescription(content) {
|
|
17881
|
-
const fields = parseFrontmatter(content, ["description"]);
|
|
17882
|
-
return { description: fields.description ?? "" };
|
|
17836
|
+
return { name, description };
|
|
17883
17837
|
}
|
|
17884
17838
|
function isDirLikeSync(p) {
|
|
17885
17839
|
try {
|
|
@@ -17896,19 +17850,19 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
|
17896
17850
|
return;
|
|
17897
17851
|
}
|
|
17898
17852
|
for (const ent of entries) {
|
|
17899
|
-
const entryPath =
|
|
17853
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
17900
17854
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
17901
17855
|
let content;
|
|
17902
17856
|
try {
|
|
17903
|
-
content = import_node_fs9.default.readFileSync(
|
|
17857
|
+
content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
|
|
17904
17858
|
} catch {
|
|
17905
17859
|
try {
|
|
17906
|
-
content = import_node_fs9.default.readFileSync(
|
|
17860
|
+
content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
|
|
17907
17861
|
} catch {
|
|
17908
17862
|
continue;
|
|
17909
17863
|
}
|
|
17910
17864
|
}
|
|
17911
|
-
const { description } =
|
|
17865
|
+
const { description } = parseFrontmatter(content);
|
|
17912
17866
|
const baseName = ent.name;
|
|
17913
17867
|
const name = pluginName ? `${pluginName}:${baseName}` : baseName;
|
|
17914
17868
|
if (seen.has(name)) continue;
|
|
@@ -17926,7 +17880,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17926
17880
|
return;
|
|
17927
17881
|
}
|
|
17928
17882
|
for (const ent of entries) {
|
|
17929
|
-
const entryPath =
|
|
17883
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
17930
17884
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
17931
17885
|
const ns = ent.name;
|
|
17932
17886
|
let subEntries;
|
|
@@ -17937,7 +17891,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17937
17891
|
}
|
|
17938
17892
|
for (const se of subEntries) {
|
|
17939
17893
|
if (!se.name.endsWith(".md")) continue;
|
|
17940
|
-
const sePath =
|
|
17894
|
+
const sePath = import_node_path9.default.join(entryPath, se.name);
|
|
17941
17895
|
let content;
|
|
17942
17896
|
try {
|
|
17943
17897
|
content = import_node_fs9.default.readFileSync(sePath, "utf8");
|
|
@@ -17945,7 +17899,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17945
17899
|
continue;
|
|
17946
17900
|
}
|
|
17947
17901
|
const cmd = se.name.replace(/\.md$/, "");
|
|
17948
|
-
const { description } =
|
|
17902
|
+
const { description } = parseFrontmatter(content);
|
|
17949
17903
|
const qualified = `${ns}:${cmd}`;
|
|
17950
17904
|
const name = pluginName ? `${pluginName}:${qualified}` : qualified;
|
|
17951
17905
|
if (seen.has(name)) continue;
|
|
@@ -17962,7 +17916,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17962
17916
|
continue;
|
|
17963
17917
|
}
|
|
17964
17918
|
const cmd = ent.name.replace(/\.md$/, "");
|
|
17965
|
-
const { description } =
|
|
17919
|
+
const { description } = parseFrontmatter(content);
|
|
17966
17920
|
const name = pluginName ? `${pluginName}:${cmd}` : cmd;
|
|
17967
17921
|
if (seen.has(name)) continue;
|
|
17968
17922
|
seen.add(name);
|
|
@@ -17973,7 +17927,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
17973
17927
|
}
|
|
17974
17928
|
}
|
|
17975
17929
|
function readInstalledPlugins(home) {
|
|
17976
|
-
const file =
|
|
17930
|
+
const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
17977
17931
|
let raw;
|
|
17978
17932
|
try {
|
|
17979
17933
|
raw = import_node_fs9.default.readFileSync(file, "utf8");
|
|
@@ -18013,231 +17967,30 @@ var SkillsScanner = class {
|
|
|
18013
17967
|
*/
|
|
18014
17968
|
list(args) {
|
|
18015
17969
|
const seen = /* @__PURE__ */ new Set();
|
|
18016
|
-
const
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
name: b.name,
|
|
18022
|
-
source: "builtin",
|
|
18023
|
-
description: b.description
|
|
18024
|
-
});
|
|
18025
|
-
}
|
|
18026
|
-
const fsBlock = [];
|
|
18027
|
-
scanSkillDir(import_node_path8.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
|
|
18028
|
-
scanCommandDir(import_node_path8.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
|
|
18029
|
-
scanSkillDir(import_node_path8.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
|
|
18030
|
-
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);
|
|
18031
17975
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
18032
17976
|
for (const { name, root } of plugins) {
|
|
18033
|
-
scanSkillDir(
|
|
18034
|
-
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);
|
|
18035
17979
|
}
|
|
18036
|
-
|
|
18037
|
-
return
|
|
17980
|
+
out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
17981
|
+
return out;
|
|
18038
17982
|
}
|
|
18039
17983
|
};
|
|
18040
17984
|
|
|
18041
|
-
// src/
|
|
17985
|
+
// src/observer/session-observer.ts
|
|
18042
17986
|
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
18043
17987
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
18044
|
-
var import_node_path9 = __toESM(require("path"), 1);
|
|
18045
|
-
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
18046
|
-
function isDirLikeSync2(p) {
|
|
18047
|
-
try {
|
|
18048
|
-
return import_node_fs10.default.statSync(p).isDirectory();
|
|
18049
|
-
} catch {
|
|
18050
|
-
return false;
|
|
18051
|
-
}
|
|
18052
|
-
}
|
|
18053
|
-
function fileExistsSync(p) {
|
|
18054
|
-
try {
|
|
18055
|
-
return import_node_fs10.default.statSync(p).isFile();
|
|
18056
|
-
} catch {
|
|
18057
|
-
return false;
|
|
18058
|
-
}
|
|
18059
|
-
}
|
|
18060
|
-
function parseAgentFile(filePath) {
|
|
18061
|
-
let content;
|
|
18062
|
-
try {
|
|
18063
|
-
content = import_node_fs10.default.readFileSync(filePath, "utf8");
|
|
18064
|
-
} catch {
|
|
18065
|
-
return {};
|
|
18066
|
-
}
|
|
18067
|
-
const fm = parseFrontmatter(content, ["description", "whenToUse"]);
|
|
18068
|
-
return {
|
|
18069
|
-
description: fm.description,
|
|
18070
|
-
whenToUse: fm.whenToUse
|
|
18071
|
-
};
|
|
18072
|
-
}
|
|
18073
|
-
function scanAgentsDir(dir, source, seen, out) {
|
|
18074
|
-
let entries;
|
|
18075
|
-
try {
|
|
18076
|
-
entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
|
|
18077
|
-
} catch {
|
|
18078
|
-
return;
|
|
18079
|
-
}
|
|
18080
|
-
for (const ent of entries) {
|
|
18081
|
-
if (!ent.name.endsWith(".md")) continue;
|
|
18082
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path9.default.join(dir, ent.name)))) {
|
|
18083
|
-
continue;
|
|
18084
|
-
}
|
|
18085
|
-
const filePath = import_node_path9.default.join(dir, ent.name);
|
|
18086
|
-
const baseName = ent.name.replace(/\.md$/, "");
|
|
18087
|
-
if (seen.has(baseName)) continue;
|
|
18088
|
-
seen.add(baseName);
|
|
18089
|
-
const { description, whenToUse } = parseAgentFile(filePath);
|
|
18090
|
-
out.push({
|
|
18091
|
-
name: baseName,
|
|
18092
|
-
source,
|
|
18093
|
-
path: filePath,
|
|
18094
|
-
...description ? { description } : {},
|
|
18095
|
-
...whenToUse ? { whenToUse } : {}
|
|
18096
|
-
});
|
|
18097
|
-
}
|
|
18098
|
-
}
|
|
18099
|
-
function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
18100
|
-
function walk(dir, namespaces) {
|
|
18101
|
-
let entries;
|
|
18102
|
-
try {
|
|
18103
|
-
entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
|
|
18104
|
-
} catch {
|
|
18105
|
-
return;
|
|
18106
|
-
}
|
|
18107
|
-
for (const ent of entries) {
|
|
18108
|
-
const childPath = import_node_path9.default.join(dir, ent.name);
|
|
18109
|
-
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
18110
|
-
walk(childPath, [...namespaces, ent.name]);
|
|
18111
|
-
continue;
|
|
18112
|
-
}
|
|
18113
|
-
if (!ent.name.endsWith(".md")) continue;
|
|
18114
|
-
const baseName = ent.name.replace(/\.md$/, "");
|
|
18115
|
-
const nameParts = [pluginName, ...namespaces, baseName];
|
|
18116
|
-
const name = nameParts.join(":");
|
|
18117
|
-
if (seen.has(name)) continue;
|
|
18118
|
-
seen.add(name);
|
|
18119
|
-
const { description, whenToUse } = parseAgentFile(childPath);
|
|
18120
|
-
out.push({
|
|
18121
|
-
name,
|
|
18122
|
-
source: "plugin",
|
|
18123
|
-
path: childPath,
|
|
18124
|
-
plugin: pluginName,
|
|
18125
|
-
...description ? { description } : {},
|
|
18126
|
-
...whenToUse ? { whenToUse } : {}
|
|
18127
|
-
});
|
|
18128
|
-
}
|
|
18129
|
-
}
|
|
18130
|
-
walk(root, []);
|
|
18131
|
-
}
|
|
18132
|
-
function readInstalledPlugins2(home) {
|
|
18133
|
-
const pluginsDir = import_node_path9.default.join(home, ".claude", "plugins");
|
|
18134
|
-
const v2 = import_node_path9.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
18135
|
-
const v1 = import_node_path9.default.join(pluginsDir, "installed_plugins.json");
|
|
18136
|
-
let raw = null;
|
|
18137
|
-
for (const candidate of [v2, v1]) {
|
|
18138
|
-
try {
|
|
18139
|
-
raw = import_node_fs10.default.readFileSync(candidate, "utf8");
|
|
18140
|
-
break;
|
|
18141
|
-
} catch {
|
|
18142
|
-
}
|
|
18143
|
-
}
|
|
18144
|
-
if (!raw) return [];
|
|
18145
|
-
let parsed;
|
|
18146
|
-
try {
|
|
18147
|
-
parsed = JSON.parse(raw);
|
|
18148
|
-
} catch {
|
|
18149
|
-
return [];
|
|
18150
|
-
}
|
|
18151
|
-
const out = [];
|
|
18152
|
-
for (const [key, entries] of Object.entries(parsed.plugins ?? {})) {
|
|
18153
|
-
if (!Array.isArray(entries) || entries.length === 0) continue;
|
|
18154
|
-
const entry = entries[0];
|
|
18155
|
-
if (!entry?.installPath) continue;
|
|
18156
|
-
if (entry.enabled === false) continue;
|
|
18157
|
-
const pluginName = key.includes("@") ? key.slice(0, key.indexOf("@")) : key;
|
|
18158
|
-
if (!pluginName) continue;
|
|
18159
|
-
out.push({ name: pluginName, root: entry.installPath });
|
|
18160
|
-
}
|
|
18161
|
-
return out;
|
|
18162
|
-
}
|
|
18163
|
-
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
18164
|
-
let cur = import_node_path9.default.resolve(startCwd);
|
|
18165
|
-
const fsRoot = import_node_path9.default.parse(cur).root;
|
|
18166
|
-
while (true) {
|
|
18167
|
-
scanAgentsDir(import_node_path9.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
18168
|
-
let hasGit = false;
|
|
18169
|
-
try {
|
|
18170
|
-
hasGit = import_node_fs10.default.existsSync(import_node_path9.default.join(cur, ".git"));
|
|
18171
|
-
} catch {
|
|
18172
|
-
}
|
|
18173
|
-
if (hasGit) return;
|
|
18174
|
-
if (cur === home) return;
|
|
18175
|
-
if (cur === fsRoot) return;
|
|
18176
|
-
const parent = import_node_path9.default.dirname(cur);
|
|
18177
|
-
if (parent === cur) return;
|
|
18178
|
-
cur = parent;
|
|
18179
|
-
}
|
|
18180
|
-
}
|
|
18181
|
-
var AgentsScanner = class {
|
|
18182
|
-
home;
|
|
18183
|
-
extraPluginRoots;
|
|
18184
|
-
policyDir;
|
|
18185
|
-
constructor(opts = {}) {
|
|
18186
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os6.default.homedir();
|
|
18187
|
-
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
18188
|
-
if (opts.policyDir !== void 0) {
|
|
18189
|
-
this.policyDir = opts.policyDir;
|
|
18190
|
-
} else if (process.platform === "darwin") {
|
|
18191
|
-
this.policyDir = DEFAULT_POLICY_DIR_DARWIN;
|
|
18192
|
-
} else {
|
|
18193
|
-
this.policyDir = null;
|
|
18194
|
-
}
|
|
18195
|
-
}
|
|
18196
|
-
list(args) {
|
|
18197
|
-
const seen = /* @__PURE__ */ new Set();
|
|
18198
|
-
const builtinBlock = [];
|
|
18199
|
-
for (const b of BUILTIN_AGENTS) {
|
|
18200
|
-
if (seen.has(b.name)) continue;
|
|
18201
|
-
seen.add(b.name);
|
|
18202
|
-
builtinBlock.push({
|
|
18203
|
-
name: b.name,
|
|
18204
|
-
source: "builtin",
|
|
18205
|
-
...b.description ? { description: b.description } : {},
|
|
18206
|
-
...b.whenToUse ? { whenToUse: b.whenToUse } : {}
|
|
18207
|
-
});
|
|
18208
|
-
}
|
|
18209
|
-
const fsBlock = [];
|
|
18210
|
-
scanAgentsDir(
|
|
18211
|
-
import_node_path9.default.join(this.home, ".claude", "agents"),
|
|
18212
|
-
"global",
|
|
18213
|
-
seen,
|
|
18214
|
-
fsBlock
|
|
18215
|
-
);
|
|
18216
|
-
walkUpProjectAgentsDirs(args.cwd, this.home, seen, fsBlock);
|
|
18217
|
-
if (this.policyDir) {
|
|
18218
|
-
scanAgentsDir(this.policyDir, "policy", seen, fsBlock);
|
|
18219
|
-
}
|
|
18220
|
-
const plugins = [
|
|
18221
|
-
...readInstalledPlugins2(this.home),
|
|
18222
|
-
...this.extraPluginRoots
|
|
18223
|
-
];
|
|
18224
|
-
for (const { name, root } of plugins) {
|
|
18225
|
-
const agentsRoot = import_node_path9.default.join(root, "agents");
|
|
18226
|
-
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
18227
|
-
}
|
|
18228
|
-
return [...builtinBlock, ...fsBlock];
|
|
18229
|
-
}
|
|
18230
|
-
};
|
|
18231
|
-
|
|
18232
|
-
// src/observer/session-observer.ts
|
|
18233
|
-
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
18234
|
-
var import_node_os7 = __toESM(require("os"), 1);
|
|
18235
17988
|
var import_node_path10 = __toESM(require("path"), 1);
|
|
18236
17989
|
init_claude_history();
|
|
18237
17990
|
var SessionObserver = class {
|
|
18238
17991
|
constructor(opts) {
|
|
18239
17992
|
this.opts = opts;
|
|
18240
|
-
this.home = opts.home ??
|
|
17993
|
+
this.home = opts.home ?? import_node_os6.default.homedir();
|
|
18241
17994
|
}
|
|
18242
17995
|
opts;
|
|
18243
17996
|
home;
|
|
@@ -18251,7 +18004,7 @@ var SessionObserver = class {
|
|
|
18251
18004
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
18252
18005
|
let size = 0;
|
|
18253
18006
|
try {
|
|
18254
|
-
size =
|
|
18007
|
+
size = import_node_fs10.default.statSync(filePath).size;
|
|
18255
18008
|
} catch {
|
|
18256
18009
|
}
|
|
18257
18010
|
const w = {
|
|
@@ -18264,10 +18017,10 @@ var SessionObserver = class {
|
|
|
18264
18017
|
adapter: args.adapter
|
|
18265
18018
|
};
|
|
18266
18019
|
try {
|
|
18267
|
-
|
|
18020
|
+
import_node_fs10.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
|
|
18268
18021
|
} catch {
|
|
18269
18022
|
}
|
|
18270
|
-
w.watcher =
|
|
18023
|
+
w.watcher = import_node_fs10.default.watch(import_node_path10.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
18271
18024
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
18272
18025
|
this.poll(w);
|
|
18273
18026
|
});
|
|
@@ -18282,7 +18035,7 @@ var SessionObserver = class {
|
|
|
18282
18035
|
// reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
|
|
18283
18036
|
hydrateMetaTail(w, maxLines = 200) {
|
|
18284
18037
|
try {
|
|
18285
|
-
const raw =
|
|
18038
|
+
const raw = import_node_fs10.default.readFileSync(w.filePath, "utf8");
|
|
18286
18039
|
if (!raw) return;
|
|
18287
18040
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
18288
18041
|
if (allLines.length === 0) return;
|
|
@@ -18303,7 +18056,7 @@ var SessionObserver = class {
|
|
|
18303
18056
|
poll(w) {
|
|
18304
18057
|
let size = 0;
|
|
18305
18058
|
try {
|
|
18306
|
-
size =
|
|
18059
|
+
size = import_node_fs10.default.statSync(w.filePath).size;
|
|
18307
18060
|
} catch {
|
|
18308
18061
|
return;
|
|
18309
18062
|
}
|
|
@@ -18312,11 +18065,11 @@ var SessionObserver = class {
|
|
|
18312
18065
|
w.buf = "";
|
|
18313
18066
|
}
|
|
18314
18067
|
if (size === w.lastSize) return;
|
|
18315
|
-
const fd =
|
|
18068
|
+
const fd = import_node_fs10.default.openSync(w.filePath, "r");
|
|
18316
18069
|
try {
|
|
18317
18070
|
const len = size - w.lastSize;
|
|
18318
18071
|
const buf = Buffer.alloc(len);
|
|
18319
|
-
|
|
18072
|
+
import_node_fs10.default.readSync(fd, buf, 0, len, w.lastSize);
|
|
18320
18073
|
w.lastSize = size;
|
|
18321
18074
|
w.buf += buf.toString("utf8");
|
|
18322
18075
|
let newlineIndex;
|
|
@@ -18330,7 +18083,7 @@ var SessionObserver = class {
|
|
|
18330
18083
|
this.maybeReportUserMessage(w.sessionId, line);
|
|
18331
18084
|
}
|
|
18332
18085
|
} finally {
|
|
18333
|
-
|
|
18086
|
+
import_node_fs10.default.closeSync(fd);
|
|
18334
18087
|
}
|
|
18335
18088
|
}
|
|
18336
18089
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -18982,7 +18735,7 @@ function isLocalhost(addr) {
|
|
|
18982
18735
|
}
|
|
18983
18736
|
|
|
18984
18737
|
// src/discovery/state-file.ts
|
|
18985
|
-
var
|
|
18738
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
18986
18739
|
var import_node_path11 = __toESM(require("path"), 1);
|
|
18987
18740
|
function defaultStateFilePath(dataDir) {
|
|
18988
18741
|
return import_node_path11.default.join(dataDir, "state.json");
|
|
@@ -19007,7 +18760,7 @@ var StateFileManager = class {
|
|
|
19007
18760
|
}
|
|
19008
18761
|
read() {
|
|
19009
18762
|
try {
|
|
19010
|
-
const raw =
|
|
18763
|
+
const raw = import_node_fs11.default.readFileSync(this.file, "utf8");
|
|
19011
18764
|
const parsed = JSON.parse(raw);
|
|
19012
18765
|
return parsed;
|
|
19013
18766
|
} catch {
|
|
@@ -19021,33 +18774,33 @@ var StateFileManager = class {
|
|
|
19021
18774
|
return { status: "stale", existing };
|
|
19022
18775
|
}
|
|
19023
18776
|
write(state) {
|
|
19024
|
-
|
|
18777
|
+
import_node_fs11.default.mkdirSync(import_node_path11.default.dirname(this.file), { recursive: true });
|
|
19025
18778
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
19026
|
-
|
|
19027
|
-
|
|
18779
|
+
import_node_fs11.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
18780
|
+
import_node_fs11.default.renameSync(tmp, this.file);
|
|
19028
18781
|
if (process.platform !== "win32") {
|
|
19029
18782
|
try {
|
|
19030
|
-
|
|
18783
|
+
import_node_fs11.default.chmodSync(this.file, 384);
|
|
19031
18784
|
} catch {
|
|
19032
18785
|
}
|
|
19033
18786
|
}
|
|
19034
18787
|
}
|
|
19035
18788
|
delete() {
|
|
19036
18789
|
try {
|
|
19037
|
-
|
|
18790
|
+
import_node_fs11.default.unlinkSync(this.file);
|
|
19038
18791
|
} catch {
|
|
19039
18792
|
}
|
|
19040
18793
|
}
|
|
19041
18794
|
};
|
|
19042
18795
|
|
|
19043
18796
|
// src/tunnel/tunnel-manager.ts
|
|
19044
|
-
var
|
|
18797
|
+
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
19045
18798
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
19046
18799
|
var import_node_crypto4 = __toESM(require("crypto"), 1);
|
|
19047
18800
|
var import_node_child_process4 = require("child_process");
|
|
19048
18801
|
|
|
19049
18802
|
// src/tunnel/tunnel-store.ts
|
|
19050
|
-
var
|
|
18803
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
19051
18804
|
var import_node_path12 = __toESM(require("path"), 1);
|
|
19052
18805
|
var TunnelStore = class {
|
|
19053
18806
|
constructor(filePath) {
|
|
@@ -19056,7 +18809,7 @@ var TunnelStore = class {
|
|
|
19056
18809
|
filePath;
|
|
19057
18810
|
async get() {
|
|
19058
18811
|
try {
|
|
19059
|
-
const raw = await
|
|
18812
|
+
const raw = await import_node_fs12.default.promises.readFile(this.filePath, "utf8");
|
|
19060
18813
|
const obj = JSON.parse(raw);
|
|
19061
18814
|
if (!isPersistedTunnel(obj)) return null;
|
|
19062
18815
|
return obj;
|
|
@@ -19068,21 +18821,21 @@ var TunnelStore = class {
|
|
|
19068
18821
|
}
|
|
19069
18822
|
async set(v) {
|
|
19070
18823
|
const dir = import_node_path12.default.dirname(this.filePath);
|
|
19071
|
-
await
|
|
18824
|
+
await import_node_fs12.default.promises.mkdir(dir, { recursive: true });
|
|
19072
18825
|
const data = JSON.stringify(v, null, 2);
|
|
19073
18826
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
19074
|
-
await
|
|
18827
|
+
await import_node_fs12.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
19075
18828
|
if (process.platform !== "win32") {
|
|
19076
18829
|
try {
|
|
19077
|
-
await
|
|
18830
|
+
await import_node_fs12.default.promises.chmod(tmp, 384);
|
|
19078
18831
|
} catch {
|
|
19079
18832
|
}
|
|
19080
18833
|
}
|
|
19081
|
-
await
|
|
18834
|
+
await import_node_fs12.default.promises.rename(tmp, this.filePath);
|
|
19082
18835
|
}
|
|
19083
18836
|
async clear() {
|
|
19084
18837
|
try {
|
|
19085
|
-
await
|
|
18838
|
+
await import_node_fs12.default.promises.unlink(this.filePath);
|
|
19086
18839
|
} catch (err) {
|
|
19087
18840
|
const code = err?.code;
|
|
19088
18841
|
if (code !== "ENOENT") throw err;
|
|
@@ -19177,8 +18930,8 @@ function escape(v) {
|
|
|
19177
18930
|
}
|
|
19178
18931
|
|
|
19179
18932
|
// src/tunnel/frpc-binary.ts
|
|
19180
|
-
var
|
|
19181
|
-
var
|
|
18933
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
18934
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
19182
18935
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
19183
18936
|
var import_node_child_process3 = require("child_process");
|
|
19184
18937
|
var import_node_stream = require("stream");
|
|
@@ -19211,7 +18964,7 @@ function frpcDownloadUrl(version2, p) {
|
|
|
19211
18964
|
}
|
|
19212
18965
|
async function ensureFrpcBinary(opts) {
|
|
19213
18966
|
if (opts.override) {
|
|
19214
|
-
if (!
|
|
18967
|
+
if (!import_node_fs13.default.existsSync(opts.override)) {
|
|
19215
18968
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
19216
18969
|
}
|
|
19217
18970
|
return opts.override;
|
|
@@ -19219,10 +18972,10 @@ async function ensureFrpcBinary(opts) {
|
|
|
19219
18972
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
19220
18973
|
const platform = opts.platform ?? detectPlatform();
|
|
19221
18974
|
const binDir = import_node_path13.default.join(opts.dataDir, "bin");
|
|
19222
|
-
|
|
18975
|
+
import_node_fs13.default.mkdirSync(binDir, { recursive: true });
|
|
19223
18976
|
cleanupStaleArtifacts(binDir);
|
|
19224
18977
|
const stableBin = import_node_path13.default.join(binDir, "frpc");
|
|
19225
|
-
if (
|
|
18978
|
+
if (import_node_fs13.default.existsSync(stableBin)) return stableBin;
|
|
19226
18979
|
const partialBin = `${stableBin}.partial`;
|
|
19227
18980
|
const tarballPath = import_node_path13.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
19228
18981
|
try {
|
|
@@ -19233,8 +18986,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
19233
18986
|
} else {
|
|
19234
18987
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
19235
18988
|
}
|
|
19236
|
-
|
|
19237
|
-
|
|
18989
|
+
import_node_fs13.default.chmodSync(partialBin, 493);
|
|
18990
|
+
import_node_fs13.default.renameSync(partialBin, stableBin);
|
|
19238
18991
|
} finally {
|
|
19239
18992
|
safeUnlink(tarballPath);
|
|
19240
18993
|
safeUnlink(partialBin);
|
|
@@ -19244,7 +18997,7 @@ async function ensureFrpcBinary(opts) {
|
|
|
19244
18997
|
function cleanupStaleArtifacts(binDir) {
|
|
19245
18998
|
let entries;
|
|
19246
18999
|
try {
|
|
19247
|
-
entries =
|
|
19000
|
+
entries = import_node_fs13.default.readdirSync(binDir);
|
|
19248
19001
|
} catch {
|
|
19249
19002
|
return;
|
|
19250
19003
|
}
|
|
@@ -19252,7 +19005,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
19252
19005
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
19253
19006
|
const full = import_node_path13.default.join(binDir, name);
|
|
19254
19007
|
try {
|
|
19255
|
-
|
|
19008
|
+
import_node_fs13.default.rmSync(full, { recursive: true, force: true });
|
|
19256
19009
|
} catch {
|
|
19257
19010
|
}
|
|
19258
19011
|
}
|
|
@@ -19260,7 +19013,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
19260
19013
|
}
|
|
19261
19014
|
function safeUnlink(p) {
|
|
19262
19015
|
try {
|
|
19263
|
-
|
|
19016
|
+
import_node_fs13.default.unlinkSync(p);
|
|
19264
19017
|
} catch {
|
|
19265
19018
|
}
|
|
19266
19019
|
}
|
|
@@ -19271,13 +19024,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
19271
19024
|
if (!res.ok || !res.body) {
|
|
19272
19025
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
19273
19026
|
}
|
|
19274
|
-
const out =
|
|
19027
|
+
const out = import_node_fs13.default.createWriteStream(dest);
|
|
19275
19028
|
const nodeStream = import_node_stream.Readable.fromWeb(res.body);
|
|
19276
19029
|
await (0, import_promises.pipeline)(nodeStream, out);
|
|
19277
19030
|
}
|
|
19278
19031
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
19279
19032
|
const work = import_node_path13.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
19280
|
-
|
|
19033
|
+
import_node_fs13.default.mkdirSync(work, { recursive: true });
|
|
19281
19034
|
try {
|
|
19282
19035
|
await new Promise((resolve, reject) => {
|
|
19283
19036
|
const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -19286,12 +19039,12 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
19286
19039
|
});
|
|
19287
19040
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
19288
19041
|
const src = import_node_path13.default.join(work, dirName, "frpc");
|
|
19289
|
-
if (!
|
|
19042
|
+
if (!import_node_fs13.default.existsSync(src)) {
|
|
19290
19043
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
19291
19044
|
}
|
|
19292
|
-
|
|
19045
|
+
import_node_fs13.default.copyFileSync(src, destBin);
|
|
19293
19046
|
} finally {
|
|
19294
|
-
|
|
19047
|
+
import_node_fs13.default.rmSync(work, { recursive: true, force: true });
|
|
19295
19048
|
}
|
|
19296
19049
|
}
|
|
19297
19050
|
|
|
@@ -19428,12 +19181,12 @@ var TunnelManager = class {
|
|
|
19428
19181
|
localPort,
|
|
19429
19182
|
logLevel: "info"
|
|
19430
19183
|
});
|
|
19431
|
-
await
|
|
19184
|
+
await import_node_fs14.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
19432
19185
|
const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
|
|
19433
19186
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19434
19187
|
});
|
|
19435
19188
|
const logFilePath = import_node_path14.default.join(this.deps.dataDir, "frpc.log");
|
|
19436
|
-
const logStream =
|
|
19189
|
+
const logStream = import_node_fs14.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
19437
19190
|
logStream.on("error", () => {
|
|
19438
19191
|
});
|
|
19439
19192
|
const tee = (chunk) => {
|
|
@@ -19514,18 +19267,18 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
19514
19267
|
}
|
|
19515
19268
|
|
|
19516
19269
|
// src/tunnel/device-key.ts
|
|
19517
|
-
var
|
|
19270
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
19518
19271
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
19519
19272
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
19520
19273
|
function deriveStableDeviceKey(opts = {}) {
|
|
19521
|
-
const hostname = opts.hostname ??
|
|
19522
|
-
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);
|
|
19523
19276
|
const input = `${hostname}::${uid}`;
|
|
19524
19277
|
return import_node_crypto5.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
19525
19278
|
}
|
|
19526
19279
|
|
|
19527
19280
|
// src/auth-store.ts
|
|
19528
|
-
var
|
|
19281
|
+
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
19529
19282
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
19530
19283
|
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
19531
19284
|
var AUTH_FILE_NAME = "auth.json";
|
|
@@ -19546,7 +19299,7 @@ function defaultGenerate() {
|
|
|
19546
19299
|
}
|
|
19547
19300
|
function readAuthFile(file) {
|
|
19548
19301
|
try {
|
|
19549
|
-
const raw =
|
|
19302
|
+
const raw = import_node_fs15.default.readFileSync(file, "utf8");
|
|
19550
19303
|
const parsed = JSON.parse(raw);
|
|
19551
19304
|
if (typeof parsed?.token === "string" && parsed.token.length > 0) {
|
|
19552
19305
|
return {
|
|
@@ -19562,10 +19315,10 @@ function readAuthFile(file) {
|
|
|
19562
19315
|
}
|
|
19563
19316
|
}
|
|
19564
19317
|
function writeAuthFile(file, content) {
|
|
19565
|
-
|
|
19566
|
-
|
|
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 });
|
|
19567
19320
|
try {
|
|
19568
|
-
|
|
19321
|
+
import_node_fs15.default.chmodSync(file, 384);
|
|
19569
19322
|
} catch {
|
|
19570
19323
|
}
|
|
19571
19324
|
}
|
|
@@ -19577,12 +19330,12 @@ init_protocol();
|
|
|
19577
19330
|
init_protocol();
|
|
19578
19331
|
|
|
19579
19332
|
// src/session/fork.ts
|
|
19580
|
-
var
|
|
19581
|
-
var
|
|
19333
|
+
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
19334
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
19582
19335
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
19583
19336
|
init_claude_history();
|
|
19584
19337
|
function readJsonlEntries(file) {
|
|
19585
|
-
const raw =
|
|
19338
|
+
const raw = import_node_fs16.default.readFileSync(file, "utf8");
|
|
19586
19339
|
const out = [];
|
|
19587
19340
|
for (const line of raw.split("\n")) {
|
|
19588
19341
|
const t = line.trim();
|
|
@@ -19595,10 +19348,10 @@ function readJsonlEntries(file) {
|
|
|
19595
19348
|
return out;
|
|
19596
19349
|
}
|
|
19597
19350
|
function forkSession(input) {
|
|
19598
|
-
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");
|
|
19599
19352
|
const projectDir = import_node_path16.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
19600
19353
|
const sourceFile = import_node_path16.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
19601
|
-
if (!
|
|
19354
|
+
if (!import_node_fs16.default.existsSync(sourceFile)) {
|
|
19602
19355
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
19603
19356
|
}
|
|
19604
19357
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -19629,8 +19382,8 @@ function forkSession(input) {
|
|
|
19629
19382
|
forkedLines.push(JSON.stringify(forked));
|
|
19630
19383
|
}
|
|
19631
19384
|
const forkedFilePath = import_node_path16.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
19632
|
-
|
|
19633
|
-
|
|
19385
|
+
import_node_fs16.default.mkdirSync(projectDir, { recursive: true });
|
|
19386
|
+
import_node_fs16.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
19634
19387
|
return { forkedToolSessionId, forkedFilePath };
|
|
19635
19388
|
}
|
|
19636
19389
|
|
|
@@ -19639,6 +19392,12 @@ function buildSessionHandlers(deps) {
|
|
|
19639
19392
|
const { manager, observer, getAdapter: getAdapter2 } = deps;
|
|
19640
19393
|
const create = async (frame) => {
|
|
19641
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
|
+
}
|
|
19642
19401
|
const { response, broadcast } = manager.create(args);
|
|
19643
19402
|
return { response: { type: "session:info", ...response }, broadcast };
|
|
19644
19403
|
};
|
|
@@ -19872,7 +19631,7 @@ function buildHistoryHandlers(deps) {
|
|
|
19872
19631
|
// src/handlers/workspace.ts
|
|
19873
19632
|
init_protocol();
|
|
19874
19633
|
function buildWorkspaceHandlers(deps) {
|
|
19875
|
-
const { workspace, skills
|
|
19634
|
+
const { workspace, skills } = deps;
|
|
19876
19635
|
const list = async (frame) => {
|
|
19877
19636
|
const args = WorkspaceListArgs.parse(frame);
|
|
19878
19637
|
const res = workspace.list(args);
|
|
@@ -19888,16 +19647,10 @@ function buildWorkspaceHandlers(deps) {
|
|
|
19888
19647
|
const list2 = skills.list(args);
|
|
19889
19648
|
return { response: { type: "skills:list", skills: list2 } };
|
|
19890
19649
|
};
|
|
19891
|
-
const agentsList = async (frame) => {
|
|
19892
|
-
const args = AgentsListArgs.parse(frame);
|
|
19893
|
-
const list2 = agents.list(args);
|
|
19894
|
-
return { response: { type: "agents:list", agents: list2 } };
|
|
19895
|
-
};
|
|
19896
19650
|
return {
|
|
19897
19651
|
"workspace:list": list,
|
|
19898
19652
|
"workspace:read": read,
|
|
19899
|
-
"skills:list": skillsList
|
|
19900
|
-
"agents:list": agentsList
|
|
19653
|
+
"skills:list": skillsList
|
|
19901
19654
|
};
|
|
19902
19655
|
}
|
|
19903
19656
|
|
|
@@ -19906,8 +19659,8 @@ init_protocol();
|
|
|
19906
19659
|
|
|
19907
19660
|
// src/workspace/git.ts
|
|
19908
19661
|
var import_node_child_process5 = require("child_process");
|
|
19909
|
-
var
|
|
19910
|
-
var
|
|
19662
|
+
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
19663
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
19911
19664
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
19912
19665
|
var import_node_util = require("util");
|
|
19913
19666
|
var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
|
|
@@ -19925,7 +19678,7 @@ function formatChildProcessError(err) {
|
|
|
19925
19678
|
function normalizePath(p) {
|
|
19926
19679
|
const resolved = import_node_path17.default.resolve(p);
|
|
19927
19680
|
try {
|
|
19928
|
-
return
|
|
19681
|
+
return import_node_fs17.default.realpathSync(resolved);
|
|
19929
19682
|
} catch {
|
|
19930
19683
|
return resolved;
|
|
19931
19684
|
}
|
|
@@ -20012,7 +19765,7 @@ function sanitizeLabel(raw) {
|
|
|
20012
19765
|
function computePrefix() {
|
|
20013
19766
|
let username;
|
|
20014
19767
|
try {
|
|
20015
|
-
username =
|
|
19768
|
+
username = import_node_os10.default.userInfo().username;
|
|
20016
19769
|
} catch {
|
|
20017
19770
|
username = void 0;
|
|
20018
19771
|
}
|
|
@@ -20028,10 +19781,10 @@ function encodeClaudeProjectDir(absPath) {
|
|
|
20028
19781
|
if (!absPath || typeof absPath !== "string") return "";
|
|
20029
19782
|
let canonical = import_node_path17.default.resolve(absPath);
|
|
20030
19783
|
try {
|
|
20031
|
-
canonical =
|
|
19784
|
+
canonical = import_node_fs17.default.realpathSync(canonical);
|
|
20032
19785
|
} catch {
|
|
20033
19786
|
try {
|
|
20034
|
-
const parent =
|
|
19787
|
+
const parent = import_node_fs17.default.realpathSync(import_node_path17.default.dirname(canonical));
|
|
20035
19788
|
canonical = import_node_path17.default.join(parent, import_node_path17.default.basename(canonical));
|
|
20036
19789
|
} catch {
|
|
20037
19790
|
}
|
|
@@ -20062,11 +19815,13 @@ async function createWorktree(input) {
|
|
|
20062
19815
|
}
|
|
20063
19816
|
const worktreeRoot = import_node_path17.default.join(parent, dirName);
|
|
20064
19817
|
try {
|
|
20065
|
-
await pexec("git", ["-C", cwd, "
|
|
20066
|
-
timeout:
|
|
19818
|
+
await pexec("git", ["-C", cwd, "fetch", "origin", baseBranch, "--no-tags"], {
|
|
19819
|
+
timeout: 3e4
|
|
20067
19820
|
});
|
|
20068
|
-
} catch {
|
|
20069
|
-
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
|
+
);
|
|
20070
19825
|
}
|
|
20071
19826
|
try {
|
|
20072
19827
|
await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${branch}`], {
|
|
@@ -20077,13 +19832,13 @@ async function createWorktree(input) {
|
|
|
20077
19832
|
const msg = err.message;
|
|
20078
19833
|
if (msg.startsWith("\u5206\u652F ")) throw err;
|
|
20079
19834
|
}
|
|
20080
|
-
if (
|
|
19835
|
+
if (import_node_fs17.default.existsSync(worktreeRoot)) {
|
|
20081
19836
|
throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
|
|
20082
19837
|
}
|
|
20083
19838
|
try {
|
|
20084
19839
|
await pexec(
|
|
20085
19840
|
"git",
|
|
20086
|
-
["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, baseBranch],
|
|
19841
|
+
["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, `origin/${baseBranch}`],
|
|
20087
19842
|
{ timeout: 15e3 }
|
|
20088
19843
|
);
|
|
20089
19844
|
} catch (err) {
|
|
@@ -20118,7 +19873,7 @@ async function removeWorktree(input) {
|
|
|
20118
19873
|
} catch (err) {
|
|
20119
19874
|
const stderr = err.stderr ?? "";
|
|
20120
19875
|
const lower = stderr.toLowerCase();
|
|
20121
|
-
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);
|
|
20122
19877
|
if (!vanished) {
|
|
20123
19878
|
throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
|
|
20124
19879
|
}
|
|
@@ -20137,10 +19892,10 @@ async function removeWorktree(input) {
|
|
|
20137
19892
|
try {
|
|
20138
19893
|
const encoded = encodeClaudeProjectDir(worktreeRoot);
|
|
20139
19894
|
if (encoded) {
|
|
20140
|
-
const projectsRoot = import_node_path17.default.join(
|
|
19895
|
+
const projectsRoot = import_node_path17.default.join(import_node_os10.default.homedir(), ".claude", "projects");
|
|
20141
19896
|
const target = import_node_path17.default.resolve(projectsRoot, encoded);
|
|
20142
19897
|
if (target.startsWith(projectsRoot + import_node_path17.default.sep) && target !== projectsRoot) {
|
|
20143
|
-
|
|
19898
|
+
import_node_fs17.default.rmSync(target, { recursive: true, force: true });
|
|
20144
19899
|
}
|
|
20145
19900
|
}
|
|
20146
19901
|
} catch {
|
|
@@ -20212,7 +19967,7 @@ function buildCapabilitiesHandlers(deps) {
|
|
|
20212
19967
|
}
|
|
20213
19968
|
|
|
20214
19969
|
// src/handlers/meta.ts
|
|
20215
|
-
var
|
|
19970
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
20216
19971
|
init_protocol();
|
|
20217
19972
|
|
|
20218
19973
|
// src/version.ts
|
|
@@ -20234,7 +19989,7 @@ function buildReadyFrame(deps) {
|
|
|
20234
19989
|
return {
|
|
20235
19990
|
version,
|
|
20236
19991
|
protocolVersion: PROTOCOL_VERSION,
|
|
20237
|
-
hostname:
|
|
19992
|
+
hostname: import_node_os11.default.hostname(),
|
|
20238
19993
|
os: process.platform,
|
|
20239
19994
|
tools,
|
|
20240
19995
|
runningSessions: info.runningSessions,
|
|
@@ -20385,7 +20140,6 @@ async function startDaemon(config) {
|
|
|
20385
20140
|
const store = new SessionStore({ dataDir: config.dataDir });
|
|
20386
20141
|
const workspace = new WorkspaceBrowser();
|
|
20387
20142
|
const skills = new SkillsScanner();
|
|
20388
|
-
const agents = new AgentsScanner();
|
|
20389
20143
|
const history = new ClaudeHistoryReader();
|
|
20390
20144
|
let transport = null;
|
|
20391
20145
|
const manager = new SessionManager({
|
|
@@ -20446,7 +20200,6 @@ async function startDaemon(config) {
|
|
|
20446
20200
|
manager,
|
|
20447
20201
|
workspace,
|
|
20448
20202
|
skills,
|
|
20449
|
-
agents,
|
|
20450
20203
|
history,
|
|
20451
20204
|
observer,
|
|
20452
20205
|
getAdapter,
|
|
@@ -20582,7 +20335,7 @@ ${bar}
|
|
|
20582
20335
|
`);
|
|
20583
20336
|
try {
|
|
20584
20337
|
const connectPath = import_node_path18.default.join(config.dataDir, "connect.txt");
|
|
20585
|
-
|
|
20338
|
+
import_node_fs18.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
20586
20339
|
} catch {
|
|
20587
20340
|
}
|
|
20588
20341
|
} catch (err) {
|