@clawos-dev/clawd 0.2.134-beta.278.7c624cd → 0.2.135-beta.280.568890f
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 +1173 -414
- package/dist/persona-defaults/persona-developer/CLAUDE.md +0 -13
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -4508,6 +4508,9 @@ var init_persona_schemas = __esm({
|
|
|
4508
4508
|
// 8-key set defined UI-side in `lib/session-icons.ts`; protocol stays plain string
|
|
4509
4509
|
// for forward compatibility, consumer fallbacks to default when key not found.
|
|
4510
4510
|
iconKey: external_exports.string().optional(),
|
|
4511
|
+
// 绑定的 agent tool('claude' / 'codex');缺省消费侧按 'claude' 兜底。
|
|
4512
|
+
// 与 model 平行:persona 新建 session 的默认 tool,可平滑切换。
|
|
4513
|
+
tool: external_exports.string().optional(),
|
|
4511
4514
|
createdAt: external_exports.number(),
|
|
4512
4515
|
updatedAt: external_exports.number()
|
|
4513
4516
|
}).strict();
|
|
@@ -4558,6 +4561,7 @@ var init_persona_schemas = __esm({
|
|
|
4558
4561
|
label: external_exports.string().min(1),
|
|
4559
4562
|
personality: external_exports.string(),
|
|
4560
4563
|
model: external_exports.string().optional(),
|
|
4564
|
+
tool: external_exports.string().optional(),
|
|
4561
4565
|
public: external_exports.boolean().optional(),
|
|
4562
4566
|
iconKey: external_exports.string().optional()
|
|
4563
4567
|
}).strict();
|
|
@@ -4569,6 +4573,7 @@ var init_persona_schemas = __esm({
|
|
|
4569
4573
|
patch: external_exports.object({
|
|
4570
4574
|
label: external_exports.string().min(1).optional(),
|
|
4571
4575
|
model: external_exports.string().optional(),
|
|
4576
|
+
tool: external_exports.string().optional(),
|
|
4572
4577
|
personality: external_exports.string().optional(),
|
|
4573
4578
|
public: external_exports.boolean().optional(),
|
|
4574
4579
|
// pass `null` to clear; daemon strips the field from PersonaFile on null
|
|
@@ -4579,7 +4584,7 @@ var init_persona_schemas = __esm({
|
|
|
4579
4584
|
});
|
|
4580
4585
|
|
|
4581
4586
|
// ../protocol/src/schemas.ts
|
|
4582
|
-
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelReadyEventSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema, PROJECT_PORT_MIN, PROJECT_PORT_MAX, projectNameRegex, DEFAULT_DEV_COMMAND, ProjectMetadataSchema, PROJECT_STAGE_VALUES, ProjectStageSchema, ProjectWithStatusSchema, ListProjectsArgsSchema, ListProjectsResultSchema, GetProjectArgsSchema, GetProjectResultSchema, CreateProjectArgsSchema, CreateProjectResultSchema, DeleteProjectArgsSchema, DeleteProjectResultSchema, UpdateProjectPortArgsSchema, UpdateProjectPortResultSchema, SetProdUrlArgsSchema, SetProdUrlResultSchema, StartDevServerArgsSchema, StartDevServerResultSchema, ASSISTANT_REPORTABLE_STAGES, ReportStageArgsSchema, ReportStageResultSchema, StopDevServerArgsSchema, StopDevServerResultSchema, AppBuilderProjectUpdatedEventSchema, PublishArgsSchema, PublishResultSchema, DismissPublishJobArgsSchema, DismissPublishJobResultSchema, AppBuilderPublishProgressEventSchema, AppBuilderPublishFailedEventSchema;
|
|
4587
|
+
var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelReadyEventSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema, PROJECT_PORT_MIN, PROJECT_PORT_MAX, projectNameRegex, DEFAULT_DEV_COMMAND, ProjectMetadataSchema, PROJECT_STAGE_VALUES, ProjectStageSchema, ProjectWithStatusSchema, ListProjectsArgsSchema, ListProjectsResultSchema, GetProjectArgsSchema, GetProjectResultSchema, CreateProjectArgsSchema, CreateProjectResultSchema, DeleteProjectArgsSchema, DeleteProjectResultSchema, UpdateProjectPortArgsSchema, UpdateProjectPortResultSchema, SetProdUrlArgsSchema, SetProdUrlResultSchema, StartDevServerArgsSchema, StartDevServerResultSchema, ASSISTANT_REPORTABLE_STAGES, ReportStageArgsSchema, ReportStageResultSchema, StopDevServerArgsSchema, StopDevServerResultSchema, AppBuilderProjectUpdatedEventSchema, PublishArgsSchema, PublishResultSchema, DismissPublishJobArgsSchema, DismissPublishJobResultSchema, AppBuilderPublishProgressEventSchema, AppBuilderPublishFailedEventSchema;
|
|
4583
4588
|
var init_schemas = __esm({
|
|
4584
4589
|
"../protocol/src/schemas.ts"() {
|
|
4585
4590
|
"use strict";
|
|
@@ -4637,12 +4642,23 @@ var init_schemas = __esm({
|
|
|
4637
4642
|
CapabilitiesGetArgs = external_exports.object({
|
|
4638
4643
|
tool: external_exports.string().min(1)
|
|
4639
4644
|
});
|
|
4645
|
+
ToolFeaturesSchema = external_exports.object({
|
|
4646
|
+
rewind: external_exports.boolean(),
|
|
4647
|
+
subagents: external_exports.boolean(),
|
|
4648
|
+
tui: external_exports.boolean(),
|
|
4649
|
+
observe: external_exports.boolean(),
|
|
4650
|
+
fileSharing: external_exports.boolean(),
|
|
4651
|
+
// fork:session:fork 走 forkSession(claude jsonl 专用,派生新 jsonl)。codex 无 claude jsonl
|
|
4652
|
+
// → fork 不可用。UI 据此 gate assistant 消息上的 fork 按钮(codex 一轮多条消息会刷出一堆按钮且点了报错)。
|
|
4653
|
+
fork: external_exports.boolean()
|
|
4654
|
+
});
|
|
4640
4655
|
CapabilitiesResponseSchema = external_exports.object({
|
|
4641
4656
|
tool: external_exports.string().min(1),
|
|
4642
4657
|
toolSessionIdLabel: external_exports.string().optional(),
|
|
4643
4658
|
models: external_exports.array(ModelInfoSchema),
|
|
4644
4659
|
permissionModes: external_exports.array(ModeInfoSchema),
|
|
4645
|
-
configSchema: external_exports.array(ConfigFieldSchemaSchema)
|
|
4660
|
+
configSchema: external_exports.array(ConfigFieldSchemaSchema),
|
|
4661
|
+
features: ToolFeaturesSchema
|
|
4646
4662
|
});
|
|
4647
4663
|
AllowRuleSchema = external_exports.object({
|
|
4648
4664
|
tool: external_exports.string().min(1),
|
|
@@ -5034,7 +5050,11 @@ var init_schemas = __esm({
|
|
|
5034
5050
|
});
|
|
5035
5051
|
PermissionRespondArgs = external_exports.object({
|
|
5036
5052
|
sessionId: external_exports.string().min(1),
|
|
5037
|
-
requestId
|
|
5053
|
+
// 权限请求 id 用 `permissionRequestId`,**不能**叫 `requestId`:WS 传输层用帧顶层的
|
|
5054
|
+
// `requestId` 做 RPC 请求/响应关联(daemon-client 发帧时 `{...args, type, requestId}`,
|
|
5055
|
+
// 传输 id 在最后会覆盖 args 同名字段)。若沿用 `requestId`,权限 id 会被传输 id(如 "r61")
|
|
5056
|
+
// 覆盖,daemon 查 pendingPermissions 永远 miss → 点了允许一直卡住。
|
|
5057
|
+
permissionRequestId: external_exports.string().min(1),
|
|
5038
5058
|
allow: external_exports.boolean(),
|
|
5039
5059
|
permanent: external_exports.boolean().optional(),
|
|
5040
5060
|
pattern: external_exports.string().optional()
|
|
@@ -5065,7 +5085,7 @@ var init_schemas = __esm({
|
|
|
5065
5085
|
cwd: external_exports.string().min(1),
|
|
5066
5086
|
path: external_exports.string().min(1)
|
|
5067
5087
|
});
|
|
5068
|
-
SkillsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
|
|
5088
|
+
SkillsListArgs = external_exports.object({ cwd: external_exports.string().min(1), tool: external_exports.string().optional() });
|
|
5069
5089
|
SkillEntrySchema = external_exports.object({
|
|
5070
5090
|
name: external_exports.string().min(1),
|
|
5071
5091
|
source: external_exports.enum(SKILL_SOURCE_VALUES),
|
|
@@ -5081,7 +5101,7 @@ var init_schemas = __esm({
|
|
|
5081
5101
|
whenToUse: external_exports.string().optional(),
|
|
5082
5102
|
plugin: external_exports.string().optional()
|
|
5083
5103
|
});
|
|
5084
|
-
AgentsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
|
|
5104
|
+
AgentsListArgs = external_exports.object({ cwd: external_exports.string().min(1), tool: external_exports.string().optional() });
|
|
5085
5105
|
AgentsListResponseSchema = external_exports.object({
|
|
5086
5106
|
agents: external_exports.array(AgentEntrySchema)
|
|
5087
5107
|
});
|
|
@@ -6842,10 +6862,10 @@ var require_redaction = __commonJS({
|
|
|
6842
6862
|
var strict = false;
|
|
6843
6863
|
function redaction(opts, serialize) {
|
|
6844
6864
|
const { paths, censor, remove } = handle(opts);
|
|
6845
|
-
const shape = paths.reduce((o,
|
|
6865
|
+
const shape = paths.reduce((o, str4) => {
|
|
6846
6866
|
rx.lastIndex = 0;
|
|
6847
|
-
const first = rx.exec(
|
|
6848
|
-
const next = rx.exec(
|
|
6867
|
+
const first = rx.exec(str4);
|
|
6868
|
+
const next = rx.exec(str4);
|
|
6849
6869
|
let ns = first[1] !== void 0 ? first[1].replace(/^(?:"|'|`)(.*)(?:"|'|`)$/, "$1") : first[0];
|
|
6850
6870
|
if (ns === "*") {
|
|
6851
6871
|
ns = wildcardFirstSym;
|
|
@@ -6858,7 +6878,7 @@ var require_redaction = __commonJS({
|
|
|
6858
6878
|
return o;
|
|
6859
6879
|
}
|
|
6860
6880
|
const { index } = next;
|
|
6861
|
-
const nextPath = `${
|
|
6881
|
+
const nextPath = `${str4.substr(index, str4.length - 1)}`;
|
|
6862
6882
|
o[ns] = o[ns] || [];
|
|
6863
6883
|
if (ns !== wildcardFirstSym && o[ns].length === 0) {
|
|
6864
6884
|
o[ns].push(...o[wildcardFirstSym] || []);
|
|
@@ -6974,7 +6994,7 @@ var require_quick_format_unescaped = __commonJS({
|
|
|
6974
6994
|
}
|
|
6975
6995
|
var argLen = args.length;
|
|
6976
6996
|
if (argLen === 0) return f;
|
|
6977
|
-
var
|
|
6997
|
+
var str4 = "";
|
|
6978
6998
|
var a = 1 - offset;
|
|
6979
6999
|
var lastPos = -1;
|
|
6980
7000
|
var flen = f && f.length || 0;
|
|
@@ -6989,8 +7009,8 @@ var require_quick_format_unescaped = __commonJS({
|
|
|
6989
7009
|
break;
|
|
6990
7010
|
if (args[a] == null) break;
|
|
6991
7011
|
if (lastPos < i)
|
|
6992
|
-
|
|
6993
|
-
|
|
7012
|
+
str4 += f.slice(lastPos, i);
|
|
7013
|
+
str4 += Number(args[a]);
|
|
6994
7014
|
lastPos = i + 2;
|
|
6995
7015
|
i++;
|
|
6996
7016
|
break;
|
|
@@ -6999,8 +7019,8 @@ var require_quick_format_unescaped = __commonJS({
|
|
|
6999
7019
|
break;
|
|
7000
7020
|
if (args[a] == null) break;
|
|
7001
7021
|
if (lastPos < i)
|
|
7002
|
-
|
|
7003
|
-
|
|
7022
|
+
str4 += f.slice(lastPos, i);
|
|
7023
|
+
str4 += Math.floor(Number(args[a]));
|
|
7004
7024
|
lastPos = i + 2;
|
|
7005
7025
|
i++;
|
|
7006
7026
|
break;
|
|
@@ -7013,21 +7033,21 @@ var require_quick_format_unescaped = __commonJS({
|
|
|
7013
7033
|
break;
|
|
7014
7034
|
if (args[a] === void 0) break;
|
|
7015
7035
|
if (lastPos < i)
|
|
7016
|
-
|
|
7036
|
+
str4 += f.slice(lastPos, i);
|
|
7017
7037
|
var type = typeof args[a];
|
|
7018
7038
|
if (type === "string") {
|
|
7019
|
-
|
|
7039
|
+
str4 += "'" + args[a] + "'";
|
|
7020
7040
|
lastPos = i + 2;
|
|
7021
7041
|
i++;
|
|
7022
7042
|
break;
|
|
7023
7043
|
}
|
|
7024
7044
|
if (type === "function") {
|
|
7025
|
-
|
|
7045
|
+
str4 += args[a].name || "<anonymous>";
|
|
7026
7046
|
lastPos = i + 2;
|
|
7027
7047
|
i++;
|
|
7028
7048
|
break;
|
|
7029
7049
|
}
|
|
7030
|
-
|
|
7050
|
+
str4 += ss(args[a]);
|
|
7031
7051
|
lastPos = i + 2;
|
|
7032
7052
|
i++;
|
|
7033
7053
|
break;
|
|
@@ -7035,15 +7055,15 @@ var require_quick_format_unescaped = __commonJS({
|
|
|
7035
7055
|
if (a >= argLen)
|
|
7036
7056
|
break;
|
|
7037
7057
|
if (lastPos < i)
|
|
7038
|
-
|
|
7039
|
-
|
|
7058
|
+
str4 += f.slice(lastPos, i);
|
|
7059
|
+
str4 += String(args[a]);
|
|
7040
7060
|
lastPos = i + 2;
|
|
7041
7061
|
i++;
|
|
7042
7062
|
break;
|
|
7043
7063
|
case 37:
|
|
7044
7064
|
if (lastPos < i)
|
|
7045
|
-
|
|
7046
|
-
|
|
7065
|
+
str4 += f.slice(lastPos, i);
|
|
7066
|
+
str4 += "%";
|
|
7047
7067
|
lastPos = i + 2;
|
|
7048
7068
|
i++;
|
|
7049
7069
|
a--;
|
|
@@ -7056,9 +7076,9 @@ var require_quick_format_unescaped = __commonJS({
|
|
|
7056
7076
|
if (lastPos === -1)
|
|
7057
7077
|
return f;
|
|
7058
7078
|
else if (lastPos < flen) {
|
|
7059
|
-
|
|
7079
|
+
str4 += f.slice(lastPos);
|
|
7060
7080
|
}
|
|
7061
|
-
return
|
|
7081
|
+
return str4;
|
|
7062
7082
|
}
|
|
7063
7083
|
}
|
|
7064
7084
|
});
|
|
@@ -7102,7 +7122,7 @@ var require_atomic_sleep = __commonJS({
|
|
|
7102
7122
|
var require_sonic_boom = __commonJS({
|
|
7103
7123
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
7104
7124
|
"use strict";
|
|
7105
|
-
var
|
|
7125
|
+
var fs51 = require("fs");
|
|
7106
7126
|
var EventEmitter3 = require("events");
|
|
7107
7127
|
var inherits = require("util").inherits;
|
|
7108
7128
|
var path59 = require("path");
|
|
@@ -7159,20 +7179,20 @@ var require_sonic_boom = __commonJS({
|
|
|
7159
7179
|
const mode = sonic.mode;
|
|
7160
7180
|
if (sonic.sync) {
|
|
7161
7181
|
try {
|
|
7162
|
-
if (sonic.mkdir)
|
|
7163
|
-
const fd =
|
|
7182
|
+
if (sonic.mkdir) fs51.mkdirSync(path59.dirname(file), { recursive: true });
|
|
7183
|
+
const fd = fs51.openSync(file, flags, mode);
|
|
7164
7184
|
fileOpened(null, fd);
|
|
7165
7185
|
} catch (err) {
|
|
7166
7186
|
fileOpened(err);
|
|
7167
7187
|
throw err;
|
|
7168
7188
|
}
|
|
7169
7189
|
} else if (sonic.mkdir) {
|
|
7170
|
-
|
|
7190
|
+
fs51.mkdir(path59.dirname(file), { recursive: true }, (err) => {
|
|
7171
7191
|
if (err) return fileOpened(err);
|
|
7172
|
-
|
|
7192
|
+
fs51.open(file, flags, mode, fileOpened);
|
|
7173
7193
|
});
|
|
7174
7194
|
} else {
|
|
7175
|
-
|
|
7195
|
+
fs51.open(file, flags, mode, fileOpened);
|
|
7176
7196
|
}
|
|
7177
7197
|
}
|
|
7178
7198
|
function SonicBoom(opts) {
|
|
@@ -7213,8 +7233,8 @@ var require_sonic_boom = __commonJS({
|
|
|
7213
7233
|
this.flush = flushBuffer;
|
|
7214
7234
|
this.flushSync = flushBufferSync;
|
|
7215
7235
|
this._actualWrite = actualWriteBuffer;
|
|
7216
|
-
fsWriteSync = () =>
|
|
7217
|
-
fsWrite = () =>
|
|
7236
|
+
fsWriteSync = () => fs51.writeSync(this.fd, this._writingBuf);
|
|
7237
|
+
fsWrite = () => fs51.write(this.fd, this._writingBuf, this.release);
|
|
7218
7238
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
7219
7239
|
this._writingBuf = "";
|
|
7220
7240
|
this.write = write;
|
|
@@ -7223,15 +7243,15 @@ var require_sonic_boom = __commonJS({
|
|
|
7223
7243
|
this._actualWrite = actualWrite;
|
|
7224
7244
|
fsWriteSync = () => {
|
|
7225
7245
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7226
|
-
return
|
|
7246
|
+
return fs51.writeSync(this.fd, this._writingBuf);
|
|
7227
7247
|
}
|
|
7228
|
-
return
|
|
7248
|
+
return fs51.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7229
7249
|
};
|
|
7230
7250
|
fsWrite = () => {
|
|
7231
7251
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7232
|
-
return
|
|
7252
|
+
return fs51.write(this.fd, this._writingBuf, this.release);
|
|
7233
7253
|
}
|
|
7234
|
-
return
|
|
7254
|
+
return fs51.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
7235
7255
|
};
|
|
7236
7256
|
} else {
|
|
7237
7257
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -7288,7 +7308,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7288
7308
|
}
|
|
7289
7309
|
}
|
|
7290
7310
|
if (this._fsync) {
|
|
7291
|
-
|
|
7311
|
+
fs51.fsyncSync(this.fd);
|
|
7292
7312
|
}
|
|
7293
7313
|
const len = this._len;
|
|
7294
7314
|
if (this._reopening) {
|
|
@@ -7402,7 +7422,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7402
7422
|
const onDrain = () => {
|
|
7403
7423
|
if (!this._fsync) {
|
|
7404
7424
|
try {
|
|
7405
|
-
|
|
7425
|
+
fs51.fsync(this.fd, (err) => {
|
|
7406
7426
|
this._flushPending = false;
|
|
7407
7427
|
cb(err);
|
|
7408
7428
|
});
|
|
@@ -7504,7 +7524,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7504
7524
|
const fd = this.fd;
|
|
7505
7525
|
this.once("ready", () => {
|
|
7506
7526
|
if (fd !== this.fd) {
|
|
7507
|
-
|
|
7527
|
+
fs51.close(fd, (err) => {
|
|
7508
7528
|
if (err) {
|
|
7509
7529
|
return this.emit("error", err);
|
|
7510
7530
|
}
|
|
@@ -7553,7 +7573,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7553
7573
|
buf = this._bufs[0];
|
|
7554
7574
|
}
|
|
7555
7575
|
try {
|
|
7556
|
-
const n = Buffer.isBuffer(buf) ?
|
|
7576
|
+
const n = Buffer.isBuffer(buf) ? fs51.writeSync(this.fd, buf) : fs51.writeSync(this.fd, buf, "utf8");
|
|
7557
7577
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
7558
7578
|
buf = releasedBufObj.writingBuf;
|
|
7559
7579
|
this._len = releasedBufObj.len;
|
|
@@ -7569,7 +7589,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7569
7589
|
}
|
|
7570
7590
|
}
|
|
7571
7591
|
try {
|
|
7572
|
-
|
|
7592
|
+
fs51.fsyncSync(this.fd);
|
|
7573
7593
|
} catch {
|
|
7574
7594
|
}
|
|
7575
7595
|
}
|
|
@@ -7590,7 +7610,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7590
7610
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
7591
7611
|
}
|
|
7592
7612
|
try {
|
|
7593
|
-
const n =
|
|
7613
|
+
const n = fs51.writeSync(this.fd, buf);
|
|
7594
7614
|
buf = buf.subarray(n);
|
|
7595
7615
|
this._len = Math.max(this._len - n, 0);
|
|
7596
7616
|
if (buf.length <= 0) {
|
|
@@ -7618,13 +7638,13 @@ var require_sonic_boom = __commonJS({
|
|
|
7618
7638
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
7619
7639
|
if (this.sync) {
|
|
7620
7640
|
try {
|
|
7621
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
7641
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs51.writeSync(this.fd, this._writingBuf) : fs51.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7622
7642
|
release(null, written);
|
|
7623
7643
|
} catch (err) {
|
|
7624
7644
|
release(err);
|
|
7625
7645
|
}
|
|
7626
7646
|
} else {
|
|
7627
|
-
|
|
7647
|
+
fs51.write(this.fd, this._writingBuf, release);
|
|
7628
7648
|
}
|
|
7629
7649
|
}
|
|
7630
7650
|
function actualWriteBuffer() {
|
|
@@ -7633,7 +7653,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7633
7653
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
7634
7654
|
if (this.sync) {
|
|
7635
7655
|
try {
|
|
7636
|
-
const written =
|
|
7656
|
+
const written = fs51.writeSync(this.fd, this._writingBuf);
|
|
7637
7657
|
release(null, written);
|
|
7638
7658
|
} catch (err) {
|
|
7639
7659
|
release(err);
|
|
@@ -7642,7 +7662,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7642
7662
|
if (kCopyBuffer) {
|
|
7643
7663
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
7644
7664
|
}
|
|
7645
|
-
|
|
7665
|
+
fs51.write(this.fd, this._writingBuf, release);
|
|
7646
7666
|
}
|
|
7647
7667
|
}
|
|
7648
7668
|
function actualClose(sonic) {
|
|
@@ -7658,12 +7678,12 @@ var require_sonic_boom = __commonJS({
|
|
|
7658
7678
|
sonic._lens = [];
|
|
7659
7679
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
7660
7680
|
try {
|
|
7661
|
-
|
|
7681
|
+
fs51.fsync(sonic.fd, closeWrapped);
|
|
7662
7682
|
} catch {
|
|
7663
7683
|
}
|
|
7664
7684
|
function closeWrapped() {
|
|
7665
7685
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
7666
|
-
|
|
7686
|
+
fs51.close(sonic.fd, done);
|
|
7667
7687
|
} else {
|
|
7668
7688
|
done();
|
|
7669
7689
|
}
|
|
@@ -8544,38 +8564,38 @@ var require_tools = __commonJS({
|
|
|
8544
8564
|
}
|
|
8545
8565
|
}
|
|
8546
8566
|
}
|
|
8547
|
-
function asString(
|
|
8567
|
+
function asString(str4) {
|
|
8548
8568
|
let result = "";
|
|
8549
8569
|
let last = 0;
|
|
8550
8570
|
let found = false;
|
|
8551
8571
|
let point = 255;
|
|
8552
|
-
const l =
|
|
8572
|
+
const l = str4.length;
|
|
8553
8573
|
if (l > 100) {
|
|
8554
|
-
return JSON.stringify(
|
|
8574
|
+
return JSON.stringify(str4);
|
|
8555
8575
|
}
|
|
8556
8576
|
for (var i = 0; i < l && point >= 32; i++) {
|
|
8557
|
-
point =
|
|
8577
|
+
point = str4.charCodeAt(i);
|
|
8558
8578
|
if (point === 34 || point === 92) {
|
|
8559
|
-
result +=
|
|
8579
|
+
result += str4.slice(last, i) + "\\";
|
|
8560
8580
|
last = i;
|
|
8561
8581
|
found = true;
|
|
8562
8582
|
}
|
|
8563
8583
|
}
|
|
8564
8584
|
if (!found) {
|
|
8565
|
-
result =
|
|
8585
|
+
result = str4;
|
|
8566
8586
|
} else {
|
|
8567
|
-
result +=
|
|
8587
|
+
result += str4.slice(last);
|
|
8568
8588
|
}
|
|
8569
|
-
return point < 32 ? JSON.stringify(
|
|
8589
|
+
return point < 32 ? JSON.stringify(str4) : '"' + result + '"';
|
|
8570
8590
|
}
|
|
8571
|
-
function asJson(obj, msg,
|
|
8591
|
+
function asJson(obj, msg, num3, time) {
|
|
8572
8592
|
if (asJsonChan.hasSubscribers === false) {
|
|
8573
|
-
return _asJson.call(this, obj, msg,
|
|
8593
|
+
return _asJson.call(this, obj, msg, num3, time);
|
|
8574
8594
|
}
|
|
8575
8595
|
const store = { instance: this, arguments };
|
|
8576
|
-
return asJsonChan.traceSync(_asJson, store, this, obj, msg,
|
|
8596
|
+
return asJsonChan.traceSync(_asJson, store, this, obj, msg, num3, time);
|
|
8577
8597
|
}
|
|
8578
|
-
function _asJson(obj, msg,
|
|
8598
|
+
function _asJson(obj, msg, num3, time) {
|
|
8579
8599
|
const stringify2 = this[stringifySym];
|
|
8580
8600
|
const stringifySafe = this[stringifySafeSym];
|
|
8581
8601
|
const stringifiers = this[stringifiersSym];
|
|
@@ -8585,7 +8605,7 @@ var require_tools = __commonJS({
|
|
|
8585
8605
|
const formatters = this[formattersSym];
|
|
8586
8606
|
const messageKey = this[messageKeySym];
|
|
8587
8607
|
const errorKey = this[errorKeySym];
|
|
8588
|
-
let data = this[lsCacheSym][
|
|
8608
|
+
let data = this[lsCacheSym][num3] + time;
|
|
8589
8609
|
data = data + chindings;
|
|
8590
8610
|
let value;
|
|
8591
8611
|
if (formatters.log) {
|
|
@@ -9212,7 +9232,7 @@ var require_proto = __commonJS({
|
|
|
9212
9232
|
function defaultMixinMergeStrategy(mergeObject, mixinObject) {
|
|
9213
9233
|
return Object.assign(mixinObject, mergeObject);
|
|
9214
9234
|
}
|
|
9215
|
-
function write(_obj, msg,
|
|
9235
|
+
function write(_obj, msg, num3) {
|
|
9216
9236
|
const t = this[timeSym]();
|
|
9217
9237
|
const mixin = this[mixinSym];
|
|
9218
9238
|
const errorKey = this[errorKeySym];
|
|
@@ -9234,12 +9254,12 @@ var require_proto = __commonJS({
|
|
|
9234
9254
|
}
|
|
9235
9255
|
}
|
|
9236
9256
|
if (mixin) {
|
|
9237
|
-
obj = mixinMergeStrategy(obj, mixin(obj,
|
|
9257
|
+
obj = mixinMergeStrategy(obj, mixin(obj, num3, this));
|
|
9238
9258
|
}
|
|
9239
|
-
const s = this[asJsonSym](obj, msg,
|
|
9259
|
+
const s = this[asJsonSym](obj, msg, num3, t);
|
|
9240
9260
|
const stream = this[streamSym];
|
|
9241
9261
|
if (stream[needsMetadataGsym] === true) {
|
|
9242
|
-
stream.lastLevel =
|
|
9262
|
+
stream.lastLevel = num3;
|
|
9243
9263
|
stream.lastObj = obj;
|
|
9244
9264
|
stream.lastMsg = msg;
|
|
9245
9265
|
stream.lastTime = t.slice(this[timeSliceIndexSym]);
|
|
@@ -9272,11 +9292,11 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
9272
9292
|
exports2.configure = configure;
|
|
9273
9293
|
module2.exports = stringify;
|
|
9274
9294
|
var strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;
|
|
9275
|
-
function strEscape(
|
|
9276
|
-
if (
|
|
9277
|
-
return `"${
|
|
9295
|
+
function strEscape(str4) {
|
|
9296
|
+
if (str4.length < 5e3 && !strEscapeSequencesRegExp.test(str4)) {
|
|
9297
|
+
return `"${str4}"`;
|
|
9278
9298
|
}
|
|
9279
|
-
return JSON.stringify(
|
|
9299
|
+
return JSON.stringify(str4);
|
|
9280
9300
|
}
|
|
9281
9301
|
function sort(array, comparator) {
|
|
9282
9302
|
if (array.length > 200 || comparator) {
|
|
@@ -10233,6 +10253,23 @@ var require_pino = __commonJS({
|
|
|
10233
10253
|
}
|
|
10234
10254
|
});
|
|
10235
10255
|
|
|
10256
|
+
// src/session/stdout-splitter.ts
|
|
10257
|
+
function splitStdoutChunk(buf, chunk) {
|
|
10258
|
+
let next = buf + (typeof chunk === "string" ? chunk : chunk.toString("utf8"));
|
|
10259
|
+
const lines = [];
|
|
10260
|
+
let idx;
|
|
10261
|
+
while ((idx = next.indexOf("\n")) >= 0) {
|
|
10262
|
+
lines.push(next.slice(0, idx));
|
|
10263
|
+
next = next.slice(idx + 1);
|
|
10264
|
+
}
|
|
10265
|
+
return { newBuf: next, lines };
|
|
10266
|
+
}
|
|
10267
|
+
var init_stdout_splitter = __esm({
|
|
10268
|
+
"src/session/stdout-splitter.ts"() {
|
|
10269
|
+
"use strict";
|
|
10270
|
+
}
|
|
10271
|
+
});
|
|
10272
|
+
|
|
10236
10273
|
// src/session/permission-stdio.ts
|
|
10237
10274
|
function encodePermissionResponse(requestId, approved, input, message) {
|
|
10238
10275
|
const innerResponse = approved ? {
|
|
@@ -10255,23 +10292,6 @@ var init_permission_stdio = __esm({
|
|
|
10255
10292
|
}
|
|
10256
10293
|
});
|
|
10257
10294
|
|
|
10258
|
-
// src/session/stdout-splitter.ts
|
|
10259
|
-
function splitStdoutChunk(buf, chunk) {
|
|
10260
|
-
let next = buf + (typeof chunk === "string" ? chunk : chunk.toString("utf8"));
|
|
10261
|
-
const lines = [];
|
|
10262
|
-
let idx;
|
|
10263
|
-
while ((idx = next.indexOf("\n")) >= 0) {
|
|
10264
|
-
lines.push(next.slice(0, idx));
|
|
10265
|
-
next = next.slice(idx + 1);
|
|
10266
|
-
}
|
|
10267
|
-
return { newBuf: next, lines };
|
|
10268
|
-
}
|
|
10269
|
-
var init_stdout_splitter = __esm({
|
|
10270
|
-
"src/session/stdout-splitter.ts"() {
|
|
10271
|
-
"use strict";
|
|
10272
|
-
}
|
|
10273
|
-
});
|
|
10274
|
-
|
|
10275
10295
|
// ../node_modules/.pnpm/diff@7.0.0/node_modules/diff/lib/index.mjs
|
|
10276
10296
|
function Diff() {
|
|
10277
10297
|
}
|
|
@@ -10310,22 +10330,22 @@ function buildValues(diff2, lastComponent, newString, oldString, useLongestToken
|
|
|
10310
10330
|
}
|
|
10311
10331
|
return components;
|
|
10312
10332
|
}
|
|
10313
|
-
function longestCommonPrefix(str1,
|
|
10333
|
+
function longestCommonPrefix(str1, str22) {
|
|
10314
10334
|
var i;
|
|
10315
|
-
for (i = 0; i < str1.length && i <
|
|
10316
|
-
if (str1[i] !=
|
|
10335
|
+
for (i = 0; i < str1.length && i < str22.length; i++) {
|
|
10336
|
+
if (str1[i] != str22[i]) {
|
|
10317
10337
|
return str1.slice(0, i);
|
|
10318
10338
|
}
|
|
10319
10339
|
}
|
|
10320
10340
|
return str1.slice(0, i);
|
|
10321
10341
|
}
|
|
10322
|
-
function longestCommonSuffix(str1,
|
|
10342
|
+
function longestCommonSuffix(str1, str22) {
|
|
10323
10343
|
var i;
|
|
10324
|
-
if (!str1 || !
|
|
10344
|
+
if (!str1 || !str22 || str1[str1.length - 1] != str22[str22.length - 1]) {
|
|
10325
10345
|
return "";
|
|
10326
10346
|
}
|
|
10327
|
-
for (i = 0; i < str1.length && i <
|
|
10328
|
-
if (str1[str1.length - (i + 1)] !=
|
|
10347
|
+
for (i = 0; i < str1.length && i < str22.length; i++) {
|
|
10348
|
+
if (str1[str1.length - (i + 1)] != str22[str22.length - (i + 1)]) {
|
|
10329
10349
|
return str1.slice(-i);
|
|
10330
10350
|
}
|
|
10331
10351
|
}
|
|
@@ -11257,12 +11277,12 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11257
11277
|
const raw = Array.isArray(a.memories) ? a.memories : [];
|
|
11258
11278
|
const memories = raw.map((m2) => {
|
|
11259
11279
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11260
|
-
const
|
|
11261
|
-
const path59 = typeof
|
|
11262
|
-
const content = typeof
|
|
11280
|
+
const rec3 = m2;
|
|
11281
|
+
const path59 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11282
|
+
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11263
11283
|
if (!path59 || content == null) return null;
|
|
11264
11284
|
const entry = { path: path59, content };
|
|
11265
|
-
if (typeof
|
|
11285
|
+
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11266
11286
|
return entry;
|
|
11267
11287
|
}).filter((m2) => m2 !== null);
|
|
11268
11288
|
if (memories.length === 0) return null;
|
|
@@ -12072,12 +12092,12 @@ function parseAttachment(obj) {
|
|
|
12072
12092
|
const raw = Array.isArray(a.memories) ? a.memories : [];
|
|
12073
12093
|
const memories = raw.map((m2) => {
|
|
12074
12094
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12075
|
-
const
|
|
12076
|
-
const path59 = typeof
|
|
12077
|
-
const content = typeof
|
|
12095
|
+
const rec3 = m2;
|
|
12096
|
+
const path59 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12097
|
+
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12078
12098
|
if (!path59 || content == null) return null;
|
|
12079
12099
|
const out = { path: path59, content };
|
|
12080
|
-
if (typeof
|
|
12100
|
+
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12081
12101
|
return out;
|
|
12082
12102
|
}).filter((m2) => m2 !== null);
|
|
12083
12103
|
if (memories.length === 0) return null;
|
|
@@ -12224,6 +12244,7 @@ var init_claude = __esm({
|
|
|
12224
12244
|
toolSessionIdLabel: "Claude Session ID",
|
|
12225
12245
|
models: CLAUDE_MODELS,
|
|
12226
12246
|
permissionModes: CLAUDE_PERMISSION_MODES,
|
|
12247
|
+
features: { rewind: true, subagents: true, tui: true, observe: true, fileSharing: true, fork: true },
|
|
12227
12248
|
configSchema: [
|
|
12228
12249
|
{
|
|
12229
12250
|
name: "model",
|
|
@@ -17712,26 +17733,26 @@ var require_permessage_deflate = __commonJS({
|
|
|
17712
17733
|
value = value[0];
|
|
17713
17734
|
if (key === "client_max_window_bits") {
|
|
17714
17735
|
if (value !== true) {
|
|
17715
|
-
const
|
|
17716
|
-
if (!Number.isInteger(
|
|
17736
|
+
const num3 = +value;
|
|
17737
|
+
if (!Number.isInteger(num3) || num3 < 8 || num3 > 15) {
|
|
17717
17738
|
throw new TypeError(
|
|
17718
17739
|
`Invalid value for parameter "${key}": ${value}`
|
|
17719
17740
|
);
|
|
17720
17741
|
}
|
|
17721
|
-
value =
|
|
17742
|
+
value = num3;
|
|
17722
17743
|
} else if (!this._isServer) {
|
|
17723
17744
|
throw new TypeError(
|
|
17724
17745
|
`Invalid value for parameter "${key}": ${value}`
|
|
17725
17746
|
);
|
|
17726
17747
|
}
|
|
17727
17748
|
} else if (key === "server_max_window_bits") {
|
|
17728
|
-
const
|
|
17729
|
-
if (!Number.isInteger(
|
|
17749
|
+
const num3 = +value;
|
|
17750
|
+
if (!Number.isInteger(num3) || num3 < 8 || num3 > 15) {
|
|
17730
17751
|
throw new TypeError(
|
|
17731
17752
|
`Invalid value for parameter "${key}": ${value}`
|
|
17732
17753
|
);
|
|
17733
17754
|
}
|
|
17734
|
-
value =
|
|
17755
|
+
value = num3;
|
|
17735
17756
|
} else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
|
|
17736
17757
|
if (value !== true) {
|
|
17737
17758
|
throw new TypeError(
|
|
@@ -18426,8 +18447,8 @@ var require_receiver = __commonJS({
|
|
|
18426
18447
|
return;
|
|
18427
18448
|
}
|
|
18428
18449
|
const buf = this.consume(8);
|
|
18429
|
-
const
|
|
18430
|
-
if (
|
|
18450
|
+
const num3 = buf.readUInt32BE(0);
|
|
18451
|
+
if (num3 > Math.pow(2, 53 - 32) - 1) {
|
|
18431
18452
|
const error = this.createError(
|
|
18432
18453
|
RangeError,
|
|
18433
18454
|
"Unsupported WebSocket frame: payload length > 2^53 - 1",
|
|
@@ -18438,7 +18459,7 @@ var require_receiver = __commonJS({
|
|
|
18438
18459
|
cb(error);
|
|
18439
18460
|
return;
|
|
18440
18461
|
}
|
|
18441
|
-
this._payloadLength =
|
|
18462
|
+
this._payloadLength = num3 * Math.pow(2, 32) + buf.readUInt32BE(4);
|
|
18442
18463
|
this.haveLength(cb);
|
|
18443
18464
|
}
|
|
18444
18465
|
/**
|
|
@@ -22752,19 +22773,19 @@ var require_stream_readable = __commonJS({
|
|
|
22752
22773
|
var ret = p2.data;
|
|
22753
22774
|
n -= ret.length;
|
|
22754
22775
|
while (p2 = p2.next) {
|
|
22755
|
-
var
|
|
22756
|
-
var nb = n >
|
|
22757
|
-
if (nb ===
|
|
22758
|
-
else ret +=
|
|
22776
|
+
var str4 = p2.data;
|
|
22777
|
+
var nb = n > str4.length ? str4.length : n;
|
|
22778
|
+
if (nb === str4.length) ret += str4;
|
|
22779
|
+
else ret += str4.slice(0, n);
|
|
22759
22780
|
n -= nb;
|
|
22760
22781
|
if (n === 0) {
|
|
22761
|
-
if (nb ===
|
|
22782
|
+
if (nb === str4.length) {
|
|
22762
22783
|
++c;
|
|
22763
22784
|
if (p2.next) list.head = p2.next;
|
|
22764
22785
|
else list.head = list.tail = null;
|
|
22765
22786
|
} else {
|
|
22766
22787
|
list.head = p2;
|
|
22767
|
-
p2.data =
|
|
22788
|
+
p2.data = str4.slice(nb);
|
|
22768
22789
|
}
|
|
22769
22790
|
break;
|
|
22770
22791
|
}
|
|
@@ -23660,14 +23681,14 @@ var require_utils = __commonJS({
|
|
|
23660
23681
|
var nodejsUtils = require_nodejsUtils();
|
|
23661
23682
|
var external = require_external();
|
|
23662
23683
|
require_setImmediate();
|
|
23663
|
-
function string2binary(
|
|
23684
|
+
function string2binary(str4) {
|
|
23664
23685
|
var result = null;
|
|
23665
23686
|
if (support.uint8array) {
|
|
23666
|
-
result = new Uint8Array(
|
|
23687
|
+
result = new Uint8Array(str4.length);
|
|
23667
23688
|
} else {
|
|
23668
|
-
result = new Array(
|
|
23689
|
+
result = new Array(str4.length);
|
|
23669
23690
|
}
|
|
23670
|
-
return stringToArrayLike(
|
|
23691
|
+
return stringToArrayLike(str4, result);
|
|
23671
23692
|
}
|
|
23672
23693
|
exports2.newBlob = function(part, type) {
|
|
23673
23694
|
exports2.checkSupport("blob");
|
|
@@ -23689,9 +23710,9 @@ var require_utils = __commonJS({
|
|
|
23689
23710
|
function identity(input) {
|
|
23690
23711
|
return input;
|
|
23691
23712
|
}
|
|
23692
|
-
function stringToArrayLike(
|
|
23693
|
-
for (var i = 0; i <
|
|
23694
|
-
array[i] =
|
|
23713
|
+
function stringToArrayLike(str4, array) {
|
|
23714
|
+
for (var i = 0; i < str4.length; ++i) {
|
|
23715
|
+
array[i] = str4.charCodeAt(i) & 255;
|
|
23695
23716
|
}
|
|
23696
23717
|
return array;
|
|
23697
23718
|
}
|
|
@@ -23904,10 +23925,10 @@ var require_utils = __commonJS({
|
|
|
23904
23925
|
};
|
|
23905
23926
|
exports2.MAX_VALUE_16BITS = 65535;
|
|
23906
23927
|
exports2.MAX_VALUE_32BITS = -1;
|
|
23907
|
-
exports2.pretty = function(
|
|
23928
|
+
exports2.pretty = function(str4) {
|
|
23908
23929
|
var res = "", code, i;
|
|
23909
|
-
for (i = 0; i < (
|
|
23910
|
-
code =
|
|
23930
|
+
for (i = 0; i < (str4 || "").length; i++) {
|
|
23931
|
+
code = str4.charCodeAt(i);
|
|
23911
23932
|
res += "\\x" + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();
|
|
23912
23933
|
}
|
|
23913
23934
|
return res;
|
|
@@ -24217,12 +24238,12 @@ var require_utf8 = __commonJS({
|
|
|
24217
24238
|
}
|
|
24218
24239
|
var i;
|
|
24219
24240
|
_utf8len[254] = _utf8len[254] = 1;
|
|
24220
|
-
var string2buf = function(
|
|
24221
|
-
var buf, c, c2, m_pos, i2, str_len =
|
|
24241
|
+
var string2buf = function(str4) {
|
|
24242
|
+
var buf, c, c2, m_pos, i2, str_len = str4.length, buf_len = 0;
|
|
24222
24243
|
for (m_pos = 0; m_pos < str_len; m_pos++) {
|
|
24223
|
-
c =
|
|
24244
|
+
c = str4.charCodeAt(m_pos);
|
|
24224
24245
|
if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
|
|
24225
|
-
c2 =
|
|
24246
|
+
c2 = str4.charCodeAt(m_pos + 1);
|
|
24226
24247
|
if ((c2 & 64512) === 56320) {
|
|
24227
24248
|
c = 65536 + (c - 55296 << 10) + (c2 - 56320);
|
|
24228
24249
|
m_pos++;
|
|
@@ -24236,9 +24257,9 @@ var require_utf8 = __commonJS({
|
|
|
24236
24257
|
buf = new Array(buf_len);
|
|
24237
24258
|
}
|
|
24238
24259
|
for (i2 = 0, m_pos = 0; i2 < buf_len; m_pos++) {
|
|
24239
|
-
c =
|
|
24260
|
+
c = str4.charCodeAt(m_pos);
|
|
24240
24261
|
if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
|
|
24241
|
-
c2 =
|
|
24262
|
+
c2 = str4.charCodeAt(m_pos + 1);
|
|
24242
24263
|
if ((c2 & 64512) === 56320) {
|
|
24243
24264
|
c = 65536 + (c - 55296 << 10) + (c2 - 56320);
|
|
24244
24265
|
m_pos++;
|
|
@@ -24322,11 +24343,11 @@ var require_utf8 = __commonJS({
|
|
|
24322
24343
|
}
|
|
24323
24344
|
return utils.applyFromCharCode(utf16buf);
|
|
24324
24345
|
};
|
|
24325
|
-
exports2.utf8encode = function utf8encode(
|
|
24346
|
+
exports2.utf8encode = function utf8encode(str4) {
|
|
24326
24347
|
if (support.nodebuffer) {
|
|
24327
|
-
return nodejsUtils.newBufferFrom(
|
|
24348
|
+
return nodejsUtils.newBufferFrom(str4, "utf-8");
|
|
24328
24349
|
}
|
|
24329
|
-
return string2buf(
|
|
24350
|
+
return string2buf(str4);
|
|
24330
24351
|
};
|
|
24331
24352
|
exports2.utf8decode = function utf8decode(buf) {
|
|
24332
24353
|
if (support.nodebuffer) {
|
|
@@ -24735,11 +24756,11 @@ var require_crc32 = __commonJS({
|
|
|
24735
24756
|
}
|
|
24736
24757
|
return crc ^ -1;
|
|
24737
24758
|
}
|
|
24738
|
-
function crc32str(crc,
|
|
24759
|
+
function crc32str(crc, str4, len, pos) {
|
|
24739
24760
|
var t = crcTable, end = pos + len;
|
|
24740
24761
|
crc = crc ^ -1;
|
|
24741
24762
|
for (var i = pos; i < end; i++) {
|
|
24742
|
-
crc = crc >>> 8 ^ t[(crc ^
|
|
24763
|
+
crc = crc >>> 8 ^ t[(crc ^ str4.charCodeAt(i)) & 255];
|
|
24743
24764
|
}
|
|
24744
24765
|
return crc ^ -1;
|
|
24745
24766
|
}
|
|
@@ -25936,7 +25957,7 @@ var require_deflate = __commonJS({
|
|
|
25936
25957
|
}
|
|
25937
25958
|
function fill_window(s) {
|
|
25938
25959
|
var _w_size = s.w_size;
|
|
25939
|
-
var p2, n, m2, more,
|
|
25960
|
+
var p2, n, m2, more, str4;
|
|
25940
25961
|
do {
|
|
25941
25962
|
more = s.window_size - s.lookahead - s.strstart;
|
|
25942
25963
|
if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
|
|
@@ -25964,14 +25985,14 @@ var require_deflate = __commonJS({
|
|
|
25964
25985
|
n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
|
|
25965
25986
|
s.lookahead += n;
|
|
25966
25987
|
if (s.lookahead + s.insert >= MIN_MATCH) {
|
|
25967
|
-
|
|
25968
|
-
s.ins_h = s.window[
|
|
25969
|
-
s.ins_h = (s.ins_h << s.hash_shift ^ s.window[
|
|
25988
|
+
str4 = s.strstart - s.insert;
|
|
25989
|
+
s.ins_h = s.window[str4];
|
|
25990
|
+
s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str4 + 1]) & s.hash_mask;
|
|
25970
25991
|
while (s.insert) {
|
|
25971
|
-
s.ins_h = (s.ins_h << s.hash_shift ^ s.window[
|
|
25972
|
-
s.prev[
|
|
25973
|
-
s.head[s.ins_h] =
|
|
25974
|
-
|
|
25992
|
+
s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str4 + MIN_MATCH - 1]) & s.hash_mask;
|
|
25993
|
+
s.prev[str4 & s.w_mask] = s.head[s.ins_h];
|
|
25994
|
+
s.head[s.ins_h] = str4;
|
|
25995
|
+
str4++;
|
|
25975
25996
|
s.insert--;
|
|
25976
25997
|
if (s.lookahead + s.insert < MIN_MATCH) {
|
|
25977
25998
|
break;
|
|
@@ -26747,7 +26768,7 @@ var require_deflate = __commonJS({
|
|
|
26747
26768
|
function deflateSetDictionary(strm, dictionary) {
|
|
26748
26769
|
var dictLength = dictionary.length;
|
|
26749
26770
|
var s;
|
|
26750
|
-
var
|
|
26771
|
+
var str4, n;
|
|
26751
26772
|
var wrap2;
|
|
26752
26773
|
var avail;
|
|
26753
26774
|
var next;
|
|
@@ -26785,15 +26806,15 @@ var require_deflate = __commonJS({
|
|
|
26785
26806
|
strm.input = dictionary;
|
|
26786
26807
|
fill_window(s);
|
|
26787
26808
|
while (s.lookahead >= MIN_MATCH) {
|
|
26788
|
-
|
|
26809
|
+
str4 = s.strstart;
|
|
26789
26810
|
n = s.lookahead - (MIN_MATCH - 1);
|
|
26790
26811
|
do {
|
|
26791
|
-
s.ins_h = (s.ins_h << s.hash_shift ^ s.window[
|
|
26792
|
-
s.prev[
|
|
26793
|
-
s.head[s.ins_h] =
|
|
26794
|
-
|
|
26812
|
+
s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str4 + MIN_MATCH - 1]) & s.hash_mask;
|
|
26813
|
+
s.prev[str4 & s.w_mask] = s.head[s.ins_h];
|
|
26814
|
+
s.head[s.ins_h] = str4;
|
|
26815
|
+
str4++;
|
|
26795
26816
|
} while (--n);
|
|
26796
|
-
s.strstart =
|
|
26817
|
+
s.strstart = str4;
|
|
26797
26818
|
s.lookahead = MIN_MATCH - 1;
|
|
26798
26819
|
fill_window(s);
|
|
26799
26820
|
}
|
|
@@ -26844,12 +26865,12 @@ var require_strings = __commonJS({
|
|
|
26844
26865
|
}
|
|
26845
26866
|
var q;
|
|
26846
26867
|
_utf8len[254] = _utf8len[254] = 1;
|
|
26847
|
-
exports2.string2buf = function(
|
|
26848
|
-
var buf, c, c2, m_pos, i, str_len =
|
|
26868
|
+
exports2.string2buf = function(str4) {
|
|
26869
|
+
var buf, c, c2, m_pos, i, str_len = str4.length, buf_len = 0;
|
|
26849
26870
|
for (m_pos = 0; m_pos < str_len; m_pos++) {
|
|
26850
|
-
c =
|
|
26871
|
+
c = str4.charCodeAt(m_pos);
|
|
26851
26872
|
if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
|
|
26852
|
-
c2 =
|
|
26873
|
+
c2 = str4.charCodeAt(m_pos + 1);
|
|
26853
26874
|
if ((c2 & 64512) === 56320) {
|
|
26854
26875
|
c = 65536 + (c - 55296 << 10) + (c2 - 56320);
|
|
26855
26876
|
m_pos++;
|
|
@@ -26859,9 +26880,9 @@ var require_strings = __commonJS({
|
|
|
26859
26880
|
}
|
|
26860
26881
|
buf = new utils.Buf8(buf_len);
|
|
26861
26882
|
for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
|
|
26862
|
-
c =
|
|
26883
|
+
c = str4.charCodeAt(m_pos);
|
|
26863
26884
|
if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
|
|
26864
|
-
c2 =
|
|
26885
|
+
c2 = str4.charCodeAt(m_pos + 1);
|
|
26865
26886
|
if ((c2 & 64512) === 56320) {
|
|
26866
26887
|
c = 65536 + (c - 55296 << 10) + (c2 - 56320);
|
|
26867
26888
|
m_pos++;
|
|
@@ -26900,10 +26921,10 @@ var require_strings = __commonJS({
|
|
|
26900
26921
|
exports2.buf2binstring = function(buf) {
|
|
26901
26922
|
return buf2binstring(buf, buf.length);
|
|
26902
26923
|
};
|
|
26903
|
-
exports2.binstring2buf = function(
|
|
26904
|
-
var buf = new utils.Buf8(
|
|
26924
|
+
exports2.binstring2buf = function(str4) {
|
|
26925
|
+
var buf = new utils.Buf8(str4.length);
|
|
26905
26926
|
for (var i = 0, len = buf.length; i < len; i++) {
|
|
26906
|
-
buf[i] =
|
|
26927
|
+
buf[i] = str4.charCodeAt(i);
|
|
26907
26928
|
}
|
|
26908
26929
|
return buf;
|
|
26909
26930
|
};
|
|
@@ -30745,8 +30766,8 @@ function startRunCaseRecorder(opts) {
|
|
|
30745
30766
|
});
|
|
30746
30767
|
const ensureStream = () => {
|
|
30747
30768
|
if (stream) return stream;
|
|
30748
|
-
|
|
30749
|
-
stream =
|
|
30769
|
+
import_node_fs34.default.mkdirSync(dir, { recursive: true });
|
|
30770
|
+
stream = import_node_fs34.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
30750
30771
|
stream.on("close", () => closedResolve());
|
|
30751
30772
|
return stream;
|
|
30752
30773
|
};
|
|
@@ -30771,11 +30792,11 @@ function startRunCaseRecorder(opts) {
|
|
|
30771
30792
|
};
|
|
30772
30793
|
return { tap, close, closed };
|
|
30773
30794
|
}
|
|
30774
|
-
var
|
|
30795
|
+
var import_node_fs34, import_node_path47;
|
|
30775
30796
|
var init_recorder = __esm({
|
|
30776
30797
|
"src/run-case/recorder.ts"() {
|
|
30777
30798
|
"use strict";
|
|
30778
|
-
|
|
30799
|
+
import_node_fs34 = __toESM(require("fs"), 1);
|
|
30779
30800
|
import_node_path47 = __toESM(require("path"), 1);
|
|
30780
30801
|
}
|
|
30781
30802
|
});
|
|
@@ -30819,7 +30840,7 @@ var init_wire = __esm({
|
|
|
30819
30840
|
// src/run-case/controller.ts
|
|
30820
30841
|
async function runController(opts) {
|
|
30821
30842
|
const now = opts.now ?? Date.now;
|
|
30822
|
-
const cwd = opts.cwd ?? (0,
|
|
30843
|
+
const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path48.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
|
|
30823
30844
|
const ownsCwd = opts.cwd === void 0;
|
|
30824
30845
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
30825
30846
|
const spawnCtx = { cwd };
|
|
@@ -30980,17 +31001,17 @@ async function runController(opts) {
|
|
|
30980
31001
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
30981
31002
|
if (ownsCwd) {
|
|
30982
31003
|
try {
|
|
30983
|
-
(0,
|
|
31004
|
+
(0, import_node_fs35.rmSync)(cwd, { recursive: true, force: true });
|
|
30984
31005
|
} catch {
|
|
30985
31006
|
}
|
|
30986
31007
|
}
|
|
30987
31008
|
return exitCode ?? 0;
|
|
30988
31009
|
}
|
|
30989
|
-
var
|
|
31010
|
+
var import_node_fs35, import_node_os19, import_node_path48;
|
|
30990
31011
|
var init_controller = __esm({
|
|
30991
31012
|
"src/run-case/controller.ts"() {
|
|
30992
31013
|
"use strict";
|
|
30993
|
-
|
|
31014
|
+
import_node_fs35 = require("fs");
|
|
30994
31015
|
import_node_os19 = __toESM(require("os"), 1);
|
|
30995
31016
|
import_node_path48 = __toESM(require("path"), 1);
|
|
30996
31017
|
init_claude();
|
|
@@ -31228,7 +31249,7 @@ Env (advanced):
|
|
|
31228
31249
|
|
|
31229
31250
|
// src/index.ts
|
|
31230
31251
|
var import_node_path46 = __toESM(require("path"), 1);
|
|
31231
|
-
var
|
|
31252
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
31232
31253
|
|
|
31233
31254
|
// src/logger.ts
|
|
31234
31255
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
@@ -31625,9 +31646,6 @@ function buildRule(tool, input) {
|
|
|
31625
31646
|
return { tool, pattern, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
31626
31647
|
}
|
|
31627
31648
|
|
|
31628
|
-
// src/session/reducer.ts
|
|
31629
|
-
init_permission_stdio();
|
|
31630
|
-
|
|
31631
31649
|
// src/persona/connection-prompt.ts
|
|
31632
31650
|
var OWNER_TEMPLATE = `# \u8FDE\u63A5\u4E0A\u4E0B\u6587
|
|
31633
31651
|
\u4F60\u73B0\u5728\u4EE5 Owner \u8EAB\u4EFD\u88AB\u8FDE\u63A5\uFF0C\u5BF9\u65B9\u5C31\u662F owner \u672C\u4EBA\uFF08{ownerLabel}\uFF09\u3002
|
|
@@ -31749,6 +31767,9 @@ function buildSpawnContext(state, deps) {
|
|
|
31749
31767
|
if (meta?.addDirs && meta.addDirs.length > 0) {
|
|
31750
31768
|
ctx.addDirs = meta.addDirs;
|
|
31751
31769
|
}
|
|
31770
|
+
if (meta?.networkAccess !== void 0) {
|
|
31771
|
+
ctx.networkAccess = meta.networkAccess;
|
|
31772
|
+
}
|
|
31752
31773
|
return ctx;
|
|
31753
31774
|
}
|
|
31754
31775
|
function sessionInfoFrame(file) {
|
|
@@ -31814,10 +31835,7 @@ function applyParsedEvent(state, event, deps) {
|
|
|
31814
31835
|
effects.push(...pushed2.effects);
|
|
31815
31836
|
const hit = matchesAnyRule(next.file.permissionRules, tool, input);
|
|
31816
31837
|
if (hit) {
|
|
31817
|
-
effects.push({
|
|
31818
|
-
kind: "write-stdin",
|
|
31819
|
-
payload: encodePermissionResponse(requestId, true, input)
|
|
31820
|
-
});
|
|
31838
|
+
effects.push({ kind: "respond-permission", requestId, allow: true, input });
|
|
31821
31839
|
} else {
|
|
31822
31840
|
const pending = {
|
|
31823
31841
|
tool,
|
|
@@ -32210,13 +32228,11 @@ function reduceSession(state, input, deps) {
|
|
|
32210
32228
|
next.pendingPermissions = nextPending;
|
|
32211
32229
|
const effects = [
|
|
32212
32230
|
{
|
|
32213
|
-
kind: "
|
|
32214
|
-
|
|
32215
|
-
|
|
32216
|
-
|
|
32217
|
-
|
|
32218
|
-
input.message
|
|
32219
|
-
)
|
|
32231
|
+
kind: "respond-permission",
|
|
32232
|
+
requestId: input.requestId,
|
|
32233
|
+
allow: input.allow,
|
|
32234
|
+
input: pending.input,
|
|
32235
|
+
message: input.message
|
|
32220
32236
|
}
|
|
32221
32237
|
];
|
|
32222
32238
|
if (input.allow && input.permanent) {
|
|
@@ -32356,6 +32372,7 @@ function reduceSession(state, input, deps) {
|
|
|
32356
32372
|
|
|
32357
32373
|
// src/session/runner.ts
|
|
32358
32374
|
init_stdout_splitter();
|
|
32375
|
+
init_permission_stdio();
|
|
32359
32376
|
|
|
32360
32377
|
// src/ipc-recorder.ts
|
|
32361
32378
|
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
@@ -32463,6 +32480,9 @@ var SessionRunner = class {
|
|
|
32463
32480
|
hooks;
|
|
32464
32481
|
state;
|
|
32465
32482
|
proc = null;
|
|
32483
|
+
// JSON-RPC 类 agent(codex app-server) 的 per-session 驱动器;非 null 时 runner 不用 spawn()/ChildProcess,
|
|
32484
|
+
// effect 路由到 session 一等方法(startTurn/respondPermission/answerQuestion/interrupt/stop)。claude 恒 null。
|
|
32485
|
+
session = null;
|
|
32466
32486
|
stdoutBuf = "";
|
|
32467
32487
|
// 未决 control_request 表;key = request_id
|
|
32468
32488
|
pendingControlRequests = /* @__PURE__ */ new Map();
|
|
@@ -32571,6 +32591,15 @@ var SessionRunner = class {
|
|
|
32571
32591
|
if (this.hooks.onFileEdit) this.observeForFileEdit(events);
|
|
32572
32592
|
this.input({ kind: "inject-events", events });
|
|
32573
32593
|
}
|
|
32594
|
+
// session:interrupt 的 SDK 通道分流:codex → AgentSession.interrupt();claude → control_request('interrupt')。
|
|
32595
|
+
// TUI(pty) 路径在 manager.dispatchInterrupt 里先于此处理,不进这里。
|
|
32596
|
+
async interrupt() {
|
|
32597
|
+
if (this.session) {
|
|
32598
|
+
this.session.interrupt();
|
|
32599
|
+
return;
|
|
32600
|
+
}
|
|
32601
|
+
await this.sendControlRequest("interrupt");
|
|
32602
|
+
}
|
|
32574
32603
|
/**
|
|
32575
32604
|
* file-sharing tool_use ↔ tool_result 配对(spec §6 PR 3)。
|
|
32576
32605
|
*
|
|
@@ -32695,9 +32724,17 @@ var SessionRunner = class {
|
|
|
32695
32724
|
this.doSpawn(effect.ctx);
|
|
32696
32725
|
break;
|
|
32697
32726
|
case "kill":
|
|
32727
|
+
if (this.session) {
|
|
32728
|
+
void this.session.stop(effect.signal);
|
|
32729
|
+
break;
|
|
32730
|
+
}
|
|
32698
32731
|
this.doKill(effect.signal);
|
|
32699
32732
|
break;
|
|
32700
32733
|
case "write-stdin":
|
|
32734
|
+
if (this.session) {
|
|
32735
|
+
this.session.startTurn(effect.payload);
|
|
32736
|
+
break;
|
|
32737
|
+
}
|
|
32701
32738
|
this.hooks.logger?.debug("[RG] write-stdin", {
|
|
32702
32739
|
procAlive: !!this.proc,
|
|
32703
32740
|
stdinWritable: !!this.proc?.stdin,
|
|
@@ -32707,6 +32744,16 @@ var SessionRunner = class {
|
|
|
32707
32744
|
this.proc?.stdin?.write(effect.payload);
|
|
32708
32745
|
this.recorder?.tapStdinWrite(effect.payload);
|
|
32709
32746
|
break;
|
|
32747
|
+
case "respond-permission": {
|
|
32748
|
+
if (this.session) {
|
|
32749
|
+
this.session.respondPermission(effect.requestId, effect.allow);
|
|
32750
|
+
break;
|
|
32751
|
+
}
|
|
32752
|
+
const payload = encodePermissionResponse(effect.requestId, effect.allow, effect.input, effect.message);
|
|
32753
|
+
this.proc?.stdin?.write(payload);
|
|
32754
|
+
this.recorder?.tapStdinWrite(payload);
|
|
32755
|
+
break;
|
|
32756
|
+
}
|
|
32710
32757
|
case "send-control-response-allow-with-input": {
|
|
32711
32758
|
const payload = encodeAllowWithInputControlResponse(effect.requestId, effect.updatedInput);
|
|
32712
32759
|
this.proc?.stdin?.write(payload);
|
|
@@ -32764,6 +32811,22 @@ var SessionRunner = class {
|
|
|
32764
32811
|
}
|
|
32765
32812
|
// 启动子进程,绑定 stdout line buffer → 回灌 reducer
|
|
32766
32813
|
doSpawn(ctx) {
|
|
32814
|
+
if (this.hooks.adapter.createSession) {
|
|
32815
|
+
this.session = this.hooks.adapter.createSession(ctx, {
|
|
32816
|
+
pushEvents: (events) => {
|
|
32817
|
+
if (events.length === 0) return;
|
|
32818
|
+
const uuid = (this.hooks.genUuid ?? v4_default)();
|
|
32819
|
+
this.input({ kind: "inject-events", events: events.map((e) => e.uuid ? e : { ...e, uuid }) });
|
|
32820
|
+
},
|
|
32821
|
+
onExit: (code) => {
|
|
32822
|
+
this.session = null;
|
|
32823
|
+
this.clearIdleKillTimers();
|
|
32824
|
+
this.input({ kind: "proc-exit", code });
|
|
32825
|
+
},
|
|
32826
|
+
onError: (message) => this.input({ kind: "proc-error", message })
|
|
32827
|
+
});
|
|
32828
|
+
return;
|
|
32829
|
+
}
|
|
32767
32830
|
const proc = this.hooks.spawnOverride ? this.hooks.spawnOverride(ctx) : this.hooks.adapter.spawn(ctx);
|
|
32768
32831
|
this.proc = proc;
|
|
32769
32832
|
this.stdoutBuf = "";
|
|
@@ -33203,6 +33266,8 @@ var SessionManager = class {
|
|
|
33203
33266
|
const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
|
|
33204
33267
|
const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
|
|
33205
33268
|
subSessionMeta.extraSettings = JSON.stringify(settings);
|
|
33269
|
+
const domains = settings.sandbox?.network?.allowedDomains;
|
|
33270
|
+
subSessionMeta.networkAccess = Array.isArray(domains) && domains.length > 0;
|
|
33206
33271
|
}
|
|
33207
33272
|
const attachmentGroup = this.deps.attachmentGroup;
|
|
33208
33273
|
const runner = new SessionRunner(makeInitialState(file, subSessionMeta), {
|
|
@@ -33634,7 +33699,7 @@ var SessionManager = class {
|
|
|
33634
33699
|
tsid,
|
|
33635
33700
|
mode: this.deps.mode
|
|
33636
33701
|
});
|
|
33637
|
-
await runner.
|
|
33702
|
+
await runner.interrupt();
|
|
33638
33703
|
}
|
|
33639
33704
|
// 批量版本:UI 打开 session 时一次性拿到"磁盘和快照有差异"的 user message id 集合,
|
|
33640
33705
|
// 用来在消息流里精准控制 rewind 按钮的显示。session 没 toolSessionId 时返回空
|
|
@@ -34192,17 +34257,17 @@ var SessionManager = class {
|
|
|
34192
34257
|
if (!runner) {
|
|
34193
34258
|
throw new ClawdError(
|
|
34194
34259
|
ERROR_CODES.PERMISSION_REQUEST_STALE,
|
|
34195
|
-
`no pending permission request: ${args.
|
|
34260
|
+
`no pending permission request: ${args.permissionRequestId}`
|
|
34196
34261
|
);
|
|
34197
34262
|
}
|
|
34198
|
-
const pending = runner.getState().pendingPermissions[args.
|
|
34263
|
+
const pending = runner.getState().pendingPermissions[args.permissionRequestId];
|
|
34199
34264
|
if (!pending) {
|
|
34200
34265
|
return { response: { ok: true }, broadcast: [] };
|
|
34201
34266
|
}
|
|
34202
34267
|
const { broadcast } = this.withCollector(() => {
|
|
34203
34268
|
runner.input({
|
|
34204
34269
|
kind: "permission-decision",
|
|
34205
|
-
requestId: args.
|
|
34270
|
+
requestId: args.permissionRequestId,
|
|
34206
34271
|
allow: args.allow,
|
|
34207
34272
|
permanent: args.permanent,
|
|
34208
34273
|
pattern: args.pattern,
|
|
@@ -34417,6 +34482,11 @@ var PersonaStore = class {
|
|
|
34417
34482
|
claudeMdPath(personaId) {
|
|
34418
34483
|
return path9.join(this.personaDir(personaId), "CLAUDE.md");
|
|
34419
34484
|
}
|
|
34485
|
+
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
34486
|
+
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
34487
|
+
agentsMdPath(personaId) {
|
|
34488
|
+
return path9.join(this.personaDir(personaId), "AGENTS.md");
|
|
34489
|
+
}
|
|
34420
34490
|
/**
|
|
34421
34491
|
* persona 级 sandbox 模板落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
34422
34492
|
* source 自动发现扫不到(owner `--setting-sources user,project,local` 不会顺手带进来)。
|
|
@@ -34430,6 +34500,7 @@ var PersonaStore = class {
|
|
|
34430
34500
|
const dir = this.personaDir(persona.personaId);
|
|
34431
34501
|
fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
|
|
34432
34502
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
34503
|
+
this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
|
|
34433
34504
|
this.atomicWrite(
|
|
34434
34505
|
this.sandboxSettingsPath(persona.personaId),
|
|
34435
34506
|
JSON.stringify(buildGuestSettingsV1(), null, 2)
|
|
@@ -34438,6 +34509,7 @@ var PersonaStore = class {
|
|
|
34438
34509
|
}
|
|
34439
34510
|
writePersonality(personaId, personality) {
|
|
34440
34511
|
this.atomicWrite(this.claudeMdPath(personaId), personality);
|
|
34512
|
+
this.atomicWrite(this.agentsMdPath(personaId), personality);
|
|
34441
34513
|
}
|
|
34442
34514
|
/**
|
|
34443
34515
|
* 覆盖式写 persona 级 sandbox 配置(seed 给有 profile 的 persona 写 base⊕profile;owner 之后可手编)。
|
|
@@ -34467,9 +34539,11 @@ var PersonaStore = class {
|
|
|
34467
34539
|
return fs7.existsSync(this.metaPath(personaId));
|
|
34468
34540
|
}
|
|
34469
34541
|
readPersonality(personaId) {
|
|
34470
|
-
const
|
|
34471
|
-
if (
|
|
34472
|
-
|
|
34542
|
+
const claudeMd = this.claudeMdPath(personaId);
|
|
34543
|
+
if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
|
|
34544
|
+
const agentsMd = this.agentsMdPath(personaId);
|
|
34545
|
+
if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
|
|
34546
|
+
return null;
|
|
34473
34547
|
}
|
|
34474
34548
|
/**
|
|
34475
34549
|
* 读 sandbox-settings.json 当前内容;文件不存在 / JSON 解析失败均返回 null。
|
|
@@ -34871,6 +34945,7 @@ var PersonaManager = class {
|
|
|
34871
34945
|
personaId,
|
|
34872
34946
|
label: args.label,
|
|
34873
34947
|
model: args.model,
|
|
34948
|
+
tool: args.tool,
|
|
34874
34949
|
public: args.public ?? false,
|
|
34875
34950
|
iconKey: args.iconKey,
|
|
34876
34951
|
createdAt: now,
|
|
@@ -35154,8 +35229,454 @@ function refreshDaemonManagedDirs(args) {
|
|
|
35154
35229
|
// src/index.ts
|
|
35155
35230
|
init_claude();
|
|
35156
35231
|
|
|
35157
|
-
// src/tools/
|
|
35232
|
+
// src/tools/codex.ts
|
|
35233
|
+
var import_node_child_process4 = require("child_process");
|
|
35158
35234
|
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
35235
|
+
|
|
35236
|
+
// src/tools/codex-session.ts
|
|
35237
|
+
var import_node_child_process3 = require("child_process");
|
|
35238
|
+
|
|
35239
|
+
// src/tools/codex-app-server-client.ts
|
|
35240
|
+
var import_node_readline = require("readline");
|
|
35241
|
+
var CodexAppServerClient = class {
|
|
35242
|
+
constructor(proc, opts = {}) {
|
|
35243
|
+
this.proc = proc;
|
|
35244
|
+
this.opts = opts;
|
|
35245
|
+
const rl = (0, import_node_readline.createInterface)({ input: proc.stdout, crlfDelay: Infinity });
|
|
35246
|
+
rl.on("line", (l) => this.onLine(l));
|
|
35247
|
+
rl.on("close", () => {
|
|
35248
|
+
for (const p2 of this.pending.values()) p2.reject(new Error("app-server connection closed"));
|
|
35249
|
+
this.pending.clear();
|
|
35250
|
+
this.opts.onClose?.();
|
|
35251
|
+
});
|
|
35252
|
+
}
|
|
35253
|
+
proc;
|
|
35254
|
+
opts;
|
|
35255
|
+
nextId = 1;
|
|
35256
|
+
pending = /* @__PURE__ */ new Map();
|
|
35257
|
+
request(method, params) {
|
|
35258
|
+
const id = this.nextId++;
|
|
35259
|
+
return new Promise((resolve6, reject) => {
|
|
35260
|
+
this.pending.set(id, { resolve: resolve6, reject });
|
|
35261
|
+
this.write({ jsonrpc: "2.0", method, id, params });
|
|
35262
|
+
});
|
|
35263
|
+
}
|
|
35264
|
+
notify(method, params) {
|
|
35265
|
+
this.write({ jsonrpc: "2.0", method, params });
|
|
35266
|
+
}
|
|
35267
|
+
// server-request 的响应也必须带 jsonrpc:'2.0',否则 codex app-server 忽略它 → 审批/问答永远卡住。
|
|
35268
|
+
respond(id, result) {
|
|
35269
|
+
this.write({ jsonrpc: "2.0", id, result });
|
|
35270
|
+
}
|
|
35271
|
+
onLine(line) {
|
|
35272
|
+
const t = line.trim();
|
|
35273
|
+
if (!t) return;
|
|
35274
|
+
let m2;
|
|
35275
|
+
try {
|
|
35276
|
+
m2 = JSON.parse(t);
|
|
35277
|
+
} catch {
|
|
35278
|
+
return;
|
|
35279
|
+
}
|
|
35280
|
+
if (!isRecord(m2)) return;
|
|
35281
|
+
const hasId = typeof m2.id === "number", hasMethod = typeof m2.method === "string";
|
|
35282
|
+
if (hasId && !hasMethod) {
|
|
35283
|
+
const p2 = this.pending.get(m2.id);
|
|
35284
|
+
if (!p2) return;
|
|
35285
|
+
this.pending.delete(m2.id);
|
|
35286
|
+
if (m2.error) {
|
|
35287
|
+
const e = isRecord(m2.error) ? m2.error : {};
|
|
35288
|
+
p2.reject(new Error(typeof e.message === "string" ? e.message : "app-server error"));
|
|
35289
|
+
} else p2.resolve(m2.result);
|
|
35290
|
+
return;
|
|
35291
|
+
}
|
|
35292
|
+
if (hasId && hasMethod) {
|
|
35293
|
+
this.opts.onServerRequest?.(m2.id, m2.method, m2.params);
|
|
35294
|
+
return;
|
|
35295
|
+
}
|
|
35296
|
+
if (hasMethod) this.opts.onNotification?.(m2.method, m2.params);
|
|
35297
|
+
}
|
|
35298
|
+
write(o) {
|
|
35299
|
+
this.proc.stdin.write(JSON.stringify(o) + "\n");
|
|
35300
|
+
}
|
|
35301
|
+
};
|
|
35302
|
+
function isRecord(v2) {
|
|
35303
|
+
return typeof v2 === "object" && v2 !== null;
|
|
35304
|
+
}
|
|
35305
|
+
|
|
35306
|
+
// src/tools/codex-app-server-events.ts
|
|
35307
|
+
function translateNotification(method, params) {
|
|
35308
|
+
const p2 = rec(params);
|
|
35309
|
+
switch (method) {
|
|
35310
|
+
case "thread/started": {
|
|
35311
|
+
const id = str(rec(p2?.thread)?.id);
|
|
35312
|
+
return id ? [{ kind: "session_init", toolSessionId: id }] : [];
|
|
35313
|
+
}
|
|
35314
|
+
case "item/agentMessage/delta": {
|
|
35315
|
+
const text = str(p2?.delta);
|
|
35316
|
+
const id = str(p2?.itemId);
|
|
35317
|
+
return text ? [{ kind: "text", text, ...id ? { partialId: id } : {} }] : [];
|
|
35318
|
+
}
|
|
35319
|
+
case "item/reasoning/textDelta":
|
|
35320
|
+
case "item/reasoning/summaryTextDelta": {
|
|
35321
|
+
const text = str(p2?.delta);
|
|
35322
|
+
const id = str(p2?.itemId);
|
|
35323
|
+
return text ? [{ kind: "thinking", text, ...id ? { partialId: id } : {} }] : [];
|
|
35324
|
+
}
|
|
35325
|
+
case "item/commandExecution/outputDelta":
|
|
35326
|
+
return [];
|
|
35327
|
+
// 命令输出增量 v1 不逐字(完成时整段给)
|
|
35328
|
+
case "item/started":
|
|
35329
|
+
return itemStarted(rec(p2?.item));
|
|
35330
|
+
case "item/completed":
|
|
35331
|
+
return itemCompleted(rec(p2?.item));
|
|
35332
|
+
case "thread/tokenUsage/updated":
|
|
35333
|
+
return tokenUsage(rec(rec(p2?.tokenUsage)));
|
|
35334
|
+
case "turn/completed":
|
|
35335
|
+
return turnCompleted(rec(p2?.turn));
|
|
35336
|
+
default:
|
|
35337
|
+
return [];
|
|
35338
|
+
}
|
|
35339
|
+
}
|
|
35340
|
+
function itemStarted(item) {
|
|
35341
|
+
if (!item) return [];
|
|
35342
|
+
const id = str(item.id);
|
|
35343
|
+
if (!id) return [];
|
|
35344
|
+
if (item.type === "commandExecution") {
|
|
35345
|
+
return [{ kind: "tool_call", toolUseId: id, tool: "commandExecution", toolKind: "codex", input: { command: str(item.command) ?? "" } }];
|
|
35346
|
+
}
|
|
35347
|
+
if (item.type === "fileChange") {
|
|
35348
|
+
return [{ kind: "tool_call", toolUseId: id, tool: "fileChange", toolKind: "codex", input: { changes: Array.isArray(item.changes) ? item.changes : [] } }];
|
|
35349
|
+
}
|
|
35350
|
+
return [];
|
|
35351
|
+
}
|
|
35352
|
+
function itemCompleted(item) {
|
|
35353
|
+
if (!item) return [];
|
|
35354
|
+
switch (item.type) {
|
|
35355
|
+
case "userMessage":
|
|
35356
|
+
return [];
|
|
35357
|
+
// 用户输入回显, clawd 自己 synthesize user_text
|
|
35358
|
+
case "agentMessage": {
|
|
35359
|
+
const text = str(item.text);
|
|
35360
|
+
return text ? [{ kind: "text", text }] : [];
|
|
35361
|
+
}
|
|
35362
|
+
case "reasoning": {
|
|
35363
|
+
const text = str(item.text);
|
|
35364
|
+
return text ? [{ kind: "thinking", text }] : [];
|
|
35365
|
+
}
|
|
35366
|
+
case "commandExecution": {
|
|
35367
|
+
const id = str(item.id);
|
|
35368
|
+
if (!id) return [];
|
|
35369
|
+
const exit = num(item.exitCode);
|
|
35370
|
+
const ev = { kind: "tool_result", toolUseId: id, output: str(item.aggregatedOutput ?? item.output) ?? "" };
|
|
35371
|
+
if (exit !== void 0 && exit !== 0) ev.error = `exit ${exit}`;
|
|
35372
|
+
return [ev];
|
|
35373
|
+
}
|
|
35374
|
+
case "fileChange": {
|
|
35375
|
+
const id = str(item.id);
|
|
35376
|
+
if (!id) return [];
|
|
35377
|
+
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
35378
|
+
const output = changes.map((c) => str(c.diff) ?? "").filter(Boolean).join("\n");
|
|
35379
|
+
const ev = { kind: "tool_result", toolUseId: id, output };
|
|
35380
|
+
const status = str(item.status);
|
|
35381
|
+
if (status === "failed" || status === "declined") ev.error = `patch ${status}`;
|
|
35382
|
+
return [ev];
|
|
35383
|
+
}
|
|
35384
|
+
default:
|
|
35385
|
+
return [];
|
|
35386
|
+
}
|
|
35387
|
+
}
|
|
35388
|
+
function tokenUsage(usage) {
|
|
35389
|
+
if (!usage) return [];
|
|
35390
|
+
const last = rec(usage.last);
|
|
35391
|
+
if (!last) return [];
|
|
35392
|
+
const i = num(last.inputTokens), o = num(last.outputTokens);
|
|
35393
|
+
const patch = {};
|
|
35394
|
+
if (i !== void 0 && o !== void 0) patch.contextUsage = { inputTokens: i, outputTokens: o };
|
|
35395
|
+
const w2 = num(usage.modelContextWindow);
|
|
35396
|
+
if (w2 !== void 0) patch.contextWindowSize = w2;
|
|
35397
|
+
return Object.keys(patch).length ? [{ kind: "meta_update", patch }] : [];
|
|
35398
|
+
}
|
|
35399
|
+
function turnCompleted(turn) {
|
|
35400
|
+
if (turn?.status === "failed") return [{ kind: "error", message: str(rec(turn.error)?.message) ?? "codex turn failed" }, { kind: "turn_end" }];
|
|
35401
|
+
return [{ kind: "turn_end" }];
|
|
35402
|
+
}
|
|
35403
|
+
function rec(v2) {
|
|
35404
|
+
return typeof v2 === "object" && v2 !== null ? v2 : void 0;
|
|
35405
|
+
}
|
|
35406
|
+
function str(v2) {
|
|
35407
|
+
return typeof v2 === "string" ? v2 : void 0;
|
|
35408
|
+
}
|
|
35409
|
+
function num(v2) {
|
|
35410
|
+
return typeof v2 === "number" ? v2 : void 0;
|
|
35411
|
+
}
|
|
35412
|
+
|
|
35413
|
+
// src/tools/codex-app-server-params.ts
|
|
35414
|
+
function resolveSandbox(ctx) {
|
|
35415
|
+
if (ctx.personaMode === "guest") return "workspace-write";
|
|
35416
|
+
return "danger-full-access";
|
|
35417
|
+
}
|
|
35418
|
+
function resolveApprovalPolicy(ctx) {
|
|
35419
|
+
if (ctx.personaMode === "owner" || ctx.personaMode === "guest") return "never";
|
|
35420
|
+
const m2 = ctx.permissionMode ?? "";
|
|
35421
|
+
if (m2 === "untrusted" || m2 === "on-failure" || m2 === "on-request" || m2 === "never") return m2;
|
|
35422
|
+
return "on-request";
|
|
35423
|
+
}
|
|
35424
|
+
function threadStartParams(ctx) {
|
|
35425
|
+
const params = {
|
|
35426
|
+
cwd: ctx.cwd,
|
|
35427
|
+
sandbox: resolveSandbox(ctx),
|
|
35428
|
+
approvalPolicy: resolveApprovalPolicy(ctx),
|
|
35429
|
+
approvalsReviewer: "user",
|
|
35430
|
+
...ctx.model ? { model: ctx.model } : {}
|
|
35431
|
+
};
|
|
35432
|
+
if (ctx.personaMode === "guest") {
|
|
35433
|
+
params.config = {
|
|
35434
|
+
sandbox_workspace_write: { writable_roots: ctx.addDirs ?? [], network_access: ctx.networkAccess ?? false }
|
|
35435
|
+
};
|
|
35436
|
+
}
|
|
35437
|
+
return params;
|
|
35438
|
+
}
|
|
35439
|
+
var ATTACHMENT_RE2 = /\[attachment:(image|file):([^\]]+)\]/g;
|
|
35440
|
+
var SKILL_RE = /\[skill:(.+?):(\/[^\]]+)\]/g;
|
|
35441
|
+
function turnStartInput(text) {
|
|
35442
|
+
const items = [];
|
|
35443
|
+
let leftover = text;
|
|
35444
|
+
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
35445
|
+
const [marker, name, path59] = m2;
|
|
35446
|
+
items.push({ type: "skill", name, path: path59 });
|
|
35447
|
+
leftover = leftover.replace(marker, "");
|
|
35448
|
+
}
|
|
35449
|
+
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
35450
|
+
const [marker, kind, url] = m2;
|
|
35451
|
+
if (kind === "image") {
|
|
35452
|
+
items.push({ type: "image", url });
|
|
35453
|
+
leftover = leftover.replace(marker, "");
|
|
35454
|
+
}
|
|
35455
|
+
}
|
|
35456
|
+
const trimmed = leftover.trim();
|
|
35457
|
+
if (trimmed || items.length === 0) items.push({ type: "text", text: trimmed, text_elements: [] });
|
|
35458
|
+
return items;
|
|
35459
|
+
}
|
|
35460
|
+
|
|
35461
|
+
// src/tools/codex-session.ts
|
|
35462
|
+
function createCodexSession(ctx, sink, deps = {}) {
|
|
35463
|
+
const cmd = process.env.CODEX_BIN ?? "codex";
|
|
35464
|
+
const args = ["app-server", "--listen", "stdio://"];
|
|
35465
|
+
const env = { ...process.env, ...ctx.env };
|
|
35466
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0, import_node_child_process3.spawn)(cmd, args, { cwd: ctx.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
35467
|
+
let threadId = ctx.toolSessionId;
|
|
35468
|
+
let turnId;
|
|
35469
|
+
const approvalIds = /* @__PURE__ */ new Map();
|
|
35470
|
+
let pendingSystemPrompt = ctx.toolSessionId ? void 0 : ctx.extraSystemPrompt;
|
|
35471
|
+
const effort = ctx.effort;
|
|
35472
|
+
let exited = false;
|
|
35473
|
+
const finish = (code) => {
|
|
35474
|
+
if (exited) return;
|
|
35475
|
+
exited = true;
|
|
35476
|
+
sink.onExit(code);
|
|
35477
|
+
};
|
|
35478
|
+
const client = new CodexAppServerClient(proc, {
|
|
35479
|
+
onNotification: (method, params) => {
|
|
35480
|
+
if (method === "turn/started") {
|
|
35481
|
+
const id = params?.turn?.id;
|
|
35482
|
+
if (id) turnId = id;
|
|
35483
|
+
}
|
|
35484
|
+
const events = translateNotification(method, params);
|
|
35485
|
+
if (events.length) sink.pushEvents(events);
|
|
35486
|
+
},
|
|
35487
|
+
onServerRequest: (id, method, params) => {
|
|
35488
|
+
const p2 = params ?? {};
|
|
35489
|
+
if (method === "item/commandExecution/requestApproval" || method === "item/fileChange/requestApproval") {
|
|
35490
|
+
const reqId = String(id);
|
|
35491
|
+
approvalIds.set(reqId, id);
|
|
35492
|
+
sink.pushEvents([
|
|
35493
|
+
{
|
|
35494
|
+
kind: "permission_request",
|
|
35495
|
+
requestId: reqId,
|
|
35496
|
+
tool: method.includes("fileChange") ? "fileChange" : "commandExecution",
|
|
35497
|
+
input: p2,
|
|
35498
|
+
...typeof p2.itemId === "string" ? { toolUseId: p2.itemId } : {}
|
|
35499
|
+
}
|
|
35500
|
+
]);
|
|
35501
|
+
return;
|
|
35502
|
+
}
|
|
35503
|
+
client.respond(id, "cancel");
|
|
35504
|
+
},
|
|
35505
|
+
onClose: () => finish(proc.exitCode)
|
|
35506
|
+
});
|
|
35507
|
+
proc.stderr?.on(
|
|
35508
|
+
"data",
|
|
35509
|
+
(c) => deps.logger?.warn("codex app-server stderr", { line: c.toString().slice(0, 500) })
|
|
35510
|
+
);
|
|
35511
|
+
proc.on("error", (err) => {
|
|
35512
|
+
const message = err.message;
|
|
35513
|
+
deps.logger?.error("codex app-server spawn failed", { message });
|
|
35514
|
+
sink.onError(`codex app-server spawn failed: ${message}`);
|
|
35515
|
+
});
|
|
35516
|
+
proc.on("exit", (code) => finish(code));
|
|
35517
|
+
const ready = (async () => {
|
|
35518
|
+
await client.request("initialize", {
|
|
35519
|
+
clientInfo: { name: "clawd", title: "clawd", version: "0" },
|
|
35520
|
+
capabilities: null
|
|
35521
|
+
});
|
|
35522
|
+
client.notify("initialized", {});
|
|
35523
|
+
if (threadId) {
|
|
35524
|
+
await client.request("thread/resume", { threadId, ...threadStartParams(ctx) });
|
|
35525
|
+
} else {
|
|
35526
|
+
const res = await client.request("thread/start", threadStartParams(ctx));
|
|
35527
|
+
threadId = res?.thread?.id;
|
|
35528
|
+
if (threadId) sink.pushEvents([{ kind: "session_init", toolSessionId: threadId }]);
|
|
35529
|
+
}
|
|
35530
|
+
})().catch((e) => sink.onError(`codex app-server init failed: ${e.message}`));
|
|
35531
|
+
return {
|
|
35532
|
+
startTurn(text) {
|
|
35533
|
+
const body = pendingSystemPrompt ? `${pendingSystemPrompt}
|
|
35534
|
+
|
|
35535
|
+
${text}` : text;
|
|
35536
|
+
pendingSystemPrompt = void 0;
|
|
35537
|
+
void ready.then(() => {
|
|
35538
|
+
if (threadId)
|
|
35539
|
+
void client.request("turn/start", {
|
|
35540
|
+
threadId,
|
|
35541
|
+
input: turnStartInput(body),
|
|
35542
|
+
// TurnStartParams 字段是 `effort`(不是 `reasoningEffort`,0.138 改名)——传错名字
|
|
35543
|
+
// codex 静默忽略, reasoning effort 改了不生效。"override for this turn and subsequent turns"。
|
|
35544
|
+
...effort ? { effort } : {}
|
|
35545
|
+
}).catch((e) => sink.onError(`turn/start failed: ${e.message}`));
|
|
35546
|
+
});
|
|
35547
|
+
},
|
|
35548
|
+
respondPermission(requestId, allow) {
|
|
35549
|
+
const id = approvalIds.get(requestId);
|
|
35550
|
+
if (id === void 0) return;
|
|
35551
|
+
approvalIds.delete(requestId);
|
|
35552
|
+
client.respond(id, { decision: allow ? "accept" : "decline" });
|
|
35553
|
+
},
|
|
35554
|
+
interrupt() {
|
|
35555
|
+
if (threadId && turnId) {
|
|
35556
|
+
void client.request("turn/interrupt", { threadId, turnId }).catch(() => {
|
|
35557
|
+
});
|
|
35558
|
+
return;
|
|
35559
|
+
}
|
|
35560
|
+
if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGTERM");
|
|
35561
|
+
},
|
|
35562
|
+
// signal 由 runner 透传 reducer 的 kill effect(runtime-patch / stop 恒 SIGKILL),与 claude doKill 语义统一:
|
|
35563
|
+
// SIGTERM 兜底会在 app-server 卡死收不到时泄漏进程,故尊重 SIGKILL 强杀。
|
|
35564
|
+
async stop(signal = "SIGTERM") {
|
|
35565
|
+
if (threadId && turnId) void client.request("turn/interrupt", { threadId, turnId }).catch(() => {
|
|
35566
|
+
});
|
|
35567
|
+
if (proc.exitCode === null && proc.signalCode === null) proc.kill(signal);
|
|
35568
|
+
}
|
|
35569
|
+
};
|
|
35570
|
+
}
|
|
35571
|
+
|
|
35572
|
+
// src/tools/codex.ts
|
|
35573
|
+
var CODEX_MODELS = [
|
|
35574
|
+
{ id: "", label: "Default", description: "codex config.toml \u9ED8\u8BA4", contextWindowSize: 258400, default: true },
|
|
35575
|
+
{ id: "gpt-5.5", label: "GPT-5.5", description: "Frontier model for complex coding", contextWindowSize: 258400 },
|
|
35576
|
+
{ id: "gpt-5.4", label: "GPT-5.4", contextWindowSize: 258400 },
|
|
35577
|
+
{ id: "gpt-5.4-mini", label: "GPT-5.4-Mini", contextWindowSize: 258400 }
|
|
35578
|
+
];
|
|
35579
|
+
var CODEX_EFFORTS = [
|
|
35580
|
+
{ value: "low", label: "Low", description: "Fast responses with lighter reasoning" },
|
|
35581
|
+
{ value: "medium", label: "Medium", description: "Balances speed and reasoning depth for everyday tasks" },
|
|
35582
|
+
{ value: "high", label: "High", description: "Greater reasoning depth for complex problems" },
|
|
35583
|
+
{ value: "xhigh", label: "Extra high", description: "Extra high reasoning depth for complex problems" }
|
|
35584
|
+
];
|
|
35585
|
+
var CODEX_APPROVAL_PRESETS = [
|
|
35586
|
+
{ id: "untrusted", label: "Ask for approval", description: "\u51E0\u4E4E\u6BCF\u6761\u547D\u4EE4\u90FD\u95EE\u4F60\uFF08\u6700\u8C28\u614E\uFF09" },
|
|
35587
|
+
{ id: "on-request", label: "Approve for me", description: "\u6A21\u578B\u81EA\u5DF1\u5224\u65AD\uFF0C\u53EA\u5BF9\u9AD8\u98CE\u9669\u64CD\u4F5C\u95EE\u4F60\uFF08\u9ED8\u8BA4\uFF09" },
|
|
35588
|
+
{ id: "never", label: "Full Access", description: "\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" }
|
|
35589
|
+
];
|
|
35590
|
+
var CODEX_CAPABILITIES = {
|
|
35591
|
+
tool: "codex",
|
|
35592
|
+
toolSessionIdLabel: "Codex Thread ID",
|
|
35593
|
+
models: CODEX_MODELS,
|
|
35594
|
+
permissionModes: CODEX_APPROVAL_PRESETS,
|
|
35595
|
+
// codex 不支持这些 clawd 功能(rewind 无 file-snapshot / 无子 agent / 无 TUI pty /
|
|
35596
|
+
// 无 observe 推送 / 无文件分享 / fork 是 claude jsonl 专用);UI 据此 gate 入口。
|
|
35597
|
+
features: { rewind: false, subagents: false, tui: false, observe: false, fileSharing: false, fork: false },
|
|
35598
|
+
configSchema: [
|
|
35599
|
+
{
|
|
35600
|
+
name: "model",
|
|
35601
|
+
type: "select",
|
|
35602
|
+
label: "Model",
|
|
35603
|
+
scope: "core",
|
|
35604
|
+
options: CODEX_MODELS.map((m2) => ({ value: m2.id, label: m2.label, description: m2.description })),
|
|
35605
|
+
default: ""
|
|
35606
|
+
},
|
|
35607
|
+
{
|
|
35608
|
+
name: "permissionMode",
|
|
35609
|
+
type: "select",
|
|
35610
|
+
label: "Approval",
|
|
35611
|
+
scope: "core",
|
|
35612
|
+
options: CODEX_APPROVAL_PRESETS.map((m2) => ({ value: m2.id, label: m2.label, description: m2.description })),
|
|
35613
|
+
default: "on-request"
|
|
35614
|
+
},
|
|
35615
|
+
{
|
|
35616
|
+
name: "effort",
|
|
35617
|
+
type: "select",
|
|
35618
|
+
label: "Reasoning effort",
|
|
35619
|
+
scope: "tool-specific",
|
|
35620
|
+
// 渲染在 Advanced 区(与 claude effort 一致)
|
|
35621
|
+
options: CODEX_EFFORTS,
|
|
35622
|
+
default: "medium"
|
|
35623
|
+
}
|
|
35624
|
+
]
|
|
35625
|
+
};
|
|
35626
|
+
function sanitizeCodexModel(model) {
|
|
35627
|
+
if (model === void 0) return void 0;
|
|
35628
|
+
return CODEX_MODELS.some((m2) => m2.id === model) ? model : void 0;
|
|
35629
|
+
}
|
|
35630
|
+
async function probeCodex(env = process.env) {
|
|
35631
|
+
if (env.CODEX_BIN && import_node_fs10.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
|
|
35632
|
+
try {
|
|
35633
|
+
const out = (0, import_node_child_process4.execFileSync)("which", ["codex"], { encoding: "utf8" }).trim();
|
|
35634
|
+
if (out && import_node_fs10.default.existsSync(out)) return { available: true, path: out };
|
|
35635
|
+
} catch {
|
|
35636
|
+
}
|
|
35637
|
+
return { available: false };
|
|
35638
|
+
}
|
|
35639
|
+
var CodexAdapter = class {
|
|
35640
|
+
id = "codex";
|
|
35641
|
+
// 历史读取器:history:read 按 session.tool 路由到这里(thread/read)。
|
|
35642
|
+
historyReader;
|
|
35643
|
+
probeCache = null;
|
|
35644
|
+
logger;
|
|
35645
|
+
probeOverride;
|
|
35646
|
+
constructor(opts = {}) {
|
|
35647
|
+
this.logger = opts.logger;
|
|
35648
|
+
this.probeOverride = opts.probeOverride;
|
|
35649
|
+
this.historyReader = opts.historyReader;
|
|
35650
|
+
}
|
|
35651
|
+
async probe() {
|
|
35652
|
+
if (this.probeCache) return this.probeCache;
|
|
35653
|
+
this.probeCache = this.probeOverride ? await this.probeOverride() : await probeCodex();
|
|
35654
|
+
return this.probeCache;
|
|
35655
|
+
}
|
|
35656
|
+
async capabilities() {
|
|
35657
|
+
return CODEX_CAPABILITIES;
|
|
35658
|
+
}
|
|
35659
|
+
resolveContextWindow(modelId) {
|
|
35660
|
+
return (CODEX_MODELS.find((m2) => m2.id === (modelId ?? "")) ?? CODEX_MODELS[0]).contextWindowSize;
|
|
35661
|
+
}
|
|
35662
|
+
createSession(ctx, sink) {
|
|
35663
|
+
return createCodexSession({ ...ctx, model: sanitizeCodexModel(ctx.model) }, sink, { logger: this.logger });
|
|
35664
|
+
}
|
|
35665
|
+
spawn(_ctx) {
|
|
35666
|
+
throw new Error("CodexAdapter uses createSession, not spawn");
|
|
35667
|
+
}
|
|
35668
|
+
parseLine(_line) {
|
|
35669
|
+
return [];
|
|
35670
|
+
}
|
|
35671
|
+
// 原样返回带 marker 的文本;附件 marker → codex image 多模态由 turnStartInput 解析
|
|
35672
|
+
// (codex-app-server-params.ts, PR1)。encodeStdin 不动 markers。
|
|
35673
|
+
encodeStdin(text, _ctx) {
|
|
35674
|
+
return text;
|
|
35675
|
+
}
|
|
35676
|
+
};
|
|
35677
|
+
|
|
35678
|
+
// src/tools/claude-tui.ts
|
|
35679
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
35159
35680
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
35160
35681
|
var import_node_path10 = __toESM(require("path"), 1);
|
|
35161
35682
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
@@ -36139,7 +36660,7 @@ function jsonlExistsForCtx(ctx) {
|
|
|
36139
36660
|
const home = import_node_os5.default.homedir();
|
|
36140
36661
|
const file = import_node_path10.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
36141
36662
|
try {
|
|
36142
|
-
return
|
|
36663
|
+
return import_node_fs11.default.statSync(file).isFile();
|
|
36143
36664
|
} catch {
|
|
36144
36665
|
return false;
|
|
36145
36666
|
}
|
|
@@ -36148,8 +36669,238 @@ function jsonlExistsForCtx(ctx) {
|
|
|
36148
36669
|
// src/index.ts
|
|
36149
36670
|
init_claude_history();
|
|
36150
36671
|
|
|
36672
|
+
// src/tools/codex-history.ts
|
|
36673
|
+
var import_node_child_process5 = require("child_process");
|
|
36674
|
+
var DEFAULT_TIMEOUT_MS = 8e3;
|
|
36675
|
+
function rec2(v2) {
|
|
36676
|
+
return v2 && typeof v2 === "object" && !Array.isArray(v2) ? v2 : void 0;
|
|
36677
|
+
}
|
|
36678
|
+
function str2(v2) {
|
|
36679
|
+
return typeof v2 === "string" ? v2 : void 0;
|
|
36680
|
+
}
|
|
36681
|
+
function num2(v2) {
|
|
36682
|
+
return typeof v2 === "number" && Number.isFinite(v2) ? v2 : void 0;
|
|
36683
|
+
}
|
|
36684
|
+
function userInputText(content) {
|
|
36685
|
+
if (!Array.isArray(content)) return "";
|
|
36686
|
+
return content.map((c) => {
|
|
36687
|
+
const r = rec2(c);
|
|
36688
|
+
return r && r.type === "text" ? str2(r.text) ?? "" : "";
|
|
36689
|
+
}).filter(Boolean).join("");
|
|
36690
|
+
}
|
|
36691
|
+
function threadItemToHistoryMessages(item) {
|
|
36692
|
+
const it = rec2(item);
|
|
36693
|
+
if (!it) return [];
|
|
36694
|
+
switch (it.type) {
|
|
36695
|
+
case "userMessage": {
|
|
36696
|
+
const text = userInputText(it.content);
|
|
36697
|
+
return text ? [{ kind: "user-text", text, raw: item }] : [];
|
|
36698
|
+
}
|
|
36699
|
+
case "agentMessage": {
|
|
36700
|
+
const text = str2(it.text);
|
|
36701
|
+
return text ? [{ kind: "assistant-text", text, raw: item }] : [];
|
|
36702
|
+
}
|
|
36703
|
+
case "commandExecution": {
|
|
36704
|
+
const id = str2(it.id);
|
|
36705
|
+
if (!id) return [];
|
|
36706
|
+
const msgs = [
|
|
36707
|
+
{
|
|
36708
|
+
kind: "tool_call",
|
|
36709
|
+
tool: "commandExecution",
|
|
36710
|
+
toolUseId: id,
|
|
36711
|
+
input: { command: str2(it.command) ?? "" },
|
|
36712
|
+
raw: item
|
|
36713
|
+
}
|
|
36714
|
+
];
|
|
36715
|
+
if (it.status === "completed" || it.aggregatedOutput != null || it.exitCode != null) {
|
|
36716
|
+
const exit = num2(it.exitCode);
|
|
36717
|
+
const result = {
|
|
36718
|
+
kind: "tool_result",
|
|
36719
|
+
toolUseId: id,
|
|
36720
|
+
output: str2(it.aggregatedOutput) ?? "",
|
|
36721
|
+
raw: item
|
|
36722
|
+
};
|
|
36723
|
+
if (exit !== void 0 && exit !== 0) result.output = `${result.output ?? ""}
|
|
36724
|
+
(exit ${exit})`;
|
|
36725
|
+
msgs.push(result);
|
|
36726
|
+
}
|
|
36727
|
+
return msgs;
|
|
36728
|
+
}
|
|
36729
|
+
default:
|
|
36730
|
+
return [];
|
|
36731
|
+
}
|
|
36732
|
+
}
|
|
36733
|
+
async function queryCodexAppServer(cwd, method, params, deps) {
|
|
36734
|
+
const cmd = process.env.CODEX_BIN ?? "codex";
|
|
36735
|
+
const args = ["app-server", "--listen", "stdio://"];
|
|
36736
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0, import_node_child_process5.spawn)(cmd, args, { cwd, env: process.env, stdio: ["pipe", "pipe", "pipe"] });
|
|
36737
|
+
const client = new CodexAppServerClient(proc, {});
|
|
36738
|
+
const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
36739
|
+
let timer;
|
|
36740
|
+
const timeout = new Promise((_2, reject) => {
|
|
36741
|
+
timer = setTimeout(() => reject(new Error(`codex app-server ${method} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
36742
|
+
proc.on("error", (err) => reject(new Error(`codex app-server spawn failed: ${err.message}`)));
|
|
36743
|
+
});
|
|
36744
|
+
try {
|
|
36745
|
+
await Promise.race([
|
|
36746
|
+
(async () => {
|
|
36747
|
+
await client.request("initialize", {
|
|
36748
|
+
clientInfo: { name: "clawd", title: "clawd", version: "0" },
|
|
36749
|
+
capabilities: null
|
|
36750
|
+
});
|
|
36751
|
+
client.notify("initialized", {});
|
|
36752
|
+
})(),
|
|
36753
|
+
timeout
|
|
36754
|
+
]);
|
|
36755
|
+
return await Promise.race([client.request(method, params), timeout]);
|
|
36756
|
+
} finally {
|
|
36757
|
+
if (timer) clearTimeout(timer);
|
|
36758
|
+
if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGTERM");
|
|
36759
|
+
}
|
|
36760
|
+
}
|
|
36761
|
+
var CodexHistoryReader = class {
|
|
36762
|
+
deps;
|
|
36763
|
+
constructor(deps = {}) {
|
|
36764
|
+
this.deps = deps;
|
|
36765
|
+
}
|
|
36766
|
+
// v1 先返回 []:projects/list 非 session-scoped、不知 tool,跨-tool 项目浏览器合并排后续。
|
|
36767
|
+
// codex 旧会话仍能经 clawd 活跃列表(session:list, tool-agnostic) + read 打开。
|
|
36768
|
+
async listProjects() {
|
|
36769
|
+
return [];
|
|
36770
|
+
}
|
|
36771
|
+
async listSessions(args) {
|
|
36772
|
+
const res = rec2(
|
|
36773
|
+
await queryCodexAppServer(
|
|
36774
|
+
args.projectPath,
|
|
36775
|
+
"thread/list",
|
|
36776
|
+
{
|
|
36777
|
+
limit: 100,
|
|
36778
|
+
sortKey: "updated_at",
|
|
36779
|
+
sortDirection: "desc",
|
|
36780
|
+
archived: false,
|
|
36781
|
+
cwd: args.projectPath,
|
|
36782
|
+
useStateDbOnly: true
|
|
36783
|
+
},
|
|
36784
|
+
this.deps
|
|
36785
|
+
)
|
|
36786
|
+
);
|
|
36787
|
+
const data = res && Array.isArray(res.data) ? res.data : [];
|
|
36788
|
+
const out = [];
|
|
36789
|
+
for (const entry of data) {
|
|
36790
|
+
const e = rec2(entry);
|
|
36791
|
+
const id = e && str2(e.id);
|
|
36792
|
+
if (!e || !id) continue;
|
|
36793
|
+
const updatedAtMs = Math.round((num2(e.updatedAt) ?? 0) * 1e3);
|
|
36794
|
+
out.push({
|
|
36795
|
+
toolSessionId: id,
|
|
36796
|
+
summary: str2(e.preview) || "(\u7A7A\u4F1A\u8BDD)",
|
|
36797
|
+
messageCount: 0,
|
|
36798
|
+
// thread/list 不提供条数;活跃/read 时才知
|
|
36799
|
+
updatedAt: new Date(updatedAtMs).toISOString()
|
|
36800
|
+
});
|
|
36801
|
+
}
|
|
36802
|
+
return out;
|
|
36803
|
+
}
|
|
36804
|
+
async read(args) {
|
|
36805
|
+
const res = rec2(
|
|
36806
|
+
await queryCodexAppServer(
|
|
36807
|
+
args.cwd,
|
|
36808
|
+
"thread/read",
|
|
36809
|
+
{ threadId: args.toolSessionId, includeTurns: true },
|
|
36810
|
+
this.deps
|
|
36811
|
+
)
|
|
36812
|
+
);
|
|
36813
|
+
const thread = res && rec2(res.thread);
|
|
36814
|
+
const turns = thread && Array.isArray(thread.turns) ? thread.turns : [];
|
|
36815
|
+
const messages = [];
|
|
36816
|
+
for (const turn of turns) {
|
|
36817
|
+
const t = rec2(turn);
|
|
36818
|
+
const items = t && Array.isArray(t.items) ? t.items : [];
|
|
36819
|
+
for (const item of items) messages.push(...threadItemToHistoryMessages(item));
|
|
36820
|
+
}
|
|
36821
|
+
const total = messages.length;
|
|
36822
|
+
const limit = args.limit ?? total;
|
|
36823
|
+
const offset = typeof args.offset === "number" ? Math.min(Math.max(0, args.offset), total) : Math.max(0, total - limit);
|
|
36824
|
+
return { messages: messages.slice(offset, offset + limit), total, offset };
|
|
36825
|
+
}
|
|
36826
|
+
// codex 无 sidechain 子 agent / file-history-snapshot → 全 stub 空(对齐 claude-history 同方法空返回)
|
|
36827
|
+
async listSubagents() {
|
|
36828
|
+
return [];
|
|
36829
|
+
}
|
|
36830
|
+
async readSubagent() {
|
|
36831
|
+
return { messages: [] };
|
|
36832
|
+
}
|
|
36833
|
+
computeRewindDiff() {
|
|
36834
|
+
return { canRewind: false, files: [], totalInsertions: 0, totalDeletions: 0 };
|
|
36835
|
+
}
|
|
36836
|
+
listRewindableUserMessageIds() {
|
|
36837
|
+
return [];
|
|
36838
|
+
}
|
|
36839
|
+
};
|
|
36840
|
+
|
|
36841
|
+
// src/tools/codex-skills.ts
|
|
36842
|
+
var import_node_child_process6 = require("child_process");
|
|
36843
|
+
var DEFAULT_TIMEOUT_MS2 = 8e3;
|
|
36844
|
+
function str3(v2) {
|
|
36845
|
+
return typeof v2 === "string" ? v2 : void 0;
|
|
36846
|
+
}
|
|
36847
|
+
function mapSkillsListResponse(res) {
|
|
36848
|
+
const data = res?.data;
|
|
36849
|
+
if (!Array.isArray(data)) return [];
|
|
36850
|
+
const out = [];
|
|
36851
|
+
for (const entry of data) {
|
|
36852
|
+
const skills = entry?.skills;
|
|
36853
|
+
if (!Array.isArray(skills)) continue;
|
|
36854
|
+
for (const s of skills) {
|
|
36855
|
+
const r = s ?? {};
|
|
36856
|
+
const name = str3(r.name);
|
|
36857
|
+
if (!name) continue;
|
|
36858
|
+
const path59 = str3(r.path);
|
|
36859
|
+
const description = str3(r.description);
|
|
36860
|
+
const isPlugin = name.includes(":");
|
|
36861
|
+
out.push({
|
|
36862
|
+
name,
|
|
36863
|
+
source: isPlugin ? "plugin" : "project",
|
|
36864
|
+
...path59 ? { path: path59 } : {},
|
|
36865
|
+
...description ? { description } : {},
|
|
36866
|
+
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
36867
|
+
});
|
|
36868
|
+
}
|
|
36869
|
+
}
|
|
36870
|
+
return out;
|
|
36871
|
+
}
|
|
36872
|
+
async function listCodexSkills(cwd, deps = {}) {
|
|
36873
|
+
const cmd = process.env.CODEX_BIN ?? "codex";
|
|
36874
|
+
const args = ["app-server", "--listen", "stdio://"];
|
|
36875
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0, import_node_child_process6.spawn)(cmd, args, { cwd, env: process.env, stdio: ["pipe", "pipe", "pipe"] });
|
|
36876
|
+
const client = new CodexAppServerClient(proc, {});
|
|
36877
|
+
const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
36878
|
+
let timer;
|
|
36879
|
+
const timeout = new Promise((_2, reject) => {
|
|
36880
|
+
timer = setTimeout(() => reject(new Error(`codex app-server skills/list timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
36881
|
+
proc.on("error", (err) => reject(new Error(`codex app-server spawn failed: ${err.message}`)));
|
|
36882
|
+
});
|
|
36883
|
+
try {
|
|
36884
|
+
await Promise.race([
|
|
36885
|
+
(async () => {
|
|
36886
|
+
await client.request("initialize", {
|
|
36887
|
+
clientInfo: { name: "clawd", title: "clawd", version: "0" },
|
|
36888
|
+
capabilities: null
|
|
36889
|
+
});
|
|
36890
|
+
client.notify("initialized", {});
|
|
36891
|
+
})(),
|
|
36892
|
+
timeout
|
|
36893
|
+
]);
|
|
36894
|
+
const res = await Promise.race([client.request("skills/list", { cwds: [cwd] }), timeout]);
|
|
36895
|
+
return mapSkillsListResponse(res);
|
|
36896
|
+
} finally {
|
|
36897
|
+
if (timer) clearTimeout(timer);
|
|
36898
|
+
if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGTERM");
|
|
36899
|
+
}
|
|
36900
|
+
}
|
|
36901
|
+
|
|
36151
36902
|
// src/workspace/browser.ts
|
|
36152
|
-
var
|
|
36903
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
36153
36904
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
36154
36905
|
var import_node_path11 = __toESM(require("path"), 1);
|
|
36155
36906
|
init_protocol();
|
|
@@ -36165,7 +36916,7 @@ function resolveInsideCwd(cwd, subpath) {
|
|
|
36165
36916
|
}
|
|
36166
36917
|
function ensureCwd(cwd) {
|
|
36167
36918
|
try {
|
|
36168
|
-
const stat =
|
|
36919
|
+
const stat = import_node_fs12.default.statSync(cwd);
|
|
36169
36920
|
if (!stat.isDirectory()) {
|
|
36170
36921
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
36171
36922
|
}
|
|
@@ -36179,7 +36930,7 @@ var WorkspaceBrowser = class {
|
|
|
36179
36930
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
|
|
36180
36931
|
ensureCwd(cwd);
|
|
36181
36932
|
const full = resolveInsideCwd(cwd, args.path);
|
|
36182
|
-
const dirents =
|
|
36933
|
+
const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
|
|
36183
36934
|
const entries = [];
|
|
36184
36935
|
for (const d of dirents) {
|
|
36185
36936
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -36189,7 +36940,7 @@ var WorkspaceBrowser = class {
|
|
|
36189
36940
|
mtime: ""
|
|
36190
36941
|
};
|
|
36191
36942
|
try {
|
|
36192
|
-
const st =
|
|
36943
|
+
const st = import_node_fs12.default.statSync(import_node_path11.default.join(full, d.name));
|
|
36193
36944
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
36194
36945
|
if (d.isFile()) entry.size = st.size;
|
|
36195
36946
|
} catch {
|
|
@@ -36205,14 +36956,14 @@ var WorkspaceBrowser = class {
|
|
|
36205
36956
|
read(args) {
|
|
36206
36957
|
ensureCwd(args.cwd);
|
|
36207
36958
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
36208
|
-
const st =
|
|
36959
|
+
const st = import_node_fs12.default.statSync(full);
|
|
36209
36960
|
if (!st.isFile()) {
|
|
36210
36961
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
36211
36962
|
}
|
|
36212
36963
|
if (st.size > MAX_FILE_BYTES) {
|
|
36213
36964
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
36214
36965
|
}
|
|
36215
|
-
const buf =
|
|
36966
|
+
const buf = import_node_fs12.default.readFileSync(full);
|
|
36216
36967
|
const isBinary = buf.includes(0);
|
|
36217
36968
|
if (isBinary) {
|
|
36218
36969
|
return {
|
|
@@ -36234,20 +36985,20 @@ var WorkspaceBrowser = class {
|
|
|
36234
36985
|
};
|
|
36235
36986
|
|
|
36236
36987
|
// src/skills/agents-scanner.ts
|
|
36237
|
-
var
|
|
36988
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
36238
36989
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
36239
36990
|
var import_node_path12 = __toESM(require("path"), 1);
|
|
36240
36991
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
36241
36992
|
function isDirLikeSync2(p2) {
|
|
36242
36993
|
try {
|
|
36243
|
-
return
|
|
36994
|
+
return import_node_fs13.default.statSync(p2).isDirectory();
|
|
36244
36995
|
} catch {
|
|
36245
36996
|
return false;
|
|
36246
36997
|
}
|
|
36247
36998
|
}
|
|
36248
36999
|
function fileExistsSync(p2) {
|
|
36249
37000
|
try {
|
|
36250
|
-
return
|
|
37001
|
+
return import_node_fs13.default.statSync(p2).isFile();
|
|
36251
37002
|
} catch {
|
|
36252
37003
|
return false;
|
|
36253
37004
|
}
|
|
@@ -36255,7 +37006,7 @@ function fileExistsSync(p2) {
|
|
|
36255
37006
|
function parseAgentFile(filePath) {
|
|
36256
37007
|
let content;
|
|
36257
37008
|
try {
|
|
36258
|
-
content =
|
|
37009
|
+
content = import_node_fs13.default.readFileSync(filePath, "utf8");
|
|
36259
37010
|
} catch {
|
|
36260
37011
|
return {};
|
|
36261
37012
|
}
|
|
@@ -36268,7 +37019,7 @@ function parseAgentFile(filePath) {
|
|
|
36268
37019
|
function scanAgentsDir(dir, source, seen, out) {
|
|
36269
37020
|
let entries;
|
|
36270
37021
|
try {
|
|
36271
|
-
entries =
|
|
37022
|
+
entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
|
|
36272
37023
|
} catch {
|
|
36273
37024
|
return;
|
|
36274
37025
|
}
|
|
@@ -36295,7 +37046,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
36295
37046
|
function walk2(dir, namespaces) {
|
|
36296
37047
|
let entries;
|
|
36297
37048
|
try {
|
|
36298
|
-
entries =
|
|
37049
|
+
entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
|
|
36299
37050
|
} catch {
|
|
36300
37051
|
return;
|
|
36301
37052
|
}
|
|
@@ -36331,7 +37082,7 @@ function readInstalledPlugins2(home) {
|
|
|
36331
37082
|
let raw = null;
|
|
36332
37083
|
for (const candidate of [v2, v1]) {
|
|
36333
37084
|
try {
|
|
36334
|
-
raw =
|
|
37085
|
+
raw = import_node_fs13.default.readFileSync(candidate, "utf8");
|
|
36335
37086
|
break;
|
|
36336
37087
|
} catch {
|
|
36337
37088
|
}
|
|
@@ -36362,7 +37113,7 @@ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
|
36362
37113
|
scanAgentsDir(import_node_path12.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
36363
37114
|
let hasGit = false;
|
|
36364
37115
|
try {
|
|
36365
|
-
hasGit =
|
|
37116
|
+
hasGit = import_node_fs13.default.existsSync(import_node_path12.default.join(cur, ".git"));
|
|
36366
37117
|
} catch {
|
|
36367
37118
|
}
|
|
36368
37119
|
if (hasGit) return;
|
|
@@ -36425,13 +37176,13 @@ var AgentsScanner = class {
|
|
|
36425
37176
|
};
|
|
36426
37177
|
|
|
36427
37178
|
// src/observer/session-observer.ts
|
|
36428
|
-
var
|
|
37179
|
+
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
36429
37180
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
36430
37181
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
36431
37182
|
init_claude_history();
|
|
36432
37183
|
|
|
36433
37184
|
// src/observer/subagent-meta-observer.ts
|
|
36434
|
-
var
|
|
37185
|
+
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
36435
37186
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
36436
37187
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
36437
37188
|
init_claude_history();
|
|
@@ -36476,7 +37227,7 @@ var SubagentMetaObserver = class {
|
|
|
36476
37227
|
attachWatcher(w2) {
|
|
36477
37228
|
if (w2.watcher) return;
|
|
36478
37229
|
try {
|
|
36479
|
-
w2.watcher =
|
|
37230
|
+
w2.watcher = import_node_fs14.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
|
|
36480
37231
|
if (!name) return;
|
|
36481
37232
|
const m2 = META_RE.exec(String(name));
|
|
36482
37233
|
if (!m2) return;
|
|
@@ -36488,7 +37239,7 @@ var SubagentMetaObserver = class {
|
|
|
36488
37239
|
scan(w2) {
|
|
36489
37240
|
let entries;
|
|
36490
37241
|
try {
|
|
36491
|
-
entries =
|
|
37242
|
+
entries = import_node_fs14.default.readdirSync(w2.dirPath);
|
|
36492
37243
|
} catch {
|
|
36493
37244
|
return;
|
|
36494
37245
|
}
|
|
@@ -36505,7 +37256,7 @@ var SubagentMetaObserver = class {
|
|
|
36505
37256
|
const file = import_node_path13.default.join(w2.dirPath, name);
|
|
36506
37257
|
let raw;
|
|
36507
37258
|
try {
|
|
36508
|
-
raw =
|
|
37259
|
+
raw = import_node_fs14.default.readFileSync(file, "utf8");
|
|
36509
37260
|
} catch {
|
|
36510
37261
|
return;
|
|
36511
37262
|
}
|
|
@@ -36569,7 +37320,7 @@ var SessionObserver = class {
|
|
|
36569
37320
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
36570
37321
|
let size = 0;
|
|
36571
37322
|
try {
|
|
36572
|
-
size =
|
|
37323
|
+
size = import_node_fs15.default.statSync(filePath).size;
|
|
36573
37324
|
} catch {
|
|
36574
37325
|
}
|
|
36575
37326
|
const w2 = {
|
|
@@ -36583,10 +37334,10 @@ var SessionObserver = class {
|
|
|
36583
37334
|
prevIsRejectSentinel: false
|
|
36584
37335
|
};
|
|
36585
37336
|
try {
|
|
36586
|
-
|
|
37337
|
+
import_node_fs15.default.mkdirSync(import_node_path14.default.dirname(filePath), { recursive: true });
|
|
36587
37338
|
} catch {
|
|
36588
37339
|
}
|
|
36589
|
-
w2.watcher =
|
|
37340
|
+
w2.watcher = import_node_fs15.default.watch(import_node_path14.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
36590
37341
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
36591
37342
|
this.poll(w2);
|
|
36592
37343
|
});
|
|
@@ -36609,7 +37360,7 @@ var SessionObserver = class {
|
|
|
36609
37360
|
// 异常静默吞,不阻塞 watcher 启动
|
|
36610
37361
|
hydrateMetaTail(w2, maxLines = 200) {
|
|
36611
37362
|
try {
|
|
36612
|
-
const raw =
|
|
37363
|
+
const raw = import_node_fs15.default.readFileSync(w2.filePath, "utf8");
|
|
36613
37364
|
if (!raw) return;
|
|
36614
37365
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
36615
37366
|
if (allLines.length === 0) return;
|
|
@@ -36633,7 +37384,7 @@ var SessionObserver = class {
|
|
|
36633
37384
|
poll(w2) {
|
|
36634
37385
|
let size = 0;
|
|
36635
37386
|
try {
|
|
36636
|
-
size =
|
|
37387
|
+
size = import_node_fs15.default.statSync(w2.filePath).size;
|
|
36637
37388
|
} catch {
|
|
36638
37389
|
return;
|
|
36639
37390
|
}
|
|
@@ -36642,11 +37393,11 @@ var SessionObserver = class {
|
|
|
36642
37393
|
w2.buf = "";
|
|
36643
37394
|
}
|
|
36644
37395
|
if (size === w2.lastSize) return;
|
|
36645
|
-
const fd =
|
|
37396
|
+
const fd = import_node_fs15.default.openSync(w2.filePath, "r");
|
|
36646
37397
|
try {
|
|
36647
37398
|
const len = size - w2.lastSize;
|
|
36648
37399
|
const buf = Buffer.alloc(len);
|
|
36649
|
-
|
|
37400
|
+
import_node_fs15.default.readSync(fd, buf, 0, len, w2.lastSize);
|
|
36650
37401
|
w2.lastSize = size;
|
|
36651
37402
|
w2.buf += buf.toString("utf8");
|
|
36652
37403
|
let newlineIndex;
|
|
@@ -36669,7 +37420,7 @@ var SessionObserver = class {
|
|
|
36669
37420
|
}
|
|
36670
37421
|
}
|
|
36671
37422
|
} finally {
|
|
36672
|
-
|
|
37423
|
+
import_node_fs15.default.closeSync(fd);
|
|
36673
37424
|
}
|
|
36674
37425
|
}
|
|
36675
37426
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -37392,14 +38143,14 @@ async function authenticate(token, deps) {
|
|
|
37392
38143
|
}
|
|
37393
38144
|
|
|
37394
38145
|
// src/permission/capability-store.ts
|
|
37395
|
-
var
|
|
38146
|
+
var fs18 = __toESM(require("fs"), 1);
|
|
37396
38147
|
var path19 = __toESM(require("path"), 1);
|
|
37397
38148
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
37398
38149
|
var FILE_VERSION = 1;
|
|
37399
38150
|
var CapabilityStore = class {
|
|
37400
38151
|
constructor(dataDir) {
|
|
37401
38152
|
this.dataDir = dataDir;
|
|
37402
|
-
|
|
38153
|
+
fs18.mkdirSync(dataDir, { recursive: true });
|
|
37403
38154
|
this.cache = this.readFromDisk();
|
|
37404
38155
|
}
|
|
37405
38156
|
dataDir;
|
|
@@ -37429,7 +38180,7 @@ var CapabilityStore = class {
|
|
|
37429
38180
|
const file = this.filePath();
|
|
37430
38181
|
let raw;
|
|
37431
38182
|
try {
|
|
37432
|
-
raw =
|
|
38183
|
+
raw = fs18.readFileSync(file, "utf8");
|
|
37433
38184
|
} catch (err) {
|
|
37434
38185
|
if (err?.code === "ENOENT") return [];
|
|
37435
38186
|
return [];
|
|
@@ -37457,10 +38208,10 @@ var CapabilityStore = class {
|
|
|
37457
38208
|
}
|
|
37458
38209
|
atomicWrite(file, content) {
|
|
37459
38210
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
37460
|
-
|
|
37461
|
-
|
|
38211
|
+
fs18.writeFileSync(tmp, content, { mode: 384 });
|
|
38212
|
+
fs18.renameSync(tmp, file);
|
|
37462
38213
|
try {
|
|
37463
|
-
|
|
38214
|
+
fs18.chmodSync(file, 384);
|
|
37464
38215
|
} catch {
|
|
37465
38216
|
}
|
|
37466
38217
|
}
|
|
@@ -37553,14 +38304,14 @@ var CapabilityManager = class {
|
|
|
37553
38304
|
};
|
|
37554
38305
|
|
|
37555
38306
|
// src/permission/cleanup.ts
|
|
37556
|
-
var
|
|
38307
|
+
var fs19 = __toESM(require("fs"), 1);
|
|
37557
38308
|
function cleanupGuestSessionsForCapability(cap, factory) {
|
|
37558
38309
|
const removed = [];
|
|
37559
38310
|
for (const g2 of cap.grants) {
|
|
37560
38311
|
if (g2.resource.type !== "persona") continue;
|
|
37561
38312
|
const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
|
|
37562
38313
|
try {
|
|
37563
|
-
|
|
38314
|
+
fs19.rmSync(dir, { recursive: true, force: true });
|
|
37564
38315
|
removed.push(dir);
|
|
37565
38316
|
} catch {
|
|
37566
38317
|
}
|
|
@@ -37569,13 +38320,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
37569
38320
|
}
|
|
37570
38321
|
|
|
37571
38322
|
// src/inbox/inbox-store.ts
|
|
37572
|
-
var
|
|
38323
|
+
var fs20 = __toESM(require("fs"), 1);
|
|
37573
38324
|
var path20 = __toESM(require("path"), 1);
|
|
37574
38325
|
var INBOX_SUBDIR = "inbox";
|
|
37575
38326
|
var InboxStore = class {
|
|
37576
38327
|
constructor(dataDir) {
|
|
37577
38328
|
this.dataDir = dataDir;
|
|
37578
|
-
|
|
38329
|
+
fs20.mkdirSync(this.dirPath(), { recursive: true });
|
|
37579
38330
|
}
|
|
37580
38331
|
dataDir;
|
|
37581
38332
|
/**
|
|
@@ -37587,7 +38338,7 @@ var InboxStore = class {
|
|
|
37587
38338
|
const file = this.filePath(peerDeviceId);
|
|
37588
38339
|
let raw;
|
|
37589
38340
|
try {
|
|
37590
|
-
raw =
|
|
38341
|
+
raw = fs20.readFileSync(file, "utf8");
|
|
37591
38342
|
} catch (err) {
|
|
37592
38343
|
if (err?.code === "ENOENT") return [];
|
|
37593
38344
|
return [];
|
|
@@ -37603,7 +38354,7 @@ var InboxStore = class {
|
|
|
37603
38354
|
const dir = this.dirPath();
|
|
37604
38355
|
let entries;
|
|
37605
38356
|
try {
|
|
37606
|
-
entries =
|
|
38357
|
+
entries = fs20.readdirSync(dir);
|
|
37607
38358
|
} catch (err) {
|
|
37608
38359
|
if (err?.code === "ENOENT") return [];
|
|
37609
38360
|
return [];
|
|
@@ -37619,9 +38370,9 @@ var InboxStore = class {
|
|
|
37619
38370
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
37620
38371
|
const file = this.filePath(message.peerDeviceId);
|
|
37621
38372
|
const line = JSON.stringify(message) + "\n";
|
|
37622
|
-
|
|
38373
|
+
fs20.appendFileSync(file, line, { mode: 384 });
|
|
37623
38374
|
try {
|
|
37624
|
-
|
|
38375
|
+
fs20.chmodSync(file, 384);
|
|
37625
38376
|
} catch {
|
|
37626
38377
|
}
|
|
37627
38378
|
}
|
|
@@ -37651,7 +38402,7 @@ var InboxStore = class {
|
|
|
37651
38402
|
removeByPeerDeviceId(peerDeviceId) {
|
|
37652
38403
|
const file = this.filePath(peerDeviceId);
|
|
37653
38404
|
try {
|
|
37654
|
-
|
|
38405
|
+
fs20.unlinkSync(file);
|
|
37655
38406
|
} catch (err) {
|
|
37656
38407
|
if (err?.code === "ENOENT") return;
|
|
37657
38408
|
}
|
|
@@ -37660,10 +38411,10 @@ var InboxStore = class {
|
|
|
37660
38411
|
const file = this.filePath(peerDeviceId);
|
|
37661
38412
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
37662
38413
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
37663
|
-
|
|
37664
|
-
|
|
38414
|
+
fs20.writeFileSync(tmp, content, { mode: 384 });
|
|
38415
|
+
fs20.renameSync(tmp, file);
|
|
37665
38416
|
try {
|
|
37666
|
-
|
|
38417
|
+
fs20.chmodSync(file, 384);
|
|
37667
38418
|
} catch {
|
|
37668
38419
|
}
|
|
37669
38420
|
}
|
|
@@ -37758,7 +38509,7 @@ var InboxManager = class {
|
|
|
37758
38509
|
};
|
|
37759
38510
|
|
|
37760
38511
|
// src/state/contact-store.ts
|
|
37761
|
-
var
|
|
38512
|
+
var fs21 = __toESM(require("fs"), 1);
|
|
37762
38513
|
var path21 = __toESM(require("path"), 1);
|
|
37763
38514
|
var FILE_NAME = "contacts.json";
|
|
37764
38515
|
var ContactStore = class {
|
|
@@ -37772,7 +38523,7 @@ var ContactStore = class {
|
|
|
37772
38523
|
const file = path21.join(this.dataDir, FILE_NAME);
|
|
37773
38524
|
let raw;
|
|
37774
38525
|
try {
|
|
37775
|
-
raw =
|
|
38526
|
+
raw = fs21.readFileSync(file, "utf8");
|
|
37776
38527
|
} catch (err) {
|
|
37777
38528
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
37778
38529
|
return;
|
|
@@ -37822,13 +38573,13 @@ var ContactStore = class {
|
|
|
37822
38573
|
null,
|
|
37823
38574
|
2
|
|
37824
38575
|
);
|
|
37825
|
-
|
|
37826
|
-
|
|
37827
|
-
|
|
38576
|
+
fs21.mkdirSync(this.dataDir, { recursive: true });
|
|
38577
|
+
fs21.writeFileSync(tmp, content, { mode: 384 });
|
|
38578
|
+
fs21.renameSync(tmp, file);
|
|
37828
38579
|
}
|
|
37829
38580
|
renameBak(file) {
|
|
37830
38581
|
try {
|
|
37831
|
-
|
|
38582
|
+
fs21.renameSync(file, `${file}.bak`);
|
|
37832
38583
|
} catch {
|
|
37833
38584
|
}
|
|
37834
38585
|
}
|
|
@@ -37963,7 +38714,7 @@ async function autoReverseContact(args) {
|
|
|
37963
38714
|
}
|
|
37964
38715
|
|
|
37965
38716
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
37966
|
-
var
|
|
38717
|
+
var fs22 = __toESM(require("fs"), 1);
|
|
37967
38718
|
var path22 = __toESM(require("path"), 1);
|
|
37968
38719
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
37969
38720
|
function migrateFlattenSessions(opts) {
|
|
@@ -37983,7 +38734,7 @@ function migrateFlattenSessions(opts) {
|
|
|
37983
38734
|
if (!entry.endsWith(".json")) continue;
|
|
37984
38735
|
const src = path22.join(defaultDir, entry);
|
|
37985
38736
|
const dst = path22.join(sessionsDir, entry);
|
|
37986
|
-
|
|
38737
|
+
fs22.renameSync(src, dst);
|
|
37987
38738
|
movedBare += 1;
|
|
37988
38739
|
}
|
|
37989
38740
|
rmdirIfEmpty(defaultDir);
|
|
@@ -37995,10 +38746,10 @@ function migrateFlattenSessions(opts) {
|
|
|
37995
38746
|
const ownerSrc = path22.join(personaDir, "owner");
|
|
37996
38747
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
37997
38748
|
const ownerDst = path22.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
37998
|
-
|
|
38749
|
+
fs22.mkdirSync(ownerDst, { recursive: true });
|
|
37999
38750
|
for (const file of readdirSafe(ownerSrc)) {
|
|
38000
38751
|
if (!file.endsWith(".json")) continue;
|
|
38001
|
-
|
|
38752
|
+
fs22.renameSync(path22.join(ownerSrc, file), path22.join(ownerDst, file));
|
|
38002
38753
|
movedVmOwner += 1;
|
|
38003
38754
|
}
|
|
38004
38755
|
rmdirIfEmpty(ownerSrc);
|
|
@@ -38006,18 +38757,18 @@ function migrateFlattenSessions(opts) {
|
|
|
38006
38757
|
const listenerSrc = path22.join(personaDir, "listener");
|
|
38007
38758
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
38008
38759
|
const archiveDst = path22.join(dataDir, ".legacy", `listener-${pid}`);
|
|
38009
|
-
|
|
38760
|
+
fs22.mkdirSync(archiveDst, { recursive: true });
|
|
38010
38761
|
for (const file of readdirSafe(listenerSrc)) {
|
|
38011
38762
|
if (!file.endsWith(".json")) continue;
|
|
38012
|
-
|
|
38763
|
+
fs22.renameSync(path22.join(listenerSrc, file), path22.join(archiveDst, file));
|
|
38013
38764
|
archivedListener += 1;
|
|
38014
38765
|
}
|
|
38015
38766
|
rmdirIfEmpty(listenerSrc);
|
|
38016
38767
|
}
|
|
38017
38768
|
rmdirIfEmpty(personaDir);
|
|
38018
38769
|
}
|
|
38019
|
-
|
|
38020
|
-
|
|
38770
|
+
fs22.mkdirSync(sessionsDir, { recursive: true });
|
|
38771
|
+
fs22.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
38021
38772
|
return {
|
|
38022
38773
|
skipped: false,
|
|
38023
38774
|
flagWritten: true,
|
|
@@ -38028,7 +38779,7 @@ function migrateFlattenSessions(opts) {
|
|
|
38028
38779
|
}
|
|
38029
38780
|
function existsSync3(p2) {
|
|
38030
38781
|
try {
|
|
38031
|
-
|
|
38782
|
+
fs22.statSync(p2);
|
|
38032
38783
|
return true;
|
|
38033
38784
|
} catch {
|
|
38034
38785
|
return false;
|
|
@@ -38036,27 +38787,27 @@ function existsSync3(p2) {
|
|
|
38036
38787
|
}
|
|
38037
38788
|
function isDir(p2) {
|
|
38038
38789
|
try {
|
|
38039
|
-
return
|
|
38790
|
+
return fs22.statSync(p2).isDirectory();
|
|
38040
38791
|
} catch {
|
|
38041
38792
|
return false;
|
|
38042
38793
|
}
|
|
38043
38794
|
}
|
|
38044
38795
|
function readdirSafe(p2) {
|
|
38045
38796
|
try {
|
|
38046
|
-
return
|
|
38797
|
+
return fs22.readdirSync(p2);
|
|
38047
38798
|
} catch {
|
|
38048
38799
|
return [];
|
|
38049
38800
|
}
|
|
38050
38801
|
}
|
|
38051
38802
|
function rmdirIfEmpty(p2) {
|
|
38052
38803
|
try {
|
|
38053
|
-
|
|
38804
|
+
fs22.rmdirSync(p2);
|
|
38054
38805
|
} catch {
|
|
38055
38806
|
}
|
|
38056
38807
|
}
|
|
38057
38808
|
|
|
38058
38809
|
// src/transport/http-router.ts
|
|
38059
|
-
var
|
|
38810
|
+
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
38060
38811
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
38061
38812
|
|
|
38062
38813
|
// src/attachment/mime.ts
|
|
@@ -38236,7 +38987,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
38236
38987
|
}
|
|
38237
38988
|
|
|
38238
38989
|
// src/attachment/upload.ts
|
|
38239
|
-
var
|
|
38990
|
+
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
38240
38991
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
38241
38992
|
var import_node_crypto5 = __toESM(require("crypto"), 1);
|
|
38242
38993
|
var import_promises = require("stream/promises");
|
|
@@ -38258,7 +39009,7 @@ async function writeUploadedAttachment(args) {
|
|
|
38258
39009
|
assertValidFileName(args.fileName);
|
|
38259
39010
|
const attachmentsRoot = import_node_path16.default.join(args.sessionDir, ".attachments");
|
|
38260
39011
|
try {
|
|
38261
|
-
|
|
39012
|
+
import_node_fs16.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
38262
39013
|
} catch (err) {
|
|
38263
39014
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
38264
39015
|
}
|
|
@@ -38279,18 +39030,18 @@ async function writeUploadedAttachment(args) {
|
|
|
38279
39030
|
yield buf;
|
|
38280
39031
|
}
|
|
38281
39032
|
},
|
|
38282
|
-
|
|
39033
|
+
import_node_fs16.default.createWriteStream(tmpPath, { mode: 384 })
|
|
38283
39034
|
);
|
|
38284
39035
|
} catch (err) {
|
|
38285
39036
|
try {
|
|
38286
|
-
|
|
39037
|
+
import_node_fs16.default.unlinkSync(tmpPath);
|
|
38287
39038
|
} catch {
|
|
38288
39039
|
}
|
|
38289
39040
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
38290
39041
|
}
|
|
38291
39042
|
if (actualSize !== args.contentLength) {
|
|
38292
39043
|
try {
|
|
38293
|
-
|
|
39044
|
+
import_node_fs16.default.unlinkSync(tmpPath);
|
|
38294
39045
|
} catch {
|
|
38295
39046
|
}
|
|
38296
39047
|
throw new UploadError(
|
|
@@ -38303,24 +39054,24 @@ async function writeUploadedAttachment(args) {
|
|
|
38303
39054
|
let finalFileName;
|
|
38304
39055
|
let hashDirExists = false;
|
|
38305
39056
|
try {
|
|
38306
|
-
hashDirExists =
|
|
39057
|
+
hashDirExists = import_node_fs16.default.statSync(hashDir).isDirectory();
|
|
38307
39058
|
} catch {
|
|
38308
39059
|
}
|
|
38309
39060
|
if (hashDirExists) {
|
|
38310
|
-
const existing =
|
|
39061
|
+
const existing = import_node_fs16.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
|
|
38311
39062
|
finalFileName = existing[0] ?? args.fileName;
|
|
38312
39063
|
try {
|
|
38313
|
-
|
|
39064
|
+
import_node_fs16.default.unlinkSync(tmpPath);
|
|
38314
39065
|
} catch {
|
|
38315
39066
|
}
|
|
38316
39067
|
} else {
|
|
38317
39068
|
try {
|
|
38318
|
-
|
|
39069
|
+
import_node_fs16.default.mkdirSync(hashDir, { recursive: true });
|
|
38319
39070
|
finalFileName = args.fileName;
|
|
38320
|
-
|
|
39071
|
+
import_node_fs16.default.renameSync(tmpPath, import_node_path16.default.join(hashDir, finalFileName));
|
|
38321
39072
|
} catch (err) {
|
|
38322
39073
|
try {
|
|
38323
|
-
|
|
39074
|
+
import_node_fs16.default.unlinkSync(tmpPath);
|
|
38324
39075
|
} catch {
|
|
38325
39076
|
}
|
|
38326
39077
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
@@ -38844,7 +39595,7 @@ function withCtx(ctx, body) {
|
|
|
38844
39595
|
function streamFile(res, absPath, logger) {
|
|
38845
39596
|
let stat;
|
|
38846
39597
|
try {
|
|
38847
|
-
stat =
|
|
39598
|
+
stat = import_node_fs17.default.statSync(absPath);
|
|
38848
39599
|
} catch (err) {
|
|
38849
39600
|
const code = err?.code;
|
|
38850
39601
|
if (code === "ENOENT") {
|
|
@@ -38867,7 +39618,7 @@ function streamFile(res, absPath, logger) {
|
|
|
38867
39618
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
38868
39619
|
"X-Content-Type-Options": "nosniff"
|
|
38869
39620
|
});
|
|
38870
|
-
const stream =
|
|
39621
|
+
const stream = import_node_fs17.default.createReadStream(absPath);
|
|
38871
39622
|
stream.on("error", (err) => {
|
|
38872
39623
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
38873
39624
|
res.destroy();
|
|
@@ -38876,7 +39627,7 @@ function streamFile(res, absPath, logger) {
|
|
|
38876
39627
|
}
|
|
38877
39628
|
|
|
38878
39629
|
// src/attachment/gc.ts
|
|
38879
|
-
var
|
|
39630
|
+
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
38880
39631
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
38881
39632
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
38882
39633
|
function runAttachmentGc(args) {
|
|
@@ -38899,7 +39650,7 @@ function runAttachmentGc(args) {
|
|
|
38899
39650
|
const attRoot = import_node_path19.default.join(sessionDir, ".attachments");
|
|
38900
39651
|
let hashDirs;
|
|
38901
39652
|
try {
|
|
38902
|
-
hashDirs =
|
|
39653
|
+
hashDirs = import_node_fs18.default.readdirSync(attRoot);
|
|
38903
39654
|
} catch (err) {
|
|
38904
39655
|
if (err.code === "ENOENT") continue;
|
|
38905
39656
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
@@ -38909,7 +39660,7 @@ function runAttachmentGc(args) {
|
|
|
38909
39660
|
const hashDirAbs = import_node_path19.default.join(attRoot, hashDir);
|
|
38910
39661
|
let files;
|
|
38911
39662
|
try {
|
|
38912
|
-
files =
|
|
39663
|
+
files = import_node_fs18.default.readdirSync(hashDirAbs);
|
|
38913
39664
|
} catch {
|
|
38914
39665
|
continue;
|
|
38915
39666
|
}
|
|
@@ -38917,7 +39668,7 @@ function runAttachmentGc(args) {
|
|
|
38917
39668
|
const file = import_node_path19.default.join(hashDirAbs, name);
|
|
38918
39669
|
let stat;
|
|
38919
39670
|
try {
|
|
38920
|
-
stat =
|
|
39671
|
+
stat = import_node_fs18.default.statSync(file);
|
|
38921
39672
|
} catch {
|
|
38922
39673
|
continue;
|
|
38923
39674
|
}
|
|
@@ -38926,25 +39677,25 @@ function runAttachmentGc(args) {
|
|
|
38926
39677
|
if (age < ttlMs) continue;
|
|
38927
39678
|
if (liveAbs.has(file)) continue;
|
|
38928
39679
|
try {
|
|
38929
|
-
|
|
39680
|
+
import_node_fs18.default.unlinkSync(file);
|
|
38930
39681
|
} catch (err) {
|
|
38931
39682
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
38932
39683
|
}
|
|
38933
39684
|
}
|
|
38934
39685
|
try {
|
|
38935
|
-
if (
|
|
39686
|
+
if (import_node_fs18.default.readdirSync(hashDirAbs).length === 0) import_node_fs18.default.rmdirSync(hashDirAbs);
|
|
38936
39687
|
} catch {
|
|
38937
39688
|
}
|
|
38938
39689
|
}
|
|
38939
39690
|
try {
|
|
38940
|
-
if (
|
|
39691
|
+
if (import_node_fs18.default.readdirSync(attRoot).length === 0) import_node_fs18.default.rmdirSync(attRoot);
|
|
38941
39692
|
} catch {
|
|
38942
39693
|
}
|
|
38943
39694
|
}
|
|
38944
39695
|
}
|
|
38945
39696
|
|
|
38946
39697
|
// src/attachment/group.ts
|
|
38947
|
-
var
|
|
39698
|
+
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
38948
39699
|
var import_node_path20 = __toESM(require("path"), 1);
|
|
38949
39700
|
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
38950
39701
|
init_protocol();
|
|
@@ -38970,7 +39721,7 @@ var GroupFileStore = class {
|
|
|
38970
39721
|
readFile(scope, sessionId) {
|
|
38971
39722
|
const file = this.filePath(scope, sessionId);
|
|
38972
39723
|
try {
|
|
38973
|
-
const raw =
|
|
39724
|
+
const raw = import_node_fs19.default.readFileSync(file, "utf8");
|
|
38974
39725
|
const parsed = JSON.parse(raw);
|
|
38975
39726
|
if (!Array.isArray(parsed)) {
|
|
38976
39727
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -38996,10 +39747,10 @@ var GroupFileStore = class {
|
|
|
38996
39747
|
}
|
|
38997
39748
|
writeFile(scope, sessionId, entries) {
|
|
38998
39749
|
const file = this.filePath(scope, sessionId);
|
|
38999
|
-
|
|
39750
|
+
import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(file), { recursive: true });
|
|
39000
39751
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
39001
|
-
|
|
39002
|
-
|
|
39752
|
+
import_node_fs19.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
39753
|
+
import_node_fs19.default.renameSync(tmp, file);
|
|
39003
39754
|
}
|
|
39004
39755
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
39005
39756
|
list(scope, sessionId) {
|
|
@@ -39085,7 +39836,7 @@ var GroupFileStore = class {
|
|
|
39085
39836
|
};
|
|
39086
39837
|
|
|
39087
39838
|
// src/discovery/state-file.ts
|
|
39088
|
-
var
|
|
39839
|
+
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
39089
39840
|
var import_node_path21 = __toESM(require("path"), 1);
|
|
39090
39841
|
function defaultStateFilePath(dataDir) {
|
|
39091
39842
|
return import_node_path21.default.join(dataDir, "state.json");
|
|
@@ -39110,7 +39861,7 @@ var StateFileManager = class {
|
|
|
39110
39861
|
}
|
|
39111
39862
|
read() {
|
|
39112
39863
|
try {
|
|
39113
|
-
const raw =
|
|
39864
|
+
const raw = import_node_fs20.default.readFileSync(this.file, "utf8");
|
|
39114
39865
|
const parsed = JSON.parse(raw);
|
|
39115
39866
|
return parsed;
|
|
39116
39867
|
} catch {
|
|
@@ -39124,41 +39875,33 @@ var StateFileManager = class {
|
|
|
39124
39875
|
return { status: "stale", existing };
|
|
39125
39876
|
}
|
|
39126
39877
|
write(state) {
|
|
39127
|
-
|
|
39878
|
+
import_node_fs20.default.mkdirSync(import_node_path21.default.dirname(this.file), { recursive: true });
|
|
39128
39879
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
39129
|
-
|
|
39130
|
-
|
|
39880
|
+
import_node_fs20.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
39881
|
+
import_node_fs20.default.renameSync(tmp, this.file);
|
|
39131
39882
|
if (process.platform !== "win32") {
|
|
39132
39883
|
try {
|
|
39133
|
-
|
|
39884
|
+
import_node_fs20.default.chmodSync(this.file, 384);
|
|
39134
39885
|
} catch {
|
|
39135
39886
|
}
|
|
39136
39887
|
}
|
|
39137
39888
|
}
|
|
39138
39889
|
delete() {
|
|
39139
39890
|
try {
|
|
39140
|
-
|
|
39891
|
+
import_node_fs20.default.unlinkSync(this.file);
|
|
39141
39892
|
} catch {
|
|
39142
39893
|
}
|
|
39143
39894
|
}
|
|
39144
39895
|
};
|
|
39145
39896
|
|
|
39146
|
-
// src/discovery/source-from-env.ts
|
|
39147
|
-
function readDaemonSourceFromEnv(env = process.env) {
|
|
39148
|
-
const v2 = env.CLAWD_DAEMON_SOURCE;
|
|
39149
|
-
if (typeof v2 !== "string") return void 0;
|
|
39150
|
-
const trimmed = v2.trim();
|
|
39151
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
39152
|
-
}
|
|
39153
|
-
|
|
39154
39897
|
// src/tunnel/tunnel-manager.ts
|
|
39155
|
-
var
|
|
39898
|
+
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
39156
39899
|
var import_node_path25 = __toESM(require("path"), 1);
|
|
39157
39900
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
39158
|
-
var
|
|
39901
|
+
var import_node_child_process9 = require("child_process");
|
|
39159
39902
|
|
|
39160
39903
|
// src/tunnel/tunnel-store.ts
|
|
39161
|
-
var
|
|
39904
|
+
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
39162
39905
|
var import_node_path22 = __toESM(require("path"), 1);
|
|
39163
39906
|
var TunnelStore = class {
|
|
39164
39907
|
constructor(filePath) {
|
|
@@ -39167,7 +39910,7 @@ var TunnelStore = class {
|
|
|
39167
39910
|
filePath;
|
|
39168
39911
|
async get() {
|
|
39169
39912
|
try {
|
|
39170
|
-
const raw = await
|
|
39913
|
+
const raw = await import_node_fs21.default.promises.readFile(this.filePath, "utf8");
|
|
39171
39914
|
const obj = JSON.parse(raw);
|
|
39172
39915
|
if (!isPersistedTunnel(obj)) return null;
|
|
39173
39916
|
return obj;
|
|
@@ -39179,21 +39922,21 @@ var TunnelStore = class {
|
|
|
39179
39922
|
}
|
|
39180
39923
|
async set(v2) {
|
|
39181
39924
|
const dir = import_node_path22.default.dirname(this.filePath);
|
|
39182
|
-
await
|
|
39925
|
+
await import_node_fs21.default.promises.mkdir(dir, { recursive: true });
|
|
39183
39926
|
const data = JSON.stringify(v2, null, 2);
|
|
39184
39927
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
39185
|
-
await
|
|
39928
|
+
await import_node_fs21.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
39186
39929
|
if (process.platform !== "win32") {
|
|
39187
39930
|
try {
|
|
39188
|
-
await
|
|
39931
|
+
await import_node_fs21.default.promises.chmod(tmp, 384);
|
|
39189
39932
|
} catch {
|
|
39190
39933
|
}
|
|
39191
39934
|
}
|
|
39192
|
-
await
|
|
39935
|
+
await import_node_fs21.default.promises.rename(tmp, this.filePath);
|
|
39193
39936
|
}
|
|
39194
39937
|
async clear() {
|
|
39195
39938
|
try {
|
|
39196
|
-
await
|
|
39939
|
+
await import_node_fs21.default.promises.unlink(this.filePath);
|
|
39197
39940
|
} catch (err) {
|
|
39198
39941
|
const code = err?.code;
|
|
39199
39942
|
if (code !== "ENOENT") throw err;
|
|
@@ -39288,10 +40031,10 @@ function escape(v2) {
|
|
|
39288
40031
|
}
|
|
39289
40032
|
|
|
39290
40033
|
// src/tunnel/frpc-binary.ts
|
|
39291
|
-
var
|
|
40034
|
+
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
39292
40035
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
39293
40036
|
var import_node_path23 = __toESM(require("path"), 1);
|
|
39294
|
-
var
|
|
40037
|
+
var import_node_child_process7 = require("child_process");
|
|
39295
40038
|
var import_node_stream2 = require("stream");
|
|
39296
40039
|
var import_promises3 = require("stream/promises");
|
|
39297
40040
|
var FRPC_VERSION = "0.68.0";
|
|
@@ -39322,7 +40065,7 @@ function frpcDownloadUrl(version2, p2) {
|
|
|
39322
40065
|
}
|
|
39323
40066
|
async function ensureFrpcBinary(opts) {
|
|
39324
40067
|
if (opts.override) {
|
|
39325
|
-
if (!
|
|
40068
|
+
if (!import_node_fs22.default.existsSync(opts.override)) {
|
|
39326
40069
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
39327
40070
|
}
|
|
39328
40071
|
return opts.override;
|
|
@@ -39330,10 +40073,10 @@ async function ensureFrpcBinary(opts) {
|
|
|
39330
40073
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
39331
40074
|
const platform = opts.platform ?? detectPlatform();
|
|
39332
40075
|
const binDir = import_node_path23.default.join(opts.dataDir, "bin");
|
|
39333
|
-
|
|
40076
|
+
import_node_fs22.default.mkdirSync(binDir, { recursive: true });
|
|
39334
40077
|
cleanupStaleArtifacts(binDir);
|
|
39335
40078
|
const stableBin = import_node_path23.default.join(binDir, "frpc");
|
|
39336
|
-
if (
|
|
40079
|
+
if (import_node_fs22.default.existsSync(stableBin)) return stableBin;
|
|
39337
40080
|
const partialBin = `${stableBin}.partial`;
|
|
39338
40081
|
const tarballPath = import_node_path23.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
39339
40082
|
try {
|
|
@@ -39344,8 +40087,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
39344
40087
|
} else {
|
|
39345
40088
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
39346
40089
|
}
|
|
39347
|
-
|
|
39348
|
-
|
|
40090
|
+
import_node_fs22.default.chmodSync(partialBin, 493);
|
|
40091
|
+
import_node_fs22.default.renameSync(partialBin, stableBin);
|
|
39349
40092
|
} finally {
|
|
39350
40093
|
safeUnlink(tarballPath);
|
|
39351
40094
|
safeUnlink(partialBin);
|
|
@@ -39355,7 +40098,7 @@ async function ensureFrpcBinary(opts) {
|
|
|
39355
40098
|
function cleanupStaleArtifacts(binDir) {
|
|
39356
40099
|
let entries;
|
|
39357
40100
|
try {
|
|
39358
|
-
entries =
|
|
40101
|
+
entries = import_node_fs22.default.readdirSync(binDir);
|
|
39359
40102
|
} catch {
|
|
39360
40103
|
return;
|
|
39361
40104
|
}
|
|
@@ -39363,7 +40106,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
39363
40106
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
39364
40107
|
const full = import_node_path23.default.join(binDir, name);
|
|
39365
40108
|
try {
|
|
39366
|
-
|
|
40109
|
+
import_node_fs22.default.rmSync(full, { recursive: true, force: true });
|
|
39367
40110
|
} catch {
|
|
39368
40111
|
}
|
|
39369
40112
|
}
|
|
@@ -39371,7 +40114,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
39371
40114
|
}
|
|
39372
40115
|
function safeUnlink(p2) {
|
|
39373
40116
|
try {
|
|
39374
|
-
|
|
40117
|
+
import_node_fs22.default.unlinkSync(p2);
|
|
39375
40118
|
} catch {
|
|
39376
40119
|
}
|
|
39377
40120
|
}
|
|
@@ -39382,46 +40125,46 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
39382
40125
|
if (!res.ok || !res.body) {
|
|
39383
40126
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
39384
40127
|
}
|
|
39385
|
-
const out =
|
|
40128
|
+
const out = import_node_fs22.default.createWriteStream(dest);
|
|
39386
40129
|
const nodeStream = import_node_stream2.Readable.fromWeb(res.body);
|
|
39387
40130
|
await (0, import_promises3.pipeline)(nodeStream, out);
|
|
39388
40131
|
}
|
|
39389
40132
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
39390
40133
|
const work = import_node_path23.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
39391
|
-
|
|
40134
|
+
import_node_fs22.default.mkdirSync(work, { recursive: true });
|
|
39392
40135
|
try {
|
|
39393
40136
|
await new Promise((resolve6, reject) => {
|
|
39394
|
-
const proc = (0,
|
|
40137
|
+
const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
39395
40138
|
proc.on("error", reject);
|
|
39396
40139
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
39397
40140
|
});
|
|
39398
40141
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
39399
40142
|
const src = import_node_path23.default.join(work, dirName, "frpc");
|
|
39400
|
-
if (!
|
|
40143
|
+
if (!import_node_fs22.default.existsSync(src)) {
|
|
39401
40144
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
39402
40145
|
}
|
|
39403
|
-
|
|
40146
|
+
import_node_fs22.default.copyFileSync(src, destBin);
|
|
39404
40147
|
} finally {
|
|
39405
|
-
|
|
40148
|
+
import_node_fs22.default.rmSync(work, { recursive: true, force: true });
|
|
39406
40149
|
}
|
|
39407
40150
|
}
|
|
39408
40151
|
|
|
39409
40152
|
// src/tunnel/frpc-process.ts
|
|
39410
|
-
var
|
|
40153
|
+
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
39411
40154
|
var import_node_path24 = __toESM(require("path"), 1);
|
|
39412
|
-
var
|
|
40155
|
+
var import_node_child_process8 = require("child_process");
|
|
39413
40156
|
function frpcPidFilePath(dataDir) {
|
|
39414
40157
|
return import_node_path24.default.join(dataDir, "frpc.pid");
|
|
39415
40158
|
}
|
|
39416
40159
|
function writeFrpcPid(dataDir, pid) {
|
|
39417
40160
|
try {
|
|
39418
|
-
|
|
40161
|
+
import_node_fs23.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
39419
40162
|
} catch {
|
|
39420
40163
|
}
|
|
39421
40164
|
}
|
|
39422
40165
|
function clearFrpcPid(dataDir) {
|
|
39423
40166
|
try {
|
|
39424
|
-
|
|
40167
|
+
import_node_fs23.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
39425
40168
|
} catch {
|
|
39426
40169
|
}
|
|
39427
40170
|
}
|
|
@@ -39437,7 +40180,7 @@ function defaultIsPidAlive(pid) {
|
|
|
39437
40180
|
}
|
|
39438
40181
|
function defaultReadPidFile(file) {
|
|
39439
40182
|
try {
|
|
39440
|
-
return
|
|
40183
|
+
return import_node_fs23.default.readFileSync(file, "utf8");
|
|
39441
40184
|
} catch {
|
|
39442
40185
|
return null;
|
|
39443
40186
|
}
|
|
@@ -39477,7 +40220,7 @@ async function killStaleFrpc(deps) {
|
|
|
39477
40220
|
}
|
|
39478
40221
|
if (victims.size === 0) {
|
|
39479
40222
|
try {
|
|
39480
|
-
|
|
40223
|
+
import_node_fs23.default.unlinkSync(pidFile);
|
|
39481
40224
|
} catch {
|
|
39482
40225
|
}
|
|
39483
40226
|
return;
|
|
@@ -39488,14 +40231,14 @@ async function killStaleFrpc(deps) {
|
|
|
39488
40231
|
}
|
|
39489
40232
|
await sleep(deps.reapWaitMs ?? 300);
|
|
39490
40233
|
try {
|
|
39491
|
-
|
|
40234
|
+
import_node_fs23.default.unlinkSync(pidFile);
|
|
39492
40235
|
} catch {
|
|
39493
40236
|
}
|
|
39494
40237
|
}
|
|
39495
40238
|
async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
|
|
39496
40239
|
if (process.platform === "win32") return [];
|
|
39497
40240
|
return new Promise((resolve6) => {
|
|
39498
|
-
const ps = (0,
|
|
40241
|
+
const ps = (0, import_node_child_process8.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
|
|
39499
40242
|
let buf = "";
|
|
39500
40243
|
ps.stdout.on("data", (c) => {
|
|
39501
40244
|
buf += c.toString();
|
|
@@ -39663,12 +40406,12 @@ var TunnelManager = class {
|
|
|
39663
40406
|
localPort,
|
|
39664
40407
|
logLevel: "info"
|
|
39665
40408
|
});
|
|
39666
|
-
await
|
|
39667
|
-
const proc = (this.deps.spawnImpl ??
|
|
40409
|
+
await import_node_fs24.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
40410
|
+
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
39668
40411
|
stdio: ["ignore", "pipe", "pipe"]
|
|
39669
40412
|
});
|
|
39670
40413
|
const logFilePath = import_node_path25.default.join(this.deps.dataDir, "frpc.log");
|
|
39671
|
-
const logStream =
|
|
40414
|
+
const logStream = import_node_fs24.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
39672
40415
|
logStream.on("error", () => {
|
|
39673
40416
|
});
|
|
39674
40417
|
const tee = (chunk) => {
|
|
@@ -39766,7 +40509,7 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
39766
40509
|
}
|
|
39767
40510
|
|
|
39768
40511
|
// src/auth-store.ts
|
|
39769
|
-
var
|
|
40512
|
+
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
39770
40513
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
39771
40514
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
39772
40515
|
var AUTH_FILE_NAME = "auth.json";
|
|
@@ -39805,7 +40548,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
39805
40548
|
}
|
|
39806
40549
|
function readAuthFile(file) {
|
|
39807
40550
|
try {
|
|
39808
|
-
const raw =
|
|
40551
|
+
const raw = import_node_fs25.default.readFileSync(file, "utf8");
|
|
39809
40552
|
const parsed = JSON.parse(raw);
|
|
39810
40553
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
39811
40554
|
return null;
|
|
@@ -39824,16 +40567,16 @@ function readAuthFile(file) {
|
|
|
39824
40567
|
}
|
|
39825
40568
|
}
|
|
39826
40569
|
function writeAuthFile(file, content) {
|
|
39827
|
-
|
|
39828
|
-
|
|
40570
|
+
import_node_fs25.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
|
|
40571
|
+
import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
39829
40572
|
try {
|
|
39830
|
-
|
|
40573
|
+
import_node_fs25.default.chmodSync(file, 384);
|
|
39831
40574
|
} catch {
|
|
39832
40575
|
}
|
|
39833
40576
|
}
|
|
39834
40577
|
|
|
39835
40578
|
// src/owner-profile.ts
|
|
39836
|
-
var
|
|
40579
|
+
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
39837
40580
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
39838
40581
|
var import_node_path28 = __toESM(require("path"), 1);
|
|
39839
40582
|
var PROFILE_FILENAME = "profile.json";
|
|
@@ -39842,7 +40585,7 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
39842
40585
|
const profilePath = import_node_path28.default.join(dataDir, PROFILE_FILENAME);
|
|
39843
40586
|
let raw;
|
|
39844
40587
|
try {
|
|
39845
|
-
raw =
|
|
40588
|
+
raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
|
|
39846
40589
|
} catch {
|
|
39847
40590
|
return fallback;
|
|
39848
40591
|
}
|
|
@@ -39865,7 +40608,7 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
39865
40608
|
}
|
|
39866
40609
|
|
|
39867
40610
|
// src/feishu-auth/owner-identity-store.ts
|
|
39868
|
-
var
|
|
40611
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
39869
40612
|
var import_node_path29 = __toESM(require("path"), 1);
|
|
39870
40613
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
39871
40614
|
var OwnerIdentityStore = class {
|
|
@@ -39876,7 +40619,7 @@ var OwnerIdentityStore = class {
|
|
|
39876
40619
|
read() {
|
|
39877
40620
|
let raw;
|
|
39878
40621
|
try {
|
|
39879
|
-
raw =
|
|
40622
|
+
raw = import_node_fs27.default.readFileSync(this.file, "utf8");
|
|
39880
40623
|
} catch {
|
|
39881
40624
|
return null;
|
|
39882
40625
|
}
|
|
@@ -39903,16 +40646,16 @@ var OwnerIdentityStore = class {
|
|
|
39903
40646
|
};
|
|
39904
40647
|
}
|
|
39905
40648
|
write(record) {
|
|
39906
|
-
|
|
39907
|
-
|
|
40649
|
+
import_node_fs27.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
|
|
40650
|
+
import_node_fs27.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
39908
40651
|
try {
|
|
39909
|
-
|
|
40652
|
+
import_node_fs27.default.chmodSync(this.file, 384);
|
|
39910
40653
|
} catch {
|
|
39911
40654
|
}
|
|
39912
40655
|
}
|
|
39913
40656
|
clear() {
|
|
39914
40657
|
try {
|
|
39915
|
-
|
|
40658
|
+
import_node_fs27.default.unlinkSync(this.file);
|
|
39916
40659
|
} catch (err) {
|
|
39917
40660
|
const code = err?.code;
|
|
39918
40661
|
if (code !== "ENOENT") throw err;
|
|
@@ -40175,7 +40918,7 @@ function verifyConnectToken(args) {
|
|
|
40175
40918
|
}
|
|
40176
40919
|
|
|
40177
40920
|
// src/feishu-auth/server-key.ts
|
|
40178
|
-
var
|
|
40921
|
+
var fs36 = __toESM(require("fs"), 1);
|
|
40179
40922
|
var path38 = __toESM(require("path"), 1);
|
|
40180
40923
|
var FILE_NAME2 = "server-signing-key.json";
|
|
40181
40924
|
var ServerKeyStore = class {
|
|
@@ -40189,7 +40932,7 @@ var ServerKeyStore = class {
|
|
|
40189
40932
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
40190
40933
|
read() {
|
|
40191
40934
|
try {
|
|
40192
|
-
const raw =
|
|
40935
|
+
const raw = fs36.readFileSync(this.filePath(), "utf8");
|
|
40193
40936
|
const parsed = JSON.parse(raw);
|
|
40194
40937
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
40195
40938
|
return parsed.publicKeyPem;
|
|
@@ -40204,12 +40947,12 @@ var ServerKeyStore = class {
|
|
|
40204
40947
|
publicKeyPem,
|
|
40205
40948
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
40206
40949
|
};
|
|
40207
|
-
|
|
40208
|
-
|
|
40950
|
+
fs36.mkdirSync(this.dataDir, { recursive: true });
|
|
40951
|
+
fs36.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
40209
40952
|
}
|
|
40210
40953
|
clear() {
|
|
40211
40954
|
try {
|
|
40212
|
-
|
|
40955
|
+
fs36.unlinkSync(this.filePath());
|
|
40213
40956
|
} catch {
|
|
40214
40957
|
}
|
|
40215
40958
|
}
|
|
@@ -40222,12 +40965,12 @@ init_protocol();
|
|
|
40222
40965
|
init_protocol();
|
|
40223
40966
|
|
|
40224
40967
|
// src/session/fork.ts
|
|
40225
|
-
var
|
|
40968
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
40226
40969
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
40227
40970
|
var import_node_path30 = __toESM(require("path"), 1);
|
|
40228
40971
|
init_claude_history();
|
|
40229
40972
|
function readJsonlEntries(file) {
|
|
40230
|
-
const raw =
|
|
40973
|
+
const raw = import_node_fs28.default.readFileSync(file, "utf8");
|
|
40231
40974
|
const out = [];
|
|
40232
40975
|
for (const line of raw.split("\n")) {
|
|
40233
40976
|
const t = line.trim();
|
|
@@ -40243,7 +40986,7 @@ function forkSession(input) {
|
|
|
40243
40986
|
const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os14.default.homedir(), ".claude");
|
|
40244
40987
|
const projectDir = import_node_path30.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
40245
40988
|
const sourceFile = import_node_path30.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
40246
|
-
if (!
|
|
40989
|
+
if (!import_node_fs28.default.existsSync(sourceFile)) {
|
|
40247
40990
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
40248
40991
|
}
|
|
40249
40992
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -40274,8 +41017,8 @@ function forkSession(input) {
|
|
|
40274
41017
|
forkedLines.push(JSON.stringify(forked));
|
|
40275
41018
|
}
|
|
40276
41019
|
const forkedFilePath = import_node_path30.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
40277
|
-
|
|
40278
|
-
|
|
41020
|
+
import_node_fs28.default.mkdirSync(projectDir, { recursive: true });
|
|
41021
|
+
import_node_fs28.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
40279
41022
|
return { forkedToolSessionId, forkedFilePath };
|
|
40280
41023
|
}
|
|
40281
41024
|
|
|
@@ -40337,15 +41080,17 @@ function buildSessionHandlers(deps) {
|
|
|
40337
41080
|
};
|
|
40338
41081
|
const create = async (frame, _client, ctx) => {
|
|
40339
41082
|
const args = SessionCreateArgs.parse(frame);
|
|
41083
|
+
let tool = args.tool;
|
|
40340
41084
|
if (args.ownerPersonaId) {
|
|
40341
41085
|
const persona = deps.personaRegistry.get(args.ownerPersonaId);
|
|
40342
41086
|
if (!persona) {
|
|
40343
41087
|
throw new Error(`persona not found: ${args.ownerPersonaId}`);
|
|
40344
41088
|
}
|
|
41089
|
+
tool = persona.tool ?? args.tool;
|
|
40345
41090
|
}
|
|
40346
41091
|
ensurePersonaAccess(ctx, args.ownerPersonaId, "send");
|
|
40347
41092
|
const creatorPrincipalId = ctx?.principal.id ?? ownerPrincipalId;
|
|
40348
|
-
const { response, broadcast } = manager.create(args, creatorPrincipalId);
|
|
41093
|
+
const { response, broadcast } = manager.create({ ...args, tool }, creatorPrincipalId);
|
|
40349
41094
|
return { response: { type: "session:info", ...response }, broadcast };
|
|
40350
41095
|
};
|
|
40351
41096
|
const list = async (_frame, _client, ctx) => {
|
|
@@ -40465,6 +41210,13 @@ function buildSessionHandlers(deps) {
|
|
|
40465
41210
|
const sessionFile = file;
|
|
40466
41211
|
manager.ensureSession(sessionFile);
|
|
40467
41212
|
const adapter = getAdapter2(sessionFile.tool ?? "claude");
|
|
41213
|
+
const caps = await adapter.capabilities();
|
|
41214
|
+
if (caps.features.observe === false) {
|
|
41215
|
+
throw new ClawdError(
|
|
41216
|
+
ERROR_CODES.TOOL_NOT_SUPPORTED,
|
|
41217
|
+
`tool ${sessionFile.tool ?? "claude"} does not support observe`
|
|
41218
|
+
);
|
|
41219
|
+
}
|
|
40468
41220
|
observer.start({
|
|
40469
41221
|
sessionId: args.sessionId,
|
|
40470
41222
|
cwd: sessionFile.cwd,
|
|
@@ -40714,7 +41466,7 @@ function assertGuestPath(ctx, absPath, personaRoot, method, usersRoot) {
|
|
|
40714
41466
|
}
|
|
40715
41467
|
}
|
|
40716
41468
|
function buildHistoryHandlers(deps) {
|
|
40717
|
-
const { manager, history, store, personaRoot, usersRoot } = deps;
|
|
41469
|
+
const { manager, history, getHistoryReader, store, personaRoot, usersRoot } = deps;
|
|
40718
41470
|
const projects = async (_frame, _client, ctx) => {
|
|
40719
41471
|
const list2 = await history.listProjects();
|
|
40720
41472
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -40758,7 +41510,7 @@ function buildHistoryHandlers(deps) {
|
|
|
40758
41510
|
response: { type: "history:read", messages: [], total: 0, offset: 0 }
|
|
40759
41511
|
};
|
|
40760
41512
|
}
|
|
40761
|
-
const res = await
|
|
41513
|
+
const res = await getHistoryReader(f.tool ?? "claude").read({
|
|
40762
41514
|
cwd: f.cwd,
|
|
40763
41515
|
toolSessionId: f.toolSessionId,
|
|
40764
41516
|
limit: args.limit,
|
|
@@ -40837,7 +41589,7 @@ function assertGuestPath2(ctx, absPath, personaRoot, method, usersRoot) {
|
|
|
40837
41589
|
}
|
|
40838
41590
|
}
|
|
40839
41591
|
function buildWorkspaceHandlers(deps) {
|
|
40840
|
-
const { workspace, skills, agents, personaRoot, personaManager, usersRoot } = deps;
|
|
41592
|
+
const { workspace, skills, agents, getSkillsForTool, personaRoot, personaManager, usersRoot } = deps;
|
|
40841
41593
|
const list = async (frame, _client, ctx) => {
|
|
40842
41594
|
const args = WorkspaceListArgs.parse(frame);
|
|
40843
41595
|
const isGuest = ctx?.principal.kind === "guest";
|
|
@@ -40859,7 +41611,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
40859
41611
|
const args = SkillsListArgs.parse(frame);
|
|
40860
41612
|
const cwdAbs = path42.resolve(args.cwd);
|
|
40861
41613
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
40862
|
-
const list2 =
|
|
41614
|
+
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
40863
41615
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
40864
41616
|
const personaId = personaIdFromPath(cwdAbs, personaRoot);
|
|
40865
41617
|
const enabled = personaId ? buildEnabledPluginNames(personaManager, personaId) : /* @__PURE__ */ new Set();
|
|
@@ -40871,6 +41623,9 @@ function buildWorkspaceHandlers(deps) {
|
|
|
40871
41623
|
const args = AgentsListArgs.parse(frame);
|
|
40872
41624
|
const cwdAbs = path42.resolve(args.cwd);
|
|
40873
41625
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
41626
|
+
if (args.tool === "codex") {
|
|
41627
|
+
return { response: { type: "agents:list", agents: [] } };
|
|
41628
|
+
}
|
|
40874
41629
|
const list2 = agents.list(args);
|
|
40875
41630
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
40876
41631
|
const personaId = personaIdFromPath(cwdAbs, personaRoot);
|
|
@@ -40893,15 +41648,15 @@ init_protocol();
|
|
|
40893
41648
|
init_protocol();
|
|
40894
41649
|
|
|
40895
41650
|
// src/workspace/git.ts
|
|
40896
|
-
var
|
|
40897
|
-
var
|
|
41651
|
+
var import_node_child_process10 = require("child_process");
|
|
41652
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
40898
41653
|
var import_node_path31 = __toESM(require("path"), 1);
|
|
40899
41654
|
var import_node_util = require("util");
|
|
40900
|
-
var pexec = (0, import_node_util.promisify)(
|
|
41655
|
+
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
40901
41656
|
function normalizePath(p2) {
|
|
40902
41657
|
const resolved = import_node_path31.default.resolve(p2);
|
|
40903
41658
|
try {
|
|
40904
|
-
return
|
|
41659
|
+
return import_node_fs29.default.realpathSync(resolved);
|
|
40905
41660
|
} catch {
|
|
40906
41661
|
return resolved;
|
|
40907
41662
|
}
|
|
@@ -42091,22 +42846,22 @@ function pickExtId(frame) {
|
|
|
42091
42846
|
}
|
|
42092
42847
|
return extId;
|
|
42093
42848
|
}
|
|
42094
|
-
function composeState(
|
|
42095
|
-
if (
|
|
42096
|
-
if (manifestMode(
|
|
42849
|
+
function composeState(rec3, running, crashed, getPort) {
|
|
42850
|
+
if (rec3.state === "invalid") return rec3;
|
|
42851
|
+
if (manifestMode(rec3.manifest) === "hosted") {
|
|
42097
42852
|
return {
|
|
42098
|
-
...
|
|
42853
|
+
...rec3,
|
|
42099
42854
|
state: "running",
|
|
42100
|
-
target: { kind: "hosted", url:
|
|
42855
|
+
target: { kind: "hosted", url: rec3.manifest.entry.url }
|
|
42101
42856
|
};
|
|
42102
42857
|
}
|
|
42103
|
-
if (running.has(
|
|
42104
|
-
const port = getPort(
|
|
42105
|
-
if (port == null) return
|
|
42106
|
-
return { ...
|
|
42858
|
+
if (running.has(rec3.extId)) {
|
|
42859
|
+
const port = getPort(rec3.extId);
|
|
42860
|
+
if (port == null) return rec3;
|
|
42861
|
+
return { ...rec3, state: "running", target: { kind: "local", port } };
|
|
42107
42862
|
}
|
|
42108
|
-
if (crashed.has(
|
|
42109
|
-
return
|
|
42863
|
+
if (crashed.has(rec3.extId)) return { ...rec3, state: "crashed" };
|
|
42864
|
+
return rec3;
|
|
42110
42865
|
}
|
|
42111
42866
|
function buildExtensionHandlers(deps) {
|
|
42112
42867
|
const list = async (_frame, _client, ctx) => {
|
|
@@ -42323,7 +43078,7 @@ function buildExtensionHandlers(deps) {
|
|
|
42323
43078
|
}
|
|
42324
43079
|
|
|
42325
43080
|
// src/app-builder/kill-port.ts
|
|
42326
|
-
var
|
|
43081
|
+
var import_node_child_process11 = require("child_process");
|
|
42327
43082
|
async function killPortOccupants(port, ownedPids, logger) {
|
|
42328
43083
|
let pids;
|
|
42329
43084
|
try {
|
|
@@ -42365,7 +43120,7 @@ async function killPortOccupants(port, ownedPids, logger) {
|
|
|
42365
43120
|
}
|
|
42366
43121
|
function listPidsOnPort(port) {
|
|
42367
43122
|
return new Promise((resolve6, reject) => {
|
|
42368
|
-
(0,
|
|
43123
|
+
(0, import_node_child_process11.execFile)(
|
|
42369
43124
|
"lsof",
|
|
42370
43125
|
["-ti", `:${port}`],
|
|
42371
43126
|
{ timeout: 3e3 },
|
|
@@ -42437,8 +43192,8 @@ var PublishJobRegistry = class {
|
|
|
42437
43192
|
};
|
|
42438
43193
|
|
|
42439
43194
|
// src/app-builder/publish-job-runner.ts
|
|
42440
|
-
var
|
|
42441
|
-
var
|
|
43195
|
+
var import_node_child_process12 = require("child_process");
|
|
43196
|
+
var import_node_fs30 = require("fs");
|
|
42442
43197
|
var import_node_path38 = require("path");
|
|
42443
43198
|
|
|
42444
43199
|
// src/app-builder/publish-stage-parser.ts
|
|
@@ -42466,7 +43221,7 @@ function tailStderrLines(buf, n) {
|
|
|
42466
43221
|
// src/app-builder/publish-job-runner.ts
|
|
42467
43222
|
async function startPublishJob(deps, args) {
|
|
42468
43223
|
const { registry: registry2, projectDir } = deps;
|
|
42469
|
-
const
|
|
43224
|
+
const spawn12 = deps.spawnImpl ?? import_node_child_process12.spawn;
|
|
42470
43225
|
if (registry2.has(args.name)) {
|
|
42471
43226
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
42472
43227
|
}
|
|
@@ -42474,11 +43229,11 @@ async function startPublishJob(deps, args) {
|
|
|
42474
43229
|
const logPath = (0, import_node_path38.join)(projDir, ".publish.log");
|
|
42475
43230
|
let logStream = null;
|
|
42476
43231
|
try {
|
|
42477
|
-
logStream = (0,
|
|
43232
|
+
logStream = (0, import_node_fs30.createWriteStream)(logPath, { flags: "w" });
|
|
42478
43233
|
} catch {
|
|
42479
43234
|
logStream = null;
|
|
42480
43235
|
}
|
|
42481
|
-
const child =
|
|
43236
|
+
const child = spawn12("bash", [args.scriptPath, projDir], {
|
|
42482
43237
|
cwd: projDir,
|
|
42483
43238
|
env: process.env,
|
|
42484
43239
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -42732,7 +43487,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
42732
43487
|
// src/handlers/app-builder.ts
|
|
42733
43488
|
init_protocol();
|
|
42734
43489
|
var import_node_path39 = require("path");
|
|
42735
|
-
var
|
|
43490
|
+
var import_node_fs31 = require("fs");
|
|
42736
43491
|
var APP_BUILDER_PERSONAS = ["persona-app-builder"];
|
|
42737
43492
|
var PUBLISH_SCRIPT_REL = "extension-kit/scripts/publish.sh";
|
|
42738
43493
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
@@ -42814,7 +43569,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
42814
43569
|
async function listAllUsersProjects() {
|
|
42815
43570
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
42816
43571
|
const getStore = deps.getStore;
|
|
42817
|
-
const userIds = await
|
|
43572
|
+
const userIds = await import_node_fs31.promises.readdir(deps.usersRoot).catch(() => []);
|
|
42818
43573
|
const perUser = await Promise.all(
|
|
42819
43574
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
42820
43575
|
);
|
|
@@ -43354,8 +44109,8 @@ function buildMethodHandlers(deps) {
|
|
|
43354
44109
|
}
|
|
43355
44110
|
|
|
43356
44111
|
// src/app-builder/project-store.ts
|
|
43357
|
-
var
|
|
43358
|
-
var
|
|
44112
|
+
var import_node_fs32 = require("fs");
|
|
44113
|
+
var import_node_child_process13 = require("child_process");
|
|
43359
44114
|
var import_node_path42 = require("path");
|
|
43360
44115
|
init_protocol();
|
|
43361
44116
|
var PROJECTS_DIR = "projects";
|
|
@@ -43383,7 +44138,7 @@ var ProjectStore = class {
|
|
|
43383
44138
|
async list() {
|
|
43384
44139
|
let entries;
|
|
43385
44140
|
try {
|
|
43386
|
-
entries = await
|
|
44141
|
+
entries = await import_node_fs32.promises.readdir(this.projectsRoot());
|
|
43387
44142
|
} catch (err) {
|
|
43388
44143
|
if (err.code === "ENOENT") return [];
|
|
43389
44144
|
throw err;
|
|
@@ -43391,7 +44146,7 @@ var ProjectStore = class {
|
|
|
43391
44146
|
const out = [];
|
|
43392
44147
|
for (const name of entries) {
|
|
43393
44148
|
try {
|
|
43394
|
-
const raw = await
|
|
44149
|
+
const raw = await import_node_fs32.promises.readFile(this.metaPath(name), "utf8");
|
|
43395
44150
|
const json = JSON.parse(raw);
|
|
43396
44151
|
let migrated = false;
|
|
43397
44152
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -43402,7 +44157,7 @@ var ProjectStore = class {
|
|
|
43402
44157
|
if (parsed.success) {
|
|
43403
44158
|
out.push(parsed.data);
|
|
43404
44159
|
if (migrated) {
|
|
43405
|
-
void
|
|
44160
|
+
void import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
43406
44161
|
});
|
|
43407
44162
|
}
|
|
43408
44163
|
}
|
|
@@ -43446,8 +44201,8 @@ var ProjectStore = class {
|
|
|
43446
44201
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
43447
44202
|
}
|
|
43448
44203
|
const dir = this.projectDir(name);
|
|
43449
|
-
await
|
|
43450
|
-
await
|
|
44204
|
+
await import_node_fs32.promises.mkdir(dir, { recursive: true });
|
|
44205
|
+
await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
43451
44206
|
return meta;
|
|
43452
44207
|
}
|
|
43453
44208
|
/**
|
|
@@ -43462,7 +44217,7 @@ var ProjectStore = class {
|
|
|
43462
44217
|
const scriptPath = (0, import_node_path42.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
|
|
43463
44218
|
const destDir = this.projectDir(name);
|
|
43464
44219
|
return await new Promise((resolve6, reject) => {
|
|
43465
|
-
const child = (0,
|
|
44220
|
+
const child = (0, import_node_child_process13.spawn)("bash", [scriptPath, name, template, destDir], {
|
|
43466
44221
|
cwd: personaRoot,
|
|
43467
44222
|
env: { ...process.env, PATH: process.env.PATH ?? "" },
|
|
43468
44223
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -43492,7 +44247,7 @@ var ProjectStore = class {
|
|
|
43492
44247
|
}
|
|
43493
44248
|
async delete(name) {
|
|
43494
44249
|
const dir = this.projectDir(name);
|
|
43495
|
-
await
|
|
44250
|
+
await import_node_fs32.promises.rm(dir, { recursive: true, force: true });
|
|
43496
44251
|
}
|
|
43497
44252
|
async updatePort(name, newPort) {
|
|
43498
44253
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -43508,7 +44263,7 @@ var ProjectStore = class {
|
|
|
43508
44263
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
43509
44264
|
}
|
|
43510
44265
|
const updated = { ...target, port: newPort };
|
|
43511
|
-
await
|
|
44266
|
+
await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
43512
44267
|
return updated;
|
|
43513
44268
|
}
|
|
43514
44269
|
/**
|
|
@@ -43525,7 +44280,7 @@ var ProjectStore = class {
|
|
|
43525
44280
|
if (!validated.success) {
|
|
43526
44281
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
43527
44282
|
}
|
|
43528
|
-
await
|
|
44283
|
+
await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
43529
44284
|
return validated.data;
|
|
43530
44285
|
}
|
|
43531
44286
|
/**
|
|
@@ -43546,7 +44301,7 @@ var ProjectStore = class {
|
|
|
43546
44301
|
if (!validated.success) {
|
|
43547
44302
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
43548
44303
|
}
|
|
43549
|
-
await
|
|
44304
|
+
await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
43550
44305
|
return validated.data;
|
|
43551
44306
|
}
|
|
43552
44307
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -43561,13 +44316,13 @@ var ProjectStore = class {
|
|
|
43561
44316
|
if (!validated.success) {
|
|
43562
44317
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
43563
44318
|
}
|
|
43564
|
-
await
|
|
44319
|
+
await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
43565
44320
|
return validated.data;
|
|
43566
44321
|
}
|
|
43567
44322
|
};
|
|
43568
44323
|
|
|
43569
44324
|
// src/app-builder/dev-server-supervisor.ts
|
|
43570
|
-
var
|
|
44325
|
+
var import_node_child_process14 = require("child_process");
|
|
43571
44326
|
var import_node_events2 = require("events");
|
|
43572
44327
|
var DEFAULT_READY_PATTERN = /Local:\s+https?:\/\/|Nest application successfully started|server listening on/i;
|
|
43573
44328
|
var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
@@ -43604,7 +44359,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
|
43604
44359
|
tunnelHost: args.tunnelHost,
|
|
43605
44360
|
devCommand: cmd
|
|
43606
44361
|
});
|
|
43607
|
-
const child = (0,
|
|
44362
|
+
const child = (0, import_node_child_process14.spawn)("sh", ["-c", cmd], {
|
|
43608
44363
|
cwd: args.cwd,
|
|
43609
44364
|
env,
|
|
43610
44365
|
stdio: "pipe",
|
|
@@ -43996,7 +44751,7 @@ function computeGrantForFrame(method, frame) {
|
|
|
43996
44751
|
}
|
|
43997
44752
|
|
|
43998
44753
|
// src/extension/runtime.ts
|
|
43999
|
-
var
|
|
44754
|
+
var import_node_child_process15 = require("child_process");
|
|
44000
44755
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
44001
44756
|
var import_promises10 = require("timers/promises");
|
|
44002
44757
|
|
|
@@ -44083,17 +44838,17 @@ var Runtime = class {
|
|
|
44083
44838
|
const existing = this.handles.get(extId);
|
|
44084
44839
|
if (existing) return { kind: "local", port: existing.port };
|
|
44085
44840
|
const records = await loadAll(this.root);
|
|
44086
|
-
const
|
|
44087
|
-
if (!
|
|
44088
|
-
if (
|
|
44089
|
-
throw new RuntimeError("INVALID_MANIFEST",
|
|
44090
|
-
if (manifestMode(
|
|
44091
|
-
return { kind: "hosted", url:
|
|
44841
|
+
const rec3 = records.find((r) => r.extId === extId);
|
|
44842
|
+
if (!rec3) throw new RuntimeError("NOT_FOUND", `extension ${extId} not installed`);
|
|
44843
|
+
if (rec3.state === "invalid")
|
|
44844
|
+
throw new RuntimeError("INVALID_MANIFEST", rec3.invalidReason);
|
|
44845
|
+
if (manifestMode(rec3.manifest) === "hosted") {
|
|
44846
|
+
return { kind: "hosted", url: rec3.manifest.entry.url };
|
|
44092
44847
|
}
|
|
44093
44848
|
const port = await this.allocator.allocate().catch(() => {
|
|
44094
44849
|
throw new RuntimeError("PORT_EXHAUSTED", "no free port in configured range");
|
|
44095
44850
|
});
|
|
44096
|
-
const startCommand =
|
|
44851
|
+
const startCommand = rec3.manifest.runtime.startCommand;
|
|
44097
44852
|
const cmd = startCommand.replace(
|
|
44098
44853
|
/\$CLAWOS_EXT_PORT/g,
|
|
44099
44854
|
String(port)
|
|
@@ -44104,7 +44859,7 @@ var Runtime = class {
|
|
|
44104
44859
|
CLAWOS_EXT_PORT: String(port),
|
|
44105
44860
|
CLAWOS_EXT_ID: extId
|
|
44106
44861
|
};
|
|
44107
|
-
const child = (0,
|
|
44862
|
+
const child = (0, import_node_child_process15.spawn)("sh", ["-c", cmd], {
|
|
44108
44863
|
cwd: dir,
|
|
44109
44864
|
env,
|
|
44110
44865
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -44540,7 +45295,7 @@ async function startDaemon(config) {
|
|
|
44540
45295
|
const absPath = import_node_path46.default.isAbsolute(input.relPath) ? input.relPath : import_node_path46.default.join(input.cwd, input.relPath);
|
|
44541
45296
|
let size = 0;
|
|
44542
45297
|
try {
|
|
44543
|
-
size =
|
|
45298
|
+
size = import_node_fs33.default.statSync(absPath).size;
|
|
44544
45299
|
} catch (err) {
|
|
44545
45300
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
44546
45301
|
sessionId: input.sessionId,
|
|
@@ -44610,6 +45365,7 @@ async function startDaemon(config) {
|
|
|
44610
45365
|
onReady: (tsid) => manager.dispatchReadyDetected(tsid)
|
|
44611
45366
|
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
44612
45367
|
registerAdapter("claude", claudeAdapter);
|
|
45368
|
+
registerAdapter("codex", new CodexAdapter({ logger, historyReader: new CodexHistoryReader() }));
|
|
44613
45369
|
const personaRegistry = new PersonaRegistry(personaStore);
|
|
44614
45370
|
const personaManager = new PersonaManager({
|
|
44615
45371
|
store: personaStore,
|
|
@@ -44688,7 +45444,11 @@ async function startDaemon(config) {
|
|
|
44688
45444
|
workspace,
|
|
44689
45445
|
skills,
|
|
44690
45446
|
agents,
|
|
45447
|
+
// skills:list 按 tool 路由:codex → app-server skills/list;缺省 claude → SkillsScanner(同步包成 Promise)。
|
|
45448
|
+
getSkillsForTool: (tool, cwd) => tool === "codex" ? listCodexSkills(cwd) : Promise.resolve(skills.list({ cwd })),
|
|
44691
45449
|
history,
|
|
45450
|
+
// history:read 按 session.tool 路由:codex → adapter.historyReader(CodexHistoryReader);缺省 claude。
|
|
45451
|
+
getHistoryReader: (tool) => getAdapter(tool).historyReader ?? history,
|
|
44692
45452
|
observer,
|
|
44693
45453
|
getAdapter,
|
|
44694
45454
|
store,
|
|
@@ -45027,8 +45787,7 @@ async function startDaemon(config) {
|
|
|
45027
45787
|
protocolVersion: PROTOCOL_VERSION,
|
|
45028
45788
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
45029
45789
|
authMode,
|
|
45030
|
-
authToken: resolvedAuthToken ?? void 0
|
|
45031
|
-
source: readDaemonSourceFromEnv()
|
|
45790
|
+
authToken: resolvedAuthToken ?? void 0
|
|
45032
45791
|
};
|
|
45033
45792
|
stateMgr.write(stateSnapshot);
|
|
45034
45793
|
process.stdout.write(`Ready: ${url}
|
|
@@ -45079,7 +45838,7 @@ ${bar}
|
|
|
45079
45838
|
`);
|
|
45080
45839
|
try {
|
|
45081
45840
|
const connectPath = import_node_path46.default.join(config.dataDir, "connect.txt");
|
|
45082
|
-
|
|
45841
|
+
import_node_fs33.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
45083
45842
|
} catch {
|
|
45084
45843
|
}
|
|
45085
45844
|
} catch (err) {
|
|
@@ -45152,7 +45911,7 @@ ${bar}
|
|
|
45152
45911
|
function migrateDropPersonsDir(dataDir) {
|
|
45153
45912
|
const dir = import_node_path46.default.join(dataDir, "persons");
|
|
45154
45913
|
try {
|
|
45155
|
-
|
|
45914
|
+
import_node_fs33.default.rmSync(dir, { recursive: true, force: true });
|
|
45156
45915
|
} catch {
|
|
45157
45916
|
}
|
|
45158
45917
|
}
|