@lumoai/cli 1.15.0 → 1.18.0
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/README.md +13 -13
- package/assets/skill/SKILL.md +118 -0
- package/assets/skill/references/artifacts-figma.md +124 -0
- package/assets/skill/references/docs.md +306 -0
- package/assets/skill/references/memory.md +69 -0
- package/assets/skill/references/milestones.md +244 -0
- package/assets/skill/references/onboarding.md +102 -0
- package/assets/skill/references/sessions.md +157 -0
- package/assets/skill/references/sprints.md +157 -0
- package/assets/skill/references/task-context.md +109 -0
- package/assets/skill/references/tasks.md +205 -0
- package/assets/skill/references/worktree.md +60 -0
- package/dist/cli/src/commands/milestone-show.js +23 -0
- package/dist/cli/src/commands/session-attach.js +76 -37
- package/dist/cli/src/commands/setup.js +50 -22
- package/dist/cli/src/commands/sprint-show.js +32 -3
- package/dist/cli/src/commands/worktree-add.js +108 -0
- package/dist/cli/src/commands/worktree-list.js +73 -0
- package/dist/cli/src/commands/worktree-rm.js +53 -0
- package/dist/cli/src/index.js +35 -3
- package/dist/cli/src/lib/worktree.js +174 -0
- package/package.json +1 -1
- package/assets/skill.md +0 -1445
package/assets/skill.md
DELETED
|
@@ -1,1445 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: lumo
|
|
3
|
-
description: 'Use the Lumo CLI to load task context, manage session bindings, inspect projects and milestones, and create/update/list/show/comment on tasks from the terminal. Activate when: user mentions a Lumo task identifier (LUM-42, LUM-12, etc.), asks to load task background or context, wants to bind, check, or detach a Claude Code session''s task binding, is about to start development work on a specific task, wants to create a new task, list their tasks, view a task, comment on a task, list projects, list milestones, attach a task to a milestone, or update a task''s status/title/description/priority/assignee/milestone. Triggers on: "LUM-", "task context", "load context", "session start", "session attach", "session status", "session detach", "bind session", "unbind session", "which task", "what task am I on", "work on LUM", "create task", "new task", "add task", "file a task", "log a task", "list tasks", "my tasks", "show task", "view task", "comment on task", "leave a comment", "list projects", "what projects", "update task", "change task status", "rename task", "reassign task", "mark task as done", "milestone", "里程碑", "list milestones", "set milestone", "挂到 milestone", "attach milestone", "unbind milestone", "create milestone", "new milestone", "update milestone", "change milestone status", "delete milestone", "show milestone", "view milestone", "tasks in milestone", "milestone tasks", "search milestones", "find milestone", "filter milestones", "milestone search", "搜索里程碑", "查找里程碑", "milestone health", "milestone risk", "risk light", "on-track", "at-risk", "overdue", "里程碑健康度", "健康度", "风险灯", "延期风险", "新建里程碑", "更新里程碑", "删除里程碑", "查看里程碑", "archive milestone", "unarchive milestone", "restore milestone", "archived milestones", "归档里程碑", "恢复里程碑", "取消归档", "milestone summary", "milestone retro", "summarize milestone", "里程碑总结", "里程碑复盘", "milestone reorder", "milestone move", "reorder milestones", "move milestone", "排序里程碑", "调整里程碑顺序", "里程碑调序", "move milestone before", "move milestone after", "milestone add", "milestone remove", "add tasks to milestone", "remove tasks from milestone", "batch milestone", "bulk milestone", "挂任务到里程碑", "批量挂里程碑", "从里程碑移除任务", "auth login", "log in", "login", "auth logout", "log out", "logout", "sign out", "switch account", "switch identity", "whoami", "who am I", "current identity", "current user", "current workspace", "登录", "登出", "切换账号", "当前身份", "create doc", "new doc", "new document", "write doc", "写文档", "新建文档", "update doc", "edit doc", "修改文档", "更新文档", "list docs", "my docs", "我的文档", "show doc", "view doc", "查看文档", "delete doc", "删除文档", "bind doc", "attach doc to task", "把文档关联到任务", "文档绑定到任务", "unbind doc", "解绑文档", "personal doc", "workspace doc", "个人文档", "workspace 文档", "doc scope", "tag", "add tag", "remove tag", "标签", "添加标签", "移除标签", "doc tag", "task tag", "share doc", "doc share", "share document", "分享文档", "文档分享", "unshare doc", "remove share", "取消分享", "share list", "list doc shares", "who has access", "viewer", "editor", "manager", "shared with", "doc tree", "doc move", "move doc", "reparent doc", "文档树", "移动文档", "sprint", "start sprint", "close sprint", "add to sprint", "active sprints", "冲刺", "迭代", "开始冲刺", "关闭冲刺", "create sprint", "new sprint", "list sprints", "show sprint", "update sprint", "delete sprint", "sprint summary", "sprint retro", "把任务挂到冲刺", "冲刺里有什么", "lumo update", "update cli", "upgrade lumo", "update lumo", "upgrade cli", "升级 lumo", "更新 cli", "new lumo version", "是否有新版本", "lumo setup", "install lumo skill", "install lumo hooks", "wire up lumo", "set up lumo", "onboard lumo", "npx @lumoai/cli", "安装 lumo", "配置 lumo", "lumo 初始化", "task artifact", "artifact add", "artifact list", "artifact show", "artifact rm", "artifact delete", "artifact update", "update artifact", "edit artifact", "change artifact kind", "change artifact source", "remove artifact", "delete artifact", "spec artifact", "record spec", "attach spec", "attach plan", "记录 spec", "挂 spec", "查看 artifact", "编辑 artifact", "修改 artifact", "删除 artifact", figma, attach figma, figma link, 关联 figma, 设计稿, figma design, "memory", "记忆", "remember", "record a memory", "记一条", "promote memory", "promote to project", "沉淀", "task memory", "project memory", "lumo memory", "retrieval", "取全文", "load full content", "拉全文", "task slack show", "看 thread", "看 slack thread", "show slack thread", "slack 全文", "task web show", "show web link body", "web 正文", "抓网页正文", "task figma context", "figma metadata", "figma 元数据", "figma 设计上下文", "task comments list", "list comments", "看评论", "评论流", "task pr show", "查看 PR", "show pr", "PR 详情", "pr metadata", "import google doc", "sync google doc", "google drive", "doc import-gdoc", "doc sync", "导入 google 文档", "同步 google 文档", "session wrap", "wrap up session", "收尾", "post progress", "把进度发出去", "progress comment", "进度评论", "mark blocked", "blocked tag", "标 blocked", "标记 blocked", "卡住检测", "反复失败", "stuck", "repeatedly failing", "lumo next", "next task", "what''s next", "what should I work on", "recommend a task", "推荐下一个任务", "pick my next task".'
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
## Prerequisites
|
|
7
|
-
|
|
8
|
-
Before running any `lumo` command, verify the CLI is available and authenticated:
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
which lumo && lumo whoami
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
- If `lumo` is not found: tell the user to install it (`npm install -g @lumoai/cli`; for monorepo dev, `cd cli && npm install && npm link` also works)
|
|
15
|
-
- If `lumo whoami` fails with an auth error: tell the user to run `lumo auth login`
|
|
16
|
-
- Do NOT proceed with any lumo commands until both checks pass
|
|
17
|
-
|
|
18
|
-
## Onboarding
|
|
19
|
-
|
|
20
|
-
### `lumo setup [--user|--project] [--force] [--agent <token>]` — install skill + hooks
|
|
21
|
-
|
|
22
|
-
Bootstraps Lumo into a coding-agent installation. Copies the bundled `SKILL.md` into `<scope>/.claude/skills/lumo/` and idempotently merges 25 hook entries into `<scope>/.claude/settings.json`. Existing user permissions and non-Lumo hook entries are preserved.
|
|
23
|
-
|
|
24
|
-
On `--project` scope, setup also installs a `prepare-commit-msg` git hook that
|
|
25
|
-
auto-appends the branch's task ID (`[LUM-N]`, parsed from a `lumo/LUM-N-...`
|
|
26
|
-
branch name) to any commit subject that lacks it. The hook is pure sh + git
|
|
27
|
-
(no network, no `lumo` call) and is merged idempotently between
|
|
28
|
-
`# >>> lumo prepare-commit-msg >>>` / `# <<< lumo <<<` markers, preserving any
|
|
29
|
-
existing hook content. When `core.hooksPath` is set (husky or a custom hooks
|
|
30
|
-
dir), setup does **not** write the file — it prints the block plus instructions
|
|
31
|
-
to add it manually (e.g. to `.husky/prepare-commit-msg`). `--user` scope does
|
|
32
|
-
not touch git hooks.
|
|
33
|
-
|
|
34
|
-
`--agent <token>` records which coding agent these hooks run under and is **baked into every hook command** (`lumo hook <slug> --agent <token>`). Each hook then sends the agent to the server, where it's stored on the Session and inherited by auto-sedimented memories — so a memory is attributed to the agent that produced it instead of the default. Valid tokens: `claude-code | codex | cursor | gemini-cli | github-copilot | windsurf` (case-insensitive; `gemini` and `copilot` are accepted aliases). **Defaults to `claude-code`.** Re-running setup with a different `--agent` rewrites the token in place (no duplicate hook entries), and a legacy flagless entry is upgraded on the next run.
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
npx @lumoai/cli setup # interactive: prompts user/project; agent=claude-code
|
|
38
|
-
npx @lumoai/cli setup --user # write to ~/.claude/
|
|
39
|
-
npx @lumoai/cli setup --project # write to ./.claude/
|
|
40
|
-
npx @lumoai/cli setup --force # overwrite SKILL.md if it differs from bundled
|
|
41
|
-
npx @lumoai/cli setup --agent codex # bake agent=codex into the hook commands
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Use when:
|
|
45
|
-
|
|
46
|
-
- The user asks "how do I set up lumo", "install the lumo skill", "wire up lumo hooks"
|
|
47
|
-
- A fresh checkout of a project that uses Lumo doesn't have `.claude/skills/lumo/SKILL.md` yet
|
|
48
|
-
- After `npm install -g @lumoai/cli`, before the first `lumo auth login`
|
|
49
|
-
- Wiring Lumo into a non-Claude-Code agent (Codex / Cursor / …) — pass `--agent <token>` so its memories are attributed correctly
|
|
50
|
-
|
|
51
|
-
If stdin is not a TTY (CI, piped invocation), the default scope is `project` and no prompt is shown. An unrecognized `--agent` token aborts before writing anything.
|
|
52
|
-
|
|
53
|
-
## Authentication
|
|
54
|
-
|
|
55
|
-
### `lumo auth login` — paste an API key to log in
|
|
56
|
-
|
|
57
|
-
Walks the user through creating an API key in the web app and pasting it back. Opens the browser to the API Keys settings page, then reads the key from stdin (must start with the `lum_` prefix). On success prints `✓ Logged in as <email>` plus workspace + key name.
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
lumo auth login
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Use when:
|
|
64
|
-
|
|
65
|
-
- `lumo whoami` reports "Not logged in"
|
|
66
|
-
- A bearer call returns 401 (`API key invalid or revoked`) and the user wants to re-auth
|
|
67
|
-
- The user switches workspaces / accounts
|
|
68
|
-
|
|
69
|
-
The CLI stores credentials in `~/.lumo/credentials.json`. There's no `--token` flag — the paste-from-browser flow is the only auth path, and that's intentional.
|
|
70
|
-
|
|
71
|
-
### `lumo auth logout` — remove local credentials
|
|
72
|
-
|
|
73
|
-
Wipes `~/.lumo/credentials.json`. Idempotent — running twice just prints `Not logged in` the second time.
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
lumo auth logout
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Use when the user says "log out", "sign out", or wants to clear credentials before switching accounts (then run `lumo auth login` to re-auth).
|
|
80
|
-
|
|
81
|
-
### `lumo whoami` — show current identity
|
|
82
|
-
|
|
83
|
-
Prints the logged-in email, workspace name + slug, API key name + prefix, and API URL.
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
lumo whoami
|
|
87
|
-
# Logged in as cli@uselumo.ai
|
|
88
|
-
# Workspace: Lumo (lumo)
|
|
89
|
-
# Key: Claude Code (lum_68d4...)
|
|
90
|
-
# API: https://www.uselumo.ai
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Use when:
|
|
94
|
-
|
|
95
|
-
- The user asks "who am I", "which workspace am I in", "what account is this"
|
|
96
|
-
- You need to disambiguate whether `lumo task list` would hit the user's expected workspace
|
|
97
|
-
- Before suggesting a destructive command on a shared machine — confirm the identity is right
|
|
98
|
-
|
|
99
|
-
## Self-Update
|
|
100
|
-
|
|
101
|
-
### `lumo update` — upgrade the CLI to the latest npm release
|
|
102
|
-
|
|
103
|
-
Synchronously checks `registry.npmjs.org` for the latest published version of `@lumoai/cli`. When a newer version exists, runs `npm install -g @lumoai/cli@latest` and streams npm's output. When already on the latest, exits cleanly with a "Already on the latest version (X)" message.
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
lumo update
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
The CLI also performs a passive check at most once every 24 hours (a detached child process refreshes a cache at `~/.lumo/update-check.json`), and prints a one-line "Update available" notice on subsequent invocations when a newer version is in the cache.
|
|
110
|
-
|
|
111
|
-
Use when:
|
|
112
|
-
|
|
113
|
-
- The user asks "how do I update", "upgrade lumo", "is there a new version"
|
|
114
|
-
- A bug-fix or feature mentioned in conversation requires a newer CLI than the user is running
|
|
115
|
-
- The passive notice has appeared and the user wants to act on it
|
|
116
|
-
|
|
117
|
-
If `npm install -g` fails (permissions, npm not on PATH, alternative package manager), `lumo update` prints a fallback hint instructing the user to run the install command manually. Do not auto-retry; let the user resolve the environment issue first.
|
|
118
|
-
|
|
119
|
-
## Task Context Loading
|
|
120
|
-
|
|
121
|
-
When the user mentions a task identifier or asks for task background, load the context:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
lumo task context <identifier>
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Example: `lumo task context LUM-42`
|
|
128
|
-
|
|
129
|
-
### Reading the output
|
|
130
|
-
|
|
131
|
-
The command prints a markdown document to stdout containing:
|
|
132
|
-
|
|
133
|
-
1. **Task header** — identifier, title, status, description
|
|
134
|
-
2. **Memory section** — cross-session learnings accumulated over prior sessions; treat as trusted background context
|
|
135
|
-
3. **Inline source cards** — Slack / web / Figma / artifacts / documents / comments / Pull Requests (see "Context Retrieval" below)
|
|
136
|
-
4. **PR Review 待办** — mirrored PR review comments as a checkbox todo list: each line-level reviewer comment (shown as `` `file:line` `` + the reviewer's ask + a link to the GitHub comment) and each `changes_requested` review summary (shown as "🛑 整体要求改动"). Present only when the task's PR(s) have review comments. This same block is **auto-injected at session start** (alongside the memory section) when the session is bound to a task — so reviewer asks surface without re-running `task context`.
|
|
137
|
-
- The **inline source cards** (Slack / web / Figma / PR) are likewise **auto-injected at session start** when the session is bound, under a single global token budget shared with the memory section (priority: memory > PR > Slack > Figma > web). Cards that don't fit the budget are degraded to a one-line manifest carrying just the title and its `lumo task … show` retrieval command — so you still know they exist and can pull the full content on demand.
|
|
138
|
-
5. **Previous sessions** — ordered newest-first, each with:
|
|
139
|
-
- A headline summary of what was done
|
|
140
|
-
- Unresolved items (carry-over TODOs from that session)
|
|
141
|
-
|
|
142
|
-
### How to use the context
|
|
143
|
-
|
|
144
|
-
- **Unresolved items** from the most recent session are the highest-priority carry-overs — address them before starting new work unless the user says otherwise
|
|
145
|
-
- **PR Review 待办** items are reviewer-requested changes — treat each unchecked box as a TODO to resolve, then reply on the PR (a Lumo comment mirrors back to GitHub)
|
|
146
|
-
- **Memory section** provides validated context that persists across sessions — use it to avoid re-learning decisions or constraints
|
|
147
|
-
- Focus on the **most recent 1–2 sessions** for relevant state; older sessions are for historical reference only
|
|
148
|
-
- If there are **no prior sessions**, this is a fresh start — read the task description carefully and ask clarifying questions if needed
|
|
149
|
-
|
|
150
|
-
## Context Retrieval (按需取全文)
|
|
151
|
-
|
|
152
|
-
LUM-122 split task context injection into tiers. `lumo task context <LUM-N>`
|
|
153
|
-
now emits a **cheap inline card** for each source — a short summary or just
|
|
154
|
-
metadata — instead of dumping full bodies. Slack, docs, artifacts, and comments
|
|
155
|
-
get an **LLM summary**; web links, Figma, and PRs get **metadata only**. Each
|
|
156
|
-
card ends with the **retrieval command** you run to pull the heavy content on
|
|
157
|
-
demand.
|
|
158
|
-
|
|
159
|
-
**How to use it:** when the inline card is not enough and you need the full
|
|
160
|
-
Slack thread, the web page body, the Figma metadata, the entire comment thread,
|
|
161
|
-
or the PR detail — run the matching command below. Pass the same identifier
|
|
162
|
-
(`LUM-N`) plus the id the card shows for that source (a Slack `contextId`, a web
|
|
163
|
-
`linkId`, a Figma `linkId`, or a PR `number`).
|
|
164
|
-
|
|
165
|
-
All five are **read-only** (no live Slack/GitHub/Figma calls except the web body
|
|
166
|
-
fetch). Web/Figma/PR are v1 metadata-degraded: they print a `note:` explaining
|
|
167
|
-
that live content needs an external integration.
|
|
168
|
-
|
|
169
|
-
### `lumo task slack show <identifier> <contextId>` — full Slack thread snapshot
|
|
170
|
-
|
|
171
|
-
Prints the **stored** thread snapshot (no live Slack call), one line per message
|
|
172
|
-
as `author: text`. Author falls back to `@<userId>` when the display name is
|
|
173
|
-
missing. Empty snapshot prints `(no messages in stored snapshot)`.
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
lumo task slack show LUM-42 ctx_abc123
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### `lumo task web show <identifier> <linkId>` — fetched web link body
|
|
180
|
-
|
|
181
|
-
Fetches the page body on demand behind the SSRF guard (cached after first read)
|
|
182
|
-
and prints it as plain text. Empty body prints `(empty body)`. Fetch failures
|
|
183
|
-
(blocked host, timeout) print the server's error message.
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
lumo task web show LUM-42 wl_abc123
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### `lumo task figma context <identifier> <linkId>` — Figma link metadata
|
|
190
|
-
|
|
191
|
-
**v1 metadata fallback.** Prints the cached design metadata as `file:` /
|
|
192
|
-
`frame:` / `url:` / `synced:` (and `syncError:` if the last sync failed) lines.
|
|
193
|
-
Live design context (layers, variables, code connect) requires the Figma MCP
|
|
194
|
-
server, so the command ends with a `note:` saying so.
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
lumo task figma context LUM-42 cfl_abc123
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### `lumo task comments list <identifier>` — full comment thread
|
|
201
|
-
|
|
202
|
-
Prints the **entire** comment thread: each comment as `author · createdAt`
|
|
203
|
-
followed by its plain-text body (comment bodies are stored as HTML and stripped
|
|
204
|
-
to text). Replies are indented two spaces under their parent. Author falls back
|
|
205
|
-
to `unknown`. No comments prints `(no comments)`.
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
lumo task comments list LUM-42
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
**Plural, and distinct from `task comment`.** `task comments list` _reads_ the
|
|
212
|
-
whole thread (this retrieval command). `task comment <identifier> <body>`
|
|
213
|
-
_writes_ a single new comment (see Task Management). Don't confuse the two —
|
|
214
|
-
the plural `comments` is read-only.
|
|
215
|
-
|
|
216
|
-
### `lumo task pr show <identifier> <number>` — synced PR metadata
|
|
217
|
-
|
|
218
|
-
**v1 metadata fallback.** Prints the synced PR record: a `#<number> (repo)
|
|
219
|
-
title` header, then `state:` (with ` · draft` when draft), `ci:`, `author:`,
|
|
220
|
-
`branch: <head> → <base>`, and `url:` lines. The live diff + review comments
|
|
221
|
-
require the GitHub integration, so the command ends with a `note:` saying so.
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
lumo task pr show LUM-42 128
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
## Task Management
|
|
228
|
-
|
|
229
|
-
### `lumo task create <title> [flags]` — create a new task
|
|
230
|
-
|
|
231
|
-
Use this when the user wants to file a new task from the terminal. Title is positional and required (non-empty).
|
|
232
|
-
|
|
233
|
-
| Flag | Type | Notes |
|
|
234
|
-
| ------------------------ | ------ | ----------------------------------------------------------------------------------- |
|
|
235
|
-
| `-d, --description <>` | string | Optional task description. |
|
|
236
|
-
| `-p, --priority <level>` | enum | `low \| medium \| high \| urgent` (case-insensitive). Defaults to `low`. |
|
|
237
|
-
| `-a, --assignee <ref>` | string | `me`, an email, or a member name. Defaults to `me`. |
|
|
238
|
-
| `--project <ref>` | string | Project name or slug. **Required when the workspace has more than one project.** |
|
|
239
|
-
| `--milestone <ref>` | string | Milestone name (case-insensitive) within the resolved project. Omit for no binding. |
|
|
240
|
-
| `--sprint <ref>` | string | Sprint number or UUID to bind the task to on creation. Omit for no sprint binding. |
|
|
241
|
-
| `--tag <name>` | string | Attach a tag by name (repeatable). The name is resolved to an id server-side. |
|
|
242
|
-
| `--tag-id <cuid>` | string | Attach a tag by cuid (repeatable). Combines with `--tag`. |
|
|
243
|
-
|
|
244
|
-
Examples:
|
|
245
|
-
|
|
246
|
-
```bash
|
|
247
|
-
lumo task create "Fix Slack OAuth redirect bug"
|
|
248
|
-
lumo task create "Refactor task service" --priority high --description "Split into smaller files"
|
|
249
|
-
lumo task create "Investigate slow query" --assignee teammate@example.com --project backend
|
|
250
|
-
lumo task create "Plan API design" --milestone "v1.0"
|
|
251
|
-
lumo task create "Sprint task" --sprint 3
|
|
252
|
-
lumo task create "Add rate limiting" --tag bug --tag urgent
|
|
253
|
-
lumo task create "Spike: evaluate caching options" --tag rfc --tag-id clm_abc123
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
On success the command prints one or two lines to stdout:
|
|
257
|
-
|
|
258
|
-
```
|
|
259
|
-
Created LUM-55 "Title" https://www.uselumo.ai/workspace/<slug>/my-tasks/LUM-55
|
|
260
|
-
Tags: bug, urgent
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
The `Tags:` line is omitted when no tags were attached.
|
|
264
|
-
|
|
265
|
-
If the workspace has multiple projects and `--project` is omitted, the server will return an error naming available projects — re-run with `--project <slug>`.
|
|
266
|
-
|
|
267
|
-
### When to suggest `task create`
|
|
268
|
-
|
|
269
|
-
- The user describes wanting a new task ("create a task to ...", "file a bug for ...", "log a TODO that ...", "add a task: ...").
|
|
270
|
-
- After a discussion that ends in "let's track that separately" — offer to create the task with a sensible title and priority.
|
|
271
|
-
- For follow-ups discovered mid-work that shouldn't bloat the current change — propose `task create` rather than silently expanding scope.
|
|
272
|
-
|
|
273
|
-
### `lumo task update <identifier> [flags]` — patch a task
|
|
274
|
-
|
|
275
|
-
Pure flag-driven update. Provide at least one of:
|
|
276
|
-
|
|
277
|
-
| Flag | Type | Notes |
|
|
278
|
-
| ------------------------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
279
|
-
| `-t, --title <text>` | string | Cannot be empty. |
|
|
280
|
-
| `-d, --description <>` | string | `--description ""` clears the field. |
|
|
281
|
-
| `-s, --status <value>` | enum | `todo \| in_progress \| in_review \| done` (case-insensitive). |
|
|
282
|
-
| `-p, --priority <lvl>` | enum | `low \| medium \| high \| urgent`. |
|
|
283
|
-
| `-a, --assignee <ref>` | string | `me`, an email, or a member name. `--assignee ""` clears the field. |
|
|
284
|
-
| `--milestone <ref>` | string | Milestone name (case-insensitive) within the task's project. `--milestone ""` unbinds. |
|
|
285
|
-
| `--sprint <ref>` | string | Sprint number or UUID to bind the task to. `--sprint ""` clears the current sprint binding (idempotent when already unbound). |
|
|
286
|
-
| `--tag <name>` | string (repeatable) | **Bulk replace** the tag set by name. Creates tag if missing. Max 20. Mutually exclusive with `--add-tag*` / `--remove-tag*`. |
|
|
287
|
-
| `--tag-id <cuid>` | string (repeatable) | **Bulk replace** the tag set by id. Max 20. Mutually exclusive with `--add-tag*` / `--remove-tag*`. |
|
|
288
|
-
| `--add-tag <name>` | string (repeatable) | Attach tag by name (find-or-create). Max 20. |
|
|
289
|
-
| `--add-tag-id <cuid>` | string (repeatable) | Attach tag by id. Max 20. |
|
|
290
|
-
| `--remove-tag <name>` | string (repeatable) | Detach tag by name. `--remove-tag <name>` resolves the name via find-or-create on the workspace. If the name was unknown, a new Tag row is created (orphan, no attachments) before the detach runs as a no-op. Use `--remove-tag-id <cuid>` to avoid orphans. Max 20. |
|
|
291
|
-
| `--remove-tag-id <cuid>` | string (repeatable) | Detach tag by id. Unknown ids are a no-op (no side effects). Max 20. |
|
|
292
|
-
|
|
293
|
-
`--tag` / `--tag-id` (bulk replace) are mutually exclusive with `--add-tag` / `--add-tag-id` / `--remove-tag` / `--remove-tag-id`. The CLI errors before any network call if both families are mixed.
|
|
294
|
-
|
|
295
|
-
Examples:
|
|
296
|
-
|
|
297
|
-
```bash
|
|
298
|
-
lumo task update LUM-48 --status in_progress
|
|
299
|
-
lumo task update LUM-48 --title "Update task from CLI" --priority high
|
|
300
|
-
lumo task update LUM-48 --assignee me
|
|
301
|
-
lumo task update LUM-48 --description "" # clear description
|
|
302
|
-
lumo task update LUM-48 --assignee "" # unassign
|
|
303
|
-
lumo task update LUM-48 --milestone "v1.0" # attach to milestone
|
|
304
|
-
lumo task update LUM-48 --milestone "" # unbind milestone
|
|
305
|
-
lumo task update LUM-48 --sprint 3 # bind to sprint #3
|
|
306
|
-
lumo task update LUM-48 --sprint "" # unbind from current sprint
|
|
307
|
-
lumo task update LUM-42 --add-tag urgent --remove-tag draft
|
|
308
|
-
lumo task update LUM-42 --tag final --tag approved # replace entire tag set
|
|
309
|
-
lumo task update LUM-42 --tag final --add-tag oops
|
|
310
|
-
# Error: --tag/--tag-id are mutually exclusive with --add-tag/--add-tag-id/--remove-tag/--remove-tag-id
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
On success the command prints one or two lines to stdout:
|
|
314
|
-
|
|
315
|
-
```
|
|
316
|
-
Updated LUM-48 "Title" https://www.uselumo.ai/workspace/<slug>/my-tasks/LUM-48
|
|
317
|
-
Tags: urgent
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
The `Tags:` line is omitted when the resulting tag set is empty.
|
|
321
|
-
|
|
322
|
-
### When to suggest `task update`
|
|
323
|
-
|
|
324
|
-
- The user describes a state change in natural language (e.g. "mark LUM-48 as in progress", "rename LUM-12 to ...", "assign LUM-30 to me", "bump the priority on LUM-7").
|
|
325
|
-
- After the agent finishes a task and the user confirms — offer to move it to `done`.
|
|
326
|
-
- Multiple status changes in a row should each be a separate `update` invocation rather than batched.
|
|
327
|
-
|
|
328
|
-
### Sprint output format
|
|
329
|
-
|
|
330
|
-
`--sprint <ref>` prints a `Sprint:` line after the update line showing old → new binding:
|
|
331
|
-
|
|
332
|
-
```
|
|
333
|
-
Sprint: - → #3 # newly bound (was backlog)
|
|
334
|
-
Sprint: #2 → #3 # rebound (moved from sprint 2 to 3)
|
|
335
|
-
Sprint: #3 → - # unbound
|
|
336
|
-
Task LUM-48 already in sprint #3 # noop (same sprint)
|
|
337
|
-
Task LUM-48 has no sprint binding # noop (already unbound)
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
`--sprint` can be combined with other update flags. The PATCH (field updates) runs first; the sprint operation runs after. Failures on either step pass through independently without rollback.
|
|
341
|
-
|
|
342
|
-
### Out of scope
|
|
343
|
-
|
|
344
|
-
The CLI does **not** currently update due date or parent task. Those need to be edited in the web UI.
|
|
345
|
-
|
|
346
|
-
Milestone updates (`--milestone`) and sprint binding (`--sprint`) both work. Full milestone CRUD is available via `lumo milestone create / show / update / delete`, tasks can be bound/unbound in bulk via `lumo milestone add / remove <identifier> <task...>`, and milestones can be manually reordered via `lumo milestone reorder <ref...>` / `lumo milestone move <ref> --before|--after <ref>` (see below). Full sprint CRUD is available via `lumo sprint create / show / update / delete / start / close / add / remove` (see below).
|
|
347
|
-
|
|
348
|
-
### `lumo task list [flags]` — list tasks assigned to you
|
|
349
|
-
|
|
350
|
-
Default behavior: prints every task currently assigned to the authenticated user (no project / status filter), one per line, as a fixed-width table:
|
|
351
|
-
|
|
352
|
-
```
|
|
353
|
-
LUM-42 IN_PROGRESS HIGH web Fix Slack OAuth redirect
|
|
354
|
-
LUM-48 TODO MEDIUM backend Investigate slow query
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
| Flag | Type | Notes |
|
|
358
|
-
| ----------------------- | ------- | -------------------------------------------------------------------------------- |
|
|
359
|
-
| `-s, --status <value>` | enum | Filter by status: `todo \| in_progress \| in_review \| done` (case-insensitive). |
|
|
360
|
-
| `-p, --project <ref>` | string | Filter by project name (case-insensitive match against display name). |
|
|
361
|
-
| `-m, --milestone <ref>` | string | Filter to my tasks under this milestone (name or UUID). |
|
|
362
|
-
| `-n, --limit <count>` | integer | Cap output to the first N rows. |
|
|
363
|
-
|
|
364
|
-
When `--milestone` is set, the CLI calls `GET /api/milestones/<id>/tasks?assigned=me` instead of `/api/tasks/me`. Other filters (`--status`, `--limit`) still apply client-side to the milestone-scoped result.
|
|
365
|
-
|
|
366
|
-
Filtering is currently client-side — the server returns the full "my tasks" set and the CLI slices it. This is fine for typical workspaces (dozens of tasks); revisit if a workspace has hundreds.
|
|
367
|
-
|
|
368
|
-
### When to suggest `task list`
|
|
369
|
-
|
|
370
|
-
- The user asks "what am I working on", "what tasks do I have", "list my tasks", "show me my queue".
|
|
371
|
-
- Before suggesting a status change ("mark something as done"), if no task ID is in context — run `task list` first to surface candidates.
|
|
372
|
-
|
|
373
|
-
### `lumo next [--count <N>]` — recommend the next task to work on
|
|
374
|
-
|
|
375
|
-
Ranks the tasks assigned to you and prints the top N (default 3), each with a
|
|
376
|
-
one-line reason. Read-only — it does **not** bind or load context. Pick one from
|
|
377
|
-
the list, then run `lumo session attach <LUM-N>` + `lumo task context <LUM-N>`.
|
|
378
|
-
|
|
379
|
-
Ranking is lexicographic: **priority** (URGENT→LOW) first, then **active-sprint
|
|
380
|
-
membership**, then **due date** (earlier first), then in-flight status
|
|
381
|
-
(IN_PROGRESS / IN_REVIEW ahead of TODO). DONE tasks are excluded. The active
|
|
382
|
-
sprint lookup is best-effort — if it fails the command still recommends, just
|
|
383
|
-
without the sprint boost.
|
|
384
|
-
|
|
385
|
-
| Flag | Type | Notes |
|
|
386
|
-
| ----------------- | ------- | ----------------------------------------------------------------------- |
|
|
387
|
-
| `-n, --count <N>` | integer | How many tasks to recommend. Defaults to 3. Must be a positive integer. |
|
|
388
|
-
|
|
389
|
-
```bash
|
|
390
|
-
lumo next
|
|
391
|
-
lumo next --count 1
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
Output:
|
|
395
|
-
|
|
396
|
-
```
|
|
397
|
-
Top 3 recommended tasks (of 12 open):
|
|
398
|
-
|
|
399
|
-
1. LUM-42 IN_PROGRESS URGENT Fix Slack OAuth redirect
|
|
400
|
-
↳ URGENT · active sprint · due 2026-06-03 (overdue) · in progress
|
|
401
|
-
2. LUM-48 TODO HIGH Investigate slow query
|
|
402
|
-
↳ HIGH · active sprint
|
|
403
|
-
3. LUM-12 TODO MEDIUM Add rate limiting
|
|
404
|
-
↳ MEDIUM · due 2026-06-10
|
|
405
|
-
|
|
406
|
-
Next: lumo session attach LUM-42 && lumo task context LUM-42
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
When to suggest: the user asks "what should I work on", "what's next", "推荐下一个任务", "pick my next task", or starts a session without a task in mind. After they choose, run `session attach` + `task context` for the picked task.
|
|
410
|
-
|
|
411
|
-
### `lumo task show <identifier>` — print one task's detail
|
|
412
|
-
|
|
413
|
-
Returns a key:value block for a single task — title, status, priority, project, assignee (with display name from Clerk), URL, and the full description below. Lighter than `task context` because it does not load prior session summaries or memory.
|
|
414
|
-
|
|
415
|
-
```bash
|
|
416
|
-
lumo task show LUM-42
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
Use when the user wants the current state of a task without the agent-handoff payload.
|
|
420
|
-
|
|
421
|
-
### `lumo task comment <identifier> <body>` — leave a comment
|
|
422
|
-
|
|
423
|
-
Two-step under the hood (resolve LUM-N → POST comment). Body is plain text; quote it to embed spaces or newlines.
|
|
424
|
-
|
|
425
|
-
```bash
|
|
426
|
-
lumo task comment LUM-42 "Reproduced the redirect bug on staging — Safari only, not Chrome."
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
The CLI does not support @-mention chip syntax. If the user wants to ping someone, they should comment from the web UI.
|
|
430
|
-
|
|
431
|
-
### Task ↔ Spec Artifacts
|
|
432
|
-
|
|
433
|
-
Record Claude Code spec-engineering products (spec / plan / design …) on a task. The artifacts show up in the task detail "规格" (definition) layer and are injected into `lumo task context`.
|
|
434
|
-
|
|
435
|
-
#### `lumo task artifact add <task> --kind <kind> --title <title> --file <path> --source <source> --agent <agent>`
|
|
436
|
-
|
|
437
|
-
Attaches an artifact to a task. `--kind`, `--title`, `--source` are stored verbatim — **`kind` is opaque** (no enumeration; `spec` / `plan` / `requirements` / anything is accepted). `--source` is **required** and names the spec-generation framework that produced the artifact, written as its **formal name** (`Superpowers` / `Spec Kit` / `BMad` / `OpenSpec` / `GSD` / …) — it is also opaque (no enumeration), but there is **no default**, so you must pass it. Quote names that contain spaces (`--source "Spec Kit"`). `--file` supplies the body (file contents). Each call appends to the end of the task's artifact list — call once per artifact (e.g. Superpowers: one `spec`, one `plan`). The `<task>` (e.g. `LUM-42`) is resolved server-side. **`--file` is sandboxed:** the CLI rejects any path that resolves **outside the current project directory** (parent-traversal, absolute paths, escaping symlinks) or that matches a **sensitive-file denylist** (`.env*`, `id_rsa`/`id_ed25519`, `*.pem`/`*.key`, `.aws`/`.ssh` contents, `credentials`, `.npmrc`, …). There is no override flag — pass only project-local, non-secret files (e.g. `docs/spec.md`). To record an out-of-tree file, copy it into the project first.
|
|
438
|
-
|
|
439
|
-
`--agent` is **required** and names the coding tool that produced the artifact (enum). Valid values: `claude-code | codex | cursor | gemini-cli | github-copilot | windsurf` (case-insensitive; `gemini` and `copilot` are accepted aliases).
|
|
440
|
-
|
|
441
|
-
```bash
|
|
442
|
-
lumo task artifact add LUM-42 --kind spec --title "Spec" --file docs/spec.md --source Superpowers --agent claude-code
|
|
443
|
-
lumo task artifact add LUM-42 --kind plan --title "Implementation plan" --file docs/plan.md --source "Spec Kit" --agent claude-code
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
Output: `Added [spec] "Spec" to LUM-42`
|
|
447
|
-
|
|
448
|
-
#### `lumo task artifact update <task> <artifact-id> [--kind <kind>] [--title <title>] [--source <source>] [--agent <agent>]`
|
|
449
|
-
|
|
450
|
-
Patches an existing artifact's metadata in place. Editable fields are **`kind`, `title`, `source`, and `agent`** — **content is immutable** (to change the body, `rm` the artifact and `add` it again). At least one flag is required; passing none errors before any network call. Empty values (`--kind ""`) are rejected. The `<artifact-id>` is the cuid in column 1 of `artifact list`. `--agent` accepts the same valid values and aliases as `artifact add`: `claude-code | codex | cursor | gemini-cli | github-copilot | windsurf` (case-insensitive; `gemini` and `copilot` are accepted aliases).
|
|
451
|
-
|
|
452
|
-
```bash
|
|
453
|
-
lumo task artifact update LUM-42 cma_xxx --kind plan # re-classify spec → plan
|
|
454
|
-
lumo task artifact update LUM-42 cma_xxx --source "Spec Kit" # fix the framework label
|
|
455
|
-
lumo task artifact update LUM-42 cma_xxx --title "Final spec" --source OpenSpec
|
|
456
|
-
lumo task artifact update LUM-42 cma_xxx --agent cursor # fix the agent label
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
Output: `Updated [plan] "Final spec" (OpenSpec) on LUM-42`. A 404 (task or artifact missing in this workspace) prints the server message and exits 1.
|
|
460
|
-
|
|
461
|
-
#### `lumo task artifact list <task>`
|
|
462
|
-
|
|
463
|
-
Lists artifacts on the task in order: `<id> <kind> <agent> <source> <title>`. Prints `No artifacts on <task>` when there are none.
|
|
464
|
-
|
|
465
|
-
```bash
|
|
466
|
-
lumo task artifact list LUM-42
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
#### `lumo task artifact show <task> <artifact-id>`
|
|
470
|
-
|
|
471
|
-
Prints one artifact's key:value header (id, kind, title, agent, source, order, task) followed by the full content body. The `<artifact-id>` is the cuid in column 1 of `artifact list`.
|
|
472
|
-
|
|
473
|
-
```bash
|
|
474
|
-
lumo task artifact show LUM-42 cma_xxx
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
#### `lumo task artifact rm <task> <artifact-id> --yes`
|
|
478
|
-
|
|
479
|
-
Deletes an artifact from a task. Irreversible — `--yes` is required and there is no interactive prompt (agent-friendly). On success prints `Removed <artifact-id> from <task>`. A 404 (task or artifact missing in this workspace) prints the server message and exits 1.
|
|
480
|
-
|
|
481
|
-
```bash
|
|
482
|
-
lumo task artifact rm LUM-42 cma_xxx --yes
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
When to suggest: after running a spec/plan workflow in Claude Code, offer to record the product(s) with `task artifact add` (one call per artifact) — always pass `--source` with the framework you used. Use `task artifact list` to see what's already recorded, `task artifact show` to inspect a single artifact's content, `task artifact update` to fix a wrong kind/title/source without re-uploading, and `task artifact rm` to drop one that's wrong or stale.
|
|
486
|
-
|
|
487
|
-
### Task ↔ Figma Designs
|
|
488
|
-
|
|
489
|
-
#### `lumo task figma add <task> <url>` — attach a Figma file/frame
|
|
490
|
-
|
|
491
|
-
Fetches file name, frame name, and thumbnail via Figma OAuth and stores them
|
|
492
|
-
on the task.
|
|
493
|
-
|
|
494
|
-
```bash
|
|
495
|
-
lumo task figma add LUM-42 "https://www.figma.com/design/abc123/Onboarding?node-id=1-234"
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
If the URL omits `node-id`, the link is stored as file-level; the CLI prints
|
|
499
|
-
a `(file-level, thumbnail from "...")` note showing the auto-picked
|
|
500
|
-
representative frame.
|
|
501
|
-
|
|
502
|
-
Idempotent — re-adding the same URL within 7 days returns the existing row
|
|
503
|
-
without re-calling Figma.
|
|
504
|
-
|
|
505
|
-
**Not connected?** Errors with:
|
|
506
|
-
|
|
507
|
-
```
|
|
508
|
-
✗ You haven't connected Figma yet.
|
|
509
|
-
Run: open https://www.uselumo.ai/settings/integrations
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
#### `lumo task figma list <task>` — list attachments
|
|
513
|
-
|
|
514
|
-
```
|
|
515
|
-
$ lumo task figma list LUM-42
|
|
516
|
-
cfl_xxx1 Onboarding Welcome screen 2026-05-28
|
|
517
|
-
cfl_xxx2 Design System Button / Primary 2026-05-27
|
|
518
|
-
cfl_xxx3 Onboarding (file-level) 2026-05-20 ⚠ thumbnail stale
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
`⚠ thumbnail stale` appears when `thumbnailFetchedAt > 25 days`.
|
|
522
|
-
|
|
523
|
-
#### `lumo task figma rm <task> <link-id-or-url>` — remove an attachment
|
|
524
|
-
|
|
525
|
-
Accepts a `cfl_*` cuid or the original URL. Idempotent (`Not linked: ...` + exit 0 when no match).
|
|
526
|
-
|
|
527
|
-
#### `lumo task figma refresh <task>` — manual refresh
|
|
528
|
-
|
|
529
|
-
Re-fetches metadata + thumbnail for every Figma link on the task. Per-link
|
|
530
|
-
failures are isolated.
|
|
531
|
-
|
|
532
|
-
```
|
|
533
|
-
$ lumo task figma refresh LUM-42
|
|
534
|
-
Refreshed 3 Figma links on LUM-42
|
|
535
|
-
✓ Onboarding · Welcome screen
|
|
536
|
-
✓ Onboarding · Sign-up form
|
|
537
|
-
✗ Design System · Button (file not accessible)
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
### When to suggest the `task figma` commands
|
|
541
|
-
|
|
542
|
-
- User pastes a Figma URL or mentions a design ("here's the mock", "the
|
|
543
|
-
Figma is at...").
|
|
544
|
-
- User asks "what designs are linked to this task" or "show me the Figma
|
|
545
|
-
for LUM-42".
|
|
546
|
-
- After implementing a UI change, suggest `lumo task figma refresh <task>`
|
|
547
|
-
if the user mentioned updating the Figma source.
|
|
548
|
-
|
|
549
|
-
OAuth connection lives in the Web UI at
|
|
550
|
-
`/settings/integrations`. The CLI does **not** have a `figma auth`
|
|
551
|
-
command; if the user tries `task figma add` without connecting, the error
|
|
552
|
-
message directs them to the Web UI.
|
|
553
|
-
|
|
554
|
-
### `lumo project list` — list projects in the workspace
|
|
555
|
-
|
|
556
|
-
Prints `<slug> <Display Name>` lines. The slug column matches the `--project <ref>` argument accepted by `task create`, so users (and you) can copy a slug straight from this output into a create command.
|
|
557
|
-
|
|
558
|
-
```bash
|
|
559
|
-
lumo project list
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### `lumo milestone list [--project <ref>] [--archived] [--all] [--search <text>]` — list milestones in a project
|
|
563
|
-
|
|
564
|
-
Prints fixed-width rows: `<STATUS> <HEALTH> <target-date or -> <name>`, sorted by target date asc (nulls last) then created asc.
|
|
565
|
-
|
|
566
|
-
By default, only **non-archived** milestones are listed. Use `--archived` to show **only** archived milestones, or `--all` to show **both** archived and non-archived. Archived rows are marked with a ` (archived)` suffix on the name.
|
|
567
|
-
|
|
568
|
-
Use `--search <text>` to filter to milestones whose **name or description** contains the text (case-insensitive substring match). It applies **on top of** the archive filter (e.g. `--all --search q3`). A blank/whitespace-only value is ignored (no filtering). The matched text is bounded to 120 chars server-side.
|
|
569
|
-
|
|
570
|
-
| Flag | Type | Notes |
|
|
571
|
-
| ----------------- | ------- | -------------------------------------------------------------------------------------- |
|
|
572
|
-
| `--project <ref>` | string | Required when the workspace has more than one project. Name or slug, case-insensitive. |
|
|
573
|
-
| `--archived` | boolean | Show **only** archived milestones (instead of the default non-archived set). |
|
|
574
|
-
| `--all` | boolean | Show **both** archived and non-archived milestones. |
|
|
575
|
-
| `--search <text>` | string | Filter by **name/description** case-insensitive substring. Combines with the archive filter; blank value ignored. |
|
|
576
|
-
|
|
577
|
-
`HEALTH` is the target-date risk light, server-computed from the milestone's target date + task progress:
|
|
578
|
-
|
|
579
|
-
- `ON-TRACK` — on schedule (or all tasks done)
|
|
580
|
-
- `AT-RISK` — completion lags elapsed time, or (no start date) the target is within ~7 days with work remaining
|
|
581
|
-
- `OVERDUE` — past the target date with tasks still open
|
|
582
|
-
- `-` — no light applies (status `COMPLETED`/`CANCELLED`, or no target date)
|
|
583
|
-
|
|
584
|
-
```bash
|
|
585
|
-
lumo milestone list # one-project workspace (non-archived only)
|
|
586
|
-
lumo milestone list --project lumo # multi-project workspace
|
|
587
|
-
lumo milestone list --archived # only archived milestones
|
|
588
|
-
lumo milestone list --all # archived + non-archived (archived marked "(archived)")
|
|
589
|
-
lumo milestone list --search q3 # name/description contains "q3" (case-insensitive)
|
|
590
|
-
lumo milestone list --all --search launch # search across archived + non-archived
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
`--project <ref>` is required when the workspace has more than one project (consistent with `task create --project`). Match is by project name or slug, case-insensitive.
|
|
594
|
-
|
|
595
|
-
### When to suggest `milestone list`
|
|
596
|
-
|
|
597
|
-
- Before suggesting `task create --milestone <ref>` or `task update --milestone <ref>` to confirm the milestone exists under the expected name.
|
|
598
|
-
- When the user asks "what milestones do we have", "what's on v1.0", or similar.
|
|
599
|
-
- When the user wants to **find/search milestones by keyword** ("find the launch milestone", "搜索里程碑", "which milestones mention X") — use `--search <text>` rather than listing all and eyeballing.
|
|
600
|
-
|
|
601
|
-
When to suggest: before `task create --project <ref>` when the workspace has more than one project and the user hasn't specified which one.
|
|
602
|
-
|
|
603
|
-
### `lumo milestone create <name>` — create a milestone
|
|
604
|
-
|
|
605
|
-
| Flag | Type | Notes |
|
|
606
|
-
| ---------------------- | ------ | --------------------------------------- |
|
|
607
|
-
| `--project <ref>` | string | Required when workspace has >1 project. |
|
|
608
|
-
| `-d, --description <>` | string | Optional. |
|
|
609
|
-
| `--start <date>` | string | YYYY-MM-DD. |
|
|
610
|
-
| `--target <date>` | string | YYYY-MM-DD. |
|
|
611
|
-
|
|
612
|
-
Examples:
|
|
613
|
-
|
|
614
|
-
```bash
|
|
615
|
-
lumo milestone create "Q3 Launch"
|
|
616
|
-
lumo milestone create "Q3 Launch" --start 2026-06-01 --target 2026-08-31
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
On success: `Created milestone "Q3 Launch" <id>`.
|
|
620
|
-
|
|
621
|
-
### `lumo milestone show <identifier>` — show milestone detail + tasks
|
|
622
|
-
|
|
623
|
-
Accepts UUID or name. With a name, `--project <ref>` is required when the workspace has >1 project.
|
|
624
|
-
|
|
625
|
-
Prints a key:value header (name, status, **health**, dates, project, description), task counts, and the full task table under the milestone. The `Health:` line shows the same target-date risk light as `milestone list` (`ON-TRACK` / `AT-RISK` / `OVERDUE`, or `-` when none applies).
|
|
626
|
-
|
|
627
|
-
```bash
|
|
628
|
-
lumo milestone show "Q3 Launch"
|
|
629
|
-
lumo milestone show 11111111-2222-3333-4444-555555555555
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
### `lumo milestone update <identifier>` — patch a milestone
|
|
633
|
-
|
|
634
|
-
| Flag | Type | Notes |
|
|
635
|
-
| ---------------------- | ------ | ---------------------------------------------------------------- |
|
|
636
|
-
| `--project <ref>` | string | Required when identifier is a name and workspace has >1 project. |
|
|
637
|
-
| `-n, --name <text>` | string | Cannot be empty. |
|
|
638
|
-
| `-d, --description <>` | string | `--description ""` clears. |
|
|
639
|
-
| `-s, --status <value>` | enum | `planned \| active \| completed \| cancelled`. |
|
|
640
|
-
| `--start <date>` | string | `--start ""` clears. |
|
|
641
|
-
| `--target <date>` | string | `--target ""` clears. |
|
|
642
|
-
|
|
643
|
-
At least one field required.
|
|
644
|
-
|
|
645
|
-
```bash
|
|
646
|
-
lumo milestone update "Q3 Launch" --status active
|
|
647
|
-
lumo milestone update "Q3 Launch" --target 2026-09-15
|
|
648
|
-
lumo milestone update "Q3 Launch" --description ""
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
### `lumo milestone delete <identifier>` — delete a milestone
|
|
652
|
-
|
|
653
|
-
Requires `--yes`. No interactive prompt — CLI is agent-friendly. Tasks under the milestone keep their data; their `milestoneId` is cleared.
|
|
654
|
-
|
|
655
|
-
```bash
|
|
656
|
-
lumo milestone delete "Q3 Launch" --yes
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
### `lumo milestone archive <identifier>` — soft-archive a milestone
|
|
660
|
-
|
|
661
|
-
Soft-archives a milestone by setting `archivedAt`. The milestone is **hidden from `milestone list` by default** (use `--archived` or `--all` to see it), but its **history and task links are preserved**, and the action is **reversible** via `milestone unarchive`. This is distinct from `milestone delete`, which is a **hard delete**. While archived, the milestone **rejects edits** (`milestone update`) and **new task bindings** (`task --milestone`, `milestone add`) with a 409 until it is restored. `<identifier>` accepts a UUID or name; `--project <ref>` is required when the identifier is a name and the workspace has >1 project.
|
|
662
|
-
|
|
663
|
-
```bash
|
|
664
|
-
lumo milestone archive "Q3 Launch"
|
|
665
|
-
lumo milestone archive 11111111-2222-3333-4444-555555555555
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
### `lumo milestone unarchive <identifier>` — restore an archived milestone
|
|
669
|
-
|
|
670
|
-
Restores an archived milestone by clearing `archivedAt`. It reappears in `milestone list` and can be edited and bound to tasks again. Idempotent — unarchiving an already-active milestone is a no-op. Same identifier / `--project` rules as `milestone archive`: `<identifier>` accepts a UUID or name; `--project <ref>` is required when the identifier is a name and the workspace has >1 project.
|
|
671
|
-
|
|
672
|
-
```bash
|
|
673
|
-
lumo milestone unarchive "Q3 Launch"
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
### `lumo milestone add <identifier> <task...>` — bind tasks to a milestone (batch)
|
|
677
|
-
|
|
678
|
-
Binds **one or more** tasks to a milestone in a single call — the batch counterpart of `task update --milestone <ref>` (which only takes one task at a time). `<identifier>` accepts a milestone name or UUID; each `<task>` accepts `LUM-N` or a task UUID. `--project <ref>` is required when the identifier is a name and the workspace has >1 project.
|
|
679
|
-
|
|
680
|
-
Task refs are deduped (case-insensitive, order preserved). Each task is PATCHed independently — **partial failures do not roll back**: a task that fails (e.g. not found, or its project has no milestone of that name) is reported on its own line while the rest still bind. Exit code is non-zero if **any** task failed.
|
|
681
|
-
|
|
682
|
-
```bash
|
|
683
|
-
lumo milestone add "Q3 Launch" LUM-1 LUM-2 LUM-3
|
|
684
|
-
lumo milestone add 11111111-2222-3333-4444-555555555555 LUM-1 LUM-2
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
Output — a tally header (zero categories omitted) plus one line per task:
|
|
688
|
-
|
|
689
|
-
```
|
|
690
|
-
Q3 Launch: 2 added, 1 failed
|
|
691
|
-
✓ LUM-1
|
|
692
|
-
✓ LUM-2
|
|
693
|
-
✗ LUM-3 no milestone matches "Q3 Launch" in this project. Try `lumo milestone list`.
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
### `lumo milestone remove <identifier> <task...>` — unbind tasks from a milestone (batch)
|
|
697
|
-
|
|
698
|
-
Unbinds **one or more** tasks from a milestone in one call. A task that is **not currently in this milestone is skipped** (idempotent) — it is never reassigned away from a different milestone. `<identifier>` accepts a name or UUID; each `<task>` accepts `LUM-N` or a task UUID. `--project <ref>` is required when the identifier is a name and the workspace has >1 project.
|
|
699
|
-
|
|
700
|
-
```bash
|
|
701
|
-
lumo milestone remove "Q3 Launch" LUM-1 LUM-5
|
|
702
|
-
```
|
|
703
|
-
|
|
704
|
-
Output — `✓` removed, `-` skipped (not in milestone), `✗` failed:
|
|
705
|
-
|
|
706
|
-
```
|
|
707
|
-
Q3 Launch: 1 removed, 1 skipped
|
|
708
|
-
✓ LUM-1
|
|
709
|
-
- LUM-5 not in this milestone
|
|
710
|
-
```
|
|
711
|
-
|
|
712
|
-
### When to suggest `milestone add` / `milestone remove`
|
|
713
|
-
|
|
714
|
-
- The user wants to attach/detach **several** tasks to a milestone at once ("挂这几个任务到 Q3", "把 LUM-1 LUM-2 LUM-3 都放进里程碑", "remove these from the milestone"). For a single task, `task update --milestone <ref>` (or `--milestone ""` to clear) is equally fine.
|
|
715
|
-
- `remove` only clears the binding for tasks actually in the named milestone, so it's safe to pass a broad list — anything not in it is reported as skipped, not clobbered.
|
|
716
|
-
- For one-at-a-time sprint binding see `lumo sprint add / remove` (sprint batch is not yet supported).
|
|
717
|
-
|
|
718
|
-
### `lumo milestone summary <identifier> [--retry]` — fetch AI-generated milestone retro
|
|
719
|
-
|
|
720
|
-
Prints the AI-generated retrospective summary for a milestone (mirrors `sprint summary`). `<identifier>` accepts a milestone name or UUID; `--project <ref>` is required when the identifier is a name and the workspace has more than one project. When no summary exists yet the command prints `(no summary generated yet)`.
|
|
721
|
-
|
|
722
|
-
A summary is generated automatically when a milestone transitions to `COMPLETED` (e.g. via `lumo milestone update <id> --status completed`). The generated report has sections `## Summary`, `## Delivered`, `## Outstanding` plus a one-line `tldr`. Use `--retry` to queue regeneration (e.g. after a failed generation) before fetching — regeneration is async, so the printed result may still be the previous summary or `(no summary generated yet)`.
|
|
723
|
-
|
|
724
|
-
| Flag | Type | Notes |
|
|
725
|
-
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------ |
|
|
726
|
-
| `--project <ref>` | string | Project name or slug. Required when identifier is a name and the workspace has >1 project. |
|
|
727
|
-
| `--retry` | boolean | Queue a regeneration (async, server returns 202) before fetching. Only valid on a COMPLETED milestone. |
|
|
728
|
-
|
|
729
|
-
```bash
|
|
730
|
-
lumo milestone summary "Q3 Launch"
|
|
731
|
-
lumo milestone summary "Q3 Launch" --retry
|
|
732
|
-
lumo milestone summary 11111111-2222-3333-4444-555555555555
|
|
733
|
-
```
|
|
734
|
-
|
|
735
|
-
When to suggest: user asks "summarize the milestone", "milestone retro", "give me a summary of the Q3 milestone", "里程碑总结", "里程碑复盘".
|
|
736
|
-
|
|
737
|
-
### `lumo milestone reorder <ref...> [--project <ref>]` — set the full milestone order
|
|
738
|
-
|
|
739
|
-
Reorders a project's milestones. Pass **every** milestone in the project (by name, case-insensitive, or its cuid) in the desired order — the command rewrites each milestone's `sortOrder` to match. An incomplete list (not every milestone named), an unknown ref, or a duplicate is rejected **before any network mutation**, with a message naming the offending / missing milestones.
|
|
740
|
-
|
|
741
|
-
```bash
|
|
742
|
-
lumo milestone reorder "Q3 Launch" "Beta" "Alpha"
|
|
743
|
-
lumo milestone reorder "Q3 Launch" "Beta" "Alpha" --project backend
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
`--project <ref>` is required when the workspace has more than one project.
|
|
747
|
-
|
|
748
|
-
Output:
|
|
749
|
-
|
|
750
|
-
```
|
|
751
|
-
Reordered 3 milestones:
|
|
752
|
-
1. Q3 Launch
|
|
753
|
-
2. Beta
|
|
754
|
-
3. Alpha
|
|
755
|
-
```
|
|
756
|
-
|
|
757
|
-
### `lumo milestone move <ref> --before <ref> | --after <ref> [--project <ref>]` — move one milestone
|
|
758
|
-
|
|
759
|
-
Moves a single milestone immediately before or after a target milestone, leaving the rest in their current relative order. `--before` and `--after` are **mutually exclusive and exactly one is required** (the CLI errors before any network call if both or neither is given). Refs resolve by cuid or case-insensitive name.
|
|
760
|
-
|
|
761
|
-
```bash
|
|
762
|
-
lumo milestone move "Alpha" --before "Q3 Launch"
|
|
763
|
-
lumo milestone move "Alpha" --after "Beta" --project backend
|
|
764
|
-
```
|
|
765
|
-
|
|
766
|
-
Output:
|
|
767
|
-
|
|
768
|
-
```
|
|
769
|
-
Moved "Alpha" before "Q3 Launch". New order:
|
|
770
|
-
1. Alpha
|
|
771
|
-
2. Q3 Launch
|
|
772
|
-
3. Beta
|
|
773
|
-
```
|
|
774
|
-
|
|
775
|
-
Both commands resolve to a full ordered list client-side and call the same `PATCH /api/projects/<id>/milestones/reorder` endpoint (which requires the list to name every milestone exactly once). New milestones created via `milestone create` are appended to the bottom of the order.
|
|
776
|
-
|
|
777
|
-
**Ambiguous names:** milestone names are not unique within a project (only the slug is). A ref whose name matches more than one milestone is **rejected** with an `ambiguous milestone name … re-run with the id` error listing the candidate cuids — pass the cuid instead. This applies to every name-based milestone ref (`reorder`, `move`, and also `show` / `update` / `delete` / `summary` / `add` / `remove`).
|
|
778
|
-
|
|
779
|
-
When to suggest: user asks to "reorder milestones", "排序里程碑", "调整里程碑顺序", "move milestone X before/after Y", "把里程碑 X 移到 Y 前面/后面", "put this milestone first".
|
|
780
|
-
|
|
781
|
-
## Document Management
|
|
782
|
-
|
|
783
|
-
### `lumo doc create [title] [flags]` — create a new document
|
|
784
|
-
|
|
785
|
-
Use this when the user wants to write a new document from the terminal. Title is positional and optional. When omitted, the doc title defaults to empty (server renders as "Untitled" via i18n).
|
|
786
|
-
|
|
787
|
-
| Flag | Type | Notes |
|
|
788
|
-
| ------------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
789
|
-
| `--content <text>` | string | Inline markdown body. |
|
|
790
|
-
| `--file <path>` | string | Read markdown body from file. |
|
|
791
|
-
| (stdin) | — | Pipe markdown; treated as content when stdin is not a TTY. |
|
|
792
|
-
| `--scope <scope>` | enum | `personal` (default) or `workspace`. Maps to PRIVATE / WORKSPACE. |
|
|
793
|
-
| `--project <ref>` | string | Project name or slug to file under. Default null. (Note: v1 does not server-resolve names; pass a cuid or omit.) |
|
|
794
|
-
| `--task <LUM-N>` | string | Bind to this task immediately after create. |
|
|
795
|
-
| `--tag <name>` | string (repeatable) | Attach tag by name. Creates tag if missing. Max 20 per call. |
|
|
796
|
-
| `--tag-id <cuid>` | string (repeatable) | Attach tag by id. Combines with `--tag`. Max 20 per call. |
|
|
797
|
-
| `--parent <doc>` | string | cuid or case-insensitive title. Files the new doc under this parent. Omit for root. |
|
|
798
|
-
|
|
799
|
-
The three content channels (`--content`, `--file`, stdin) are mutually exclusive — specify at most one. **`--file` is sandboxed:** the CLI rejects a path that resolves outside the current project directory (parent-traversal, absolute, escaping symlinks) or matches a sensitive-file denylist (`.env*`, private keys, `*.pem`/`*.key`, `credentials`, `.ssh`/`.aws` contents, …). Pass only project-local, non-secret files; there is no override flag.
|
|
800
|
-
|
|
801
|
-
Examples:
|
|
802
|
-
|
|
803
|
-
```bash
|
|
804
|
-
lumo doc create "RFC: doc CLI" --scope workspace --file scratch/rfc.md --task LUM-66
|
|
805
|
-
lumo doc create "RFC: tags" --tag rfc --tag draft
|
|
806
|
-
lumo doc create "Design spec" --tag-id clm_abc123 --tag draft
|
|
807
|
-
lumo doc create "Sub-doc" --parent "RFC"
|
|
808
|
-
```
|
|
809
|
-
|
|
810
|
-
Success output:
|
|
811
|
-
|
|
812
|
-
```
|
|
813
|
-
Created cmd_xxx "RFC: doc CLI" https://www.uselumo.ai/workspace/lumo/documents/rfc-doc-cli-42
|
|
814
|
-
Tags: rfc, draft
|
|
815
|
-
```
|
|
816
|
-
|
|
817
|
-
The cuid (`cmd_xxx`) is still printed as a stable identifier you can pass back into other `lumo doc ...` commands; the URL switched to the per-workspace slug shape (`slugify(title)-<number>`) and the cuid is no longer a valid web URL.
|
|
818
|
-
|
|
819
|
-
The `Tags:` line is omitted when no tags were attached.
|
|
820
|
-
|
|
821
|
-
### When to suggest `doc create`
|
|
822
|
-
|
|
823
|
-
- User says "write a doc", "起一篇 RFC", "新建文档", or describes a deliverable that should live as a document.
|
|
824
|
-
- After a discussion that needs a write-up, offer to create the doc with a title and the right scope.
|
|
825
|
-
|
|
826
|
-
### `lumo doc update <doc> [flags]` — update a document
|
|
827
|
-
|
|
828
|
-
`<doc>` accepts a cuid or a case-insensitive title. Ambiguous titles fail with a candidate list — re-run with the cuid.
|
|
829
|
-
|
|
830
|
-
| Flag | Type | Notes |
|
|
831
|
-
| ------------------------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
832
|
-
| `--title <text>` | string | New title (cannot be empty). |
|
|
833
|
-
| `--content <text>` | string | Replace content (inline). |
|
|
834
|
-
| `--file <path>` | string | Replace content from file. |
|
|
835
|
-
| (stdin) | — | Pipe to replace content. |
|
|
836
|
-
| `--scope <scope>` | enum | `personal` / `workspace`. |
|
|
837
|
-
| `--project <ref>` | string | Project name/slug. `--project ""` clears the filing. |
|
|
838
|
-
| `--tag <name>` | string (repeatable) | **Bulk replace** the tag set by name. Creates tag if missing. Max 20. Mutually exclusive with `--add-tag*` / `--remove-tag*`. |
|
|
839
|
-
| `--tag-id <cuid>` | string (repeatable) | **Bulk replace** the tag set by id. Max 20. Mutually exclusive with `--add-tag*` / `--remove-tag*`. |
|
|
840
|
-
| `--add-tag <name>` | string (repeatable) | Attach tag by name (find-or-create). Max 20. |
|
|
841
|
-
| `--add-tag-id <cuid>` | string (repeatable) | Attach tag by id. Max 20. |
|
|
842
|
-
| `--remove-tag <name>` | string (repeatable) | Detach tag by name. `--remove-tag <name>` resolves the name via find-or-create on the workspace. If the name was unknown, a new Tag row is created (orphan, no attachments) before the detach runs as a no-op. Use `--remove-tag-id <cuid>` to avoid orphans. Max 20. |
|
|
843
|
-
| `--remove-tag-id <cuid>` | string (repeatable) | Detach tag by id. Unknown ids are a no-op (no side effects). Max 20. |
|
|
844
|
-
|
|
845
|
-
`--tag` / `--tag-id` (bulk replace) are mutually exclusive with `--add-tag` / `--add-tag-id` / `--remove-tag` / `--remove-tag-id`. The CLI errors before any network call if both families are mixed.
|
|
846
|
-
|
|
847
|
-
Like `doc create`, `--file` is sandboxed: the CLI rejects paths that resolve outside the project directory or match the sensitive-file denylist (`.env*`, private keys, `credentials`, …). No override flag.
|
|
848
|
-
|
|
849
|
-
Examples:
|
|
850
|
-
|
|
851
|
-
```bash
|
|
852
|
-
lumo doc update "RFC: doc CLI" --scope personal
|
|
853
|
-
lumo doc update cmd_xxx --title "RFC v2"
|
|
854
|
-
lumo doc update cmd_xxx --file rfc-v2.md
|
|
855
|
-
lumo doc update RFC --add-tag urgent --remove-tag draft
|
|
856
|
-
lumo doc update cmd_xxx --tag final --tag approved # replace entire tag set
|
|
857
|
-
lumo doc update RFC --tag final --add-tag oops
|
|
858
|
-
# Error: --tag/--tag-id are mutually exclusive with --add-tag/--add-tag-id/--remove-tag/--remove-tag-id
|
|
859
|
-
```
|
|
860
|
-
|
|
861
|
-
### When to suggest `doc update`
|
|
862
|
-
|
|
863
|
-
- User wants to revise an existing doc.
|
|
864
|
-
- After running `lumo doc list` or `doc show`, if the user wants to change a doc's scope, title, or content.
|
|
865
|
-
|
|
866
|
-
### `lumo doc show <doc>` — print one document's detail
|
|
867
|
-
|
|
868
|
-
Prints a key:value header (id, title, scope, project, created/updated timestamps, mentioned tasks) and the content rendered back to markdown.
|
|
869
|
-
|
|
870
|
-
```bash
|
|
871
|
-
lumo doc show "RFC: doc CLI"
|
|
872
|
-
```
|
|
873
|
-
|
|
874
|
-
Note: the markdown rendered by `doc show` is best-effort. Round-trip via `doc show > tmp.md && doc update --file tmp.md` is NOT guaranteed to be a no-op.
|
|
875
|
-
|
|
876
|
-
Use when the user wants the current state or content of a doc without loading full task context.
|
|
877
|
-
|
|
878
|
-
### `lumo doc list [flags]` — list documents
|
|
879
|
-
|
|
880
|
-
Default behavior: lists every document the current user can see, as fixed-width rows: `<cuid> <SCOPE> <project|-> <title>`.
|
|
881
|
-
|
|
882
|
-
| Flag | Type | Notes |
|
|
883
|
-
| ----------------- | ------- | -------------------------------------------------------------------------------------- |
|
|
884
|
-
| `--scope <scope>` | enum | `personal`, `workspace`, or `all`. Default `all`. |
|
|
885
|
-
| `--project <ref>` | string | Filter by project. |
|
|
886
|
-
| `--task <LUM-N>` | string | Only docs bound to this task. Routes through `GET /api/tasks/<id>/documents`. |
|
|
887
|
-
| `--limit <n>` | int | Cap output to the first N rows. |
|
|
888
|
-
| `--tree` | boolean | Render as an indented tree (two spaces per depth level) instead of the flat row table. |
|
|
889
|
-
|
|
890
|
-
`--tree` plus the existing filters work together: the CLI fetches with the filters applied, then builds the tree from whatever rows came back. Docs whose parent is **not** in the result (e.g. filtered out by `--task LUM-N`) render as top-level rows. `--limit N --tree` truncates the flat list to N rows _before_ the tree is built, so a deeply nested subtree may not appear contiguously.
|
|
891
|
-
|
|
892
|
-
When `--task` is combined with `--scope` / `--project`, those become client-side filters on the task-scoped result.
|
|
893
|
-
|
|
894
|
-
Examples:
|
|
895
|
-
|
|
896
|
-
```bash
|
|
897
|
-
lumo doc list --scope workspace
|
|
898
|
-
lumo doc list --task LUM-42
|
|
899
|
-
lumo doc list --scope workspace --tree
|
|
900
|
-
```
|
|
901
|
-
|
|
902
|
-
### When to suggest `doc list`
|
|
903
|
-
|
|
904
|
-
- The user asks "what docs do I have", "show me workspace docs", "what's on LUM-42".
|
|
905
|
-
- Before suggesting `doc update` or `doc delete` when no doc ID is in context — run `doc list` first to surface candidates.
|
|
906
|
-
|
|
907
|
-
### `lumo doc move <doc> [flags]` — move a doc under a different parent or to root
|
|
908
|
-
|
|
909
|
-
Reparents a doc. `<doc>` accepts a cuid or a case-insensitive title; ambiguous titles fail with a candidate list — re-run with the cuid.
|
|
910
|
-
|
|
911
|
-
| Flag | Type | Notes |
|
|
912
|
-
| ---------------- | ------- | ------------------------------------------------ |
|
|
913
|
-
| `--parent <doc>` | string | New parent doc (cuid or case-insensitive title). |
|
|
914
|
-
| `--root` | boolean | Move to top level (`parentId = null`). |
|
|
915
|
-
|
|
916
|
-
`--parent` and `--root` are **mutually exclusive** and one of them is **required**. CLI errors before any network call if both or neither is supplied.
|
|
917
|
-
|
|
918
|
-
The new `sortOrder` is computed CLI-side as `max(sibling.sortOrder) + 1` — the moved doc lands at the end of its new sibling list. Reordering among siblings (`--before` / `--after`) is not yet supported; for now use the Web UI to reorder.
|
|
919
|
-
|
|
920
|
-
Examples:
|
|
921
|
-
|
|
922
|
-
```bash
|
|
923
|
-
lumo doc move "Sub-doc" --parent "Roadmap"
|
|
924
|
-
lumo doc move "Sub-doc" --root
|
|
925
|
-
lumo doc move cmd_xxx --parent cmd_yyy
|
|
926
|
-
```
|
|
927
|
-
|
|
928
|
-
Output:
|
|
929
|
-
|
|
930
|
-
```
|
|
931
|
-
Moved cmd_xxx "Sub-doc" → "Roadmap"
|
|
932
|
-
Moved cmd_xxx "Sub-doc" → root
|
|
933
|
-
```
|
|
934
|
-
|
|
935
|
-
### When to suggest `doc move`
|
|
936
|
-
|
|
937
|
-
- User says "move doc X under Y", "把文档 X 挂到 Y 下", "reparent X to root", "promote X to top level".
|
|
938
|
-
- After `doc create`, if the user realizes the new doc should live elsewhere in the tree — suggest `doc move` rather than recreating.
|
|
939
|
-
|
|
940
|
-
### `lumo doc delete <doc> --yes` — delete a document
|
|
941
|
-
|
|
942
|
-
Requires `--yes`; no interactive prompt (agent-friendly).
|
|
943
|
-
|
|
944
|
-
```bash
|
|
945
|
-
lumo doc delete cmd_xxx --yes
|
|
946
|
-
```
|
|
947
|
-
|
|
948
|
-
### `lumo doc bind <doc> <task>` — bind a doc to a task
|
|
949
|
-
|
|
950
|
-
Adds an explicit DocumentMention row. Survives content edits in the Web UI. If a CONTENT-derived mention already exists for the same pair, it's upgraded to EXPLICIT so a later `unbind` can remove it.
|
|
951
|
-
|
|
952
|
-
Output:
|
|
953
|
-
|
|
954
|
-
```
|
|
955
|
-
Bound cmd_xxx ↔ LUM-42
|
|
956
|
-
Bound cmd_xxx ↔ LUM-42 (upgraded from content) # when upgrading a CONTENT row
|
|
957
|
-
Already bound cmd_xxx ↔ LUM-42 # idempotent
|
|
958
|
-
```
|
|
959
|
-
|
|
960
|
-
### `lumo doc unbind <doc> <task>` — unbind a doc from a task
|
|
961
|
-
|
|
962
|
-
Removes EXPLICIT mentions only. A purely CONTENT-derived mention can't be unbound from CLI — fails with 409 and a message instructing the user to remove the @LUM-N from the doc body in the Web UI.
|
|
963
|
-
|
|
964
|
-
```bash
|
|
965
|
-
lumo doc unbind cmd_xxx LUM-42
|
|
966
|
-
```
|
|
967
|
-
|
|
968
|
-
### `lumo doc share <doc> <member> [--role viewer|editor|manager]` — share with a workspace member
|
|
969
|
-
|
|
970
|
-
Adds (or updates) a DocumentShare row for the given member. `<member>` resolves the same way as `task --assignee`: `me`, an email, or a display name (case-insensitive). Role defaults to `viewer`.
|
|
971
|
-
|
|
972
|
-
**Auto-promotion**: when invoked on a PRIVATE doc, server-side transactionally flips the doc's visibility to SHARED before upserting the share row. No flag needed — sharing a doc is treated as expressing the intent that it should be SHARED.
|
|
973
|
-
|
|
974
|
-
Examples:
|
|
975
|
-
|
|
976
|
-
```bash
|
|
977
|
-
lumo doc share "RFC" alice@example.com --role editor
|
|
978
|
-
lumo doc share cmd_xxx "Alice Wong" --role manager
|
|
979
|
-
lumo doc share cmd_xxx me # share with yourself (rare; mostly for testing)
|
|
980
|
-
```
|
|
981
|
-
|
|
982
|
-
Output:
|
|
983
|
-
|
|
984
|
-
```
|
|
985
|
-
Shared cmd_xxx ↔ Alice Wong (EDITOR)
|
|
986
|
-
```
|
|
987
|
-
|
|
988
|
-
A second invocation with a different role updates the existing row in place (upsert semantics).
|
|
989
|
-
|
|
990
|
-
### `lumo doc unshare <doc> <member>` — remove a member's share
|
|
991
|
-
|
|
992
|
-
Idempotent. If the member has no share row, prints `Not shared with <name>` and exits 0.
|
|
993
|
-
|
|
994
|
-
```bash
|
|
995
|
-
lumo doc unshare "RFC" alice@example.com
|
|
996
|
-
# → Unshared cmd_xxx ↔ Alice Wong
|
|
997
|
-
```
|
|
998
|
-
|
|
999
|
-
Unshare does **not** flip visibility back to PRIVATE — that has to be done explicitly via `lumo doc update --scope personal`.
|
|
1000
|
-
|
|
1001
|
-
### `lumo doc share-list <doc>` — list current shares
|
|
1002
|
-
|
|
1003
|
-
Prints fixed-width rows: `<displayName> <ROLE>`. Empty output means the doc has no shares (it may still be WORKSPACE-visible).
|
|
1004
|
-
|
|
1005
|
-
```bash
|
|
1006
|
-
lumo doc share-list "RFC"
|
|
1007
|
-
# Alice Wong EDITOR
|
|
1008
|
-
# Bob Chan VIEWER
|
|
1009
|
-
```
|
|
1010
|
-
|
|
1011
|
-
### When to suggest the doc share commands
|
|
1012
|
-
|
|
1013
|
-
- User says "share doc X with Y", "give Y access to X", "把文档分享给 Y"
|
|
1014
|
-
- After `doc create --scope personal`, if the user mentions teammates needing access, suggest `doc share` rather than `doc update --scope workspace` when only specific members should see it
|
|
1015
|
-
- Before `doc unshare`, run `doc share-list` if the user hasn't named a specific member
|
|
1016
|
-
|
|
1017
|
-
### `lumo doc import-gdoc <url> [--scope personal|workspace] [--task LUM-N]` — import a Google Doc
|
|
1018
|
-
|
|
1019
|
-
One-way import of a Google Doc into Lumo. The doc is exported from Google as markdown and turned into a native Lumo document (markdown → HTML), storing the source `googleDocId` and importer so it can be re-synced later (`lumo doc sync`). `<url>` accepts a Google Doc URL or a bare doc id.
|
|
1020
|
-
|
|
1021
|
-
| Flag | Type | Notes |
|
|
1022
|
-
| ----------------- | ------ | ------------------------------------------------------------------------------------------ |
|
|
1023
|
-
| `--scope <scope>` | enum | `personal` (→ PRIVATE) or `workspace` (→ WORKSPACE). Omit to use the server default scope. |
|
|
1024
|
-
| `--task <LUM-N>` | string | Bind the imported doc to this task immediately after import. |
|
|
1025
|
-
|
|
1026
|
-
**Over-share note:** once imported, the content follows **Lumo's** sharing model (PRIVATE / SHARED / WORKSPACE) and is **no longer gated by Google permissions**. Importing a `workspace`-scoped doc can therefore expose it to everyone in the workspace even if the Google Doc was restricted — the command prints this reminder on success.
|
|
1027
|
-
|
|
1028
|
-
Requires a connected Google Drive integration; connect it in the Web UI at `/settings/integrations`. There is no CLI `google auth` command.
|
|
1029
|
-
|
|
1030
|
-
```bash
|
|
1031
|
-
lumo doc import-gdoc "https://docs.google.com/document/d/<id>/edit"
|
|
1032
|
-
lumo doc import-gdoc "https://docs.google.com/document/d/<id>/edit" --scope workspace --task LUM-127
|
|
1033
|
-
```
|
|
1034
|
-
|
|
1035
|
-
Output:
|
|
1036
|
-
|
|
1037
|
-
```
|
|
1038
|
-
Imported cmd_xxx "Quarterly Plan" https://www.uselumo.ai/workspace/lumo/documents/quarterly-plan-42
|
|
1039
|
-
Note: imported content follows Lumo sharing and is no longer gated by Google permissions.
|
|
1040
|
-
Bound cmd_xxx ↔ LUM-127
|
|
1041
|
-
```
|
|
1042
|
-
|
|
1043
|
-
The `Bound ... ↔ LUM-N` line appears only when `--task` is supplied.
|
|
1044
|
-
|
|
1045
|
-
### When to suggest `doc import-gdoc`
|
|
1046
|
-
|
|
1047
|
-
- User pastes a Google Doc URL or says "import this Google Doc", "pull this gdoc into Lumo", "把这篇 Google 文档导入".
|
|
1048
|
-
- User wants a Google Doc tracked alongside Lumo tasks/docs — suggest import (with `--task LUM-N` if a task is in context) and remind them about the over-share semantics for `--scope workspace`.
|
|
1049
|
-
|
|
1050
|
-
### `lumo doc sync <doc>` — re-sync an imported doc from Google
|
|
1051
|
-
|
|
1052
|
-
Re-imports a previously imported Google Doc and **overwrites the Lumo body** with the current Google content. **One-way and destructive** — any edits made to the doc inside Lumo are discarded; Google is the source of truth for synced docs.
|
|
1053
|
-
|
|
1054
|
-
Sync always runs as the **importer** (owner model): it re-exports using the importer's stored Google token, not the token of whoever runs the command. If the importer has lost access to the Google Doc, sync fails with a clear error.
|
|
1055
|
-
|
|
1056
|
-
`<doc>` accepts a doc cuid or a case-insensitive title; ambiguous titles fail with a candidate list — re-run with the cuid.
|
|
1057
|
-
|
|
1058
|
-
```bash
|
|
1059
|
-
lumo doc sync cmd_xxx
|
|
1060
|
-
lumo doc sync "Quarterly Plan"
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
Output:
|
|
1064
|
-
|
|
1065
|
-
```
|
|
1066
|
-
Synced cmd_xxx "Quarterly Plan" from Google
|
|
1067
|
-
```
|
|
1068
|
-
|
|
1069
|
-
### When to suggest `doc sync`
|
|
1070
|
-
|
|
1071
|
-
- User says "re-sync the Google Doc", "pull the latest from Google", "refresh the imported doc", "更新一下从 Google 导入的文档".
|
|
1072
|
-
- After the user mentions the Google Doc changed upstream. Warn first that local Lumo edits to that doc will be overwritten (one-way, destructive).
|
|
1073
|
-
|
|
1074
|
-
### Out of scope (CLI v1)
|
|
1075
|
-
|
|
1076
|
-
The CLI does **not** currently support:
|
|
1077
|
-
|
|
1078
|
-
- `--from-editor` (interactive $EDITOR).
|
|
1079
|
-
- Lossless markdown round-trip.
|
|
1080
|
-
- Reordering siblings within the same parent (`--before` / `--after`); use the Web UI for that.
|
|
1081
|
-
|
|
1082
|
-
### When to suggest session binding for docs
|
|
1083
|
-
|
|
1084
|
-
If user creates a doc with `--task LUM-N` and the current Claude Code session is not bound, suggest `lumo session attach LUM-N` so subsequent hook events also tag that task.
|
|
1085
|
-
|
|
1086
|
-
## Sprint Management
|
|
1087
|
-
|
|
1088
|
-
### `lumo sprint list [flags]` — list sprints in a team
|
|
1089
|
-
|
|
1090
|
-
Prints fixed-width rows: `<NUMBER> <STATUS> <start> <end> <name>`, sorted newest-first (server sort).
|
|
1091
|
-
|
|
1092
|
-
| Flag | Type | Notes |
|
|
1093
|
-
| ---------------------- | ------- | ----------------------------------------------------- |
|
|
1094
|
-
| `--team <ref>` | string | Team name or slug. Required in multi-team workspaces. |
|
|
1095
|
-
| `-s, --status <value>` | enum | `draft \| active \| closed`. |
|
|
1096
|
-
| `-n, --limit <count>` | integer | Cap output to the first N rows. |
|
|
1097
|
-
|
|
1098
|
-
```bash
|
|
1099
|
-
lumo sprint list
|
|
1100
|
-
lumo sprint list --status active
|
|
1101
|
-
lumo sprint list --team backend --limit 5
|
|
1102
|
-
```
|
|
1103
|
-
|
|
1104
|
-
When to suggest: user asks "what sprints do we have", "which sprint is active", "list sprints", "show me the current sprint", "active sprints".
|
|
1105
|
-
|
|
1106
|
-
### `lumo sprint create [flags]` — create a sprint
|
|
1107
|
-
|
|
1108
|
-
| Flag | Type | Notes |
|
|
1109
|
-
| ---------------- | ------ | ----------------------------------------------------- |
|
|
1110
|
-
| `--team <ref>` | string | Team name or slug. Required in multi-team workspaces. |
|
|
1111
|
-
| `--start <date>` | string | **Required.** YYYY-MM-DD. |
|
|
1112
|
-
| `--end <date>` | string | **Required.** YYYY-MM-DD. |
|
|
1113
|
-
| `-n, --name <>` | string | Optional. Server fills a default name when omitted. |
|
|
1114
|
-
|
|
1115
|
-
```bash
|
|
1116
|
-
lumo sprint create --start 2026-06-01 --end 2026-06-14
|
|
1117
|
-
lumo sprint create --name "Sprint 4" --start 2026-06-01 --end 2026-06-14 --team backend
|
|
1118
|
-
```
|
|
1119
|
-
|
|
1120
|
-
On success: `Created sprint #<number> "<name>" <id>`.
|
|
1121
|
-
|
|
1122
|
-
When to suggest: user says "create a sprint", "new sprint", "新建冲刺", "start a new iteration".
|
|
1123
|
-
|
|
1124
|
-
### `lumo sprint show <identifier> [--team <ref>]` — show sprint detail + task table
|
|
1125
|
-
|
|
1126
|
-
`<identifier>` accepts a sprint number (e.g. `3`) or a UUID. `--team` is required when using a number in a multi-team workspace.
|
|
1127
|
-
|
|
1128
|
-
Output: key:value header (number, name, status, dates, team) followed by a task table listing every task in the sprint.
|
|
1129
|
-
|
|
1130
|
-
```bash
|
|
1131
|
-
lumo sprint show 3
|
|
1132
|
-
lumo sprint show 3 --team backend
|
|
1133
|
-
lumo sprint show 11111111-2222-3333-4444-555555555555
|
|
1134
|
-
```
|
|
1135
|
-
|
|
1136
|
-
When to suggest: user asks "what's in sprint 3", "show me the current sprint", "冲刺里有什么", "what tasks are in this sprint".
|
|
1137
|
-
|
|
1138
|
-
### `lumo sprint update <identifier> [flags]` — patch a sprint
|
|
1139
|
-
|
|
1140
|
-
Updates sprint metadata. At least one flag required. **No `--status` flag** — use `lumo sprint start` / `lumo sprint close` to transition status.
|
|
1141
|
-
|
|
1142
|
-
| Flag | Type | Notes |
|
|
1143
|
-
| ---------------- | ------ | --------------------------------------------------------------- |
|
|
1144
|
-
| `--team <ref>` | string | Required when identifier is a number in a multi-team workspace. |
|
|
1145
|
-
| `-n, --name <>` | string | New name. Cannot be empty. |
|
|
1146
|
-
| `--start <date>` | string | YYYY-MM-DD. `--start ""` clears. |
|
|
1147
|
-
| `--end <date>` | string | YYYY-MM-DD. `--end ""` clears. |
|
|
1148
|
-
|
|
1149
|
-
```bash
|
|
1150
|
-
lumo sprint update 3 --name "Sprint 4 (extended)"
|
|
1151
|
-
lumo sprint update 3 --end 2026-06-21
|
|
1152
|
-
```
|
|
1153
|
-
|
|
1154
|
-
When to suggest: user wants to rename a sprint, extend dates, or fix sprint metadata.
|
|
1155
|
-
|
|
1156
|
-
### `lumo sprint delete <identifier> --yes` — delete a sprint (DRAFT only)
|
|
1157
|
-
|
|
1158
|
-
Requires `--yes`; no interactive prompt (agent-friendly). Server rejects with an error if the sprint is ACTIVE or CLOSED.
|
|
1159
|
-
|
|
1160
|
-
```bash
|
|
1161
|
-
lumo sprint delete 3 --yes
|
|
1162
|
-
```
|
|
1163
|
-
|
|
1164
|
-
When to suggest: user wants to remove a draft sprint that was created by mistake.
|
|
1165
|
-
|
|
1166
|
-
### `lumo sprint start <identifier>` — transition DRAFT → ACTIVE
|
|
1167
|
-
|
|
1168
|
-
No additional flags. Fails if the sprint is already ACTIVE or CLOSED.
|
|
1169
|
-
|
|
1170
|
-
```bash
|
|
1171
|
-
lumo sprint start 3
|
|
1172
|
-
```
|
|
1173
|
-
|
|
1174
|
-
When to suggest: user says "start the sprint", "开始冲刺", "kick off sprint 3", "activate sprint".
|
|
1175
|
-
|
|
1176
|
-
### `lumo sprint close <identifier> [flags]` — transition ACTIVE → CLOSED
|
|
1177
|
-
|
|
1178
|
-
Handles unfinished tasks based on flags. Without flags: closes only if all tasks are done; otherwise prints a list of unfinished tasks and refuses.
|
|
1179
|
-
|
|
1180
|
-
| Flag | Type | Notes |
|
|
1181
|
-
| --------------- | ------- | -------------------------------------------------------------------------------- |
|
|
1182
|
-
| `--move-all` | boolean | Move all unfinished tasks to the next sprint. Requires `--yes`. |
|
|
1183
|
-
| `--backlog-all` | boolean | Remove all unfinished tasks from the sprint (send to backlog). Requires `--yes`. |
|
|
1184
|
-
| `--yes` | boolean | Required when `--move-all` or `--backlog-all` is given. |
|
|
1185
|
-
|
|
1186
|
-
```bash
|
|
1187
|
-
lumo sprint close 3 # fails if unfinished tasks exist
|
|
1188
|
-
lumo sprint close 3 --move-all --yes # move unfinished to next sprint
|
|
1189
|
-
lumo sprint close 3 --backlog-all --yes # send unfinished to backlog
|
|
1190
|
-
```
|
|
1191
|
-
|
|
1192
|
-
When to suggest: user says "close the sprint", "关闭冲刺", "end sprint 3", "wrap up the sprint". If they haven't decided what to do with unfinished tasks, ask before adding `--move-all` or `--backlog-all`.
|
|
1193
|
-
|
|
1194
|
-
### `lumo sprint summary <identifier> [--retry]` — fetch AI-generated sprint retro
|
|
1195
|
-
|
|
1196
|
-
Prints the AI-generated retrospective summary for the sprint. A 404 response means no summary has been generated yet ("no summary yet").
|
|
1197
|
-
|
|
1198
|
-
| Flag | Type | Notes |
|
|
1199
|
-
| --------- | ------- | ------------------------------------------------- |
|
|
1200
|
-
| `--retry` | boolean | Queue a regeneration (async, server returns 202). |
|
|
1201
|
-
|
|
1202
|
-
```bash
|
|
1203
|
-
lumo sprint summary 3
|
|
1204
|
-
lumo sprint summary 3 --retry
|
|
1205
|
-
```
|
|
1206
|
-
|
|
1207
|
-
When to suggest: user asks "summarize the sprint", "sprint retro", "give me a summary of sprint 3", "冲刺总结".
|
|
1208
|
-
|
|
1209
|
-
### `lumo sprint add <identifier> <task>` — bind a task to a sprint
|
|
1210
|
-
|
|
1211
|
-
Adds `<task>` (e.g. `LUM-48`) to the sprint. Same-team check applies — the task's team must match the sprint's team.
|
|
1212
|
-
|
|
1213
|
-
```bash
|
|
1214
|
-
lumo sprint add 3 LUM-48
|
|
1215
|
-
```
|
|
1216
|
-
|
|
1217
|
-
When to suggest: user says "add LUM-48 to sprint 3", "把任务挂到冲刺", "put this task in the sprint".
|
|
1218
|
-
|
|
1219
|
-
### `lumo sprint remove <identifier> <task>` — unbind a task from a sprint
|
|
1220
|
-
|
|
1221
|
-
Removes `<task>` from the sprint. Idempotent — if the task is not in the sprint, the server returns success.
|
|
1222
|
-
|
|
1223
|
-
```bash
|
|
1224
|
-
lumo sprint remove 3 LUM-48
|
|
1225
|
-
```
|
|
1226
|
-
|
|
1227
|
-
When to suggest: user says "remove LUM-48 from the sprint", "take this task out of sprint 3", "move task to backlog".
|
|
1228
|
-
|
|
1229
|
-
## Memory management
|
|
1230
|
-
|
|
1231
|
-
Record and curate the long-term Memory that Claude reads on future sessions.
|
|
1232
|
-
Memories are scoped **TASK** (useful only for one task) or **PROJECT** (useful
|
|
1233
|
-
across the whole project). Automated extraction (layer1) and promotion (layer2,
|
|
1234
|
-
on task→done) already run; these commands are the manual override.
|
|
1235
|
-
|
|
1236
|
-
### Commands
|
|
1237
|
-
|
|
1238
|
-
```bash
|
|
1239
|
-
# List
|
|
1240
|
-
lumo task memory list [LUM-N] [--category trap|decision|convention|procedural] [-n N]
|
|
1241
|
-
lumo project memory list [<project>] [--category ...] [-n N]
|
|
1242
|
-
|
|
1243
|
-
# Add (per-category fields; <task>/<project> default to the session-bound task)
|
|
1244
|
-
lumo task memory add [LUM-N] --category trap --trigger "..." --outcome "..." [--workaround "..."] [--agent <agent>]
|
|
1245
|
-
lumo task memory add [LUM-N] --category decision --what "..." --why "..." [--alternatives "..."] [--implications "..."] [--agent <agent>]
|
|
1246
|
-
lumo task memory add [LUM-N] --category convention --rule "..." --applies "..." [--agent <agent>]
|
|
1247
|
-
lumo task memory add [LUM-N] --category procedural --workflow "..." --trigger "..." [--step "..." --step "..."] [--agent <agent>]
|
|
1248
|
-
lumo project memory add [<project>] --category ... [--agent <agent>] # same flags; records at PROJECT scope
|
|
1249
|
-
|
|
1250
|
-
# --agent values: claude-code | codex | cursor | gemini-cli | github-copilot | windsurf (default claude-code)
|
|
1251
|
-
# Aliases: gemini → gemini-cli, copilot → github-copilot (case-insensitive)
|
|
1252
|
-
# Omitting --agent records the memory as produced by Claude Code.
|
|
1253
|
-
|
|
1254
|
-
# Single-memory ops (memoryId from `... memory list` column 1)
|
|
1255
|
-
lumo memory promote <memoryId> # TASK → PROJECT
|
|
1256
|
-
lumo memory rm <memoryId> --yes # hard delete
|
|
1257
|
-
```
|
|
1258
|
-
|
|
1259
|
-
When the session is bound (`lumo session attach <LUM-N>`), omit the identifier:
|
|
1260
|
-
`lumo task memory add --category trap --trigger ... --outcome ...` records onto
|
|
1261
|
-
the bound task; `lumo project memory add ...` records onto its project.
|
|
1262
|
-
|
|
1263
|
-
### When to record a memory (worthiness)
|
|
1264
|
-
|
|
1265
|
-
Record only knowledge that is **invisible in the codebase** — the _why_ behind a
|
|
1266
|
-
choice, a gotcha that only surfaces at runtime, a rule that lives in people's
|
|
1267
|
-
heads, a non-obvious failure cause, a non-trivial workflow. **Skip** routine work
|
|
1268
|
-
(reading files, plain edits, normal git, successful builds) and anything a
|
|
1269
|
-
developer could learn from the source, git log, or docs. When unsure, don't.
|
|
1270
|
-
|
|
1271
|
-
### Which category
|
|
1272
|
-
|
|
1273
|
-
- `trap` — a pitfall. Describe the PROBLEM ONLY (`--trigger`, `--outcome`); put any fix in a separate `procedural`.
|
|
1274
|
-
- `decision` — an engineering decision (`--what` + `--why`, optional `--alternatives`/`--implications`).
|
|
1275
|
-
- `convention` — a team rule (`--rule` + `--applies` = where it applies).
|
|
1276
|
-
- `procedural` — a reusable workflow (`--workflow` + `--trigger` + `--step`…).
|
|
1277
|
-
|
|
1278
|
-
### TASK vs PROJECT (at add time)
|
|
1279
|
-
|
|
1280
|
-
Default to **TASK** (`lumo task memory add`). Record directly to **PROJECT**
|
|
1281
|
-
(`lumo project memory add`) only when it helps _any_ task in the project: a
|
|
1282
|
-
toolchain/environment trap, a team-wide convention, a cross-task decision. When
|
|
1283
|
-
unsure → TASK.
|
|
1284
|
-
|
|
1285
|
-
### When to promote (TASK → PROJECT)
|
|
1286
|
-
|
|
1287
|
-
`lumo memory promote <id>` only when the lesson **recurs across 2+ different
|
|
1288
|
-
tasks**, would help a _different_ task, and no equivalent PROJECT memory exists.
|
|
1289
|
-
A wrong promotion is costly (every agent sees it forever) — prefer leaving it at TASK.
|
|
1290
|
-
|
|
1291
|
-
### When to reach for this
|
|
1292
|
-
|
|
1293
|
-
After a non-trivial debugging session, a pitfall you hit, or establishing a
|
|
1294
|
-
convention → consider `lumo task memory add`. When you notice a lesson recurring
|
|
1295
|
-
across multiple tasks → consider `lumo memory promote`.
|
|
1296
|
-
|
|
1297
|
-
## Session Management
|
|
1298
|
-
|
|
1299
|
-
### Auto-bind at session start (from local git)
|
|
1300
|
-
|
|
1301
|
-
When a session starts **without** a bound task, the `session-start` hook tries to
|
|
1302
|
-
infer the task from local git before falling back to the "请告诉我任务编号" prompt:
|
|
1303
|
-
|
|
1304
|
-
- It reads the **current branch name** first (e.g. `lumo/LUM-145-...`), then the
|
|
1305
|
-
**most recent commit subjects** (e.g. `... [LUM-145]`), extracting the first
|
|
1306
|
-
`LUM-<n>`.
|
|
1307
|
-
- On a hit it binds the session to that task automatically (same `bind-task`
|
|
1308
|
-
endpoint as `session attach`) and prints a single line:
|
|
1309
|
-
`已自动绑定 LUM-145 - <title>(依据分支名/最近 commit)。如果不对,回复"不是"我就帮你解绑。`
|
|
1310
|
-
The freshly-bound task's memory is injected too.
|
|
1311
|
-
- No match (detached HEAD, a non-lumo branch with no tagged commits, not a git
|
|
1312
|
-
repo) or a failed bind (unknown task) → it degrades silently to the normal
|
|
1313
|
-
unbound prompt.
|
|
1314
|
-
|
|
1315
|
-
**Agent guidance:** if the user responds "不是" / "不对" / "wrong task" to an
|
|
1316
|
-
auto-bind line, run `lumo session detach` to clear the binding (then `session
|
|
1317
|
-
attach <LUM-N>` if they name the right one). No detach is needed when the
|
|
1318
|
-
auto-bound task is correct.
|
|
1319
|
-
|
|
1320
|
-
### Layer 2 project-memory review at session start
|
|
1321
|
-
|
|
1322
|
-
When the session is bound, session-start may inject a **"🆕 待核对:上次会话自动合并的项目级记忆"** section alongside the memory / PR-review blocks (LUM-165). It lists the **PROJECT-scope** memories that the member's **immediately-preceding session** auto-consolidated (Layer 2 runs asynchronously when a task is marked `done`). Each item shows its `id`.
|
|
1323
|
-
|
|
1324
|
-
- **Why it's here:** Layer 2 promotions land async, so they can't be reviewed in the synchronous `session wrap` panel — they're surfaced at the _next_ session-start instead, when they've definitely landed.
|
|
1325
|
-
- **Show-once:** the section appears only at the session that immediately follows the one that produced the memories. It does **not** re-nag on later sessions, so act on it now or it scrolls off.
|
|
1326
|
-
- **Agent guidance:** briefly sanity-check each listed memory against the codebase/context. If one is wrong or over-generalized, remove it with `lumo memory rm <id> --yes` (ideally confirm with the user first). If they all look right, ignore the section and continue.
|
|
1327
|
-
|
|
1328
|
-
Attribution requires the CC session id to reach the server: `lumo task update <id> --status done` automatically sends `CLAUDE_CODE_SESSION_ID` (via an `X-Lumo-Session-Id` header) so the resulting Layer 2 memories are attributed to the session. Marking a task done from the **web UI** leaves them unattributed (they won't surface for review) — that's expected.
|
|
1329
|
-
|
|
1330
|
-
### `lumo session attach <identifier>` — bind the current session to a task
|
|
1331
|
-
|
|
1332
|
-
Use this whenever the user mentions a task ID. The command is the only way to bind a session to a task.
|
|
1333
|
-
|
|
1334
|
-
```bash
|
|
1335
|
-
lumo session attach LUM-42
|
|
1336
|
-
```
|
|
1337
|
-
|
|
1338
|
-
What it does:
|
|
1339
|
-
|
|
1340
|
-
- Reads `CLAUDE_CODE_SESSION_ID` from the environment (Claude Code sets this automatically). If it is not set, the command errors out — it must run from inside a Claude Code session.
|
|
1341
|
-
- Calls `POST /api/sessions/<session_id>/bind-task` on the Lumo server, which sets the Session row's `taskId` and re-tags previously-untagged HookEvent rows in this session.
|
|
1342
|
-
- The binding lives entirely on the server (`Session.taskId`); subsequent hooks read it back via the session row. The CLI keeps no local sentinel.
|
|
1343
|
-
|
|
1344
|
-
**After attaching, always run `lumo task context <identifier>` to load the task background.**
|
|
1345
|
-
|
|
1346
|
-
### Parallel sessions
|
|
1347
|
-
|
|
1348
|
-
Each Claude Code session has its own `CLAUDE_CODE_SESSION_ID`. Two terminals running `claude code` and binding to different tasks will not interfere with each other — the bindings are scoped per session row server-side.
|
|
1349
|
-
|
|
1350
|
-
### `lumo session status` — show current binding
|
|
1351
|
-
|
|
1352
|
-
Prints which task the current Claude Code session is bound to, or "(no task)" if none. Requires `$CLAUDE_CODE_SESSION_ID` (i.e. must run inside Claude Code).
|
|
1353
|
-
|
|
1354
|
-
```bash
|
|
1355
|
-
lumo session status
|
|
1356
|
-
```
|
|
1357
|
-
|
|
1358
|
-
When to suggest: the user asks "which task am I on", "what's this session bound to", or you need to decide whether to suggest `session attach` for a mentioned task ID.
|
|
1359
|
-
|
|
1360
|
-
### `lumo session detach` — clear the current binding
|
|
1361
|
-
|
|
1362
|
-
Idempotent — running it twice is fine, the second call reports `already unbound`. Past hook events keep their original `taskId`; only future events on this session will be untagged.
|
|
1363
|
-
|
|
1364
|
-
```bash
|
|
1365
|
-
lumo session detach
|
|
1366
|
-
```
|
|
1367
|
-
|
|
1368
|
-
When to suggest: the user wants to stop tagging the current session with the active task (e.g., switching to unrelated exploratory work without binding to a different task).
|
|
1369
|
-
|
|
1370
|
-
### `lumo session wrap [--yes] [--dry-run]` — wrap-up panel: progress comment + memory review + blocked-tag prompt
|
|
1371
|
-
|
|
1372
|
-
Session-end wrap-up panel with **three sections, run in order**:
|
|
1373
|
-
|
|
1374
|
-
**1. 进度评论** — reads back the current Claude Code session's per-turn
|
|
1375
|
-
`turnSummary` rows (the one-line Chinese summaries written each STOP), aggregates
|
|
1376
|
-
every turn **since the last progress comment** into one bulleted body, and — after
|
|
1377
|
-
a `[y] 发送 / [e] 编辑 / [s] 跳过` confirmation — posts it as a comment on the
|
|
1378
|
-
session's bound task. A server-side watermark (`Session.lastProgressCommentAt`)
|
|
1379
|
-
means re-running never re-posts the same turns.
|
|
1380
|
-
|
|
1381
|
-
**2. 记忆审阅** — lists the Layer1 memories this session sedimented since the
|
|
1382
|
-
last review (deduped by a per-session watermark `Session.lastMemoryReviewAt`).
|
|
1383
|
-
Each new memory is shown as `[SCOPE] CATEGORY headline`, numbered from 1. You
|
|
1384
|
-
curate with a single line: `d 1,3` deletes rows 1 and 3, `p 2` promotes row 2 to
|
|
1385
|
-
project scope, and they combine (`d 1,3 p 2`). **回车 (empty) keeps all**; `s`
|
|
1386
|
-
skips the section. Keeping all (回车 or `--yes`) still **advances the watermark**
|
|
1387
|
-
so the next wrap won't re-list reviewed memories; `s` leaves them for next time.
|
|
1388
|
-
Out-of-range indices are ignored. Deletes/promotes run server-side, scoped to
|
|
1389
|
-
memories this session created (you can't touch other sessions' memories through
|
|
1390
|
-
this panel). With no new memories the section prints "(无内容)" and does nothing.
|
|
1391
|
-
|
|
1392
|
-
**3. 卡住检测 (blocked-tag prompt, LUM-153)** — if the **same kind of failure
|
|
1393
|
-
recurred ≥ 3 times** in this session (server-aggregated from
|
|
1394
|
-
`POST_TOOL_USE_FAILURE` events grouped by tool name, plus `STOP_FAILURE`
|
|
1395
|
-
turn-level failures), the section surfaces the dominant failure (`卡在 <tool>
|
|
1396
|
-
(N 次失败)` + last error summary) and prompts `[y] 标记 / [s] 跳过` whether to
|
|
1397
|
-
flag the bound task with a **`blocked` tag**. **Prompt-only — never auto-flips
|
|
1398
|
-
status.** It uses a plain tag (no `TaskStatus` enum, no board column, **no
|
|
1399
|
-
schema migration**). The prompt is **suppressed** when: there's no bound task,
|
|
1400
|
-
the threshold isn't met, or the task **already** carries a `blocked` tag (the
|
|
1401
|
-
idempotent gate — there's no watermark, the existing tag is what prevents
|
|
1402
|
-
re-nagging). The default on empty input / `s` is **do nothing** (tagging is
|
|
1403
|
-
opt-in), so a stray Enter never tags the task. Confirming with an explicit `y`
|
|
1404
|
-
attaches the tag idempotently. **`--yes` does NOT auto-tag** — tagging the
|
|
1405
|
-
shared board requires an interactive `y`, so `--yes` (and non-TTY) prints the
|
|
1406
|
-
suggestion and moves on rather than silently flipping board state. When there's
|
|
1407
|
-
nothing to prompt, the section prints "(无内容)".
|
|
1408
|
-
|
|
1409
|
-
```bash
|
|
1410
|
-
lumo session wrap # interactive: preview each section, choose per-section
|
|
1411
|
-
lumo session wrap --yes # progress posted + memories kept; blocked tag NOT auto-applied (needs interactive y)
|
|
1412
|
-
lumo session wrap --dry-run # print all drafts only; never posts, never mutates, never advances watermarks
|
|
1413
|
-
```
|
|
1414
|
-
|
|
1415
|
-
- Requires `$CLAUDE_CODE_SESSION_ID` (must run inside Claude Code) and a bound
|
|
1416
|
-
task (`lumo session attach <LUM-N>` first). With no bound task or no new turn
|
|
1417
|
-
summaries, the 进度评论 section prints "(无内容)" and posts nothing.
|
|
1418
|
-
- `[e] 编辑` (进度评论) opens `$EDITOR` (fallback vi/nano) on the drafted body;
|
|
1419
|
-
the edited text is posted and the watermark still advances to the turns the
|
|
1420
|
-
draft covered.
|
|
1421
|
-
- `--yes` posts the progress comment AND keeps all memories (no
|
|
1422
|
-
deletes/promotes) while advancing the memory-review watermark; for the
|
|
1423
|
-
blocked-tag section it prints the suggestion but does **not** apply the tag.
|
|
1424
|
-
- `--dry-run` prints all drafts; never posts, never mutates memories/tags, never
|
|
1425
|
-
advances either watermark.
|
|
1426
|
-
- Non-TTY without `--yes`: prints the drafts and does **not** post, mutate, or
|
|
1427
|
-
tag (safe default).
|
|
1428
|
-
|
|
1429
|
-
When to suggest: at the end of a working session on a bound task, to record what
|
|
1430
|
-
was done as a progress comment — offer `lumo session wrap` rather than composing
|
|
1431
|
-
a `task comment` by hand.
|
|
1432
|
-
|
|
1433
|
-
### When to suggest session binding
|
|
1434
|
-
|
|
1435
|
-
- If the user mentions a task ID (e.g., "let's work on LUM-42") and no session is currently bound, **suggest running `lumo session attach`**.
|
|
1436
|
-
- If the user switches tasks mid-session, run `attach` with the new task ID — the server overwrites the existing binding atomically.
|
|
1437
|
-
|
|
1438
|
-
## Workflow Example
|
|
1439
|
-
|
|
1440
|
-
Typical flow when a user says "help me with LUM-42":
|
|
1441
|
-
|
|
1442
|
-
1. Run `lumo session attach LUM-42` to bind this session
|
|
1443
|
-
2. Run `lumo task context LUM-42` to load background
|
|
1444
|
-
3. Review unresolved items and task description
|
|
1445
|
-
4. Begin working on the task
|