[Feature]: Lark Task Source
@brennanb2025 is already working on this.
Since Jul 13, 2026.
- Dominant language
- TypeScript
- Stars
- 72.1k
- Forks
- 4.7k
- Avg merge
- 14h 54m
- Merged PRs (30d)
- 520
Description
Problem or use case
Developers who track work in Feishu/Lark Task Center cannot use Orca’s Tasks surface for that work. They switch between Lark and Orca: check a Preferred list in the browser, copy context by hand, and mark tasks done outside the editor. Existing Task Sources (GitHub, GitLab, Linear, Jira) do not cover Lark, so Feishu-centric teams lose the same “pick source → list work → open detail → create/complete” loop that other providers already provide.
Proposed solution
Add Lark as a first-class Task Source in Tasks. Users bind a Preferred Lark Tasklist to each Orca project, list Open Lark Tasks in that list, open a read-only detail drawer (with complete/reopen and open-in-Lark/Feishu), and create tasks (title, description, optional due) into that list. All access goes through a local Lark CLI Session (lark-cli, Lark User Identity only). Orca never stores Lark tokens and never runs lark-cli on the project’s SSH host. The provider is always selectable (like Jira); missing CLI or login shows a clear empty state.
Alternatives or additional context
User Stories
- As an Orca user, I want Lark to appear as a Task Source alongside GitHub, GitLab, Linear, and Jira, so that I can work Feishu/Lark tasks without leaving Orca.
- As an Orca user, I want the Tasks settings pane to let me show or hide Lark like other providers, so that I can keep my source picker focused.
- As an Orca user, I want at least one Task Source to remain visible, so that Tasks never ends up with an empty provider set after editing visibility.
- As an Orca user, I want Lark to remain visible in the source picker even when
lark-cliis missing, so that I can discover how to connect instead of hunting for a hidden integration. - As an Orca user, I want Lark to remain visible when I am logged out of
lark-cli, so that the login empty state is reachable from Tasks. - As an Orca user without
lark-cliinstalled, I want a clear empty state that tells me to installlark-cli, so that I know the exact dependency. - As an Orca user with
lark-cliinstalled but no user session, I want a clear empty state that tells me to runlark-cli auth login, so that I can connect without Orca storing tokens. - As an Orca user with a usable Lark CLI Session, I want status to show that I am connected as my current CLI user (name when available), so that I know which identity is acting.
- As an Orca user with multiple CLI logins, I want Orca to always use the CLI’s current user, so that account switching stays in
lark-cliand Orca does not invent a second account picker. - As an Orca user, I want all Lark operations to use user identity (
--as user), so that personal tasklists and human ownership behave correctly. - As an Orca user on an SSH-backed project, I want Lark tasks to still load from my local machine’s
lark-cli, so that I do not need Feishu login on the remote host. - As an Orca user, I want the UI label to say “Lark” or “Feishu” according to CLI brand or locale, so that the product name matches my region while the provider id stays
lark. - As an Orca user opening Tasks on a project with no Preferred Lark Tasklist, I want an empty state with a searchable tasklist picker, so that I can bind a list without leaving Tasks.
- As an Orca user, I want tasklist search to find lists by keyword, so that I can locate the right list among many.
- As an Orca user, I want to browse discoverable tasklists when I do not know a keyword, so that first-time setup still works.
- As an Orca user, I want selecting a tasklist to save it as that Orca project’s Preferred Lark Tasklist, so that the next visit reuses the same scope.
- As an Orca user, I want switching Orca projects to switch the Preferred Lark Tasklist with the project, so that each project keeps its own work container.
- As an Orca user, I want to change the Preferred Lark Tasklist later via a scope control, so that I can rebind without deleting the project.
- As an Orca user whose Preferred Lark Tasklist is deleted or inaccessible, I want an error that keeps the stored binding and offers Change tasklist, so that transient failures do not wipe my preference.
- As an Orca user with a valid Preferred Lark Tasklist, I want the main list to show Open Lark Tasks only by default, so that I see work still to do.
- As an Orca user, I want a control to show completed tasks in that list, so that I can verify recently finished work.
- As an Orca user, I want the list to load without keyword search in v1, so that the product stays scoped to the Preferred list without global search ambiguity.
- As an Orca user, I want each row to show enough identity to recognize the task (title, open/done, due if any, human-facing number if available), so that I can scan quickly.
- As an Orca user, I want opening a row to show a detail drawer with title, description, status, due, assignees when available, and link, so that I can read the task in Orca.
- As an Orca user, I want detail to be read-only for fields in v1, so that I am not blocked waiting for full edit parity.
- As an Orca user, I want Complete and Reopen actions in the detail drawer, so that I can finish or revive work without leaving Orca.
- As an Orca user, I want optional Complete/Reopen on the list row if the product already does that for other sources, so that muscle memory stays consistent.
- As an Orca user, I want an Open in Lark/Feishu action that uses the task URL from the CLI, so that I can jump to the full Task Center when needed.
- As an Orca user, I want create to target the Preferred Lark Tasklist automatically, so that I never re-pick the list on every create.
- As an Orca user, I want create to require a title (summary), so that empty tasks are not created by mistake.
- As an Orca user, I want optional description on create, so that I can capture context at creation time.
- As an Orca user, I want optional due date on create, so that time-bound work is visible in Lark and in Orca.
- As an Orca user, I want create to fail clearly if there is no Preferred Lark Tasklist, so that I am guided to bind a list first.
- As an Orca user, I want successful create to refresh or insert the new Open Lark Task into the list, so that I see my work immediately.
- As an Orca user, I want complete to remove the task from the default Open view (or mark it done under the completed filter), so that list state matches Lark.
- As an Orca user, I want reopen to return a task to the Open list, so that mistakes are recoverable.
- As an Orca user, I want mutations to address tasks by GUID even when the UI shows a human-facing number, so that operations stay correct.
- As an Orca user, I want connection and list errors to be classified (missing tool, missing auth, permission, not found, generic), so that the UI can show the right recovery.
- As an agent implementing this feature, I want Preferred Lark Tasklist identity in Task Source context / cache scope, so that caches do not collide across projects or lists.
- As an agent implementing this feature, I want Lark included in TaskProvider normalization, so that settings and picker never drop an unknown provider id after upgrade.
- As an Orca user, I want sidebar / Tasks shortcuts to treat Lark like other visible providers when enabled, so that navigation is consistent.
- As an Orca user, I want Minutes (妙记) todos to remain out of this Task Source, so that I am not confused with a different Feishu product surface.
- As an Orca user, I want no requirement to paste API tokens into Orca for Lark, so that secrets stay in the CLI session.
- As an Orca user returning after
lark-clirefreshed my user token, I want Tasks to keep working without reconfiguration, so that normal CLI refresh is invisible. - As an Orca user with bot identity ready but user identity missing, I want the product to treat Lark as not connected for Tasks, so that bot membership surprises do not create tasks as an app.
- As an Orca user, I want pagination or load-more for long tasklists consistent with other Task Sources, so that large lists remain usable without inventing a new chrome pattern.
- As an Orca user, I want create UI chrome consistent with Linear/Jira create on Tasks (modal or inline as existing pattern), so that learning cost stays low.
- As an Orca user, I want i18n strings for empty states and provider labels, so that non-English UI stays coherent.
- As a maintainer, I want domain terms (Preferred Lark Tasklist, Lark CLI Session, etc.) respected in code comments and product copy, so that Feishu “project” vs tasklist language does not drift.
- As a future contributor, I want v1 explicitly not to launch workspaces from Lark tasks, so that scope does not expand mid-implementation without a new decision.
Implementation Decisions
Architecture (ADR-0001)
- Provider id is always
lark. Display name may be Lark or Feishu from CLIbrandand/or locale. - Scope unit is a Lark Tasklist, not a git repo and not a personal-only inbox.
- Preferred Lark Tasklist is stored per Orca project (single list per project). Identity includes stable tasklist GUID and optional display name.
- Auth: fully delegated to
lark-cli. No Lark tokens in Orca credential storage. - Identity: every call uses Lark User Identity (
--as user). No bot mode for Tasks v1. - Multi-login: CLI current user only; no Orca account picker.
- Lark Execution Host: always the machine running the Orca app (local main process). Do not route
lark-clithrough the project SSH/runtime host. - Visibility: always treat Lark as available for picker presence like Jira (do not hide when disconnected). Empty states cover missing CLI / missing user auth.
- Stale Preferred list: keep stored GUID on not-found/no-access; show error + Change tasklist; only overwrite when user selects a new list (or explicit clear if provided).
- Default list filter: Open Lark Tasks only; control to show completed.
- No in-list text search in v1.
- Create fields: required summary/title, optional description, optional due; always attach Preferred tasklist id.
- Detail: read-only fields + complete/reopen + open external URL. No inline edit, comments, or assign in v1.
- Minutes todos are out of this source.
Modules and interfaces (logical)
- Extend TaskProvider union and provider lists/settings normalization so
larkis a first-class source. - Extend Task Source context / provider identity with a Lark identity shape: provider
lark, tasklist GUID, optional tasklist name; include it in cache-scope encoding. - Lark Task Source service (main process): single primary API used by IPC for status, tasklist search/list, list tasks (open/completed), get task, create, complete, reopen. Injectable CLI runner for tests.
- CLI runner: resolve
lark-clion PATH locally; run with JSON output; map exit codes/stderr into classified errors; always pass user identity. - CLI command mapping (conceptual):
- Status:
lark-cli auth status(JSON) → installed + user identity usability + display name/brand. - Tasklists: list and/or
+tasklist-searchfor picker. - Tasks in list:
tasklists taskswith Preferred GUID; filter open vs completed per product rules (normalize awkward CLI completed flag as needed). - Detail:
tasks getby GUID. - Create:
task +createwith summary, description, due, tasklist id. - Complete / reopen:
task +complete/task +reopenby task id/GUID.
- Status:
- IPC + preload surface: expose the service operations to the renderer with the same source-context style used by other account-backed providers (local host id for Lark).
- Renderer Tasks UI: source option for Lark; connection empty states; Preferred tasklist empty state + searchable picker; list chrome with open/completed control; detail drawer actions; create form; provider icon/label; settings Tasks pane entry.
- Persistence: Preferred Lark Tasklist keyed by Orca project id (project-associated task-source preference). Must survive app restart.
- Task page state: when active source is Lark, build Task Source context with project id, local host, and Lark provider identity for caching and summaries.
- Concurrency: apply a modest concurrency limit around CLI invocations (same spirit as other task clients) so refresh storms do not spawn unbounded processes.
- After mutations: invalidate or update list/detail caches for the affected project + tasklist scope.
- Open in Lark/Feishu: use URL from CLI payload when present; disable or hide if missing.
- Do not implement agent “launch workspace from Lark task”, comments, assign, followers, custom fields, multi-list merge, or My-tasks virtual scope in this spec.
Type-shape sketch (decision-rich, not a file path)
type TaskProvider = 'github' | 'gitlab' | 'linear' | 'jira' | 'lark'
type LarkTaskProviderIdentity = {
provider: 'lark'
tasklistGuid: string
tasklistName?: string | null
}
// Connection for Tasks (derived from local lark-cli auth status)
type LarkConnectionStatus =
| { state: 'missing-cli' }
| { state: 'missing-user-auth'; message?: string }
| { state: 'ready'; userName?: string | null; brand?: 'lark' | 'feishu' | string | null }
Testing Decisions
What makes a good test
- Assert external behavior of the Lark Task Source service and pure settings/identity helpers.
- Do not assert internal helper decomposition, exact argv order trivia beyond the contract, or React tree structure.
- Never require a real
lark-clior network in unit tests; inject a fake runner.
Primary seam (confirmed)
Lark Task Source service — mock the CLI runner; cover:
- Status classification: missing binary, missing/unusable user identity, ready with user metadata/brand.
- Tasklist discovery returns mappable results for the picker.
- List tasks for a Preferred GUID with open vs completed filter semantics.
- Get/create/complete/reopen map to correct CLI operations and domain results.
- User identity always requested; no bot fallback.
- Errors for not-found/forbidden/generic failures surface without false success.
- Create requires Preferred list id + title; optional description/due passed through when present.
Secondary pure seams
- TaskProvider settings:
larknormalization; always-available like Jira for visibility filtering. - Task source context: Lark identity in normalize + cache scope.
- Preferred-tasklist reconciliation helpers: empty selection, valid stored GUID, stale GUID kept for UI error path (no auto-pick first list).
Prior art
- Jira issues tests: mock transport/client, assert operation outcomes and error surfacing.
- GitHub issue/CLI tests: mock exec, assert command effects.
- Linear team selection reconciliation tests: pure selection helpers.
- Task provider settings / task-source-context unit tests: extend existing patterns.
Not primary
- Full TaskPage e2e as the main gate (optional later smoke only).
- Real
lark-cliintegration in CI unless a hermetic fixture is added later.
Out of Scope
- Comments, assign, followers, reminders, subtasks/ancestors, custom fields.
- Inline edit of title/description/due after create.
- In-list or global task keyword search UI.
- “My tasks” / “Related tasks” virtual scopes as primary list.
- Multi-tasklist merge views; multi-select Preferred lists.
- Launch workspace / start agent from a Lark Task.
- Orca-managed Lark OAuth tokens or direct OpenAPI client as the primary path.
- Running
lark-clion SSH/runtime project hosts. - Bot identity for Tasks; Orca multi-account picker for CLI users.
- Feishu Minutes (妙记) todos.
- Mobile-specific Lark Tasks surface beyond shared types if mobile does not yet share the full Tasks page (follow existing provider rollout conventions; desktop Tasks is the v1 product surface).
- Agent skill package for Lark tickets (may follow later).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.