stablyai / stablyai/orca

[Feature]: Lark Task Source

Open
#8,280 2 comments 0 reactions 1 assignee View on GitHub

@brennanb2025 is already working on this.

Since Jul 13, 2026.

enhancement
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

  1. 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.
  2. 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.
  3. 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.
  4. As an Orca user, I want Lark to remain visible in the source picker even when lark-cli is missing, so that I can discover how to connect instead of hunting for a hidden integration.
  5. 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.
  6. As an Orca user without lark-cli installed, I want a clear empty state that tells me to install lark-cli, so that I know the exact dependency.
  7. As an Orca user with lark-cli installed but no user session, I want a clear empty state that tells me to run lark-cli auth login, so that I can connect without Orca storing tokens.
  8. 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.
  9. 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-cli and Orca does not invent a second account picker.
  10. As an Orca user, I want all Lark operations to use user identity (--as user), so that personal tasklists and human ownership behave correctly.
  11. 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.
  12. 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.
  13. 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.
  14. As an Orca user, I want tasklist search to find lists by keyword, so that I can locate the right list among many.
  15. As an Orca user, I want to browse discoverable tasklists when I do not know a keyword, so that first-time setup still works.
  16. 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.
  17. 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.
  18. 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.
  19. 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.
  20. 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.
  21. As an Orca user, I want a control to show completed tasks in that list, so that I can verify recently finished work.
  22. 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.
  23. 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.
  24. 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.
  25. 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.
  26. 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.
  27. 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.
  28. 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.
  29. 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.
  30. As an Orca user, I want create to require a title (summary), so that empty tasks are not created by mistake.
  31. As an Orca user, I want optional description on create, so that I can capture context at creation time.
  32. As an Orca user, I want optional due date on create, so that time-bound work is visible in Lark and in Orca.
  33. 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.
  34. 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.
  35. 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.
  36. As an Orca user, I want reopen to return a task to the Open list, so that mistakes are recoverable.
  37. 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.
  38. 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.
  39. 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.
  40. 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.
  41. As an Orca user, I want sidebar / Tasks shortcuts to treat Lark like other visible providers when enabled, so that navigation is consistent.
  42. 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.
  43. As an Orca user, I want no requirement to paste API tokens into Orca for Lark, so that secrets stay in the CLI session.
  44. As an Orca user returning after lark-cli refreshed my user token, I want Tasks to keep working without reconfiguration, so that normal CLI refresh is invisible.
  45. 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.
  46. 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.
  47. 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.
  48. As an Orca user, I want i18n strings for empty states and provider labels, so that non-English UI stays coherent.
  49. 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.
  50. 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)
  1. Provider id is always lark. Display name may be Lark or Feishu from CLI brand and/or locale.
  2. Scope unit is a Lark Tasklist, not a git repo and not a personal-only inbox.
  3. Preferred Lark Tasklist is stored per Orca project (single list per project). Identity includes stable tasklist GUID and optional display name.
  4. Auth: fully delegated to lark-cli. No Lark tokens in Orca credential storage.
  5. Identity: every call uses Lark User Identity (--as user). No bot mode for Tasks v1.
  6. Multi-login: CLI current user only; no Orca account picker.
  7. Lark Execution Host: always the machine running the Orca app (local main process). Do not route lark-cli through the project SSH/runtime host.
  8. Visibility: always treat Lark as available for picker presence like Jira (do not hide when disconnected). Empty states cover missing CLI / missing user auth.
  9. 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).
  10. Default list filter: Open Lark Tasks only; control to show completed.
  11. No in-list text search in v1.
  12. Create fields: required summary/title, optional description, optional due; always attach Preferred tasklist id.
  13. Detail: read-only fields + complete/reopen + open external URL. No inline edit, comments, or assign in v1.
  14. Minutes todos are out of this source.
Modules and interfaces (logical)
  1. Extend TaskProvider union and provider lists/settings normalization so lark is a first-class source.
  2. Extend Task Source context / provider identity with a Lark identity shape: provider lark, tasklist GUID, optional tasklist name; include it in cache-scope encoding.
  3. 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.
  4. CLI runner: resolve lark-cli on PATH locally; run with JSON output; map exit codes/stderr into classified errors; always pass user identity.
  5. CLI command mapping (conceptual):
    • Status: lark-cli auth status (JSON) → installed + user identity usability + display name/brand.
    • Tasklists: list and/or +tasklist-search for picker.
    • Tasks in list: tasklists tasks with Preferred GUID; filter open vs completed per product rules (normalize awkward CLI completed flag as needed).
    • Detail: tasks get by GUID.
    • Create: task +create with summary, description, due, tasklist id.
    • Complete / reopen: task +complete / task +reopen by task id/GUID.
  6. 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).
  7. 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.
  8. Persistence: Preferred Lark Tasklist keyed by Orca project id (project-associated task-source preference). Must survive app restart.
  9. 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.
  10. Concurrency: apply a modest concurrency limit around CLI invocations (same spirit as other task clients) so refresh storms do not spawn unbounded processes.
  11. After mutations: invalidate or update list/detail caches for the affected project + tasklist scope.
  12. Open in Lark/Feishu: use URL from CLI payload when present; disable or hide if missing.
  13. 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-cli or 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: lark normalization; 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-cli integration 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-cli on 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.