docs: improve task skill scoped resolution

Change-Id: I4068d821adf1b249d00950a8f6ff53414825aeff
This commit is contained in:
mayang.my
2026-06-10 23:41:53 +08:00
committed by liangshuo-1
parent feed8fb884
commit 93e4fc7af0
3 changed files with 19 additions and 43 deletions

View File

@@ -16,6 +16,8 @@ metadata:
> **任务清单搜索技巧**:任务清单也遵循同样的判断逻辑。先区分用户是否**特地指定使用搜索 skill**,以及是否真的提供了**清单查询关键字**(例如清单名称、关键词、片段描述)。如果用户特地指定使用搜索 skill或明确给出了清单查询关键字则优先使用 `+tasklist-search`。如果用户没有特地指定使用搜索 skill且意图里没有查询关键字只有范围条件例如“由我创建的任务清单”“今年以来创建的清单”并且使用搜索或原生列取清单都能达到目的时应优先使用原生 `tasklists.list` 接口列取清单(先 `schema task.tasklists.list`,再 `lark-cli task tasklists list --as user ...`),再按 `creator`、`created_at` 等字段做本地筛选和分页控制。
> **意图区分补充**:像“搜索飞书中今年以来我关注的任务”这类表达,虽然字面带有“搜索”,但如果没有真正的查询关键字,且本质是在限定“与我相关 + 时间范围”,则应优先走 `+get-related-tasks`;像“搜索飞书中由我创建的任务清单”这类表达,如果没有清单关键字,且本质是在限定“清单范围 + 创建者”,则应优先走原生 `tasklists.list` 后筛选,而不是直接走搜索型 shortcut。
> **用户身份识别**在用户身份user identity场景下如果用户提到了“我”例如“分配给我”、“由我创建”请默认获取当前登录用户的 `open_id` 作为对应的参数值。
> **清单范围内定位任务优先**:当用户同时给出明确任务清单和任务名称(例如“把 A 清单里的 B 标记完成/更新/查看”)时,先定位清单,再调用原生 `tasklists.tasks` 在该清单内按 `summary` 精确匹配任务;不要直接用任务名称做全局 `task +search`。只有清单任务列表没有唯一命中时,才可用全局搜索兜底;兜底候选必须再 `tasks.get` 验证其 `tasklists[].tasklist_guid` 包含目标清单 GUID 后才能执行写操作。清单内或验证后的候选仍有多个同名任务时,必须让用户确认,不能默认选择第一项。
> **清单范围内解析负责人优先**:当用户同时给出明确任务清单和负责人姓名(例如“在 A 清单里给全名为张三的用户创建待办”)时,先定位清单,再从该清单的 `owner` / `creator` / `members` 候选用户中批量回填姓名并做精确匹配;只有清单候选内没有唯一命中时,才 fallback 到全局 `contact +search-user --query`。全局搜索命中多个同名用户且下一步是创建/分配任务时,必须让用户确认,不能默认选择第一项。
> **术语理解 — 待办 disambiguation必读**
> - 用户提到「待办 / todo / 任务」时,**先判断归属**,不要默认走本 skill。
> - **走 [lark-minutes](../lark-minutes/SKILL.md) 的 `minutes +todo`**(禁止本 skill上下文含 **妙记 / 会议纪要 / minute_token / 妙记 URL**`/minutes/`);或「在某某妙记里新建/修改待办」「妙记 AI 待办」「会议录制里的待办」。
@@ -127,42 +129,3 @@ lark-cli task <resource> <method> [flags] # 调用 API
### agent_task_step_info
- `append_task_steps` — 写入任务记录。
## 权限表
| 方法 | 所需 scope |
|------|-----------|
| `tasks.create` | `task:task:write` |
| `tasks.delete` | `task:task:write` |
| `tasks.get` | `task:task:read` |
| `tasks.list` | `task:task:read` |
| `tasks.patch` | `task:task:write` |
| `tasklists.add_members` | `task:tasklist:write` |
| `tasklists.create` | `task:tasklist:write` |
| `tasklists.delete` | `task:tasklist:write` |
| `tasklists.get` | `task:tasklist:read` |
| `tasklists.list` | `task:tasklist:read` |
| `tasklists.patch` | `task:tasklist:write` |
| `tasklists.remove_members` | `task:tasklist:write` |
| `tasklists.tasks` | `task:tasklist:read` |
| `subtasks.create` | `task:task:write` |
| `subtasks.list` | `task:task:read` |
| `members.add` | `task:task:write` |
| `members.remove` | `task:task:write` |
| `sections.create` | `task:section:write` |
| `sections.delete` | `task:section:write` |
| `sections.get` | `task:section:read` |
| `sections.list` | `task:section:read` |
| `sections.patch` | `task:section:write` |
| `sections.tasks` | `task:section:read` |
| `custom_fields.create` | `task:custom_field:write` |
| `custom_fields.get` | `task:custom_field:read` |
| `custom_fields.patch` | `task:custom_field:write` |
| `custom_fields.list` | `task:custom_field:read` |
| `custom_fields.add` | `task:custom_field:write` |
| `custom_fields.remove` | `task:custom_field:write` |
| `custom_field_options.create` | `task:custom_field:write` |
| `custom_field_options.patch` | `task:custom_field:write` |
| `agent.update_agent_profile` | `task:task:write` |
| `agent.register_agent` | `task:task:write` |
| `agent_task_step_info.append_task_steps` | `task:task:write` |

View File

@@ -20,8 +20,15 @@ lark-cli task +complete --task-id "<task_guid>"
## Workflow
1. Confirm the task to complete.
2. Execute the command.
3. Report success.
2. If the user gives both a tasklist and a task name, resolve the task inside that tasklist before using global task search:
- Locate the tasklist first. If `+tasklist-search` has no recall, use `tasklists.list` pagination and exact local name matching.
- Read incomplete tasks from the list with `lark-cli task tasklists tasks --as user --params '{"tasklist_guid":"<tasklist_guid>","completed":false,"page_size":100,"user_id_type":"open_id"}'`.
- Match `summary` exactly against the requested task name. If exactly one incomplete task matches, use that task `guid`.
- If the incomplete list has no unique exact match, global `lark-cli task +search --query "<task name>" --as user` may be used only as a fallback. For every fallback candidate, call `tasks.get` and keep only candidates whose `tasklists[].tasklist_guid` contains the target tasklist GUID.
- If more than one in-scope task still matches, ask the user to disambiguate before completing; do not choose the first result.
3. Execute `lark-cli task +complete --task-id "<task_guid>"`.
4. Verify completion by reading the same tasklist's incomplete tasks again with `completed:false`; confirm the completed task's `guid` or exact `summary` is absent. Optionally read `completed:true` or `tasks.get` to show the task is now done.
5. Report success.
> [!CAUTION]
> This is a **Write Operation** -- You must confirm the user's intent before executing.

View File

@@ -45,8 +45,14 @@ lark-cli task +create --summary "Test Task" --dry-run
1. Confirm with the user: task summary, due date, assignee, and tasklist if necessary.
- **Crucial Rule for Assignee**: If the user explicitly or implicitly says "create a task for me" (给我创建一个任务), or "help me create a task" (帮我新建/创建一个任务), you MUST assign the task to the current logged-in user. You can get the current user's `open_id` by executing `lark-cli auth status` (it already outputs JSON by default, so do not add `--json`) or `lark-cli contact +get-user` first, extracting `.identities.user.openId` (from `auth status`) or `.data.user.open_id` (from `contact +get-user`), and then passing it to the `--assignee` parameter.
2. Execute `lark-cli task +create --summary "..." ...`
3. Report the result: task ID and summary.
2. If the user provides both a specific tasklist and an assignee name, resolve the assignee within the tasklist context before global contact search:
- Locate the tasklist and collect candidate user IDs from `owner`, `creator`, and `members` (ignore non-user members such as chats).
- Batch hydrate those IDs with `lark-cli contact +search-user --user-ids "<ou_a,ou_b,...>" --as user`.
- Prefer an exact full-name match (`localized_name` equals the requested name). If exactly one user matches, use that `open_id`.
- If there is no exact match in the tasklist candidates, fallback to `lark-cli contact +search-user --query "<name>" --exclude-external-users --as user`.
- If global search returns multiple exact same-name users, ask the user to confirm by email or department before creating the task; do not choose the first result.
3. Execute `lark-cli task +create --summary "..." ...`
4. Report the result: task ID and summary.
> [!CAUTION]
> This is a **Write Operation** -- You must confirm the user's intent before executing.