@keyou007/agent-bot 0.1.15-alpha.1 → 0.1.15-alpha.3

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.
@@ -1,6 +1,7 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { promises as fs } from "node:fs";
2
- import path from "node:path";
3
3
  import os from "node:os";
4
+ import path from "node:path";
4
5
  import { createProjectlessWorkspace, detectProjectlessWorkspace } from "../codex/ProjectlessWorkspace.js";
5
6
  import { resolveUserPath } from "../config/paths.js";
6
7
  import { CommandRouter } from "../commands/CommandRouter.js";
@@ -19,7 +20,8 @@ const MESSAGE_RECEIVED_REACTION = "OnIt";
19
20
  const MESSAGE_COMPLETED_REACTION = "DONE";
20
21
  const MESSAGE_FAILED_REACTION = "ERROR";
21
22
  const MESSAGE_CANCELLED_REACTION = "CrossMark";
22
- const SESSION_PAGE_SIZE = 5;
23
+ const SESSION_PAGE_SIZE = 10;
24
+ const SESSION_PROMPT_PREVIEW_LENGTH = 50;
23
25
  const DIRECTORY_PAGE_SIZE = 15;
24
26
  const RESET_HISTORY_PAGE_SIZE = 10;
25
27
  const MAX_LLM_TURN_RETRIES = 3;
@@ -458,8 +460,18 @@ export class ProxySessionController {
458
460
  }
459
461
  if (!this.store.claimInboundEvent(action.actionId, "card_action"))
460
462
  return;
461
- const contextKey = this.cardActionContextKey(action);
462
- const scopedAction = contextKey === action.contextKey ? action : { ...action, contextKey };
463
+ let resolvedAction;
464
+ try {
465
+ resolvedAction = this.resolveCardActionBinding(action);
466
+ }
467
+ catch (error) {
468
+ await this.sendError(action.contextKey, error);
469
+ return;
470
+ }
471
+ const contextKey = this.cardActionContextKey(resolvedAction);
472
+ const scopedAction = contextKey === resolvedAction.contextKey
473
+ ? resolvedAction
474
+ : { ...resolvedAction, contextKey };
463
475
  const replyTarget = isThreadContextKey(contextKey) && action.messageId
464
476
  ? { messageId: action.messageId, replyInThread: true }
465
477
  : undefined;
@@ -526,6 +538,25 @@ export class ProxySessionController {
526
538
  await this.assertSendableFile(filePath);
527
539
  await this.outbound.sendFile(contextKey, filePath);
528
540
  }
541
+ else if (kind === "directory_new_folder_prompt") {
542
+ const directory = directoryActionPath(scopedAction.value.directory);
543
+ await this.assertBrowsableDirectory(directory);
544
+ await this.outbound.updateInteractiveCard(contextKey, requiredCardMessageId(scopedAction.messageId), this.cardRenderer.renderDirectoryNewFolderCard({
545
+ directory,
546
+ displayDirectory: abbreviateHomeDirectory(directory),
547
+ contextKey,
548
+ page: directoryPageValue(scopedAction.value.page),
549
+ }));
550
+ }
551
+ else if (kind === "directory_new_folder_submit") {
552
+ await this.createDirectoryFromCard(contextKey, scopedAction);
553
+ }
554
+ else if (kind === "directory_new_folder_cancel") {
555
+ await this.openDirectoryBrowser(contextKey, directoryActionPath(scopedAction.value.directory), {
556
+ updateMessageId: requiredCardMessageId(scopedAction.messageId),
557
+ page: directoryPageValue(scopedAction.value.page),
558
+ });
559
+ }
529
560
  else if (kind === "directory_new" || kind === "directory_new_group") {
530
561
  const directory = directoryActionPath(scopedAction.value.directory);
531
562
  await this.assertBrowsableDirectory(directory);
@@ -1218,6 +1249,19 @@ export class ProxySessionController {
1218
1249
  ? turnSession.contextKey
1219
1250
  : action.contextKey;
1220
1251
  }
1252
+ resolveCardActionBinding(action) {
1253
+ if (typeof action.value.action === "string")
1254
+ return action;
1255
+ const token = typeof action.value.t === "string" ? action.value.t : undefined;
1256
+ if (!token)
1257
+ return action;
1258
+ if (!action.messageId)
1259
+ throw new Error("任务列表卡片缺少消息 ID,请重新发送 /sessions。");
1260
+ const value = this.store.getCardActionBinding(action.messageId, token);
1261
+ if (!value)
1262
+ throw new Error("任务列表卡片已失效,请重新发送 /sessions。");
1263
+ return { ...action, value };
1264
+ }
1221
1265
  async execute(contextKey, command, messageId, replyTarget, localImagePaths, userId, incomingMessage) {
1222
1266
  const context = this.store.getOrCreateUserContext(contextKey, this.config.defaults.agent);
1223
1267
  if (!this.currentSession(contextKey) && isThreadContextKey(contextKey) && commandRequiresCurrentSession(command)) {
@@ -3828,12 +3872,12 @@ export class ProxySessionController {
3828
3872
  const card = this.cardRenderer.renderDirectoryBrowserCard({
3829
3873
  directory: abbreviateHomeDirectory(directory),
3830
3874
  entries: visibleEntries,
3831
- currentActions: directoryCreationActions(directory, contextKey),
3875
+ currentActions: directoryCreationActions(directory, contextKey, page),
3832
3876
  navigationActions,
3833
3877
  footerLines: [
3834
3878
  `第 ${page + 1}/${totalPages} 页 · ${directoryCount} 个目录 · ${entries.length - directoryCount} 个文件`,
3835
3879
  "",
3836
- "> 点击目录名称进入,点击文件名称发送到当前会话;卡片顶部的 **New** 和 **NewGroup** 使用当前目录。",
3880
+ "> 点击目录名称进入,点击文件名称发送到当前会话;卡片顶部可新建目录、任务或群聊。",
3837
3881
  ],
3838
3882
  });
3839
3883
  if (options.updateMessageId) {
@@ -3892,6 +3936,28 @@ export class ProxySessionController {
3892
3936
  if (!stats.isDirectory())
3893
3937
  throw new Error(`这不是目录:${directory}`);
3894
3938
  }
3939
+ async createDirectoryFromCard(contextKey, action) {
3940
+ const directory = directoryActionPath(action.value.directory);
3941
+ await this.assertBrowsableDirectory(directory);
3942
+ const folderName = directoryFolderName(cardFormValue(action.value, "folderName"));
3943
+ const newDirectory = path.join(directory, folderName);
3944
+ try {
3945
+ await fs.mkdir(newDirectory);
3946
+ }
3947
+ catch (error) {
3948
+ const code = typeof error === "object" && error !== null && "code" in error
3949
+ ? String(error.code)
3950
+ : undefined;
3951
+ if (code === "EEXIST")
3952
+ throw new Error(`目录已存在:${newDirectory}`);
3953
+ throw new Error(`无法创建目录 ${newDirectory}:${runtimeErrorMessage(error)}`);
3954
+ }
3955
+ await this.openDirectoryBrowser(contextKey, directory, {
3956
+ updateMessageId: requiredCardMessageId(action.messageId),
3957
+ page: directoryPageValue(action.value.page),
3958
+ });
3959
+ await this.outbound.sendText(contextKey, `已创建目录:${newDirectory}`);
3960
+ }
3895
3961
  async assertSendableFile(filePath) {
3896
3962
  let stats;
3897
3963
  try {
@@ -3928,10 +3994,28 @@ export class ProxySessionController {
3928
3994
  const remoteHint = remoteErrors.length > 0
3929
3995
  ? `部分 Agent 的任务读取失败:${remoteErrors.join(";")}`
3930
3996
  : undefined;
3931
- const entries = orderTaskListByProject(mergeTaskList(localSessions, remoteSessions, context.currentSessionId)
3997
+ const latestLocalUserPrompts = new Map();
3998
+ for (const session of localSessions) {
3999
+ const persisted = this.store.findLatestTurnSnapshotForSession(session.localSessionId);
4000
+ const prompt = latestUserPromptFromTurnView(turnViewSnapshot(persisted?.snapshot));
4001
+ if (prompt)
4002
+ latestLocalUserPrompts.set(session.localSessionId, prompt);
4003
+ }
4004
+ const latestRemoteUserPrompts = new Map();
4005
+ for (const { agentName, session: remote } of remoteSessions) {
4006
+ const local = this.store.findSessionByRemoteSessionId(remote.id, undefined, agentName);
4007
+ if (!local)
4008
+ continue;
4009
+ const persisted = this.store.findLatestTurnSnapshotForSession(local.localSessionId);
4010
+ const prompt = latestUserPromptFromTurnView(turnViewSnapshot(persisted?.snapshot));
4011
+ if (prompt)
4012
+ latestRemoteUserPrompts.set(agentRemoteKey(agentName, remote.id), prompt);
4013
+ }
4014
+ const globallyOrderedEntries = orderTaskListByRecency(mergeTaskList(localSessions, remoteSessions, context.currentSessionId, latestLocalUserPrompts, latestRemoteUserPrompts)
3932
4015
  .filter((entry) => !normalizedSearch
3933
4016
  || [entry.id, entry.title, entry.cwd, entry.agentName]
3934
4017
  .some((value) => value.toLowerCase().includes(normalizedSearch))));
4018
+ const entries = groupTaskListPagesByProject(globallyOrderedEntries, SESSION_PAGE_SIZE);
3935
4019
  const activeCount = entries.filter((entry) => entry.active).length;
3936
4020
  const lastKnownPage = Math.max(0, Math.ceil(entries.length / SESSION_PAGE_SIZE) - 1);
3937
4021
  const page = remoteHasMore ? requestedPage : Math.min(requestedPage, lastKnownPage);
@@ -3946,14 +4030,16 @@ export class ProxySessionController {
3946
4030
  const hasPrevious = page > 0;
3947
4031
  const hasNext = remoteHasMore || entries.length > offset + SESSION_PAGE_SIZE;
3948
4032
  this.lastSessionListings.set(contextKey, entries.map((entry) => entry.reference));
4033
+ const cardActionBindings = new Map();
4034
+ const bindCardAction = (action) => bindSessionCardAction(action, cardActionBindings);
3949
4035
  const cardEntries = visibleEntries.map((entry, index) => {
3950
4036
  const project = taskProjectInfo(entry);
3951
4037
  const projectActionSource = projectActionSources.get(project.key) ?? entry;
3952
- const marker = entry.current ? "✅" : entry.active ? "🟢" : "•";
4038
+ const marker = entry.current ? "✅ " : entry.active ? "🟢 " : "";
3953
4039
  const showStop = entry.status === "外部执行中"
3954
4040
  && entry.reference !== options.forceSwitchTaskId
3955
4041
  && entry.id !== options.forceSwitchTaskId;
3956
- const actions = entry.current ? [] : [{
4042
+ const actions = entry.current ? [] : [bindCardAction({
3957
4043
  text: showStop ? "Stop" : "Switch",
3958
4044
  type: showStop ? "danger" : "default",
3959
4045
  value: {
@@ -3963,8 +4049,8 @@ export class ProxySessionController {
3963
4049
  page: String(page),
3964
4050
  contextKey,
3965
4051
  },
3966
- }];
3967
- const projectActions = [{
4052
+ })];
4053
+ const projectActions = [bindCardAction({
3968
4054
  text: "New",
3969
4055
  value: {
3970
4056
  action: "session_new",
@@ -3973,7 +4059,7 @@ export class ProxySessionController {
3973
4059
  page: String(page),
3974
4060
  contextKey,
3975
4061
  },
3976
- }, {
4062
+ }), bindCardAction({
3977
4063
  text: "NewGroup",
3978
4064
  value: {
3979
4065
  action: "session_new_group",
@@ -3982,8 +4068,8 @@ export class ProxySessionController {
3982
4068
  page: String(page),
3983
4069
  contextKey,
3984
4070
  },
3985
- }];
3986
- actions.push({
4071
+ })];
4072
+ actions.push(bindCardAction({
3987
4073
  text: "Fork",
3988
4074
  value: {
3989
4075
  action: "session_fork",
@@ -3992,8 +4078,8 @@ export class ProxySessionController {
3992
4078
  page: String(page),
3993
4079
  contextKey,
3994
4080
  },
3995
- });
3996
- actions.push({
4081
+ }));
4082
+ actions.push(bindCardAction({
3997
4083
  text: "ForkGroup",
3998
4084
  value: {
3999
4085
  action: "session_fork_group",
@@ -4002,16 +4088,16 @@ export class ProxySessionController {
4002
4088
  page: String(page),
4003
4089
  contextKey,
4004
4090
  },
4005
- });
4006
- actions.push({
4091
+ }));
4092
+ actions.push(bindCardAction({
4007
4093
  text: "Status",
4008
4094
  value: {
4009
4095
  action: "session_status",
4010
4096
  sessionId: entry.reference,
4011
4097
  contextKey,
4012
4098
  },
4013
- });
4014
- actions.push({
4099
+ }));
4100
+ actions.push(bindCardAction({
4015
4101
  text: "Archive",
4016
4102
  value: {
4017
4103
  action: "session_archive",
@@ -4020,18 +4106,18 @@ export class ProxySessionController {
4020
4106
  page: String(page),
4021
4107
  contextKey,
4022
4108
  },
4023
- });
4109
+ }));
4024
4110
  const title = truncateText(entry.title.replace(/\s+/gu, " ").trim() || "未命名任务", 56);
4111
+ const lastUserPrompt = sessionPromptPreview(entry.lastUserPrompt);
4025
4112
  return {
4026
4113
  project,
4027
4114
  projectActions,
4028
4115
  cardEntry: {
4029
4116
  reference: entry.reference,
4030
- summary: `${offset + index + 1}. ${marker} ${title} · ${entry.agentName}`,
4117
+ summary: `${offset + index + 1}. ${marker}${title} · ${entry.agentName}`,
4031
4118
  detailLines: [
4032
- `**状态 / 更新时间**:${cardText(entry.status)} / ${cardText(entry.updatedLabel)}`,
4033
- `**Agent / 任务 ID**:${cardCode(entry.agentName)} / ${cardCode(entry.id)}`,
4034
- `**目录**:${cardCode(entry.cwd || "目录未知")}`,
4119
+ cardText(lastUserPrompt),
4120
+ `**更新时间**:${cardText(entry.updatedLabel)}`,
4035
4121
  ],
4036
4122
  actions,
4037
4123
  current: entry.current,
@@ -4058,10 +4144,10 @@ export class ProxySessionController {
4058
4144
  ...(remoteHint ? [remoteHint] : []),
4059
4145
  `第 ${page + 1} 页 · 每页 ${SESSION_PAGE_SIZE} 个任务${hasNext ? "" : ` · 当前共 ${entries.length} 个任务`}`,
4060
4146
  "",
4061
- "> 项目行:**New** 新建任务,**NewGroup** 新建群。",
4147
+ "> 项目菜单:**New** 新建任务,**NewGroup** 新建群。",
4062
4148
  "> 任务详情:**Switch** 切换,**Stop** 停止,**Fork** / **ForkGroup** 创建分支,**Status** 查看状态,**Archive** 归档。",
4063
4149
  ], [
4064
- ...(hasPrevious ? [{
4150
+ ...(hasPrevious ? [bindCardAction({
4065
4151
  text: "Previous",
4066
4152
  value: {
4067
4153
  action: "session_page",
@@ -4069,8 +4155,8 @@ export class ProxySessionController {
4069
4155
  page: String(page - 1),
4070
4156
  contextKey,
4071
4157
  },
4072
- }] : []),
4073
- ...(hasNext ? [{
4158
+ })] : []),
4159
+ ...(hasNext ? [bindCardAction({
4074
4160
  text: "Next",
4075
4161
  value: {
4076
4162
  action: "session_page",
@@ -4078,13 +4164,20 @@ export class ProxySessionController {
4078
4164
  page: String(page + 1),
4079
4165
  contextKey,
4080
4166
  },
4081
- }] : []),
4167
+ })] : []),
4082
4168
  ]);
4169
+ const bindings = [...cardActionBindings.values()];
4083
4170
  if (options.updateMessageId) {
4171
+ this.store.upsertCardActionBindings(options.updateMessageId, bindings);
4084
4172
  await this.outbound.updateInteractiveCard(contextKey, options.updateMessageId, card);
4173
+ this.store.retainCardActionBindings(options.updateMessageId, bindings.map((binding) => binding.token));
4085
4174
  }
4086
4175
  else {
4087
- await this.outbound.sendInteractiveCard(contextKey, card);
4176
+ const messageId = await this.outbound.sendInteractiveCard(contextKey, card);
4177
+ if (messageId) {
4178
+ this.store.upsertCardActionBindings(messageId, bindings);
4179
+ this.store.retainCardActionBindings(messageId, bindings.map((binding) => binding.token));
4180
+ }
4088
4181
  }
4089
4182
  }
4090
4183
  async refreshSessionsCardFromAction(action, options = {}) {
@@ -4774,28 +4867,26 @@ function statusRefreshAction(sessionId, contextKey) {
4774
4867
  },
4775
4868
  };
4776
4869
  }
4777
- function orderTaskListByProject(entries) {
4778
- const groups = new Map();
4779
- for (const entry of entries) {
4780
- const project = taskProjectInfo(entry);
4781
- const group = groups.get(project.key);
4782
- if (group)
4783
- group.entries.push(entry);
4784
- else
4785
- groups.set(project.key, { project, entries: [entry] });
4786
- }
4787
- const orderedGroups = [...groups.values()]
4788
- .map((group) => ({
4789
- ...group,
4790
- current: group.entries.some((entry) => entry.current),
4791
- active: group.entries.some((entry) => entry.active),
4792
- updatedAt: Math.max(...group.entries.map((entry) => entry.updatedAt)),
4793
- }))
4794
- .sort((left, right) => Number(right.current) - Number(left.current)
4795
- || Number(right.active) - Number(left.active)
4796
- || right.updatedAt - left.updatedAt
4797
- || left.project.title.localeCompare(right.project.title, undefined, { sensitivity: "base" }));
4798
- return orderedGroups.flatMap((group) => group.entries.sort(compareTaskListEntries));
4870
+ function orderTaskListByRecency(entries) {
4871
+ return [...entries].sort(compareTaskListEntries);
4872
+ }
4873
+ function groupTaskListPagesByProject(entries, pageSize) {
4874
+ const result = [];
4875
+ for (let offset = 0; offset < entries.length; offset += pageSize) {
4876
+ const groups = new Map();
4877
+ for (const entry of entries.slice(offset, offset + pageSize)) {
4878
+ const key = taskProjectInfo(entry).key;
4879
+ const group = groups.get(key);
4880
+ if (group)
4881
+ group.push(entry);
4882
+ else
4883
+ groups.set(key, [entry]);
4884
+ }
4885
+ for (const group of groups.values()) {
4886
+ result.push(...group.sort(compareTaskListEntries));
4887
+ }
4888
+ }
4889
+ return result;
4799
4890
  }
4800
4891
  function compareTaskListEntries(left, right) {
4801
4892
  return Number(right.current) - Number(left.current)
@@ -4818,7 +4909,7 @@ function taskProjectInfo(entry) {
4818
4909
  title: `📁 ${abbreviateHomeDirectory(entry.cwd)}`,
4819
4910
  };
4820
4911
  }
4821
- function mergeTaskList(localSessions, remoteSessions, currentLocalSessionId) {
4912
+ function mergeTaskList(localSessions, remoteSessions, currentLocalSessionId, latestLocalUserPrompts = new Map(), latestRemoteUserPrompts = new Map()) {
4822
4913
  const localByRemoteId = new Map(localSessions
4823
4914
  .filter((session) => session.runtimeKind === "codex" && session.remoteSessionId)
4824
4915
  .map((session) => [agentRemoteKey(session.agentName, session.remoteSessionId), session]));
@@ -4841,6 +4932,9 @@ function mergeTaskList(localSessions, remoteSessions, currentLocalSessionId) {
4841
4932
  status,
4842
4933
  active,
4843
4934
  current: Boolean(local && local.localSessionId === currentLocalSessionId),
4935
+ lastUserPrompt: remote.lastUserPrompt
4936
+ ?? (local ? latestLocalUserPrompts.get(local.localSessionId) : undefined)
4937
+ ?? latestRemoteUserPrompts.get(agentRemoteKey(agentName, remote.id)),
4844
4938
  updatedAt: (recencyAt ?? 0) * 1_000,
4845
4939
  updatedLabel: formatRemoteTime(recencyAt),
4846
4940
  };
@@ -4860,6 +4954,7 @@ function mergeTaskList(localSessions, remoteSessions, currentLocalSessionId) {
4860
4954
  status: sessionStatusLabel(local.status),
4861
4955
  active: local.status === "running",
4862
4956
  current: local.localSessionId === currentLocalSessionId,
4957
+ lastUserPrompt: latestLocalUserPrompts.get(local.localSessionId),
4863
4958
  updatedAt: Number.isNaN(updatedAt) ? 0 : updatedAt,
4864
4959
  updatedLabel: formatStatusTime(local.updatedAt),
4865
4960
  });
@@ -4888,6 +4983,16 @@ function parseRemoteSessionReference(reference) {
4888
4983
  return undefined;
4889
4984
  }
4890
4985
  }
4986
+ function bindSessionCardAction(action, bindings) {
4987
+ const serialized = JSON.stringify(action.value);
4988
+ const token = createHash("sha256").update(serialized).digest("hex").slice(0, 16);
4989
+ const existing = bindings.get(token);
4990
+ if (existing && JSON.stringify(existing.value) !== serialized) {
4991
+ throw new Error("任务列表卡片操作令牌发生冲突,请重试。");
4992
+ }
4993
+ bindings.set(token, { token, value: action.value });
4994
+ return { ...action, value: { t: token } };
4995
+ }
4891
4996
  function runtimeErrorMessage(error) {
4892
4997
  return error instanceof Error ? error.message : String(error);
4893
4998
  }
@@ -4907,6 +5012,19 @@ function turnViewSnapshot(value) {
4907
5012
  ? candidate
4908
5013
  : undefined;
4909
5014
  }
5015
+ function latestUserPromptFromTurnView(snapshot) {
5016
+ const latestUserActivity = [...(snapshot?.activities ?? [])]
5017
+ .reverse()
5018
+ .find((activity) => activity.kind === "user" && Boolean(activity.text.trim()));
5019
+ return latestUserActivity?.text.trim() || snapshot?.prompt?.trim() || undefined;
5020
+ }
5021
+ function sessionPromptPreview(prompt) {
5022
+ const normalized = prompt?.replace(/\s+/gu, " ").trim() || "暂无用户 Prompt";
5023
+ const characters = Array.from(normalized);
5024
+ return characters.length > SESSION_PROMPT_PREVIEW_LENGTH
5025
+ ? `${characters.slice(0, SESSION_PROMPT_PREVIEW_LENGTH).join("")}...`
5026
+ : normalized;
5027
+ }
4910
5028
  function isTerminalTurnViewStatus(status) {
4911
5029
  return status === "completed" || status === "cancelled" || status === "failed";
4912
5030
  }
@@ -5242,10 +5360,43 @@ function directoryFileActionPath(value) {
5242
5360
  }
5243
5361
  return path.resolve(value);
5244
5362
  }
5245
- function directoryCreationActions(directory, contextKey) {
5363
+ function cardFormValue(value, name) {
5364
+ const formValue = value.formValue;
5365
+ return typeof formValue === "object" && formValue !== null
5366
+ ? formValue[name]
5367
+ : undefined;
5368
+ }
5369
+ function directoryFolderName(value) {
5370
+ if (typeof value !== "string" || !value.trim())
5371
+ throw new Error("请输入目录名。");
5372
+ const name = value.trim();
5373
+ if (name === "." || name === "..")
5374
+ throw new Error("目录名不能是 . 或 ..。");
5375
+ if (name.length > 255)
5376
+ throw new Error("目录名不能超过 255 个字符。");
5377
+ if (/[<>:"/\\|?*\u0000-\u001F]/u.test(name)) {
5378
+ throw new Error("目录名不能包含路径分隔符或以下字符:< > : \" / \\ | ? *");
5379
+ }
5380
+ if (/[. ]$/u.test(name))
5381
+ throw new Error("目录名不能以空格或句点结尾。");
5382
+ if (/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/iu.test(name)) {
5383
+ throw new Error("该名称是系统保留名称,请使用其他目录名。");
5384
+ }
5385
+ return name;
5386
+ }
5387
+ function directoryCreationActions(directory, contextKey, page) {
5246
5388
  return [
5247
5389
  {
5248
- text: "New",
5390
+ text: "NewFolder",
5391
+ value: {
5392
+ action: "directory_new_folder_prompt",
5393
+ directory,
5394
+ contextKey,
5395
+ page: String(page),
5396
+ },
5397
+ },
5398
+ {
5399
+ text: "NewTask",
5249
5400
  value: {
5250
5401
  action: "directory_new",
5251
5402
  directory,
@@ -5253,7 +5404,7 @@ function directoryCreationActions(directory, contextKey) {
5253
5404
  },
5254
5405
  },
5255
5406
  {
5256
- text: "NewGroup",
5407
+ text: "NewGroupTask",
5257
5408
  value: {
5258
5409
  action: "directory_new_group",
5259
5410
  directory,